Loading core/api/test-current.txt +1 −1 Original line number Diff line number Diff line Loading @@ -2623,7 +2623,7 @@ package android.os { } public class UserManager { method @FlaggedApi("android.os.allow_private_profile") @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public boolean canAddPrivateProfile(); method @FlaggedApi("android.os.allow_private_profile") @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS, android.Manifest.permission.QUERY_USERS}) public boolean canAddPrivateProfile(); method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public android.content.pm.UserInfo createProfileForUser(@Nullable String, @NonNull String, int, int, @Nullable String[]); method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public android.content.pm.UserInfo createRestrictedProfile(@Nullable String); method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public android.content.pm.UserInfo createUser(@Nullable String, @NonNull String, int); Loading core/java/android/content/pm/UserInfo.java +21 −3 Original line number Diff line number Diff line Loading @@ -473,7 +473,7 @@ public class UserInfo implements Parcelable { /** * @return true if user is of type {@link UserManager#USER_TYPE_SYSTEM_HEADLESS} and * {@link com.android.internal.R.bool.config_canSwitchToHeadlessSystemUser} is true. * {@link com.android.internal.R.bool#config_canSwitchToHeadlessSystemUser} is true. */ @android.ravenwood.annotation.RavenwoodThrow private boolean canSwitchToHeadlessSystemUser() { Loading @@ -491,8 +491,10 @@ public class UserInfo implements Parcelable { return supportsSwitchTo(); } // TODO(b/142482943): Make this logic more specific and customizable. (canHaveProfile(userType)) /* @hide */ /** * Returns whether the user can have profiles, in general (on the basis of its UserInfo data). * See {@link #canHaveProfile(String)} for more fine-grained determination. */ public boolean canHaveProfile() { if (!isFull() || isProfile() || isGuest() || isRestricted() || isDemo()) { return false; Loading @@ -506,6 +508,22 @@ public class UserInfo implements Parcelable { com.android.internal.R.bool.config_supportProfilesOnNonMainUser)); } /** * Returns if the user can have a profile of the given type (on the basis of its UserInfo data). * @hide */ public boolean canHaveProfile(String userType) { if (!canHaveProfile()) { return false; } if (UserManager.isUserTypePrivateProfile(userType)) { // Even if we eventually allow other users to have profiles too, only MainUsers are // eligible to have a Private Space, for some reason. return isMain(); } return true; } // TODO(b/142482943): Get rid of this (after removing it from all tests) if feasible. /** * @deprecated This is dangerous since it doesn't set the mandatory fields. Use a different Loading core/java/android/content/pm/multiuser.aconfig +21 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,27 @@ flag { bug: "285426179" } flag { name: "consistent_max_users" namespace: "multiuser" description: "Makes max supported users be consistent and fine-grained." bug: "394178333" } flag { name: "consistent_max_users_including_guests" namespace: "multiuser" description: "Builds on consistent_max_users, making Guest users included in the max." bug: "394178333" } flag { name: "max_users_in_car_is_for_secondary" namespace: "multiuser" description: "Update Car SystemUi and Settings to specify FULL_SECONDARY for max users (alongside consistent_max_users flag)." bug: "394178333" } flag { name: "support_communal_profile_nextgen" is_exported: true Loading core/java/android/os/IUserManager.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -66,11 +66,11 @@ interface IUserManager { List<UserInfo> getProfiles(int userId, boolean enabledOnly); int[] getProfileIds(int userId, boolean enabledOnly); boolean isUserTypeEnabled(in String userType); int getCurrentAllowedNumberOfUsers(in String userType); boolean canAddMoreUsersOfType(in String userType); int getRemainingCreatableUserCount(in String userType); int getRemainingCreatableProfileCount(in String userType, int userId); boolean canAddMoreProfilesToUser(in String userType, int userId, boolean allowedToRemoveOne); boolean canAddMoreManagedProfiles(int userId, boolean allowedToRemoveOne); UserInfo getProfileParent(int userId); boolean isSameProfileGroup(int userId, int otherUserHandle); boolean isHeadlessSystemUserMode(); Loading core/java/android/os/UserManager.java +137 −46 Original line number Diff line number Diff line Loading @@ -2460,10 +2460,10 @@ public class UserManager { */ public static final int USER_OPERATION_ERROR_DISABLED_USER = 8; /** * Indicates user operation failed because private space is disabled on the device. * Indicates user operation failed because the system features do not support this user type. * @hide */ public static final int USER_OPERATION_ERROR_PRIVATE_PROFILE = 9; public static final int USER_OPERATION_ERROR_FEATURE_UNSUPPORTED = 9; /** * Indicates user operation failed because user is restricted on the device. * @hide Loading @@ -2486,7 +2486,7 @@ public class UserManager { USER_OPERATION_ERROR_MAX_USERS, USER_OPERATION_ERROR_USER_ACCOUNT_ALREADY_EXISTS, USER_OPERATION_ERROR_DISABLED_USER, USER_OPERATION_ERROR_PRIVATE_PROFILE, USER_OPERATION_ERROR_FEATURE_UNSUPPORTED, USER_OPERATION_ERROR_USER_RESTRICTED, }) public @interface UserOperationResult {} Loading Loading @@ -2646,7 +2646,9 @@ public class UserManager { /** * Returns whether this device supports multiple users with their own login and customizable * space. * @return whether the device supports multiple users. * <p>Note that, even if false, multiple users might still be possible, as long as no login UI * is required; e.g., profiles might still be supported, as they do not require a login UI. * @return whether the device supports multiple switchable users. */ public static boolean supportsMultipleUsers() { return getMaxSupportedUsers() > 1 Loading Loading @@ -3341,7 +3343,12 @@ public class UserManager { } /** * Checks if it's possible to add a private profile to the context user * Checks if it's possible to add a private profile to the context user. * * Takes into account any possible considerations, including whether the user type is supported, * maximum user limits, and UserRestrictions (and so is inconsistent with similar APIs in this * class.) * * @return whether the context user can add a private profile. * @hide */ Loading @@ -3349,11 +3356,17 @@ public class UserManager { @FlaggedApi(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE) @RequiresPermission(anyOf = { Manifest.permission.MANAGE_USERS, Manifest.permission.CREATE_USERS}) Manifest.permission.CREATE_USERS, Manifest.permission.QUERY_USERS}) @UserHandleAware public boolean canAddPrivateProfile() { if (!android.multiuser.Flags.enablePrivateSpaceFeatures()) return false; if (android.multiuser.Flags.blockPrivateSpaceCreation()) { // TODO(b/413464199): Ideally, move this client-side, changing it to // if (android.multiuser.Flags.consistentMaxUsers()) { // return canAddMoreProfilesToUser(USER_TYPE_PROFILE_PRIVATE, mUserId) // && !hasUserRestriction(UserManager.DISALLOW_ADD_PRIVATE_PROFILE); // } try { return mService.canAddPrivateProfile(mUserId); } catch (RemoteException re) { Loading Loading @@ -5256,38 +5269,13 @@ public class UserManager { } } /** * Checks whether it's possible to add more users. * * @return true if more users can be added, false if limit has been reached. * * @deprecated use {@link #canAddMoreUsers(String)} instead. * * @hide */ @Deprecated @RequiresPermission(anyOf = { android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS }) public boolean canAddMoreUsers() { // TODO(b/142482943): UMS has different logic, excluding Demo and Profile from counting. Why // not here? The logic is inconsistent. See UMS.canAddMoreManagedProfiles final List<UserInfo> users = getAliveUsers(); final int totalUserCount = users.size(); int aliveUserCount = 0; for (int i = 0; i < totalUserCount; i++) { UserInfo user = users.get(i); if (!user.isGuest()) { aliveUserCount++; } } return aliveUserCount < getMaxSupportedUsers(); } /** * Checks whether it is possible to add more users of the given user type. * * Takes into account whether the user type is supported and maximum user limits, but does not * take into account UserRestrictions. * It is consistent with {@link #getRemainingCreatableUserCount(String)}. * * @param userType the type of user, such as {@link UserManager#USER_TYPE_FULL_SECONDARY}. * @return true if more users of the given type can be added, otherwise false. * @hide Loading @@ -5297,12 +5285,12 @@ public class UserManager { android.Manifest.permission.CREATE_USERS }) public boolean canAddMoreUsers(@NonNull String userType) { if (!android.multiuser.Flags.consistentMaxUsers()) { return canAddMoreUsersLegacy(userType); } try { if (userType.equals(USER_TYPE_FULL_GUEST)) { // Differs from getRemainingCreatableUserCount only because of isCreationOverrideEnabled return mService.canAddMoreUsersOfType(userType); } else { return canAddMoreUsers() && mService.canAddMoreUsersOfType(userType); } } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } Loading Loading @@ -5360,6 +5348,10 @@ public class UserManager { * if allowedToRemoveOne is true and if the user already has a managed profile, then return if * we could add a new managed profile to this user after removing the existing one. * * Takes into account whether the user type is supported and maximum user limits, but does not * take into account UserRestrictions. * It is consistent with {@link #getRemainingCreatableProfileCount(String)}. * * @return true if more managed profiles can be added, false if limit has been reached. * @hide */ Loading @@ -5370,7 +5362,8 @@ public class UserManager { }) public boolean canAddMoreManagedProfiles(@UserIdInt int userId, boolean allowedToRemoveOne) { try { return mService.canAddMoreManagedProfiles(userId, allowedToRemoveOne); return mService.canAddMoreProfilesToUser( USER_TYPE_PROFILE_MANAGED, userId, allowedToRemoveOne); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } Loading @@ -5379,6 +5372,10 @@ public class UserManager { /** * Checks whether it's possible to add more profiles of the given type to the given user. * * Takes into account whether the user type is supported and maximum user limits, but does not * take into account UserRestrictions. * It is consistent with {@link #getRemainingCreatableProfileCount(String)}. * * @param userType the type of user, such as {@link UserManager#USER_TYPE_PROFILE_MANAGED}. * @return true if more profiles can be added, false if limit has been reached. * @hide Loading @@ -5396,6 +5393,39 @@ public class UserManager { } } /** * Returns how many users of the given type are currently allowed on the device, including ones * that already exist. * * Takes into account the maximum number of users allowed on the device (of that type, and in * general), as well as how many users of other types are already on the device (which thereby * already count towards the device maximum). Does not take into account UserRestrictions. * It is consistent with {@link #getRemainingCreatableUserCount(String)}. * * The value will be no less than the number of users of that type that currently exist (even if * that value exceeds the maximum allowed, for whatever reason). * * @return a value greater than or equal to 0 * @hide */ @RequiresPermission(anyOf = { android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS }) public int getCurrentAllowedNumberOfUsers(@NonNull String userType) { if (!android.multiuser.Flags.consistentMaxUsers()) { throw new UnsupportedOperationException("This method requires flag consistentMaxUsers"); } try { // Note: If we get rid of the overall device max, this should be the same as // UMS.getMaxSupportedUsersOfType(). But even then it can still technically differ if // the max gets exceeded for any reason. return mService.getCurrentAllowedNumberOfUsers(userType); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } /** * Checks whether this device supports users of the given user type. * Loading Loading @@ -6504,15 +6534,22 @@ public class UserManager { } /** * Returns the maximum number of users that can be created on this device. A return value * of 1 means that it is a single user device. * @hide * Returns the maximum number of users (of any type) that can be created on this device. * A return value of 1 means that it is a single-user device. * * This value is based on the device's limitation of total number of users. This is typically * limited by storage considerations, not UX considerations (which depends on user type). * Note that this includes all types of users, including profile and guest users * (if {@link android.multiuser.Flags#consistentMaxUsersIncludingGuests()} is true). * * Under very rare circumstances, the number of users on the device can exceed this amount * (such as if it were decreased during an OTA but more users had already been created). * * @return a value greater than or equal to 1 * @hide */ @UnsupportedAppUsage public static int getMaxSupportedUsers() { // Don't allow multiple users on certain builds if (android.os.Build.ID.startsWith("JVP")) return 1; return Math.max(1, SystemProperties.getInt("fw.max_users", Resources.getSystem().getInteger(R.integer.config_multiuserMaximumUsers))); } Loading Loading @@ -6829,6 +6866,60 @@ public class UserManager { } } /** * Checks whether it's possible to add more users. Legacy version of parameterless * {@link #canAddMoreUsers(String)}. Do not use. * * @return true if more users can be added, false if limit has been reached. * * @deprecated use {@link #canAddMoreUsers(String)} instead. * * @hide */ @Deprecated @RequiresPermission(anyOf = { android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS }) public boolean canAddMoreUsersLegacy() { if (android.multiuser.Flags.consistentMaxUsers() && android.multiuser.Flags.maxUsersInCarIsForSecondary()) { // TODO(b/394178333): When the flags are permanent, delete this method entirely. throw new UnsupportedOperationException("This method is no longer supported"); } // TODO(b/142482943): UMS has different logic, excluding Demo and Profile from counting. // Why not here? The logic is inconsistent. See // UMS.canAddMoreManagedProfiles final List<UserInfo> users = getAliveUsers(); final int totalUserCount = users.size(); int aliveUserCount = 0; for (int i = 0; i < totalUserCount; i++) { UserInfo user = users.get(i); if (!user.isGuest()) { aliveUserCount++; } } return aliveUserCount < getMaxSupportedUsers(); } /** Legacy version of {@link #canAddMoreUsers(String)}. Do not use. */ private boolean canAddMoreUsersLegacy(@NonNull String userType) { if (android.multiuser.Flags.consistentMaxUsers()) { // TODO(b/394178333): When the flag is permanent, delete this method entirely. throw new UnsupportedOperationException("This method is no longer supported"); } try { if (userType.equals(USER_TYPE_FULL_GUEST)) { return mService.canAddMoreUsersOfType(userType); } else { return canAddMoreUsersLegacy() && mService.canAddMoreUsersOfType(userType); } } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } /** * Returns the user who should be in the foreground when boot completes. * Loading Loading
core/api/test-current.txt +1 −1 Original line number Diff line number Diff line Loading @@ -2623,7 +2623,7 @@ package android.os { } public class UserManager { method @FlaggedApi("android.os.allow_private_profile") @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public boolean canAddPrivateProfile(); method @FlaggedApi("android.os.allow_private_profile") @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS, android.Manifest.permission.QUERY_USERS}) public boolean canAddPrivateProfile(); method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public android.content.pm.UserInfo createProfileForUser(@Nullable String, @NonNull String, int, int, @Nullable String[]); method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public android.content.pm.UserInfo createRestrictedProfile(@Nullable String); method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public android.content.pm.UserInfo createUser(@Nullable String, @NonNull String, int); Loading
core/java/android/content/pm/UserInfo.java +21 −3 Original line number Diff line number Diff line Loading @@ -473,7 +473,7 @@ public class UserInfo implements Parcelable { /** * @return true if user is of type {@link UserManager#USER_TYPE_SYSTEM_HEADLESS} and * {@link com.android.internal.R.bool.config_canSwitchToHeadlessSystemUser} is true. * {@link com.android.internal.R.bool#config_canSwitchToHeadlessSystemUser} is true. */ @android.ravenwood.annotation.RavenwoodThrow private boolean canSwitchToHeadlessSystemUser() { Loading @@ -491,8 +491,10 @@ public class UserInfo implements Parcelable { return supportsSwitchTo(); } // TODO(b/142482943): Make this logic more specific and customizable. (canHaveProfile(userType)) /* @hide */ /** * Returns whether the user can have profiles, in general (on the basis of its UserInfo data). * See {@link #canHaveProfile(String)} for more fine-grained determination. */ public boolean canHaveProfile() { if (!isFull() || isProfile() || isGuest() || isRestricted() || isDemo()) { return false; Loading @@ -506,6 +508,22 @@ public class UserInfo implements Parcelable { com.android.internal.R.bool.config_supportProfilesOnNonMainUser)); } /** * Returns if the user can have a profile of the given type (on the basis of its UserInfo data). * @hide */ public boolean canHaveProfile(String userType) { if (!canHaveProfile()) { return false; } if (UserManager.isUserTypePrivateProfile(userType)) { // Even if we eventually allow other users to have profiles too, only MainUsers are // eligible to have a Private Space, for some reason. return isMain(); } return true; } // TODO(b/142482943): Get rid of this (after removing it from all tests) if feasible. /** * @deprecated This is dangerous since it doesn't set the mandatory fields. Use a different Loading
core/java/android/content/pm/multiuser.aconfig +21 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,27 @@ flag { bug: "285426179" } flag { name: "consistent_max_users" namespace: "multiuser" description: "Makes max supported users be consistent and fine-grained." bug: "394178333" } flag { name: "consistent_max_users_including_guests" namespace: "multiuser" description: "Builds on consistent_max_users, making Guest users included in the max." bug: "394178333" } flag { name: "max_users_in_car_is_for_secondary" namespace: "multiuser" description: "Update Car SystemUi and Settings to specify FULL_SECONDARY for max users (alongside consistent_max_users flag)." bug: "394178333" } flag { name: "support_communal_profile_nextgen" is_exported: true Loading
core/java/android/os/IUserManager.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -66,11 +66,11 @@ interface IUserManager { List<UserInfo> getProfiles(int userId, boolean enabledOnly); int[] getProfileIds(int userId, boolean enabledOnly); boolean isUserTypeEnabled(in String userType); int getCurrentAllowedNumberOfUsers(in String userType); boolean canAddMoreUsersOfType(in String userType); int getRemainingCreatableUserCount(in String userType); int getRemainingCreatableProfileCount(in String userType, int userId); boolean canAddMoreProfilesToUser(in String userType, int userId, boolean allowedToRemoveOne); boolean canAddMoreManagedProfiles(int userId, boolean allowedToRemoveOne); UserInfo getProfileParent(int userId); boolean isSameProfileGroup(int userId, int otherUserHandle); boolean isHeadlessSystemUserMode(); Loading
core/java/android/os/UserManager.java +137 −46 Original line number Diff line number Diff line Loading @@ -2460,10 +2460,10 @@ public class UserManager { */ public static final int USER_OPERATION_ERROR_DISABLED_USER = 8; /** * Indicates user operation failed because private space is disabled on the device. * Indicates user operation failed because the system features do not support this user type. * @hide */ public static final int USER_OPERATION_ERROR_PRIVATE_PROFILE = 9; public static final int USER_OPERATION_ERROR_FEATURE_UNSUPPORTED = 9; /** * Indicates user operation failed because user is restricted on the device. * @hide Loading @@ -2486,7 +2486,7 @@ public class UserManager { USER_OPERATION_ERROR_MAX_USERS, USER_OPERATION_ERROR_USER_ACCOUNT_ALREADY_EXISTS, USER_OPERATION_ERROR_DISABLED_USER, USER_OPERATION_ERROR_PRIVATE_PROFILE, USER_OPERATION_ERROR_FEATURE_UNSUPPORTED, USER_OPERATION_ERROR_USER_RESTRICTED, }) public @interface UserOperationResult {} Loading Loading @@ -2646,7 +2646,9 @@ public class UserManager { /** * Returns whether this device supports multiple users with their own login and customizable * space. * @return whether the device supports multiple users. * <p>Note that, even if false, multiple users might still be possible, as long as no login UI * is required; e.g., profiles might still be supported, as they do not require a login UI. * @return whether the device supports multiple switchable users. */ public static boolean supportsMultipleUsers() { return getMaxSupportedUsers() > 1 Loading Loading @@ -3341,7 +3343,12 @@ public class UserManager { } /** * Checks if it's possible to add a private profile to the context user * Checks if it's possible to add a private profile to the context user. * * Takes into account any possible considerations, including whether the user type is supported, * maximum user limits, and UserRestrictions (and so is inconsistent with similar APIs in this * class.) * * @return whether the context user can add a private profile. * @hide */ Loading @@ -3349,11 +3356,17 @@ public class UserManager { @FlaggedApi(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE) @RequiresPermission(anyOf = { Manifest.permission.MANAGE_USERS, Manifest.permission.CREATE_USERS}) Manifest.permission.CREATE_USERS, Manifest.permission.QUERY_USERS}) @UserHandleAware public boolean canAddPrivateProfile() { if (!android.multiuser.Flags.enablePrivateSpaceFeatures()) return false; if (android.multiuser.Flags.blockPrivateSpaceCreation()) { // TODO(b/413464199): Ideally, move this client-side, changing it to // if (android.multiuser.Flags.consistentMaxUsers()) { // return canAddMoreProfilesToUser(USER_TYPE_PROFILE_PRIVATE, mUserId) // && !hasUserRestriction(UserManager.DISALLOW_ADD_PRIVATE_PROFILE); // } try { return mService.canAddPrivateProfile(mUserId); } catch (RemoteException re) { Loading Loading @@ -5256,38 +5269,13 @@ public class UserManager { } } /** * Checks whether it's possible to add more users. * * @return true if more users can be added, false if limit has been reached. * * @deprecated use {@link #canAddMoreUsers(String)} instead. * * @hide */ @Deprecated @RequiresPermission(anyOf = { android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS }) public boolean canAddMoreUsers() { // TODO(b/142482943): UMS has different logic, excluding Demo and Profile from counting. Why // not here? The logic is inconsistent. See UMS.canAddMoreManagedProfiles final List<UserInfo> users = getAliveUsers(); final int totalUserCount = users.size(); int aliveUserCount = 0; for (int i = 0; i < totalUserCount; i++) { UserInfo user = users.get(i); if (!user.isGuest()) { aliveUserCount++; } } return aliveUserCount < getMaxSupportedUsers(); } /** * Checks whether it is possible to add more users of the given user type. * * Takes into account whether the user type is supported and maximum user limits, but does not * take into account UserRestrictions. * It is consistent with {@link #getRemainingCreatableUserCount(String)}. * * @param userType the type of user, such as {@link UserManager#USER_TYPE_FULL_SECONDARY}. * @return true if more users of the given type can be added, otherwise false. * @hide Loading @@ -5297,12 +5285,12 @@ public class UserManager { android.Manifest.permission.CREATE_USERS }) public boolean canAddMoreUsers(@NonNull String userType) { if (!android.multiuser.Flags.consistentMaxUsers()) { return canAddMoreUsersLegacy(userType); } try { if (userType.equals(USER_TYPE_FULL_GUEST)) { // Differs from getRemainingCreatableUserCount only because of isCreationOverrideEnabled return mService.canAddMoreUsersOfType(userType); } else { return canAddMoreUsers() && mService.canAddMoreUsersOfType(userType); } } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } Loading Loading @@ -5360,6 +5348,10 @@ public class UserManager { * if allowedToRemoveOne is true and if the user already has a managed profile, then return if * we could add a new managed profile to this user after removing the existing one. * * Takes into account whether the user type is supported and maximum user limits, but does not * take into account UserRestrictions. * It is consistent with {@link #getRemainingCreatableProfileCount(String)}. * * @return true if more managed profiles can be added, false if limit has been reached. * @hide */ Loading @@ -5370,7 +5362,8 @@ public class UserManager { }) public boolean canAddMoreManagedProfiles(@UserIdInt int userId, boolean allowedToRemoveOne) { try { return mService.canAddMoreManagedProfiles(userId, allowedToRemoveOne); return mService.canAddMoreProfilesToUser( USER_TYPE_PROFILE_MANAGED, userId, allowedToRemoveOne); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } Loading @@ -5379,6 +5372,10 @@ public class UserManager { /** * Checks whether it's possible to add more profiles of the given type to the given user. * * Takes into account whether the user type is supported and maximum user limits, but does not * take into account UserRestrictions. * It is consistent with {@link #getRemainingCreatableProfileCount(String)}. * * @param userType the type of user, such as {@link UserManager#USER_TYPE_PROFILE_MANAGED}. * @return true if more profiles can be added, false if limit has been reached. * @hide Loading @@ -5396,6 +5393,39 @@ public class UserManager { } } /** * Returns how many users of the given type are currently allowed on the device, including ones * that already exist. * * Takes into account the maximum number of users allowed on the device (of that type, and in * general), as well as how many users of other types are already on the device (which thereby * already count towards the device maximum). Does not take into account UserRestrictions. * It is consistent with {@link #getRemainingCreatableUserCount(String)}. * * The value will be no less than the number of users of that type that currently exist (even if * that value exceeds the maximum allowed, for whatever reason). * * @return a value greater than or equal to 0 * @hide */ @RequiresPermission(anyOf = { android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS }) public int getCurrentAllowedNumberOfUsers(@NonNull String userType) { if (!android.multiuser.Flags.consistentMaxUsers()) { throw new UnsupportedOperationException("This method requires flag consistentMaxUsers"); } try { // Note: If we get rid of the overall device max, this should be the same as // UMS.getMaxSupportedUsersOfType(). But even then it can still technically differ if // the max gets exceeded for any reason. return mService.getCurrentAllowedNumberOfUsers(userType); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } /** * Checks whether this device supports users of the given user type. * Loading Loading @@ -6504,15 +6534,22 @@ public class UserManager { } /** * Returns the maximum number of users that can be created on this device. A return value * of 1 means that it is a single user device. * @hide * Returns the maximum number of users (of any type) that can be created on this device. * A return value of 1 means that it is a single-user device. * * This value is based on the device's limitation of total number of users. This is typically * limited by storage considerations, not UX considerations (which depends on user type). * Note that this includes all types of users, including profile and guest users * (if {@link android.multiuser.Flags#consistentMaxUsersIncludingGuests()} is true). * * Under very rare circumstances, the number of users on the device can exceed this amount * (such as if it were decreased during an OTA but more users had already been created). * * @return a value greater than or equal to 1 * @hide */ @UnsupportedAppUsage public static int getMaxSupportedUsers() { // Don't allow multiple users on certain builds if (android.os.Build.ID.startsWith("JVP")) return 1; return Math.max(1, SystemProperties.getInt("fw.max_users", Resources.getSystem().getInteger(R.integer.config_multiuserMaximumUsers))); } Loading Loading @@ -6829,6 +6866,60 @@ public class UserManager { } } /** * Checks whether it's possible to add more users. Legacy version of parameterless * {@link #canAddMoreUsers(String)}. Do not use. * * @return true if more users can be added, false if limit has been reached. * * @deprecated use {@link #canAddMoreUsers(String)} instead. * * @hide */ @Deprecated @RequiresPermission(anyOf = { android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS }) public boolean canAddMoreUsersLegacy() { if (android.multiuser.Flags.consistentMaxUsers() && android.multiuser.Flags.maxUsersInCarIsForSecondary()) { // TODO(b/394178333): When the flags are permanent, delete this method entirely. throw new UnsupportedOperationException("This method is no longer supported"); } // TODO(b/142482943): UMS has different logic, excluding Demo and Profile from counting. // Why not here? The logic is inconsistent. See // UMS.canAddMoreManagedProfiles final List<UserInfo> users = getAliveUsers(); final int totalUserCount = users.size(); int aliveUserCount = 0; for (int i = 0; i < totalUserCount; i++) { UserInfo user = users.get(i); if (!user.isGuest()) { aliveUserCount++; } } return aliveUserCount < getMaxSupportedUsers(); } /** Legacy version of {@link #canAddMoreUsers(String)}. Do not use. */ private boolean canAddMoreUsersLegacy(@NonNull String userType) { if (android.multiuser.Flags.consistentMaxUsers()) { // TODO(b/394178333): When the flag is permanent, delete this method entirely. throw new UnsupportedOperationException("This method is no longer supported"); } try { if (userType.equals(USER_TYPE_FULL_GUEST)) { return mService.canAddMoreUsersOfType(userType); } else { return canAddMoreUsersLegacy() && mService.canAddMoreUsersOfType(userType); } } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } /** * Returns the user who should be in the foreground when boot completes. * Loading