1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.pm;
18 
19 import android.app.ActivityManager;
20 import android.content.BroadcastReceiver;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.IntentFilter;
24 import android.content.pm.PackageManager;
25 import android.content.pm.UserInfo;
26 import android.os.Bundle;
27 import android.os.UserHandle;
28 import android.os.UserManager;
29 import android.provider.Settings;
30 import android.test.AndroidTestCase;
31 import android.test.suitebuilder.annotation.LargeTest;
32 import android.test.suitebuilder.annotation.MediumTest;
33 import android.test.suitebuilder.annotation.SmallTest;
34 
35 import com.android.internal.util.ArrayUtils;
36 
37 import java.util.ArrayList;
38 import java.util.Arrays;
39 import java.util.List;
40 import java.util.concurrent.ExecutorService;
41 import java.util.concurrent.Executors;
42 import java.util.concurrent.TimeUnit;
43 import java.util.concurrent.atomic.AtomicInteger;
44 
45 /** Test {@link UserManager} functionality. */
46 public class UserManagerTest extends AndroidTestCase {
47     // Taken from UserManagerService
48     private static final long EPOCH_PLUS_30_YEARS = 30L * 365 * 24 * 60 * 60 * 1000L; // 30 years
49 
50     private static final int REMOVE_CHECK_INTERVAL_MILLIS = 500; // 0.5 seconds
51     private static final int REMOVE_TIMEOUT_MILLIS = 60 * 1000; // 60 seconds
52     private static final int SWITCH_USER_TIMEOUT_MILLIS = 40 * 1000; // 40 seconds
53 
54     // Packages which are used during tests.
55     private static final String[] PACKAGES = new String[] {
56             "com.android.egg"
57     };
58 
59     private final Object mUserRemoveLock = new Object();
60     private final Object mUserSwitchLock = new Object();
61 
62     private UserManager mUserManager = null;
63     private PackageManager mPackageManager;
64     private List<Integer> usersToRemove;
65 
66     @Override
setUp()67     public void setUp() throws Exception {
68         super.setUp();
69         mUserManager = UserManager.get(getContext());
70         mPackageManager = getContext().getPackageManager();
71 
72         IntentFilter filter = new IntentFilter(Intent.ACTION_USER_REMOVED);
73         filter.addAction(Intent.ACTION_USER_SWITCHED);
74         getContext().registerReceiver(new BroadcastReceiver() {
75             @Override
76             public void onReceive(Context context, Intent intent) {
77                 switch (intent.getAction()) {
78                     case Intent.ACTION_USER_REMOVED:
79                         synchronized (mUserRemoveLock) {
80                             mUserRemoveLock.notifyAll();
81                         }
82                         break;
83                     case Intent.ACTION_USER_SWITCHED:
84                         synchronized (mUserSwitchLock) {
85                             mUserSwitchLock.notifyAll();
86                         }
87                         break;
88                 }
89             }
90         }, filter);
91 
92         removeExistingUsers();
93         usersToRemove = new ArrayList<>();
94     }
95 
96     @Override
tearDown()97     protected void tearDown() throws Exception {
98         for (Integer userId : usersToRemove) {
99             removeUser(userId);
100         }
101         super.tearDown();
102     }
103 
removeExistingUsers()104     private void removeExistingUsers() {
105         List<UserInfo> list = mUserManager.getUsers();
106         for (UserInfo user : list) {
107             // Keep system and primary user.
108             // We do not have to keep primary user, but in split system user mode, we need it
109             // until http://b/22976637 is fixed.  Right now in split system user mode, you need to
110             // switch to primary user and run tests under primary user.
111             if (user.id != UserHandle.USER_SYSTEM && !user.isPrimary()) {
112                 removeUser(user.id);
113             }
114         }
115     }
116 
117     @SmallTest
testHasSystemUser()118     public void testHasSystemUser() throws Exception {
119         assertTrue(findUser(UserHandle.USER_SYSTEM));
120     }
121 
122     @MediumTest
testAddUser()123     public void testAddUser() throws Exception {
124         UserInfo userInfo = createUser("Guest 1", UserInfo.FLAG_GUEST);
125         assertTrue(userInfo != null);
126 
127         List<UserInfo> list = mUserManager.getUsers();
128         boolean found = false;
129         for (UserInfo user : list) {
130             if (user.id == userInfo.id && user.name.equals("Guest 1")
131                     && user.isGuest()
132                     && !user.isAdmin()
133                     && !user.isPrimary()) {
134                 found = true;
135                 Bundle restrictions = mUserManager.getUserRestrictions(user.getUserHandle());
136                 assertTrue("Guest user should have DISALLOW_CONFIG_WIFI=true by default",
137                         restrictions.getBoolean(UserManager.DISALLOW_CONFIG_WIFI));
138             }
139         }
140         assertTrue(found);
141     }
142 
143     @MediumTest
testAdd2Users()144     public void testAdd2Users() throws Exception {
145         UserInfo user1 = createUser("Guest 1", UserInfo.FLAG_GUEST);
146         UserInfo user2 = createUser("User 2", UserInfo.FLAG_ADMIN);
147 
148         assertTrue(user1 != null);
149         assertTrue(user2 != null);
150 
151         assertTrue(findUser(0));
152         assertTrue(findUser(user1.id));
153         assertTrue(findUser(user2.id));
154     }
155 
156     @MediumTest
testRemoveUser()157     public void testRemoveUser() throws Exception {
158         UserInfo userInfo = createUser("Guest 1", UserInfo.FLAG_GUEST);
159         removeUser(userInfo.id);
160 
161         assertFalse(findUser(userInfo.id));
162     }
163 
164     @MediumTest
testRemoveUserByHandle()165     public void testRemoveUserByHandle() {
166         UserInfo userInfo = createUser("Guest 1", UserInfo.FLAG_GUEST);
167         final UserHandle user = userInfo.getUserHandle();
168         synchronized (mUserRemoveLock) {
169             mUserManager.removeUser(user);
170             long time = System.currentTimeMillis();
171             while (mUserManager.getUserInfo(user.getIdentifier()) != null) {
172                 try {
173                     mUserRemoveLock.wait(REMOVE_CHECK_INTERVAL_MILLIS);
174                 } catch (InterruptedException ie) {
175                     Thread.currentThread().interrupt();
176                     return;
177                 }
178                 if (System.currentTimeMillis() - time > REMOVE_TIMEOUT_MILLIS) {
179                     fail("Timeout waiting for removeUser. userId = " + user.getIdentifier());
180                 }
181             }
182         }
183 
184         assertFalse(findUser(userInfo.id));
185     }
186 
187     @MediumTest
testRemoveUserByHandle_ThrowsException()188     public void testRemoveUserByHandle_ThrowsException() {
189         synchronized (mUserRemoveLock) {
190             try {
191                 mUserManager.removeUser(null);
192                 fail("Expected IllegalArgumentException on passing in a null UserHandle.");
193             } catch (IllegalArgumentException expected) {
194                 // Do nothing - exception is expected.
195             }
196         }
197     }
198 
199     @MediumTest
testAddGuest()200     public void testAddGuest() throws Exception {
201         UserInfo userInfo1 = createUser("Guest 1", UserInfo.FLAG_GUEST);
202         UserInfo userInfo2 = createUser("Guest 2", UserInfo.FLAG_GUEST);
203         assertNotNull(userInfo1);
204         assertNull(userInfo2);
205     }
206 
207     @MediumTest
testSetUserAdmin()208     public void testSetUserAdmin() throws Exception {
209         UserInfo userInfo = createUser("SecondaryUser", /*flags=*/ 0);
210 
211         // Assert user is not admin and has SMS and calls restrictions.
212         assertFalse(userInfo.isAdmin());
213         assertTrue(mUserManager.hasUserRestriction(UserManager.DISALLOW_SMS,
214                 userInfo.getUserHandle()));
215         assertTrue(mUserManager.hasUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS,
216                 userInfo.getUserHandle()));
217 
218         // Assign admin privileges.
219         mUserManager.setUserAdmin(userInfo.id);
220 
221         // Refresh.
222         userInfo = mUserManager.getUserInfo(userInfo.id);
223 
224         // Verify user became admin and SMS and call restrictions are lifted.
225         assertTrue(userInfo.isAdmin());
226         assertFalse(mUserManager.hasUserRestriction(UserManager.DISALLOW_SMS,
227                 userInfo.getUserHandle()));
228         assertFalse(mUserManager.hasUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS,
229                 userInfo.getUserHandle()));
230     }
231 
232     @MediumTest
testGetProfileParent()233     public void testGetProfileParent() throws Exception {
234         final int primaryUserId = mUserManager.getPrimaryUser().id;
235 
236         UserInfo userInfo = createProfileForUser("Profile",
237                 UserInfo.FLAG_MANAGED_PROFILE, primaryUserId);
238         assertNotNull(userInfo);
239         assertNull(mUserManager.getProfileParent(primaryUserId));
240         UserInfo parentProfileInfo = mUserManager.getProfileParent(userInfo.id);
241         assertNotNull(parentProfileInfo);
242         assertEquals(parentProfileInfo.id, primaryUserId);
243         removeUser(userInfo.id);
244         assertNull(mUserManager.getProfileParent(primaryUserId));
245     }
246 
247     // Make sure only one managed profile can be created
248     @MediumTest
testAddManagedProfile()249     public void testAddManagedProfile() throws Exception {
250         final int primaryUserId = mUserManager.getPrimaryUser().id;
251         UserInfo userInfo1 = createProfileForUser("Managed 1",
252                 UserInfo.FLAG_MANAGED_PROFILE, primaryUserId);
253         UserInfo userInfo2 = createProfileForUser("Managed 2",
254                 UserInfo.FLAG_MANAGED_PROFILE, primaryUserId);
255 
256         assertNotNull(userInfo1);
257         assertNull(userInfo2);
258         // Verify that current user is not a managed profile
259         assertFalse(mUserManager.isManagedProfile());
260     }
261 
262     // Verify that disallowed packages are not installed in the managed profile.
263     @MediumTest
testAddManagedProfile_withDisallowedPackages()264     public void testAddManagedProfile_withDisallowedPackages() throws Exception {
265         final int primaryUserId = mUserManager.getPrimaryUser().id;
266         UserInfo userInfo1 = createProfileForUser("Managed1",
267                 UserInfo.FLAG_MANAGED_PROFILE, primaryUserId);
268         // Verify that the packagesToVerify are installed by default.
269         for (String pkg : PACKAGES) {
270             assertTrue("Package should be installed in managed profile: " + pkg,
271                     isPackageInstalledForUser(pkg, userInfo1.id));
272         }
273         removeUser(userInfo1.id);
274 
275         UserInfo userInfo2 = createProfileForUser("Managed2",
276                 UserInfo.FLAG_MANAGED_PROFILE, primaryUserId, PACKAGES);
277         // Verify that the packagesToVerify are not installed by default.
278         for (String pkg : PACKAGES) {
279             assertFalse("Package should not be installed in managed profile when disallowed: "
280                     + pkg, isPackageInstalledForUser(pkg, userInfo2.id));
281         }
282     }
283 
284     // Verify that if any packages are disallowed to install during creation of managed profile can
285     // still be installed later.
286     @MediumTest
testAddManagedProfile_disallowedPackagesInstalledLater()287     public void testAddManagedProfile_disallowedPackagesInstalledLater() throws Exception {
288         final int primaryUserId = mUserManager.getPrimaryUser().id;
289         UserInfo userInfo = createProfileForUser("Managed",
290                 UserInfo.FLAG_MANAGED_PROFILE, primaryUserId, PACKAGES);
291         // Verify that the packagesToVerify are not installed by default.
292         for (String pkg : PACKAGES) {
293             assertFalse("Package should not be installed in managed profile when disallowed: "
294                     + pkg, isPackageInstalledForUser(pkg, userInfo.id));
295         }
296 
297         // Verify that the disallowed packages during profile creation can be installed now.
298         for (String pkg : PACKAGES) {
299             assertEquals("Package could not be installed: " + pkg,
300                     PackageManager.INSTALL_SUCCEEDED,
301                     mPackageManager.installExistingPackageAsUser(pkg, userInfo.id));
302         }
303     }
304 
305     // Make sure createUser would fail if we have DISALLOW_ADD_USER.
306     @MediumTest
testCreateUser_disallowAddUser()307     public void testCreateUser_disallowAddUser() throws Exception {
308         final int primaryUserId = mUserManager.getPrimaryUser().id;
309         final UserHandle primaryUserHandle = new UserHandle(primaryUserId);
310         mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_USER, true, primaryUserHandle);
311         try {
312             UserInfo userInfo = createUser("SecondaryUser", /*flags=*/ 0);
313             assertNull(userInfo);
314         } finally {
315             mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_USER, false,
316                     primaryUserHandle);
317         }
318     }
319 
320     // Make sure createProfile would fail if we have DISALLOW_ADD_MANAGED_PROFILE.
321     @MediumTest
testCreateProfileForUser_disallowAddManagedProfile()322     public void testCreateProfileForUser_disallowAddManagedProfile() throws Exception {
323         final int primaryUserId = mUserManager.getPrimaryUser().id;
324         final UserHandle primaryUserHandle = new UserHandle(primaryUserId);
325         mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_MANAGED_PROFILE, true,
326                 primaryUserHandle);
327         try {
328             UserInfo userInfo = createProfileForUser("Managed",
329                     UserInfo.FLAG_MANAGED_PROFILE, primaryUserId);
330             assertNull(userInfo);
331         } finally {
332             mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_MANAGED_PROFILE, false,
333                     primaryUserHandle);
334         }
335     }
336 
337     // Make sure createProfileEvenWhenDisallowedForUser bypass DISALLOW_ADD_MANAGED_PROFILE.
338     @MediumTest
testCreateProfileForUserEvenWhenDisallowed()339     public void testCreateProfileForUserEvenWhenDisallowed() throws Exception {
340         final int primaryUserId = mUserManager.getPrimaryUser().id;
341         final UserHandle primaryUserHandle = new UserHandle(primaryUserId);
342         mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_MANAGED_PROFILE, true,
343                 primaryUserHandle);
344         try {
345             UserInfo userInfo = createProfileEvenWhenDisallowedForUser("Managed",
346                     UserInfo.FLAG_MANAGED_PROFILE, primaryUserId);
347             assertNotNull(userInfo);
348         } finally {
349             mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_MANAGED_PROFILE, false,
350                     primaryUserHandle);
351         }
352     }
353 
354     // createProfile succeeds even if DISALLOW_ADD_USER is set
355     @MediumTest
testCreateProfileForUser_disallowAddUser()356     public void testCreateProfileForUser_disallowAddUser() throws Exception {
357         final int primaryUserId = mUserManager.getPrimaryUser().id;
358         final UserHandle primaryUserHandle = new UserHandle(primaryUserId);
359         mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_USER, true, primaryUserHandle);
360         try {
361             UserInfo userInfo = createProfileForUser("Managed",
362                     UserInfo.FLAG_MANAGED_PROFILE, primaryUserId);
363             assertNotNull(userInfo);
364         } finally {
365             mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_USER, false,
366                     primaryUserHandle);
367         }
368     }
369 
370     @MediumTest
testAddRestrictedProfile()371     public void testAddRestrictedProfile() throws Exception {
372         assertFalse("There should be no associated restricted profiles before the test",
373                 mUserManager.hasRestrictedProfiles());
374         UserInfo userInfo = createRestrictedProfile("Profile");
375         assertNotNull(userInfo);
376 
377         Bundle restrictions = mUserManager.getUserRestrictions(UserHandle.of(userInfo.id));
378         assertTrue("Restricted profile should have DISALLOW_MODIFY_ACCOUNTS restriction by default",
379                 restrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS));
380         assertTrue("Restricted profile should have DISALLOW_SHARE_LOCATION restriction by default",
381                 restrictions.getBoolean(UserManager.DISALLOW_SHARE_LOCATION));
382 
383         int locationMode = Settings.Secure.getIntForUser(getContext().getContentResolver(),
384                 Settings.Secure.LOCATION_MODE,
385                 Settings.Secure.LOCATION_MODE_HIGH_ACCURACY,
386                 userInfo.id);
387         assertEquals("Restricted profile should have setting LOCATION_MODE set to "
388                 + "LOCATION_MODE_OFF by default", locationMode, Settings.Secure.LOCATION_MODE_OFF);
389 
390         assertTrue("Newly created profile should be associated with the current user",
391                 mUserManager.hasRestrictedProfiles());
392     }
393 
394     @MediumTest
testGetUserCreationTime()395     public void testGetUserCreationTime() throws Exception {
396         final int primaryUserId = mUserManager.getPrimaryUser().id;
397         final long startTime = System.currentTimeMillis();
398         UserInfo profile = createProfileForUser("Managed 1",
399                 UserInfo.FLAG_MANAGED_PROFILE, primaryUserId);
400         final long endTime = System.currentTimeMillis();
401         assertNotNull(profile);
402         if (System.currentTimeMillis() > EPOCH_PLUS_30_YEARS) {
403             assertTrue("creationTime must be set when the profile is created",
404                     profile.creationTime >= startTime && profile.creationTime <= endTime);
405         } else {
406             assertTrue("creationTime must be 0 if the time is not > EPOCH_PLUS_30_years",
407                     profile.creationTime == 0);
408         }
409         assertEquals(profile.creationTime, mUserManager.getUserCreationTime(
410                 new UserHandle(profile.id)));
411 
412         long ownerCreationTime = mUserManager.getUserInfo(primaryUserId).creationTime;
413         assertEquals(ownerCreationTime, mUserManager.getUserCreationTime(
414                 new UserHandle(primaryUserId)));
415     }
416 
417     @SmallTest
testGetUserCreationTime_nonExistentUser()418     public void testGetUserCreationTime_nonExistentUser() throws Exception {
419         try {
420             int noSuchUserId = 100500;
421             mUserManager.getUserCreationTime(new UserHandle(noSuchUserId));
422             fail("SecurityException should be thrown for nonexistent user");
423         } catch (Exception e) {
424             assertTrue("SecurityException should be thrown for nonexistent user, but was: " + e,
425                     e instanceof SecurityException);
426         }
427     }
428 
429     @SmallTest
testGetUserCreationTime_otherUser()430     public void testGetUserCreationTime_otherUser() throws Exception {
431         UserInfo user = createUser("User 1", 0);
432         try {
433             mUserManager.getUserCreationTime(new UserHandle(user.id));
434             fail("SecurityException should be thrown for other user");
435         } catch (Exception e) {
436             assertTrue("SecurityException should be thrown for other user, but was: " + e,
437                     e instanceof SecurityException);
438         }
439     }
440 
findUser(int id)441     private boolean findUser(int id) {
442         List<UserInfo> list = mUserManager.getUsers();
443 
444         for (UserInfo user : list) {
445             if (user.id == id) {
446                 return true;
447             }
448         }
449         return false;
450     }
451 
452     @MediumTest
testSerialNumber()453     public void testSerialNumber() {
454         UserInfo user1 = createUser("User 1", 0);
455         int serialNumber1 = user1.serialNumber;
456         assertEquals(serialNumber1, mUserManager.getUserSerialNumber(user1.id));
457         assertEquals(user1.id, mUserManager.getUserHandle(serialNumber1));
458         UserInfo user2 = createUser("User 2", 0);
459         int serialNumber2 = user2.serialNumber;
460         assertFalse(serialNumber1 == serialNumber2);
461         assertEquals(serialNumber2, mUserManager.getUserSerialNumber(user2.id));
462         assertEquals(user2.id, mUserManager.getUserHandle(serialNumber2));
463     }
464 
465     @MediumTest
testGetSerialNumbersOfUsers()466     public void testGetSerialNumbersOfUsers() {
467         UserInfo user1 = createUser("User 1", 0);
468         UserInfo user2 = createUser("User 2", 0);
469         long[] serialNumbersOfUsers = mUserManager.getSerialNumbersOfUsers(false);
470         String errMsg = "Array " + Arrays.toString(serialNumbersOfUsers) + " should contain ";
471         assertTrue(errMsg + user1.serialNumber,
472                 ArrayUtils.contains(serialNumbersOfUsers, user1.serialNumber));
473         assertTrue(errMsg + user2.serialNumber,
474                 ArrayUtils.contains(serialNumbersOfUsers, user2.serialNumber));
475     }
476 
477     @MediumTest
testMaxUsers()478     public void testMaxUsers() {
479         int N = UserManager.getMaxSupportedUsers();
480         int count = mUserManager.getUsers().size();
481         // Create as many users as permitted and make sure creation passes
482         while (count < N) {
483             UserInfo ui = createUser("User " + count, 0);
484             assertNotNull(ui);
485             count++;
486         }
487         // Try to create one more user and make sure it fails
488         UserInfo extra = createUser("One more", 0);
489         assertNull(extra);
490     }
491 
492     @MediumTest
testGetUserCount()493     public void testGetUserCount() {
494         int count = mUserManager.getUsers().size();
495         UserInfo user1 = createUser("User 1", 0);
496         assertNotNull(user1);
497         UserInfo user2 = createUser("User 2", 0);
498         assertNotNull(user2);
499         assertEquals(count + 2, mUserManager.getUserCount());
500     }
501 
502     @MediumTest
testRestrictions()503     public void testRestrictions() {
504         UserInfo testUser = createUser("User 1", 0);
505 
506         mUserManager.setUserRestriction(
507                 UserManager.DISALLOW_INSTALL_APPS, true, new UserHandle(testUser.id));
508         mUserManager.setUserRestriction(
509                 UserManager.DISALLOW_CONFIG_WIFI, false, new UserHandle(testUser.id));
510 
511         Bundle stored = mUserManager.getUserRestrictions(new UserHandle(testUser.id));
512         // Note this will fail if DO already sets those restrictions.
513         assertEquals(stored.getBoolean(UserManager.DISALLOW_CONFIG_WIFI), false);
514         assertEquals(stored.getBoolean(UserManager.DISALLOW_UNINSTALL_APPS), false);
515         assertEquals(stored.getBoolean(UserManager.DISALLOW_INSTALL_APPS), true);
516     }
517 
518     @MediumTest
testSetDefaultGuestRestrictions()519     public void testSetDefaultGuestRestrictions() {
520         final Bundle origGuestRestrictions = mUserManager.getDefaultGuestRestrictions();
521         Bundle restrictions = new Bundle();
522         restrictions.putBoolean(UserManager.DISALLOW_FUN, true);
523         mUserManager.setDefaultGuestRestrictions(restrictions);
524 
525         try {
526             UserInfo guest = createUser("Guest", UserInfo.FLAG_GUEST);
527             assertNotNull(guest);
528             assertTrue(mUserManager.hasUserRestriction(UserManager.DISALLOW_FUN,
529                     guest.getUserHandle()));
530         } finally {
531             mUserManager.setDefaultGuestRestrictions(origGuestRestrictions);
532         }
533     }
534 
testGetUserSwitchability()535     public void testGetUserSwitchability() {
536         int userSwitchable = mUserManager.getUserSwitchability();
537         assertEquals("Expected users to be switchable", UserManager.SWITCHABILITY_STATUS_OK,
538                 userSwitchable);
539     }
540 
541     @LargeTest
testSwitchUser()542     public void testSwitchUser() {
543         ActivityManager am = getContext().getSystemService(ActivityManager.class);
544         final int startUser = am.getCurrentUser();
545         UserInfo user = createUser("User", 0);
546         assertNotNull(user);
547         // Switch to the user just created.
548         switchUser(user.id, null, true);
549         // Switch back to the starting user.
550         switchUser(startUser, null, true);
551     }
552 
553     @LargeTest
testSwitchUserByHandle()554     public void testSwitchUserByHandle() {
555         ActivityManager am = getContext().getSystemService(ActivityManager.class);
556         final int startUser = am.getCurrentUser();
557         UserInfo user = createUser("User", 0);
558         assertNotNull(user);
559         // Switch to the user just created.
560         switchUser(-1, user.getUserHandle(), false);
561         // Switch back to the starting user.
562         switchUser(-1, UserHandle.of(startUser), false);
563     }
564 
testSwitchUserByHandle_ThrowsException()565     public void testSwitchUserByHandle_ThrowsException() {
566         synchronized (mUserSwitchLock) {
567             try {
568                 ActivityManager am = getContext().getSystemService(ActivityManager.class);
569                 am.switchUser(null);
570                 fail("Expected IllegalArgumentException on passing in a null UserHandle.");
571             } catch (IllegalArgumentException expected) {
572                 // Do nothing - exception is expected.
573             }
574         }
575     }
576 
577     @MediumTest
testConcurrentUserCreate()578     public void testConcurrentUserCreate() throws Exception {
579         int userCount = mUserManager.getUserCount();
580         int maxSupportedUsers = UserManager.getMaxSupportedUsers();
581         int canBeCreatedCount = maxSupportedUsers - userCount;
582         // Test exceeding the limit while running in parallel
583         int createUsersCount = canBeCreatedCount + 5;
584         ExecutorService es = Executors.newCachedThreadPool();
585         AtomicInteger created = new AtomicInteger();
586         for (int i = 0; i < createUsersCount; i++) {
587             final String userName = "testConcUser" + i;
588             es.submit(() -> {
589                 UserInfo user = mUserManager.createUser(userName, 0);
590                 if (user != null) {
591                     created.incrementAndGet();
592                     synchronized (mUserRemoveLock) {
593                         usersToRemove.add(user.id);
594                     }
595                 }
596             });
597         }
598         es.shutdown();
599         es.awaitTermination(20, TimeUnit.SECONDS);
600         assertEquals(maxSupportedUsers, mUserManager.getUserCount());
601         assertEquals(canBeCreatedCount, created.get());
602     }
603 
isPackageInstalledForUser(String packageName, int userId)604     private boolean isPackageInstalledForUser(String packageName, int userId) {
605         try {
606             return mPackageManager.getPackageInfoAsUser(packageName, 0, userId) != null;
607         } catch (PackageManager.NameNotFoundException e) {
608             return false;
609         }
610     }
611 
612     /**
613      * @param userId value will be used to call switchUser(int) only if ignoreHandle is false.
614      * @param user value will be used to call switchUser(UserHandle) only if ignoreHandle is true.
615      * @param ignoreHandle if true, switchUser(int) will be called with the provided userId,
616      *                     else, switchUser(UserHandle) will be called with the provided user.
617      */
switchUser(int userId, UserHandle user, boolean ignoreHandle)618     private void switchUser(int userId, UserHandle user, boolean ignoreHandle) {
619         synchronized (mUserSwitchLock) {
620             ActivityManager am = getContext().getSystemService(ActivityManager.class);
621             if (ignoreHandle) {
622                 am.switchUser(userId);
623             } else {
624                 am.switchUser(user);
625             }
626             long time = System.currentTimeMillis();
627             try {
628                 mUserSwitchLock.wait(SWITCH_USER_TIMEOUT_MILLIS);
629             } catch (InterruptedException ie) {
630                 Thread.currentThread().interrupt();
631                 return;
632             }
633             if (System.currentTimeMillis() - time > SWITCH_USER_TIMEOUT_MILLIS) {
634                 fail("Timeout waiting for the user switch to u"
635                         + (ignoreHandle ? userId : user.getIdentifier()));
636             }
637         }
638     }
639 
removeUser(int userId)640     private void removeUser(int userId) {
641         synchronized (mUserRemoveLock) {
642             mUserManager.removeUser(userId);
643             long time = System.currentTimeMillis();
644             while (mUserManager.getUserInfo(userId) != null) {
645                 try {
646                     mUserRemoveLock.wait(REMOVE_CHECK_INTERVAL_MILLIS);
647                 } catch (InterruptedException ie) {
648                     Thread.currentThread().interrupt();
649                     return;
650                 }
651                 if (System.currentTimeMillis() - time > REMOVE_TIMEOUT_MILLIS) {
652                     fail("Timeout waiting for removeUser. userId = " + userId);
653                 }
654             }
655         }
656     }
657 
createUser(String name, int flags)658     private UserInfo createUser(String name, int flags) {
659         UserInfo user = mUserManager.createUser(name, flags);
660         if (user != null) {
661             usersToRemove.add(user.id);
662         }
663         return user;
664     }
665 
createProfileForUser(String name, int flags, int userHandle)666     private UserInfo createProfileForUser(String name, int flags, int userHandle) {
667         return createProfileForUser(name, flags, userHandle, null);
668     }
669 
createProfileForUser(String name, int flags, int userHandle, String[] disallowedPackages)670     private UserInfo createProfileForUser(String name, int flags, int userHandle,
671             String[] disallowedPackages) {
672         UserInfo profile = mUserManager.createProfileForUser(
673                 name, flags, userHandle, disallowedPackages);
674         if (profile != null) {
675             usersToRemove.add(profile.id);
676         }
677         return profile;
678     }
679 
createProfileEvenWhenDisallowedForUser(String name, int flags, int userHandle)680     private UserInfo createProfileEvenWhenDisallowedForUser(String name, int flags,
681             int userHandle) {
682         UserInfo profile = mUserManager.createProfileForUserEvenWhenDisallowed(
683                 name, flags, userHandle, null);
684         if (profile != null) {
685             usersToRemove.add(profile.id);
686         }
687         return profile;
688     }
689 
createRestrictedProfile(String name)690     private UserInfo createRestrictedProfile(String name) {
691         UserInfo profile = mUserManager.createRestrictedProfile(name);
692         if (profile != null) {
693             usersToRemove.add(profile.id);
694         }
695         return profile;
696     }
697 
698 }
699