Fixing bugs related to pausing of private space.

Added variables to store state of the initial stack and the last
selected user in BaseActivity, which is used in DirectoryFragment to
reset the stack if the last selected user befor pausing of the private
space happened to be private user itself.

Bug: 325010006
Bug: 323589103
Bug: 324999992
Test: atest unit test
Change-Id: I398f9f4d2ac0bd24f9f457fdff4b5a965cd6f67c
diff --git a/src/com/android/documentsui/BaseActivity.java b/src/com/android/documentsui/BaseActivity.java
index 1e9c5fd..9e38303 100644
--- a/src/com/android/documentsui/BaseActivity.java
+++ b/src/com/android/documentsui/BaseActivity.java
@@ -54,6 +54,7 @@
 import com.android.documentsui.Injector.Injected;
 import com.android.documentsui.NavigationViewManager.Breadcrumb;
 import com.android.documentsui.base.DocumentInfo;
+import com.android.documentsui.base.DocumentStack;
 import com.android.documentsui.base.EventHandler;
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.base.Shared;
@@ -87,6 +88,7 @@
         extends AppCompatActivity implements CommonAddons, NavigationViewManager.Environment {
 
     private static final String BENCHMARK_TESTING_PACKAGE = "com.android.documentsui.appperftests";
+    private static final String TAG = "BaseActivity";
 
     protected SearchViewManager mSearchManager;
     protected AppsRowManager mAppsRowManager;
@@ -118,10 +120,25 @@
 
     private PreferencesMonitor mPreferencesMonitor;
 
-    private boolean mHasProfileBecomeUnavailable = false;
+    private final DocumentStack mInitialStack = new DocumentStack();
+    private UserId mLastSelectedUser = null;
 
-    public void setHasProfileBecomeUnavailable(boolean hasProfileBecomeUnavailable) {
-        mHasProfileBecomeUnavailable = hasProfileBecomeUnavailable;
+    protected void setInitialStack(DocumentStack stack) {
+        if (mInitialStack.isInitialized()) {
+            if (DEBUG) {
+                Log.d(TAG, "Initial stack already initialised. " + mInitialStack.isInitialized());
+            }
+            return;
+        }
+        mInitialStack.reset(stack);
+    }
+
+    public DocumentStack getInitialStack() {
+        return mInitialStack;
+    }
+
+    public UserId getLastSelectedUser() {
+        return mLastSelectedUser;
     }
 
     public BaseActivity(@LayoutRes int layoutId, String tag) {
@@ -345,9 +362,7 @@
                 // When a profile with user property SHOW_IN_QUIET_MODE_HIDDEN is currently
                 // selected, and it becomes unavailable, we reset the roots to recents.
                 // We do not reset it to recents when pick activity is due to ACTION_CREATE_DOCUMENT
-                mInjector.actions.loadCrossProfileRoot(
-                        (mHasProfileBecomeUnavailable && mState.action != State.ACTION_CREATE)
-                                ? getRecentsRoot() : getCurrentRoot(), userId);
+                mInjector.actions.loadCrossProfileRoot(getCurrentRoot(), userId);
             }
         });
 
@@ -398,6 +413,12 @@
     }
 
     @Override
+    protected void onPause() {
+        super.onPause();
+        mLastSelectedUser = getSelectedUser();
+    }
+
+    @Override
     public boolean onCreateOptionsMenu(Menu menu) {
         boolean showMenu = super.onCreateOptionsMenu(menu);
 
@@ -902,10 +923,6 @@
         }
     }
 
