Only perform autolaunch if list has completely rebuilt

Previously we would check for autolaunch the first time
onPostListReady is called, but that is too early in the case
when we start the async task for sorting the targets. In
that case onPostListReady is called twice - once before
task is launched, and once after task is finished.

We fix this by passing the rebuildListCompleted parameter to
the onPostListReady callback and use it to check for autolaunch.

Test: atest ChooserActivity
Test: atest ResolverActivity
Test: manual
Fixes: 154728817
Change-Id: Ib1b049af00d791898b908bdb65971c07c558f3ac
diff --git a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
index b58dbdd..5850e61 100644
--- a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
+++ b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
@@ -301,7 +301,7 @@
 
     private boolean rebuildTab(ResolverListAdapter activeListAdapter, boolean doPostProcessing) {
         if (shouldShowNoCrossProfileIntentsEmptyState(activeListAdapter)) {
-            activeListAdapter.postListReadyRunnable(doPostProcessing);
+            activeListAdapter.postListReadyRunnable(doPostProcessing, /* rebuildCompleted */ true);
             return false;
         }
         return activeListAdapter.rebuildList(doPostProcessing);
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index b671fa7..a84d964 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -2404,10 +2404,9 @@
     public ChooserGridAdapter createChooserGridAdapter(Context context,
             List<Intent> payloadIntents, Intent[] initialIntents, List<ResolveInfo> rList,
             boolean filterLastUsed, boolean useLayoutForBrowsables, UserHandle userHandle) {
-        ChooserListAdapter chooserListAdapter = new ChooserListAdapter(context, payloadIntents,
-                initialIntents, rList,
-                filterLastUsed, createListController(userHandle), useLayoutForBrowsables,
-                this, this);
+        ChooserListAdapter chooserListAdapter = createChooserListAdapter(context, payloadIntents,
+                initialIntents, rList, filterLastUsed,
+                useLayoutForBrowsables, createListController(userHandle));
         AppPredictor.Callback appPredictorCallback = createAppPredictorCallback(chooserListAdapter);
         AppPredictor appPredictor = setupAppPredictorForUser(userHandle, appPredictorCallback);
         chooserListAdapter.setAppPredictor(appPredictor);
@@ -2416,6 +2415,16 @@
     }
 
     @VisibleForTesting
+    public ChooserListAdapter createChooserListAdapter(Context context,
+            List<Intent> payloadIntents, Intent[] initialIntents, List<ResolveInfo> rList,
+            boolean filterLastUsed, boolean useLayoutForBrowsables,
+            ResolverListController resolverListController) {
+        return new ChooserListAdapter(context, payloadIntents, initialIntents, rList,
+                filterLastUsed, resolverListController, useLayoutForBrowsables,
+                this, this, context.getPackageManager());
+    }
+
+    @VisibleForTesting
     protected ResolverListController createListController(UserHandle userHandle) {
         AppPredictor appPredictor = getAppPredictorForShareActivitiesIfEnabled(userHandle);
         AbstractResolverComparator resolverComparator;
diff --git a/core/java/com/android/internal/app/ChooserListAdapter.java b/core/java/com/android/internal/app/ChooserListAdapter.java
index bdfcda5..0edc5ab 100644
--- a/core/java/com/android/internal/app/ChooserListAdapter.java
+++ b/core/java/com/android/internal/app/ChooserListAdapter.java
@@ -88,7 +88,7 @@
     private final int mMaxShortcutTargetsPerApp;
     private final ChooserListCommunicator mChooserListCommunicator;
     private final SelectableTargetInfo.SelectableTargetInfoCommunicator
-            mSelectableTargetInfoComunicator;
+            mSelectableTargetInfoCommunicator;
 
     private int mNumShortcutResults = 0;
 
@@ -117,7 +117,8 @@
             boolean filterLastUsed, ResolverListController resolverListController,
             boolean useLayoutForBrowsables,
             ChooserListCommunicator chooserListCommunicator,
-            SelectableTargetInfo.SelectableTargetInfoCommunicator selectableTargetInfoComunicator) {
+            SelectableTargetInfo.SelectableTargetInfoCommunicator selectableTargetInfoCommunicator,
+            PackageManager packageManager) {
         // Don't send the initial intents through the shared ResolverActivity path,
         // we want to separate them into a different section.
         super(context, payloadIntents, null, rList, filterLastUsed,
@@ -128,10 +129,9 @@
         mMaxShortcutTargetsPerApp =
                 context.getResources().getInteger(R.integer.config_maxShortcutTargetsPerApp);
         mChooserListCommunicator = chooserListCommunicator;
-        mSelectableTargetInfoComunicator = selectableTargetInfoComunicator;
+        mSelectableTargetInfoCommunicator = selectableTargetInfoCommunicator;
 
         if (initialIntents != null) {
-            final PackageManager pm = context.getPackageManager();
             for (int i = 0; i < initialIntents.length; i++) {
                 final Intent ii = initialIntents[i];
                 if (ii == null) {
@@ -147,7 +147,7 @@
                 final ComponentName cn = ii.getComponent();
                 if (cn != null) {
                     try {
-                        ai = pm.getActivityInfo(ii.getComponent(), 0);
+                        ai = packageManager.getActivityInfo(ii.getComponent(), 0);
                         ri = new ResolveInfo();
                         ri.activityInfo = ai;
                     } catch (PackageManager.NameNotFoundException ignored) {
@@ -155,7 +155,7 @@
                     }
                 }
                 if (ai == null) {
-                    ri = pm.resolveActivity(ii, PackageManager.MATCH_DEFAULT_ONLY);
+                    ri = packageManager.resolveActivity(ii, PackageManager.MATCH_DEFAULT_ONLY);
                     ai = ri != null ? ri.activityInfo : null;
                 }
                 if (ai == null) {
@@ -458,7 +458,7 @@
             UserHandle userHandle = getUserHandle();
             Context contextAsUser = mContext.createContextAsUser(userHandle, 0 /* flags */);
             boolean isInserted = insertServiceTarget(new SelectableTargetInfo(contextAsUser,
-                    origTarget, target, targetScore, mSelectableTargetInfoComunicator,
+                    origTarget, target, targetScore, mSelectableTargetInfoCommunicator,
                     (isShortcutResult ? directShareToShortcutInfos.get(target) : null)));
 
             if (isInserted && isShortcutResult) {
@@ -508,7 +508,7 @@
                     .map(target ->
                             new SelectableTargetInfo(
                                     contextAsUser, origTarget, target, target.getScore(),
-                                    mSelectableTargetInfoComunicator,
+                                    mSelectableTargetInfoCommunicator,
                                     (isShortcutResult ? directShareToShortcutInfos.get(target)
                                             : null))
                     )
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 84c833e..3067018 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -1026,7 +1026,8 @@
     }
 
     @Override // ResolverListCommunicator
-    public final void onPostListReady(ResolverListAdapter listAdapter, boolean doPostProcessing) {
+    public final void onPostListReady(ResolverListAdapter listAdapter, boolean doPostProcessing,
+            boolean rebuildCompleted) {
         if (isAutolaunching()) {
             return;
         }
@@ -1037,7 +1038,7 @@
         }
         // showEmptyResolverListEmptyState can mark the tab as loaded,
         // which is a precondition for auto launching
-        if (maybeAutolaunchActivity()) {
+        if (rebuildCompleted && maybeAutolaunchActivity()) {
             return;
         }
         if (doPostProcessing) {
diff --git a/core/java/com/android/internal/app/ResolverListAdapter.java b/core/java/com/android/internal/app/ResolverListAdapter.java
index cee8a92..e8f1113 100644
--- a/core/java/com/android/internal/app/ResolverListAdapter.java
+++ b/core/java/com/android/internal/app/ResolverListAdapter.java
@@ -275,7 +275,7 @@
                 }
                 setPlaceholderCount(placeholderCount);
                 createSortingTask(doPostProcessing).execute(currentResolveList);
-                postListReadyRunnable(doPostProcessing);
+                postListReadyRunnable(doPostProcessing, /* rebuildCompleted */ false);
                 return false;
             } else {
                 processSortedList(currentResolveList, doPostProcessing);
@@ -363,7 +363,7 @@
         }
 
         mResolverListCommunicator.sendVoiceChoicesIfNeeded();
-        postListReadyRunnable(doPostProcessing);
+        postListReadyRunnable(doPostProcessing, /* rebuildCompleted */ true);
         mIsTabLoaded = true;
     }
 
@@ -373,14 +373,15 @@
      * handler thread to update after the current task is finished.
      * @param doPostProcessing Whether to update the UI and load additional direct share targets
      *                         after the list has been rebuilt
+     * @param rebuildCompleted Whether the list has been completely rebuilt
      */
-    void postListReadyRunnable(boolean doPostProcessing) {
+    void postListReadyRunnable(boolean doPostProcessing, boolean rebuildCompleted) {
         if (mPostListReadyRunnable == null) {
             mPostListReadyRunnable = new Runnable() {
                 @Override
                 public void run() {
                     mResolverListCommunicator.onPostListReady(ResolverListAdapter.this,
-                            doPostProcessing);
+                            doPostProcessing, rebuildCompleted);
                     mPostListReadyRunnable = null;
                 }
             };
@@ -642,7 +643,8 @@
 
         Intent getReplacementIntent(ActivityInfo activityInfo, Intent defIntent);
 
-        void onPostListReady(ResolverListAdapter listAdapter, boolean updateUi);
+        void onPostListReady(ResolverListAdapter listAdapter, boolean updateUi,
+                boolean rebuildCompleted);
 
         void sendVoiceChoicesIfNeeded();