From f584f014dbb281727fccfea10bc9c2539a752f17 Mon Sep 17 00:00:00 2001 From: Amith Yamasani Date: Mon, 19 May 2014 17:57:25 -0700 Subject: [PATCH] Allow adding a user while still removing other users When at the user limit, removing and adding a user causes a race condition where the deleted user is still being removed and adding another one fails. This change excludes deleted users from the counting to compare against the limit. Also fix an ArrayIndexOutOfBounds recently introduced in AppOpsService. Bug: 13282768 Change-Id: Ib79659e7604396583a280dbbc560b288a6d9051c --- .../core/java/com/android/server/AppOpsService.java | 5 ++++- .../com/android/server/pm/UserManagerService.java | 12 ++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java index be206166dbd55..bfa04020a9a9e 100644 --- a/services/core/java/com/android/server/AppOpsService.java +++ b/services/core/java/com/android/server/AppOpsService.java @@ -1253,7 +1253,10 @@ public class AppOpsService extends IAppOpsService.Stub { public void removeUser(int userHandle) throws RemoteException { checkSystemUid("removeUser"); mOpRestrictions.remove(userHandle); - mProfileOwnerUids.removeAt(mProfileOwnerUids.indexOfKey(userHandle)); + final int index = mProfileOwnerUids.indexOfKey(userHandle); + if (index >= 0) { + mProfileOwnerUids.removeAt(index); + } } private void checkSystemUid(String function) { diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 131d05bf7a62c..fd180bf130f29 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -511,8 +511,16 @@ public class UserManagerService extends IUserManager.Stub { * Check if we've hit the limit of how many users can be created. */ private boolean isUserLimitReachedLocked() { - int nUsers = mUsers.size(); - return nUsers >= UserManager.getMaxSupportedUsers(); + int aliveUserCount = 0; + final int totalUserCount = mUsers.size(); + // Skip over users being removed + for (int i = 0; i < totalUserCount; i++) { + UserInfo user = mUsers.valueAt(i); + if (!mRemovingUserIds.get(user.id)) { + aliveUserCount++; + } + } + return aliveUserCount >= UserManager.getMaxSupportedUsers(); } /**