Remove State#restored.

The stack itself is the best indicator of if it has been initialized or
not. With a small refactor we can encapsulate the stack modification in
initialization phase to ActionHandlers only.

Hopefully it won't cause other issues in other corner cases.

Credits to Sony Mobile devs on their bug report.

Bug: 34593795
Change-Id: I4c8e5f9816ede8bb335151626c2aedd2bed521cc
(cherry picked from commit 23618f30215a4bfecaa10795e2ba413702c12bbf)
diff --git a/src/com/android/documentsui/BaseActivity.java b/src/com/android/documentsui/BaseActivity.java
index 8b85bfe..6c7f12b 100644
--- a/src/com/android/documentsui/BaseActivity.java
+++ b/src/com/android/documentsui/BaseActivity.java
@@ -363,6 +363,12 @@
      */
     @Override
     public final void refreshCurrentRootAndDirectory(int anim) {
+        // The following call will crash if it's called before onCreateOptionMenu() is called in
+        // which we install menu item to search view manager, and there is a search query we need to
+        // restore. This happens when we're still initializing our UI so we shouldn't cancel the
+        // search which will be restored later in onCreateOptionMenu(). Try finding a way to guard
+        // refreshCurrentRootAndDirectory() from being called while we're restoring the state of UI
+        // from the saved state passed in onCreate().
         mSearchManager.cancelSearch();
 
         refreshDirectory(anim);
diff --git a/src/com/android/documentsui/base/DocumentStack.java b/src/com/android/documentsui/base/DocumentStack.java
index aafd03f..df6fff8 100644
--- a/src/com/android/documentsui/base/DocumentStack.java
+++ b/src/com/android/documentsui/base/DocumentStack.java
@@ -90,6 +90,10 @@
         mRoot = src.mRoot;
     }
 
+    public boolean isInitialized() {
+        return mRoot != null;
+    }
+
     public @Nullable RootInfo getRoot() {
         return mRoot;
     }
diff --git a/src/com/android/documentsui/base/State.java b/src/com/android/documentsui/base/State.java
index cbadacd..8eb5901 100644
--- a/src/com/android/documentsui/base/State.java
+++ b/src/com/android/documentsui/base/State.java
@@ -79,7 +79,6 @@
     public boolean localOnly;
     public boolean showDeviceStorageOption;
     public boolean showAdvanced;
-    public boolean restored;
     /*
      * Indicates handler was an external app, like photos.
      */
@@ -131,7 +130,6 @@
         out.writeInt(localOnly ? 1 : 0);
         out.writeInt(showDeviceStorageOption ? 1 : 0);
         out.writeInt(showAdvanced ? 1 : 0);
-        out.writeInt(restored ? 1 : 0);
         out.writeInt(external ? 1 : 0);
         DurableUtils.writeToParcel(out, stack);
         out.writeMap(dirConfigs);
@@ -155,7 +153,6 @@
             state.localOnly = in.readInt() != 0;
             state.showDeviceStorageOption = in.readInt() != 0;
             state.showAdvanced = in.readInt() != 0;
-            state.restored = in.readInt() != 0;
             state.external = in.readInt() != 0;
             DurableUtils.readFromParcel(in, state.stack);
             in.readMap(state.dirConfigs, loader);
