summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Joshua Trask <joshtrask@google.com> 2023-12-15 20:20:45 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2023-12-15 20:20:45 +0000
commit0890c097c3a2cd22d01a50af77fe1c8675b07ba1 (patch)
tree607ad129cfa2202601a549b94378d691fd60717f
parent77979f2d27db4842c96fd08117091c95dfc711b3 (diff)
parent91c10ea1620ee887b477375d7a804b9e5bffac3f (diff)
Merge "Treat all inactive profiles equally" into main
-rw-r--r--java/src/com/android/intentresolver/v2/MultiProfilePagerAdapter.java103
-rw-r--r--java/src/com/android/intentresolver/v2/ResolverMultiProfilePagerAdapter.java12
-rw-r--r--tests/activity/src/com/android/intentresolver/v2/ChooserWrapperActivity.java10
-rw-r--r--tests/activity/src/com/android/intentresolver/v2/ResolverWrapperActivity.java7
-rw-r--r--tests/unit/src/com/android/intentresolver/v2/MultiProfilePagerAdapterTest.kt3
5 files changed, 61 insertions, 74 deletions
diff --git a/java/src/com/android/intentresolver/v2/MultiProfilePagerAdapter.java b/java/src/com/android/intentresolver/v2/MultiProfilePagerAdapter.java
index aa161921..6a286f21 100644
--- a/java/src/com/android/intentresolver/v2/MultiProfilePagerAdapter.java
+++ b/java/src/com/android/intentresolver/v2/MultiProfilePagerAdapter.java
@@ -36,6 +36,8 @@ import com.google.common.collect.ImmutableList;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
@@ -184,10 +186,7 @@ public class MultiProfilePagerAdapter<
}
public void clearInactiveProfileCache() {
- if (mLoadedPages.size() == 1) {
- return;
- }
- mLoadedPages.remove(1 - mCurrentPage);
+ forEachInactivePage(pageNumber -> mLoadedPages.remove(pageNumber));
}
@Override
@@ -317,30 +316,12 @@ public class MultiProfilePagerAdapter<
* to the user.
* <p>For example, if the user is viewing the work tab in the share sheet, this method returns
* the work profile {@link ListAdapterT}.
- * @see #getInactiveListAdapter()
*/
@VisibleForTesting
public final ListAdapterT getActiveListAdapter() {
return getListAdapterForPageNumber(getCurrentPage());
}
- /**
- * If this is a device with a work profile, returns the {@link ListAdapterT} instance
- * of the profile that is <b><i>not</i></b> currently visible to the user. Otherwise returns
- * {@code null}.
- * <p>For example, if the user is viewing the work tab in the share sheet, this method returns
- * the personal profile {@link ListAdapterT}.
- * @see #getActiveListAdapter()
- */
- @VisibleForTesting
- @Nullable
- public final ListAdapterT getInactiveListAdapter() {
- if (getCount() < 2) {
- return null;
- }
- return getListAdapterForPageNumber(1 - getCurrentPage());
- }
-
public final ListAdapterT getPersonalListAdapter() {
return getListAdapterForPageNumber(getPageNumberForProfile(PROFILE_PERSONAL));
}
@@ -366,14 +347,6 @@ public class MultiProfilePagerAdapter<
return getListViewForIndex(getCurrentPage());
}
- @Nullable
- public final PageViewT getInactiveAdapterView() {
- if (getCount() < 2) {
- return null;
- }
- return getListViewForIndex(1 - getCurrentPage());
- }
-
private boolean anyAdapterHasItems() {
for (int i = 0; i < mItems.size(); ++i) {
ListAdapterT listAdapter = mListAdapterExtractor.apply(getAdapterForIndex(i));
@@ -385,13 +358,10 @@ public class MultiProfilePagerAdapter<
}
public void refreshPackagesInAllTabs() {
- // TODO: handle all inactive profiles; for now we can only have at most one. It's unclear if
- // this legacy logic really requires the active tab to be rebuilt first, or if we could just
- // iterate over the tabs in arbitrary order.
+ // TODO: it's unclear if this legacy logic really requires the active tab to be rebuilt
+ // first, or if we could just iterate over the tabs in arbitrary order.
getActiveListAdapter().handlePackagesChanged();
- if (getCount() > 1) {
- getInactiveListAdapter().handlePackagesChanged();
- }
+ forEachInactivePage(page -> getListAdapterForPageNumber(page).handlePackagesChanged());
}
/**
@@ -449,9 +419,10 @@ public class MultiProfilePagerAdapter<
// autolaunch conditions).
boolean rebuildCompleted = rebuildActiveTab(true) || getActiveListAdapter().isTabLoaded();
if (includePartialRebuildOfInactiveTabs) {
- boolean rebuildInactiveCompleted =
- rebuildInactiveTab(false) || getInactiveListAdapter().isTabLoaded();
- rebuildCompleted = rebuildCompleted && rebuildInactiveCompleted;
+ // Per legacy logic, avoid short-circuiting (TODO: why? possibly so that we *start*
+ // loading the inactive tabs even if we're still waiting on the active tab to finish?).
+ boolean completedRebuildingInactiveTabs = rebuildInactiveTabs(false);
+ rebuildCompleted = rebuildCompleted && completedRebuildingInactiveTabs;
}
return rebuildCompleted;
}
@@ -468,18 +439,27 @@ public class MultiProfilePagerAdapter<
}
/**
- * Rebuilds the tab that is not currently visible to the user, if such one exists.
- * <p>Returns {@code true} if rebuild has completed.
+ * Rebuilds any tabs that are not currently visible to the user.
+ * <p>Returns {@code true} if rebuild has completed in all inactive tabs.
*/
- private boolean rebuildInactiveTab(boolean doPostProcessing) {
+ private boolean rebuildInactiveTabs(boolean doPostProcessing) {
Trace.beginSection("MultiProfilePagerAdapter#rebuildInactiveTab");
- if (getItemCount() == 1) {
- Trace.endSection();
- return false;
- }
- boolean result = rebuildTab(getInactiveListAdapter(), doPostProcessing);
+ AtomicBoolean allRebuildsComplete = new AtomicBoolean(true);
+ forEachInactivePage(pageNumber -> {
+ // Evaluate the rebuild for every inactive page, even if we've already seen some adapter
+ // return an "incomplete" status (i.e., even if `allRebuildsComplete` is already false)
+ // and so we already know we'll end up returning false for the batch.
+ // TODO: any particular reason the per-page legacy logic was set up in this order, or
+ // could we possibly short-circuit the rebuild if the tab is already "loaded"?
+ ListAdapterT inactiveAdapter = getListAdapterForPageNumber(pageNumber);
+ boolean rebuildInactivePageCompleted =
+ rebuildTab(inactiveAdapter, doPostProcessing) || inactiveAdapter.isTabLoaded();
+ if (!rebuildInactivePageCompleted) {
+ allRebuildsComplete.set(false);
+ }
+ });
Trace.endSection();
- return result;
+ return allRebuildsComplete.get();
}
private int userHandleToPageIndex(UserHandle userHandle) {
@@ -490,6 +470,20 @@ public class MultiProfilePagerAdapter<
}
}
+ protected void forEachPage(Consumer<Integer> pageNumberHandler) {
+ for (int pageNumber = 0; pageNumber < getItemCount(); ++pageNumber) {
+ pageNumberHandler.accept(pageNumber);
+ }
+ }
+
+ protected void forEachInactivePage(Consumer<Integer> inactivePageNumberHandler) {
+ forEachPage(pageNumber -> {
+ if (pageNumber != getCurrentPage()) {
+ inactivePageNumberHandler.accept(pageNumber);
+ }
+ });
+ }
+
protected boolean rebuildTab(ListAdapterT activeListAdapter, boolean doPostProcessing) {
if (shouldSkipRebuild(activeListAdapter)) {
activeListAdapter.postListReadyRunnable(doPostProcessing, /* rebuildCompleted */ true);
@@ -585,11 +579,14 @@ public class MultiProfilePagerAdapter<
* 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());
+ AtomicBoolean anyEmpty = new AtomicBoolean(false);
+ // TODO: The "inactive" condition is legacy logic. Could we simplify and ask "any"?
+ forEachInactivePage(pageNumber -> {
+ if (shouldShowEmptyStateScreen(getListAdapterForPageNumber(pageNumber))) {
+ anyEmpty.set(true);
+ }
+ });
+ return anyEmpty.get();
}
public boolean shouldShowEmptyStateScreen(ListAdapterT listAdapter) {
diff --git a/java/src/com/android/intentresolver/v2/ResolverMultiProfilePagerAdapter.java b/java/src/com/android/intentresolver/v2/ResolverMultiProfilePagerAdapter.java
index d96fd15a..21e36614 100644
--- a/java/src/com/android/intentresolver/v2/ResolverMultiProfilePagerAdapter.java
+++ b/java/src/com/android/intentresolver/v2/ResolverMultiProfilePagerAdapter.java
@@ -109,11 +109,13 @@ public class ResolverMultiProfilePagerAdapter extends
/** 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);
- }
+ // TODO: The "inactive" condition is legacy logic. Could we simplify and clear-all?
+ forEachInactivePage(pageNumber -> {
+ ListView inactiveListView = getListViewForIndex(pageNumber);
+ if (inactiveListView.getCheckedItemCount() > 0) {
+ inactiveListView.setItemChecked(inactiveListView.getCheckedItemPosition(), false);
+ }
+ });
}
private static class BottomPaddingOverrideSupplier implements Supplier<Optional<Integer>> {
diff --git a/tests/activity/src/com/android/intentresolver/v2/ChooserWrapperActivity.java b/tests/activity/src/com/android/intentresolver/v2/ChooserWrapperActivity.java
index 113d0987..700be615 100644
--- a/tests/activity/src/com/android/intentresolver/v2/ChooserWrapperActivity.java
+++ b/tests/activity/src/com/android/intentresolver/v2/ChooserWrapperActivity.java
@@ -40,7 +40,6 @@ import com.android.intentresolver.TestContentPreviewViewModel;
import com.android.intentresolver.chooser.DisplayResolveInfo;
import com.android.intentresolver.chooser.TargetInfo;
import com.android.intentresolver.emptystate.CrossProfileIntentsChecker;
-import com.android.intentresolver.grid.ChooserGridAdapter;
import com.android.intentresolver.icons.TargetDataLoader;
import com.android.intentresolver.shortcuts.ShortcutLoader;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -118,17 +117,12 @@ public class ChooserWrapperActivity extends ChooserActivity implements IChooserW
@Override
public ChooserListAdapter getPersonalListAdapter() {
- return ((ChooserGridAdapter) mMultiProfilePagerAdapter.getAdapterForIndex(0))
- .getListAdapter();
+ return mChooserMultiProfilePagerAdapter.getPersonalListAdapter();
}
@Override
public ChooserListAdapter getWorkListAdapter() {
- if (mMultiProfilePagerAdapter.getInactiveListAdapter() == null) {
- return null;
- }
- return ((ChooserGridAdapter) mMultiProfilePagerAdapter.getAdapterForIndex(1))
- .getListAdapter();
+ return mChooserMultiProfilePagerAdapter.getWorkListAdapter();
}
@Override
diff --git a/tests/activity/src/com/android/intentresolver/v2/ResolverWrapperActivity.java b/tests/activity/src/com/android/intentresolver/v2/ResolverWrapperActivity.java
index 7ae58254..a09ee894 100644
--- a/tests/activity/src/com/android/intentresolver/v2/ResolverWrapperActivity.java
+++ b/tests/activity/src/com/android/intentresolver/v2/ResolverWrapperActivity.java
@@ -118,14 +118,11 @@ public class ResolverWrapperActivity extends ResolverActivity {
}
ResolverListAdapter getPersonalListAdapter() {
- return ((ResolverListAdapter) mMultiProfilePagerAdapter.getAdapterForIndex(0));
+ return mMultiProfilePagerAdapter.getPersonalListAdapter();
}
ResolverListAdapter getWorkListAdapter() {
- if (mMultiProfilePagerAdapter.getInactiveListAdapter() == null) {
- return null;
- }
- return ((ResolverListAdapter) mMultiProfilePagerAdapter.getAdapterForIndex(1));
+ return mMultiProfilePagerAdapter.getWorkListAdapter();
}
@Override
diff --git a/tests/unit/src/com/android/intentresolver/v2/MultiProfilePagerAdapterTest.kt b/tests/unit/src/com/android/intentresolver/v2/MultiProfilePagerAdapterTest.kt
index f5dc0935..892fbb4e 100644
--- a/tests/unit/src/com/android/intentresolver/v2/MultiProfilePagerAdapterTest.kt
+++ b/tests/unit/src/com/android/intentresolver/v2/MultiProfilePagerAdapterTest.kt
@@ -69,7 +69,6 @@ class MultiProfilePagerAdapterTest {
assertThat(pagerAdapter.currentUserHandle).isEqualTo(PERSONAL_USER_HANDLE)
assertThat(pagerAdapter.getAdapterForIndex(0)).isSameInstanceAs(personalListAdapter)
assertThat(pagerAdapter.activeListAdapter).isSameInstanceAs(personalListAdapter)
- assertThat(pagerAdapter.inactiveListAdapter).isNull()
assertThat(pagerAdapter.personalListAdapter).isSameInstanceAs(personalListAdapter)
assertThat(pagerAdapter.workListAdapter).isNull()
assertThat(pagerAdapter.itemCount).isEqualTo(1)
@@ -104,7 +103,6 @@ class MultiProfilePagerAdapterTest {
assertThat(pagerAdapter.getAdapterForIndex(0)).isSameInstanceAs(personalListAdapter)
assertThat(pagerAdapter.getAdapterForIndex(1)).isSameInstanceAs(workListAdapter)
assertThat(pagerAdapter.activeListAdapter).isSameInstanceAs(personalListAdapter)
- assertThat(pagerAdapter.inactiveListAdapter).isSameInstanceAs(workListAdapter)
assertThat(pagerAdapter.personalListAdapter).isSameInstanceAs(personalListAdapter)
assertThat(pagerAdapter.workListAdapter).isSameInstanceAs(workListAdapter)
assertThat(pagerAdapter.itemCount).isEqualTo(2)
@@ -143,7 +141,6 @@ class MultiProfilePagerAdapterTest {
assertThat(pagerAdapter.getAdapterForIndex(0)).isSameInstanceAs(personalListAdapter)
assertThat(pagerAdapter.getAdapterForIndex(1)).isSameInstanceAs(workListAdapter)
assertThat(pagerAdapter.activeListAdapter).isSameInstanceAs(workListAdapter)
- assertThat(pagerAdapter.inactiveListAdapter).isSameInstanceAs(personalListAdapter)
assertThat(pagerAdapter.personalListAdapter).isSameInstanceAs(personalListAdapter)
assertThat(pagerAdapter.workListAdapter).isSameInstanceAs(workListAdapter)
assertThat(pagerAdapter.itemCount).isEqualTo(2)