diff options
author | Amith Yamasani <yamasani@google.com> | 2014-08-11 17:09:26 -0700 |
---|---|---|
committer | Amith Yamasani <yamasani@google.com> | 2014-08-13 20:09:20 +0000 |
commit | 95ab7849444125387dc88088bb5197ee463d8c17 (patch) | |
tree | c5747585a3e3e2dd8aed2475767eaf91c9376ff5 /services | |
parent | 437e61d5adc81b57c11f56b94ecc75239708fbb1 (diff) | |
download | frameworks_base-95ab7849444125387dc88088bb5197ee463d8c17.zip frameworks_base-95ab7849444125387dc88088bb5197ee463d8c17.tar.gz frameworks_base-95ab7849444125387dc88088bb5197ee463d8c17.tar.bz2 |
Decouple user limit from guest creation
Allow Guest to be created even if there are N users.
Allow N users to be created even if there are N-1 users
and a Guest.
Limit number of guests and managed profiles that can
be added.
Added unit tests.
Bug: 15934700
Change-Id: I1a8f0fa38a91d71ef7b2980e05c974244dfc337a
Diffstat (limited to 'services')
-rw-r--r-- | services/core/java/com/android/server/pm/UserManagerService.java | 37 | ||||
-rw-r--r-- | services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java | 35 |
2 files changed, 70 insertions, 2 deletions
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 33ecc4d..ad87993 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -125,6 +125,10 @@ public class UserManagerService extends IUserManager.Stub { // Number of attempts before jumping to the next BACKOFF_TIMES slot private static final int BACKOFF_INC_INTERVAL = 5; + // Maximum number of managed profiles permitted is 1. This cannot be increased + // without first making sure that the rest of the framework is prepared for it. + private static final int MAX_MANAGED_PROFILES = 1; + // Amount of time to force the user to wait before entering the PIN again, after failing // BACKOFF_INC_INTERVAL times. private static final int[] BACKOFF_TIMES = { 0, 30*1000, 60*1000, 5*60*1000, 30*60*1000 }; @@ -510,7 +514,8 @@ public class UserManagerService extends IUserManager.Stub { // Skip over users being removed for (int i = 0; i < totalUserCount; i++) { UserInfo user = mUsers.valueAt(i); - if (!mRemovingUserIds.get(user.id)) { + if (!mRemovingUserIds.get(user.id) + && !user.isGuest()) { aliveUserCount++; } } @@ -1093,6 +1098,7 @@ public class UserManagerService extends IUserManager.Stub { Log.w(LOG_TAG, "Cannot add user. DISALLOW_ADD_USER is enabled."); return null; } + final boolean isGuest = (flags & UserInfo.FLAG_GUEST) != 0; final long ident = Binder.clearCallingIdentity(); UserInfo userInfo = null; try { @@ -1103,7 +1109,21 @@ public class UserManagerService extends IUserManager.Stub { parent = getUserInfoLocked(parentId); if (parent == null) return null; } - if (isUserLimitReachedLocked()) return null; + // If we're not adding a guest user and the limit has been reached, + // cannot add a user. + if (!isGuest && isUserLimitReachedLocked()) { + return null; + } + // If we're adding a guest and there already exists one, bail. + if (isGuest && numberOfUsersOfTypeLocked(UserInfo.FLAG_GUEST, true) > 0) { + 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)); @@ -1142,6 +1162,19 @@ public class UserManagerService extends IUserManager.Stub { return userInfo; } + private int numberOfUsersOfTypeLocked(int flags, boolean excludeDying) { + int count = 0; + for (int i = mUsers.size() - 1; i >= 0; i--) { + UserInfo user = mUsers.valueAt(i); + if (!excludeDying || !mRemovingUserIds.get(user.id)) { + if ((user.flags & flags) != 0) { + count++; + } + } + } + return count; + } + /** * Removes a user and all data directories created for that user. This method should be called * after the user's processes have been terminated. diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java index 2e309be..6e13732 100644 --- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java @@ -47,6 +47,18 @@ public class UserManagerTest extends AndroidTestCase { } } }, filter); + + removeExistingUsers(); + } + + private void removeExistingUsers() { + List<UserInfo> list = mUserManager.getUsers(); + boolean found = false; + for (UserInfo user : list) { + if (user.id != UserHandle.USER_OWNER) { + removeUser(user.id); + } + } } public void testHasPrimary() throws Exception { @@ -95,6 +107,29 @@ public class UserManagerTest extends AndroidTestCase { assertFalse(findUser(userInfo.id)); } + public void testAddGuest() throws Exception { + UserInfo userInfo1 = mUserManager.createUser("Guest 1", UserInfo.FLAG_GUEST); + UserInfo userInfo2 = mUserManager.createUser("Guest 2", UserInfo.FLAG_GUEST); + assertNotNull(userInfo1); + assertNull(userInfo2); + + // Cleanup + removeUser(userInfo1.id); + } + + // Make sure only one managed profile can be created + public void testAddManagedProfile() throws Exception { + UserInfo userInfo1 = mUserManager.createProfileForUser("Managed 1", + UserInfo.FLAG_MANAGED_PROFILE, UserHandle.USER_OWNER); + UserInfo userInfo2 = mUserManager.createProfileForUser("Managed 2", + UserInfo.FLAG_MANAGED_PROFILE, UserHandle.USER_OWNER); + assertNotNull(userInfo1); + assertNull(userInfo2); + + // Cleanup + removeUser(userInfo1.id); + } + private boolean findUser(int id) { List<UserInfo> list = mUserManager.getUsers(); |