UserManagerTest.java revision 6c9116a6430ca5cd55b1b926213a5e8de77e4fc6
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
17package com.android.server.pm;
18
19import android.content.BroadcastReceiver;
20import android.content.Context;
21import android.content.Intent;
22import android.content.IntentFilter;
23import android.content.pm.PackageManager;
24import android.content.pm.UserInfo;
25import android.app.ActivityManager;
26import android.os.Bundle;
27import android.os.UserHandle;
28import android.os.UserManager;
29import android.provider.Settings;
30import android.test.AndroidTestCase;
31import android.test.suitebuilder.annotation.LargeTest;
32import android.test.suitebuilder.annotation.MediumTest;
33import android.test.suitebuilder.annotation.SmallTest;
34
35import com.android.internal.util.ArrayUtils;
36
37import java.util.ArrayList;
38import java.util.Arrays;
39import java.util.List;
40import java.util.concurrent.ExecutorService;
41import java.util.concurrent.Executors;
42import java.util.concurrent.TimeUnit;
43import java.util.concurrent.atomic.AtomicInteger;
44
45/** Test {@link UserManager} functionality. */
46public 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            "com.android.retaildemo"
58    };
59
60    private final Object mUserRemoveLock = new Object();
61    private final Object mUserSwitchLock = new Object();
62
63    private UserManager mUserManager = null;
64    private PackageManager mPackageManager;
65    private List<Integer> usersToRemove;
66
67    @Override
68    public void setUp() throws Exception {
69        super.setUp();
70        mUserManager = UserManager.get(getContext());
71        mPackageManager = getContext().getPackageManager();
72
73        IntentFilter filter = new IntentFilter(Intent.ACTION_USER_REMOVED);
74        filter.addAction(Intent.ACTION_USER_SWITCHED);
75        getContext().registerReceiver(new BroadcastReceiver() {
76            @Override
77            public void onReceive(Context context, Intent intent) {
78                switch (intent.getAction()) {
79                    case Intent.ACTION_USER_REMOVED:
80                        synchronized (mUserRemoveLock) {
81                            mUserRemoveLock.notifyAll();
82                        }
83                        break;
84                    case Intent.ACTION_USER_SWITCHED:
85                        synchronized (mUserSwitchLock) {
86                            mUserSwitchLock.notifyAll();
87                        }
88                        break;
89                }
90            }
91        }, filter);
92
93        removeExistingUsers();
94        usersToRemove = new ArrayList<>();
95    }
96
97    @Override
98    protected void tearDown() throws Exception {
99        for (Integer userId : usersToRemove) {
100            removeUser(userId);
101        }
102        super.tearDown();
103    }
104
105    private void removeExistingUsers() {
106        List<UserInfo> list = mUserManager.getUsers();
107        for (UserInfo user : list) {
108            // Keep system and primary user.
109            // We do not have to keep primary user, but in split system user mode, we need it
110            // until http://b/22976637 is fixed.  Right now in split system user mode, you need to
111            // switch to primary user and run tests under primary user.
112            if (user.id != UserHandle.USER_SYSTEM && !user.isPrimary()) {
113                removeUser(user.id);
114            }
115        }
116    }
117
118    @SmallTest
119    public void testHasSystemUser() throws Exception {
120        assertTrue(findUser(UserHandle.USER_SYSTEM));
121    }
122
123    @MediumTest
124    public void testAddUser() throws Exception {
125        UserInfo userInfo = createUser("Guest 1", UserInfo.FLAG_GUEST);
126        assertTrue(userInfo != null);
127
128        List<UserInfo> list = mUserManager.getUsers();
129        boolean found = false;
130        for (UserInfo user : list) {
131            if (user.id == userInfo.id && user.name.equals("Guest 1")
132                    && user.isGuest()
133                    && !user.isAdmin()
134                    && !user.isPrimary()) {
135                found = true;
136                Bundle restrictions = mUserManager.getUserRestrictions(user.getUserHandle());
137                assertTrue("Guest user should have DISALLOW_CONFIG_WIFI=true by default",
138                        restrictions.getBoolean(UserManager.DISALLOW_CONFIG_WIFI));
139            }
140        }
141        assertTrue(found);
142    }
143
144    @MediumTest
145    public void testAdd2Users() throws Exception {
146        UserInfo user1 = createUser("Guest 1", UserInfo.FLAG_GUEST);
147        UserInfo user2 = createUser("User 2", UserInfo.FLAG_ADMIN);
148
149        assertTrue(user1 != null);
150        assertTrue(user2 != null);
151
152        assertTrue(findUser(0));
153        assertTrue(findUser(user1.id));
154        assertTrue(findUser(user2.id));
155    }
156
157    @MediumTest
158    public void testRemoveUser() throws Exception {
159        UserInfo userInfo = createUser("Guest 1", UserInfo.FLAG_GUEST);
160        removeUser(userInfo.id);
161
162        assertFalse(findUser(userInfo.id));
163    }
164
165    @MediumTest
166    public void testAddGuest() throws Exception {
167        UserInfo userInfo1 = createUser("Guest 1", UserInfo.FLAG_GUEST);
168        UserInfo userInfo2 = createUser("Guest 2", UserInfo.FLAG_GUEST);
169        assertNotNull(userInfo1);
170        assertNull(userInfo2);
171    }
172
173    @MediumTest
174    public void testGetProfileParent() throws Exception {
175        final int primaryUserId = mUserManager.getPrimaryUser().id;
176
177        UserInfo userInfo = createProfileForUser("Profile",
178                UserInfo.FLAG_MANAGED_PROFILE, primaryUserId);
179        assertNotNull(userInfo);
180
181        UserInfo parentProfileInfo = mUserManager.getProfileParent(userInfo.id);
182        assertNotNull(parentProfileInfo);
183        assertEquals(parentProfileInfo.id, primaryUserId);
184    }
185
186    // Make sure only one managed profile can be created
187    @MediumTest
188    public void testAddManagedProfile() throws Exception {
189        final int primaryUserId = mUserManager.getPrimaryUser().id;
190        UserInfo userInfo1 = createProfileForUser("Managed 1",
191                UserInfo.FLAG_MANAGED_PROFILE, primaryUserId);
192        UserInfo userInfo2 = createProfileForUser("Managed 2",
193                UserInfo.FLAG_MANAGED_PROFILE, primaryUserId);
194
195        assertNotNull(userInfo1);
196        assertNull(userInfo2);
197        // Verify that current user is not a managed profile
198        assertFalse(mUserManager.isManagedProfile());
199    }
200
201    // Verify that disallowed packages are not installed in the managed profile.
202    @MediumTest
203    public void testAddManagedProfile_withDisallowedPackages() throws Exception {
204        final int primaryUserId = mUserManager.getPrimaryUser().id;
205        UserInfo userInfo1 = createProfileForUser("Managed1",
206                UserInfo.FLAG_MANAGED_PROFILE, primaryUserId);
207        // Verify that the packagesToVerify are installed by default.
208        for (String pkg : PACKAGES) {
209            assertTrue("Package should be installed in managed profile: " + pkg,
210                    isPackageInstalledForUser(pkg, userInfo1.id));
211        }
212        removeUser(userInfo1.id);
213
214        UserInfo userInfo2 = createProfileForUser("Managed2",
215                UserInfo.FLAG_MANAGED_PROFILE, primaryUserId, PACKAGES);
216        // Verify that the packagesToVerify are not installed by default.
217        for (String pkg : PACKAGES) {
218            assertFalse("Package should not be installed in managed profile when disallowed: "
219                    + pkg, isPackageInstalledForUser(pkg, userInfo2.id));
220        }
221    }
222
223    // Verify that if any packages are disallowed to install during creation of managed profile can
224    // still be installed later.
225    @MediumTest
226    public void testAddManagedProfile_disallowedPackagesInstalledLater() throws Exception {
227        final int primaryUserId = mUserManager.getPrimaryUser().id;
228        UserInfo userInfo = createProfileForUser("Managed",
229                UserInfo.FLAG_MANAGED_PROFILE, primaryUserId, PACKAGES);
230        // Verify that the packagesToVerify are not installed by default.
231        for (String pkg : PACKAGES) {
232            assertFalse("Package should not be installed in managed profile when disallowed: "
233                    + pkg, isPackageInstalledForUser(pkg, userInfo.id));
234        }
235
236        // Verify that the disallowed packages during profile creation can be installed now.
237        for (String pkg : PACKAGES) {
238            assertEquals("Package could not be installed: " + pkg,
239                    PackageManager.INSTALL_SUCCEEDED,
240                    mPackageManager.installExistingPackageAsUser(pkg, userInfo.id));
241        }
242    }
243
244    // Make sure createUser would fail if we have DISALLOW_ADD_USER.
245    @MediumTest
246    public void testCreateUser_disallowAddUser() throws Exception {
247        final int primaryUserId = mUserManager.getPrimaryUser().id;
248        final UserHandle primaryUserHandle = new UserHandle(primaryUserId);
249        mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_USER, true, primaryUserHandle);
250        try {
251            UserInfo userInfo = createUser("SecondaryUser", /*flags=*/ 0);
252            assertNull(userInfo);
253        } finally {
254            mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_USER, false,
255                    primaryUserHandle);
256        }
257    }
258
259    // Make sure createProfile would fail if we have DISALLOW_ADD_MANAGED_PROFILE.
260    @MediumTest
261    public void testCreateProfileForUser_disallowAddManagedProfile() throws Exception {
262        final int primaryUserId = mUserManager.getPrimaryUser().id;
263        final UserHandle primaryUserHandle = new UserHandle(primaryUserId);
264        mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_MANAGED_PROFILE, true,
265                primaryUserHandle);
266        try {
267            UserInfo userInfo = createProfileForUser("Managed",
268                    UserInfo.FLAG_MANAGED_PROFILE, primaryUserId);
269            assertNull(userInfo);
270        } finally {
271            mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_MANAGED_PROFILE, false,
272                    primaryUserHandle);
273        }
274    }
275
276    // Make sure createProfileEvenWhenDisallowedForUser bypass DISALLOW_ADD_MANAGED_PROFILE.
277    @MediumTest
278    public void testCreateProfileForUserEvenWhenDisallowed() throws Exception {
279        final int primaryUserId = mUserManager.getPrimaryUser().id;
280        final UserHandle primaryUserHandle = new UserHandle(primaryUserId);
281        mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_MANAGED_PROFILE, true,
282                primaryUserHandle);
283        try {
284            UserInfo userInfo = createProfileEvenWhenDisallowedForUser("Managed",
285                    UserInfo.FLAG_MANAGED_PROFILE, primaryUserId);
286            assertNotNull(userInfo);
287        } finally {
288            mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_MANAGED_PROFILE, false,
289                    primaryUserHandle);
290        }
291    }
292
293    // createProfile succeeds even if DISALLOW_ADD_USER is set
294    @MediumTest
295    public void testCreateProfileForUser_disallowAddUser() throws Exception {
296        final int primaryUserId = mUserManager.getPrimaryUser().id;
297        final UserHandle primaryUserHandle = new UserHandle(primaryUserId);
298        mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_USER, true, primaryUserHandle);
299        try {
300            UserInfo userInfo = createProfileForUser("Managed",
301                    UserInfo.FLAG_MANAGED_PROFILE, primaryUserId);
302            assertNotNull(userInfo);
303        } finally {
304            mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_USER, false,
305                    primaryUserHandle);
306        }
307    }
308
309    @MediumTest
310    public void testAddRestrictedProfile() throws Exception {
311        UserInfo userInfo = createRestrictedProfile("Profile");
312        assertNotNull(userInfo);
313
314        Bundle restrictions = mUserManager.getUserRestrictions(UserHandle.of(userInfo.id));
315        assertTrue("Restricted profile should have DISALLOW_MODIFY_ACCOUNTS restriction by default",
316                restrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS));
317        assertTrue("Restricted profile should have DISALLOW_SHARE_LOCATION restriction by default",
318                restrictions.getBoolean(UserManager.DISALLOW_SHARE_LOCATION));
319
320        int locationMode = Settings.Secure.getIntForUser(getContext().getContentResolver(),
321                Settings.Secure.LOCATION_MODE,
322                Settings.Secure.LOCATION_MODE_HIGH_ACCURACY,
323                userInfo.id);
324        assertEquals("Restricted profile should have setting LOCATION_MODE set to "
325                + "LOCATION_MODE_OFF by default", locationMode, Settings.Secure.LOCATION_MODE_OFF);
326    }
327
328    @MediumTest
329    public void testGetUserCreationTime() throws Exception {
330        final int primaryUserId = mUserManager.getPrimaryUser().id;
331        final long startTime = System.currentTimeMillis();
332        UserInfo profile = createProfileForUser("Managed 1",
333                UserInfo.FLAG_MANAGED_PROFILE, primaryUserId);
334        final long endTime = System.currentTimeMillis();
335        assertNotNull(profile);
336        if (System.currentTimeMillis() > EPOCH_PLUS_30_YEARS) {
337            assertTrue("creationTime must be set when the profile is created",
338                    profile.creationTime >= startTime && profile.creationTime <= endTime);
339        } else {
340            assertTrue("creationTime must be 0 if the time is not > EPOCH_PLUS_30_years",
341                    profile.creationTime == 0);
342        }
343        assertEquals(profile.creationTime, mUserManager.getUserCreationTime(
344                new UserHandle(profile.id)));
345
346        long ownerCreationTime = mUserManager.getUserInfo(primaryUserId).creationTime;
347        assertEquals(ownerCreationTime, mUserManager.getUserCreationTime(
348                new UserHandle(primaryUserId)));
349    }
350
351    @SmallTest
352    public void testGetUserCreationTime_nonExistentUser() throws Exception {
353        try {
354            int noSuchUserId = 100500;
355            mUserManager.getUserCreationTime(new UserHandle(noSuchUserId));
356            fail("SecurityException should be thrown for nonexistent user");
357        } catch (Exception e) {
358            assertTrue("SecurityException should be thrown for nonexistent user, but was: " + e,
359                    e instanceof SecurityException);
360        }
361    }
362
363    @SmallTest
364    public void testGetUserCreationTime_otherUser() throws Exception {
365        UserInfo user = createUser("User 1", 0);
366        try {
367            mUserManager.getUserCreationTime(new UserHandle(user.id));
368            fail("SecurityException should be thrown for other user");
369        } catch (Exception e) {
370            assertTrue("SecurityException should be thrown for other user, but was: " + e,
371                    e instanceof SecurityException);
372        }
373    }
374
375    private boolean findUser(int id) {
376        List<UserInfo> list = mUserManager.getUsers();
377
378        for (UserInfo user : list) {
379            if (user.id == id) {
380                return true;
381            }
382        }
383        return false;
384    }
385
386    @MediumTest
387    public void testSerialNumber() {
388        UserInfo user1 = createUser("User 1", 0);
389        int serialNumber1 = user1.serialNumber;
390        assertEquals(serialNumber1, mUserManager.getUserSerialNumber(user1.id));
391        assertEquals(user1.id, mUserManager.getUserHandle(serialNumber1));
392        UserInfo user2 = createUser("User 2", 0);
393        int serialNumber2 = user2.serialNumber;
394        assertFalse(serialNumber1 == serialNumber2);
395        assertEquals(serialNumber2, mUserManager.getUserSerialNumber(user2.id));
396        assertEquals(user2.id, mUserManager.getUserHandle(serialNumber2));
397    }
398
399    @MediumTest
400    public void testGetSerialNumbersOfUsers() {
401        UserInfo user1 = createUser("User 1", 0);
402        UserInfo user2 = createUser("User 2", 0);
403        long[] serialNumbersOfUsers = mUserManager.getSerialNumbersOfUsers(false);
404        String errMsg = "Array " + Arrays.toString(serialNumbersOfUsers) + " should contain ";
405        assertTrue(errMsg + user1.serialNumber,
406                ArrayUtils.contains(serialNumbersOfUsers, user1.serialNumber));
407        assertTrue(errMsg + user2.serialNumber,
408                ArrayUtils.contains(serialNumbersOfUsers, user2.serialNumber));
409    }
410
411    @MediumTest
412    public void testMaxUsers() {
413        int N = UserManager.getMaxSupportedUsers();
414        int count = mUserManager.getUsers().size();
415        // Create as many users as permitted and make sure creation passes
416        while (count < N) {
417            UserInfo ui = createUser("User " + count, 0);
418            assertNotNull(ui);
419            count++;
420        }
421        // Try to create one more user and make sure it fails
422        UserInfo extra = createUser("One more", 0);
423        assertNull(extra);
424    }
425
426    @MediumTest
427    public void testGetUserCount() {
428        int count = mUserManager.getUsers().size();
429        UserInfo user1 = createUser("User 1", 0);
430        assertNotNull(user1);
431        UserInfo user2 = createUser("User 2", 0);
432        assertNotNull(user2);
433        assertEquals(count + 2, mUserManager.getUserCount());
434    }
435
436    @MediumTest
437    public void testRestrictions() {
438        UserInfo testUser = createUser("User 1", 0);
439
440        mUserManager.setUserRestriction(
441                UserManager.DISALLOW_INSTALL_APPS, true, new UserHandle(testUser.id));
442        mUserManager.setUserRestriction(
443                UserManager.DISALLOW_CONFIG_WIFI, false, new UserHandle(testUser.id));
444
445        Bundle stored = mUserManager.getUserRestrictions(new UserHandle(testUser.id));
446        // Note this will fail if DO already sets those restrictions.
447        assertEquals(stored.getBoolean(UserManager.DISALLOW_CONFIG_WIFI), false);
448        assertEquals(stored.getBoolean(UserManager.DISALLOW_UNINSTALL_APPS), false);
449        assertEquals(stored.getBoolean(UserManager.DISALLOW_INSTALL_APPS), true);
450    }
451
452    @MediumTest
453    public void testSetDefaultGuestRestrictions() {
454        final Bundle origGuestRestrictions = mUserManager.getDefaultGuestRestrictions();
455        Bundle restrictions = new Bundle();
456        restrictions.putBoolean(UserManager.DISALLOW_FUN, true);
457        mUserManager.setDefaultGuestRestrictions(restrictions);
458
459        try {
460            UserInfo guest = createUser("Guest", UserInfo.FLAG_GUEST);
461            assertNotNull(guest);
462            assertTrue(mUserManager.hasUserRestriction(UserManager.DISALLOW_FUN,
463                    guest.getUserHandle()));
464        } finally {
465            mUserManager.setDefaultGuestRestrictions(origGuestRestrictions);
466        }
467    }
468
469    @LargeTest
470    public void testSwitchUser() {
471        ActivityManager am = getContext().getSystemService(ActivityManager.class);
472        final int startUser = am.getCurrentUser();
473        UserInfo user = createUser("User", 0);
474        assertNotNull(user);
475        // Switch to the user just created.
476        switchUser(user.id);
477        // Switch back to the starting user.
478        switchUser(startUser);
479    }
480
481    @MediumTest
482    public void testConcurrentUserCreate() throws Exception {
483        int userCount = mUserManager.getUserCount();
484        int maxSupportedUsers = UserManager.getMaxSupportedUsers();
485        int canBeCreatedCount = maxSupportedUsers - userCount;
486        // Test exceeding the limit while running in parallel
487        int createUsersCount = canBeCreatedCount + 5;
488        ExecutorService es = Executors.newCachedThreadPool();
489        AtomicInteger created = new AtomicInteger();
490        for (int i = 0; i < createUsersCount; i++) {
491            final String userName = "testConcUser" + i;
492            es.submit(() -> {
493                UserInfo user = mUserManager.createUser(userName, 0);
494                if (user != null) {
495                    created.incrementAndGet();
496                    synchronized (mUserRemoveLock) {
497                        usersToRemove.add(user.id);
498                    }
499                }
500            });
501        }
502        es.shutdown();
503        es.awaitTermination(20, TimeUnit.SECONDS);
504        assertEquals(maxSupportedUsers, mUserManager.getUserCount());
505        assertEquals(canBeCreatedCount, created.get());
506    }
507
508    private boolean isPackageInstalledForUser(String packageName, int userId) {
509        try {
510            return mPackageManager.getPackageInfoAsUser(packageName, 0, userId) != null;
511        } catch (PackageManager.NameNotFoundException e) {
512            return false;
513        }
514    }
515
516    private void switchUser(int userId) {
517        synchronized (mUserSwitchLock) {
518            ActivityManager am = getContext().getSystemService(ActivityManager.class);
519            am.switchUser(userId);
520            long time = System.currentTimeMillis();
521            try {
522                mUserSwitchLock.wait(SWITCH_USER_TIMEOUT_MILLIS);
523            } catch (InterruptedException ie) {
524                Thread.currentThread().interrupt();
525                return;
526            }
527            if (System.currentTimeMillis() - time > SWITCH_USER_TIMEOUT_MILLIS) {
528                fail("Timeout waiting for the user switch to u" + userId);
529            }
530        }
531    }
532
533    private void removeUser(int userId) {
534        synchronized (mUserRemoveLock) {
535            mUserManager.removeUser(userId);
536            long time = System.currentTimeMillis();
537            while (mUserManager.getUserInfo(userId) != null) {
538                try {
539                    mUserRemoveLock.wait(REMOVE_CHECK_INTERVAL_MILLIS);
540                } catch (InterruptedException ie) {
541                    Thread.currentThread().interrupt();
542                    return;
543                }
544                if (System.currentTimeMillis() - time > REMOVE_TIMEOUT_MILLIS) {
545                    fail("Timeout waiting for removeUser. userId = " + userId);
546                }
547            }
548        }
549    }
550
551    private UserInfo createUser(String name, int flags) {
552        UserInfo user = mUserManager.createUser(name, flags);
553        if (user != null) {
554            usersToRemove.add(user.id);
555        }
556        return user;
557    }
558
559    private UserInfo createProfileForUser(String name, int flags, int userHandle) {
560        return createProfileForUser(name, flags, userHandle, null);
561    }
562
563    private UserInfo createProfileForUser(String name, int flags, int userHandle,
564            String[] disallowedPackages) {
565        UserInfo profile = mUserManager.createProfileForUser(
566                name, flags, userHandle, disallowedPackages);
567        if (profile != null) {
568            usersToRemove.add(profile.id);
569        }
570        return profile;
571    }
572
573    private UserInfo createProfileEvenWhenDisallowedForUser(String name, int flags,
574            int userHandle) {
575        UserInfo profile = mUserManager.createProfileForUserEvenWhenDisallowed(
576                name, flags, userHandle, null);
577        if (profile != null) {
578            usersToRemove.add(profile.id);
579        }
580        return profile;
581    }
582
583    private UserInfo createRestrictedProfile(String name) {
584        UserInfo profile = mUserManager.createRestrictedProfile(name);
585        if (profile != null) {
586            usersToRemove.add(profile.id);
587        }
588        return profile;
589    }
590
591}
592