Merge "Various createUsers don't sometimes return null"

This commit is contained in:
Adam Bookatz
2023-02-13 22:55:54 +00:00
committed by Android (Google) Code Review
4 changed files with 84 additions and 75 deletions

View File

@@ -3612,7 +3612,7 @@ public class UserManager {
*
* <p>Requires {@link android.Manifest.permission#MANAGE_USERS}.
* {@link android.Manifest.permission#CREATE_USERS} suffices if flags are in
* com.android.server.pm.UserManagerService#ALLOWED_FLAGS_FOR_CREATE_USERS_PERMISSION}.
* com.android.server.pm.UserManagerService#ALLOWED_FLAGS_FOR_CREATE_USERS_PERMISSION.
*
* @param name the user's name
* @param userType the type of user, such as {@link UserManager#USER_TYPE_FULL_GUEST}.
@@ -3686,7 +3686,7 @@ public class UserManager {
*
* <p>Requires {@link android.Manifest.permission#MANAGE_USERS}.
* {@link android.Manifest.permission#CREATE_USERS} suffices if flags are in
* com.android.server.pm.UserManagerService#ALLOWED_FLAGS_FOR_CREATE_USERS_PERMISSION}.
* com.android.server.pm.UserManagerService#ALLOWED_FLAGS_FOR_CREATE_USERS_PERMISSION.
*
* @param userType the type of user, such as {@link UserManager#USER_TYPE_FULL_GUEST}.
* @return the {@link UserInfo} object for the created user.
@@ -3718,25 +3718,23 @@ public class UserManager {
*/
@RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
Manifest.permission.CREATE_USERS})
public UserInfo createGuest(Context context) {
public @Nullable UserInfo createGuest(Context context) {
try {
final UserInfo guest = mService.createUserWithThrow(null, USER_TYPE_FULL_GUEST, 0);
if (guest != null) {
Settings.Secure.putStringForUser(context.getContentResolver(),
Settings.Secure.SKIP_FIRST_USE_HINTS, "1", guest.id);
Settings.Secure.putStringForUser(context.getContentResolver(),
Settings.Secure.SKIP_FIRST_USE_HINTS, "1", guest.id);
if (UserManager.isGuestUserAllowEphemeralStateChange()) {
// Mark guest as (changeably) ephemeral if REMOVE_GUEST_ON_EXIT is 1
// This is done so that a user via a UI controller can choose to
// make a guest as ephemeral or not.
// Settings.Global.REMOVE_GUEST_ON_EXIT holds the choice on what the guest state
// should be, with default being ephemeral.
boolean resetGuestOnExit = Settings.Global.getInt(context.getContentResolver(),
Settings.Global.REMOVE_GUEST_ON_EXIT, 1) == 1;
if (UserManager.isGuestUserAllowEphemeralStateChange()) {
// Mark guest as (changeably) ephemeral if REMOVE_GUEST_ON_EXIT is 1
// This is done so that a user via a UI controller can choose to
// make a guest as ephemeral or not.
// Settings.Global.REMOVE_GUEST_ON_EXIT holds the choice on what the guest state
// should be, with default being ephemeral.
boolean resetGuestOnExit = Settings.Global.getInt(context.getContentResolver(),
Settings.Global.REMOVE_GUEST_ON_EXIT, 1) == 1;
if (resetGuestOnExit && !guest.isEphemeral()) {
setUserEphemeral(guest.id, true);
}
if (resetGuestOnExit && !guest.isEphemeral()) {
setUserEphemeral(guest.id, true);
}
}
return guest;
@@ -3855,7 +3853,7 @@ public class UserManager {
*/
@RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
Manifest.permission.CREATE_USERS})
public UserInfo createProfileForUser(String name, @NonNull String userType,
public @Nullable UserInfo createProfileForUser(String name, @NonNull String userType,
@UserInfoFlag int flags, @UserIdInt int userId) {
return createProfileForUser(name, userType, flags, userId, null);
}
@@ -3900,7 +3898,7 @@ public class UserManager {
*/
@RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
Manifest.permission.CREATE_USERS})
public UserInfo createProfileForUserEvenWhenDisallowed(String name,
public @Nullable UserInfo createProfileForUserEvenWhenDisallowed(String name,
@NonNull String userType, @UserInfoFlag int flags, @UserIdInt int userId,
String[] disallowedPackages) {
try {
@@ -3931,11 +3929,9 @@ public class UserManager {
try {
final int parentUserId = mUserId;
final UserInfo profile = mService.createRestrictedProfileWithThrow(name, parentUserId);
if (profile != null) {
final UserHandle parentUserHandle = UserHandle.of(parentUserId);
AccountManager.get(mContext).addSharedAccountsFromParentUser(parentUserHandle,
UserHandle.of(profile.id));
}
final UserHandle parentUserHandle = UserHandle.of(parentUserId);
AccountManager.get(mContext).addSharedAccountsFromParentUser(parentUserHandle,
UserHandle.of(profile.id));
return profile;
} catch (ServiceSpecificException e) {
return null;

View File

@@ -238,8 +238,9 @@ public abstract class UserManagerInternal {
* the user is created (as it will be passed back to it through
* {@link UserLifecycleListener#onUserCreated(UserInfo, Object)});
*/
public abstract UserInfo createUserEvenWhenDisallowed(String name, String userType,
int flags, String[] disallowedPackages, @Nullable Object token)
public abstract @NonNull UserInfo createUserEvenWhenDisallowed(
@Nullable String name, @NonNull String userType, @UserInfo.UserInfoFlag int flags,
@Nullable String[] disallowedPackages, @Nullable Object token)
throws UserManager.CheckedUserOperationException;
/**

View File

@@ -4495,9 +4495,11 @@ public class UserManagerService extends IUserManager.Stub {
* as well as for {@link UserManager#USER_TYPE_FULL_RESTRICTED}.
*/
@Override
public UserInfo createProfileForUserWithThrow(@Nullable String name, @NonNull String userType,
@UserInfoFlag int flags, @UserIdInt int userId, @Nullable String[] disallowedPackages)
public @NonNull UserInfo createProfileForUserWithThrow(
@Nullable String name, @NonNull String userType, @UserInfoFlag int flags,
@UserIdInt int userId, @Nullable String[] disallowedPackages)
throws ServiceSpecificException {
checkCreateUsersPermission(flags);
try {
return createUserInternal(name, userType, flags, userId, disallowedPackages);
@@ -4510,10 +4512,11 @@ public class UserManagerService extends IUserManager.Stub {
* @see #createProfileForUser
*/
@Override
public UserInfo createProfileForUserEvenWhenDisallowedWithThrow(String name,
@NonNull String userType,
@UserInfoFlag int flags, @UserIdInt int userId, @Nullable String[] disallowedPackages)
public @NonNull UserInfo createProfileForUserEvenWhenDisallowedWithThrow(
@Nullable String name, @NonNull String userType, @UserInfoFlag int flags,
@UserIdInt int userId, @Nullable String[] disallowedPackages)
throws ServiceSpecificException {
checkCreateUsersPermission(flags);
try {
return createUserInternalUnchecked(name, userType, flags, userId,
@@ -4524,9 +4527,10 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
public UserInfo createUserWithThrow(String name, @NonNull String userType,
@UserInfoFlag int flags)
public @NonNull UserInfo createUserWithThrow(
@Nullable String name, @NonNull String userType, @UserInfoFlag int flags)
throws ServiceSpecificException {
checkCreateUsersPermission(flags);
try {
return createUserInternal(name, userType, flags, UserHandle.USER_NULL,
@@ -4537,7 +4541,10 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
public UserInfo preCreateUserWithThrow(String userType) throws ServiceSpecificException {
public @NonNull UserInfo preCreateUserWithThrow(
@NonNull String userType)
throws ServiceSpecificException {
final UserTypeDetails userTypeDetails = mUserTypes.get(userType);
final int flags = userTypeDetails != null ? userTypeDetails.getDefaultUserInfoFlags() : 0;
@@ -4557,10 +4564,12 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
public UserHandle createUserWithAttributes(
String userName, String userType, @UserInfoFlag int flags,
Bitmap userIcon,
String accountName, String accountType, PersistableBundle accountOptions) {
public @NonNull UserHandle createUserWithAttributes(
@Nullable String userName, @NonNull String userType, @UserInfoFlag int flags,
@Nullable Bitmap userIcon, @Nullable String accountName, @Nullable String accountType,
@Nullable PersistableBundle accountOptions)
throws ServiceSpecificException {
checkCreateUsersPermission(flags);
if (someUserHasAccountNoChecks(accountName, accountType)) {
@@ -4570,12 +4579,7 @@ public class UserManagerService extends IUserManager.Stub {
UserInfo userInfo;
try {
userInfo = createUserInternal(userName, userType, flags,
UserHandle.USER_NULL, null);
if (userInfo == null) {
throw new ServiceSpecificException(USER_OPERATION_ERROR_UNKNOWN);
}
userInfo = createUserInternal(userName, userType, flags, UserHandle.USER_NULL, null);
} catch (UserManager.CheckedUserOperationException e) {
throw e.toServiceSpecificException();
}
@@ -4589,7 +4593,8 @@ public class UserManagerService extends IUserManager.Stub {
return userInfo.getUserHandle();
}
private UserInfo createUserInternal(@Nullable String name, @NonNull String userType,
private @NonNull UserInfo createUserInternal(
@Nullable String name, @NonNull String userType,
@UserInfoFlag int flags, @UserIdInt int parentId,
@Nullable String[] disallowedPackages)
throws UserManager.CheckedUserOperationException {
@@ -4611,11 +4616,12 @@ public class UserManagerService extends IUserManager.Stub {
/* preCreate= */ false, disallowedPackages, /* token= */ null);
}
private UserInfo createUserInternalUnchecked(@Nullable String name,
@NonNull String userType, @UserInfoFlag int flags, @UserIdInt int parentId,
boolean preCreate, @Nullable String[] disallowedPackages,
private @NonNull UserInfo createUserInternalUnchecked(
@Nullable String name, @NonNull String userType, @UserInfoFlag int flags,
@UserIdInt int parentId, boolean preCreate, @Nullable String[] disallowedPackages,
@Nullable Object token)
throws UserManager.CheckedUserOperationException {
final int noneUserId = -1;
final TimingsTraceAndSlog t = new TimingsTraceAndSlog();
t.traceBegin("createUser-" + flags);
@@ -4633,27 +4639,31 @@ public class UserManagerService extends IUserManager.Stub {
}
}
private UserInfo createUserInternalUncheckedNoTracing(@Nullable String name,
@NonNull String userType, @UserInfoFlag int flags, @UserIdInt int parentId,
boolean preCreate, @Nullable String[] disallowedPackages,
private @NonNull UserInfo createUserInternalUncheckedNoTracing(
@Nullable String name, @NonNull String userType, @UserInfoFlag int flags,
@UserIdInt int parentId, boolean preCreate, @Nullable String[] disallowedPackages,
@NonNull TimingsTraceAndSlog t, @Nullable Object token)
throws UserManager.CheckedUserOperationException {
throws UserManager.CheckedUserOperationException {
final UserTypeDetails userTypeDetails = mUserTypes.get(userType);
if (userTypeDetails == null) {
Slog.e(LOG_TAG, "Cannot create user of invalid user type: " + userType);
return null;
throwCheckedUserOperationException(
"Cannot create user of invalid user type: " + userType,
USER_OPERATION_ERROR_UNKNOWN);
}
userType = userType.intern(); // Now that we know it's valid, we can intern it.
flags |= userTypeDetails.getDefaultUserInfoFlags();
if (!checkUserTypeConsistency(flags)) {
Slog.e(LOG_TAG, "Cannot add user. Flags (" + Integer.toHexString(flags)
+ ") and userTypeDetails (" + userType + ") are inconsistent.");
return null;
throwCheckedUserOperationException(
"Cannot add user. Flags (" + Integer.toHexString(flags)
+ ") and userTypeDetails (" + userType + ") are inconsistent.",
USER_OPERATION_ERROR_UNKNOWN);
}
if ((flags & UserInfo.FLAG_SYSTEM) != 0) {
Slog.e(LOG_TAG, "Cannot add user. Flags (" + Integer.toHexString(flags)
+ ") indicated SYSTEM user, which cannot be created.");
return null;
throwCheckedUserOperationException(
"Cannot add user. Flags (" + Integer.toHexString(flags)
+ ") indicated SYSTEM user, which cannot be created.",
USER_OPERATION_ERROR_UNKNOWN);
}
if (!isUserTypeEnabled(userTypeDetails)) {
throwCheckedUserOperationException(
@@ -4679,7 +4689,8 @@ public class UserManagerService extends IUserManager.Stub {
DeviceStorageMonitorInternal dsm = LocalServices
.getService(DeviceStorageMonitorInternal.class);
if (dsm.isMemoryLow()) {
throwCheckedUserOperationException("Cannot add user. Not enough space on disk.",
throwCheckedUserOperationException(
"Cannot add user. Not enough space on disk.",
UserManager.USER_OPERATION_ERROR_LOW_STORAGE);
}
@@ -4707,7 +4718,8 @@ public class UserManagerService extends IUserManager.Stub {
}
}
if (!preCreate && !canAddMoreUsersOfType(userTypeDetails)) {
throwCheckedUserOperationException("Cannot add more users of type " + userType
throwCheckedUserOperationException(
"Cannot add more users of type " + userType
+ ". Maximum number of that type already exists.",
UserManager.USER_OPERATION_ERROR_MAX_USERS);
}
@@ -5332,13 +5344,13 @@ public class UserManagerService extends IUserManager.Stub {
* @hide
*/
@Override
public UserInfo createRestrictedProfileWithThrow(@Nullable String name, int parentUserId) {
public @NonNull UserInfo createRestrictedProfileWithThrow(
@Nullable String name, @UserIdInt int parentUserId)
throws ServiceSpecificException {
checkCreateUsersPermission("setupRestrictedProfile");
final UserInfo user = createProfileForUserWithThrow(
name, UserManager.USER_TYPE_FULL_RESTRICTED, 0, parentUserId, null);
if (user == null) {
return null;
}
final long identity = Binder.clearCallingIdentity();
try {
setUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, true, user.id);
@@ -6339,8 +6351,10 @@ public class UserManagerService extends IUserManager.Stub {
setSeedAccountDataNoChecks(userId, accountName, accountType, accountOptions, persist);
}
private void setSeedAccountDataNoChecks(@UserIdInt int userId, String accountName,
String accountType, PersistableBundle accountOptions, boolean persist) {
private void setSeedAccountDataNoChecks(@UserIdInt int userId, @Nullable String accountName,
@Nullable String accountType, @Nullable PersistableBundle accountOptions,
boolean persist) {
synchronized (mPackagesLock) {
final UserData userData;
synchronized (mUsersLock) {
@@ -6909,9 +6923,11 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
public UserInfo createUserEvenWhenDisallowed(String name, @NonNull String userType,
@UserInfoFlag int flags, String[] disallowedPackages, @Nullable Object token)
public @NonNull UserInfo createUserEvenWhenDisallowed(
@Nullable String name, @NonNull String userType, @UserInfoFlag int flags,
@Nullable String[] disallowedPackages, @Nullable Object token)
throws UserManager.CheckedUserOperationException {
return createUserInternalUnchecked(name, userType, flags,
UserHandle.USER_NULL, /* preCreated= */ false, disallowedPackages, token);
}

View File

@@ -113,11 +113,7 @@ final class HsumBootUserInitializer {
UserInfo.FLAG_ADMIN | UserInfo.FLAG_MAIN,
/* disallowedPackages= */ null,
/* token= */ null);
if (newInitialUser == null) {
Slogf.wtf(TAG, "Initial bootable MainUser creation failed: returned null");
} else {
Slogf.i(TAG, "Successfully created MainUser, userId=%d", newInitialUser.id);
}
Slogf.i(TAG, "Successfully created MainUser, userId=%d", newInitialUser.id);
} catch (UserManager.CheckedUserOperationException e) {
Slogf.wtf(TAG, "Initial bootable MainUser creation failed", e);
}