From 6e99d3f0445698cee87e391c9cf2dd90932e8e13 Mon Sep 17 00:00:00 2001 From: Fyodor Kupolov Date: Tue, 1 Nov 2016 17:18:41 -0700 Subject: [PATCH] Do not exclude partial users that are not being removed Otherwise maxSupportedUsers limit can be exceeded by creating users in parallel. Test: Manual cmd line + UI guest create/switch/remove + UserManagerTest Bug: 32485535 Change-Id: I490a70501f3643980bbfb1c95940b9ae3f20ccee --- .../android/server/pm/UserManagerService.java | 3 +- .../android/server/pm/UserManagerTest.java | 32 +++++++++++++++++++ 2 files changed, 33 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 a15af3ca9849e..67488ce37d816 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -1487,8 +1487,7 @@ public class UserManagerService extends IUserManager.Stub { // Skip over users being removed for (int i = 0; i < totalUserCount; i++) { UserInfo user = mUsers.valueAt(i).info; - if (!mRemovingUserIds.get(user.id) - && !user.isGuest() && !user.partial) { + if (!mRemovingUserIds.get(user.id) && !user.isGuest()) { aliveUserCount++; } } 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 1f0422b4ed504..40d8ac0434c80 100644 --- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java @@ -37,6 +37,10 @@ import com.android.internal.util.ArrayUtils; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; /** Test {@link UserManager} functionality. */ public class UserManagerTest extends AndroidTestCase { @@ -441,6 +445,33 @@ public class UserManagerTest extends AndroidTestCase { switchUser(startUser); } + @MediumTest + public void testConcurrentUserCreate() throws Exception { + int userCount = mUserManager.getUserCount(); + int maxSupportedUsers = UserManager.getMaxSupportedUsers(); + int canBeCreatedCount = maxSupportedUsers - userCount; + // Test exceeding the limit while running in parallel + int createUsersCount = canBeCreatedCount + 5; + ExecutorService es = Executors.newCachedThreadPool(); + AtomicInteger created = new AtomicInteger(); + for (int i = 0; i < createUsersCount; i++) { + final String userName = "testConcUser" + i; + es.submit(() -> { + UserInfo user = mUserManager.createUser(userName, 0); + if (user != null) { + created.incrementAndGet(); + synchronized (mUserRemoveLock) { + usersToRemove.add(user.id); + } + } + }); + } + es.shutdown(); + es.awaitTermination(20, TimeUnit.SECONDS); + assertEquals(maxSupportedUsers, mUserManager.getUserCount()); + assertEquals(canBeCreatedCount, created.get()); + } + private boolean isPackageInstalledForUser(String packageName, int userId) { try { return mPackageManager.getPackageInfoAsUser(packageName, 0, userId) != null; @@ -523,4 +554,5 @@ public class UserManagerTest extends AndroidTestCase { } return profile; } + }