diff --git a/src/com/android/documentsui/files/ActionHandler.java b/src/com/android/documentsui/files/ActionHandler.java
index 9c39a64..8e66c56 100644
--- a/src/com/android/documentsui/files/ActionHandler.java
+++ b/src/com/android/documentsui/files/ActionHandler.java
@@ -341,12 +341,14 @@
     public void initLocation(Intent intent) {
         assert(intent != null);
 
-        if (mState.restored) {
+        // stack is initialized if it's restored from bundle, which means we're restoring a
+        // previously stored state.
+        if (mState.stack.isInitialized()) {
             if (DEBUG) Log.d(TAG, "Stack already resolved for uri: " + intent.getData());
             return;
         }
 
-        if (launchToStackLocation(mState.stack)) {
+        if (launchToStackLocation(intent)) {
             if (DEBUG) Log.d(TAG, "Launched to location from stack.");
             return;
         }
@@ -370,9 +372,8 @@
         loadHomeDir();
     }
 
-    // If a non-empty stack is present in our state, it was read (presumably)
-    // from EXTRA_STACK intent extra. In this case, we'll skip other means of
-    // loading or restoring the stack (like URI).
+    // If EXTRA_STACK is not null in intent, we'll skip other means of loading
+    // or restoring the stack (like URI).
     //
     // When restoring from a stack, if a URI is present, it should only ever be:
     // -- a launch URI: Launch URIs support sensible activity management,
@@ -381,11 +382,13 @@
     //
     // Any other URI is *sorta* unexpected...except when browsing an archive
     // in downloads.
-    private boolean launchToStackLocation(DocumentStack stack) {
+    private boolean launchToStackLocation(Intent intent) {
+        DocumentStack stack = intent.getParcelableExtra(Shared.EXTRA_STACK);
         if (stack == null || stack.getRoot() == null) {
             return false;
         }
 
+        mState.stack.reset(stack);
         if (mState.stack.isEmpty()) {
             mActivity.onRootPicked(mState.stack.getRoot());
         } else {
diff --git a/src/com/android/documentsui/files/FilesActivity.java b/src/com/android/documentsui/files/FilesActivity.java
index 9ebfbe6..a53d64d 100644
--- a/src/com/android/documentsui/files/FilesActivity.java
+++ b/src/com/android/documentsui/files/FilesActivity.java
@@ -177,11 +177,6 @@
 
         // Options specific to the DocumentsActivity.
         assert(!intent.hasExtra(Intent.EXTRA_LOCAL_ONLY));
-
-        final DocumentStack stack = intent.getParcelableExtra(Shared.EXTRA_STACK);
-        if (stack != null) {
-            state.stack.reset(stack);
-        }
     }
 
     @Override
diff --git a/src/com/android/documentsui/picker/ActionHandler.java b/src/com/android/documentsui/picker/ActionHandler.java
index 9611b57..77a4ebc 100644
--- a/src/com/android/documentsui/picker/ActionHandler.java
+++ b/src/com/android/documentsui/picker/ActionHandler.java
@@ -84,7 +84,9 @@
     public void initLocation(Intent intent) {
         assert(intent != null);
 
-        if (mState.restored) {
+        // stack is initialized if it's restored from bundle, which means we're restoring a
+        // previously stored state.
+        if (mState.stack.isInitialized()) {
             if (DEBUG) Log.d(TAG, "Stack already resolved for uri: " + intent.getData());
             return;
         }
diff --git a/src/com/android/documentsui/picker/LoadLastAccessedStackTask.java b/src/com/android/documentsui/picker/LoadLastAccessedStackTask.java
index bb22e08..dea7dc4 100644
--- a/src/com/android/documentsui/picker/LoadLastAccessedStackTask.java
+++ b/src/com/android/documentsui/picker/LoadLastAccessedStackTask.java
@@ -102,7 +102,6 @@
 
     @Override
     protected void finish(Void result) {
-        mState.restored = mRestoredStack;
         mState.external = mExternal;
         mOwner.refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE);
     }
diff --git a/src/com/android/documentsui/roots/LoadRootTask.java b/src/com/android/documentsui/roots/LoadRootTask.java
index 7bc6d0a..a1e2c44 100644
--- a/src/com/android/documentsui/roots/LoadRootTask.java
+++ b/src/com/android/documentsui/roots/LoadRootTask.java
@@ -54,8 +54,6 @@
 
     @Override
     protected void finish(RootInfo root) {
-        mState.restored = true;
-
         if (root != null) {
             if (DEBUG) Log.d(TAG, "Loaded root: " + root);
             mOwner.onRootPicked(root);