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