Merge changes from topic "AppCloningXSharesheet-master"
* changes:
Swithing to ResolveInfo.userHandle in Sharesheet.
Include cloned apps in system sharesheet.
diff --git a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
index 2316738..5e2eceb 100644
--- a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
+++ b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
@@ -16,8 +16,8 @@
package com.android.internal.app;
import android.annotation.IntDef;
-import android.annotation.Nullable;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.AppGlobals;
import android.content.ContentResolver;
@@ -60,16 +60,19 @@
private Set<Integer> mLoadedPages;
private final EmptyStateProvider mEmptyStateProvider;
private final UserHandle mWorkProfileUserHandle;
+ private final UserHandle mCloneUserHandle;
private final QuietModeManager mQuietModeManager;
AbstractMultiProfilePagerAdapter(Context context, int currentPage,
EmptyStateProvider emptyStateProvider,
QuietModeManager quietModeManager,
- UserHandle workProfileUserHandle) {
+ UserHandle workProfileUserHandle,
+ UserHandle cloneUserHandle) {
mContext = Objects.requireNonNull(context);
mCurrentPage = currentPage;
mLoadedPages = new HashSet<>();
mWorkProfileUserHandle = workProfileUserHandle;
+ mCloneUserHandle = cloneUserHandle;
mEmptyStateProvider = emptyStateProvider;
mQuietModeManager = quietModeManager;
}
@@ -160,6 +163,10 @@
return null;
}
+ public UserHandle getCloneUserHandle() {
+ return mCloneUserHandle;
+ }
+
/**
* Returns the {@link ProfileDescriptor} relevant to the given <code>pageIndex</code>.
* <ul>
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 9f283d4..791819b 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -873,7 +873,7 @@
return new NoCrossProfileEmptyStateProvider(getPersonalProfileUserHandle(),
noWorkToPersonalEmptyState, noPersonalToWorkEmptyState,
- createCrossProfileIntentsChecker(), createMyUserIdProvider());
+ createCrossProfileIntentsChecker(), getTabOwnerUserHandleForLaunch());
}
private ChooserMultiProfilePagerAdapter createChooserMultiProfilePagerAdapterForOneProfile(
@@ -886,13 +886,14 @@
initialIntents,
rList,
filterLastUsed,
- /* userHandle */ UserHandle.of(UserHandle.myUserId()));
+ /* userHandle */ getPersonalProfileUserHandle());
return new ChooserMultiProfilePagerAdapter(
/* context */ this,
adapter,
createEmptyStateProvider(/* workProfileUserHandle= */ null),
mQuietModeManager,
/* workProfileUserHandle= */ null,
+ getCloneProfileUserHandle(),
mMaxTargetsPerRow);
}
@@ -923,13 +924,14 @@
mQuietModeManager,
selectedProfile,
getWorkProfileUserHandle(),
+ getCloneProfileUserHandle(),
mMaxTargetsPerRow);
}
private int findSelectedProfile() {
int selectedProfile = getSelectedProfileExtra();
if (selectedProfile == -1) {
- selectedProfile = getProfileForUser(getUser());
+ selectedProfile = getProfileForUser(getTabOwnerUserHandleForLaunch());
}
return selectedProfile;
}
@@ -1800,8 +1802,12 @@
targetList = new ArrayList<DisplayResolveInfo>();
targetList.add((DisplayResolveInfo) targetInfo);
}
+ // Adding userHandle from ResolveInfo allows the app icon in Dialog Box to be
+ // resolved correctly.
bundle.putParcelable(ChooserTargetActionsDialogFragment.USER_HANDLE_KEY,
- mChooserMultiProfilePagerAdapter.getCurrentUserHandle());
+ getResolveInfoUserHandle(
+ targetInfo.getResolveInfo(),
+ mChooserMultiProfilePagerAdapter.getCurrentUserHandle()));
bundle.putParcelableArrayList(ChooserTargetActionsDialogFragment.TARGET_INFOS_KEY,
targetList);
fragment.setArguments(bundle);
@@ -1865,8 +1871,11 @@
if (!mti.hasSelected()) {
ChooserStackedAppDialogFragment f = new ChooserStackedAppDialogFragment();
Bundle b = new Bundle();
+ // Add userHandle based badge to the stackedAppDialogBox.
b.putParcelable(ChooserTargetActionsDialogFragment.USER_HANDLE_KEY,
- mChooserMultiProfilePagerAdapter.getCurrentUserHandle());
+ getResolveInfoUserHandle(
+ targetInfo.getResolveInfo(),
+ mChooserMultiProfilePagerAdapter.getCurrentUserHandle()));
b.putObject(ChooserStackedAppDialogFragment.MULTI_DRI_KEY,
mti);
b.putInt(ChooserStackedAppDialogFragment.WHICH_KEY, which);
@@ -2433,15 +2442,24 @@
* Sort intents alphabetically based on display label.
*/
static class AzInfoComparator implements Comparator<DisplayResolveInfo> {
- Collator mCollator;
+ Comparator<DisplayResolveInfo> mComparator;
AzInfoComparator(Context context) {
- mCollator = Collator.getInstance(context.getResources().getConfiguration().locale);
+ Collator collator = Collator
+ .getInstance(context.getResources().getConfiguration().locale);
+ // Adding two stage comparator, first stage compares using displayLabel, next stage
+ // compares using resolveInfo.userHandle
+ mComparator = Comparator.comparing(DisplayResolveInfo::getDisplayLabel, collator)
+ .thenComparingInt(displayResolveInfo ->
+ getResolveInfoUserHandle(
+ displayResolveInfo.getResolveInfo(),
+ // TODO: User resolveInfo.userHandle, once its available.
+ UserHandle.SYSTEM).getIdentifier());
}
@Override
public int compare(
DisplayResolveInfo lhsp, DisplayResolveInfo rhsp) {
- return mCollator.compare(lhsp.getDisplayLabel(), rhsp.getDisplayLabel());
+ return mComparator.compare(lhsp, rhsp);
}
}
@@ -2466,9 +2484,10 @@
String referrerPackageName,
int launchedFromUid,
UserHandle userId,
- AbstractResolverComparator resolverComparator) {
+ AbstractResolverComparator resolverComparator,
+ UserHandle queryIntentsAsUser) {
super(context, pm, targetIntent, referrerPackageName, launchedFromUid, userId,
- resolverComparator);
+ resolverComparator, queryIntentsAsUser);
}
@Override
@@ -2533,6 +2552,7 @@
getReferrerPackageName(), null, getChooserActivityLogger());
}
+ UserHandle queryIntentsUser = getQueryIntentsUser(userHandle);
return new ChooserListController(
this,
mPm,
@@ -2540,7 +2560,8 @@
getReferrerPackageName(),
mLaunchedFromUid,
userHandle,
- resolverComparator);
+ resolverComparator,
+ queryIntentsUser == null ? userHandle : queryIntentsUser);
}
@VisibleForTesting
@@ -2741,17 +2762,16 @@
}
/**
- * Returns {@link #PROFILE_PERSONAL}, {@link #PROFILE_WORK}, or -1 if the given user handle
- * does not match either the personal or work user handle.
+ * Returns {@link #PROFILE_WORK}, if the given user handle matches work user handle.
+ * Returns {@link #PROFILE_PERSONAL}, otherwise.
**/
private int getProfileForUser(UserHandle currentUserHandle) {
- if (currentUserHandle.equals(getPersonalProfileUserHandle())) {
- return PROFILE_PERSONAL;
- } else if (currentUserHandle.equals(getWorkProfileUserHandle())) {
+ if (currentUserHandle.equals(getWorkProfileUserHandle())) {
return PROFILE_WORK;
}
- Log.e(TAG, "User " + currentUserHandle + " does not belong to a personal or work profile.");
- return -1;
+ // We return personal profile, as it is the default when there is no work profile, personal
+ // profile represents rootUser, clonedUser & secondaryUser, covering all use cases.
+ return PROFILE_PERSONAL;
}
private ViewGroup getActiveEmptyStateView() {
diff --git a/core/java/com/android/internal/app/ChooserListAdapter.java b/core/java/com/android/internal/app/ChooserListAdapter.java
index 2ae2c09..e0568cf 100644
--- a/core/java/com/android/internal/app/ChooserListAdapter.java
+++ b/core/java/com/android/internal/app/ChooserListAdapter.java
@@ -197,6 +197,7 @@
ri.nonLocalizedLabel = li.getNonLocalizedLabel();
ri.icon = li.getIconResource();
ri.iconResourceId = ri.icon;
+ ri.userHandle = getUserHandle();
}
if (userManager.isManagedProfile()) {
ri.noResourceId = true;
@@ -351,7 +352,9 @@
Map<String, DisplayResolveInfo> consolidated = new HashMap<>();
for (DisplayResolveInfo info : allTargets) {
String resolvedTarget = info.getResolvedComponentName().getPackageName()
- + '#' + info.getDisplayLabel();
+ + '#' + info.getDisplayLabel()
+ + '#' + ResolverActivity.getResolveInfoUserHandle(
+ info.getResolveInfo(), getUserHandle()).getIdentifier();
DisplayResolveInfo multiDri = consolidated.get(resolvedTarget);
if (multiDri == null) {
consolidated.put(resolvedTarget, info);
@@ -367,7 +370,8 @@
}
List<DisplayResolveInfo> groupedTargets = new ArrayList<>();
groupedTargets.addAll(consolidated.values());
- Collections.sort(groupedTargets, new ChooserActivity.AzInfoComparator(mContext));
+ Collections.sort(groupedTargets,
+ new ChooserActivity.AzInfoComparator(mContext));
return groupedTargets;
}
@Override
diff --git a/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java
index 0509b67..f56f818 100644
--- a/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java
+++ b/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java
@@ -45,9 +45,10 @@
EmptyStateProvider emptyStateProvider,
QuietModeManager quietModeManager,
UserHandle workProfileUserHandle,
+ UserHandle cloneUserHandle,
int maxTargetsPerRow) {
super(context, /* currentPage */ 0, emptyStateProvider, quietModeManager,
- workProfileUserHandle);
+ workProfileUserHandle, cloneUserHandle);
mItems = new ChooserProfileDescriptor[] {
createProfileDescriptor(adapter)
};
@@ -61,9 +62,10 @@
QuietModeManager quietModeManager,
@Profile int defaultProfile,
UserHandle workProfileUserHandle,
+ UserHandle cloneUserHandle,
int maxTargetsPerRow) {
super(context, /* currentPage */ defaultProfile, emptyStateProvider,
- quietModeManager, workProfileUserHandle);
+ quietModeManager, workProfileUserHandle, cloneUserHandle);
mItems = new ChooserProfileDescriptor[] {
createProfileDescriptor(personalAdapter),
createProfileDescriptor(workAdapter)
@@ -110,11 +112,12 @@
@Override
@Nullable
ChooserListAdapter getListAdapterForUserHandle(UserHandle userHandle) {
- if (getActiveListAdapter().getUserHandle().equals(userHandle)) {
- return getActiveListAdapter();
- } else if (getInactiveListAdapter() != null
- && getInactiveListAdapter().getUserHandle().equals(userHandle)) {
- return getInactiveListAdapter();
+ if (getPersonalListAdapter().getUserHandle().equals(userHandle)
+ || userHandle.equals(getCloneUserHandle())) {
+ return getPersonalListAdapter();
+ } else if (getWorkListAdapter() != null
+ && getWorkListAdapter().getUserHandle().equals(userHandle)) {
+ return getWorkListAdapter();
}
return null;
}
@@ -153,13 +156,13 @@
}
@Override
- public ResolverListAdapter getPersonalListAdapter() {
+ public ChooserListAdapter getPersonalListAdapter() {
return getAdapterForIndex(PROFILE_PERSONAL).getListAdapter();
}
@Override
@Nullable
- public ResolverListAdapter getWorkListAdapter() {
+ public ChooserListAdapter getWorkListAdapter() {
return getAdapterForIndex(PROFILE_WORK).getListAdapter();
}
diff --git a/core/java/com/android/internal/app/NoAppsAvailableEmptyStateProvider.java b/core/java/com/android/internal/app/NoAppsAvailableEmptyStateProvider.java
index 34249f2..747780b 100644
--- a/core/java/com/android/internal/app/NoAppsAvailableEmptyStateProvider.java
+++ b/core/java/com/android/internal/app/NoAppsAvailableEmptyStateProvider.java
@@ -28,10 +28,9 @@
import android.os.UserHandle;
import android.stats.devicepolicy.nano.DevicePolicyEnums;
+import com.android.internal.R;
import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyState;
import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyStateProvider;
-import com.android.internal.app.AbstractMultiProfilePagerAdapter.MyUserIdProvider;
-import com.android.internal.R;
import java.util.List;
@@ -50,16 +49,16 @@
@NonNull
private final String mMetricsCategory;
@NonNull
- private final MyUserIdProvider mMyUserIdProvider;
+ private final UserHandle mTabOwnerUserHandleForLaunch;
public NoAppsAvailableEmptyStateProvider(Context context, UserHandle workProfileUserHandle,
UserHandle personalProfileUserHandle, String metricsCategory,
- MyUserIdProvider myUserIdProvider) {
+ UserHandle tabOwnerUserHandleForLaunch) {
mContext = context;
mWorkProfileUserHandle = workProfileUserHandle;
mPersonalProfileUserHandle = personalProfileUserHandle;
mMetricsCategory = metricsCategory;
- mMyUserIdProvider = myUserIdProvider;
+ mTabOwnerUserHandleForLaunch = tabOwnerUserHandleForLaunch;
}
@Nullable
@@ -69,7 +68,7 @@
UserHandle listUserHandle = resolverListAdapter.getUserHandle();
if (mWorkProfileUserHandle != null
- && (mMyUserIdProvider.getMyUserId() == listUserHandle.getIdentifier()
+ && (mTabOwnerUserHandleForLaunch.equals(listUserHandle)
|| !hasAppsInOtherProfile(resolverListAdapter))) {
String title;
@@ -102,7 +101,7 @@
return false;
}
List<ResolverActivity.ResolvedComponentInfo> resolversForIntent =
- adapter.getResolversForUser(UserHandle.of(mMyUserIdProvider.getMyUserId()));
+ adapter.getResolversForUser(mTabOwnerUserHandleForLaunch);
for (ResolverActivity.ResolvedComponentInfo info : resolversForIntent) {
ResolveInfo resolveInfo = info.getResolveInfoAt(0);
if (resolveInfo.targetUserId != UserHandle.USER_CURRENT) {
diff --git a/core/java/com/android/internal/app/NoCrossProfileEmptyStateProvider.java b/core/java/com/android/internal/app/NoCrossProfileEmptyStateProvider.java
index 2e7d5bf..2046bfc 100644
--- a/core/java/com/android/internal/app/NoCrossProfileEmptyStateProvider.java
+++ b/core/java/com/android/internal/app/NoCrossProfileEmptyStateProvider.java
@@ -27,7 +27,6 @@
import com.android.internal.app.AbstractMultiProfilePagerAdapter.CrossProfileIntentsChecker;
import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyState;
import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyStateProvider;
-import com.android.internal.app.AbstractMultiProfilePagerAdapter.MyUserIdProvider;
/**
* Empty state provider that does not allow cross profile sharing, it will return a blocker
@@ -39,28 +38,28 @@
private final EmptyState mNoWorkToPersonalEmptyState;
private final EmptyState mNoPersonalToWorkEmptyState;
private final CrossProfileIntentsChecker mCrossProfileIntentsChecker;
- private final MyUserIdProvider mUserIdProvider;
+ private final UserHandle mTabOwnerUserHandleForLaunch;
public NoCrossProfileEmptyStateProvider(UserHandle personalUserHandle,
EmptyState noWorkToPersonalEmptyState,
EmptyState noPersonalToWorkEmptyState,
CrossProfileIntentsChecker crossProfileIntentsChecker,
- MyUserIdProvider myUserIdProvider) {
+ UserHandle preselectedTabOwnerUserHandle) {
mPersonalProfileUserHandle = personalUserHandle;
mNoWorkToPersonalEmptyState = noWorkToPersonalEmptyState;
mNoPersonalToWorkEmptyState = noPersonalToWorkEmptyState;
mCrossProfileIntentsChecker = crossProfileIntentsChecker;
- mUserIdProvider = myUserIdProvider;
+ mTabOwnerUserHandleForLaunch = preselectedTabOwnerUserHandle;
}
@Nullable
@Override
public EmptyState getEmptyState(ResolverListAdapter resolverListAdapter) {
boolean shouldShowBlocker =
- mUserIdProvider.getMyUserId() != resolverListAdapter.getUserHandle().getIdentifier()
+ !mTabOwnerUserHandleForLaunch.equals(resolverListAdapter.getUserHandle())
&& !mCrossProfileIntentsChecker
.hasCrossProfileIntents(resolverListAdapter.getIntents(),
- mUserIdProvider.getMyUserId(),
+ mTabOwnerUserHandleForLaunch.getIdentifier(),
resolverListAdapter.getUserHandle().getIdentifier());
if (!shouldShowBlocker) {
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index f098e2c..ddfc238 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -166,6 +166,7 @@
@UnsupportedAppUsage
protected PackageManager mPm;
protected int mLaunchedFromUid;
+ private UserHandle mLaunchedFromUserHandle;
private static final String TAG = "ResolverActivity";
private static final boolean DEBUG = false;
@@ -229,12 +230,15 @@
private BroadcastReceiver mWorkProfileStateReceiver;
private UserHandle mHeaderCreatorUser;
-
+ private UserHandle mPersonalProfileUserHandle;
private UserHandle mWorkProfileUserHandle;
@Nullable
private OnSwitchOnWorkSelectedListener mOnSwitchOnWorkSelectedListener;
+ private UserHandle mCloneProfileUserHandle;
+ private UserHandle mTabOwnerUserHandleForLaunch;
+
protected final LatencyTracker mLatencyTracker = getLatencyTracker();
private LatencyTracker getLatencyTracker() {
@@ -400,6 +404,7 @@
setProfileSwitchMessage(intent.getContentUserHint());
mLaunchedFromUid = getLaunchedFromUid();
+ mLaunchedFromUserHandle = UserHandle.getUserHandleForUid(mLaunchedFromUid);
if (mLaunchedFromUid < 0 || UserHandle.isIsolated(mLaunchedFromUid)) {
// Gulp!
finish();
@@ -416,15 +421,21 @@
mDefaultTitleResId = defaultTitleRes;
mSupportsAlwaysUseOption = supportsAlwaysUseOption;
+ mPersonalProfileUserHandle = fetchPersonalProfileUserHandle();
mWorkProfileUserHandle = fetchWorkProfileUserProfile();
+ mCloneProfileUserHandle = fetchCloneProfileUserHandle();
+ mTabOwnerUserHandleForLaunch = fetchTabOwnerUserHandleForLaunch();
// The last argument of createResolverListAdapter is whether to do special handling
// 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.
+ // 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.
boolean filterLastUsed = mSupportsAlwaysUseOption && !isVoiceInteraction()
- && !shouldShowTabs();
+ && !shouldShowTabs() && !hasCloneProfile();
mMultiProfilePagerAdapter = createMultiProfilePagerAdapter(initialIntents, rList, filterLastUsed);
if (configureContentView()) {
return;
@@ -566,9 +577,12 @@
/* devicePolicyEventId= */ RESOLVER_EMPTY_STATE_NO_SHARING_TO_WORK,
/* devicePolicyEventCategory= */ ResolverActivity.METRICS_CATEGORY_RESOLVER);
- return new NoCrossProfileEmptyStateProvider(getPersonalProfileUserHandle(),
- noWorkToPersonalEmptyState, noPersonalToWorkEmptyState,
- createCrossProfileIntentsChecker(), createMyUserIdProvider());
+ return new NoCrossProfileEmptyStateProvider(
+ getPersonalProfileUserHandle(),
+ noWorkToPersonalEmptyState,
+ noPersonalToWorkEmptyState,
+ createCrossProfileIntentsChecker(),
+ getTabOwnerUserHandleForLaunch());
}
protected EmptyStateProvider createEmptyStateProvider(
@@ -589,7 +603,7 @@
workProfileUserHandle,
getPersonalProfileUserHandle(),
getMetricsCategory(),
- createMyUserIdProvider()
+ getTabOwnerUserHandleForLaunch()
);
// Return composite provider, the order matters (the higher, the more priority)
@@ -609,14 +623,15 @@
initialIntents,
rList,
filterLastUsed,
- /* userHandle */ UserHandle.of(UserHandle.myUserId()));
+ /* userHandle */ getPersonalProfileUserHandle());
QuietModeManager quietModeManager = createQuietModeManager();
return new ResolverMultiProfilePagerAdapter(
/* context */ this,
adapter,
createEmptyStateProvider(/* workProfileUserHandle= */ null),
quietModeManager,
- /* workProfileUserHandle= */ null);
+ /* workProfileUserHandle= */ null,
+ getCloneProfileUserHandle());
}
private UserHandle getIntentUser() {
@@ -634,7 +649,7 @@
// this happens, we check for it here and set the current profile's tab.
int selectedProfile = getCurrentProfile();
UserHandle intentUser = getIntentUser();
- if (!getUser().equals(intentUser)) {
+ if (!getTabOwnerUserHandleForLaunch().equals(intentUser)) {
if (getPersonalProfileUserHandle().equals(intentUser)) {
selectedProfile = PROFILE_PERSONAL;
} else if (getWorkProfileUserHandle().equals(intentUser)) {
@@ -674,7 +689,8 @@
createEmptyStateProvider(getWorkProfileUserHandle()),
quietModeManager,
selectedProfile,
- getWorkProfileUserHandle());
+ getWorkProfileUserHandle(),
+ getCloneProfileUserHandle());
}
protected int appliedThemeResId() {
@@ -701,20 +717,35 @@
}
protected @Profile int getCurrentProfile() {
- return (UserHandle.myUserId() == UserHandle.USER_SYSTEM ? PROFILE_PERSONAL : PROFILE_WORK);
+ return (UserHandle.myUserId() == getPersonalProfileUserHandle().getIdentifier()
+ ? PROFILE_PERSONAL : PROFILE_WORK);
}
protected UserHandle getPersonalProfileUserHandle() {
- return UserHandle.of(ActivityManager.getCurrentUser());
+ return mPersonalProfileUserHandle;
}
protected @Nullable UserHandle getWorkProfileUserHandle() {
return mWorkProfileUserHandle;
}
+ protected @Nullable UserHandle getCloneProfileUserHandle() {
+ return mCloneProfileUserHandle;
+ }
+
+ protected UserHandle getTabOwnerUserHandleForLaunch() {
+ return mTabOwnerUserHandleForLaunch;
+ }
+
+ protected UserHandle fetchPersonalProfileUserHandle() {
+ mPersonalProfileUserHandle = UserHandle.of(ActivityManager.getCurrentUser());
+ return mPersonalProfileUserHandle;
+ }
+
protected @Nullable UserHandle fetchWorkProfileUserProfile() {
mWorkProfileUserHandle = null;
UserManager userManager = getSystemService(UserManager.class);
- for (final UserInfo userInfo : userManager.getProfiles(ActivityManager.getCurrentUser())) {
+ for (final UserInfo userInfo : userManager
+ .getProfiles(mPersonalProfileUserHandle.getIdentifier())) {
if (userInfo.isManagedProfile()) {
mWorkProfileUserHandle = userInfo.getUserHandle();
}
@@ -722,10 +753,38 @@
return mWorkProfileUserHandle;
}
+ protected @Nullable UserHandle fetchCloneProfileUserHandle() {
+ mCloneProfileUserHandle = null;
+ UserManager userManager = getSystemService(UserManager.class);
+ for (final UserInfo userInfo :
+ userManager.getProfiles(mPersonalProfileUserHandle.getIdentifier())) {
+ if (userInfo.isCloneProfile()) {
+ mCloneProfileUserHandle = userInfo.getUserHandle();
+ }
+ }
+ return mCloneProfileUserHandle;
+ }
+
+ private UserHandle fetchTabOwnerUserHandleForLaunch() {
+ if (isLaunchedAsCloneProfile()) {
+ return getPersonalProfileUserHandle();
+ }
+ return mLaunchedFromUserHandle;
+ }
+
private boolean hasWorkProfile() {
return getWorkProfileUserHandle() != null;
}
+ private boolean hasCloneProfile() {
+ return getCloneProfileUserHandle() != null;
+ }
+
+ private boolean isLaunchedAsCloneProfile() {
+ return hasCloneProfile()
+ && (UserHandle.myUserId() == getCloneProfileUserHandle().getIdentifier());
+ }
+
protected boolean shouldShowTabs() {
return hasWorkProfile() && ENABLE_TABBED_VIEW;
}
@@ -1123,6 +1182,14 @@
mAlwaysButton.setEnabled(false);
return;
}
+ // In case of clonedProfile being active, we do not allow the 'Always' option in the
+ // disambiguation dialog of Personal Profile as the package manager cannot distinguish
+ // between cross-profile preferred activities.
+ if (hasCloneProfile() && !mMultiProfilePagerAdapter
+ .getCurrentUserHandle().equals(mWorkProfileUserHandle)) {
+ mAlwaysButton.setEnabled(false);
+ return;
+ }
boolean enabled = false;
ResolveInfo ri = null;
if (hasValidSelection) {
@@ -1431,17 +1498,14 @@
return true;
}
- @VisibleForTesting
- public void safelyStartActivity(TargetInfo cti) {
- // We're dispatching intents that might be coming from legacy apps, so
- // don't kill ourselves.
- StrictMode.disableDeathOnFileUriExposure();
- try {
- UserHandle currentUserHandle = mMultiProfilePagerAdapter.getCurrentUserHandle();
- safelyStartActivityInternal(cti, currentUserHandle, null);
- } finally {
- StrictMode.enableDeathOnFileUriExposure();
- }
+ /** Start the activity specified by the {@link TargetInfo}.*/
+ public final void safelyStartActivity(TargetInfo cti) {
+ // In case cloned apps are present, we would want to start those apps in cloned user
+ // space, which will not be same as adaptor's userHandle. resolveInfo.userHandle
+ // identifies the correct user space in such cases.
+ UserHandle activityUserHandle = getResolveInfoUserHandle(
+ cti.getResolveInfo(), mMultiProfilePagerAdapter.getCurrentUserHandle());
+ safelyStartActivityAsUser(cti, activityUserHandle, null);
}
/**
@@ -1449,11 +1513,12 @@
* @param cti TargetInfo to be launched.
* @param user User to launch this activity as.
*/
- @VisibleForTesting
- public void safelyStartActivityAsUser(TargetInfo cti, UserHandle user) {
+ public final void safelyStartActivityAsUser(TargetInfo cti, UserHandle user) {
safelyStartActivityAsUser(cti, user, null);
}
+ // TODO: Make method public final.
+ @VisibleForTesting
protected void safelyStartActivityAsUser(
TargetInfo cti, UserHandle user, @Nullable Bundle options) {
// We're dispatching intents that might be coming from legacy apps, so
@@ -1466,7 +1531,8 @@
}
}
- private void safelyStartActivityInternal(
+ @VisibleForTesting
+ protected void safelyStartActivityInternal(
TargetInfo cti, UserHandle user, @Nullable Bundle options) {
// If the target is suspended, the activity will not be successfully launched.
// Do not unregister from package manager updates in this case
@@ -1550,13 +1616,15 @@
@VisibleForTesting
protected ResolverListController createListController(UserHandle userHandle) {
+ UserHandle queryIntentsUser = getQueryIntentsUser(userHandle);
return new ResolverListController(
this,
mPm,
getTargetIntent(),
getReferrerPackageName(),
mLaunchedFromUid,
- userHandle);
+ userHandle,
+ queryIntentsUser);
}
/**
@@ -2170,16 +2238,10 @@
public boolean useLayoutWithDefault() {
// We only use the default app layout when the profile of the active user has a
// filtered item. We always show the same default app even in the inactive user profile.
- boolean currentUserAdapterHasFilteredItem;
- if (mMultiProfilePagerAdapter.getCurrentUserHandle().getIdentifier()
- == UserHandle.myUserId()) {
- currentUserAdapterHasFilteredItem =
- mMultiProfilePagerAdapter.getActiveListAdapter().hasFilteredItem();
- } else {
- currentUserAdapterHasFilteredItem =
- mMultiProfilePagerAdapter.getInactiveListAdapter().hasFilteredItem();
- }
- return mSupportsAlwaysUseOption && currentUserAdapterHasFilteredItem;
+ boolean adapterForCurrentUserHasFilteredItem =
+ mMultiProfilePagerAdapter.getListAdapterForUserHandle(
+ getTabOwnerUserHandleForLaunch()).hasFilteredItem();
+ return mSupportsAlwaysUseOption && adapterForCurrentUserHasFilteredItem;
}
/**
@@ -2198,7 +2260,14 @@
return lhs == null ? rhs == null
: lhs.activityInfo == null ? rhs.activityInfo == null
: Objects.equals(lhs.activityInfo.name, rhs.activityInfo.name)
- && Objects.equals(lhs.activityInfo.packageName, rhs.activityInfo.packageName);
+ && Objects.equals(lhs.activityInfo.packageName, rhs.activityInfo.packageName)
+ // Comparing against resolveInfo.userHandle in case cloned apps are present,
+ // as they will have the same activityInfo.
+ && Objects.equals(
+ getResolveInfoUserHandle(lhs,
+ mMultiProfilePagerAdapter.getActiveListAdapter().getUserHandle()),
+ getResolveInfoUserHandle(rhs,
+ mMultiProfilePagerAdapter.getActiveListAdapter().getUserHandle()));
}
protected String getMetricsCategory() {
@@ -2439,4 +2508,30 @@
}
protected void maybeLogProfileChange() {}
+
+ /**
+ * Returns the {@link UserHandle} to use when querying resolutions for intents in a
+ * {@link ResolverListController} configured for the provided {@code userHandle}.
+ */
+ protected final UserHandle getQueryIntentsUser(UserHandle userHandle) {
+ // In case launching app is in clonedProfile, and we are building the personal tab, intent
+ // resolution will be attempted as clonedUser instead of user 0. This is because intent
+ // resolution from user 0 and clonedUser is not guaranteed to return same results.
+ // We do not care about the case when personal adapter is started with non-root user
+ // (secondary user case), as clone profile is guaranteed to be non-active in that case.
+ UserHandle queryIntentsUser = userHandle;
+ if (isLaunchedAsCloneProfile() && userHandle.equals(getPersonalProfileUserHandle())) {
+ queryIntentsUser = getCloneProfileUserHandle();
+ }
+ return queryIntentsUser;
+ }
+
+ /**
+ * This function is temporary in nature, and its usages will be replaced with just
+ * resolveInfo.userHandle, once it is available, once sharesheet is stable.
+ */
+ public static UserHandle getResolveInfoUserHandle(ResolveInfo resolveInfo,
+ UserHandle predictedHandle) {
+ return resolveInfo.userHandle;
+ }
}
diff --git a/core/java/com/android/internal/app/ResolverListAdapter.java b/core/java/com/android/internal/app/ResolverListAdapter.java
index 42b46cd..e3236ba 100644
--- a/core/java/com/android/internal/app/ResolverListAdapter.java
+++ b/core/java/com/android/internal/app/ResolverListAdapter.java
@@ -440,6 +440,7 @@
ri.nonLocalizedLabel = li.getNonLocalizedLabel();
ri.icon = li.getIconResource();
ri.iconResourceId = ri.icon;
+ ri.userHandle = getUserHandle();
}
if (userManager.isManagedProfile()) {
ri.noResourceId = true;
@@ -737,8 +738,10 @@
}
Drawable loadIconForResolveInfo(ResolveInfo ri) {
- // Load icons based on the current process. If in work profile icons should be badged.
- return makePresentationGetter(ri).getIcon(getUserHandle());
+ // Load icons based on userHandle from ResolveInfo. If in work profile/clone profile, icons
+ // should be badged.
+ return makePresentationGetter(ri)
+ .getIcon(ResolverActivity.getResolveInfoUserHandle(ri, getUserHandle()));
}
void loadFilteredItemIconTaskAsync(@NonNull ImageView iconView) {
diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java
index 8a2036a..5f90e73 100644
--- a/core/java/com/android/internal/app/ResolverListController.java
+++ b/core/java/com/android/internal/app/ResolverListController.java
@@ -60,6 +60,7 @@
private AbstractResolverComparator mResolverComparator;
private boolean isComputed = false;
+ private final UserHandle mQueryIntentsAsUser;
public ResolverListController(
Context context,
@@ -67,10 +68,11 @@
Intent targetIntent,
String referrerPackage,
int launchedFromUid,
- UserHandle userHandle) {
+ UserHandle userHandle,
+ UserHandle queryIntentsAsUser) {
this(context, pm, targetIntent, referrerPackage, launchedFromUid, userHandle,
new ResolverRankerServiceResolverComparator(
- context, targetIntent, referrerPackage, null, null));
+ context, targetIntent, referrerPackage, null, null), queryIntentsAsUser);
}
public ResolverListController(
@@ -80,7 +82,8 @@
String referrerPackage,
int launchedFromUid,
UserHandle userHandle,
- AbstractResolverComparator resolverComparator) {
+ AbstractResolverComparator resolverComparator,
+ UserHandle queryIntentsAsUser) {
mContext = context;
mpm = pm;
mLaunchedFromUid = launchedFromUid;
@@ -88,6 +91,7 @@
mReferrerPackage = referrerPackage;
mUserHandle = userHandle;
mResolverComparator = resolverComparator;
+ mQueryIntentsAsUser = queryIntentsAsUser;
}
@VisibleForTesting
@@ -113,7 +117,7 @@
boolean shouldGetOnlyDefaultActivities,
List<Intent> intents) {
return getResolversForIntentAsUser(shouldGetResolvedFilter, shouldGetActivityMetadata,
- shouldGetOnlyDefaultActivities, intents, mUserHandle);
+ shouldGetOnlyDefaultActivities, intents, mQueryIntentsAsUser);
}
public List<ResolverActivity.ResolvedComponentInfo> getResolversForIntentAsUser(
@@ -171,6 +175,10 @@
final int intoCount = into.size();
for (int i = 0; i < fromCount; i++) {
final ResolveInfo newInfo = from.get(i);
+ if (newInfo.userHandle == null) {
+ Log.w(TAG, "Skipping ResolveInfo with no userHandle: " + newInfo);
+ continue;
+ }
boolean found = false;
// Only loop to the end of into as it was before we started; no dupes in from.
for (int j = 0; j < intoCount; j++) {
diff --git a/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java
index 9922051..1ecaf21 100644
--- a/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java
+++ b/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java
@@ -41,9 +41,10 @@
ResolverListAdapter adapter,
EmptyStateProvider emptyStateProvider,
QuietModeManager quietModeManager,
- UserHandle workProfileUserHandle) {
+ UserHandle workProfileUserHandle,
+ UserHandle cloneUserHandle) {
super(context, /* currentPage */ 0, emptyStateProvider, quietModeManager,
- workProfileUserHandle);
+ workProfileUserHandle, cloneUserHandle);
mItems = new ResolverProfileDescriptor[] {
createProfileDescriptor(adapter)
};
@@ -55,9 +56,10 @@
EmptyStateProvider emptyStateProvider,
QuietModeManager quietModeManager,
@Profile int defaultProfile,
- UserHandle workProfileUserHandle) {
+ UserHandle workProfileUserHandle,
+ UserHandle cloneUserHandle) {
super(context, /* currentPage */ defaultProfile, emptyStateProvider, quietModeManager,
- workProfileUserHandle);
+ workProfileUserHandle, cloneUserHandle);
mItems = new ResolverProfileDescriptor[] {
createProfileDescriptor(personalAdapter),
createProfileDescriptor(workAdapter)
@@ -107,11 +109,12 @@
@Override
@Nullable
ResolverListAdapter getListAdapterForUserHandle(UserHandle userHandle) {
- if (getActiveListAdapter().getUserHandle().equals(userHandle)) {
- return getActiveListAdapter();
- } else if (getInactiveListAdapter() != null
- && getInactiveListAdapter().getUserHandle().equals(userHandle)) {
- return getInactiveListAdapter();
+ if (getPersonalListAdapter().getUserHandle().equals(userHandle)
+ || userHandle.equals(getCloneUserHandle())) {
+ return getPersonalListAdapter();
+ } else if (getWorkListAdapter() != null
+ && getWorkListAdapter().getUserHandle().equals(userHandle)) {
+ return getWorkListAdapter();
}
return null;
}
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityOverrideData.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityOverrideData.java
index eead4ed..5469843 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityOverrideData.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityOverrideData.java
@@ -29,7 +29,6 @@
import android.util.Pair;
import com.android.internal.app.AbstractMultiProfilePagerAdapter.CrossProfileIntentsChecker;
-import com.android.internal.app.AbstractMultiProfilePagerAdapter.MyUserIdProvider;
import com.android.internal.app.AbstractMultiProfilePagerAdapter.QuietModeManager;
import com.android.internal.app.chooser.TargetInfo;
import com.android.internal.logging.MetricsLogger;
@@ -71,13 +70,14 @@
public int alternateProfileSetting;
public Resources resources;
public UserHandle workProfileUserHandle;
+ public UserHandle cloneProfileUserHandle;
+ public UserHandle tabOwnerUserHandleForLaunch;
public boolean hasCrossProfileIntents;
public boolean isQuietModeEnabled;
public boolean isWorkProfileUserRunning;
public boolean isWorkProfileUserUnlocked;
public Integer myUserId;
public QuietModeManager mQuietModeManager;
- public MyUserIdProvider mMyUserIdProvider;
public CrossProfileIntentsChecker mCrossProfileIntentsChecker;
public PackageManager packageManager;
@@ -98,6 +98,8 @@
alternateProfileSetting = 0;
resources = null;
workProfileUserHandle = null;
+ cloneProfileUserHandle = null;
+ tabOwnerUserHandleForLaunch = null;
hasCrossProfileIntents = true;
isQuietModeEnabled = false;
isWorkProfileUserRunning = true;
@@ -126,13 +128,6 @@
}
};
- mMyUserIdProvider = new MyUserIdProvider() {
- @Override
- public int getMyUserId() {
- return myUserId != null ? myUserId : UserHandle.myUserId();
- }
- };
-
mCrossProfileIntentsChecker = mock(CrossProfileIntentsChecker.class);
when(mCrossProfileIntentsChecker.hasCrossProfileIntents(any(), anyInt(), anyInt()))
.thenAnswer(invocation -> hasCrossProfileIntents);
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
index d656678..78a75db 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
@@ -143,7 +143,8 @@
* `Parameterized` runner.
* --------
*/
-
+ private static final UserHandle PERSONAL_USER_HANDLE = InstrumentationRegistry
+ .getInstrumentation().getTargetContext().getUser();
private static final Function<PackageManager, PackageManager> DEFAULT_PM = pm -> pm;
private static final Function<PackageManager, PackageManager> NO_APP_PREDICTION_SERVICE_PM =
pm -> {
@@ -472,7 +473,7 @@
List<ResolvedComponentInfo> infosToStack = new ArrayList<>();
for (int i = 0; i < 4; i++) {
ResolveInfo resolveInfo = ResolverDataProvider.createResolveInfo(i,
- UserHandle.USER_CURRENT);
+ UserHandle.USER_CURRENT, PERSONAL_USER_HANDLE);
resolveInfo.activityInfo.applicationInfo.name = appName;
resolveInfo.activityInfo.applicationInfo.packageName = packageName;
resolveInfo.activityInfo.packageName = packageName;
@@ -1329,7 +1330,11 @@
final DisplayResolveInfo testDri =
activity.createTestDisplayResolveInfo(sendIntent,
- ResolverDataProvider.createResolveInfo(3, 0), "testLabel", "testInfo", sendIntent,
+ ResolverDataProvider.createResolveInfo(
+ 3, 0, PERSONAL_USER_HANDLE),
+ "testLabel",
+ "testInfo",
+ sendIntent,
/* resolveInfoPresentationGetter */ null);
final ChooserListAdapter adapter = activity.getAdapter();
@@ -1450,7 +1455,8 @@
ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
// Create direct share target
List<ChooserTarget> serviceTargets = createDirectShareTargets(1, "");
- ResolveInfo ri = ResolverDataProvider.createResolveInfo(3, 0);
+ ResolveInfo ri = ResolverDataProvider.createResolveInfo(3, 0,
+ PERSONAL_USER_HANDLE);
// Start activity
final IChooserWrapper activity = (IChooserWrapper)
@@ -1528,7 +1534,8 @@
// Create direct share target
List<ChooserTarget> serviceTargets = createDirectShareTargets(1,
resolvedComponentInfos.get(0).getResolveInfoAt(0).activityInfo.packageName);
- ResolveInfo ri = ResolverDataProvider.createResolveInfo(3, 0);
+ ResolveInfo ri = ResolverDataProvider.createResolveInfo(3, 0,
+ PERSONAL_USER_HANDLE);
// Start activity
final IChooserWrapper activity = (IChooserWrapper)
@@ -1606,7 +1613,8 @@
// Create direct share target
List<ChooserTarget> serviceTargets = createDirectShareTargets(2,
resolvedComponentInfos.get(0).getResolveInfoAt(0).activityInfo.packageName);
- ResolveInfo ri = ResolverDataProvider.createResolveInfo(3, 0);
+ ResolveInfo ri = ResolverDataProvider.createResolveInfo(3, 0,
+ PERSONAL_USER_HANDLE);
// Start activity
final ChooserActivity activity =
@@ -1679,7 +1687,8 @@
// Create direct share target
List<ChooserTarget> serviceTargets = createDirectShareTargets(2,
resolvedComponentInfos.get(0).getResolveInfoAt(0).activityInfo.packageName);
- ResolveInfo ri = ResolverDataProvider.createResolveInfo(3, 0);
+ ResolveInfo ri = ResolverDataProvider.createResolveInfo(3, 0,
+ PERSONAL_USER_HANDLE);
// Start activity
final ChooserActivity activity =
@@ -1791,7 +1800,8 @@
// Create direct share target
List<ChooserTarget> serviceTargets = createDirectShareTargets(1,
resolvedComponentInfos.get(14).getResolveInfoAt(0).activityInfo.packageName);
- ResolveInfo ri = ResolverDataProvider.createResolveInfo(16, 0);
+ ResolveInfo ri = ResolverDataProvider.createResolveInfo(16, 0,
+ PERSONAL_USER_HANDLE);
// Start activity
final IChooserWrapper activity = (IChooserWrapper)
@@ -2187,7 +2197,8 @@
// Create direct share target
List<ChooserTarget> serviceTargets = createDirectShareTargets(1,
resolvedComponentInfos.get(0).getResolveInfoAt(0).activityInfo.packageName);
- ResolveInfo ri = ResolverDataProvider.createResolveInfo(3, 0);
+ ResolveInfo ri = ResolverDataProvider.createResolveInfo(3, 0,
+ PERSONAL_USER_HANDLE);
ChooserActivityOverrideData
.getInstance()
@@ -2721,7 +2732,7 @@
new Intent[] {new Intent("action.fake")});
ChooserActivityOverrideData.getInstance().packageManager = mock(PackageManager.class);
ResolveInfo ri = ResolverDataProvider.createResolveInfo(0,
- UserHandle.USER_CURRENT);
+ UserHandle.USER_CURRENT, PERSONAL_USER_HANDLE);
when(
ChooserActivityOverrideData
.getInstance()
@@ -2886,6 +2897,53 @@
assertEquals(3, wrapper.getWorkListAdapter().getCount());
}
+ @Test
+ public void testClonedProfilePresent_personalAdapterIsSetWithPersonalProfile() {
+ // enable cloneProfile
+ markCloneProfileUserAvailable();
+ List<ResolvedComponentInfo> resolvedComponentInfos =
+ createResolvedComponentsWithCloneProfileForTest(
+ 3,
+ PERSONAL_USER_HANDLE,
+ ChooserActivityOverrideData.getInstance().cloneProfileUserHandle);
+ when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent(
+ Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
+ Mockito.isA(List.class)))
+ .thenReturn(new ArrayList<>(resolvedComponentInfos));
+ Intent sendIntent = createSendTextIntent();
+
+ final IChooserWrapper activity = (IChooserWrapper) mActivityRule
+ .launchActivity(Intent.createChooser(sendIntent, "personalProfileTest"));
+ waitForIdle();
+
+ assertThat(activity.getPersonalListAdapter().getUserHandle(), is(PERSONAL_USER_HANDLE));
+ assertThat(activity.getAdapter().getCount(), is(3));
+ }
+
+ @Test
+ public void testClonedProfilePresent_personalTabUsesExpectedAdapter() {
+ // enable the work tab feature flag
+ ResolverActivity.ENABLE_TABBED_VIEW = true;
+ markWorkProfileUserAvailable();
+ markCloneProfileUserAvailable();
+ List<ResolvedComponentInfo> personalResolvedComponentInfos =
+ createResolvedComponentsForTest(3);
+ List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(
+ 4);
+ setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
+ Intent sendIntent = createSendTextIntent();
+ sendIntent.setType(TEST_MIME_TYPE);
+
+
+ final IChooserWrapper activity = (IChooserWrapper)
+ mActivityRule.launchActivity(Intent.createChooser(sendIntent, "multi tab test"));
+ waitForIdle();
+
+ assertThat(activity.getCurrentUserHandle(), is(PERSONAL_USER_HANDLE));
+ }
+
private Intent createChooserIntent(Intent intent, Intent[] initialIntents) {
Intent chooserIntent = new Intent();
chooserIntent.setAction(Intent.ACTION_CHOOSER);
@@ -2906,6 +2964,7 @@
ri.activityInfo.packageName = "fake.package.name";
ri.activityInfo.applicationInfo = new ApplicationInfo();
ri.activityInfo.applicationInfo.packageName = "fake.package.name";
+ ri.userHandle = UserHandle.CURRENT;
return ri;
}
@@ -2967,7 +3026,23 @@
private List<ResolvedComponentInfo> createResolvedComponentsForTest(int numberOfResults) {
List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
for (int i = 0; i < numberOfResults; i++) {
- infoList.add(ResolverDataProvider.createResolvedComponentInfo(i));
+ infoList.add(ResolverDataProvider.createResolvedComponentInfo(i, PERSONAL_USER_HANDLE));
+ }
+ return infoList;
+ }
+
+ private List<ResolvedComponentInfo> createResolvedComponentsWithCloneProfileForTest(
+ int numberOfResults,
+ UserHandle resolvedForPersonalUser,
+ UserHandle resolvedForClonedUser) {
+ List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
+ for (int i = 0; i < 1; i++) {
+ infoList.add(ResolverDataProvider.createResolvedComponentInfo(i,
+ resolvedForPersonalUser));
+ }
+ for (int i = 1; i < numberOfResults; i++) {
+ infoList.add(ResolverDataProvider.createResolvedComponentInfo(i,
+ resolvedForClonedUser));
}
return infoList;
}
@@ -2977,9 +3052,11 @@
List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
for (int i = 0; i < numberOfResults; i++) {
if (i == 0) {
- infoList.add(ResolverDataProvider.createResolvedComponentInfoWithOtherId(i));
+ infoList.add(ResolverDataProvider.createResolvedComponentInfoWithOtherId(i,
+ PERSONAL_USER_HANDLE));
} else {
- infoList.add(ResolverDataProvider.createResolvedComponentInfo(i));
+ infoList.add(ResolverDataProvider.createResolvedComponentInfo(i,
+ PERSONAL_USER_HANDLE));
}
}
return infoList;
@@ -2991,9 +3068,11 @@
for (int i = 0; i < numberOfResults; i++) {
if (i == 0) {
infoList.add(
- ResolverDataProvider.createResolvedComponentInfoWithOtherId(i, userId));
+ ResolverDataProvider.createResolvedComponentInfoWithOtherId(i, userId,
+ PERSONAL_USER_HANDLE));
} else {
- infoList.add(ResolverDataProvider.createResolvedComponentInfo(i));
+ infoList.add(ResolverDataProvider.createResolvedComponentInfo(i,
+ PERSONAL_USER_HANDLE));
}
}
return infoList;
@@ -3003,7 +3082,8 @@
int numberOfResults, int userId) {
List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
for (int i = 0; i < numberOfResults; i++) {
- infoList.add(ResolverDataProvider.createResolvedComponentInfoWithOtherId(i, userId));
+ infoList.add(ResolverDataProvider.createResolvedComponentInfoWithOtherId(i, userId,
+ PERSONAL_USER_HANDLE));
}
return infoList;
}
@@ -3097,6 +3177,10 @@
ChooserActivityOverrideData.getInstance().workProfileUserHandle = UserHandle.of(10);
}
+ private void markCloneProfileUserAvailable() {
+ ChooserActivityOverrideData.getInstance().cloneProfileUserHandle = UserHandle.of(11);
+ }
+
private void setupResolverControllers(
List<ResolvedComponentInfo> personalResolvedComponentInfos,
List<ResolvedComponentInfo> workResolvedComponentInfos) {
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityWorkProfileTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityWorkProfileTest.java
index b6ea9dd..db69cf2 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityWorkProfileTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityWorkProfileTest.java
@@ -49,8 +49,8 @@
import androidx.test.rule.ActivityTestRule;
import com.android.internal.R;
-import com.android.internal.app.ResolverActivity.ResolvedComponentInfo;
import com.android.internal.app.ChooserActivityWorkProfileTest.TestCase.Tab;
+import com.android.internal.app.ResolverActivity.ResolvedComponentInfo;
import junit.framework.AssertionFailedError;
@@ -93,7 +93,7 @@
public void testBlocker() {
setUpPersonalAndWorkComponentInfos();
sOverrides.hasCrossProfileIntents = mTestCase.hasCrossProfileIntents();
- sOverrides.myUserId = mTestCase.getMyUserHandle().getIdentifier();
+ sOverrides.tabOwnerUserHandleForLaunch = mTestCase.getMyUserHandle();
launchActivity(mTestCase.getIsSendAction());
switchToTab(mTestCase.getTab());
@@ -238,19 +238,21 @@
}
private List<ResolvedComponentInfo> createResolvedComponentsForTestWithOtherProfile(
- int numberOfResults, int userId) {
+ int numberOfResults, int userId, UserHandle resolvedForUser) {
List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
for (int i = 0; i < numberOfResults; i++) {
infoList.add(
- ResolverDataProvider.createResolvedComponentInfoWithOtherId(i, userId));
+ ResolverDataProvider
+ .createResolvedComponentInfoWithOtherId(i, userId, resolvedForUser));
}
return infoList;
}
- private List<ResolvedComponentInfo> createResolvedComponentsForTest(int numberOfResults) {
+ private List<ResolvedComponentInfo> createResolvedComponentsForTest(int numberOfResults,
+ UserHandle resolvedForUser) {
List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
for (int i = 0; i < numberOfResults; i++) {
- infoList.add(ResolverDataProvider.createResolvedComponentInfo(i));
+ infoList.add(ResolverDataProvider.createResolvedComponentInfo(i, resolvedForUser));
}
return infoList;
}
@@ -262,9 +264,9 @@
int workProfileTargets = 4;
List<ResolvedComponentInfo> personalResolvedComponentInfos =
createResolvedComponentsForTestWithOtherProfile(3,
- /* userId */ WORK_USER_HANDLE.getIdentifier());
+ /* userId */ WORK_USER_HANDLE.getIdentifier(), PERSONAL_USER_HANDLE);
List<ResolvedComponentInfo> workResolvedComponentInfos =
- createResolvedComponentsForTest(workProfileTargets);
+ createResolvedComponentsForTest(workProfileTargets, WORK_USER_HANDLE);
setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
}
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
index 5dc0c8b..d7a8b3a 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
@@ -16,10 +16,6 @@
package com.android.internal.app;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.annotation.Nullable;
@@ -34,12 +30,12 @@
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
+import android.os.Bundle;
import android.os.UserHandle;
import android.util.Pair;
import android.util.Size;
import com.android.internal.app.AbstractMultiProfilePagerAdapter.CrossProfileIntentsChecker;
-import com.android.internal.app.AbstractMultiProfilePagerAdapter.MyUserIdProvider;
import com.android.internal.app.ResolverListAdapter.ResolveInfoPresentationGetter;
import com.android.internal.app.chooser.DisplayResolveInfo;
import com.android.internal.app.chooser.TargetInfo;
@@ -132,14 +128,6 @@
}
@Override
- protected MyUserIdProvider createMyUserIdProvider() {
- if (sOverrides.mMyUserIdProvider != null) {
- return sOverrides.mMyUserIdProvider;
- }
- return super.createMyUserIdProvider();
- }
-
- @Override
protected CrossProfileIntentsChecker createCrossProfileIntentsChecker() {
if (sOverrides.mCrossProfileIntentsChecker != null) {
return sOverrides.mCrossProfileIntentsChecker;
@@ -155,13 +143,15 @@
return super.createQuietModeManager();
}
+ // TODO: Remove this and override safelyStartActivityInternal() instead.
@Override
- public void safelyStartActivity(com.android.internal.app.chooser.TargetInfo cti) {
+ public void safelyStartActivityAsUser(TargetInfo cti, UserHandle user,
+ @Nullable Bundle options) {
if (sOverrides.onSafelyStartCallback != null &&
sOverrides.onSafelyStartCallback.apply(cti)) {
return;
}
- super.safelyStartActivity(cti);
+ super.safelyStartActivityAsUser(cti, user, options);
}
@Override
@@ -253,6 +243,14 @@
}
@Override
+ protected UserHandle getTabOwnerUserHandleForLaunch() {
+ if (sOverrides.tabOwnerUserHandleForLaunch == null) {
+ return super.getTabOwnerUserHandleForLaunch();
+ }
+ return sOverrides.tabOwnerUserHandleForLaunch;
+ }
+
+ @Override
public Context createContextAsUser(UserHandle user, int flags) {
// return the current context as a work profile doesn't really exist in these tests
return getApplicationContext();
diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
index 92c05b0..b82bc16 100644
--- a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
@@ -79,6 +79,9 @@
*/
@RunWith(AndroidJUnit4.class)
public class ResolverActivityTest {
+
+ private static final UserHandle PERSONAL_USER_HANDLE = InstrumentationRegistry
+ .getInstrumentation().getTargetContext().getUser();
@Rule
public ActivityTestRule<ResolverWrapperActivity> mActivityRule =
new ActivityTestRule<>(ResolverWrapperActivity.class, false,
@@ -92,7 +95,8 @@
@Test
public void twoOptionsAndUserSelectsOne() throws InterruptedException {
Intent sendIntent = createSendImageIntent();
- List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
+ List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2,
+ PERSONAL_USER_HANDLE);
when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
Mockito.anyBoolean(),
@@ -124,7 +128,8 @@
@Test
public void setMaxHeight() throws Exception {
Intent sendIntent = createSendImageIntent();
- List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
+ List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2,
+ PERSONAL_USER_HANDLE);
when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
Mockito.anyBoolean(),
@@ -169,7 +174,8 @@
@Test
public void setShowAtTopToTrue() throws Exception {
Intent sendIntent = createSendImageIntent();
- List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
+ List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2,
+ PERSONAL_USER_HANDLE);
when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
Mockito.anyBoolean(),
@@ -201,7 +207,8 @@
@Test
public void hasLastChosenActivity() throws Exception {
Intent sendIntent = createSendImageIntent();
- List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
+ List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2,
+ PERSONAL_USER_HANDLE);
ResolveInfo toChoose = resolvedComponentInfos.get(0).getResolveInfoAt(0);
when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
@@ -234,10 +241,12 @@
// enable the work tab feature flag
ResolverActivity.ENABLE_TABBED_VIEW = true;
List<ResolvedComponentInfo> personalResolvedComponentInfos =
- createResolvedComponentsForTestWithOtherProfile(2, /* userId */ 10);
- List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4);
- setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
+ createResolvedComponentsForTestWithOtherProfile(2, /* userId */ 10,
+ PERSONAL_USER_HANDLE);
markWorkProfileUserAvailable();
+ List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4,
+ sOverrides.workProfileUserHandle);
+ setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
ResolveInfo toChoose = personalResolvedComponentInfos.get(1).getResolveInfoAt(0);
Intent sendIntent = createSendImageIntent();
@@ -255,7 +264,8 @@
};
// Make a stable copy of the components as the original list may be modified
List<ResolvedComponentInfo> stableCopy =
- createResolvedComponentsForTestWithOtherProfile(2, /* userId= */ 10);
+ createResolvedComponentsForTestWithOtherProfile(2, /* userId= */ 10,
+ PERSONAL_USER_HANDLE);
// We pick the first one as there is another one in the work profile side
onView(first(withText(stableCopy.get(1).getResolveInfoAt(0).activityInfo.name)))
.perform(click());
@@ -272,7 +282,7 @@
Intent sendIntent = createSendImageIntent();
List<ResolvedComponentInfo> resolvedComponentInfos =
- createResolvedComponentsForTestWithOtherProfile(3);
+ createResolvedComponentsForTestWithOtherProfile(3, PERSONAL_USER_HANDLE);
ResolveInfo toChoose = resolvedComponentInfos.get(1).getResolveInfoAt(0);
when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
@@ -298,7 +308,7 @@
// Make a stable copy of the components as the original list may be modified
List<ResolvedComponentInfo> stableCopy =
- createResolvedComponentsForTestWithOtherProfile(2);
+ createResolvedComponentsForTestWithOtherProfile(2, PERSONAL_USER_HANDLE);
onView(withText(stableCopy.get(1).getResolveInfoAt(0).activityInfo.name))
.perform(click());
@@ -317,7 +327,7 @@
// chosen activity.
Intent sendIntent = createSendImageIntent();
List<ResolvedComponentInfo> resolvedComponentInfos =
- createResolvedComponentsForTestWithOtherProfile(3);
+ createResolvedComponentsForTestWithOtherProfile(3, PERSONAL_USER_HANDLE);
ResolveInfo toChoose = resolvedComponentInfos.get(1).getResolveInfoAt(0);
when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
@@ -345,7 +355,7 @@
// Make a stable copy of the components as the original list may be modified
List<ResolvedComponentInfo> stableCopy =
- createResolvedComponentsForTestWithOtherProfile(2);
+ createResolvedComponentsForTestWithOtherProfile(2, PERSONAL_USER_HANDLE);
onView(withText(stableCopy.get(1).getResolveInfoAt(0).activityInfo.name))
.perform(click());
@@ -428,12 +438,14 @@
// enable the work tab feature flag
ResolverActivity.ENABLE_TABBED_VIEW = true;
List<ResolvedComponentInfo> personalResolvedComponentInfos =
- createResolvedComponentsForTestWithOtherProfile(3, /* userId = */ 10);
- List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4);
+ createResolvedComponentsForTestWithOtherProfile(3, /* userId = */ 10,
+ PERSONAL_USER_HANDLE);
+ markWorkProfileUserAvailable();
+ List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4,
+ sOverrides.workProfileUserHandle);
setupResolverControllers(personalResolvedComponentInfos,
new ArrayList<>(workResolvedComponentInfos));
Intent sendIntent = createSendImageIntent();
- markWorkProfileUserAvailable();
final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
waitForIdle();
@@ -448,11 +460,13 @@
// enable the work tab feature flag
ResolverActivity.ENABLE_TABBED_VIEW = true;
List<ResolvedComponentInfo> personalResolvedComponentInfos =
- createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10);
- List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4);
+ createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10,
+ PERSONAL_USER_HANDLE);
+ markWorkProfileUserAvailable();
+ List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4,
+ sOverrides.workProfileUserHandle);
setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
Intent sendIntent = createSendImageIntent();
- markWorkProfileUserAvailable();
final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
waitForIdle();
@@ -467,11 +481,12 @@
// enable the work tab feature flag
ResolverActivity.ENABLE_TABBED_VIEW = true;
List<ResolvedComponentInfo> personalResolvedComponentInfos =
- createResolvedComponentsForTestWithOtherProfile(3);
- List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4);
+ createResolvedComponentsForTestWithOtherProfile(3, PERSONAL_USER_HANDLE);
+ markWorkProfileUserAvailable();
+ List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4,
+ sOverrides.workProfileUserHandle);
setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
Intent sendIntent = createSendImageIntent();
- markWorkProfileUserAvailable();
final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
waitForIdle();
@@ -487,8 +502,10 @@
ResolverActivity.ENABLE_TABBED_VIEW = true;
markWorkProfileUserAvailable();
List<ResolvedComponentInfo> personalResolvedComponentInfos =
- createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10);
- List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4);
+ createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10,
+ PERSONAL_USER_HANDLE);
+ List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4,
+ sOverrides.workProfileUserHandle);
setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
Intent sendIntent = createSendImageIntent();
@@ -507,8 +524,10 @@
ResolverActivity.ENABLE_TABBED_VIEW = true;
markWorkProfileUserAvailable();
List<ResolvedComponentInfo> personalResolvedComponentInfos =
- createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10);
- List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4);
+ createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10,
+ PERSONAL_USER_HANDLE);
+ List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4,
+ sOverrides.workProfileUserHandle);
setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
Intent sendIntent = createSendImageIntent();
ResolveInfo[] chosen = new ResolveInfo[1];
@@ -539,8 +558,9 @@
ResolverActivity.ENABLE_TABBED_VIEW = true;
markWorkProfileUserAvailable();
List<ResolvedComponentInfo> personalResolvedComponentInfos =
- createResolvedComponentsForTestWithOtherProfile(1);
- List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4);
+ createResolvedComponentsForTestWithOtherProfile(1, PERSONAL_USER_HANDLE);
+ List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4,
+ sOverrides.workProfileUserHandle);
setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
Intent sendIntent = createSendImageIntent();
@@ -559,8 +579,9 @@
ResolverActivity.ENABLE_TABBED_VIEW = true;
markWorkProfileUserAvailable();
List<ResolvedComponentInfo> personalResolvedComponentInfos =
- createResolvedComponentsForTestWithOtherProfile(1);
- List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4);
+ createResolvedComponentsForTestWithOtherProfile(1, PERSONAL_USER_HANDLE);
+ List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4,
+ sOverrides.workProfileUserHandle);
setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
Intent sendIntent = createOpenWebsiteIntent();
@@ -578,8 +599,9 @@
ResolverActivity.ENABLE_TABBED_VIEW = true;
markWorkProfileUserAvailable();
List<ResolvedComponentInfo> personalResolvedComponentInfos =
- createResolvedComponentsForTestWithOtherProfile(1);
- List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4);
+ createResolvedComponentsForTestWithOtherProfile(1, PERSONAL_USER_HANDLE);
+ List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4,
+ sOverrides.workProfileUserHandle);
setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
Intent sendIntent = createOpenWebsiteIntent();
@@ -605,8 +627,10 @@
ResolverActivity.ENABLE_TABBED_VIEW = true;
markWorkProfileUserAvailable();
List<ResolvedComponentInfo> personalResolvedComponentInfos =
- createResolvedComponentsForTestWithOtherProfile(3, /* userId= */ 10);
- List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4);
+ createResolvedComponentsForTestWithOtherProfile(3, /* userId= */ 10,
+ PERSONAL_USER_HANDLE);
+ List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4,
+ sOverrides.workProfileUserHandle);
setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
Intent sendIntent = createSendImageIntent();
ResolveInfo[] chosen = new ResolveInfo[1];
@@ -639,9 +663,11 @@
markWorkProfileUserAvailable();
int workProfileTargets = 4;
List<ResolvedComponentInfo> personalResolvedComponentInfos =
- createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10);
+ createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10,
+ PERSONAL_USER_HANDLE);
List<ResolvedComponentInfo> workResolvedComponentInfos =
- createResolvedComponentsForTest(workProfileTargets);
+ createResolvedComponentsForTest(workProfileTargets,
+ sOverrides.workProfileUserHandle);
sOverrides.hasCrossProfileIntents = false;
setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
Intent sendIntent = createSendImageIntent();
@@ -665,9 +691,11 @@
markWorkProfileUserAvailable();
int workProfileTargets = 4;
List<ResolvedComponentInfo> personalResolvedComponentInfos =
- createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10);
+ createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10,
+ PERSONAL_USER_HANDLE);
List<ResolvedComponentInfo> workResolvedComponentInfos =
- createResolvedComponentsForTest(workProfileTargets);
+ createResolvedComponentsForTest(workProfileTargets,
+ sOverrides.workProfileUserHandle);
sOverrides.isQuietModeEnabled = true;
setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
Intent sendIntent = createSendImageIntent();
@@ -690,9 +718,9 @@
ResolverActivity.ENABLE_TABBED_VIEW = true;
markWorkProfileUserAvailable();
List<ResolvedComponentInfo> personalResolvedComponentInfos =
- createResolvedComponentsForTest(3);
+ createResolvedComponentsForTest(3, PERSONAL_USER_HANDLE);
List<ResolvedComponentInfo> workResolvedComponentInfos =
- createResolvedComponentsForTest(0);
+ createResolvedComponentsForTest(0, sOverrides.workProfileUserHandle);
setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
Intent sendIntent = createSendImageIntent();
sendIntent.setType("TestType");
@@ -714,9 +742,9 @@
ResolverActivity.ENABLE_TABBED_VIEW = true;
markWorkProfileUserAvailable();
List<ResolvedComponentInfo> personalResolvedComponentInfos =
- createResolvedComponentsForTest(3);
+ createResolvedComponentsForTest(3, PERSONAL_USER_HANDLE);
List<ResolvedComponentInfo> workResolvedComponentInfos =
- createResolvedComponentsForTest(0);
+ createResolvedComponentsForTest(0, sOverrides.workProfileUserHandle);
setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
Intent sendIntent = createSendImageIntent();
sendIntent.setType("TestType");
@@ -739,9 +767,9 @@
ResolverActivity.ENABLE_TABBED_VIEW = true;
markWorkProfileUserAvailable();
List<ResolvedComponentInfo> personalResolvedComponentInfos =
- createResolvedComponentsForTest(1);
+ createResolvedComponentsForTest(1, PERSONAL_USER_HANDLE);
List<ResolvedComponentInfo> workResolvedComponentInfos =
- createResolvedComponentsForTest(1);
+ createResolvedComponentsForTest(1, sOverrides.workProfileUserHandle);
// Personal profile only has a browser
personalResolvedComponentInfos.get(0).getResolveInfoAt(0).handleAllWebDataURI = true;
setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
@@ -758,9 +786,9 @@
ResolverActivity.ENABLE_TABBED_VIEW = true;
markWorkProfileUserAvailable();
List<ResolvedComponentInfo> personalResolvedComponentInfos =
- createResolvedComponentsForTest(0);
+ createResolvedComponentsForTest(0, PERSONAL_USER_HANDLE);
List<ResolvedComponentInfo> workResolvedComponentInfos =
- createResolvedComponentsForTest(1);
+ createResolvedComponentsForTest(1, sOverrides.workProfileUserHandle);
setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
Intent sendIntent = createSendImageIntent();
sendIntent.setType("TestType");
@@ -787,9 +815,9 @@
ResolverActivity.ENABLE_TABBED_VIEW = true;
markWorkProfileUserAvailable();
List<ResolvedComponentInfo> personalResolvedComponentInfos =
- createResolvedComponentsForTest(3);
+ createResolvedComponentsForTest(3, PERSONAL_USER_HANDLE);
List<ResolvedComponentInfo> workResolvedComponentInfos =
- createResolvedComponentsForTest(0);
+ createResolvedComponentsForTest(0, sOverrides.workProfileUserHandle);
setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
Intent sendIntent = createSendImageIntent();
sendIntent.setType("TestType");
@@ -810,7 +838,8 @@
public void testAutolaunch_singleTarget_withWorkProfileAndTabbedViewOff_noAutolaunch() {
ResolverActivity.ENABLE_TABBED_VIEW = false;
List<ResolvedComponentInfo> personalResolvedComponentInfos =
- createResolvedComponentsForTestWithOtherProfile(2, /* userId */ 10);
+ createResolvedComponentsForTestWithOtherProfile(2, /* userId */ 10,
+ PERSONAL_USER_HANDLE);
when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
Mockito.anyBoolean(),
Mockito.anyBoolean(),
@@ -835,7 +864,7 @@
public void testAutolaunch_singleTarget_noWorkProfile_autolaunch() {
ResolverActivity.ENABLE_TABBED_VIEW = false;
List<ResolvedComponentInfo> personalResolvedComponentInfos =
- createResolvedComponentsForTest(1);
+ createResolvedComponentsForTest(1, PERSONAL_USER_HANDLE);
when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
Mockito.anyBoolean(),
Mockito.anyBoolean(),
@@ -863,9 +892,11 @@
markWorkProfileUserAvailable();
int workProfileTargets = 4;
List<ResolvedComponentInfo> personalResolvedComponentInfos =
- createResolvedComponentsForTestWithOtherProfile(2, /* userId */ 10);
+ createResolvedComponentsForTestWithOtherProfile(2, /* userId */ 10,
+ PERSONAL_USER_HANDLE);
List<ResolvedComponentInfo> workResolvedComponentInfos =
- createResolvedComponentsForTest(workProfileTargets);
+ createResolvedComponentsForTest(workProfileTargets,
+ sOverrides.workProfileUserHandle);
sOverrides.hasCrossProfileIntents = false;
setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
Intent sendIntent = createSendImageIntent();
@@ -892,7 +923,7 @@
// chosen activity.
Intent sendIntent = createSendImageIntent();
List<ResolvedComponentInfo> resolvedComponentInfos =
- createResolvedComponentsForTest(2);
+ createResolvedComponentsForTest(2, PERSONAL_USER_HANDLE);
when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
Mockito.anyBoolean(),
@@ -911,6 +942,193 @@
assertThat(activity.getAdapter().getPlaceholderCount(), is(2));
}
+ @Test
+ public void testClonedProfilePresent_personalAdapterIsSetWithPersonalProfile() {
+ // enable cloneProfile
+ markCloneProfileUserAvailable();
+ List<ResolvedComponentInfo> resolvedComponentInfos =
+ createResolvedComponentsWithCloneProfileForTest(
+ 3,
+ PERSONAL_USER_HANDLE,
+ sOverrides.cloneProfileUserHandle);
+ when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
+ Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
+ Intent sendIntent = createSendImageIntent();
+
+ final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
+ waitForIdle();
+
+ assertThat(activity.getCurrentUserHandle(), is(activity.getPersonalProfileUserHandle()));
+ assertThat(activity.getAdapter().getCount(), is(3));
+ }
+
+ @Test
+ public void testClonedProfilePresent_personalTabUsesExpectedAdapter() {
+ // enable the work tab feature flag
+ ResolverActivity.ENABLE_TABBED_VIEW = true;
+ markWorkProfileUserAvailable();
+ // enable cloneProfile
+ markCloneProfileUserAvailable();
+ List<ResolvedComponentInfo> personalResolvedComponentInfos =
+ createResolvedComponentsWithCloneProfileForTest(
+ 3,
+ PERSONAL_USER_HANDLE,
+ sOverrides.cloneProfileUserHandle);
+ List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4,
+ sOverrides.workProfileUserHandle);
+ setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
+ Intent sendIntent = createSendImageIntent();
+
+ final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
+ waitForIdle();
+
+ assertThat(activity.getCurrentUserHandle(), is(activity.getPersonalProfileUserHandle()));
+ assertThat(activity.getAdapter().getCount(), is(3));
+ }
+
+ @Test
+ public void testClonedProfilePresent_layoutWithDefault_neverShown() throws Exception {
+ // enable cloneProfile
+ markCloneProfileUserAvailable();
+ Intent sendIntent = createSendImageIntent();
+ List<ResolvedComponentInfo> resolvedComponentInfos =
+ createResolvedComponentsWithCloneProfileForTest(
+ 2,
+ PERSONAL_USER_HANDLE,
+ sOverrides.cloneProfileUserHandle);
+
+ when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
+ Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
+ when(sOverrides.resolverListController.getLastChosen())
+ .thenReturn(resolvedComponentInfos.get(0).getResolveInfoAt(0));
+
+ final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
+ Espresso.registerIdlingResources(activity.getAdapter().getLabelIdlingResource());
+ waitForIdle();
+
+ assertThat(activity.getAdapter().hasFilteredItem(), is(false));
+ assertThat(activity.getAdapter().getCount(), is(2));
+ assertThat(activity.getAdapter().getPlaceholderCount(), is(2));
+ }
+
+ @Test
+ public void testClonedProfilePresent_alwaysButtonDisabled() throws Exception {
+ // enable cloneProfile
+ markCloneProfileUserAvailable();
+ Intent sendIntent = createSendImageIntent();
+ List<ResolvedComponentInfo> resolvedComponentInfos =
+ createResolvedComponentsWithCloneProfileForTest(
+ 3,
+ PERSONAL_USER_HANDLE,
+ sOverrides.cloneProfileUserHandle);
+
+ when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
+ Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
+ when(sOverrides.resolverListController.getLastChosen())
+ .thenReturn(resolvedComponentInfos.get(0).getResolveInfoAt(0));
+
+ final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
+ waitForIdle();
+
+ // Confirm that the button bar is disabled by default
+ onView(withId(R.id.button_once)).check(matches(not(isEnabled())));
+ onView(withId(R.id.button_always)).check(matches(not(isEnabled())));
+
+ // Make a stable copy of the components as the original list may be modified
+ List<ResolvedComponentInfo> stableCopy =
+ createResolvedComponentsForTestWithOtherProfile(2, PERSONAL_USER_HANDLE);
+
+ onView(withText(stableCopy.get(1).getResolveInfoAt(0).activityInfo.name))
+ .perform(click());
+
+ onView(withId(R.id.button_once)).check(matches(isEnabled()));
+ onView(withId(R.id.button_always)).check(matches(not(isEnabled())));
+ }
+
+ @Test
+ public void testClonedProfilePresent_personalProfileActivityIsStartedInCorrectUser()
+ throws Exception {
+ // enable the work tab feature flag
+ ResolverActivity.ENABLE_TABBED_VIEW = true;
+ markWorkProfileUserAvailable();
+ // enable cloneProfile
+ markCloneProfileUserAvailable();
+
+ List<ResolvedComponentInfo> personalResolvedComponentInfos =
+ createResolvedComponentsWithCloneProfileForTest(
+ 3,
+ PERSONAL_USER_HANDLE,
+ sOverrides.cloneProfileUserHandle);
+ List<ResolvedComponentInfo> workResolvedComponentInfos =
+ createResolvedComponentsForTest(3, sOverrides.workProfileUserHandle);
+ sOverrides.hasCrossProfileIntents = false;
+ setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
+ Intent sendIntent = createSendImageIntent();
+ sendIntent.setType("TestType");
+ final UserHandle[] selectedActivityUserHandle = new UserHandle[1];
+ sOverrides.onSafelyStartInternalCallback = userHandle -> {
+ selectedActivityUserHandle[0] = userHandle;
+ return true;
+ };
+
+ final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
+ waitForIdle();
+ onView(first(allOf(withText(personalResolvedComponentInfos.get(0)
+ .getResolveInfoAt(0).activityInfo.applicationInfo.name), isCompletelyDisplayed())))
+ .perform(click());
+ onView(withId(R.id.button_once))
+ .perform(click());
+ waitForIdle();
+
+ assertThat(selectedActivityUserHandle[0], is(activity.getAdapter().getUserHandle()));
+ }
+
+ @Test
+ public void testClonedProfilePresent_workProfileActivityIsStartedInCorrectUser()
+ throws Exception {
+ // enable the work tab feature flag
+ ResolverActivity.ENABLE_TABBED_VIEW = true;
+ markWorkProfileUserAvailable();
+ // enable cloneProfile
+ markCloneProfileUserAvailable();
+
+ List<ResolvedComponentInfo> personalResolvedComponentInfos =
+ createResolvedComponentsWithCloneProfileForTest(
+ 3,
+ PERSONAL_USER_HANDLE,
+ sOverrides.cloneProfileUserHandle);
+ List<ResolvedComponentInfo> workResolvedComponentInfos =
+ createResolvedComponentsForTest(3, sOverrides.workProfileUserHandle);
+ setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
+ Intent sendIntent = createSendImageIntent();
+ sendIntent.setType("TestType");
+ final UserHandle[] selectedActivityUserHandle = new UserHandle[1];
+ sOverrides.onSafelyStartInternalCallback = userHandle -> {
+ selectedActivityUserHandle[0] = userHandle;
+ return true;
+ };
+
+ final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
+ waitForIdle();
+ onView(withText(R.string.resolver_work_tab))
+ .perform(click());
+ waitForIdle();
+ onView(first(allOf(withText(workResolvedComponentInfos.get(0)
+ .getResolveInfoAt(0).activityInfo.applicationInfo.name), isCompletelyDisplayed())))
+ .perform(click());
+ onView(withId(R.id.button_once))
+ .perform(click());
+ waitForIdle();
+
+ assertThat(selectedActivityUserHandle[0], is(activity.getAdapter().getUserHandle()));
+ }
+
private Intent createSendImageIntent() {
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
@@ -926,36 +1144,55 @@
return sendIntent;
}
- private List<ResolvedComponentInfo> createResolvedComponentsForTest(int numberOfResults) {
+ private List<ResolvedComponentInfo> createResolvedComponentsForTest(int numberOfResults,
+ UserHandle resolvedForUser) {
List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
for (int i = 0; i < numberOfResults; i++) {
- infoList.add(ResolverDataProvider.createResolvedComponentInfo(i));
+ infoList.add(ResolverDataProvider.createResolvedComponentInfo(i, resolvedForUser));
+ }
+ return infoList;
+ }
+
+ private List<ResolvedComponentInfo> createResolvedComponentsWithCloneProfileForTest(
+ int numberOfResults,
+ UserHandle resolvedForPersonalUser,
+ UserHandle resolvedForClonedUser) {
+ List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
+ for (int i = 0; i < 1; i++) {
+ infoList.add(ResolverDataProvider.createResolvedComponentInfo(i,
+ resolvedForPersonalUser));
+ }
+ for (int i = 1; i < numberOfResults; i++) {
+ infoList.add(ResolverDataProvider.createResolvedComponentInfo(i,
+ resolvedForClonedUser));
}
return infoList;
}
private List<ResolvedComponentInfo> createResolvedComponentsForTestWithOtherProfile(
- int numberOfResults) {
+ int numberOfResults, UserHandle resolvedForUser) {
List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
for (int i = 0; i < numberOfResults; i++) {
if (i == 0) {
- infoList.add(ResolverDataProvider.createResolvedComponentInfoWithOtherId(i));
+ infoList.add(ResolverDataProvider.createResolvedComponentInfoWithOtherId(i,
+ resolvedForUser));
} else {
- infoList.add(ResolverDataProvider.createResolvedComponentInfo(i));
+ infoList.add(ResolverDataProvider.createResolvedComponentInfo(i, resolvedForUser));
}
}
return infoList;
}
private List<ResolvedComponentInfo> createResolvedComponentsForTestWithOtherProfile(
- int numberOfResults, int userId) {
+ int numberOfResults, int userId, UserHandle resolvedForUser) {
List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
for (int i = 0; i < numberOfResults; i++) {
if (i == 0) {
infoList.add(
- ResolverDataProvider.createResolvedComponentInfoWithOtherId(i, userId));
+ ResolverDataProvider.createResolvedComponentInfoWithOtherId(i, userId,
+ resolvedForUser));
} else {
- infoList.add(ResolverDataProvider.createResolvedComponentInfo(i));
+ infoList.add(ResolverDataProvider.createResolvedComponentInfo(i, resolvedForUser));
}
}
return infoList;
@@ -969,6 +1206,10 @@
ResolverWrapperActivity.sOverrides.workProfileUserHandle = UserHandle.of(10);
}
+ private void markCloneProfileUserAvailable() {
+ ResolverWrapperActivity.sOverrides.cloneProfileUserHandle = UserHandle.of(11);
+ }
+
private void setupResolverControllers(
List<ResolvedComponentInfo> personalResolvedComponentInfos,
List<ResolvedComponentInfo> workResolvedComponentInfos) {
diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverActivityWorkProfileTest.java b/core/tests/coretests/src/com/android/internal/app/ResolverActivityWorkProfileTest.java
index 4a79f5e..9d16d85 100644
--- a/core/tests/coretests/src/com/android/internal/app/ResolverActivityWorkProfileTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ResolverActivityWorkProfileTest.java
@@ -92,7 +92,7 @@
public void testBlocker() {
setUpPersonalAndWorkComponentInfos();
sOverrides.hasCrossProfileIntents = mTestCase.hasCrossProfileIntents();
- sOverrides.myUserId = mTestCase.getMyUserHandle().getIdentifier();
+ sOverrides.tabOwnerUserHandleForLaunch = mTestCase.getMyUserHandle();
launchActivity(/* callingUser= */ mTestCase.getExtraCallingUser());
switchToTab(mTestCase.getTab());
@@ -230,19 +230,21 @@
}
private List<ResolvedComponentInfo> createResolvedComponentsForTestWithOtherProfile(
- int numberOfResults, int userId) {
+ int numberOfResults, int userId, UserHandle resolvedForUser) {
List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
for (int i = 0; i < numberOfResults; i++) {
infoList.add(
- ResolverDataProvider.createResolvedComponentInfoWithOtherId(i, userId));
+ ResolverDataProvider
+ .createResolvedComponentInfoWithOtherId(i, userId, resolvedForUser));
}
return infoList;
}
- private List<ResolvedComponentInfo> createResolvedComponentsForTest(int numberOfResults) {
+ private List<ResolvedComponentInfo> createResolvedComponentsForTest(int numberOfResults,
+ UserHandle resolvedForUser) {
List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
for (int i = 0; i < numberOfResults; i++) {
- infoList.add(ResolverDataProvider.createResolvedComponentInfo(i));
+ infoList.add(ResolverDataProvider.createResolvedComponentInfo(i, resolvedForUser));
}
return infoList;
}
@@ -254,9 +256,9 @@
int workProfileTargets = 4;
List<ResolvedComponentInfo> personalResolvedComponentInfos =
createResolvedComponentsForTestWithOtherProfile(3,
- /* userId */ WORK_USER_HANDLE.getIdentifier());
+ /* userId */ WORK_USER_HANDLE.getIdentifier(), PERSONAL_USER_HANDLE);
List<ResolvedComponentInfo> workResolvedComponentInfos =
- createResolvedComponentsForTest(workProfileTargets);
+ createResolvedComponentsForTest(workProfileTargets, WORK_USER_HANDLE);
setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
}
diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverDataProvider.java b/core/tests/coretests/src/com/android/internal/app/ResolverDataProvider.java
index d7db5f8..55318f3 100644
--- a/core/tests/coretests/src/com/android/internal/app/ResolverDataProvider.java
+++ b/core/tests/coretests/src/com/android/internal/app/ResolverDataProvider.java
@@ -36,20 +36,24 @@
static private int USER_SOMEONE_ELSE = 10;
- static ResolverActivity.ResolvedComponentInfo createResolvedComponentInfo(int i) {
- return new ResolverActivity.ResolvedComponentInfo(createComponentName(i),
- createResolverIntent(i), createResolveInfo(i, UserHandle.USER_CURRENT));
- }
-
- static ResolverActivity.ResolvedComponentInfo createResolvedComponentInfoWithOtherId(int i) {
- return new ResolverActivity.ResolvedComponentInfo(createComponentName(i),
- createResolverIntent(i), createResolveInfo(i, USER_SOMEONE_ELSE));
+ static ResolverActivity.ResolvedComponentInfo createResolvedComponentInfo(int i,
+ UserHandle resolvedForUser) {
+ return new ResolverActivity.ResolvedComponentInfo(
+ createComponentName(i),
+ createResolverIntent(i),
+ createResolveInfo(i, UserHandle.USER_CURRENT, resolvedForUser));
}
static ResolverActivity.ResolvedComponentInfo createResolvedComponentInfoWithOtherId(int i,
- int userId) {
+ UserHandle resolvedForUser) {
return new ResolverActivity.ResolvedComponentInfo(createComponentName(i),
- createResolverIntent(i), createResolveInfo(i, userId));
+ createResolverIntent(i), createResolveInfo(i, USER_SOMEONE_ELSE, resolvedForUser));
+ }
+
+ static ResolverActivity.ResolvedComponentInfo createResolvedComponentInfoWithOtherId(int i,
+ int userId, UserHandle resolvedForUser) {
+ return new ResolverActivity.ResolvedComponentInfo(createComponentName(i),
+ createResolverIntent(i), createResolveInfo(i, userId, resolvedForUser));
}
static ComponentName createComponentName(int i) {
@@ -57,10 +61,11 @@
return new ComponentName("foo.bar." + name, name);
}
- static ResolveInfo createResolveInfo(int i, int userId) {
+ static ResolveInfo createResolveInfo(int i, int userId, UserHandle resolvedForUser) {
final ResolveInfo resolveInfo = new ResolveInfo();
resolveInfo.activityInfo = createActivityInfo(i);
resolveInfo.targetUserId = userId;
+ resolveInfo.userHandle = resolvedForUser;
return resolveInfo;
}
diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverListControllerTest.java b/core/tests/coretests/src/com/android/internal/app/ResolverListControllerTest.java
index 42593f6..b0f1e04 100644
--- a/core/tests/coretests/src/com/android/internal/app/ResolverListControllerTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ResolverListControllerTest.java
@@ -44,6 +44,7 @@
import android.os.UserHandle;
import android.util.ArrayMap;
+import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import com.android.internal.app.ResolverActivity.ResolvedComponentInfo;
@@ -75,6 +76,8 @@
private ResolverListController mController;
private UsageStatsManager mUsm;
+ private static final UserHandle PERSONAL_USER_HANDLE = InstrumentationRegistry
+ .getInstrumentation().getTargetContext().getUser();
@Before
public void setUp() throws Exception {
@@ -119,7 +122,8 @@
anyString(), anyInt(), anyString(), any(), anyString());
when(mMockContext.getOpPackageName()).thenReturn(refererPackage);
mController = new ResolverListController(mMockContext, mMockPackageManager, sendIntent,
- refererPackage, UserHandle.USER_CURRENT, /* userHandle */ UserHandle.SYSTEM);
+ refererPackage, UserHandle.USER_CURRENT, /* userHandle */ UserHandle.SYSTEM,
+ UserHandle.SYSTEM);
mController.sort(new ArrayList<ResolvedComponentInfo>());
long beforeReport = getCount(mUsm, packageName, action, annotation);
mController.updateChooserCounts(packageName, UserHandle.USER_CURRENT, action);
@@ -134,7 +138,8 @@
String refererPackage = "test_referer_package";
List<ResolvedComponentInfo> resolvedComponents = createResolvedComponentsForTest(10);
mController = new ResolverListController(mMockContext, mMockPackageManager, sendIntent,
- refererPackage, UserHandle.USER_CURRENT, /* userHandle */ UserHandle.SYSTEM);
+ refererPackage, UserHandle.USER_CURRENT, /* userHandle */ UserHandle.SYSTEM,
+ UserHandle.SYSTEM);
List<ResolvedComponentInfo> topKList = new ArrayList<>(resolvedComponents);
mController.topK(topKList, 5);
List<ResolvedComponentInfo> sortList = new ArrayList<>(topKList);
@@ -157,12 +162,13 @@
public void getResolversForIntent_usesResultsFromPackageManager() {
mockStats();
List<ResolveInfo> infos = new ArrayList<>();
- infos.add(ResolverDataProvider.createResolveInfo(0, UserHandle.USER_CURRENT));
+ infos.add(ResolverDataProvider.createResolveInfo(0, UserHandle.USER_CURRENT,
+ PERSONAL_USER_HANDLE));
when(mMockPackageManager.queryIntentActivitiesAsUser(any(), anyInt(),
any(UserHandle.class))).thenReturn(infos);
mController = new ResolverListController(mMockContext, mMockPackageManager,
createSendImageIntent("test"), null, UserHandle.USER_CURRENT,
- /* userHandle= */ UserHandle.SYSTEM);
+ /* userHandle= */ UserHandle.SYSTEM, UserHandle.SYSTEM);
List<Intent> intents = new ArrayList<>();
intents.add(createActionMainIntent());
@@ -181,12 +187,13 @@
public void getResolversForIntent_shouldGetOnlyDefaultActivitiesTrue_addsFlag() {
mockStats();
List<ResolveInfo> infos = new ArrayList<>();
- infos.add(ResolverDataProvider.createResolveInfo(0, UserHandle.USER_CURRENT));
+ infos.add(ResolverDataProvider.createResolveInfo(0, UserHandle.USER_CURRENT,
+ PERSONAL_USER_HANDLE));
when(mMockPackageManager.queryIntentActivitiesAsUser(any(), anyInt(),
any(UserHandle.class))).thenReturn(infos);
mController = new ResolverListController(mMockContext, mMockPackageManager,
createSendImageIntent("test"), null, UserHandle.USER_CURRENT,
- /* userHandle= */ UserHandle.SYSTEM);
+ /* userHandle= */ UserHandle.SYSTEM, UserHandle.SYSTEM);
List<Intent> intents = new ArrayList<>();
intents.add(createActionMainIntent());
@@ -205,12 +212,13 @@
public void getResolversForIntent_shouldGetOnlyDefaultActivitiesFalse_doesNotAddFlag() {
mockStats();
List<ResolveInfo> infos = new ArrayList<>();
- infos.add(ResolverDataProvider.createResolveInfo(0, UserHandle.USER_CURRENT));
+ infos.add(ResolverDataProvider.createResolveInfo(0, UserHandle.USER_CURRENT,
+ PERSONAL_USER_HANDLE));
when(mMockPackageManager.queryIntentActivitiesAsUser(any(), anyInt(),
any(UserHandle.class))).thenReturn(infos);
mController = new ResolverListController(mMockContext, mMockPackageManager,
createSendImageIntent("test"), null, UserHandle.USER_CURRENT,
- /* userHandle= */ UserHandle.SYSTEM);
+ /* userHandle= */ UserHandle.SYSTEM, UserHandle.SYSTEM);
List<Intent> intents = new ArrayList<>();
intents.add(createActionMainIntent());
@@ -225,6 +233,32 @@
doesNotContainFlag(PackageManager.MATCH_DEFAULT_ONLY), any());
}
+
+ @Test
+ public void testResolveInfoWithNoUserHandle_isNotAddedToResults()
+ throws Exception {
+ List<ResolveInfo> infos = new ArrayList<>();
+ infos.add(ResolverDataProvider.createResolveInfo(0, UserHandle.USER_CURRENT,
+ PERSONAL_USER_HANDLE));
+ infos.add(ResolverDataProvider.createResolveInfo(0, UserHandle.USER_CURRENT, null));
+ when(mMockPackageManager.queryIntentActivitiesAsUser(any(), anyInt(),
+ any(UserHandle.class))).thenReturn(infos);
+ mController = new ResolverListController(mMockContext, mMockPackageManager,
+ createSendImageIntent("test"), null, UserHandle.USER_CURRENT,
+ /* userHandle= */ UserHandle.SYSTEM, UserHandle.SYSTEM);
+ List<Intent> intents = new ArrayList<>();
+ intents.add(createActionMainIntent());
+
+ List<ResolverActivity.ResolvedComponentInfo> result = mController
+ .getResolversForIntent(
+ /* shouldGetResolvedFilter= */ true,
+ /* shouldGetActivityMetadata= */ true,
+ /* shouldGetOnlyDefaultActivities= */ false,
+ intents);
+
+ assertThat(result.size(), is(1));
+ }
+
private int containsFlag(int flag) {
return intThat(new FlagMatcher(flag, /* contains= */ true));
}
@@ -308,7 +342,7 @@
private List<ResolvedComponentInfo> createResolvedComponentsForTest(int numberOfResults) {
List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
for (int i = 0; i < numberOfResults; i++) {
- infoList.add(ResolverDataProvider.createResolvedComponentInfo(i));
+ infoList.add(ResolverDataProvider.createResolvedComponentInfo(i, PERSONAL_USER_HANDLE));
}
return infoList;
}
diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverWrapperActivity.java b/core/tests/coretests/src/com/android/internal/app/ResolverWrapperActivity.java
index c778dfe..8f6f29d 100644
--- a/core/tests/coretests/src/com/android/internal/app/ResolverWrapperActivity.java
+++ b/core/tests/coretests/src/com/android/internal/app/ResolverWrapperActivity.java
@@ -21,6 +21,7 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import android.annotation.Nullable;
import android.app.usage.UsageStatsManager;
import android.content.Context;
import android.content.Intent;
@@ -30,7 +31,6 @@
import android.os.UserHandle;
import com.android.internal.app.AbstractMultiProfilePagerAdapter.CrossProfileIntentsChecker;
-import com.android.internal.app.AbstractMultiProfilePagerAdapter.MyUserIdProvider;
import com.android.internal.app.AbstractMultiProfilePagerAdapter.QuietModeManager;
import com.android.internal.app.chooser.TargetInfo;
@@ -57,14 +57,6 @@
}
@Override
- protected MyUserIdProvider createMyUserIdProvider() {
- if (sOverrides.mMyUserIdProvider != null) {
- return sOverrides.mMyUserIdProvider;
- }
- return super.createMyUserIdProvider();
- }
-
- @Override
protected CrossProfileIntentsChecker createCrossProfileIntentsChecker() {
if (sOverrides.mCrossProfileIntentsChecker != null) {
return sOverrides.mCrossProfileIntentsChecker;
@@ -103,13 +95,25 @@
return super.isVoiceInteraction();
}
+ // TODO: Remove this and override safelyStartActivityInternal() instead.
@Override
- public void safelyStartActivity(TargetInfo cti) {
+ public void safelyStartActivityAsUser(TargetInfo cti, UserHandle user,
+ @Nullable Bundle options) {
if (sOverrides.onSafelyStartCallback != null &&
sOverrides.onSafelyStartCallback.apply(cti)) {
return;
}
- super.safelyStartActivity(cti);
+ super.safelyStartActivityAsUser(cti, user, options);
+ }
+
+ @Override
+ public void safelyStartActivityInternal(TargetInfo cti, UserHandle user,
+ @Nullable Bundle options) {
+ if (sOverrides.onSafelyStartInternalCallback != null
+ && sOverrides.onSafelyStartInternalCallback.apply(user)) {
+ return;
+ }
+ super.safelyStartActivityInternal(cti, user, options);
}
@Override
@@ -135,11 +139,29 @@
}
@Override
+ protected UserHandle getPersonalProfileUserHandle() {
+ return super.getPersonalProfileUserHandle();
+ }
+
+ @Override
protected UserHandle getWorkProfileUserHandle() {
return sOverrides.workProfileUserHandle;
}
@Override
+ protected UserHandle getCloneProfileUserHandle() {
+ return sOverrides.cloneProfileUserHandle;
+ }
+
+ @Override
+ protected UserHandle getTabOwnerUserHandleForLaunch() {
+ if (sOverrides.tabOwnerUserHandleForLaunch == null) {
+ return super.getTabOwnerUserHandleForLaunch();
+ }
+ return sOverrides.tabOwnerUserHandleForLaunch;
+ }
+
+ @Override
public void startActivityAsUser(Intent intent, Bundle options, UserHandle user) {
super.startActivityAsUser(intent, options, user);
}
@@ -153,24 +175,29 @@
@SuppressWarnings("Since15")
public Function<PackageManager, PackageManager> createPackageManager;
public Function<TargetInfo, Boolean> onSafelyStartCallback;
+ public Function<UserHandle, Boolean> onSafelyStartInternalCallback;
public ResolverListController resolverListController;
public ResolverListController workResolverListController;
public Boolean isVoiceInteraction;
public UserHandle workProfileUserHandle;
+ public UserHandle cloneProfileUserHandle;
+ public UserHandle tabOwnerUserHandleForLaunch;
public Integer myUserId;
public boolean hasCrossProfileIntents;
public boolean isQuietModeEnabled;
public QuietModeManager mQuietModeManager;
- public MyUserIdProvider mMyUserIdProvider;
public CrossProfileIntentsChecker mCrossProfileIntentsChecker;
public void reset() {
onSafelyStartCallback = null;
+ onSafelyStartInternalCallback = null;
isVoiceInteraction = null;
createPackageManager = null;
resolverListController = mock(ResolverListController.class);
workResolverListController = mock(ResolverListController.class);
workProfileUserHandle = null;
+ cloneProfileUserHandle = null;
+ tabOwnerUserHandleForLaunch = null;
myUserId = null;
hasCrossProfileIntents = true;
isQuietModeEnabled = false;
@@ -197,13 +224,6 @@
}
};
- mMyUserIdProvider = new MyUserIdProvider() {
- @Override
- public int getMyUserId() {
- return myUserId != null ? myUserId : UserHandle.myUserId();
- }
- };
-
mCrossProfileIntentsChecker = mock(CrossProfileIntentsChecker.class);
when(mCrossProfileIntentsChecker.hasCrossProfileIntents(any(), anyInt(), anyInt()))
.thenAnswer(invocation -> hasCrossProfileIntents);