-    public RootInfo getRecentsRoot() {
-        return mProviders.generateRecentsRoot(getSelectedUser());
-    }
-
     @Override
     public DocumentInfo getCurrentDirectory() {
         return mState.stack.peek();
diff --git a/src/com/android/documentsui/DocumentsApplication.java b/src/com/android/documentsui/DocumentsApplication.java
index c5be414..84e4754 100644
--- a/src/com/android/documentsui/DocumentsApplication.java
+++ b/src/com/android/documentsui/DocumentsApplication.java
@@ -262,13 +262,15 @@
                 final String packageName = data.getSchemeSpecificPart();
                 mProviders.updatePackageAsync(UserId.DEFAULT_USER, packageName);
             } else if (PROFILE_FILTER_ACTIONS.contains(action)) {
-                // After we have reloaded roots. Resend the broadcast locally so the other
-                // components can reload properly after roots are updated.
+                // Make the changes to UserManagerState object before calling providers updateAsync
+                // so that providers for all the users are loaded
                 if (getConfigStore().isPrivateSpaceInDocsUIEnabled()) {
                     UserHandle userHandle = intent.getParcelableExtra(Intent.EXTRA_USER);
                     UserId userId = UserId.of(userHandle);
                     getUserManagerState(context).onProfileActionStatusChange(action, userId);
                 }
+                // After we have reloaded roots. Resend the broadcast locally so the other
+                // components can reload properly after roots are updated.
                 mProviders.updateAsync(/* forceRefreshAll= */ true,
                         () -> LocalBroadcastManager.getInstance(context).sendBroadcast(intent));
             } else {
diff --git a/src/com/android/documentsui/MultiRootDocumentsLoader.java b/src/com/android/documentsui/MultiRootDocumentsLoader.java
index f450814..db78daa 100644
--- a/src/com/android/documentsui/MultiRootDocumentsLoader.java
+++ b/src/com/android/documentsui/MultiRootDocumentsLoader.java
@@ -59,7 +59,7 @@
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 
-/*
+/**
  * The abstract class to query multiple roots from {@link android.provider.DocumentsProvider}
  * and return the combined result.
  */
@@ -88,7 +88,7 @@
     private LockingContentObserver mObserver;
 
     @GuardedBy("mTasks")
-    /** A authority -> QueryTask map */
+    /* A authority -> QueryTask map */
     private final Map<String, QueryTask> mTasks = new HashMap<>();
 
     private CountDownLatch mFirstPassLatch;
@@ -96,7 +96,7 @@
 
     private DirectoryResult mResult;
 
-    /*
+    /**
      * Create the loader to query roots from {@link android.provider.DocumentsProvider}.
      *
      * @param context the context
diff --git a/src/com/android/documentsui/NavigationViewManager.java b/src/com/android/documentsui/NavigationViewManager.java
index 21112ff..cd19b65 100644
--- a/src/com/android/documentsui/NavigationViewManager.java
+++ b/src/com/android/documentsui/NavigationViewManager.java
@@ -71,7 +71,8 @@
     private final ConfigStore mConfigStore;
 
     private boolean mIsActionModeActivated = false;
-    private @ColorRes int mDefaultStatusBarColorResId;
+    @ColorRes
+    private int mDefaultStatusBarColorResId;
 
     public NavigationViewManager(
             BaseActivity activity,
diff --git a/src/com/android/documentsui/ProfileTabs.java b/src/com/android/documentsui/ProfileTabs.java
index d096d59..b692c7a 100644
--- a/src/com/android/documentsui/ProfileTabs.java
+++ b/src/com/android/documentsui/ProfileTabs.java
@@ -128,13 +128,8 @@
             // Update the layout according to the current root if necessary.
             // Make sure we do not invoke callback. Otherwise, it is likely to cause infinite loop.
             mTabs.removeOnTabSelectedListener(mOnTabSelectedListener);
-            if (!mUserIds.contains(currentRoot.userId)) {
-                mTabs.addOnTabSelectedListener(mOnTabSelectedListener);
-                mTabs.selectTab(mTabs.getTabAt(mUserIds.indexOf(UserId.CURRENT_USER)));
-            } else {
-                mTabs.selectTab(mTabs.getTabAt(mUserIds.indexOf(currentRoot.userId)));
-                mTabs.addOnTabSelectedListener(mOnTabSelectedListener);
-            }
+            mTabs.selectTab(mTabs.getTabAt(mUserIds.indexOf(currentRoot.userId)));
+            mTabs.addOnTabSelectedListener(mOnTabSelectedListener);
         }
         mTabsContainer.setVisibility(shouldShow() ? View.VISIBLE : View.GONE);
 
diff --git a/src/com/android/documentsui/dirlist/DirectoryFragment.java b/src/com/android/documentsui/dirlist/DirectoryFragment.java
index 32f3683..bf54e25 100644
--- a/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -246,7 +246,6 @@
             } else {
                 profileStatusReceiverPreV(intent, action);
             }
-
         }
 
         private void profileStatusReceiverPostV(Intent intent, String action) {
@@ -310,16 +309,17 @@
 
     private void onHiddenProfileStatusChange(String action, UserId userId) {
         if (Intent.ACTION_PROFILE_UNAVAILABLE.equals(action)) {
-            mActivity.setHasProfileBecomeUnavailable(true);
             if (mProviderTestRunnable != null) {
                 mHandler.removeCallbacks(mProviderTestRunnable);
                 mProviderTestRunnable = null;
             }
-            while (mState.stack.size() > 0) {
-                mState.stack.pop();
+            if (!mActivity.isSearchExpanded()) {
+                if (mActivity.getLastSelectedUser() != null
+                        && mActivity.getLastSelectedUser().equals(userId)) {
+                    mState.stack.reset(mActivity.getInitialStack());
+                }
+                mActivity.refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE);
             }
-            mActivity.updateNavigator();
-            mActivity.setHasProfileBecomeUnavailable(false);
         } else {
             checkUriAndScheduleCheckIfNeeded(userId);
         }
diff --git a/src/com/android/documentsui/files/FilesActivity.java b/src/com/android/documentsui/files/FilesActivity.java
index 7099381..7a53e53 100644
--- a/src/com/android/documentsui/files/FilesActivity.java
+++ b/src/com/android/documentsui/files/FilesActivity.java
@@ -352,6 +352,8 @@
         final RootInfo root = getCurrentRoot();
         final DocumentInfo cwd = getCurrentDirectory();
 
+        setInitialStack(mState.stack);
+
         assert (!mSearchManager.isSearching());
 
         if (mState.stack.isRecents()) {
diff --git a/src/com/android/documentsui/picker/PickActivity.java b/src/com/android/documentsui/picker/PickActivity.java
index 8ba48db..c14c8b8 100644
--- a/src/com/android/documentsui/picker/PickActivity.java
+++ b/src/com/android/documentsui/picker/PickActivity.java
@@ -358,6 +358,8 @@
         final RootInfo root = getCurrentRoot();
         final DocumentInfo cwd = getCurrentDirectory();
 
+        setInitialStack(mState.stack);
+
         if (mState.stack.isRecents()) {
             DirectoryFragment.showRecentsOpen(fm, anim);
 
diff --git a/src/com/android/documentsui/roots/ProvidersCache.java b/src/com/android/documentsui/roots/ProvidersCache.java
index 6750584..15089a6 100644
--- a/src/com/android/documentsui/roots/ProvidersCache.java
+++ b/src/com/android/documentsui/roots/ProvidersCache.java
@@ -127,7 +127,7 @@
     /**
      * Generates recent root for the provided user id
      */
-    public RootInfo generateRecentsRoot(UserId rootUserId) {
+    private RootInfo generateRecentsRoot(UserId rootUserId) {
         return new RootInfo() {{
             // Special root for recents
             userId = rootUserId;
@@ -537,7 +537,7 @@
 
             final long start = SystemClock.elapsedRealtime();
 
-            List<UserId> userIds = getUserIds();
+            List<UserId> userIds = new ArrayList<>(getUserIds());
             for (UserId userId : userIds) {
                 final RootInfo recents = createOrGetRecentsRoot(userId);
                 synchronized (mLock) {