From 12678a99f12ae20fa8518bb8199c35d52be17954 Mon Sep 17 00:00:00 2001 From: Nicolas Prevot Date: Wed, 13 May 2015 12:15:03 -0700 Subject: [PATCH] Allow creating a managed profile if there is only one user. BUG:21119929 Change-ID: Ice1cf25f8ae8199228f828d22118c94b9e11b567 --- core/java/android/os/IUserManager.aidl | 1 + core/java/android/os/UserManager.java | 16 ++++++++ .../com/android/server/pm/UserManagerService.java | 43 +++++++++++++++++----- 3 files changed, 50 insertions(+), 10 deletions(-) diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl index b5295fb24f63..66c40f76ddd1 100644 --- a/core/java/android/os/IUserManager.aidl +++ b/core/java/android/os/IUserManager.aidl @@ -35,6 +35,7 @@ interface IUserManager { Bitmap getUserIcon(int userHandle); List getUsers(boolean excludeDying); List 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 d124a499f66d..b36624d6a79a 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -886,6 +886,22 @@ public class UserManager { } /** + * 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 f84cb30e6e8b..c5588452b8e2 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 @@ public class UserManagerService extends IUserManager.Stub { * 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 @@ public class UserManagerService extends IUserManager.Stub { aliveUserCount++; } } - return aliveUserCount >= UserManager.getMaxSupportedUsers(); + return aliveUserCount; } /** @@ -1152,7 +1174,11 @@ public class UserManagerService extends IUserManager.Stub { 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,19 +1189,16 @@ public class UserManagerService extends IUserManager.Stub { 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 we're adding a guest and there already exists one, bail. - if (isGuest && findCurrentGuestUserLocked() != 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; } - // 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) { + // If we're adding a guest and there already exists one, bail. + if (isGuest && findCurrentGuestUserLocked() != null) { return null; } int userId = getNextAvailableIdLocked(); -- 2.11.0