Initialize the location to recents if we fail to restore stack.
Bug: 36083419
Change-Id: I8da79eb9dd50d69c828472aae725e286d5e1e8a0
(cherry picked from commit bab25161824d80657b11ba6db6e9f0ecfc72dfbc)
diff --git a/src/com/android/documentsui/base/State.java b/src/com/android/documentsui/base/State.java
index b8ccbb6..d50dbdb 100644
--- a/src/com/android/documentsui/base/State.java
+++ b/src/com/android/documentsui/base/State.java
@@ -80,10 +80,6 @@
public boolean localOnly;
public boolean showDeviceStorageOption;
public boolean showAdvanced;
- /*
- * Indicates handler was an external app, like photos.
- */
- public boolean external;
// Indicates that a copy operation (or move) includes a directory.
// Why? Directory creation isn't supported by some roots (like Downloads).
@@ -130,7 +126,6 @@
out.writeInt(localOnly ? 1 : 0);
out.writeInt(showDeviceStorageOption ? 1 : 0);
out.writeInt(showAdvanced ? 1 : 0);
- out.writeInt(external ? 1 : 0);
DurableUtils.writeToParcel(out, stack);
out.writeMap(dirConfigs);
out.writeList(excludedAuthorities);
@@ -153,7 +148,6 @@
state.localOnly = in.readInt() != 0;
state.showDeviceStorageOption = in.readInt() != 0;
state.showAdvanced = in.readInt() != 0;
- state.external = in.readInt() != 0;
DurableUtils.readFromParcel(in, state.stack);
in.readMap(state.dirConfigs, loader);
in.readList(state.excludedAuthorities, loader);
diff --git a/src/com/android/documentsui/picker/ActionHandler.java b/src/com/android/documentsui/picker/ActionHandler.java
index 444ae67..553cee7 100644
--- a/src/com/android/documentsui/picker/ActionHandler.java
+++ b/src/com/android/documentsui/picker/ActionHandler.java
@@ -38,11 +38,13 @@
import com.android.documentsui.base.RootInfo;
import com.android.documentsui.base.Shared;
import com.android.documentsui.base.State;
+import com.android.documentsui.dirlist.AnimationView;
import com.android.documentsui.dirlist.DocumentDetails;
import com.android.documentsui.Model;
import com.android.documentsui.picker.ActionHandler.Addons;
import com.android.documentsui.queries.SearchViewManager;
import com.android.documentsui.roots.RootsAccess;
+import com.android.internal.annotations.VisibleForTesting;
import java.util.concurrent.Executor;
@@ -134,7 +136,19 @@
private void loadLastAccessedStack() {
if (DEBUG) Log.d(TAG, "Attempting to load last used stack for calling package.");
- new LoadLastAccessedStackTask<>(mActivity, mState, mRoots).execute();
+ new LoadLastAccessedStackTask<>(mActivity, mState, mRoots, this::onLoadedLastAccessedStack)
+ .execute();
+ }
+
+ @VisibleForTesting
+ void onLoadedLastAccessedStack(@Nullable DocumentStack stack) {
+ if (stack == null) {
+ mState.stack.changeRoot(mRoots.getRecentsRoot());
+ } else {
+ mState.stack.reset(stack);
+ }
+
+ mActivity.refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE);
}
@Override
diff --git a/src/com/android/documentsui/picker/LastAccessedProvider.java b/src/com/android/documentsui/picker/LastAccessedProvider.java
index 8428bf8..e911778 100644
--- a/src/com/android/documentsui/picker/LastAccessedProvider.java
+++ b/src/com/android/documentsui/picker/LastAccessedProvider.java
@@ -50,7 +50,6 @@
public class LastAccessedProvider extends ContentProvider {
private static final String TAG = "LastAccessedProvider";
-
private static final String AUTHORITY = "com.android.documentsui.lastAccessed";
private static final UriMatcher sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
diff --git a/src/com/android/documentsui/picker/LoadLastAccessedStackTask.java b/src/com/android/documentsui/picker/LoadLastAccessedStackTask.java
index dea7dc4..004bbb4 100644
--- a/src/com/android/documentsui/picker/LoadLastAccessedStackTask.java
+++ b/src/com/android/documentsui/picker/LoadLastAccessedStackTask.java
@@ -24,12 +24,12 @@
import android.util.Log;
import com.android.documentsui.AbstractActionHandler.CommonAddons;
+import com.android.documentsui.base.DocumentStack;
import com.android.documentsui.base.DurableUtils;
import com.android.documentsui.base.PairedTask;
import com.android.documentsui.base.RootInfo;
import com.android.documentsui.base.Shared;
import com.android.documentsui.base.State;
-import com.android.documentsui.dirlist.AnimationView;
import com.android.documentsui.picker.LastAccessedProvider.Columns;
import com.android.documentsui.roots.RootsAccess;
@@ -38,6 +38,9 @@
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Collection;
+import java.util.function.Consumer;
+
+import javax.annotation.Nullable;
/**
* Loads the last used path (stack) from Recents (history).
@@ -46,54 +49,54 @@
* for an app like DropBox.
*/
final class LoadLastAccessedStackTask<T extends Activity & CommonAddons>
- extends PairedTask<T, Void, Void> {
+ extends PairedTask<T, Void, DocumentStack> {
- private static final String TAG = "LoadLastAccessedStackTask";
- private volatile boolean mRestoredStack;
- private volatile boolean mExternal;
+ private static final String TAG = "LoadLastAccessedStackTa";
+
private final State mState;
- private RootsAccess mRoots;
+ private final RootsAccess mRoots;
+ private final Consumer<DocumentStack> mCallback;
- public LoadLastAccessedStackTask(T activity, State state, RootsAccess roots) {
+ LoadLastAccessedStackTask(
+ T activity, State state, RootsAccess roots, Consumer<DocumentStack> callback) {
super(activity);
- mState = state;
mRoots = roots;
+ mState = state;
+ mCallback = callback;
}
@Override
- protected Void run(Void... params) {
- if (DEBUG && !mState.stack.isEmpty()) {
- Log.w(TAG, "Overwriting existing stack.");
- }
+ protected DocumentStack run(Void... params) {
+ DocumentStack stack = null;
+
String callingPackage = Shared.getCallingPackageName(mOwner);
Uri resumeUri = LastAccessedProvider.buildLastAccessed(
callingPackage);
Cursor cursor = mOwner.getContentResolver().query(resumeUri, null, null, null, null);
try {
if (cursor.moveToFirst()) {
- mExternal = cursor.getInt(cursor.getColumnIndex(Columns.EXTERNAL)) != 0;
+ stack = new DocumentStack();
final byte[] rawStack = cursor.getBlob(
cursor.getColumnIndex(Columns.STACK));
- DurableUtils.readFromArray(rawStack, mState.stack);
- mRestoredStack = true;
+ DurableUtils.readFromArray(rawStack, stack);
}
} catch (IOException e) {
- Log.w(TAG, "Failed to resume: " + e);
+ Log.w(TAG, "Failed to resume: ", e);
} finally {
IoUtils.closeQuietly(cursor);
}
- if (mRestoredStack) {
+ if (stack != null) {
// Update the restored stack to ensure we have freshest data
final Collection<RootInfo> matchingRoots = mRoots.getMatchingRootsBlocking(mState);
try {
- mState.stack.updateRoot(matchingRoots);
- mState.stack.updateDocuments(mOwner.getContentResolver());
+
+ stack.updateRoot(matchingRoots);
+ stack.updateDocuments(mOwner.getContentResolver());
+ return stack;
+
} catch (FileNotFoundException e) {
- Log.w(TAG, "Failed to restore stack for package: " + callingPackage
- + " because of error: "+ e);
- mState.stack.reset();
- mRestoredStack = false;
+ Log.w(TAG, "Failed to restore stack for package: " + callingPackage, e);
}
}
@@ -101,8 +104,7 @@
}
@Override
- protected void finish(Void result) {
- mState.external = mExternal;
- mOwner.refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE);
+ protected void finish(@Nullable DocumentStack stack) {
+ mCallback.accept(stack);
}
}
diff --git a/src/com/android/documentsui/roots/RootsAccess.java b/src/com/android/documentsui/roots/RootsAccess.java
index 9ddca70..9ea51ab 100644
--- a/src/com/android/documentsui/roots/RootsAccess.java
+++ b/src/com/android/documentsui/roots/RootsAccess.java
@@ -50,6 +50,8 @@
RootInfo getDefaultRootBlocking(State state);
+ RootInfo getRecentsRoot();
+
/**
* Returns a list of roots for the specified authority. If not found, then
* an empty list is returned.
diff --git a/src/com/android/documentsui/roots/RootsCache.java b/src/com/android/documentsui/roots/RootsCache.java
index 111a42d..ed29413 100644
--- a/src/com/android/documentsui/roots/RootsCache.java
+++ b/src/com/android/documentsui/roots/RootsCache.java
@@ -322,6 +322,7 @@
return null;
}
+ @Override
public RootInfo getRecentsRoot() {
return mRecentsRoot;
}
diff --git a/tests/common/com/android/documentsui/testing/TestRootsAccess.java b/tests/common/com/android/documentsui/testing/TestRootsAccess.java
index 45a30c7..6175cd3 100644
--- a/tests/common/com/android/documentsui/testing/TestRootsAccess.java
+++ b/tests/common/com/android/documentsui/testing/TestRootsAccess.java
@@ -125,4 +125,9 @@
public RootInfo getDefaultRootBlocking(State state) {
return DOWNLOADS;
}
+
+ @Override
+ public RootInfo getRecentsRoot() {
+ return RECENTS;
+ }
}
diff --git a/tests/unit/com/android/documentsui/picker/ActionHandlerTest.java b/tests/unit/com/android/documentsui/picker/ActionHandlerTest.java
index a5bef37..3d5f64b 100644
--- a/tests/unit/com/android/documentsui/picker/ActionHandlerTest.java
+++ b/tests/unit/com/android/documentsui/picker/ActionHandlerTest.java
@@ -28,6 +28,7 @@
import android.provider.DocumentsContract.Path;
import android.support.test.filters.MediumTest;
import android.support.test.runner.AndroidJUnit4;
+import android.test.mock.MockContentProvider;
import com.android.documentsui.R;
import com.android.documentsui.base.DocumentInfo;
@@ -123,6 +124,16 @@
}
@Test
+ public void testOnLoadedLastAccessStackCallback_defaultToRecents() throws Exception {
+ mActivity.refreshCurrentRootAndDirectory.assertNotCalled();
+
+ mHandler.onLoadedLastAccessedStack(null);
+
+ assertEquals(TestRootsAccess.RECENTS, mEnv.state.stack.getRoot());
+ mActivity.refreshCurrentRootAndDirectory.assertCalled();
+ }
+
+ @Test
public void testOpenContainerDocument() {
mHandler.openContainerDocument(TestEnv.FOLDER_0);