aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-12-15 00:41:26 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-12-15 00:41:26 +0000
commit4930af51a2b754d3826aa5489d5f56f0b952e529 (patch)
tree7edfc23366f90cdca5852209a6ac207b7de884a4
parent62cce688e4a2b55fe0c96ce0c78f35822f5a2a14 (diff)
parent3007d9f481e92ed57ca9e3783719b3d84797ef2c (diff)
downloadIntentResolver-android14-qpr2-s3-release.tar.gz
Change-Id: I5e65c02be1b78ed590a943b4687185439c5e98c2
-rw-r--r--java/src/com/android/intentresolver/v2/MultiProfilePagerAdapter.java17
-rw-r--r--java/src/com/android/intentresolver/v2/ResolverActivity.java94
2 files changed, 83 insertions, 28 deletions
diff --git a/java/src/com/android/intentresolver/v2/MultiProfilePagerAdapter.java b/java/src/com/android/intentresolver/v2/MultiProfilePagerAdapter.java
index f785c11..2d9be81 100644
--- a/java/src/com/android/intentresolver/v2/MultiProfilePagerAdapter.java
+++ b/java/src/com/android/intentresolver/v2/MultiProfilePagerAdapter.java
@@ -204,6 +204,14 @@ public class MultiProfilePagerAdapter<
return mCurrentPage;
}
+ public final @Profile int getActiveProfile() {
+ // TODO: here and elsewhere in this class, distinguish between a "profile ID" integer and
+ // its mapped "page index." When we support more than two profiles, this won't be a "stable
+ // mapping" -- some particular profile may not be represented by a "page," but the ones that
+ // are will be assigned contiguous page numbers that skip over the holes.
+ return getCurrentPage();
+ }
+
@VisibleForTesting
public UserHandle getCurrentUserHandle() {
return getActiveListAdapter().getUserHandle();
@@ -329,6 +337,15 @@ public class MultiProfilePagerAdapter<
return mListAdapterExtractor.apply(getAdapterForIndex(PROFILE_PERSONAL));
}
+ /** @return whether our tab data contains a page for the specified {@code profile} ID. */
+ public final boolean hasPageForProfile(@Profile int profile) {
+ // TODO: here and elsewhere in this class, distinguish between a "profile ID" integer and
+ // its mapped "page index." When we support more than two profiles, this won't be a "stable
+ // mapping" -- some particular profile may not be represented by a "page," but the ones that
+ // are will be assigned contiguous page numbers that skip over the holes.
+ return hasAdapterForIndex(profile);
+ }
+
@Nullable
public final ListAdapterT getWorkListAdapter() {
if (!hasAdapterForIndex(PROFILE_WORK)) {
diff --git a/java/src/com/android/intentresolver/v2/ResolverActivity.java b/java/src/com/android/intentresolver/v2/ResolverActivity.java
index 3d08735..2ba50ec 100644
--- a/java/src/com/android/intentresolver/v2/ResolverActivity.java
+++ b/java/src/com/android/intentresolver/v2/ResolverActivity.java
@@ -308,7 +308,7 @@ public class ResolverActivity extends FragmentActivity implements
// of the last used choice to highlight it in the list. We need to always
// turn this off when running under voice interaction, since it results in
// a more complicated UI that the current voice interaction flow is not able
- // to handle. We also turn it off when the work tab is shown to simplify the UX.
+ // to handle. We also turn it off when multiple tabs are shown to simplify the UX.
// We also turn it off when clonedProfile is present on the device, because we might have
// different "last chosen" activities in the different profiles, and PackageManager doesn't
// provide any more information to help us select between them.
@@ -332,7 +332,7 @@ public class ResolverActivity extends FragmentActivity implements
requireAnnotatedUserHandles().personalProfileUserHandle,
false
);
- if (shouldShowTabs()) {
+ if (hasWorkProfile()) {
mWorkPackageMonitor = createPackageMonitor(
mMultiProfilePagerAdapter.getWorkListAdapter());
mWorkPackageMonitor.register(
@@ -1276,7 +1276,7 @@ public class ResolverActivity extends FragmentActivity implements
getMainLooper(),
requireAnnotatedUserHandles().personalProfileUserHandle,
false);
- if (shouldShowTabs()) {
+ if (hasWorkProfile()) {
if (mWorkPackageMonitor == null) {
mWorkPackageMonitor = createPackageMonitor(
mMultiProfilePagerAdapter.getWorkListAdapter());
@@ -1291,7 +1291,7 @@ public class ResolverActivity extends FragmentActivity implements
}
WorkProfileAvailabilityManager workProfileAvailabilityManager =
mLogic.getWorkProfileAvailabilityManager();
- if (shouldShowTabs() && workProfileAvailabilityManager.isWaitingToEnableWorkProfile()) {
+ if (hasWorkProfile() && workProfileAvailabilityManager.isWaitingToEnableWorkProfile()) {
if (workProfileAvailabilityManager.isQuietModeEnabled()) {
workProfileAvailabilityManager.markWorkProfileEnabledBroadcastReceived();
}
@@ -1305,7 +1305,7 @@ public class ResolverActivity extends FragmentActivity implements
super.onStart();
this.getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
- if (shouldShowTabs()) {
+ if (hasWorkProfile()) {
mLogic.getWorkProfileAvailabilityManager().registerWorkProfileStateReceiver(this);
}
}
@@ -1510,6 +1510,7 @@ public class ResolverActivity extends FragmentActivity implements
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.
+ // To date, we really only care about "partially rebuilding" tabs for work and/or personal.
boolean rebuildCompleted = mMultiProfilePagerAdapter.rebuildTabs(shouldShowTabs());
if (shouldUseMiniResolver()) {
@@ -1540,12 +1541,25 @@ public class ResolverActivity extends FragmentActivity implements
mLayoutId = R.layout.miniresolver;
setContentView(mLayoutId);
- DisplayResolveInfo sameProfileResolveInfo =
- mMultiProfilePagerAdapter.getActiveListAdapter().getFirstDisplayResolveInfo();
+ // TODO: try to dedupe and use the pager's `getActiveProfile()` instead of the activity
+ // `getCurrentProfile()` (or align them if they're not currently equivalent). If they truly
+ // need to be distinct here, then `getCurrentProfile()` should at *least* get a more
+ // specific name -- but note that checking `getCurrentProfile()` here, then following
+ // `getActiveProfile()` to find the "in/active adapter," is exactly the legacy behavior.
boolean inWorkProfile = getCurrentProfile() == PROFILE_WORK;
- final ResolverListAdapter inactiveAdapter =
- mMultiProfilePagerAdapter.getInactiveListAdapter();
+ ResolverListAdapter sameProfileAdapter =
+ (mMultiProfilePagerAdapter.getActiveProfile() == PROFILE_PERSONAL)
+ ? mMultiProfilePagerAdapter.getPersonalListAdapter()
+ : mMultiProfilePagerAdapter.getWorkListAdapter();
+
+ ResolverListAdapter inactiveAdapter =
+ (mMultiProfilePagerAdapter.getActiveProfile() == PROFILE_PERSONAL)
+ ? mMultiProfilePagerAdapter.getWorkListAdapter()
+ : mMultiProfilePagerAdapter.getPersonalListAdapter();
+
+ DisplayResolveInfo sameProfileResolveInfo = sameProfileAdapter.getFirstDisplayResolveInfo();
+
final DisplayResolveInfo otherProfileResolveInfo =
inactiveAdapter.getFirstDisplayResolveInfo();
@@ -1584,24 +1598,36 @@ public class ResolverActivity extends FragmentActivity implements
});
}
+ private boolean isTwoPagePersonalAndWorkConfiguration() {
+ return (mMultiProfilePagerAdapter.getCount() == 2)
+ && mMultiProfilePagerAdapter.hasPageForProfile(PROFILE_PERSONAL)
+ && mMultiProfilePagerAdapter.hasPageForProfile(PROFILE_WORK);
+ }
+
/**
* Mini resolver should be used when all of the following are true:
* 1. This is the intent picker (ResolverActivity).
- * 2. This profile only has web browser matches.
- * 3. The other profile has a single non-browser match.
+ * 2. There are exactly two tabs, for the "personal" and "work" profiles.
+ * 3. This profile only has web browser matches.
+ * 4. The other profile has a single non-browser match.
*/
private boolean shouldUseMiniResolver() {
if (!mIsIntentPicker) {
return false;
}
- if (mMultiProfilePagerAdapter.getActiveListAdapter() == null
- || mMultiProfilePagerAdapter.getInactiveListAdapter() == null) {
+ if (!isTwoPagePersonalAndWorkConfiguration()) {
return false;
}
+
ResolverListAdapter sameProfileAdapter =
- mMultiProfilePagerAdapter.getActiveListAdapter();
+ (mMultiProfilePagerAdapter.getActiveProfile() == PROFILE_PERSONAL)
+ ? mMultiProfilePagerAdapter.getPersonalListAdapter()
+ : mMultiProfilePagerAdapter.getWorkListAdapter();
+
ResolverListAdapter otherProfileAdapter =
- mMultiProfilePagerAdapter.getInactiveListAdapter();
+ (mMultiProfilePagerAdapter.getActiveProfile() == PROFILE_PERSONAL)
+ ? mMultiProfilePagerAdapter.getWorkListAdapter()
+ : mMultiProfilePagerAdapter.getPersonalListAdapter();
if (sameProfileAdapter.getDisplayResolveInfoCount() == 0) {
Log.d(TAG, "No targets in the current profile");
@@ -1661,10 +1687,7 @@ public class ResolverActivity extends FragmentActivity implements
int numberOfProfiles = mMultiProfilePagerAdapter.getItemCount();
if (numberOfProfiles == 1 && maybeAutolaunchIfSingleTarget()) {
return true;
- } else if (numberOfProfiles == 2
- && mMultiProfilePagerAdapter.getActiveListAdapter().isTabLoaded()
- && mMultiProfilePagerAdapter.getInactiveListAdapter().isTabLoaded()
- && maybeAutolaunchIfCrossProfileSupported()) {
+ } else if (maybeAutolaunchIfCrossProfileSupported()) {
// TODO(b/280988288): If the ChooserActivity is shown we should consider showing the
// correct intent-picker UIs (e.g., mini-resolver) if it was launched without
// ACTION_SEND.
@@ -1695,33 +1718,48 @@ public class ResolverActivity extends FragmentActivity implements
}
/**
- * When we have a personal and a work profile, we auto launch in the following scenario:
+ * When we have just a personal and a work profile, we auto launch in the following scenario:
* - There is 1 resolved target on each profile
* - That target is the same app on both profiles
* - The target app has permission to communicate cross profiles
* - The target app has declared it supports cross-profile communication via manifest metadata
*/
private boolean maybeAutolaunchIfCrossProfileSupported() {
- ResolverListAdapter activeListAdapter = mMultiProfilePagerAdapter.getActiveListAdapter();
- int count = activeListAdapter.getUnfilteredCount();
- if (count != 1) {
+ if (!isTwoPagePersonalAndWorkConfiguration()) {
return false;
}
+
+ ResolverListAdapter activeListAdapter =
+ (mMultiProfilePagerAdapter.getActiveProfile() == PROFILE_PERSONAL)
+ ? mMultiProfilePagerAdapter.getPersonalListAdapter()
+ : mMultiProfilePagerAdapter.getWorkListAdapter();
+
ResolverListAdapter inactiveListAdapter =
- mMultiProfilePagerAdapter.getInactiveListAdapter();
- if (inactiveListAdapter.getUnfilteredCount() != 1) {
+ (mMultiProfilePagerAdapter.getActiveProfile() == PROFILE_PERSONAL)
+ ? mMultiProfilePagerAdapter.getWorkListAdapter()
+ : mMultiProfilePagerAdapter.getPersonalListAdapter();
+
+ if (!activeListAdapter.isTabLoaded() || !inactiveListAdapter.isTabLoaded()) {
return false;
}
- TargetInfo activeProfileTarget = activeListAdapter
- .targetInfoForPosition(0, false);
+
+ if ((activeListAdapter.getUnfilteredCount() != 1)
+ || (inactiveListAdapter.getUnfilteredCount() != 1)) {
+ return false;
+ }
+
+ TargetInfo activeProfileTarget = activeListAdapter.targetInfoForPosition(0, false);
TargetInfo inactiveProfileTarget = inactiveListAdapter.targetInfoForPosition(0, false);
- if (!Objects.equals(activeProfileTarget.getResolvedComponentName(),
+ if (!Objects.equals(
+ activeProfileTarget.getResolvedComponentName(),
inactiveProfileTarget.getResolvedComponentName())) {
return false;
}
+
if (!shouldAutoLaunchSingleChoice(activeProfileTarget)) {
return false;
}
+
String packageName = activeProfileTarget.getResolvedComponentName().getPackageName();
if (!canAppInteractCrossProfiles(packageName)) {
return false;