Allow creating a managed profile if there is only one user.
BUG:21119929
Change-ID: Ice1cf25f8ae8199228f828d22118c94b9e11b567
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index b5295fb..66c40f7 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -35,6 +35,7 @@
Bitmap getUserIcon(int userHandle);
List<UserInfo> getUsers(boolean excludeDying);
List<UserInfo> getProfiles(int userHandle, boolean enabledOnly);
+ boolean canAddMoreManagedProfiles();
UserInfo getProfileParent(int userHandle);
UserInfo getUserInfo(int userHandle);
boolean isRestricted();
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index d124a49..b36624d 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -886,6 +886,22 @@
}
/**
+ * Checks whether it's possible to add more managed profiles. Caller must hold the MANAGE_USERS
+ * permission.
+ *
+ * @return true if more managed profiles can be added, false if limit has been reached.
+ * @hide
+ */
+ public boolean canAddMoreManagedProfiles() {
+ try {
+ return mService.canAddMoreManagedProfiles();
+ } catch (RemoteException re) {
+ Log.w(TAG, "Could not check if we can add more managed profiles", re);
+ return false;
+ }
+ }
+
+ /**
* Returns list of the profiles of userHandle including
* userHandle itself.
* Note that this returns both enabled and not enabled profiles. See
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index f84cb30..c558845 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -537,6 +537,28 @@
* Check if we've hit the limit of how many users can be created.
*/
private boolean isUserLimitReachedLocked() {
+ return getAliveUsersExcludingGuestsCountLocked() >= UserManager.getMaxSupportedUsers();
+ }
+
+ @Override
+ public boolean canAddMoreManagedProfiles() {
+ checkManageUsersPermission("check if more managed profiles can be added.");
+ if (ActivityManager.isLowRamDeviceStatic()) {
+ return false;
+ }
+ synchronized(mPackagesLock) {
+ // Limit number of managed profiles that can be created
+ if (numberOfUsersOfTypeLocked(UserInfo.FLAG_MANAGED_PROFILE, true)
+ >= MAX_MANAGED_PROFILES) {
+ return false;
+ }
+ int usersCount = getAliveUsersExcludingGuestsCountLocked();
+ // We allow creating a managed profile in the special case where there is only one user.
+ return usersCount == 1 || usersCount < UserManager.getMaxSupportedUsers();
+ }
+ }
+
+ private int getAliveUsersExcludingGuestsCountLocked() {
int aliveUserCount = 0;
final int totalUserCount = mUsers.size();
// Skip over users being removed
@@ -547,7 +569,7 @@
aliveUserCount++;
}
}
- return aliveUserCount >= UserManager.getMaxSupportedUsers();
+ return aliveUserCount;
}
/**
@@ -1152,7 +1174,11 @@
Log.w(LOG_TAG, "Cannot add user. DISALLOW_ADD_USER is enabled.");
return null;
}
+ if (ActivityManager.isLowRamDeviceStatic()) {
+ return null;
+ }
final boolean isGuest = (flags & UserInfo.FLAG_GUEST) != 0;
+ final boolean isManagedProfile = (flags & UserInfo.FLAG_MANAGED_PROFILE) != 0;
final long ident = Binder.clearCallingIdentity();
UserInfo userInfo = null;
try {
@@ -1163,21 +1189,18 @@
parent = getUserInfoLocked(parentId);
if (parent == null) return null;
}
- // If we're not adding a guest user and the limit has been reached,
- // cannot add a user.
- if (!isGuest && isUserLimitReachedLocked()) {
+ if (isManagedProfile && !canAddMoreManagedProfiles()) {
+ return null;
+ }
+ if (!isGuest && !isManagedProfile && isUserLimitReachedLocked()) {
+ // If we're not adding a guest user or a managed profile and the limit has
+ // been reached, cannot add a user.
return null;
}
// If we're adding a guest and there already exists one, bail.
if (isGuest && findCurrentGuestUserLocked() != null) {
return null;
}
- // Limit number of managed profiles that can be created
- if ((flags & UserInfo.FLAG_MANAGED_PROFILE) != 0
- && numberOfUsersOfTypeLocked(UserInfo.FLAG_MANAGED_PROFILE, true)
- >= MAX_MANAGED_PROFILES) {
- return null;
- }
int userId = getNextAvailableIdLocked();
userInfo = new UserInfo(userId, name, null, flags);
File userPath = new File(mBaseUserPath, Integer.toString(userId));