diff options
author | 2025-03-05 10:08:46 -0800 | |
---|---|---|
committer | 2025-03-05 10:08:46 -0800 | |
commit | 800e5f08ccdde397b2ae935e3b176c6b88a46ed6 (patch) | |
tree | 2c275864ba8c90b495704b8a9b65e111e2856229 | |
parent | 72e54720cf3306584e0d0e3358d4085b4eb3acdf (diff) | |
parent | 390acf6d34df54a69051505b8288689368d5c24f (diff) |
Merge "Fix getCanForwardToProfileIdMapInternal implementation to resolve cross profile access." into main
-rw-r--r-- | src/com/android/documentsui/UserManagerState.java | 432 | ||||
-rw-r--r-- | tests/unit/com/android/documentsui/UserManagerStateTest.java | 644 |
2 files changed, 617 insertions, 459 deletions
diff --git a/src/com/android/documentsui/UserManagerState.java b/src/com/android/documentsui/UserManagerState.java index b2bc418a9..d2ddae615 100644 --- a/src/com/android/documentsui/UserManagerState.java +++ b/src/com/android/documentsui/UserManagerState.java @@ -33,6 +33,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; import android.content.pm.UserProperties; import android.graphics.drawable.Drawable; import android.os.Build; @@ -47,12 +48,12 @@ import androidx.annotation.VisibleForTesting; import com.android.documentsui.base.Features; import com.android.documentsui.base.UserId; -import com.android.documentsui.util.CrossProfileUtils; import com.android.documentsui.util.VersionUtils; import com.android.modules.utils.build.SdkLevel; import com.google.common.base.Objects; +import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -63,26 +64,23 @@ public interface UserManagerState { /** * Returns the {@link UserId} of each profile which should be queried for documents. This will - * always - * include {@link UserId#CURRENT_USER}. + * always include {@link UserId#CURRENT_USER}. */ List<UserId> getUserIds(); - /** - * Returns mapping between the {@link UserId} and the label for the profile - */ + /** Returns mapping between the {@link UserId} and the label for the profile */ Map<UserId, String> getUserIdToLabelMap(); /** * Returns mapping between the {@link UserId} and the drawable badge for the profile * - * returns {@code null} for non-profile userId + * <p>returns {@code null} for non-profile userId */ Map<UserId, Drawable> getUserIdToBadgeMap(); /** - * Returns a map of {@link UserId} to boolean value indicating whether - * the {@link UserId}.CURRENT_USER can forward {@link Intent} to that {@link UserId} + * Returns a map of {@link UserId} to boolean value indicating whether the {@link + * UserId}.CURRENT_USER can forward {@link Intent} to that {@link UserId} */ Map<UserId, Boolean> getCanForwardToProfileIdMap(Intent intent); @@ -92,31 +90,24 @@ public interface UserManagerState { * * @param userId {@link UserId} for the profile for which the availability status changed * @param action {@link Intent}.ACTION_PROFILE_UNAVAILABLE and {@link - * Intent}.ACTION_PROFILE_AVAILABLE, {@link Intent}.ACTION_PROFILE_ADDED} and - * {@link - * Intent}.ACTION_PROFILE_REMOVED} + * Intent}.ACTION_PROFILE_AVAILABLE, {@link Intent}.ACTION_PROFILE_ADDED} and {@link + * Intent}.ACTION_PROFILE_REMOVED} */ void onProfileActionStatusChange(String action, UserId userId); - /** - * Sets the intent that triggered the launch of the DocsUI - */ + /** Sets the intent that triggered the launch of the DocsUI */ void setCurrentStateIntent(Intent intent); /** Returns true if there are hidden profiles */ boolean areHiddenInQuietModeProfilesPresent(); - /** - * Creates an implementation of {@link UserManagerState}. - */ + /** Creates an implementation of {@link UserManagerState}. */ // TODO: b/314746383 Make this class a singleton static UserManagerState create(Context context) { return new RuntimeUserManagerState(context); } - /** - * Implementation of {@link UserManagerState} - */ + /** Implementation of {@link UserManagerState} */ final class RuntimeUserManagerState implements UserManagerState { private static final String TAG = "UserManagerState"; @@ -125,58 +116,63 @@ public interface UserManagerState { private final boolean mIsDeviceSupported; private final UserManager mUserManager; private final ConfigStore mConfigStore; + /** * List of all the {@link UserId} that have the {@link UserProperties.ShowInSharingSurfaces} * set as `SHOW_IN_SHARING_SURFACES_SEPARATE` OR it is a system/personal user */ @GuardedBy("mUserIds") private final List<UserId> mUserIds = new ArrayList<>(); - /** - * Mapping between the {@link UserId} to the corresponding profile label - */ + + /** Mapping between the {@link UserId} to the corresponding profile label */ @GuardedBy("mUserIdToLabelMap") private final Map<UserId, String> mUserIdToLabelMap = new HashMap<>(); - /** - * Mapping between the {@link UserId} to the corresponding profile badge - */ + + /** Mapping between the {@link UserId} to the corresponding profile badge */ @GuardedBy("mUserIdToBadgeMap") private final Map<UserId, Drawable> mUserIdToBadgeMap = new HashMap<>(); + /** * Map containing {@link UserId}, other than that of the current user, as key and boolean * denoting whether it is accessible by the current user or not as value */ - @GuardedBy("mCanFrowardToProfileIdMap") - private final Map<UserId, Boolean> mCanFrowardToProfileIdMap = new HashMap<>(); + @GuardedBy("mCanForwardToProfileIdMap") + private final Map<UserId, Boolean> mCanForwardToProfileIdMap = new HashMap<>(); private Intent mCurrentStateIntent; - private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - synchronized (mUserIds) { - mUserIds.clear(); - } - synchronized (mUserIdToLabelMap) { - mUserIdToLabelMap.clear(); - } - synchronized (mUserIdToBadgeMap) { - mUserIdToBadgeMap.clear(); - } - synchronized (mCanFrowardToProfileIdMap) { - mCanFrowardToProfileIdMap.clear(); - } - } - }; - + private final BroadcastReceiver mIntentReceiver = + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + synchronized (mUserIds) { + mUserIds.clear(); + } + synchronized (mUserIdToLabelMap) { + mUserIdToLabelMap.clear(); + } + synchronized (mUserIdToBadgeMap) { + mUserIdToBadgeMap.clear(); + } + synchronized (mCanForwardToProfileIdMap) { + mCanForwardToProfileIdMap.clear(); + } + } + }; private RuntimeUserManagerState(Context context) { - this(context, UserId.CURRENT_USER, + this( + context, + UserId.CURRENT_USER, Features.CROSS_PROFILE_TABS && isDeviceSupported(context), DocumentsApplication.getConfigStore()); } @VisibleForTesting - RuntimeUserManagerState(Context context, UserId currentUser, boolean isDeviceSupported, + RuntimeUserManagerState( + Context context, + UserId currentUser, + boolean isDeviceSupported, ConfigStore configStore) { mContext = context.getApplicationContext(); mCurrentUser = checkNotNull(currentUser); @@ -226,11 +222,11 @@ public interface UserManagerState { @Override public Map<UserId, Boolean> getCanForwardToProfileIdMap(Intent intent) { - synchronized (mCanFrowardToProfileIdMap) { - if (mCanFrowardToProfileIdMap.isEmpty()) { + synchronized (mCanForwardToProfileIdMap) { + if (mCanForwardToProfileIdMap.isEmpty()) { getCanForwardToProfileIdMapInternal(intent); } - return mCanFrowardToProfileIdMap; + return mCanForwardToProfileIdMap; } } @@ -238,8 +234,8 @@ public interface UserManagerState { @SuppressLint("NewApi") public void onProfileActionStatusChange(String action, UserId userId) { if (!SdkLevel.isAtLeastV()) return; - UserProperties userProperties = mUserManager.getUserProperties( - UserHandle.of(userId.getIdentifier())); + UserProperties userProperties = + mUserManager.getUserProperties(UserHandle.of(userId.getIdentifier())); if (userProperties.getShowInQuietMode() != UserProperties.SHOW_IN_QUIET_MODE_HIDDEN) { return; } @@ -265,19 +261,37 @@ public interface UserManagerState { mUserIdToBadgeMap.put(userId, getProfileBadge(userId)); } } - synchronized (mCanFrowardToProfileIdMap) { - if (!mCanFrowardToProfileIdMap.containsKey(userId)) { - if (userId.getIdentifier() == ActivityManager.getCurrentUser() - || isCrossProfileContentSharingStrategyDelegatedFromParent( - UserHandle.of(userId.getIdentifier())) - || CrossProfileUtils.getCrossProfileResolveInfo(mCurrentUser, - mContext.getPackageManager(), mCurrentStateIntent, mContext, - mConfigStore.isPrivateSpaceInDocsUIEnabled()) != null) { - mCanFrowardToProfileIdMap.put(userId, true); + synchronized (mCanForwardToProfileIdMap) { + if (!mCanForwardToProfileIdMap.containsKey(userId)) { + + UserHandle handle = UserHandle.of(userId.getIdentifier()); + + // Decide if to use the parent's access, or this handle's access. + if (isCrossProfileContentSharingStrategyDelegatedFromParent(handle)) { + UserHandle parentHandle = mUserManager.getProfileParent(handle); + // Couldn't resolve parent to check access, so fail closed. + if (parentHandle == null) { + mCanForwardToProfileIdMap.put(userId, false); + } else if (mCurrentUser.getIdentifier() + == parentHandle.getIdentifier()) { + // Check if the parent is the current user, if so this profile + // is also accessible. + mCanForwardToProfileIdMap.put(userId, true); + + } else { + UserId parent = UserId.of(parentHandle); + mCanForwardToProfileIdMap.put( + userId, + doesCrossProfileForwardingActivityExistForUser( + mCurrentStateIntent, parent)); + } } else { - mCanFrowardToProfileIdMap.put(userId, false); + // Update the profile map for this profile. + mCanForwardToProfileIdMap.put( + userId, + doesCrossProfileForwardingActivityExistForUser( + mCurrentStateIntent, userId)); } - } } } else { @@ -298,8 +312,8 @@ public interface UserManagerState { for (UserId userId : getUserIds()) { if (mUserManager - .getUserProperties(UserHandle.of(userId.getIdentifier())) - .getShowInQuietMode() + .getUserProperties(UserHandle.of(userId.getIdentifier())) + .getShowInQuietMode() == UserProperties.SHOW_IN_QUIET_MODE_HIDDEN) { return true; } @@ -345,7 +359,7 @@ public interface UserManagerState { // returned should satisfy both the following conditions: // 1. It has user property SHOW_IN_SHARING_SURFACES_SEPARATE // 2. Quite mode is not enabled, if it is enabled then the profile's user - // property is not SHOW_IN_QUIET_MODE_HIDDEN + // property is not SHOW_IN_QUIET_MODE_HIDDEN if (isProfileAllowed(userHandle)) { result.add(UserId.of(userHandle)); } @@ -362,15 +376,17 @@ public interface UserManagerState { * @param userHandle The ID of the user. * @return {@code true} if the package is installed for the user, {@code false} otherwise. */ - @RequiresPermission(anyOf = { - "android.permission.MANAGE_USERS", - "android.permission.INTERACT_ACROSS_USERS" - }) + @RequiresPermission( + anyOf = { + "android.permission.MANAGE_USERS", + "android.permission.INTERACT_ACROSS_USERS" + }) private boolean isPackageInstalledForUser(UserHandle userHandle) { String packageName = mContext.getPackageName(); try { - Context userPackageContext = mContext.createPackageContextAsUser( - mContext.getPackageName(), 0 /* flags */, userHandle); + Context userPackageContext = + mContext.createPackageContextAsUser( + mContext.getPackageName(), 0 /* flags */, userHandle); return userPackageContext != null; } catch (PackageManager.NameNotFoundException e) { Log.w(TAG, "Package " + packageName + " not found for user " + userHandle); @@ -396,17 +412,22 @@ public interface UserManagerState { * @return {@code true} if the profile should be allowed, {@code false} otherwise. */ @SuppressLint("NewApi") - @RequiresPermission(anyOf = { - "android.permission.MANAGE_USERS", - "android.permission.INTERACT_ACROSS_USERS" - }) + @RequiresPermission( + anyOf = { + "android.permission.MANAGE_USERS", + "android.permission.INTERACT_ACROSS_USERS" + }) private boolean isProfileAllowed(UserHandle userHandle) { final UserProperties userProperties = mUserManager.getUserProperties(userHandle); // 1. Check if the package is installed for the user if (!isPackageInstalledForUser(userHandle)) { - Log.w(TAG, "Package " + mContext.getPackageName() - + " is not installed for user " + userHandle); + Log.w( + TAG, + "Package " + + mContext.getPackageName() + + " is not installed for user " + + userHandle); return false; } @@ -415,8 +436,9 @@ public interface UserManagerState { == UserProperties.SHOW_IN_SHARING_SURFACES_SEPARATE) { // Return true if profile is not in quiet mode or if it is in quiet mode // then its user properties do not require it to be hidden - return !isQuietModeEnabledForUser(userHandle) || userProperties.getShowInQuietMode() - != UserProperties.SHOW_IN_QUIET_MODE_HIDDEN; + return !isQuietModeEnabledForUser(userHandle) + || userProperties.getShowInQuietMode() + != UserProperties.SHOW_IN_QUIET_MODE_HIDDEN; } return false; @@ -439,9 +461,12 @@ public interface UserManagerState { result.add(0, systemUser); } else { if (DEBUG) { - Log.w(TAG, "The current user " + UserId.CURRENT_USER - + " is neither system nor managed user. has system user: " - + (systemUser != null)); + Log.w( + TAG, + "The current user " + + UserId.CURRENT_USER + + " is neither system nor managed user. has system user: " + + (systemUser != null)); } } } @@ -477,13 +502,13 @@ public interface UserManagerState { for (UserId userId : userIds) { if (mUserManager.isManagedProfile(userId.getIdentifier())) { synchronized (mUserIdToLabelMap) { - mUserIdToLabelMap.put(userId, - getEnterpriseString(WORK_TAB, R.string.work_tab)); + mUserIdToLabelMap.put( + userId, getEnterpriseString(WORK_TAB, R.string.work_tab)); } } else { synchronized (mUserIdToLabelMap) { - mUserIdToLabelMap.put(userId, - getEnterpriseString(PERSONAL_TAB, R.string.personal_tab)); + mUserIdToLabelMap.put( + userId, getEnterpriseString(PERSONAL_TAB, R.string.personal_tab)); } } } @@ -495,8 +520,9 @@ public interface UserManagerState { return getEnterpriseString(PERSONAL_TAB, R.string.personal_tab); } try { - Context userContext = mContext.createContextAsUser( - UserHandle.of(userId.getIdentifier()), 0 /* flags */); + Context userContext = + mContext.createContextAsUser( + UserHandle.of(userId.getIdentifier()), 0 /* flags */); UserManager userManagerAsUser = userContext.getSystemService(UserManager.class); if (userManagerAsUser == null) { Log.e(TAG, "cannot obtain user manager"); @@ -524,9 +550,8 @@ public interface UserManagerState { Log.e(TAG, "can not get device policy manager"); return mContext.getString(defaultStringId); } - return dpm.getResources().getString( - updatableStringId, - () -> mContext.getString(defaultStringId)); + return dpm.getResources() + .getString(updatableStringId, () -> mContext.getString(defaultStringId)); } private void getUserIdToBadgeMapInternal() { @@ -561,8 +586,10 @@ public interface UserManagerState { for (UserId userId : userIds) { if (mUserManager.isManagedProfile(userId.getIdentifier())) { synchronized (mUserIdToBadgeMap) { - mUserIdToBadgeMap.put(userId, - SdkLevel.isAtLeastT() ? getWorkProfileBadge() + mUserIdToBadgeMap.put( + userId, + SdkLevel.isAtLeastT() + ? getWorkProfileBadge() : mContext.getDrawable(R.drawable.ic_briefcase)); } } @@ -575,8 +602,9 @@ public interface UserManagerState { return null; } try { - Context userContext = mContext.createContextAsUser( - UserHandle.of(userId.getIdentifier()), 0 /* flags */); + Context userContext = + mContext.createContextAsUser( + UserHandle.of(userId.getIdentifier()), 0 /* flags */); UserManager userManagerAsUser = userContext.getSystemService(UserManager.class); if (userManagerAsUser == null) { Log.e(TAG, "cannot obtain user manager"); @@ -592,86 +620,142 @@ public interface UserManagerState { @RequiresApi(Build.VERSION_CODES.TIRAMISU) private Drawable getWorkProfileBadge() { DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class); - Drawable drawable = dpm.getResources().getDrawable(WORK_PROFILE_ICON, SOLID_COLORED, - () -> - mContext.getDrawable(R.drawable.ic_briefcase)); + Drawable drawable = + dpm.getResources() + .getDrawable( + WORK_PROFILE_ICON, + SOLID_COLORED, + () -> mContext.getDrawable(R.drawable.ic_briefcase)); return drawable; } + /** + * Updates Cross Profile access for all UserProfiles in {@code getUserIds()} + * + * <p>This method looks at a variety of situations for each Profile and decides if the + * profile's content is accessible by the current process owner user id. + * + * <ol> + * <li>UserProperties attributes for CrossProfileDelegation are checked first. When the + * profile delegates to the parent profile, the parent's access is used. + * <li>{@link CrossProfileIntentForwardingActivity}s are resolved via the process owner's + * PackageManager, and are considered when evaluating cross profile to the target + * profile. + * </ol> + * + * <p>In the event none of the above checks succeeds, the profile is considered to be + * inaccessible to the current process user. + * + * @param intent The intent Photopicker is currently running under, for + * CrossProfileForwardActivity checking. + */ private void getCanForwardToProfileIdMapInternal(Intent intent) { - // Versions less than V will not have the user properties required to determine whether - // cross profile check is delegated from parent or not - if (!SdkLevel.isAtLeastV()) { - getCanForwardToProfileIdMapPreV(intent); - return; - } - if (mUserManager == null) { - Log.e(TAG, "can not get user manager"); - return; - } - List<UserId> parentOrDelegatedFromParent = new ArrayList<>(); - List<UserId> canForwardToProfileIds = new ArrayList<>(); - List<UserId> noDelegation = new ArrayList<>(); + Map<UserId, Boolean> profileIsAccessibleToProcessOwner = new HashMap<>(); - List<UserId> userIds = getUserIds(); - for (UserId userId : userIds) { - final UserHandle userHandle = UserHandle.of(userId.getIdentifier()); - // Parent (personal) profile and all the child profiles that delegate cross profile - // content sharing check to parent can share among each other - if (userId.getIdentifier() == ActivityManager.getCurrentUser() - || isCrossProfileContentSharingStrategyDelegatedFromParent(userHandle)) { - parentOrDelegatedFromParent.add(userId); - } else { - noDelegation.add(userId); + List<UserId> delegatedFromParent = new ArrayList<>(); + + for (UserId userId : getUserIds()) { + + // Early exit, self is always accessible. + if (userId.getIdentifier() == mCurrentUser.getIdentifier()) { + profileIsAccessibleToProcessOwner.put(userId, true); + continue; } - } - if (noDelegation.size() > 1) { - Log.e(TAG, "There cannot be more than one profile delegating cross profile " - + "content sharing check from self."); - } - - /* - * Cross profile resolve info need to be checked in the following 2 cases: - * 1. current user is either parent or delegates check to parent and the target user - * does not delegate to parent - * 2. current user does not delegate check to the parent and the target user is the - * parent profile - */ - UserId needToCheck = null; - if (parentOrDelegatedFromParent.contains(mCurrentUser) - && !noDelegation.isEmpty()) { - needToCheck = noDelegation.get(0); - } else if (mCurrentUser.getIdentifier() != ActivityManager.getCurrentUser()) { - final UserHandle parentProfile = mUserManager.getProfileParent( - UserHandle.of(mCurrentUser.getIdentifier())); - needToCheck = UserId.of(parentProfile); - } - - if (needToCheck != null && CrossProfileUtils.getCrossProfileResolveInfo(mCurrentUser, - mContext.getPackageManager(), intent, mContext, - mConfigStore.isPrivateSpaceInDocsUIEnabled()) != null) { - if (parentOrDelegatedFromParent.contains(needToCheck)) { - canForwardToProfileIds.addAll(parentOrDelegatedFromParent); - } else { - canForwardToProfileIds.add(needToCheck); + // CrossProfileContentSharingStrategyDelegatedFromParent is only V+ sdks. + if (SdkLevel.isAtLeastV() + && isCrossProfileContentSharingStrategyDelegatedFromParent( + UserHandle.of(userId.getIdentifier()))) { + delegatedFromParent.add(userId); + continue; } + + // Check for cross profile & add to the map. + profileIsAccessibleToProcessOwner.put( + userId, doesCrossProfileForwardingActivityExistForUser(intent, userId)); } - if (parentOrDelegatedFromParent.contains(mCurrentUser)) { - canForwardToProfileIds.addAll(parentOrDelegatedFromParent); + // For profiles that delegate their access to the parent, set the access for + // those profiles + // equal to the same as their parent. + for (UserId userId : delegatedFromParent) { + UserHandle parent = + mUserManager.getProfileParent(UserHandle.of(userId.getIdentifier())); + profileIsAccessibleToProcessOwner.put( + userId, + profileIsAccessibleToProcessOwner.getOrDefault( + UserId.of(parent), /* default= */ false)); } - for (UserId userId : userIds) { - synchronized (mCanFrowardToProfileIdMap) { - if (userId.equals(mCurrentUser)) { - mCanFrowardToProfileIdMap.put(userId, true); - continue; + synchronized (mCanForwardToProfileIdMap) { + mCanForwardToProfileIdMap.clear(); + for (Map.Entry<UserId, Boolean> entry : + profileIsAccessibleToProcessOwner.entrySet()) { + mCanForwardToProfileIdMap.put(entry.getKey(), entry.getValue()); + } + } + } + + /** + * Looks for a matching CrossProfileIntentForwardingActivity in the targetUserId for the + * given intent. + * + * @param intent The intent the forwarding activity needs to match. + * @param targetUserId The target user to check for. + * @return whether a CrossProfileIntentForwardingActivity could be found for the given + * intent, and user. + */ + private boolean doesCrossProfileForwardingActivityExistForUser( + Intent intent, UserId targetUserId) { + + final PackageManager pm = mContext.getPackageManager(); + final Intent intentToCheck = (Intent) intent.clone(); + intentToCheck.setComponent(null); + intentToCheck.setPackage(null); + + for (ResolveInfo resolveInfo : + pm.queryIntentActivities(intentToCheck, PackageManager.MATCH_DEFAULT_ONLY)) { + + if (resolveInfo.isCrossProfileIntentForwarderActivity()) { + /* + * IMPORTANT: This is a reflection based hack to ensure the profile is + * actually the installer of the CrossProfileIntentForwardingActivity. + * + * ResolveInfo.targetUserId exists, but is a hidden API not available to + * mainline modules, and no such API exists, so it is accessed via + * reflection below. All exceptions are caught to protect against + * reflection related issues such as: + * NoSuchFieldException / IllegalAccessException / SecurityException. + * + * In the event of an exception, the code fails "closed" for the current + * profile to avoid showing content that should not be visible. + */ + try { + Field targetUserIdField = + resolveInfo.getClass().getDeclaredField("targetUserId"); + targetUserIdField.setAccessible(true); + int activityTargetUserId = (int) targetUserIdField.get(resolveInfo); + + if (activityTargetUserId == targetUserId.getIdentifier()) { + + // Found a match for this profile + return true; + } + + } catch (NoSuchFieldException | IllegalAccessException | SecurityException ex) { + // Couldn't check the targetUserId via reflection, so fail without + // further iterations. + Log.e(TAG, "Could not access targetUserId via reflection.", ex); + return false; + } catch (Exception ex) { + Log.e(TAG, "Exception occurred during cross profile checks", ex); } - mCanFrowardToProfileIdMap.put(userId, canForwardToProfileIds.contains(userId)); } } + + // No match found, so return false. + return false; } @SuppressLint("NewApi") @@ -691,30 +775,12 @@ public interface UserManagerState { == UserProperties.CROSS_PROFILE_CONTENT_SHARING_DELEGATE_FROM_PARENT; } - private void getCanForwardToProfileIdMapPreV(Intent intent) { - // There only two profiles pre V - List<UserId> userIds = getUserIds(); - for (UserId userId : userIds) { - synchronized (mCanFrowardToProfileIdMap) { - if (mCurrentUser.equals(userId)) { - mCanFrowardToProfileIdMap.put(userId, true); - } else { - mCanFrowardToProfileIdMap.put(userId, - CrossProfileUtils.getCrossProfileResolveInfo( - mCurrentUser, mContext.getPackageManager(), intent, - mContext, mConfigStore.isPrivateSpaceInDocsUIEnabled()) - != null); - } - } - } - } - private static boolean isDeviceSupported(Context context) { - // The feature requires Android R DocumentsContract APIs and INTERACT_ACROSS_USERS_FULL - // permission. + // The feature requires Android R DocumentsContract APIs and + // INTERACT_ACROSS_USERS_FULL permission. return VersionUtils.isAtLeastR() && context.checkSelfPermission(Manifest.permission.INTERACT_ACROSS_USERS) - == PackageManager.PERMISSION_GRANTED; + == PackageManager.PERMISSION_GRANTED; } } } diff --git a/tests/unit/com/android/documentsui/UserManagerStateTest.java b/tests/unit/com/android/documentsui/UserManagerStateTest.java index 6f869dcd5..9d629c574 100644 --- a/tests/unit/com/android/documentsui/UserManagerStateTest.java +++ b/tests/unit/com/android/documentsui/UserManagerStateTest.java @@ -23,8 +23,11 @@ import static com.android.documentsui.DevicePolicyResources.Strings.WORK_TAB; import static com.google.common.truth.Truth.assertWithMessage; +import static org.junit.Assume.assumeTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -64,16 +67,37 @@ import java.util.Map; @SdkSuppress(minSdkVersion = 31, codeName = "S") public class UserManagerStateTest { + /** + * Class that exposes the @hide api [targetUserId] in order to supply proper values for + * reflection based code that is inspecting this field. + * + * @property targetUserId + */ + private static class ReflectedResolveInfo extends ResolveInfo { + + public int targetUserId; + + ReflectedResolveInfo(int targetUserId) { + this.targetUserId = targetUserId; + } + + @Override + public boolean isCrossProfileIntentForwarderActivity() { + return true; + } + } + private static final String PERSONAL = "Personal"; private static final String WORK = "Work"; private static final String PRIVATE = "Private"; private static final String PACKAGE_NAME = "com.android.documentsui"; /** - * Assume that the current user is SYSTEM_USER. - * For HSUM targets, the primary user is set as the system user. + * Assume that the current user is SYSTEM_USER. For HSUM targets, the primary user is set as the + * system user. */ private final int mCurrentUserId = UserHandle.myUserId(); + private final UserHandle mPrimaryUser = UserHandle.of(mCurrentUserId); private final UserHandle mSystemUser = mPrimaryUser == null ? UserHandle.SYSTEM : mPrimaryUser; private final UserHandle mManagedUser = UserHandle.of(mCurrentUserId + 10); @@ -81,12 +105,15 @@ public class UserManagerStateTest { private final UserHandle mOtherUser = UserHandle.of(mCurrentUserId + 30); private final UserHandle mNormalUser = UserHandle.of(mCurrentUserId + 40); - private final ResolveInfo mMockInfo1 = mock(ResolveInfo.class); - private final ResolveInfo mMockInfo2 = mock(ResolveInfo.class); - private final ResolveInfo mMockInfo3 = mock(ResolveInfo.class); + private final ResolveInfo mMockInfoPrimaryUser = + new ReflectedResolveInfo(mPrimaryUser.getIdentifier()); + private final ResolveInfo mMockInfoManagedUser = + new ReflectedResolveInfo(mManagedUser.getIdentifier()); + private final ResolveInfo mMockInfoPrivateUser = + new ReflectedResolveInfo(mPrivateUser.getIdentifier()); private final Context mMockContext = mock(Context.class); - private final Intent mMockIntent = mock(Intent.class); + private final Intent mMockIntent = new Intent(); private final UserManager mMockUserManager = UserManagers.create(); private final PackageManager mMockPackageManager = mock(PackageManager.class); private final DevicePolicyManager mDevicePolicyManager = mock(DevicePolicyManager.class); @@ -95,6 +122,8 @@ public class UserManagerStateTest { @Before public void setup() throws Exception { when(mMockContext.getApplicationContext()).thenReturn(mMockContext); + when(mMockContext.createContextAsUser(any(UserHandle.class), anyInt())) + .thenReturn(mMockContext); when(mMockUserManager.isManagedProfile(mManagedUser.getIdentifier())).thenReturn(true); when(mMockUserManager.isManagedProfile(mSystemUser.getIdentifier())).thenReturn(false); @@ -102,54 +131,60 @@ public class UserManagerStateTest { when(mMockUserManager.isManagedProfile(mOtherUser.getIdentifier())).thenReturn(false); if (SdkLevel.isAtLeastV()) { - UserProperties systemUserProperties = new UserProperties.Builder() - .setShowInSharingSurfaces(UserProperties.SHOW_IN_SHARING_SURFACES_SEPARATE) - .setCrossProfileContentSharingStrategy( - UserProperties.CROSS_PROFILE_CONTENT_SHARING_NO_DELEGATION) - .build(); - UserProperties managedUserProperties = new UserProperties.Builder() - .setShowInSharingSurfaces(UserProperties.SHOW_IN_SHARING_SURFACES_SEPARATE) - .setCrossProfileContentSharingStrategy( - UserProperties.CROSS_PROFILE_CONTENT_SHARING_NO_DELEGATION) - .setShowInQuietMode(UserProperties.SHOW_IN_QUIET_MODE_PAUSED) - .build(); - UserProperties privateUserProperties = new UserProperties.Builder() - .setShowInSharingSurfaces(UserProperties.SHOW_IN_SHARING_SURFACES_SEPARATE) - .setCrossProfileContentSharingStrategy( - UserProperties.CROSS_PROFILE_CONTENT_SHARING_DELEGATE_FROM_PARENT) - .setShowInQuietMode(UserProperties.SHOW_IN_QUIET_MODE_HIDDEN) - .build(); - UserProperties otherUserProperties = new UserProperties.Builder() - .setShowInSharingSurfaces(UserProperties.SHOW_IN_SHARING_SURFACES_WITH_PARENT) - .setCrossProfileContentSharingStrategy( - UserProperties.CROSS_PROFILE_CONTENT_SHARING_DELEGATE_FROM_PARENT) - .build(); - UserProperties normalUserProperties = new UserProperties.Builder() - .setShowInSharingSurfaces(UserProperties.SHOW_IN_SHARING_SURFACES_NO) - .setCrossProfileContentSharingStrategy( - UserProperties.CROSS_PROFILE_CONTENT_SHARING_DELEGATE_FROM_PARENT) - .build(); + UserProperties systemUserProperties = + new UserProperties.Builder() + .setShowInSharingSurfaces( + UserProperties.SHOW_IN_SHARING_SURFACES_SEPARATE) + .setCrossProfileContentSharingStrategy( + UserProperties.CROSS_PROFILE_CONTENT_SHARING_NO_DELEGATION) + .build(); + UserProperties managedUserProperties = + new UserProperties.Builder() + .setShowInSharingSurfaces( + UserProperties.SHOW_IN_SHARING_SURFACES_SEPARATE) + .setCrossProfileContentSharingStrategy( + UserProperties.CROSS_PROFILE_CONTENT_SHARING_NO_DELEGATION) + .setShowInQuietMode(UserProperties.SHOW_IN_QUIET_MODE_PAUSED) + .build(); + UserProperties privateUserProperties = + new UserProperties.Builder() + .setShowInSharingSurfaces( + UserProperties.SHOW_IN_SHARING_SURFACES_SEPARATE) + .setCrossProfileContentSharingStrategy( + UserProperties + .CROSS_PROFILE_CONTENT_SHARING_DELEGATE_FROM_PARENT) + .setShowInQuietMode(UserProperties.SHOW_IN_QUIET_MODE_HIDDEN) + .build(); + UserProperties otherUserProperties = + new UserProperties.Builder() + .setShowInSharingSurfaces( + UserProperties.SHOW_IN_SHARING_SURFACES_WITH_PARENT) + .setCrossProfileContentSharingStrategy( + UserProperties + .CROSS_PROFILE_CONTENT_SHARING_DELEGATE_FROM_PARENT) + .build(); + UserProperties normalUserProperties = + new UserProperties.Builder() + .setShowInSharingSurfaces(UserProperties.SHOW_IN_SHARING_SURFACES_NO) + .setCrossProfileContentSharingStrategy( + UserProperties + .CROSS_PROFILE_CONTENT_SHARING_DELEGATE_FROM_PARENT) + .build(); when(mMockUserManager.getUserProperties(mSystemUser)).thenReturn(systemUserProperties); - when(mMockUserManager.getUserProperties(mManagedUser)).thenReturn( - managedUserProperties); - when(mMockUserManager.getUserProperties(mPrivateUser)).thenReturn( - privateUserProperties); + when(mMockUserManager.getUserProperties(mManagedUser)) + .thenReturn(managedUserProperties); + when(mMockUserManager.getUserProperties(mPrivateUser)) + .thenReturn(privateUserProperties); when(mMockUserManager.getUserProperties(mOtherUser)).thenReturn(otherUserProperties); when(mMockUserManager.getUserProperties(mNormalUser)).thenReturn(normalUserProperties); } when(mMockUserManager.getProfileParent(mSystemUser)).thenReturn(null); - when(mMockUserManager.getProfileParent(mManagedUser)).thenReturn(mSystemUser); - when(mMockUserManager.getProfileParent(mPrivateUser)).thenReturn(mSystemUser); - when(mMockUserManager.getProfileParent(mOtherUser)).thenReturn(mSystemUser); + when(mMockUserManager.getProfileParent(mManagedUser)).thenReturn(mPrimaryUser); + when(mMockUserManager.getProfileParent(mPrivateUser)).thenReturn(mPrimaryUser); + when(mMockUserManager.getProfileParent(mOtherUser)).thenReturn(mPrimaryUser); when(mMockUserManager.getProfileParent(mNormalUser)).thenReturn(null); - if (SdkLevel.isAtLeastR()) { - when(mMockInfo1.isCrossProfileIntentForwarderActivity()).thenReturn(true); - when(mMockInfo2.isCrossProfileIntentForwarderActivity()).thenReturn(false); - when(mMockInfo3.isCrossProfileIntentForwarderActivity()).thenReturn(false); - } - when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager); when(mMockContext.getSystemServiceName(UserManager.class)).thenReturn("mMockUserManager"); when(mMockContext.getSystemService(UserManager.class)).thenReturn(mMockUserManager); @@ -157,22 +192,25 @@ public class UserManagerStateTest { .thenReturn(Context.DEVICE_POLICY_SERVICE); when(mMockContext.getSystemService(Context.DEVICE_POLICY_SERVICE)) .thenReturn(mDevicePolicyManager); - when(mMockContext.getResources()).thenReturn( - InstrumentationRegistry.getInstrumentation().getTargetContext().getResources()); + when(mMockContext.getResources()) + .thenReturn( + InstrumentationRegistry.getInstrumentation() + .getTargetContext() + .getResources()); when(mMockContext.getPackageName()).thenReturn(PACKAGE_NAME); - when(mMockContext.createPackageContextAsUser(PACKAGE_NAME, 0, mSystemUser)).thenReturn( - mMockContext); - when(mMockContext.createPackageContextAsUser(PACKAGE_NAME, 0, mManagedUser)).thenReturn( - mMockContext); - when(mMockContext.createPackageContextAsUser(PACKAGE_NAME, 0, mPrivateUser)).thenReturn( - mMockContext); - when(mMockContext.createPackageContextAsUser(PACKAGE_NAME, 0, mOtherUser)).thenReturn( - mMockContext); - when(mMockContext.createPackageContextAsUser(PACKAGE_NAME, 0, mNormalUser)).thenReturn( - mMockContext); - when(mMockContext.createPackageContextAsUser(PACKAGE_NAME, 0, mPrimaryUser)).thenReturn( - mMockContext); + when(mMockContext.createPackageContextAsUser(PACKAGE_NAME, 0, mSystemUser)) + .thenReturn(mMockContext); + when(mMockContext.createPackageContextAsUser(PACKAGE_NAME, 0, mManagedUser)) + .thenReturn(mMockContext); + when(mMockContext.createPackageContextAsUser(PACKAGE_NAME, 0, mPrivateUser)) + .thenReturn(mMockContext); + when(mMockContext.createPackageContextAsUser(PACKAGE_NAME, 0, mOtherUser)) + .thenReturn(mMockContext); + when(mMockContext.createPackageContextAsUser(PACKAGE_NAME, 0, mNormalUser)) + .thenReturn(mMockContext); + when(mMockContext.createPackageContextAsUser(PACKAGE_NAME, 0, mPrimaryUser)) + .thenReturn(mMockContext); } @Test @@ -181,48 +219,52 @@ public class UserManagerStateTest { initializeUserManagerState(currentUser, Lists.newArrayList(mSystemUser)); assertWithMessage("getUserIds returns unexpected list of user ids") - .that(mUserManagerState.getUserIds()).containsExactly(UserId.of(mSystemUser)); + .that(mUserManagerState.getUserIds()) + .containsExactly(UserId.of(mSystemUser)); } @Test public void testGetUserIds_allProfilesCurrentUserSystem_allShowInSharingSurfacesSeparate() { if (!SdkLevel.isAtLeastV()) return; UserId currentUser = UserId.of(mSystemUser); - initializeUserManagerState(currentUser, - Lists.newArrayList(mSystemUser, mManagedUser, mPrivateUser, mOtherUser, - mNormalUser)); + initializeUserManagerState( + currentUser, + Lists.newArrayList( + mSystemUser, mManagedUser, mPrivateUser, mOtherUser, mNormalUser)); assertWithMessage("getUserIds returns unexpected list of user ids") .that(mUserManagerState.getUserIds()) - .containsExactly(UserId.of(mSystemUser), UserId.of(mManagedUser), - UserId.of(mPrivateUser)); + .containsExactly( + UserId.of(mSystemUser), UserId.of(mManagedUser), UserId.of(mPrivateUser)); } @Test public void testGetUserIds_allProfilesCurrentUserManaged_allShowInSharingSurfacesSeparate() { if (!SdkLevel.isAtLeastV()) return; UserId currentUser = UserId.of(mManagedUser); - initializeUserManagerState(currentUser, - Lists.newArrayList(mSystemUser, mManagedUser, mPrivateUser, mOtherUser, - mNormalUser)); + initializeUserManagerState( + currentUser, + Lists.newArrayList( + mSystemUser, mManagedUser, mPrivateUser, mOtherUser, mNormalUser)); assertWithMessage("getUserIds returns unexpected list of user ids") .that(mUserManagerState.getUserIds()) - .containsExactly(UserId.of(mSystemUser), UserId.of(mManagedUser), - UserId.of(mPrivateUser)); + .containsExactly( + UserId.of(mSystemUser), UserId.of(mManagedUser), UserId.of(mPrivateUser)); } @Test public void testGetUserIds_allProfilesCurrentUserPrivate_allShowInSharingSurfacesSeparate() { if (!SdkLevel.isAtLeastV()) return; UserId currentUser = UserId.of(mPrivateUser); - initializeUserManagerState(currentUser, + initializeUserManagerState( + currentUser, Lists.newArrayList(mSystemUser, mManagedUser, mPrivateUser, mOtherUser)); assertWithMessage("getUserIds returns unexpected list of user ids") .that(mUserManagerState.getUserIds()) - .containsExactly(UserId.of(mSystemUser), UserId.of(mManagedUser), - UserId.of(mPrivateUser)); + .containsExactly( + UserId.of(mSystemUser), UserId.of(mManagedUser), UserId.of(mPrivateUser)); } @Test @@ -291,7 +333,8 @@ public class UserManagerStateTest { @Test public void testGetUserIds_normalAndOtherUserCurrentUserNormal_returnsCurrentUser() { - // since both users do not have show in sharing surfaces separate, returns current user + // since both users do not have show in sharing surfaces separate, returns + // current user UserId currentUser = UserId.of(mNormalUser); initializeUserManagerState(currentUser, Lists.newArrayList(mOtherUser, mNormalUser)); @@ -308,7 +351,8 @@ public class UserManagerStateTest { initializeUserManagerState(currentUser, Lists.newArrayList(mSystemUser, mManagedUser)); assertWithMessage("getUserIds returns unexpected list of user ids") .that(mUserManagerState.getUserIds()) - .containsExactly(UserId.of(mSystemUser), UserId.of(mManagedUser)).inOrder(); + .containsExactly(UserId.of(mSystemUser), UserId.of(mManagedUser)) + .inOrder(); } @Test @@ -319,66 +363,79 @@ public class UserManagerStateTest { initializeUserManagerState(currentUser, Lists.newArrayList(mSystemUser, mManagedUser)); assertWithMessage("getUserIds returns unexpected list of user ids") .that(mUserManagerState.getUserIds()) - .containsExactly(UserId.of(mSystemUser), UserId.of(mManagedUser)).inOrder(); + .containsExactly(UserId.of(mSystemUser), UserId.of(mManagedUser)) + .inOrder(); } @Test public void testGetUserIds_managedAndSystemUserCurrentUserSystem_returnsBothInOrder() { - // Returns the both if there are system and managed users, regardless of input list order. + // Returns the both if there are system and managed users, regardless of input + // list order. if (SdkLevel.isAtLeastV()) return; UserId currentUser = UserId.of(mSystemUser); initializeUserManagerState(currentUser, Lists.newArrayList(mManagedUser, mSystemUser)); assertWithMessage("getUserIds returns unexpected list of user ids") .that(mUserManagerState.getUserIds()) - .containsExactly(UserId.of(mSystemUser), UserId.of(mManagedUser)).inOrder(); + .containsExactly(UserId.of(mSystemUser), UserId.of(mManagedUser)) + .inOrder(); } @Test public void testGetUserIds_otherAndManagedUserCurrentUserOtherPreV_returnsCurrentUser() { // When there is no system user, returns the current user. - // This is a case theoretically can happen but we don't expect. So we return the current + // This is a case theoretically can happen but we don't expect. So we return the + // current // user only. if (SdkLevel.isAtLeastV()) return; UserId currentUser = UserId.of(mOtherUser); initializeUserManagerState(currentUser, Lists.newArrayList(mOtherUser, mManagedUser)); assertWithMessage("getUserIds returns unexpected list of user ids") - .that(mUserManagerState.getUserIds()).containsExactly(currentUser); + .that(mUserManagerState.getUserIds()) + .containsExactly(currentUser); } @Test public void testGetUserIds_otherAndManagedUserCurrentUserOtherPostV_returnsManagedUser() { - // Only the users with show in sharing surfaces separate are eligible to be returned + // Only the users with show in sharing surfaces separate are eligible to be + // returned if (!SdkLevel.isAtLeastV()) return; UserId currentUser = UserId.of(mOtherUser); initializeUserManagerState(currentUser, Lists.newArrayList(mOtherUser, mManagedUser)); assertWithMessage("getUserIds returns unexpected list of user ids") - .that(mUserManagerState.getUserIds()).containsExactly(UserId.of(mManagedUser)); + .that(mUserManagerState.getUserIds()) + .containsExactly(UserId.of(mManagedUser)); } @Test public void testGetUserIds_otherAndManagedUserCurrentUserManaged_returnsCurrentUser() { // When there is no system user, returns the current user. - // This is a case theoretically can happen, but we don't expect. So we return the current + // This is a case theoretically can happen, but we don't expect. So we return + // the current // user only. UserId currentUser = UserId.of(mManagedUser); initializeUserManagerState(currentUser, Lists.newArrayList(mOtherUser, mManagedUser)); assertWithMessage("getUserIds returns unexpected list of user ids") - .that(mUserManagerState.getUserIds()).containsExactly(currentUser); + .that(mUserManagerState.getUserIds()) + .containsExactly(currentUser); } @Test public void testGetUserIds_unsupportedDeviceCurrent_returnsCurrentUser() { - // This test only tests for Android R or later. This test case always passes before R. + // This test only tests for Android R or later. This test case always passes + // before R. if (VersionUtils.isAtLeastR()) { // When permission is denied, only returns the current user. when(mMockContext.checkSelfPermission(Manifest.permission.INTERACT_ACROSS_USERS)) .thenReturn(PackageManager.PERMISSION_DENIED); UserId currentUser = UserId.of(mSystemUser); - when(mMockUserManager.getUserProfiles()).thenReturn( - Lists.newArrayList(mSystemUser, mManagedUser, mPrivateUser, mOtherUser)); + when(mMockUserManager.getUserProfiles()) + .thenReturn( + Lists.newArrayList( + mSystemUser, mManagedUser, mPrivateUser, mOtherUser)); mUserManagerState = UserManagerState.create(mMockContext); assertWithMessage("Unsupported device should have returned only the current user") - .that(mUserManagerState.getUserIds()).containsExactly(currentUser); + .that(mUserManagerState.getUserIds()) + .containsExactly(currentUser); } } @@ -386,7 +443,8 @@ public class UserManagerStateTest { public void testGetUserIds_returnCachedList() { // Returns all three if there are system, managed and private users. UserId currentUser = UserId.of(mSystemUser); - initializeUserManagerState(currentUser, + initializeUserManagerState( + currentUser, Lists.newArrayList(mSystemUser, mManagedUser, mPrivateUser, mOtherUser)); assertWithMessage("getUserIds does not return cached instance") .that(mUserManagerState.getUserIds()) @@ -394,47 +452,13 @@ public class UserManagerStateTest { } @Test - public void testGetCanForwardToProfileIdMap_systemUserCanForwardToAll() { - UserId currentUser = UserId.of(mSystemUser); - final List<ResolveInfo> mMockResolveInfoList = Lists.newArrayList(mMockInfo1, mMockInfo2); - if (SdkLevel.isAtLeastV()) { - initializeUserManagerState(currentUser, - Lists.newArrayList(mSystemUser, mManagedUser, mPrivateUser)); - when(mMockPackageManager.queryIntentActivitiesAsUser(mMockIntent, - PackageManager.MATCH_DEFAULT_ONLY, mSystemUser)).thenReturn( - mMockResolveInfoList); - } else { - initializeUserManagerState(currentUser, - Lists.newArrayList(mSystemUser, mManagedUser)); - when(mMockPackageManager.queryIntentActivities(mMockIntent, - PackageManager.MATCH_DEFAULT_ONLY)).thenReturn(mMockResolveInfoList); - } - - Map<UserId, Boolean> expectedCanForwardToProfileIdMap = new HashMap<>(); - expectedCanForwardToProfileIdMap.put(UserId.of(mSystemUser), true); - expectedCanForwardToProfileIdMap.put(UserId.of(mManagedUser), true); - if (SdkLevel.isAtLeastV()) { - expectedCanForwardToProfileIdMap.put(UserId.of(mPrivateUser), true); - } - - assertWithMessage("getCanForwardToProfileIdMap returns incorrect mappings") - .that(mUserManagerState.getCanForwardToProfileIdMap(mMockIntent)) - .isEqualTo(expectedCanForwardToProfileIdMap); - } - - @Test public void testGetCanForwardToProfileIdMap_systemUserCanForwardToManaged() { UserId currentUser = UserId.of(mSystemUser); initializeUserManagerState(currentUser, Lists.newArrayList(mSystemUser, mManagedUser)); - final List<ResolveInfo> mMockResolveInfoList = Lists.newArrayList(mMockInfo1, mMockInfo2); - if (SdkLevel.isAtLeastV()) { - when(mMockPackageManager.queryIntentActivitiesAsUser(mMockIntent, - PackageManager.MATCH_DEFAULT_ONLY, mSystemUser)).thenReturn( - mMockResolveInfoList); - } else { - when(mMockPackageManager.queryIntentActivities(mMockIntent, - PackageManager.MATCH_DEFAULT_ONLY)).thenReturn(mMockResolveInfoList); - } + final List<ResolveInfo> mMockResolveInfoList = Lists.newArrayList(mMockInfoManagedUser); + + when(mMockPackageManager.queryIntentActivities(any(Intent.class), anyInt())) + .thenReturn(mMockResolveInfoList); Map<UserId, Boolean> expectedCanForwardToProfileIdMap = new HashMap<>(); expectedCanForwardToProfileIdMap.put(UserId.of(mSystemUser), true); @@ -463,18 +487,19 @@ public class UserManagerStateTest { @Test public void testGetCanForwardToProfileIdMap_systemUserCanNotForwardToManagedUser() { UserId currentUser = UserId.of(mSystemUser); - final List<ResolveInfo> mMockResolveInfoList = Lists.newArrayList(mMockInfo2, mMockInfo3); + final List<ResolveInfo> mMockResolveInfoList = + Lists.newArrayList(mMockInfoPrivateUser, mMockInfoPrimaryUser); if (SdkLevel.isAtLeastV()) { - initializeUserManagerState(currentUser, - Lists.newArrayList(mSystemUser, mManagedUser, mPrivateUser)); - when(mMockPackageManager.queryIntentActivitiesAsUser(mMockIntent, - PackageManager.MATCH_DEFAULT_ONLY, mSystemUser)).thenReturn( - mMockResolveInfoList); + initializeUserManagerState( + currentUser, Lists.newArrayList(mSystemUser, mManagedUser, mPrivateUser)); + when(mMockPackageManager.queryIntentActivitiesAsUser( + mMockIntent, PackageManager.MATCH_DEFAULT_ONLY, mSystemUser)) + .thenReturn(mMockResolveInfoList); } else { - initializeUserManagerState(currentUser, - Lists.newArrayList(mSystemUser, mManagedUser)); - when(mMockPackageManager.queryIntentActivities(mMockIntent, - PackageManager.MATCH_DEFAULT_ONLY)).thenReturn(mMockResolveInfoList); + initializeUserManagerState(currentUser, Lists.newArrayList(mSystemUser, mManagedUser)); + when(mMockPackageManager.queryIntentActivities( + mMockIntent, PackageManager.MATCH_DEFAULT_ONLY)) + .thenReturn(mMockResolveInfoList); } Map<UserId, Boolean> expectedCanForwardToProfileIdMap = new HashMap<>(); @@ -492,26 +517,17 @@ public class UserManagerStateTest { @Test public void testGetCanForwardToProfileIdMap_managedCanForwardToAll() { UserId currentUser = UserId.of(mManagedUser); - final List<ResolveInfo> mMockResolveInfoList = Lists.newArrayList(mMockInfo1, mMockInfo2); - if (SdkLevel.isAtLeastV()) { - initializeUserManagerState(currentUser, - Lists.newArrayList(mSystemUser, mManagedUser, mPrivateUser)); - when(mMockPackageManager.queryIntentActivitiesAsUser(mMockIntent, - PackageManager.MATCH_DEFAULT_ONLY, mManagedUser)).thenReturn( - mMockResolveInfoList); - } else { - initializeUserManagerState(currentUser, - Lists.newArrayList(mSystemUser, mManagedUser)); - when(mMockPackageManager.queryIntentActivities(mMockIntent, - PackageManager.MATCH_DEFAULT_ONLY)).thenReturn(mMockResolveInfoList); - } + final List<ResolveInfo> mMockResolveInfoList = Lists.newArrayList(mMockInfoPrimaryUser); + when(mMockPackageManager.queryIntentActivities(any(Intent.class), anyInt())) + .thenReturn(mMockResolveInfoList); + + initializeUserManagerState( + currentUser, Lists.newArrayList(mSystemUser, mManagedUser, mPrivateUser)); Map<UserId, Boolean> expectedCanForwardToProfileIdMap = new HashMap<>(); expectedCanForwardToProfileIdMap.put(UserId.of(mSystemUser), true); expectedCanForwardToProfileIdMap.put(UserId.of(mManagedUser), true); - if (SdkLevel.isAtLeastV()) { - expectedCanForwardToProfileIdMap.put(UserId.of(mPrivateUser), true); - } + expectedCanForwardToProfileIdMap.put(UserId.of(mPrivateUser), true); assertWithMessage("getCanForwardToProfileIdMap returns incorrect mappings") .that(mUserManagerState.getCanForwardToProfileIdMap(mMockIntent)) @@ -521,19 +537,20 @@ public class UserManagerStateTest { @Test public void testGetCanForwardToProfileIdMap_managedCanNotForwardToAll() { UserId currentUser = UserId.of(mManagedUser); - final List<ResolveInfo> mMockResolveInfoList = Lists.newArrayList(mMockInfo2, mMockInfo3); + final List<ResolveInfo> mMockResolveInfoList = + Lists.newArrayList(mMockInfoPrivateUser, mMockInfoPrimaryUser); if (SdkLevel.isAtLeastV()) { - initializeUserManagerState(currentUser, - Lists.newArrayList(mSystemUser, mManagedUser, mPrivateUser)); - when(mMockPackageManager.queryIntentActivitiesAsUser(mMockIntent, - PackageManager.MATCH_DEFAULT_ONLY, mSystemUser)).thenReturn( - mMockResolveInfoList); + initializeUserManagerState( + currentUser, Lists.newArrayList(mSystemUser, mManagedUser, mPrivateUser)); + when(mMockPackageManager.queryIntentActivitiesAsUser( + mMockIntent, PackageManager.MATCH_DEFAULT_ONLY, mSystemUser)) + .thenReturn(mMockResolveInfoList); } else { - initializeUserManagerState(currentUser, - Lists.newArrayList(mSystemUser, mManagedUser)); - when(mMockPackageManager.queryIntentActivities(mMockIntent, - PackageManager.MATCH_DEFAULT_ONLY)).thenReturn(mMockResolveInfoList); + initializeUserManagerState(currentUser, Lists.newArrayList(mSystemUser, mManagedUser)); + when(mMockPackageManager.queryIntentActivities( + mMockIntent, PackageManager.MATCH_DEFAULT_ONLY)) + .thenReturn(mMockResolveInfoList); } Map<UserId, Boolean> expectedCanForwardToProfileIdMap = new HashMap<>(); @@ -550,13 +567,13 @@ public class UserManagerStateTest { @Test public void testGetCanForwardToProfileIdMap_privateCanForwardToAll() { - if (!SdkLevel.isAtLeastV()) return; UserId currentUser = UserId.of(mPrivateUser); - initializeUserManagerState(currentUser, - Lists.newArrayList(mSystemUser, mManagedUser, mPrivateUser)); - final List<ResolveInfo> mMockResolveInfoList = Lists.newArrayList(mMockInfo1, mMockInfo2); - when(mMockPackageManager.queryIntentActivitiesAsUser(mMockIntent, - PackageManager.MATCH_DEFAULT_ONLY, mSystemUser)).thenReturn(mMockResolveInfoList); + initializeUserManagerState( + currentUser, Lists.newArrayList(mSystemUser, mManagedUser, mPrivateUser)); + final List<ResolveInfo> mMockResolveInfoList = + Lists.newArrayList(mMockInfoPrimaryUser, mMockInfoManagedUser); + when(mMockPackageManager.queryIntentActivities(any(Intent.class), anyInt())) + .thenReturn(mMockResolveInfoList); Map<UserId, Boolean> expectedCanForwardToProfileIdMap = new HashMap<>(); expectedCanForwardToProfileIdMap.put(UserId.of(mSystemUser), true); @@ -570,13 +587,13 @@ public class UserManagerStateTest { @Test public void testGetCanForwardToProfileIdMap_privateCanNotForwardToManagedUser() { - if (!SdkLevel.isAtLeastV()) return; UserId currentUser = UserId.of(mPrivateUser); - initializeUserManagerState(currentUser, - Lists.newArrayList(mSystemUser, mManagedUser, mPrivateUser)); - final List<ResolveInfo> mMockResolveInfoList = Lists.newArrayList(mMockInfo2, mMockInfo3); - when(mMockPackageManager.queryIntentActivitiesAsUser(mMockIntent, - PackageManager.MATCH_DEFAULT_ONLY, mSystemUser)).thenReturn(mMockResolveInfoList); + initializeUserManagerState( + currentUser, Lists.newArrayList(mSystemUser, mManagedUser, mPrivateUser)); + final List<ResolveInfo> mMockResolveInfoList = + Lists.newArrayList(mMockInfoPrivateUser, mMockInfoPrimaryUser); + when(mMockPackageManager.queryIntentActivities(any(Intent.class), anyInt())) + .thenReturn(mMockResolveInfoList); Map<UserId, Boolean> expectedCanForwardToProfileIdMap = new HashMap<>(); expectedCanForwardToProfileIdMap.put(UserId.of(mSystemUser), true); @@ -594,6 +611,10 @@ public class UserManagerStateTest { UserId currentUser = UserId.of(mPrivateUser); initializeUserManagerState(currentUser, Lists.newArrayList(mSystemUser, mPrivateUser)); + final List<ResolveInfo> mMockResolveInfoList = Lists.newArrayList(mMockInfoPrimaryUser); + when(mMockPackageManager.queryIntentActivities(any(Intent.class), anyInt())) + .thenReturn(mMockResolveInfoList); + Map<UserId, Boolean> expectedCanForwardToProfileIdMap = new HashMap<>(); expectedCanForwardToProfileIdMap.put(UserId.of(mSystemUser), true); expectedCanForwardToProfileIdMap.put(UserId.of(mPrivateUser), true); @@ -607,24 +628,27 @@ public class UserManagerStateTest { public void testOnProfileStatusChange_anyIntentActionForManagedProfile() { if (!SdkLevel.isAtLeastV()) return; UserId currentUser = UserId.of(mSystemUser); - initializeUserManagerState(currentUser, - Lists.newArrayList(mSystemUser, mManagedUser, mPrivateUser)); + initializeUserManagerState( + currentUser, Lists.newArrayList(mSystemUser, mManagedUser, mPrivateUser)); - // UserManagerState#mUserId and UserManagerState#mCanForwardToProfileIdMap will empty + // UserManagerState#mUserId and UserManagerState#mCanForwardToProfileIdMap will + // empty // by default if the getters of these member variables have not been called List<UserId> userIdsBeforeIntent = new ArrayList<>(mUserManagerState.getUserIds()); - Map<UserId, Boolean> canForwardToProfileIdMapBeforeIntent = new HashMap<>( - mUserManagerState.getCanForwardToProfileIdMap(mMockIntent)); + Map<UserId, Boolean> canForwardToProfileIdMapBeforeIntent = + new HashMap<>(mUserManagerState.getCanForwardToProfileIdMap(mMockIntent)); String action = "any_intent"; mUserManagerState.onProfileActionStatusChange(action, UserId.of(mManagedUser)); assertWithMessage("Unexpected changes to user id list on receiving intent: " + action) - .that(mUserManagerState.getUserIds()).isEqualTo(userIdsBeforeIntent); + .that(mUserManagerState.getUserIds()) + .isEqualTo(userIdsBeforeIntent); assertWithMessage( - "Unexpected changes to canForwardToProfileIdMap on receiving intent: " + action) - .that(mUserManagerState.getCanForwardToProfileIdMap(mMockIntent)).isEqualTo( - canForwardToProfileIdMapBeforeIntent); + "Unexpected changes to canForwardToProfileIdMap on receiving intent: " + + action) + .that(mUserManagerState.getCanForwardToProfileIdMap(mMockIntent)) + .isEqualTo(canForwardToProfileIdMapBeforeIntent); } @Test @@ -633,18 +657,20 @@ public class UserManagerStateTest { UserId currentUser = UserId.of(mSystemUser); UserId managedUser = UserId.of(mManagedUser); UserId privateUser = UserId.of(mPrivateUser); - final List<ResolveInfo> mMockResolveInfoList = Lists.newArrayList(mMockInfo1, mMockInfo2); - when(mMockPackageManager.queryIntentActivitiesAsUser(mMockIntent, - PackageManager.MATCH_DEFAULT_ONLY, mSystemUser)).thenReturn( - mMockResolveInfoList); - initializeUserManagerState(currentUser, - Lists.newArrayList(mSystemUser, mManagedUser, mPrivateUser)); - - // UserManagerState#mUserId and UserManagerState#mCanForwardToProfileIdMap will empty + final List<ResolveInfo> mMockResolveInfoList = + Lists.newArrayList(mMockInfoManagedUser, mMockInfoPrivateUser); + when(mMockPackageManager.queryIntentActivitiesAsUser( + mMockIntent, PackageManager.MATCH_DEFAULT_ONLY, mSystemUser)) + .thenReturn(mMockResolveInfoList); + initializeUserManagerState( + currentUser, Lists.newArrayList(mSystemUser, mManagedUser, mPrivateUser)); + + // UserManagerState#mUserId and UserManagerState#mCanForwardToProfileIdMap will + // empty // by default if the getters of these member variables have not been called List<UserId> userIdsBeforeIntent = new ArrayList<>(mUserManagerState.getUserIds()); - Map<UserId, Boolean> canForwardToProfileIdMapBeforeIntent = new HashMap<>( - mUserManagerState.getCanForwardToProfileIdMap(mMockIntent)); + Map<UserId, Boolean> canForwardToProfileIdMapBeforeIntent = + new HashMap<>(mUserManagerState.getCanForwardToProfileIdMap(mMockIntent)); List<UserId> expectedUserIdsAfterIntent = Lists.newArrayList(currentUser, managedUser); @@ -652,14 +678,18 @@ public class UserManagerStateTest { mUserManagerState.onProfileActionStatusChange(action, privateUser); assertWithMessage( - "UserIds list should not be same before and after receiving intent: " + action) - .that(mUserManagerState.getUserIds()).isNotEqualTo(userIdsBeforeIntent); + "UserIds list should not be same before and after receiving intent: " + + action) + .that(mUserManagerState.getUserIds()) + .isNotEqualTo(userIdsBeforeIntent); assertWithMessage("Unexpected changes to user id list on receiving intent: " + action) - .that(mUserManagerState.getUserIds()).isEqualTo(expectedUserIdsAfterIntent); - assertWithMessage("CanForwardToLabelMap should be same before and after receiving intent: " - + action) - .that(mUserManagerState.getCanForwardToProfileIdMap(mMockIntent)).isEqualTo( - canForwardToProfileIdMapBeforeIntent); + .that(mUserManagerState.getUserIds()) + .isEqualTo(expectedUserIdsAfterIntent); + assertWithMessage( + "CanForwardToLabelMap should be same before and after receiving intent: " + + action) + .that(mUserManagerState.getCanForwardToProfileIdMap(mMockIntent)) + .isEqualTo(canForwardToProfileIdMapBeforeIntent); } @Test @@ -668,40 +698,84 @@ public class UserManagerStateTest { UserId currentUser = UserId.of(mSystemUser); UserId managedUser = UserId.of(mManagedUser); UserId privateUser = UserId.of(mPrivateUser); - final List<ResolveInfo> mMockResolveInfoList = Lists.newArrayList(mMockInfo1, mMockInfo2); - when(mMockPackageManager.queryIntentActivitiesAsUser(mMockIntent, - PackageManager.MATCH_DEFAULT_ONLY, mSystemUser)).thenReturn( - mMockResolveInfoList); - initializeUserManagerState(currentUser, - Lists.newArrayList(mSystemUser, mManagedUser, mPrivateUser)); + final List<ResolveInfo> mMockResolveInfoList = + Lists.newArrayList(mMockInfoManagedUser, mMockInfoPrivateUser); + when(mMockPackageManager.queryIntentActivitiesAsUser( + mMockIntent, PackageManager.MATCH_DEFAULT_ONLY, mSystemUser)) + .thenReturn(mMockResolveInfoList); + initializeUserManagerState( + currentUser, Lists.newArrayList(mSystemUser, mManagedUser, mPrivateUser)); // initialising the userIds list and canForwardToProfileIdMap mUserManagerState.getUserIds(); mUserManagerState.getCanForwardToProfileIdMap(mMockIntent); // Making the private profile unavailable after it has been initialised - mUserManagerState.onProfileActionStatusChange(Intent.ACTION_PROFILE_UNAVAILABLE, - privateUser); + mUserManagerState.onProfileActionStatusChange( + Intent.ACTION_PROFILE_UNAVAILABLE, privateUser); List<UserId> userIdsBeforeIntent = new ArrayList<>(mUserManagerState.getUserIds()); - Map<UserId, Boolean> canForwardToProfileIdMapBeforeIntent = new HashMap<>( - mUserManagerState.getCanForwardToProfileIdMap(mMockIntent)); + Map<UserId, Boolean> canForwardToProfileIdMapBeforeIntent = + new HashMap<>(mUserManagerState.getCanForwardToProfileIdMap(mMockIntent)); - List<UserId> expectedUserIdsAfterIntent = Lists.newArrayList(currentUser, managedUser, - privateUser); + List<UserId> expectedUserIdsAfterIntent = + Lists.newArrayList(currentUser, managedUser, privateUser); String action = Intent.ACTION_PROFILE_AVAILABLE; mUserManagerState.onProfileActionStatusChange(action, privateUser); assertWithMessage( - "UserIds list should not be same before and after receiving intent: " + action) - .that(mUserManagerState.getUserIds()).isNotEqualTo(userIdsBeforeIntent); + "UserIds list should not be same before and after receiving intent: " + + action) + .that(mUserManagerState.getUserIds()) + .isNotEqualTo(userIdsBeforeIntent); assertWithMessage("Unexpected changes to user id list on receiving intent: " + action) - .that(mUserManagerState.getUserIds()).isEqualTo(expectedUserIdsAfterIntent); - assertWithMessage("CanForwardToLabelMap should be same before and after receiving intent: " - + action) - .that(mUserManagerState.getCanForwardToProfileIdMap(mMockIntent)).isEqualTo( - canForwardToProfileIdMapBeforeIntent); + .that(mUserManagerState.getUserIds()) + .isEqualTo(expectedUserIdsAfterIntent); + assertWithMessage( + "CanForwardToLabelMap should be same before and after receiving intent: " + + action) + .that(mUserManagerState.getCanForwardToProfileIdMap(mMockIntent)) + .isEqualTo(canForwardToProfileIdMapBeforeIntent); + } + + @Test + public void testOnProfileStatusChange_actionProfileAdded() { + assumeTrue(SdkLevel.isAtLeastV()); + UserId currentUser = UserId.of(mSystemUser); + UserId managedUser = UserId.of(mManagedUser); + UserId privateUser = UserId.of(mPrivateUser); + + final List<ResolveInfo> mMockResolveInfoList = Lists.newArrayList(mMockInfoManagedUser); + + when(mMockPackageManager.queryIntentActivities(any(Intent.class), anyInt())) + .thenReturn(mMockResolveInfoList); + + initializeUserManagerState(currentUser, Lists.newArrayList(mSystemUser, mManagedUser)); + + mUserManagerState.setCurrentStateIntent(new Intent()); + + // initialising the userIds list and canForwardToProfileIdMap + mUserManagerState.getUserIds(); + mUserManagerState.getCanForwardToProfileIdMap(mMockIntent); + + String action = Intent.ACTION_PROFILE_ADDED; + mUserManagerState.onProfileActionStatusChange(action, privateUser); + + assertWithMessage( + "UserIds list should not be same before and after receiving intent: " + + action) + .that(mUserManagerState.getUserIds()) + .containsExactly(currentUser, managedUser, privateUser); + assertWithMessage( + "CanForwardToLabelMap should be same before and after receiving intent: " + + action) + .that(mUserManagerState.getCanForwardToProfileIdMap(mMockIntent)) + .isEqualTo( + Map.ofEntries( + Map.entry(currentUser, true), + Map.entry(managedUser, true), + Map.entry(privateUser, true))); } @Test @@ -710,24 +784,27 @@ public class UserManagerStateTest { UserId currentUser = UserId.of(mSystemUser); UserId managedUser = UserId.of(mManagedUser); UserId privateUser = UserId.of(mPrivateUser); - final List<ResolveInfo> mMockResolveInfoList = Lists.newArrayList(mMockInfo1, mMockInfo2); - when(mMockPackageManager.queryIntentActivitiesAsUser(mMockIntent, - PackageManager.MATCH_DEFAULT_ONLY, mSystemUser)).thenReturn( - mMockResolveInfoList); + final List<ResolveInfo> mMockResolveInfoList = + Lists.newArrayList(mMockInfoManagedUser, mMockInfoPrivateUser); + when(mMockPackageManager.queryIntentActivities(any(Intent.class), anyInt())) + .thenReturn(mMockResolveInfoList); + + when(mMockUserManager.getProfileParent(UserHandle.of(privateUser.getIdentifier()))) + .thenReturn(mPrimaryUser); // Private user will not be initialised if it is in quiet mode when(mMockUserManager.isQuietModeEnabled(mPrivateUser)).thenReturn(true); - initializeUserManagerState(currentUser, - Lists.newArrayList(mSystemUser, mManagedUser, mPrivateUser)); - - // UserManagerState#mUserId and UserManagerState#mCanForwardToProfileIdMap will be empty - // by default if the getters of these member variables have not been called + initializeUserManagerState( + currentUser, Lists.newArrayList(mSystemUser, mManagedUser, mPrivateUser)); + mUserManagerState.setCurrentStateIntent(new Intent()); + // UserManagerState#mUserId and UserManagerState#mCanForwardToProfileIdMap will + // be empty by default if the getters of these member variables have not been called List<UserId> userIdsBeforeIntent = new ArrayList<>(mUserManagerState.getUserIds()); - Map<UserId, Boolean> canForwardToProfileIdMapBeforeIntent = new HashMap<>( - mUserManagerState.getCanForwardToProfileIdMap(mMockIntent)); + Map<UserId, Boolean> canForwardToProfileIdMapBeforeIntent = + new HashMap<>(mUserManagerState.getCanForwardToProfileIdMap(mMockIntent)); - List<UserId> expectedUserIdsAfterIntent = Lists.newArrayList(currentUser, managedUser, - privateUser); + List<UserId> expectedUserIdsAfterIntent = + Lists.newArrayList(currentUser, managedUser, privateUser); Map<UserId, Boolean> expectedCanForwardToProfileIdMapAfterIntent = new HashMap<>(); expectedCanForwardToProfileIdMapAfterIntent.put(currentUser, true); expectedCanForwardToProfileIdMapAfterIntent.put(managedUser, true); @@ -737,56 +814,62 @@ public class UserManagerStateTest { mUserManagerState.onProfileActionStatusChange(action, privateUser); assertWithMessage( - "UserIds list should not be same before and after receiving intent: " + action) - .that(mUserManagerState.getUserIds()).isNotEqualTo(userIdsBeforeIntent); + "UserIds list should not be same before and after receiving intent: " + + action) + .that(mUserManagerState.getUserIds()) + .isNotEqualTo(userIdsBeforeIntent); assertWithMessage("Unexpected changes to user id list on receiving intent: " + action) - .that(mUserManagerState.getUserIds()).isEqualTo(expectedUserIdsAfterIntent); + .that(mUserManagerState.getUserIds()) + .isEqualTo(expectedUserIdsAfterIntent); assertWithMessage( - "CanForwardToLabelMap should not be same before and after receiving intent: " - + action) - .that(mUserManagerState.getCanForwardToProfileIdMap(mMockIntent)).isNotEqualTo( - canForwardToProfileIdMapBeforeIntent); + "CanForwardToLabelMap should not be same before and after receiving intent:" + + " " + + action) + .that(mUserManagerState.getCanForwardToProfileIdMap(mMockIntent)) + .isNotEqualTo(canForwardToProfileIdMapBeforeIntent); assertWithMessage( - "Unexpected changes to canForwardToProfileIdMap on receiving intent: " + action) - .that(mUserManagerState.getCanForwardToProfileIdMap(mMockIntent)).isEqualTo( - expectedCanForwardToProfileIdMapAfterIntent); + "Unexpected changes to canForwardToProfileIdMap on receiving intent: " + + action) + .that(mUserManagerState.getCanForwardToProfileIdMap(mMockIntent)) + .isEqualTo(expectedCanForwardToProfileIdMapAfterIntent); } @Test public void testGetUserIdToLabelMap_systemUserAndManagedUser_PreV() { if (SdkLevel.isAtLeastV()) return; UserId currentUser = UserId.of(mSystemUser); - initializeUserManagerState(currentUser, - Lists.newArrayList(mSystemUser, mManagedUser)); + initializeUserManagerState(currentUser, Lists.newArrayList(mSystemUser, mManagedUser)); if (SdkLevel.isAtLeastT()) { - DevicePolicyResourcesManager devicePolicyResourcesManager = mock( - DevicePolicyResourcesManager.class); + DevicePolicyResourcesManager devicePolicyResourcesManager = + mock(DevicePolicyResourcesManager.class); when(mDevicePolicyManager.getResources()).thenReturn(devicePolicyResourcesManager); - when(devicePolicyResourcesManager.getString(eq(PERSONAL_TAB), any())).thenReturn( - PERSONAL); + when(devicePolicyResourcesManager.getString(eq(PERSONAL_TAB), any())) + .thenReturn(PERSONAL); when(devicePolicyResourcesManager.getString(eq(WORK_TAB), any())).thenReturn(WORK); } Map<UserId, String> userIdToLabelMap = mUserManagerState.getUserIdToLabelMap(); assertWithMessage("Incorrect label returned for user id " + mSystemUser) - .that(userIdToLabelMap.get(UserId.of(mSystemUser))).isEqualTo(PERSONAL); + .that(userIdToLabelMap.get(UserId.of(mSystemUser))) + .isEqualTo(PERSONAL); assertWithMessage("Incorrect label returned for user id " + mManagedUser) - .that(userIdToLabelMap.get(UserId.of(mManagedUser))).isEqualTo(WORK); + .that(userIdToLabelMap.get(UserId.of(mManagedUser))) + .isEqualTo(WORK); } @Test public void testGetUserIdToLabelMap_systemUserManagedUserPrivateUser_PostV() { if (!SdkLevel.isAtLeastV()) return; UserId currentUser = UserId.of(mSystemUser); - initializeUserManagerState(currentUser, - Lists.newArrayList(mSystemUser, mManagedUser, mPrivateUser)); + initializeUserManagerState( + currentUser, Lists.newArrayList(mSystemUser, mManagedUser, mPrivateUser)); if (SdkLevel.isAtLeastT()) { - DevicePolicyResourcesManager devicePolicyResourcesManager = mock( - DevicePolicyResourcesManager.class); + DevicePolicyResourcesManager devicePolicyResourcesManager = + mock(DevicePolicyResourcesManager.class); when(mDevicePolicyManager.getResources()).thenReturn(devicePolicyResourcesManager); - when(devicePolicyResourcesManager.getString(eq(PERSONAL_TAB), any())).thenReturn( - PERSONAL); + when(devicePolicyResourcesManager.getString(eq(PERSONAL_TAB), any())) + .thenReturn(PERSONAL); } UserManager managedUserManager = getUserManagerForManagedUser(); UserManager privateUserManager = getUserManagerForPrivateUser(); @@ -796,45 +879,50 @@ public class UserManagerStateTest { Map<UserId, String> userIdToLabelMap = mUserManagerState.getUserIdToLabelMap(); assertWithMessage("Incorrect label returned for user id " + mSystemUser) - .that(userIdToLabelMap.get(UserId.of(mSystemUser))).isEqualTo(PERSONAL); + .that(userIdToLabelMap.get(UserId.of(mSystemUser))) + .isEqualTo(PERSONAL); assertWithMessage("Incorrect label returned for user id " + mManagedUser) - .that(userIdToLabelMap.get(UserId.of(mManagedUser))).isEqualTo(WORK); + .that(userIdToLabelMap.get(UserId.of(mManagedUser))) + .isEqualTo(WORK); assertWithMessage("Incorrect label returned for user id " + mPrivateUser) - .that(userIdToLabelMap.get(UserId.of(mPrivateUser))).isEqualTo(PRIVATE); + .that(userIdToLabelMap.get(UserId.of(mPrivateUser))) + .isEqualTo(PRIVATE); } @Test public void testGetUserIdToBadgeMap_systemUserManagedUser_PreV() { if (SdkLevel.isAtLeastV()) return; UserId currentUser = UserId.of(mSystemUser); - initializeUserManagerState(currentUser, - Lists.newArrayList(mSystemUser, mManagedUser)); + initializeUserManagerState(currentUser, Lists.newArrayList(mSystemUser, mManagedUser)); Drawable workBadge = mock(Drawable.class); Resources resources = mock(Resources.class); when(mMockContext.getResources()).thenReturn(resources); when(mMockContext.getDrawable(R.drawable.ic_briefcase)).thenReturn(workBadge); if (SdkLevel.isAtLeastT()) { - DevicePolicyResourcesManager devicePolicyResourcesManager = mock( - DevicePolicyResourcesManager.class); + DevicePolicyResourcesManager devicePolicyResourcesManager = + mock(DevicePolicyResourcesManager.class); when(mDevicePolicyManager.getResources()).thenReturn(devicePolicyResourcesManager); - when(devicePolicyResourcesManager.getDrawable(eq(WORK_PROFILE_ICON), eq(SOLID_COLORED), - any())).thenReturn(workBadge); + when(devicePolicyResourcesManager.getDrawable( + eq(WORK_PROFILE_ICON), eq(SOLID_COLORED), any())) + .thenReturn(workBadge); } Map<UserId, Drawable> userIdToBadgeMap = mUserManagerState.getUserIdToBadgeMap(); assertWithMessage("There should be no badge present for personal user") - .that(userIdToBadgeMap.containsKey(UserId.of(mSystemUser))).isFalse(); + .that(userIdToBadgeMap.containsKey(UserId.of(mSystemUser))) + .isFalse(); assertWithMessage("Incorrect badge returned for user id " + mManagedUser) - .that(userIdToBadgeMap.get(UserId.of(mManagedUser))).isEqualTo(workBadge); + .that(userIdToBadgeMap.get(UserId.of(mManagedUser))) + .isEqualTo(workBadge); } @Test public void testGetUserIdToBadgeMap_systemUserManagedUserPrivateUser_PostV() { if (!SdkLevel.isAtLeastV()) return; UserId currentUser = UserId.of(mSystemUser); - initializeUserManagerState(currentUser, - Lists.newArrayList(mSystemUser, mManagedUser, mPrivateUser)); + initializeUserManagerState( + currentUser, Lists.newArrayList(mSystemUser, mManagedUser, mPrivateUser)); Drawable workBadge = mock(Drawable.class); Drawable privateBadge = mock(Drawable.class); UserManager managedUserManager = getUserManagerForManagedUser(); @@ -845,19 +933,23 @@ public class UserManagerStateTest { Map<UserId, Drawable> userIdToBadgeMap = mUserManagerState.getUserIdToBadgeMap(); assertWithMessage("There should be no badge present for personal user") - .that(userIdToBadgeMap.get(UserId.of(mSystemUser))).isNull(); + .that(userIdToBadgeMap.get(UserId.of(mSystemUser))) + .isNull(); assertWithMessage("Incorrect badge returned for user id " + mManagedUser) - .that(userIdToBadgeMap.get(UserId.of(mManagedUser))).isEqualTo(workBadge); + .that(userIdToBadgeMap.get(UserId.of(mManagedUser))) + .isEqualTo(workBadge); assertWithMessage("Incorrect badge returned for user id " + mPrivateUser) - .that(userIdToBadgeMap.get(UserId.of(mPrivateUser))).isEqualTo(privateBadge); + .that(userIdToBadgeMap.get(UserId.of(mPrivateUser))) + .isEqualTo(privateBadge); } private void initializeUserManagerState(UserId current, List<UserHandle> usersOnDevice) { when(mMockUserManager.getUserProfiles()).thenReturn(usersOnDevice); TestConfigStore testConfigStore = new TestConfigStore(); testConfigStore.enablePrivateSpaceInPhotoPicker(); - mUserManagerState = new UserManagerState.RuntimeUserManagerState(mMockContext, current, - true, testConfigStore); + mUserManagerState = + new UserManagerState.RuntimeUserManagerState( + mMockContext, current, true, testConfigStore); } private UserManager getUserManagerForManagedUser() { |