diff options
| author | 2024-03-07 10:45:25 +0000 | |
|---|---|---|
| committer | 2024-03-07 10:45:25 +0000 | |
| commit | 91e9bac3ed82f89a9bd22e7508840ab7d9c65e4f (patch) | |
| tree | 06d1cf2cade7faa2f36a8968ce52c66753a4f300 | |
| parent | a126e5fc3c116c0ad742517fde8b2438dbdb8811 (diff) | |
| parent | 4e9eb5f76ab0807289ed1e18e56ecf1facffe852 (diff) | |
Merge "Block private space creation based on device conditions" into main
7 files changed, 207 insertions, 9 deletions
diff --git a/core/java/android/content/pm/multiuser.aconfig b/core/java/android/content/pm/multiuser.aconfig index ac80561c3b50..48a7cc920f1d 100644 --- a/core/java/android/content/pm/multiuser.aconfig +++ b/core/java/android/content/pm/multiuser.aconfig @@ -184,3 +184,11 @@ flag { description: "Enable Private Space telephony and SMS intent redirection to the main user" bug: "325576602" } + +flag { + name: "block_private_space_creation" + namespace: "profile_experiences" + description: "Allow blocking private space creation based on specific conditions" + bug: "290333800" + is_fixed_read_only: true +} diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl index 800ba6d3a542..23d6007e3d8b 100644 --- a/core/java/android/os/IUserManager.aidl +++ b/core/java/android/os/IUserManager.aidl @@ -85,6 +85,7 @@ interface IUserManager { boolean isUserSwitcherEnabled(boolean showEvenIfNotActionable, int mUserId); boolean isRestricted(int userId); boolean canHaveRestrictedProfile(int userId); + boolean canAddPrivateProfile(int userId); int getUserSerialNumber(int userId); int getUserHandle(int userSerialNumber); int getUserRestrictionSource(String restrictionKey, int userId); diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index 9757a1096a30..fdaa0b467566 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -2353,6 +2353,17 @@ public class UserManager { public static final int USER_OPERATION_ERROR_USER_ACCOUNT_ALREADY_EXISTS = 7; /** + * Indicates user operation failed because user is disabled on the device. + * @hide + */ + public static final int USER_OPERATION_ERROR_DISABLED_USER = 8; + /** + * Indicates user operation failed because user is disabled on the device. + * @hide + */ + public static final int USER_OPERATION_ERROR_PRIVATE_PROFILE = 9; + + /** * Result returned from various user operations. * * @hide @@ -2366,7 +2377,9 @@ public class UserManager { USER_OPERATION_ERROR_CURRENT_USER, USER_OPERATION_ERROR_LOW_STORAGE, USER_OPERATION_ERROR_MAX_USERS, - USER_OPERATION_ERROR_USER_ACCOUNT_ALREADY_EXISTS + USER_OPERATION_ERROR_USER_ACCOUNT_ALREADY_EXISTS, + USER_OPERATION_ERROR_DISABLED_USER, + USER_OPERATION_ERROR_PRIVATE_PROFILE, }) public @interface UserOperationResult {} @@ -2563,6 +2576,17 @@ public class UserManager { } /** + * Returns whether the device supports Private Profile + * @hide + */ + public static boolean isPrivateProfileEnabled() { + if (android.multiuser.Flags.blockPrivateSpaceCreation()) { + return !ActivityManager.isLowRamDeviceStatic(); + } + return true; + } + + /** * Returns whether multiple admins are enabled on the device * @hide */ @@ -3155,6 +3179,27 @@ public class UserManager { } /** + * Checks if it's possible to add a private profile to the context user + * @return whether the context user can add a private profile. + * @hide + */ + @RequiresPermission(anyOf = { + Manifest.permission.MANAGE_USERS, + Manifest.permission.CREATE_USERS}, + conditional = true) + @UserHandleAware + public boolean canAddPrivateProfile() { + if (android.multiuser.Flags.blockPrivateSpaceCreation()) { + try { + return mService.canAddPrivateProfile(mUserId); + } catch (RemoteException re) { + throw re.rethrowFromSystemServer(); + } + } + return true; + } + + /** * Returns whether the context user has at least one restricted profile associated with it. * @return whether the user has a restricted profile associated with it * @hide diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 7349755402b1..e0af5fcab779 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -21,10 +21,15 @@ import static android.content.Intent.ACTION_SCREEN_ON; import static android.content.Intent.EXTRA_USER_ID; import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; +import static android.content.pm.PackageManager.FEATURE_AUTOMOTIVE; +import static android.content.pm.PackageManager.FEATURE_EMBEDDED; +import static android.content.pm.PackageManager.FEATURE_LEANBACK; +import static android.content.pm.PackageManager.FEATURE_WATCH; import static android.os.UserManager.DEV_CREATE_OVERRIDE_PROPERTY; import static android.os.UserManager.DISALLOW_USER_SWITCH; import static android.os.UserManager.SYSTEM_USER_MODE_EMULATION_PROPERTY; import static android.os.UserManager.USER_OPERATION_ERROR_UNKNOWN; +import static android.os.UserManager.USER_TYPE_PROFILE_PRIVATE; import static com.android.internal.app.SetScreenLockDialogActivity.EXTRA_ORIGIN_USER_ID; import static com.android.internal.app.SetScreenLockDialogActivity.LAUNCH_REASON_DISABLE_QUIET_MODE; @@ -1006,6 +1011,13 @@ public class UserManagerService extends IUserManager.Stub { emulateSystemUserModeIfNeeded(); } + private boolean doesDeviceHardwareSupportPrivateSpace() { + return !mPm.hasSystemFeature(FEATURE_EMBEDDED, 0) + && !mPm.hasSystemFeature(FEATURE_WATCH, 0) + && !mPm.hasSystemFeature(FEATURE_LEANBACK, 0) + && !mPm.hasSystemFeature(FEATURE_AUTOMOTIVE, 0); + } + private static boolean isAutoLockForPrivateSpaceEnabled() { return android.os.Flags.allowPrivateProfile() && Flags.supportAutolockForPrivateSpace(); @@ -2751,6 +2763,18 @@ public class UserManagerService extends IUserManager.Stub { } @Override + public boolean canAddPrivateProfile(@UserIdInt int userId) { + checkCreateUsersPermission("canHaveRestrictedProfile"); + UserInfo parentUserInfo = getUserInfo(userId); + return isUserTypeEnabled(USER_TYPE_PROFILE_PRIVATE) + && canAddMoreProfilesToUser(USER_TYPE_PROFILE_PRIVATE, + userId, /* allowedToRemoveOne */ false) + && (parentUserInfo != null && parentUserInfo.isMain()) + && doesDeviceHardwareSupportPrivateSpace() + && !hasUserRestriction(UserManager.DISALLOW_ADD_PRIVATE_PROFILE, userId); + } + + @Override public boolean hasRestrictedProfiles(@UserIdInt int userId) { checkManageUsersPermission("hasRestrictedProfiles"); synchronized (mUsersLock) { @@ -5308,7 +5332,7 @@ public class UserManagerService extends IUserManager.Stub { if (!isUserTypeEnabled(userTypeDetails)) { throwCheckedUserOperationException( "Cannot add a user of disabled type " + userType + ".", - UserManager.USER_OPERATION_ERROR_MAX_USERS); + UserManager.USER_OPERATION_ERROR_DISABLED_USER); } synchronized (mUsersLock) { @@ -5341,6 +5365,7 @@ public class UserManagerService extends IUserManager.Stub { final boolean isDemo = UserManager.isUserTypeDemo(userType); final boolean isManagedProfile = UserManager.isUserTypeManagedProfile(userType); final boolean isCommunalProfile = UserManager.isUserTypeCommunalProfile(userType); + final boolean isPrivateProfile = UserManager.isUserTypePrivateProfile(userType); final long ident = Binder.clearCallingIdentity(); UserInfo userInfo; @@ -5387,6 +5412,12 @@ public class UserManagerService extends IUserManager.Stub { + " for user " + parentId, UserManager.USER_OPERATION_ERROR_MAX_USERS); } + if (android.multiuser.Flags.blockPrivateSpaceCreation() + && isPrivateProfile && !canAddPrivateProfile(parentId)) { + throwCheckedUserOperationException( + "Cannot add profile of type " + userType + " for user " + parentId, + UserManager.USER_OPERATION_ERROR_PRIVATE_PROFILE); + } if (isRestricted && (parentId != UserHandle.USER_SYSTEM) && !isCreationOverrideEnabled()) { throwCheckedUserOperationException( diff --git a/services/core/java/com/android/server/pm/UserTypeFactory.java b/services/core/java/com/android/server/pm/UserTypeFactory.java index 114daaac3c18..7f9c1cfafe68 100644 --- a/services/core/java/com/android/server/pm/UserTypeFactory.java +++ b/services/core/java/com/android/server/pm/UserTypeFactory.java @@ -292,6 +292,7 @@ public final class UserTypeFactory { .setName(USER_TYPE_PROFILE_PRIVATE) .setBaseType(FLAG_PROFILE) .setMaxAllowedPerParent(1) + .setEnabled(UserManager.isPrivateProfileEnabled() ? 1 : 0) .setLabels(R.string.profile_label_private) .setIconBadge(com.android.internal.R.drawable.ic_private_profile_icon_badge) .setBadgePlain(com.android.internal.R.drawable.ic_private_profile_badge) diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java index 7bbcd50cdf1f..bc7c9a59ff29 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java @@ -15,6 +15,10 @@ */ package com.android.server.pm; +import static android.content.pm.PackageManager.FEATURE_AUTOMOTIVE; +import static android.content.pm.PackageManager.FEATURE_EMBEDDED; +import static android.content.pm.PackageManager.FEATURE_LEANBACK; +import static android.content.pm.PackageManager.FEATURE_WATCH; import static android.os.UserManager.DISALLOW_OUTGOING_CALLS; import static android.os.UserManager.DISALLOW_SMS; import static android.os.UserManager.DISALLOW_USER_SWITCH; @@ -41,6 +45,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.when; import android.annotation.UserIdInt; +import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.KeyguardManager; import android.content.Context; @@ -48,6 +53,7 @@ import android.content.pm.PackageManagerInternal; import android.content.pm.UserInfo; import android.multiuser.Flags; import android.os.PowerManager; +import android.os.ServiceSpecificException; import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; @@ -76,6 +82,7 @@ import org.junit.Rule; import org.junit.Test; import org.mockito.Mock; import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -120,11 +127,14 @@ public final class UserManagerServiceTest { private static final String TAG_RESTRICTIONS = "restrictions"; + private static final String PRIVATE_PROFILE_NAME = "TestPrivateProfile"; + @Rule public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this) .spyStatic(UserManager.class) .spyStatic(LocalServices.class) .spyStatic(SystemProperties.class) + .spyStatic(ActivityManager.class) .mockStatic(Settings.Global.class) .mockStatic(Settings.Secure.class) .build(); @@ -163,6 +173,7 @@ public final class UserManagerServiceTest { @Before @UiThreadTest // Needed to initialize main handler public void setFixtures() { + MockitoAnnotations.initMocks(this); mSpiedContext = spy(mRealContext); // Called when WatchedUserStates is constructed @@ -172,11 +183,12 @@ public final class UserManagerServiceTest { when(mDeviceStorageMonitorInternal.isMemoryLow()).thenReturn(false); mockGetLocalService(DeviceStorageMonitorInternal.class, mDeviceStorageMonitorInternal); when(mSpiedContext.getSystemService(StorageManager.class)).thenReturn(mStorageManager); - when(mSpiedContext.getSystemService(KeyguardManager.class)).thenReturn(mKeyguardManager); + doReturn(mKeyguardManager).when(mSpiedContext).getSystemService(KeyguardManager.class); when(mSpiedContext.getSystemService(PowerManager.class)).thenReturn(mPowerManager); mockGetLocalService(LockSettingsInternal.class, mLockSettingsInternal); mockGetLocalService(PackageManagerInternal.class, mPackageManagerInternal); doNothing().when(mSpiedContext).sendBroadcastAsUser(any(), any(), any()); + mockIsLowRamDevice(false); // Must construct UserManagerService in the UiThread mTestDir = new File(mRealContext.getDataDir(), "umstest"); @@ -570,9 +582,10 @@ public final class UserManagerServiceTest { @Test public void testAutoLockPrivateProfile() { + mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE); UserManagerService mSpiedUms = spy(mUms); UserInfo privateProfileUser = - mSpiedUms.createProfileForUserEvenWhenDisallowedWithThrow("TestPrivateProfile", + mSpiedUms.createProfileForUserEvenWhenDisallowedWithThrow(PRIVATE_PROFILE_NAME, USER_TYPE_PROFILE_PRIVATE, 0, 0, null); Mockito.doNothing().when(mSpiedUms).setQuietModeEnabledAsync( eq(privateProfileUser.getUserHandle().getIdentifier()), eq(true), any(), @@ -587,10 +600,11 @@ public final class UserManagerServiceTest { @Test public void testAutoLockOnDeviceLockForPrivateProfile() { + mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE); mSetFlagsRule.enableFlags(Flags.FLAG_SUPPORT_AUTOLOCK_FOR_PRIVATE_SPACE); UserManagerService mSpiedUms = spy(mUms); UserInfo privateProfileUser = - mSpiedUms.createProfileForUserEvenWhenDisallowedWithThrow("TestPrivateProfile", + mSpiedUms.createProfileForUserEvenWhenDisallowedWithThrow(PRIVATE_PROFILE_NAME, USER_TYPE_PROFILE_PRIVATE, 0, 0, null); mockAutoLockForPrivateSpace(Settings.Secure.PRIVATE_SPACE_AUTO_LOCK_ON_DEVICE_LOCK); Mockito.doNothing().when(mSpiedUms).setQuietModeEnabledAsync( @@ -606,10 +620,11 @@ public final class UserManagerServiceTest { @Test public void testAutoLockOnDeviceLockForPrivateProfile_keyguardUnlocked() { + mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE); mSetFlagsRule.enableFlags(Flags.FLAG_SUPPORT_AUTOLOCK_FOR_PRIVATE_SPACE); UserManagerService mSpiedUms = spy(mUms); UserInfo privateProfileUser = - mSpiedUms.createProfileForUserEvenWhenDisallowedWithThrow("TestPrivateProfile", + mSpiedUms.createProfileForUserEvenWhenDisallowedWithThrow(PRIVATE_PROFILE_NAME, USER_TYPE_PROFILE_PRIVATE, 0, 0, null); mockAutoLockForPrivateSpace(Settings.Secure.PRIVATE_SPACE_AUTO_LOCK_ON_DEVICE_LOCK); @@ -623,10 +638,11 @@ public final class UserManagerServiceTest { @Test public void testAutoLockOnDeviceLockForPrivateProfile_flagDisabled() { + mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE); mSetFlagsRule.disableFlags(Flags.FLAG_SUPPORT_AUTOLOCK_FOR_PRIVATE_SPACE); UserManagerService mSpiedUms = spy(mUms); UserInfo privateProfileUser = - mSpiedUms.createProfileForUserEvenWhenDisallowedWithThrow("TestPrivateProfile", + mSpiedUms.createProfileForUserEvenWhenDisallowedWithThrow(PRIVATE_PROFILE_NAME, USER_TYPE_PROFILE_PRIVATE, 0, 0, null); mSpiedUms.tryAutoLockingPrivateSpaceOnKeyguardChanged(true); @@ -641,13 +657,14 @@ public final class UserManagerServiceTest { @Test public void testAutoLockAfterInactityForPrivateProfile() { + mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE); mSetFlagsRule.enableFlags(Flags.FLAG_SUPPORT_AUTOLOCK_FOR_PRIVATE_SPACE); UserManagerService mSpiedUms = spy(mUms); mockAutoLockForPrivateSpace(Settings.Secure.PRIVATE_SPACE_AUTO_LOCK_AFTER_INACTIVITY); when(mPowerManager.isInteractive()).thenReturn(false); UserInfo privateProfileUser = - mSpiedUms.createProfileForUserEvenWhenDisallowedWithThrow("TestPrivateProfile", + mSpiedUms.createProfileForUserEvenWhenDisallowedWithThrow(PRIVATE_PROFILE_NAME, USER_TYPE_PROFILE_PRIVATE, 0, 0, null); Mockito.doNothing().when(mSpiedUms).scheduleMessageToAutoLockPrivateSpace( eq(privateProfileUser.getUserHandle().getIdentifier()), any(), @@ -662,6 +679,7 @@ public final class UserManagerServiceTest { @Test public void testSetOrUpdateAutoLockPreference_noPrivateProfile() { + mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE); mSetFlagsRule.enableFlags(Flags.FLAG_SUPPORT_AUTOLOCK_FOR_PRIVATE_SPACE); mUms.setOrUpdateAutoLockPreferenceForPrivateProfile( @@ -675,8 +693,9 @@ public final class UserManagerServiceTest { @Test public void testSetOrUpdateAutoLockPreference() { + mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE); mSetFlagsRule.enableFlags(Flags.FLAG_SUPPORT_AUTOLOCK_FOR_PRIVATE_SPACE); - mUms.createProfileForUserEvenWhenDisallowedWithThrow("TestPrivateProfile", + mUms.createProfileForUserEvenWhenDisallowedWithThrow(PRIVATE_PROFILE_NAME, USER_TYPE_PROFILE_PRIVATE, 0, 0, null); // Set the preference to auto lock on device lock @@ -733,6 +752,77 @@ public final class UserManagerServiceTest { } } + @Test + public void testCreatePrivateProfileOnHeadlessSystemUser_shouldAllowCreation() { + mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE); + mSetFlagsRule.enableFlags(Flags.FLAG_BLOCK_PRIVATE_SPACE_CREATION); + UserManagerService mSpiedUms = spy(mUms); + int mainUser = mSpiedUms.getMainUserId(); + doReturn(true).when(mSpiedUms).isHeadlessSystemUserMode(); + assertThat(mSpiedUms.canAddPrivateProfile(mainUser)).isTrue(); + assertThat(mSpiedUms.createProfileForUserEvenWhenDisallowedWithThrow( + PRIVATE_PROFILE_NAME, USER_TYPE_PROFILE_PRIVATE, 0, mainUser, null)).isNotNull(); + } + + @Test + public void testCreatePrivateProfileOnSecondaryUser_shouldNotAllowCreation() { + mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE); + mSetFlagsRule.enableFlags(Flags.FLAG_BLOCK_PRIVATE_SPACE_CREATION); + UserInfo user = mUms.createUserWithThrow(generateLongString(), USER_TYPE_FULL_SECONDARY, 0); + assertThat(mUms.canAddPrivateProfile(user.id)).isFalse(); + assertThrows(ServiceSpecificException.class, + () -> mUms.createProfileForUserWithThrow(PRIVATE_PROFILE_NAME, + USER_TYPE_PROFILE_PRIVATE, 0, user.id, null)); + } + + @Test + public void testCreatePrivateProfileOnAutoDevices_shouldNotAllowCreation() { + mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE); + mSetFlagsRule.enableFlags(Flags.FLAG_BLOCK_PRIVATE_SPACE_CREATION); + doReturn(true).when(mMockPms).hasSystemFeature(eq(FEATURE_AUTOMOTIVE), anyInt()); + int mainUser = mUms.getMainUserId(); + assertThat(mUms.canAddPrivateProfile(0)).isFalse(); + assertThrows(ServiceSpecificException.class, + () -> mUms.createProfileForUserWithThrow(PRIVATE_PROFILE_NAME, + USER_TYPE_PROFILE_PRIVATE, 0, mainUser, null)); + } + + @Test + public void testCreatePrivateProfileOnTV_shouldNotAllowCreation() { + mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE); + mSetFlagsRule.enableFlags(Flags.FLAG_BLOCK_PRIVATE_SPACE_CREATION); + doReturn(true).when(mMockPms).hasSystemFeature(eq(FEATURE_LEANBACK), anyInt()); + int mainUser = mUms.getMainUserId(); + assertThat(mUms.canAddPrivateProfile(0)).isFalse(); + assertThrows(ServiceSpecificException.class, + () -> mUms.createProfileForUserEvenWhenDisallowedWithThrow(PRIVATE_PROFILE_NAME, + USER_TYPE_PROFILE_PRIVATE, 0, mainUser, null)); + } + + @Test + public void testCreatePrivateProfileOnEmbedded_shouldNotAllowCreation() { + mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE); + mSetFlagsRule.enableFlags(Flags.FLAG_BLOCK_PRIVATE_SPACE_CREATION); + doReturn(true).when(mMockPms).hasSystemFeature(eq(FEATURE_EMBEDDED), anyInt()); + int mainUser = mUms.getMainUserId(); + assertThat(mUms.canAddPrivateProfile(0)).isFalse(); + assertThrows(ServiceSpecificException.class, + () -> mUms.createProfileForUserEvenWhenDisallowedWithThrow(PRIVATE_PROFILE_NAME, + USER_TYPE_PROFILE_PRIVATE, 0, mainUser, null)); + } + + @Test + public void testCreatePrivateProfileOnWatch_shouldNotAllowCreation() { + mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE); + mSetFlagsRule.enableFlags(Flags.FLAG_BLOCK_PRIVATE_SPACE_CREATION); + doReturn(true).when(mMockPms).hasSystemFeature(eq(FEATURE_WATCH), anyInt()); + int mainUser = mUms.getMainUserId(); + assertThat(mUms.canAddPrivateProfile(0)).isFalse(); + assertThrows(ServiceSpecificException.class, + () -> mUms.createProfileForUserEvenWhenDisallowedWithThrow(PRIVATE_PROFILE_NAME, + USER_TYPE_PROFILE_PRIVATE, 0, mainUser, null)); + } + /** * Returns true if the user's XML file has Default restrictions * @param userId Id of the user. @@ -800,6 +890,10 @@ public final class UserManagerServiceTest { any(), eq(android.provider.Settings.Global.USER_SWITCHER_ENABLED), anyInt())); } + private void mockIsLowRamDevice(boolean isLowRamDevice) { + doReturn(isLowRamDevice).when(ActivityManager::isLowRamDeviceStatic); + } + private void mockDeviceDemoMode(boolean enabled) { doReturn(enabled ? 1 : 0).when(() -> Settings.Global.getInt( any(), eq(android.provider.Settings.Global.DEVICE_DEMO_MODE), anyInt())); diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java index 507b3fe62e29..1591a963a406 100644 --- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java @@ -316,6 +316,10 @@ public final class UserManagerTest { .that(userTypeDetails).isNotNull(); final UserProperties typeProps = userTypeDetails.getDefaultUserPropertiesReference(); + // Only run the test if private profile creation is enabled on the device + assumeTrue("Private profile not enabled on the device", + mUserManager.canAddPrivateProfile()); + // Test that only one private profile can be created final int mainUserId = mainUser.getIdentifier(); UserInfo userInfo = createProfileForUser("Private profile1", @@ -1231,6 +1235,20 @@ public final class UserManagerTest { @MediumTest @Test + public void testPrivateProfileCreationRestrictions() { + assumeTrue(mUserManager.canAddPrivateProfile()); + final int mainUserId = ActivityManager.getCurrentUser(); + try { + UserInfo privateProfileInfo = createProfileForUser("Private", + UserManager.USER_TYPE_PROFILE_PRIVATE, mainUserId); + assertThat(privateProfileInfo).isNotNull(); + } catch (Exception e) { + fail("Creation of private profile failed due to " + e.getMessage()); + } + } + + @MediumTest + @Test public void testAddRestrictedProfile() throws Exception { if (isAutomotive() || UserManager.isHeadlessSystemUserMode()) return; assertWithMessage("There should be no associated restricted profiles before the test") |