Loading core/java/android/content/pm/multiuser.aconfig +8 −0 Original line number Diff line number Diff line Loading @@ -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 } core/java/android/os/IUserManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -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); Loading core/java/android/os/UserManager.java +46 −1 Original line number Diff line number Diff line Loading @@ -2352,6 +2352,17 @@ public class UserManager { @SystemApi 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. * Loading @@ -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 {} Loading Loading @@ -2562,6 +2575,17 @@ public class UserManager { .getBoolean(com.android.internal.R.bool.config_omnipresentCommunalUser)); } /** * 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 Loading Loading @@ -3154,6 +3178,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 Loading services/core/java/com/android/server/pm/UserManagerService.java +32 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -2750,6 +2762,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"); Loading Loading @@ -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) { Loading Loading @@ -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; Loading Loading @@ -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( Loading services/core/java/com/android/server/pm/UserTypeFactory.java +1 −0 Original line number Diff line number Diff line Loading @@ -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) Loading Loading
core/java/android/content/pm/multiuser.aconfig +8 −0 Original line number Diff line number Diff line Loading @@ -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 }
core/java/android/os/IUserManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
core/java/android/os/UserManager.java +46 −1 Original line number Diff line number Diff line Loading @@ -2352,6 +2352,17 @@ public class UserManager { @SystemApi 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. * Loading @@ -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 {} Loading Loading @@ -2562,6 +2575,17 @@ public class UserManager { .getBoolean(com.android.internal.R.bool.config_omnipresentCommunalUser)); } /** * 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 Loading Loading @@ -3154,6 +3178,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 Loading
services/core/java/com/android/server/pm/UserManagerService.java +32 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -2750,6 +2762,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"); Loading Loading @@ -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) { Loading Loading @@ -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; Loading Loading @@ -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( Loading
services/core/java/com/android/server/pm/UserTypeFactory.java +1 −0 Original line number Diff line number Diff line Loading @@ -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) Loading