summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Tyler Saunders <tylersaunders@google.com> 2025-03-12 14:04:51 +0000
committer Tyler Saunders <tylersaunders@google.com> 2025-03-13 17:24:14 +0000
commit001b7bd2fae2078b6a6cd490958d495508a6d881 (patch)
treeb6b23d047db33901d7403642142aab38d52216bb
parent79a1f4c6d841739e30e0c339c52be39dc42af086 (diff)
Handle x-profile delegation for java picker.
Bug: b/402367358 Test: atest MediaProviderTests:UserManagerStateTest Flag: EXEMPT bug_fix Change-Id: Iabc4de0d39720dcb355cf98c99724feacf6899e0
-rw-r--r--src/com/android/providers/media/photopicker/data/UserManagerState.java330
-rw-r--r--tests/src/com/android/providers/media/photopicker/data/UserManagerStateTest.java245
2 files changed, 297 insertions, 278 deletions
diff --git a/src/com/android/providers/media/photopicker/data/UserManagerState.java b/src/com/android/providers/media/photopicker/data/UserManagerState.java
index 74c06e872..8df364c3c 100644
--- a/src/com/android/providers/media/photopicker/data/UserManagerState.java
+++ b/src/com/android/providers/media/photopicker/data/UserManagerState.java
@@ -21,8 +21,6 @@ import static androidx.core.util.Preconditions.checkNotNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresApi;
-import android.annotation.SuppressLint;
-import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -242,48 +240,40 @@ public interface UserManagerState {
setUserIds();
}
- private UserId getSystemUser() {
- return UserId.of(UserHandle.of(ActivityManager.getCurrentUser()));
- }
-
private void setUserIds() {
- setUserIdsInternal();
- mIsMultiUserProfiles.postValue(isMultiUserProfiles());
- }
-
- private void setUserIdsInternal() {
mUserProfileIds.clear();
- mUserProfileIds.add(getSystemUser());
- if (mUserManager == null) {
- Log.e(TAG, "Cannot obtain user manager");
- return;
- }
- // Here there could be other profiles too , that we do not want to show anywhere
- // in photo picker at all.
- final List<UserHandle> userProfiles = mUserManager.getUserProfiles();
- if (SdkLevel.isAtLeastV()) {
- for (UserHandle userHandle : userProfiles) {
- UserProperties userProperties = mUserManager.getUserProperties(userHandle);
- UserId userId = UserId.of(userHandle);
-
- // Check if we want to show this profile data in PhotoPicker or if it is
- // an owner profile itself.
- if (getSystemUser().getIdentifier() != userHandle.getIdentifier()
- && userProperties.getShowInSharingSurfaces()
- == userProperties.SHOW_IN_SHARING_SURFACES_SEPARATE) {
- mUserProfileIds.add(userId);
+ mUserProfileIds.add(mCurrentUser);
+ boolean currentUserIsManaged =
+ mUserManager.isManagedProfile(mCurrentUser.getIdentifier());
+
+ for (UserHandle handle : mUserManager.getUserProfiles()) {
+
+ // For >= Android V, check if the profile wants to be shown
+ if (SdkLevel.isAtLeastV()) {
+
+ UserProperties properties = mUserManager.getUserProperties(handle);
+ if (properties.getShowInSharingSurfaces()
+ != UserProperties.SHOW_IN_SHARING_SURFACES_SEPARATE) {
+ continue;
}
- }
- } else {
- // if sdk version is less than V, then maximum two profiles with separate tab
- // could only be available
- for (UserHandle userHandle : userProfiles) {
- if (mUserManager.isManagedProfile(userHandle.getIdentifier())) {
- mUserProfileIds.add(UserId.of(userHandle));
+ } else {
+ // Only allow managed profiles + the parent user on lower than V.
+ if (currentUserIsManaged
+ && mUserManager.getProfileParent(mCurrentUser.getUserHandle())
+ == handle) {
+ // Intentionally empty so that this profile gets added.
+ } else if (!mUserManager.isManagedProfile(handle.getIdentifier())) {
+ continue;
}
}
+
+ // Ensure the system user doesn't get added twice.
+ if (mUserProfileIds.contains(UserId.of(handle))) continue;
+ mUserProfileIds.add(UserId.of(handle));
}
+
+ mIsMultiUserProfiles.postValue(isMultiUserProfiles());
}
@Override
@@ -312,12 +302,162 @@ public interface UserManagerState {
return crossProfileAllowedStatusForAll;
}
+
+ /**
+ * External method that allows quick checking from the current user to a target user.
+ *
+ * Takes into account the On/Off state of the profile, as well as cross profile content
+ * sharing policies.
+ *
+ * @param targetUser the target of the access. Current User is the "from" user.
+ * @return If the target user currently is eligible for cross profile content sharing.
+ */
@Override
- public boolean isCrossProfileAllowedToUser(UserId otherUser) {
+ public boolean isCrossProfileAllowedToUser(UserId targetUser) {
assertMainThread();
- return !isProfileOff(otherUser) && !isBlockedByAdmin(otherUser);
+ return !isProfileOff(targetUser) && !isBlockedByAdmin(targetUser);
}
+ /**
+ * Determines if the provided UserIds support CrossProfile content sharing.
+ *
+ * <p>This method accepts a pair of user handles (from/to) and determines if CrossProfile
+ * access is permitted between those two profiles.
+ *
+ * <p>There are differences is on how the access is determined based on the platform SDK:
+ *
+ * <p>For Platform SDK < V:
+ *
+ * <p>A check for CrossProfileIntentForwarders in the origin (from) profile that target the
+ * destination (to) profile. If such a forwarder exists, then access is allowed, and denied
+ * otherwise.
+ *
+ * <p>For Platform SDK >= V:
+ *
+ * <p>The method now takes into account access delegation, which was first added in Android
+ * V.
+ *
+ * <p>For profiles that set the [CROSS_PROFILE_CONTENT_SHARING_DELEGATE_FROM_PARENT]
+ * property in its [UserProperties], its parent profile will be substituted in for its side
+ * of the check.
+ *
+ * <p>ex. For access checks between a Managed (from) and Private (to) profile, where: -
+ * Managed does not delegate to its parent - Private delegates to its parent
+ *
+ * <p>The following logic is performed: Managed -> parent(Private)
+ *
+ * <p>The same check in the other direction would yield: parent(Private) -> Managed
+ *
+ * <p>Note how the private profile is never actually used for either side of the check,
+ * since it is delegating its access check to the parent. And thus, if Managed can access
+ * the parent, it can also access the private.
+ *
+ * @param context Current context object, for switching user contexts.
+ * @param intent The current intent the Photopicker is running under.
+ * @param fromUser The Origin profile, where the user is coming from
+ * @param toUser The destination profile, where the user is attempting to go to.
+ * @return Whether CrossProfile content sharing is supported in this handle.
+ */
+ private boolean isCrossProfileAllowedToUser(
+ Context context, Intent intent, UserId fromUser, UserId toUser) {
+
+ // Early exit conditions, accessing self.
+ // NOTE: It is also possible to reach this state if this method is recursively checking
+ // from: parent(A) to:parent(B) where A and B are both children of the same parent.
+ if (fromUser.getIdentifier() == toUser.getIdentifier()) {
+ return true;
+ }
+
+ // Decide if we should use actual from or parent(from)
+ UserHandle currentFromUser =
+ getProfileToCheckCrossProfileAccess(fromUser.getUserHandle());
+
+ // Decide if we should use actual to or parent(to)
+ UserHandle currentToUser = getProfileToCheckCrossProfileAccess(toUser.getUserHandle());
+
+ // When the from/to has changed from the original parameters, recursively restart the
+ // checks with the new from/to handles.
+ if (fromUser.getIdentifier() != currentFromUser.getIdentifier()
+ || toUser.getIdentifier() != currentToUser.getIdentifier()) {
+ return isCrossProfileAllowedToUser(
+ context, intent, UserId.of(currentFromUser), UserId.of(currentToUser));
+ }
+
+ return doesCrossProfileIntentForwarderExist(
+ intent,
+ mContext.getPackageManager(),
+ fromUser.getUserHandle(),
+ toUser.getUserHandle());
+ }
+
+ /**
+ * Checks the Intent to see if it can be resolved as a CrossProfileIntentForwarderActivity
+ * for the target user.
+ *
+ * @param intent The current intent the photopicker is running under.
+ * @param pm the PM which will be used for querying.
+ * @param fromUser the [UserHandle] of the origin user
+ * @param targetUserHandle the [UserHandle] of the target user
+ * @return Whether the current Intent Photopicker may be running under has a matching
+ * CrossProfileIntentForwarderActivity
+ */
+ private boolean doesCrossProfileIntentForwarderExist(
+ Intent intent,
+ PackageManager pm,
+ UserHandle fromUser,
+ UserHandle targetUserHandle) {
+
+ // Clear out the component & package before attempting to match
+ Intent intentToCheck = (Intent) intent.clone();
+ intentToCheck.setComponent(null);
+ intentToCheck.setPackage(null);
+
+ for (ResolveInfo resolveInfo :
+ pm.queryIntentActivitiesAsUser(
+ intentToCheck, PackageManager.MATCH_DEFAULT_ONLY, fromUser)) {
+
+ // If the activity is a CrossProfileIntentForwardingActivity, inspect its
+ // targetUserId to see if it targets the user we are currently checking for.
+ 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 targetUserId = (int) targetUserIdField.get(resolveInfo);
+
+ if (targetUserId == targetUserHandle.getIdentifier()) {
+ // Don't need to look further, exit the loop.
+ 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);
+ }
+ }
+ }
+ return false;
+ }
+
+
@Override
public MutableLiveData<Boolean> getIsMultiUserProfiles() {
return mIsMultiUserProfiles;
@@ -331,8 +471,7 @@ public interface UserManagerState {
@Override
public void resetUserIdsAndSetCrossProfileValues(Intent intent) {
- assertMainThread();
- setUserIdsInternal();
+ resetUserIds();
setCrossProfileValues(intent);
mIsMultiUserProfiles.postValue(isMultiUserProfiles());
}
@@ -510,6 +649,12 @@ public interface UserManagerState {
|| !CrossProfileUtils.isMediaProviderAvailable(userId, mContext);
}
+ /**
+ * Determines if the target UserHandle delegates its content sharing to its parent.
+ *
+ * @param userHandle The target handle to check delegation for.
+ * @return TRUE if V+ and the handle delegates to parent. False otherwise.
+ */
private boolean isCrossProfileStrategyDelegatedToParent(UserHandle userHandle) {
if (SdkLevel.isAtLeastV()) {
if (mUserManager == null) {
@@ -525,6 +670,15 @@ public interface UserManagerState {
return false;
}
+ /**
+ * Acquires the correct {@link UserHandle} which should be used for CrossProfile access
+ * checks.
+ *
+ * @param userHandle the origin handle.
+ * @return The UserHandle that should be used for cross profile access checks. In the event
+ * the origin handle delegates its access, this may not be the same handle as the origin
+ * handle.
+ */
private UserHandle getProfileToCheckCrossProfileAccess(UserHandle userHandle) {
if (mUserManager == null) {
Log.e(TAG, "Cannot obtain user manager");
@@ -551,7 +705,6 @@ public interface UserManagerState {
* @param intent The intent Photopicker is currently running under, for
* CrossProfileForwardActivity checking.
*/
- @SuppressLint("DiscouragedPrivateApi")
private void setBlockedByAdminValue(Intent intent) {
if (intent == null) {
Log.e(
@@ -561,95 +714,6 @@ public interface UserManagerState {
return;
}
- Map<UserId, Boolean> profileIsAccessibleToProcessOwner = new HashMap<>();
- List<UserId> delegatedFromParent = new ArrayList<>();
-
- final PackageManager pm = mContext.getPackageManager();
-
- // Resolve CrossProfile activities for all user profiles that Photopicker is
- // aware of.
- for (UserId userId : mUserProfileIds) {
-
- // If the UserId is the system user, exit early.
- if (userId.getIdentifier() == mCurrentUser.getIdentifier()) {
- profileIsAccessibleToProcessOwner.put(userId, true);
- continue;
- }
-
- // This UserId delegates its strategy to the parent profile
- if (isCrossProfileStrategyDelegatedToParent(userId.getUserHandle())) {
- delegatedFromParent.add(userId);
- continue;
- }
-
- // Clear out the component & package before attempting to match
- Intent intentToCheck = (Intent) intent.clone();
- intentToCheck.setComponent(null);
- intentToCheck.setPackage(null);
-
- for (ResolveInfo resolveInfo :
- pm.queryIntentActivities(
- intentToCheck, PackageManager.MATCH_DEFAULT_ONLY)) {
-
- // If the activity is a CrossProfileIntentForwardingActivity, inspect its
- // targetUserId to
- // see if it targets the user we are currently checking for.
- 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 targetUserId = (int) targetUserIdField.get(resolveInfo);
-
- if (targetUserId == userId.getIdentifier()) {
- profileIsAccessibleToProcessOwner.put(userId, true);
-
- // Don't need to look further, exit the loop.
- break;
- }
-
- } 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);
- break;
- } catch (Exception ex) {
- Log.e(TAG, "Exception occurred during cross profile checks", ex);
- }
- }
- }
- // Fail case, was unable to find a suitable Activity for this user.
- profileIsAccessibleToProcessOwner.putIfAbsent(userId, false);
- }
-
- // 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));
- }
-
mIsProfileBlockedByAdminMap.clear();
for (UserId userId : mUserProfileIds) {
mIsProfileBlockedByAdminMap.put(
@@ -657,8 +721,8 @@ public interface UserManagerState {
// calculated, (which are blocked, rather than which are accessible) so the
// boolean needs to be inverted.
userId,
- !profileIsAccessibleToProcessOwner.getOrDefault(
- userId, /* default= */ false));
+ !isCrossProfileAllowedToUser(mContext, intent, UserId.CURRENT_USER, userId)
+ );
}
}
diff --git a/tests/src/com/android/providers/media/photopicker/data/UserManagerStateTest.java b/tests/src/com/android/providers/media/photopicker/data/UserManagerStateTest.java
index dda66c673..f2fc38d9d 100644
--- a/tests/src/com/android/providers/media/photopicker/data/UserManagerStateTest.java
+++ b/tests/src/com/android/providers/media/photopicker/data/UserManagerStateTest.java
@@ -23,6 +23,7 @@ import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -111,6 +112,7 @@ public class UserManagerStateTest {
// set Managed Profile identification
when(mMockUserManager.isManagedProfile(mManagedUser.getIdentifier())).thenReturn(true);
+ when(mMockUserManager.isManagedProfile(mManagedUser2.getIdentifier())).thenReturn(true);
when(mMockUserManager.isManagedProfile(mPersonalUser.getIdentifier())).thenReturn(false);
when(mMockUserManager.isManagedProfile(mOtherUser1.getIdentifier())).thenReturn(false);
when(mMockUserManager.isManagedProfile(mOtherUser2.getIdentifier())).thenReturn(false);
@@ -171,6 +173,62 @@ public class UserManagerStateTest {
}
@Test
+ public void testCrossProfileAccessWithDelegationVPlus() {
+ assumeTrue(SdkLevel.isAtLeastV());
+
+ // Return a ResolveInfo for the correct managed profile.
+ when(mMockPackageManager.queryIntentActivitiesAsUser(
+ any(Intent.class), anyInt(), any(UserHandle.class)))
+ .thenReturn(List.of());
+
+ initializeUserManagerState(
+ UserId.of(mPersonalUser),
+ Arrays.asList(mPersonalUser, mManagedUser, mOtherUser1));
+
+ InstrumentationRegistry.getInstrumentation()
+ .runOnMainSync(
+ () -> {
+ mUserManagerState.setIntentAndCheckRestrictions(new Intent());
+ assertThat(
+ mUserManagerState.isCrossProfileAllowedToUser(
+ UserId.of(mManagedUser)))
+ .isFalse();
+ assertThat(
+ mUserManagerState.isCrossProfileAllowedToUser(
+ UserId.of(mOtherUser1)))
+ .isTrue();
+ });
+ }
+
+ @Test
+ public void testCrossProfileAccessWithDelegationManagedToPrivateVPlus() {
+ assumeTrue(SdkLevel.isAtLeastV());
+
+ // Return a ResolveInfo for the personal profile only.
+ when(mMockPackageManager.queryIntentActivitiesAsUser(
+ any(Intent.class), anyInt(), eq(mManagedUser)))
+ .thenReturn(List.of(new ReflectedResolveInfo(mPersonalUser.getIdentifier())));
+
+ initializeUserManagerState(
+ UserId.of(mManagedUser),
+ Arrays.asList(mPersonalUser, mManagedUser, mOtherUser1));
+
+ InstrumentationRegistry.getInstrumentation()
+ .runOnMainSync(
+ () -> {
+ mUserManagerState.setIntentAndCheckRestrictions(new Intent());
+ assertThat(
+ mUserManagerState.isCrossProfileAllowedToUser(
+ UserId.of(mPersonalUser)))
+ .isTrue();
+ assertThat(
+ mUserManagerState.isCrossProfileAllowedToUser(
+ UserId.of(mOtherUser1)))
+ .isTrue();
+ });
+ }
+
+ @Test
public void testCrossProfileAccessWithMultipleManagedProfilesIsAllowedVPlus() {
assumeTrue(SdkLevel.isAtLeastV());
@@ -186,7 +244,8 @@ public class UserManagerStateTest {
when(mMockUserManager.getUserProperties(mManagedUser2)).thenReturn(mManagedUser2Properties);
// Return a ResolveInfo for the correct managed profile.
- when(mMockPackageManager.queryIntentActivities(any(Intent.class), anyInt()))
+ when(mMockPackageManager.queryIntentActivitiesAsUser(
+ any(Intent.class), anyInt(), eq(mPersonalUser)))
.thenReturn(List.of(new ReflectedResolveInfo(mManagedUser2.getIdentifier())));
initializeUserManagerState(
@@ -224,7 +283,8 @@ public class UserManagerStateTest {
when(mMockUserManager.getUserProperties(mManagedUser2)).thenReturn(mManagedUser2Properties);
// Return a ResolveInfo for the OTHER managed profile.
- when(mMockPackageManager.queryIntentActivities(any(Intent.class), anyInt()))
+ when(mMockPackageManager.queryIntentActivitiesAsUser(
+ any(Intent.class), anyInt(), eq(mPersonalUser)))
.thenReturn(List.of(new ReflectedResolveInfo(mManagedUser.getIdentifier())));
initializeUserManagerState(
@@ -254,7 +314,8 @@ public class UserManagerStateTest {
when(mMockUserManager.isManagedProfile(mManagedUser2.getIdentifier())).thenReturn(true);
// Return a ResolveInfo for the correct managed profile.
- when(mMockPackageManager.queryIntentActivities(any(Intent.class), anyInt()))
+ when(mMockPackageManager.queryIntentActivitiesAsUser(
+ any(Intent.class), anyInt(), eq(mPersonalUser)))
.thenReturn(List.of(new ReflectedResolveInfo(mManagedUser2.getIdentifier())));
initializeUserManagerState(
@@ -280,7 +341,8 @@ public class UserManagerStateTest {
when(mMockUserManager.isManagedProfile(mManagedUser2.getIdentifier())).thenReturn(true);
// Return a ResolveInfo for the OTHER managed profile.
- when(mMockPackageManager.queryIntentActivities(any(Intent.class), anyInt()))
+ when(mMockPackageManager.queryIntentActivitiesAsUser(
+ any(Intent.class), anyInt(), eq(mPersonalUser)))
.thenReturn(List.of(new ReflectedResolveInfo(mManagedUser.getIdentifier())));
initializeUserManagerState(
@@ -349,19 +411,14 @@ public class UserManagerStateTest {
public void testGetAllUserProfileIdsThatNeedToShowInPhotoPicker_currentUserIsPersonalUser() {
initializeUserManagerState(
UserId.of(mPersonalUser),
- Arrays.asList(mPersonalUser, mManagedUser, mOtherUser1, mOtherUser2));
+ Arrays.asList(mPersonalUser, mManagedUser));
InstrumentationRegistry.getInstrumentation()
.runOnMainSync(
() -> {
List<UserId> userIdList =
- SdkLevel.isAtLeastV()
- ? Arrays.asList(
- UserId.of(mPersonalUser),
- UserId.of(mManagedUser),
- UserId.of(mOtherUser1))
- : Arrays.asList(
- UserId.of(mPersonalUser),
- UserId.of(mManagedUser));
+ Arrays.asList(
+ UserId.of(mPersonalUser),
+ UserId.of(mManagedUser));
assertThat(mUserManagerState.getAllUserProfileIds())
.containsExactlyElementsIn(userIdList);
@@ -372,19 +429,14 @@ public class UserManagerStateTest {
public void testGetAllUserProfileIdsThatNeedToShowInPhotoPicker_currentUserIsManagedUser() {
initializeUserManagerState(
UserId.of(mManagedUser),
- Arrays.asList(mPersonalUser, mManagedUser, mOtherUser1, mOtherUser2));
+ Arrays.asList(mPersonalUser, mManagedUser));
InstrumentationRegistry.getInstrumentation()
.runOnMainSync(
() -> {
List<UserId> userIdList =
- SdkLevel.isAtLeastV()
- ? Arrays.asList(
- UserId.of(mPersonalUser),
- UserId.of(mManagedUser),
- UserId.of(mOtherUser1))
- : Arrays.asList(
- UserId.of(mPersonalUser),
- UserId.of(mManagedUser));
+ Arrays.asList(
+ UserId.of(mPersonalUser),
+ UserId.of(mManagedUser));
assertThat(mUserManagerState.getAllUserProfileIds())
.containsExactlyElementsIn(userIdList);
@@ -392,22 +444,21 @@ public class UserManagerStateTest {
}
@Test
- public void testGetAllUserProfileIdsThatNeedToShowInPhotoPicker_currentUserIsOtherUser1() {
+ public void
+ testGetAllUserProfileIdsThatNeedToShowInPhotoPicker_currentUserIsOtherUser1VPlus() {
+ assumeTrue(SdkLevel.isAtLeastV());
initializeUserManagerState(
UserId.of(mOtherUser1),
- Arrays.asList(mPersonalUser, mManagedUser, mOtherUser1, mOtherUser2));
+ Arrays.asList(mPersonalUser, mManagedUser, mOtherUser1));
InstrumentationRegistry.getInstrumentation()
.runOnMainSync(
() -> {
List<UserId> userIdList =
- SdkLevel.isAtLeastV()
- ? Arrays.asList(
- UserId.of(mPersonalUser),
- UserId.of(mManagedUser),
- UserId.of(mOtherUser1))
- : Arrays.asList(
- UserId.of(mPersonalUser),
- UserId.of(mManagedUser));
+ Arrays.asList(
+ UserId.of(mPersonalUser),
+ UserId.of(mManagedUser),
+ UserId.of(mOtherUser1));
+
assertThat(mUserManagerState.getAllUserProfileIds())
.containsExactlyElementsIn(userIdList);
});
@@ -433,6 +484,7 @@ public class UserManagerStateTest {
@Test
public void testUserIds_multiUserProfilesAvailable_currentUserIsPersonalUser() {
+ assumeFalse(SdkLevel.isAtLeastV());
UserId currentUser = UserId.of(mPersonalUser);
// if available user profiles are {personal , managed, otherUser1 }
@@ -446,13 +498,7 @@ public class UserManagerStateTest {
assertThat(mUserManagerState.getCurrentUserProfileId())
.isEqualTo(UserId.of(mPersonalUser));
- List<UserId> userIdList =
- SdkLevel.isAtLeastV()
- ? Arrays.asList(
- UserId.of(mPersonalUser),
- UserId.of(mManagedUser),
- UserId.of(mOtherUser1))
- : Arrays.asList(
+ List<UserId> userIdList = Arrays.asList(
UserId.of(mPersonalUser),
UserId.of(mManagedUser));
assertThat(mUserManagerState.getAllUserProfileIds())
@@ -463,77 +509,36 @@ public class UserManagerStateTest {
mUserManagerState.getCurrentUserProfileId()))
.isFalse();
});
-
- // if available user profiles are {personal , otherUser1 }
- initializeUserManagerState(currentUser, Arrays.asList(mPersonalUser, mOtherUser1));
- InstrumentationRegistry.getInstrumentation()
- .runOnMainSync(
- () -> {
- if (SdkLevel.isAtLeastV()) {
- assertThat(mUserManagerState.isMultiUserProfiles()).isTrue();
- } else {
- assertThat(mUserManagerState.isMultiUserProfiles()).isFalse();
- }
-
- List<UserId> userIdList =
- SdkLevel.isAtLeastV()
- ? Arrays.asList(
- UserId.of(mPersonalUser),
- UserId.of(mOtherUser1))
- : Arrays.asList(UserId.of(mPersonalUser));
- assertThat(mUserManagerState.getAllUserProfileIds())
- .containsExactlyElementsIn(userIdList);
- });
-
- // if available user profiles are {personal , otherUser2 }
- initializeUserManagerState(currentUser, Arrays.asList(mPersonalUser, mOtherUser2));
- InstrumentationRegistry.getInstrumentation()
- .runOnMainSync(
- () -> {
- assertThat(mUserManagerState.isMultiUserProfiles()).isFalse();
-
- assertThat(mUserManagerState.getCurrentUserProfileId())
- .isEqualTo(UserId.of(mPersonalUser));
- assertThat(mUserManagerState.getAllUserProfileIds())
- .containsExactlyElementsIn(
- Arrays.asList(UserId.of(mPersonalUser)));
- });
}
@Test
- public void testUserIds_multiUserProfilesAvailable_currentUserIsOtherUser2() {
- UserId currentUser = UserId.of(mOtherUser2);
+ public void testUserIds_multiUserProfilesAvailable_currentUserIsPersonalUserVPlus() {
+ assumeTrue(SdkLevel.isAtLeastV());
+ UserId currentUser = UserId.of(mPersonalUser);
+ // if available user profiles are {personal , managed, otherUser1 }
initializeUserManagerState(
- currentUser, Arrays.asList(mPersonalUser, mManagedUser, mOtherUser1, mOtherUser2));
+ currentUser, Arrays.asList(mPersonalUser, mManagedUser, mOtherUser1));
InstrumentationRegistry.getInstrumentation()
.runOnMainSync(
() -> {
assertThat(mUserManagerState.isMultiUserProfiles()).isTrue();
+
assertThat(mUserManagerState.getCurrentUserProfileId())
- .isEqualTo(UserId.of(mOtherUser2));
+ .isEqualTo(UserId.of(mPersonalUser));
List<UserId> userIdList =
- SdkLevel.isAtLeastV()
- ? Arrays.asList(
- UserId.of(mPersonalUser),
- UserId.of(mManagedUser),
- UserId.of(mOtherUser1))
- : Arrays.asList(
- UserId.of(mPersonalUser),
- UserId.of(mManagedUser));
+ Arrays.asList(
+ UserId.of(mPersonalUser),
+ UserId.of(mManagedUser),
+ UserId.of(mOtherUser1));
assertThat(mUserManagerState.getAllUserProfileIds())
.containsExactlyElementsIn(userIdList);
- });
- initializeUserManagerState(currentUser, Arrays.asList(mPersonalUser, mOtherUser2));
- InstrumentationRegistry.getInstrumentation()
- .runOnMainSync(
- () -> {
- assertThat(mUserManagerState.isMultiUserProfiles()).isFalse();
- assertThat(mUserManagerState.getAllUserProfileIds())
- .containsExactlyElementsIn(
- Arrays.asList(UserId.of(mPersonalUser)));
+ assertThat(
+ mUserManagerState.isManagedUserProfile(
+ mUserManagerState.getCurrentUserProfileId()))
+ .isFalse();
});
}
@@ -556,56 +561,6 @@ public class UserManagerStateTest {
mUserManagerState.getCurrentUserProfileId()))
.isTrue();
});
-
- // set current user as otherUser2
- InstrumentationRegistry.getInstrumentation()
- .runOnMainSync(
- () -> {
- mUserManagerState.setUserAsCurrentUserProfile(UserId.of(mOtherUser2));
- assertThat(mUserManagerState.getCurrentUserProfileId())
- .isEqualTo(UserId.of(mManagedUser));
- });
-
- // set current user as otherUser1
- InstrumentationRegistry.getInstrumentation()
- .runOnMainSync(
- () -> {
- mUserManagerState.setUserAsCurrentUserProfile(UserId.of(mOtherUser1));
- UserHandle currentUserProfile =
- SdkLevel.isAtLeastV() ? mOtherUser1 : mManagedUser;
- assertThat(mUserManagerState.getCurrentUserProfileId())
- .isEqualTo(UserId.of(currentUserProfile));
- });
-
- // set current user as personalUser
- InstrumentationRegistry.getInstrumentation()
- .runOnMainSync(
- () -> {
- mUserManagerState.setUserAsCurrentUserProfile(UserId.of(mPersonalUser));
- assertThat(mUserManagerState.getCurrentUserProfileId())
- .isEqualTo(UserId.of(mPersonalUser));
- });
-
- // set current user otherUser3
- InstrumentationRegistry.getInstrumentation()
- .runOnMainSync(
- () -> {
- mUserManagerState.setUserAsCurrentUserProfile(UserId.of(mOtherUser3));
- assertThat(mUserManagerState.getCurrentUserProfileId())
- .isEqualTo(UserId.of(mPersonalUser));
-
- List<UserId> userIdList =
- SdkLevel.isAtLeastV()
- ? Arrays.asList(
- UserId.of(mPersonalUser),
- UserId.of(mManagedUser),
- UserId.of(mOtherUser1))
- : Arrays.asList(
- UserId.of(mPersonalUser),
- UserId.of(mManagedUser));
- assertThat(mUserManagerState.getAllUserProfileIds())
- .containsExactlyElementsIn(userIdList);
- });
}
private void initializeUserManagerState(UserId current, List<UserHandle> usersOnDevice) {