SystemProperty to create disabled usertypes

For development, it helps to be able to create users whose usertype is
disabled or their limit has been reached.
We therefore introduce a system property for this.
It can only be used on debug builds.

Bug: 255793314
Bug: 137101239
Test: adb shell setprop debug.user.creation_override 1 && try to create disabled users
Change-Id: I6ab2aa80b0387b32f1b5fe5e9c8dd0096ed7bcd7
This commit is contained in:
Adam Bookatz
2022-11-09 13:13:02 -08:00
parent 502b19b33a
commit 82c53f0c85
2 changed files with 40 additions and 27 deletions

View File

@@ -1612,6 +1612,16 @@ public class UserManager {
/** @hide */
public static final String SYSTEM_USER_MODE_EMULATION_HEADLESS = "headless";
/**
* System Property used to override whether users can be created even if their type is disabled
* or their limit is reached. Set value to 1 to enable.
*
* <p>Only used on non-user builds.
*
* @hide
*/
public static final String DEV_CREATE_OVERRIDE_PROPERTY = "debug.user.creation_override";
private static final String ACTION_CREATE_USER = "android.os.action.CREATE_USER";
/**

View File

@@ -18,6 +18,7 @@ package com.android.server.pm;
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
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;
@@ -2807,7 +2808,8 @@ public class UserManagerService extends IUserManager.Stub {
synchronized (mUsersLock) {
count = getAliveUsersExcludingGuestsCountLU();
}
return count >= UserManager.getMaxSupportedUsers();
return count >= UserManager.getMaxSupportedUsers()
&& !isCreationOverrideEnabled();
}
/**
@@ -2817,15 +2819,16 @@ public class UserManagerService extends IUserManager.Stub {
* <p>For checking whether more profiles can be added to a particular parent use
* {@link #canAddMoreProfilesToUser}.
*/
private boolean canAddMoreUsersOfType(UserTypeDetails userTypeDetails) {
if (!userTypeDetails.isEnabled()) {
private boolean canAddMoreUsersOfType(@NonNull UserTypeDetails userTypeDetails) {
if (!isUserTypeEnabled(userTypeDetails)) {
return false;
}
final int max = userTypeDetails.getMaxAllowed();
if (max == UserTypeDetails.UNLIMITED_NUMBER_OF_USERS) {
return true; // Indicates that there is no max.
}
return getNumberOfUsersOfType(userTypeDetails.getName()) < max;
return getNumberOfUsersOfType(userTypeDetails.getName()) < max
|| isCreationOverrideEnabled();
}
/**
@@ -2836,7 +2839,7 @@ public class UserManagerService extends IUserManager.Stub {
public int getRemainingCreatableUserCount(String userType) {
checkQueryOrCreateUsersPermission("get the remaining number of users that can be added.");
final UserTypeDetails type = mUserTypes.get(userType);
if (type == null || !type.isEnabled()) {
if (type == null || !isUserTypeEnabled(type)) {
return 0;
}
synchronized (mUsersLock) {
@@ -2910,7 +2913,21 @@ public class UserManagerService extends IUserManager.Stub {
public boolean isUserTypeEnabled(String userType) {
checkCreateUsersPermission("check if user type is enabled.");
final UserTypeDetails userTypeDetails = mUserTypes.get(userType);
return userTypeDetails != null && userTypeDetails.isEnabled();
return userTypeDetails != null && isUserTypeEnabled(userTypeDetails);
}
/** Returns whether the creation of users of the given user type is enabled on this device. */
private boolean isUserTypeEnabled(@NonNull UserTypeDetails userTypeDetails) {
return userTypeDetails.isEnabled() || isCreationOverrideEnabled();
}
/**
* Returns whether to almost-always allow creating users even beyond their limit or if disabled.
* For Debug builds only.
*/
private boolean isCreationOverrideEnabled() {
return Build.isDebuggable()
&& SystemProperties.getBoolean(DEV_CREATE_OVERRIDE_PROPERTY, false);
}
@Override
@@ -2923,7 +2940,8 @@ public class UserManagerService extends IUserManager.Stub {
@Override
public boolean canAddMoreProfilesToUser(String userType, @UserIdInt int userId,
boolean allowedToRemoveOne) {
return 0 < getRemainingCreatableProfileCount(userType, userId, allowedToRemoveOne);
return 0 < getRemainingCreatableProfileCount(userType, userId, allowedToRemoveOne)
|| isCreationOverrideEnabled();
}
@Override
@@ -2941,7 +2959,7 @@ public class UserManagerService extends IUserManager.Stub {
checkQueryOrCreateUsersPermission(
"get the remaining number of profiles that can be added to the given user.");
final UserTypeDetails type = mUserTypes.get(userType);
if (type == null || !type.isEnabled()) {
if (type == null || !isUserTypeEnabled(type)) {
return 0;
}
// Managed profiles have their own specific rules.
@@ -4400,7 +4418,7 @@ public class UserManagerService extends IUserManager.Stub {
+ ") indicated SYSTEM user, which cannot be created.");
return null;
}
if (!userTypeDetails.isEnabled()) {
if (!isUserTypeEnabled(userTypeDetails)) {
throwCheckedUserOperationException(
"Cannot add a user of disabled type " + userType + ".",
UserManager.USER_OPERATION_ERROR_MAX_USERS);
@@ -4472,27 +4490,12 @@ public class UserManagerService extends IUserManager.Stub {
+ " for user " + parentId,
UserManager.USER_OPERATION_ERROR_MAX_USERS);
}
// In legacy mode, restricted profile's parent can only be the owner user
if (isRestricted && !UserManager.isSplitSystemUser()
&& (parentId != UserHandle.USER_SYSTEM)) {
if (isRestricted && (parentId != UserHandle.USER_SYSTEM)
&& !isCreationOverrideEnabled()) {
throwCheckedUserOperationException(
"Cannot add restricted profile - parent user must be owner",
"Cannot add restricted profile - parent user must be system",
UserManager.USER_OPERATION_ERROR_UNKNOWN);
}
if (isRestricted && UserManager.isSplitSystemUser()) {
if (parent == null) {
throwCheckedUserOperationException(
"Cannot add restricted profile - parent user must be specified",
UserManager.USER_OPERATION_ERROR_UNKNOWN);
}
if (!parent.info.canHaveProfile()) {
throwCheckedUserOperationException(
"Cannot add restricted profile - profiles cannot be created for "
+ "the specified parent user id "
+ parentId,
UserManager.USER_OPERATION_ERROR_UNKNOWN);
}
}
userId = getNextAvailableId();
Slog.i(LOG_TAG, "Creating user " + userId + " of type " + userType);