Merge "Move per-profile operations to pager-adapter APIs" into main
diff --git a/java/src/com/android/intentresolver/v2/ChooserActivity.java b/java/src/com/android/intentresolver/v2/ChooserActivity.java
index 66705ce..7081264 100644
--- a/java/src/com/android/intentresolver/v2/ChooserActivity.java
+++ b/java/src/com/android/intentresolver/v2/ChooserActivity.java
@@ -981,11 +981,7 @@
 
     @Override
     protected void applyFooterView(int height) {
-        int count = mChooserMultiProfilePagerAdapter.getItemCount();
-
-        for (int i = 0; i < count; i++) {
-            mChooserMultiProfilePagerAdapter.getAdapterForIndex(i).setFooterHeight(height);
-        }
+        mChooserMultiProfilePagerAdapter.setFooterHeightInEveryAdapter(height);
     }
 
     private void logDirectShareTargetReceived(UserHandle forUser) {
@@ -1494,14 +1490,13 @@
 
     /**
      * If we have a tabbed view and are showing 1 row in the current profile and an empty
-     * state screen in the other profile, to prevent cropping of the empty state screen we show
+     * state screen in another profile, to prevent cropping of the empty state screen we show
      * a second row in the current profile.
      */
     private boolean shouldShowExtraRow(int rowsToShow) {
-        return shouldShowTabs()
-                && rowsToShow == 1
-                && mChooserMultiProfilePagerAdapter.shouldShowEmptyStateScreen(
-                        mChooserMultiProfilePagerAdapter.getInactiveListAdapter());
+        return rowsToShow == 1
+                && mChooserMultiProfilePagerAdapter
+                        .shouldShowEmptyStateScreenInAnyInactiveAdapter();
     }
 
     /**
diff --git a/java/src/com/android/intentresolver/v2/ChooserMultiProfilePagerAdapter.java b/java/src/com/android/intentresolver/v2/ChooserMultiProfilePagerAdapter.java
index b9ee962..de0a942 100644
--- a/java/src/com/android/intentresolver/v2/ChooserMultiProfilePagerAdapter.java
+++ b/java/src/com/android/intentresolver/v2/ChooserMultiProfilePagerAdapter.java
@@ -169,6 +169,13 @@
         return super.rebuildTab(listAdapter, doPostProcessing);
     }
 
+    /** Apply the specified {@code height} as the footer in each tab's adapter. */
+    public void setFooterHeightInEveryAdapter(int height) {
+        for (int i = 0; i < getItemCount(); ++i) {
+            getAdapterForIndex(i).setFooterHeight(height);
+        }
+    }
+
     private static class BottomPaddingOverrideSupplier implements Supplier<Optional<Integer>> {
         private final Context mContext;
         private int mBottomOffset;
diff --git a/java/src/com/android/intentresolver/v2/MultiProfilePagerAdapter.java b/java/src/com/android/intentresolver/v2/MultiProfilePagerAdapter.java
index 6d1870b..f785c11 100644
--- a/java/src/com/android/intentresolver/v2/MultiProfilePagerAdapter.java
+++ b/java/src/com/android/intentresolver/v2/MultiProfilePagerAdapter.java
@@ -414,6 +414,28 @@
     }
 
     /**
+     * Fully-rebuild the active tab and, if specified, partially-rebuild any other inactive tabs.
+     */
+    public boolean rebuildTabs(boolean includePartialRebuildOfInactiveTabs) {
+        // TODO: we may be able to determine `includePartialRebuildOfInactiveTabs` ourselves as
+        // a function of our own instance state. OTOH the purpose of this "partial rebuild" is to
+        // be able to evaluate the intermediate state of one particular profile tab (i.e. work
+        // profile) that may not generalize well when we have other "inactive tabs." I.e., either we
+        // rebuild *all* the inactive tabs just to evaluate some auto-launch conditions that only
+        // depend on personal and/or work tabs, or we have to explicitly specify the ones we care
+        // about. It's not the pager-adapter's business to know "which ones we care about," so maybe
+        // they should be rebuilt lazily when-and-if it comes up (e.g. during the evaluation of
+        // autolaunch conditions).
+        boolean rebuildCompleted = rebuildActiveTab(true) || getActiveListAdapter().isTabLoaded();
+        if (includePartialRebuildOfInactiveTabs) {
+            boolean rebuildInactiveCompleted =
+                    rebuildInactiveTab(false) || getInactiveListAdapter().isTabLoaded();
+            rebuildCompleted = rebuildCompleted && rebuildInactiveCompleted;
+        }
+        return rebuildCompleted;
+    }
+
+    /**
      * Rebuilds the tab that is currently visible to the user.
      * <p>Returns {@code true} if rebuild has completed.
      */
@@ -428,7 +450,7 @@
      * Rebuilds the tab that is not currently visible to the user, if such one exists.
      * <p>Returns {@code true} if rebuild has completed.
      */
-    public final boolean rebuildInactiveTab(boolean doPostProcessing) {
+    private boolean rebuildInactiveTab(boolean doPostProcessing) {
         Trace.beginSection("MultiProfilePagerAdapter#rebuildInactiveTab");
         if (getItemCount() == 1) {
             Trace.endSection();
@@ -537,6 +559,18 @@
         descriptor.mEmptyStateUi.hide();
     }
 
+    /**
+     * @return whether any "inactive" tab's adapter would show an empty-state screen in our current
+     * application state.
+     */
+    public final boolean shouldShowEmptyStateScreenInAnyInactiveAdapter() {
+        if (getCount() < 2) {
+            return false;
+        }
+        // TODO: check against *any* inactive adapter; for now we only have one.
+        return shouldShowEmptyStateScreen(getInactiveListAdapter());
+    }
+
     public boolean shouldShowEmptyStateScreen(ListAdapterT listAdapter) {
         int count = listAdapter.getUnfilteredCount();
         return (count == 0 && listAdapter.getPlaceholderCount() == 0)
diff --git a/java/src/com/android/intentresolver/v2/ResolverActivity.java b/java/src/com/android/intentresolver/v2/ResolverActivity.java
index f65ae5a..3d08735 100644
--- a/java/src/com/android/intentresolver/v2/ResolverActivity.java
+++ b/java/src/com/android/intentresolver/v2/ResolverActivity.java
@@ -1510,13 +1510,7 @@
         Trace.beginSection("configureContentView");
         // We partially rebuild the inactive adapter to determine if we should auto launch
         // isTabLoaded will be true here if the empty state screen is shown instead of the list.
-        boolean rebuildCompleted = mMultiProfilePagerAdapter.rebuildActiveTab(true)
-                || mMultiProfilePagerAdapter.getActiveListAdapter().isTabLoaded();
-        if (shouldShowTabs()) {
-            boolean rebuildInactiveCompleted = mMultiProfilePagerAdapter.rebuildInactiveTab(false)
-                    || mMultiProfilePagerAdapter.getInactiveListAdapter().isTabLoaded();
-            rebuildCompleted = rebuildCompleted && rebuildInactiveCompleted;
-        }
+        boolean rebuildCompleted = mMultiProfilePagerAdapter.rebuildTabs(shouldShowTabs());
 
         if (shouldUseMiniResolver()) {
             configureMiniResolverContent(targetDataLoader);
@@ -1881,10 +1875,8 @@
             return;
         }
         mLastSelected = ListView.INVALID_POSITION;
-        ListView inactiveListView = (ListView) mMultiProfilePagerAdapter.getInactiveAdapterView();
-        if (inactiveListView.getCheckedItemCount() > 0) {
-            inactiveListView.setItemChecked(inactiveListView.getCheckedItemPosition(), false);
-        }
+        ((ResolverMultiProfilePagerAdapter) mMultiProfilePagerAdapter)
+                .clearCheckedItemsInInactiveProfiles();
     }
 
     private static int getAttrColor(Context context, int attr) {
diff --git a/java/src/com/android/intentresolver/v2/ResolverMultiProfilePagerAdapter.java b/java/src/com/android/intentresolver/v2/ResolverMultiProfilePagerAdapter.java
index dadc9c0..d96fd15 100644
--- a/java/src/com/android/intentresolver/v2/ResolverMultiProfilePagerAdapter.java
+++ b/java/src/com/android/intentresolver/v2/ResolverMultiProfilePagerAdapter.java
@@ -107,6 +107,15 @@
         mBottomPaddingOverrideSupplier.setUseLayoutWithDefault(useLayoutWithDefault);
     }
 
+    /** Un-check any item(s) that may be checked in any of our inactive adapter(s). */
+    public void clearCheckedItemsInInactiveProfiles() {
+        // TODO: apply to all inactive adapters; for now we just have the one.
+        ListView inactiveListView = getInactiveAdapterView();
+        if (inactiveListView.getCheckedItemCount() > 0) {
+            inactiveListView.setItemChecked(inactiveListView.getCheckedItemPosition(), false);
+        }
+    }
+
     private static class BottomPaddingOverrideSupplier implements Supplier<Optional<Integer>> {
         private boolean mUseLayoutWithDefault;