diff --git a/core/api/current.txt b/core/api/current.txt index b063af5badcf3..dde2f904ebf4d 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -31467,10 +31467,10 @@ package android.os { method public static android.content.Intent createUserCreationIntent(@Nullable String, @Nullable String, @Nullable String, @Nullable android.os.PersistableBundle); method @WorkerThread public android.os.Bundle getApplicationRestrictions(String); method public long getSerialNumberForUser(android.os.UserHandle); - method @RequiresPermission("android.permission.MANAGE_USERS") public int getUserCount(); + method @RequiresPermission(anyOf={"android.permission.MANAGE_USERS", "android.permission.CREATE_USERS"}) public int getUserCount(); method public long getUserCreationTime(android.os.UserHandle); method public android.os.UserHandle getUserForSerialNumber(long); - method @NonNull @RequiresPermission(anyOf={"android.permission.MANAGE_USERS", android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED}, conditional=true) public String getUserName(); + method @NonNull @RequiresPermission(anyOf={"android.permission.MANAGE_USERS", android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED, "android.permission.CREATE_USERS"}, conditional=true) public String getUserName(); method public java.util.List getUserProfiles(); method public android.os.Bundle getUserRestrictions(); method @RequiresPermission(anyOf={"android.permission.MANAGE_USERS", "android.permission.INTERACT_ACROSS_USERS"}, conditional=true) public android.os.Bundle getUserRestrictions(android.os.UserHandle); diff --git a/core/api/system-current.txt b/core/api/system-current.txt index ee12eecb41e5d..b55eb99db44a5 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -8386,13 +8386,13 @@ package android.os { method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public android.os.UserHandle createProfile(@NonNull String, @NonNull String, @NonNull java.util.Set) throws android.os.UserManager.UserOperationException; method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}, conditional=true) public java.util.List getAllProfiles(); method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}, conditional=true) public java.util.List getEnabledProfiles(); - method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public android.os.UserHandle getProfileParent(@NonNull android.os.UserHandle); + method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}) public android.os.UserHandle getProfileParent(@NonNull android.os.UserHandle); method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public android.os.UserHandle getRestrictedProfileParent(); method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public String getSeedAccountName(); method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public android.os.PersistableBundle getSeedAccountOptions(); method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public String getSeedAccountType(); - method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public long[] getSerialNumbersOfUsers(boolean); - method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public java.util.List getUserHandles(boolean); + method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public long[] getSerialNumbersOfUsers(boolean); + method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public java.util.List getUserHandles(boolean); method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED}) public android.graphics.Bitmap getUserIcon(); method @Deprecated @android.os.UserManager.UserRestrictionSource @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public int getUserRestrictionSource(String, android.os.UserHandle); method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public java.util.List getUserRestrictionSources(String, android.os.UserHandle); diff --git a/core/api/test-current.txt b/core/api/test-current.txt index de3406870e088..28724f271a7fc 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -748,6 +748,65 @@ package android.content.pm { ctor public ShortcutManager(android.content.Context); } + public class UserInfo implements android.os.Parcelable { + ctor public UserInfo(int, String, int); + ctor public UserInfo(int, String, String, int); + ctor public UserInfo(int, String, String, int, String); + ctor @Deprecated public UserInfo(); + ctor public UserInfo(android.content.pm.UserInfo); + method public boolean canHaveProfile(); + method public int describeContents(); + method public android.os.UserHandle getUserHandle(); + method public boolean isAdmin(); + method public boolean isDemo(); + method public boolean isEnabled(); + method public boolean isEphemeral(); + method public boolean isFull(); + method public boolean isGuest(); + method public boolean isInitialized(); + method public boolean isManagedProfile(); + method public boolean isPrimary(); + method public boolean isProfile(); + method public boolean isQuietModeEnabled(); + method public boolean isRestricted(); + method public boolean isSystemOnly(); + method public static boolean isSystemOnly(int); + method public boolean supportsSwitchTo(); + method public boolean supportsSwitchToByUser(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + field public static final int FLAG_ADMIN = 2; // 0x2 + field @Deprecated public static final int FLAG_DEMO = 512; // 0x200 + field public static final int FLAG_DISABLED = 64; // 0x40 + field public static final int FLAG_EPHEMERAL = 256; // 0x100 + field public static final int FLAG_FULL = 1024; // 0x400 + field @Deprecated public static final int FLAG_GUEST = 4; // 0x4 + field public static final int FLAG_INITIALIZED = 16; // 0x10 + field @Deprecated public static final int FLAG_MANAGED_PROFILE = 32; // 0x20 + field public static final int FLAG_PRIMARY = 1; // 0x1 + field public static final int FLAG_PROFILE = 4096; // 0x1000 + field public static final int FLAG_QUIET_MODE = 128; // 0x80 + field @Deprecated public static final int FLAG_RESTRICTED = 8; // 0x8 + field public static final int FLAG_SYSTEM = 2048; // 0x800 + field public static final int NO_PROFILE_GROUP_ID = -10000; // 0xffffd8f0 + field public boolean convertedFromPreCreated; + field public long creationTime; + field public int flags; + field public boolean guestToRemove; + field public String iconPath; + field public int id; + field public String lastLoggedInFingerprint; + field public long lastLoggedInTime; + field public String name; + field public boolean partial; + field public boolean preCreated; + field public int profileBadge; + field public int profileGroupId; + field public int restrictedProfileParentId; + field public int serialNumber; + field public String userType; + } + } package android.content.res { @@ -1511,8 +1570,15 @@ package android.os { } public class UserManager { + 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); + method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public String getUserType(); + method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public java.util.List getUsers(boolean, boolean, boolean); method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public boolean hasBaseUserRestriction(@NonNull String, @NonNull android.os.UserHandle); + method public static boolean isGuestUserEphemeral(); method public static boolean isSplitSystemUser(); + method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public android.content.pm.UserInfo preCreateUser(@NonNull String) throws android.os.UserManager.UserOperationException; } public final class VibrationAttributes implements android.os.Parcelable { diff --git a/core/api/test-lint-baseline.txt b/core/api/test-lint-baseline.txt index 87fb5b1b3b2e0..a536efb2b4881 100644 --- a/core/api/test-lint-baseline.txt +++ b/core/api/test-lint-baseline.txt @@ -468,7 +468,7 @@ GetterSetterNames: android.location.GnssMeasurement#setBasebandCn0DbHz(double): GetterSetterNames: android.location.GnssMeasurement#setCarrierFrequencyHz(float): GetterSetterNames: android.location.GnssMeasurement#setCodeType(String): - + GetterSetterNames: android.location.GnssMeasurement#setCorrelationVectors(java.util.Collection): GetterSetterNames: android.location.GnssMeasurement#setFullInterSignalBiasNanos(double): @@ -480,7 +480,7 @@ GetterSetterNames: android.location.GnssMeasurement#setSatelliteInterSignalBiasN GetterSetterNames: android.location.GnssMeasurement#setSatelliteInterSignalBiasUncertaintyNanos(double): GetterSetterNames: android.location.GnssMeasurement#setSatellitePvt(android.location.SatellitePvt): - + GetterSetterNames: android.location.GnssMeasurement#setSnrInDb(double): GetterSetterNames: android.location.LocationRequest#isLocationSettingsIgnored(): @@ -953,6 +953,32 @@ MissingNullability: android.content.pm.PackageManager#holdLock(android.os.IBinde MissingNullability: android.content.pm.ShortcutManager#ShortcutManager(android.content.Context) parameter #0: +MissingNullability: android.content.pm.UserInfo#UserInfo(android.content.pm.UserInfo) parameter #0: + Missing nullability on parameter `orig` in method `UserInfo` +MissingNullability: android.content.pm.UserInfo#UserInfo(int, String, String, int) parameter #1: + Missing nullability on parameter `name` in method `UserInfo` +MissingNullability: android.content.pm.UserInfo#UserInfo(int, String, String, int) parameter #2: + Missing nullability on parameter `iconPath` in method `UserInfo` +MissingNullability: android.content.pm.UserInfo#UserInfo(int, String, String, int, String) parameter #1: + Missing nullability on parameter `name` in method `UserInfo` +MissingNullability: android.content.pm.UserInfo#UserInfo(int, String, String, int, String) parameter #2: + Missing nullability on parameter `iconPath` in method `UserInfo` +MissingNullability: android.content.pm.UserInfo#UserInfo(int, String, String, int, String) parameter #4: + Missing nullability on parameter `userType` in method `UserInfo` +MissingNullability: android.content.pm.UserInfo#UserInfo(int, String, int) parameter #1: + Missing nullability on parameter `name` in method `UserInfo` +MissingNullability: android.content.pm.UserInfo#getUserHandle(): + Missing nullability on method `getUserHandle` return +MissingNullability: android.content.pm.UserInfo#iconPath: + Missing nullability on field `iconPath` in class `class android.content.pm.UserInfo` +MissingNullability: android.content.pm.UserInfo#lastLoggedInFingerprint: + Missing nullability on field `lastLoggedInFingerprint` in class `class android.content.pm.UserInfo` +MissingNullability: android.content.pm.UserInfo#name: + Missing nullability on field `name` in class `class android.content.pm.UserInfo` +MissingNullability: android.content.pm.UserInfo#userType: + Missing nullability on field `userType` in class `class android.content.pm.UserInfo` +MissingNullability: android.content.pm.UserInfo#writeToParcel(android.os.Parcel, int) parameter #0: + Missing nullability on parameter `dest` in method `writeToParcel` MissingNullability: android.content.res.AssetManager#getOverlayablesToString(String) parameter #0: MissingNullability: android.content.res.Configuration#windowConfiguration: @@ -2433,6 +2459,38 @@ MutableBareField: android.content.AutofillOptions#disabledActivities: MutableBareField: android.content.AutofillOptions#whitelistedActivitiesForAugmentedAutofill: +MutableBareField: android.content.pm.UserInfo#convertedFromPreCreated: + Bare field convertedFromPreCreated must be marked final, or moved behind accessors if mutable +MutableBareField: android.content.pm.UserInfo#creationTime: + Bare field creationTime must be marked final, or moved behind accessors if mutable +MutableBareField: android.content.pm.UserInfo#flags: + Bare field flags must be marked final, or moved behind accessors if mutable +MutableBareField: android.content.pm.UserInfo#guestToRemove: + Bare field guestToRemove must be marked final, or moved behind accessors if mutable +MutableBareField: android.content.pm.UserInfo#iconPath: + Bare field iconPath must be marked final, or moved behind accessors if mutable +MutableBareField: android.content.pm.UserInfo#id: + Bare field id must be marked final, or moved behind accessors if mutable +MutableBareField: android.content.pm.UserInfo#lastLoggedInFingerprint: + Bare field lastLoggedInFingerprint must be marked final, or moved behind accessors if mutable +MutableBareField: android.content.pm.UserInfo#lastLoggedInTime: + Bare field lastLoggedInTime must be marked final, or moved behind accessors if mutable +MutableBareField: android.content.pm.UserInfo#name: + Bare field name must be marked final, or moved behind accessors if mutable +MutableBareField: android.content.pm.UserInfo#partial: + Bare field partial must be marked final, or moved behind accessors if mutable +MutableBareField: android.content.pm.UserInfo#preCreated: + Bare field preCreated must be marked final, or moved behind accessors if mutable +MutableBareField: android.content.pm.UserInfo#profileBadge: + Bare field profileBadge must be marked final, or moved behind accessors if mutable +MutableBareField: android.content.pm.UserInfo#profileGroupId: + Bare field profileGroupId must be marked final, or moved behind accessors if mutable +MutableBareField: android.content.pm.UserInfo#restrictedProfileParentId: + Bare field restrictedProfileParentId must be marked final, or moved behind accessors if mutable +MutableBareField: android.content.pm.UserInfo#serialNumber: + Bare field serialNumber must be marked final, or moved behind accessors if mutable +MutableBareField: android.content.pm.UserInfo#userType: + Bare field userType must be marked final, or moved behind accessors if mutable MutableBareField: android.database.sqlite.SQLiteDebug.DbStats#cache: MutableBareField: android.database.sqlite.SQLiteDebug.DbStats#dbName: @@ -2548,15 +2606,15 @@ NoSettingsProvider: android.provider.Settings.Global#TETHER_OFFLOAD_DISABLED: NoSettingsProvider: android.provider.Settings.Global#USE_OPEN_WIFI_PACKAGE: NoSettingsProvider: android.provider.Settings.Secure#ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED: - + NoSettingsProvider: android.provider.Settings.Secure#ACCESSIBILITY_MAGNIFICATION_CAPABILITY: - + NoSettingsProvider: android.provider.Settings.Secure#ACCESSIBILITY_MAGNIFICATION_MODE: - + NoSettingsProvider: android.provider.Settings.Secure#ACCESSIBILITY_MAGNIFICATION_MODE_ALL: - + NoSettingsProvider: android.provider.Settings.Secure#ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN: - + NoSettingsProvider: android.provider.Settings.Secure#ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW: NoSettingsProvider: android.provider.Settings.Secure#ACCESSIBILITY_SHORTCUT_TARGET_SERVICE: @@ -2619,6 +2677,10 @@ NotCloseable: android.telephony.ims.stub.ImsUtImplBase: +NullableCollection: android.os.UserManager#createProfileForUser(String, String, int, int, String[]) parameter #4: + Type of parameter disallowedPackages in android.os.UserManager.createProfileForUser(String name, String userType, int flags, int userId, String[] disallowedPackages) is a nullable collection (`java.lang.String[]`); must be non-null + + OnNameExpected: android.service.autofill.augmented.AugmentedAutofillService#dump(java.io.PrintWriter, String[]): OnNameExpected: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]): @@ -2729,6 +2791,8 @@ ParcelCreator: android.service.autofill.InternalValidator: ParcelNotFinal: android.app.WindowConfiguration: +ParcelNotFinal: android.content.pm.UserInfo: + Parcelable classes must be final: android.content.pm.UserInfo is not final ParcelNotFinal: android.net.metrics.IpConnectivityLog.Event: ParcelNotFinal: android.os.IncidentManager.IncidentReport: diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java index d81dff8f2908a..cfb6e1b572aaa 100644 --- a/core/java/android/content/pm/UserInfo.java +++ b/core/java/android/content/pm/UserInfo.java @@ -18,6 +18,7 @@ package android.content.pm; import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.TestApi; import android.annotation.UserIdInt; import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; @@ -47,6 +48,7 @@ import java.lang.annotation.RetentionPolicy; * * @hide */ +@TestApi public class UserInfo implements Parcelable { /** diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index 8bdfd3d3d6272..682754e66904a 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -1688,6 +1688,7 @@ public class UserManager { * @return Whether guest user is always ephemeral * @hide */ + @TestApi public static boolean isGuestUserEphemeral() { return Resources.getSystem() .getBoolean(com.android.internal.R.bool.config_guestUserEphemeral); @@ -1801,6 +1802,20 @@ public class UserManager { return UserHandle.myUserId(); } + /** + * @return the user type of the context user. + * @hide + */ + @TestApi + @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS, + android.Manifest.permission.CREATE_USERS + }) + @UserHandleAware + public @NonNull String getUserType() { + UserInfo userInfo = getUserInfo(mUserId); + return userInfo == null ? "" : userInfo.userType; + } + /** * Returns the user name of the context user. This call is only available to applications on * the system image; it requires the {@code android.permission.MANAGE_USERS} or {@code @@ -1809,7 +1824,8 @@ public class UserManager { * @return the user name */ @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS, - android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED}, conditional = true) + android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED, + android.Manifest.permission.CREATE_USERS}, conditional = true) @UserHandleAware public @NonNull String getUserName() { if (UserHandle.myUserId() == mUserId) { @@ -2792,6 +2808,7 @@ public class UserManager { */ @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS, Manifest.permission.CREATE_USERS}) + @TestApi public @Nullable UserInfo createUser(@Nullable String name, @NonNull String userType, @UserInfoFlag int flags) { try { @@ -2828,6 +2845,7 @@ public class UserManager { * @throws UserOperationException if the user could not be created. * @hide */ + @TestApi @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS, Manifest.permission.CREATE_USERS}) public @NonNull UserInfo preCreateUser(@NonNull String userType) @@ -2976,10 +2994,11 @@ public class UserManager { * * @hide */ + @TestApi @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS, Manifest.permission.CREATE_USERS}) - public UserInfo createProfileForUser(String name, @NonNull String userType, - @UserInfoFlag int flags, @UserIdInt int userId, String[] disallowedPackages) { + public @Nullable UserInfo createProfileForUser(@Nullable String name, @NonNull String userType, + @UserInfoFlag int flags, @UserIdInt int userId, @Nullable String[] disallowedPackages) { try { return mService.createProfileForUserWithThrow(name, userType, flags, userId, disallowedPackages); @@ -3022,9 +3041,10 @@ public class UserManager { * * @hide */ + @TestApi @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS, Manifest.permission.CREATE_USERS}) - public UserInfo createRestrictedProfile(String name) { + public @Nullable UserInfo createRestrictedProfile(@Nullable String name) { try { UserHandle parentUserHandle = Process.myUserHandle(); UserInfo user = mService.createRestrictedProfileWithThrow(name, @@ -3248,10 +3268,11 @@ public class UserManager { /** * Return the number of users currently created on the device. - *

This API is not for use by third-party apps. It requires the {@code MANAGE_USERS} - * permission.

*/ - @RequiresPermission(android.Manifest.permission.MANAGE_USERS) + @RequiresPermission(anyOf = { + android.Manifest.permission.MANAGE_USERS, + android.Manifest.permission.CREATE_USERS + }) public int getUserCount() { List users = getUsers(); return users != null ? users.size() : 1; @@ -3274,7 +3295,10 @@ public class UserManager { * @hide */ @UnsupportedAppUsage - @RequiresPermission(android.Manifest.permission.MANAGE_USERS) + @RequiresPermission(anyOf = { + android.Manifest.permission.MANAGE_USERS, + android.Manifest.permission.CREATE_USERS + }) public List getUsers() { return getUsers(/*excludePartial= */ true, /* excludeDying= */ false, /* excludePreCreated= */ true); @@ -3292,7 +3316,10 @@ public class UserManager { * @return the list of users that were created. * @hide */ - @RequiresPermission(android.Manifest.permission.MANAGE_USERS) + @RequiresPermission(anyOf = { + android.Manifest.permission.MANAGE_USERS, + android.Manifest.permission.CREATE_USERS + }) public @NonNull List getAliveUsers() { return getUsers(/*excludePartial= */ true, /* excludeDying= */ true, /* excludePreCreated= */ true); @@ -3306,7 +3333,10 @@ public class UserManager { */ @Deprecated @UnsupportedAppUsage - @RequiresPermission(android.Manifest.permission.MANAGE_USERS) + @RequiresPermission(anyOf = { + android.Manifest.permission.MANAGE_USERS, + android.Manifest.permission.CREATE_USERS + }) public @NonNull List getUsers(boolean excludeDying) { return getUsers(/*excludePartial= */ true, excludeDying, /* excludePreCreated= */ true); @@ -3317,8 +3347,12 @@ public class UserManager { * * @hide */ - @RequiresPermission(android.Manifest.permission.MANAGE_USERS) - public List getUsers(boolean excludePartial, boolean excludeDying, + @TestApi + @RequiresPermission(anyOf = { + android.Manifest.permission.MANAGE_USERS, + android.Manifest.permission.CREATE_USERS + }) + public @NonNull List getUsers(boolean excludePartial, boolean excludeDying, boolean excludePreCreated) { try { return mService.getUsers(excludePartial, excludeDying, excludePreCreated); @@ -3335,7 +3369,10 @@ public class UserManager { * @hide */ @SystemApi - @RequiresPermission(android.Manifest.permission.MANAGE_USERS) + @RequiresPermission(anyOf = { + android.Manifest.permission.MANAGE_USERS, + android.Manifest.permission.CREATE_USERS + }) public @NonNull List getUserHandles(boolean excludeDying) { List users = getUsers(/* excludePartial= */ true, excludeDying, /* excludePreCreated= */ true); @@ -3354,7 +3391,10 @@ public class UserManager { * @hide */ @SystemApi - @RequiresPermission(android.Manifest.permission.MANAGE_USERS) + @RequiresPermission(anyOf = { + android.Manifest.permission.MANAGE_USERS, + android.Manifest.permission.CREATE_USERS + }) public long[] getSerialNumbersOfUsers(boolean excludeDying) { List users = getUsers(/* excludePartial= */ true, excludeDying, /* excludePreCreated= */ true); @@ -3678,7 +3718,10 @@ public class UserManager { * @hide */ @UnsupportedAppUsage - @RequiresPermission(android.Manifest.permission.MANAGE_USERS) + @RequiresPermission(anyOf = { + android.Manifest.permission.MANAGE_USERS, + android.Manifest.permission.INTERACT_ACROSS_USERS + }) public UserInfo getProfileParent(@UserIdInt int userId) { try { return mService.getProfileParent(userId); @@ -3697,7 +3740,10 @@ public class UserManager { * @hide */ @SystemApi - @RequiresPermission(android.Manifest.permission.MANAGE_USERS) + @RequiresPermission(anyOf = { + android.Manifest.permission.MANAGE_USERS, + android.Manifest.permission.INTERACT_ACROSS_USERS + }) public @Nullable UserHandle getProfileParent(@NonNull UserHandle user) { UserInfo info = getProfileParent(user.getIdentifier()); diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 24c27bedb9f7a..c75dd27a383a3 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -983,7 +983,11 @@ public class UserManagerService extends IUserManager.Stub { @Override public UserInfo getProfileParent(@UserIdInt int userId) { - checkManageUsersPermission("get the profile parent"); + if (!hasManageUsersOrPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)) { + throw new SecurityException( + "You need MANAGE_USERS or INTERACT_ACROSS_USERS permission to get the " + + "profile parent"); + } synchronized (mUsersLock) { return getProfileParentLU(userId); } @@ -1531,11 +1535,14 @@ public class UserManagerService extends IUserManager.Stub { @Override public String getUserName() { - if (!hasManageUsersOrPermission(android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED)) { - throw new SecurityException("You need MANAGE_USERS or GET_ACCOUNTS_PRIVILEGED " - + "permissions to: get user name"); + final int callingUid = Binder.getCallingUid(); + if (!hasManageOrCreateUsersPermission() + || hasPermissionGranted( + android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED, callingUid)) { + throw new SecurityException("You need MANAGE_USERS or CREATE_USERS or " + + "GET_ACCOUNTS_PRIVILEGED permissions to: get user name"); } - final int userId = UserHandle.getUserId(Binder.getCallingUid()); + final int userId = UserHandle.getUserId(callingUid); synchronized (mUsersLock) { UserInfo userInfo = userWithName(getUserInfoLU(userId)); return userInfo == null ? "" : userInfo.name; @@ -3287,7 +3294,7 @@ public class UserManagerService extends IUserManager.Stub { * as well as for {@link UserManager#USER_TYPE_FULL_RESTRICTED}. */ @Override - public UserInfo createProfileForUserWithThrow(String name, @NonNull String userType, + public UserInfo createProfileForUserWithThrow(@Nullable String name, @NonNull String userType, @UserInfoFlag int flags, @UserIdInt int userId, @Nullable String[] disallowedPackages) throws ServiceSpecificException { checkManageOrCreateUsersPermission(flags); @@ -3868,7 +3875,7 @@ public class UserManagerService extends IUserManager.Stub { * @hide */ @Override - public UserInfo createRestrictedProfileWithThrow(String name, int parentUserId) { + public UserInfo createRestrictedProfileWithThrow(@Nullable String name, int parentUserId) { checkManageOrCreateUsersPermission("setupRestrictedProfile"); final UserInfo user = createProfileForUserWithThrow( name, UserManager.USER_TYPE_FULL_RESTRICTED, 0, parentUserId, null);