• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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 android.multiuser.cts;
18 
19 import static android.Manifest.permission.CREATE_USERS;
20 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
21 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
22 import static android.Manifest.permission.QUERY_USERS;
23 import static android.content.pm.PackageManager.FEATURE_MANAGED_USERS;
24 import static android.multiuser.cts.TestingUtils.getBooleanProperty;
25 import static android.multiuser.cts.TestingUtils.getContextForOtherUser;
26 import static android.multiuser.cts.TestingUtils.getContextForUser;
27 import static android.multiuser.cts.TestingUtils.sContext;
28 import static android.os.UserManager.USER_OPERATION_SUCCESS;
29 import static android.os.UserManager.USER_TYPE_FULL_SECONDARY;
30 import static android.os.UserManager.USER_TYPE_PROFILE_CLONE;
31 import static android.os.UserManager.USER_TYPE_PROFILE_MANAGED;
32 
33 import static com.android.bedstead.harrier.UserType.ADDITIONAL_USER;
34 import static com.android.bedstead.nene.types.OptionalBoolean.FALSE;
35 import static com.android.bedstead.nene.types.OptionalBoolean.TRUE;
36 
37 import static com.google.common.truth.Truth.assertThat;
38 import static com.google.common.truth.Truth.assertWithMessage;
39 
40 import static org.junit.Assert.assertFalse;
41 import static org.junit.Assert.assertThrows;
42 import static org.junit.Assert.assertTrue;
43 import static org.junit.Assume.assumeNoException;
44 import static org.junit.Assume.assumeNotNull;
45 import static org.junit.Assume.assumeTrue;
46 
47 import android.app.Instrumentation;
48 import android.content.Context;
49 import android.content.Intent;
50 import android.content.pm.PackageManager;
51 import android.content.pm.UserInfo;
52 import android.content.pm.UserProperties;
53 import android.content.res.Resources;
54 import android.graphics.Bitmap;
55 import android.os.NewUserRequest;
56 import android.os.NewUserResponse;
57 import android.os.PersistableBundle;
58 import android.os.UserHandle;
59 import android.os.UserManager;
60 import android.platform.test.annotations.AppModeFull;
61 import android.platform.test.annotations.SystemUserOnly;
62 import android.util.Log;
63 
64 import androidx.annotation.Nullable;
65 import androidx.test.platform.app.InstrumentationRegistry;
66 
67 import com.android.bedstead.harrier.BedsteadJUnit4;
68 import com.android.bedstead.harrier.DeviceState;
69 import com.android.bedstead.harrier.annotations.EnsureHasAdditionalUser;
70 import com.android.bedstead.harrier.annotations.EnsureHasNoAdditionalUser;
71 import com.android.bedstead.harrier.annotations.EnsureHasNoWorkProfile;
72 import com.android.bedstead.harrier.annotations.EnsureHasPermission;
73 import com.android.bedstead.harrier.annotations.EnsureHasSecondaryUser;
74 import com.android.bedstead.harrier.annotations.EnsureHasWorkProfile;
75 import com.android.bedstead.harrier.annotations.RequireFeature;
76 import com.android.bedstead.harrier.annotations.RequireHeadlessSystemUserMode;
77 import com.android.bedstead.harrier.annotations.RequireNotHeadlessSystemUserMode;
78 import com.android.bedstead.harrier.annotations.RequireRunOnInitialUser;
79 import com.android.bedstead.harrier.annotations.RequireRunOnSecondaryUser;
80 import com.android.bedstead.harrier.annotations.RequireRunOnWorkProfile;
81 import com.android.bedstead.nene.TestApis;
82 import com.android.bedstead.nene.permissions.PermissionContext;
83 import com.android.bedstead.nene.users.UserReference;
84 import com.android.compatibility.common.util.ApiTest;
85 import com.android.compatibility.common.util.BlockingBroadcastReceiver;
86 import com.android.compatibility.common.util.CddTest;
87 
88 import org.junit.Before;
89 import org.junit.ClassRule;
90 import org.junit.Rule;
91 import org.junit.Test;
92 import org.junit.runner.RunWith;
93 
94 import java.util.ArrayDeque;
95 import java.util.ArrayList;
96 import java.util.Arrays;
97 import java.util.HashSet;
98 import java.util.List;
99 import java.util.Set;
100 import java.util.function.Function;
101 import java.util.stream.Collectors;
102 
103 @RunWith(BedsteadJUnit4.class)
104 public final class UserManagerTest {
105 
106     private static final String TAG = UserManagerTest.class.getSimpleName();
107 
108     @ClassRule
109     @Rule
110     public static final DeviceState sDeviceState = new DeviceState();
111 
112     private final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
113     private UserManager mUserManager;
114 
115     private final String mAccountName = "test_account_name";
116     private final String mAccountType = "test_account_type";
117 
118     @Before
setUp()119     public void setUp() {
120         mUserManager = sContext.getSystemService(UserManager.class);
121         assertWithMessage("UserManager service").that(mUserManager).isNotNull();
122     }
123 
124     @EnsureHasPermission(CREATE_USERS)
removeUser(UserHandle userHandle)125     private void removeUser(UserHandle userHandle) {
126         if (userHandle == null) {
127             return;
128         }
129 
130         assertThat(mUserManager.removeUser(userHandle)).isTrue();
131     }
132 
133     /**
134      * Verify that the isUserAGoat() method always returns false for API level 30. This is
135      * because apps targeting R no longer have access to package queries by default.
136      */
137     @Test
testUserGoat_api30()138     public void testUserGoat_api30() {
139         assertWithMessage("isUserAGoat()").that(mUserManager.isUserAGoat()).isFalse();
140     }
141 
142     /**
143      * Verify that isAdminUser() can be called without any permissions and returns true for the
144      * initial user which is an admin user.
145      */
146     @Test
147     @ApiTest(apis = {"android.os.UserManager#isAdminUser"})
148     @RequireRunOnInitialUser
testIsAdminUserOnInitialUser_noPermission()149     public void testIsAdminUserOnInitialUser_noPermission() {
150         assertTrue(mUserManager.isAdminUser());
151     }
152 
153     /**
154      * Verify that isAdminUser() throws SecurityException when called for a different user context
155      * without any permission.
156      */
157     @Test
158     @ApiTest(apis = {"android.os.UserManager#isAdminUser"})
159     @EnsureHasAdditionalUser(installInstrumentedApp = TRUE)
testIsAdminUserForOtherUserContextFailsWithoutPermission()160     public void testIsAdminUserForOtherUserContextFailsWithoutPermission() {
161         UserReference additionalUser = sDeviceState.additionalUser();
162         additionalUser.switchTo();
163         Context userContext;
164         try (PermissionContext p =
165                      TestApis.permissions().withPermission(INTERACT_ACROSS_USERS_FULL)) {
166             userContext = getContextForUser(additionalUser.id());
167         }
168 
169         UserManager um = userContext.getSystemService(UserManager.class);
170         assertThrows(SecurityException.class, () -> um.isAdminUser());
171     }
172 
173     /**
174      * Verify that isAdminUser() works fine when called for a different user context
175      * with required permission.
176      */
177     @Test
178     @ApiTest(apis = {"android.os.UserManager#isAdminUser"})
179     @EnsureHasAdditionalUser(installInstrumentedApp = TRUE)
180     @EnsureHasPermission(CREATE_USERS)
testIsAdminUserForOtherUserContextWithPermission()181     public void testIsAdminUserForOtherUserContextWithPermission() {
182         UserReference additionalUser = sDeviceState.additionalUser();
183         Context userContext;
184         try (PermissionContext p =
185                      TestApis.permissions().withPermission(INTERACT_ACROSS_USERS_FULL)) {
186             userContext = getContextForUser(additionalUser.id());
187         }
188 
189         UserManager um = userContext.getSystemService(UserManager.class);
190         assertFalse(um.isAdminUser());
191     }
192 
193     @Test
testIsRemoveResultSuccessful()194     public void testIsRemoveResultSuccessful() {
195         assertThat(UserManager.isRemoveResultSuccessful(UserManager.REMOVE_RESULT_REMOVED))
196                 .isTrue();
197         assertThat(UserManager.isRemoveResultSuccessful(UserManager.REMOVE_RESULT_DEFERRED))
198                 .isTrue();
199         assertThat(UserManager
200                 .isRemoveResultSuccessful(UserManager.REMOVE_RESULT_ALREADY_BEING_REMOVED))
201                         .isTrue();
202         assertThat(UserManager.isRemoveResultSuccessful(UserManager.REMOVE_RESULT_ERROR_UNKNOWN))
203                 .isFalse();
204         assertThat(UserManager
205                 .isRemoveResultSuccessful(UserManager.REMOVE_RESULT_ERROR_USER_RESTRICTION))
206                         .isFalse();
207         assertThat(UserManager
208                 .isRemoveResultSuccessful(UserManager.REMOVE_RESULT_ERROR_USER_NOT_FOUND))
209                         .isFalse();
210         assertThat(
211                 UserManager.isRemoveResultSuccessful(UserManager.REMOVE_RESULT_ERROR_SYSTEM_USER))
212                         .isFalse();
213     }
214 
215     @Test
testIsHeadlessSystemUserMode()216     public void testIsHeadlessSystemUserMode() throws Exception {
217         boolean expected = getBooleanProperty(mInstrumentation,
218                 "ro.fw.mu.headless_system_user");
219         assertWithMessage("isHeadlessSystemUserMode()")
220                 .that(UserManager.isHeadlessSystemUserMode()).isEqualTo(expected);
221     }
222 
223     @Test
224     @ApiTest(apis = {"android.os.UserManager#isUserForeground"})
225     @RequireRunOnInitialUser
testIsUserForeground_differentContext_noPermission()226     public void testIsUserForeground_differentContext_noPermission() throws Exception {
227         Context context = getContextForOtherUser();
228         UserManager um = context.getSystemService(UserManager.class);
229 
230         assertThrows(SecurityException.class, () -> um.isUserForeground());
231     }
232 
233     @Test
234     @ApiTest(apis = {"android.os.UserManager#isUserForeground"})
235     @EnsureHasPermission(INTERACT_ACROSS_USERS)
testIsUserForeground_differentContext_withPermission()236     public void testIsUserForeground_differentContext_withPermission() throws Exception {
237         Context userContext = getContextForOtherUser();
238         UserManager um = userContext.getSystemService(UserManager.class);
239 
240         assertWithMessage("isUserForeground() for unknown user").that(um.isUserForeground())
241                 .isFalse();
242     }
243 
244     @Test
245     @ApiTest(apis = {"android.os.UserManager#isUserForeground"})
246     @RequireRunOnInitialUser
testIsUserForeground_currentUser()247     public void testIsUserForeground_currentUser() throws Exception {
248         assertWithMessage("isUserForeground() for current user")
249                 .that(mUserManager.isUserForeground()).isTrue();
250     }
251 
252     @Test
253     @ApiTest(apis = {"android.os.UserManager#isUserForeground"})
254     @RequireRunOnSecondaryUser(switchedToUser = FALSE)
testIsUserForeground_backgroundUser()255     public void testIsUserForeground_backgroundUser() throws Exception {
256         assertWithMessage("isUserForeground() for bg user (%s)", sContext.getUser())
257                 .that(mUserManager.isUserForeground()).isFalse();
258     }
259 
260     @Test
261     @ApiTest(apis = {"android.os.UserManager#isUserForeground"})
262     @RequireRunOnWorkProfile // TODO(b/239961027): should be @RequireRunOnProfile instead
testIsUserForeground_profileOfCurrentUser()263     public void testIsUserForeground_profileOfCurrentUser() throws Exception {
264         assertWithMessage("isUserForeground() for profile(%s) of current user", sContext.getUser())
265                 .that(mUserManager.isUserForeground()).isFalse();
266     }
267 
268     @Test
269     @ApiTest(apis = {"android.os.UserManager#isUserRunning"})
270     @RequireRunOnInitialUser
271     @EnsureHasWorkProfile(installInstrumentedApp = TRUE)
272     @EnsureHasPermission(INTERACT_ACROSS_USERS) // needed to call isUserRunning()
testIsUserRunning_stoppedProfileOfCurrentUser()273     public void testIsUserRunning_stoppedProfileOfCurrentUser() {
274         UserReference profile = sDeviceState.workProfile();
275         Log.d(TAG, "Stopping profile " + profile + " (called from " + sContext.getUser() + ")");
276         profile.stop();
277 
278         Context context = getContextForUser(profile.userHandle().getIdentifier());
279         UserManager um = context.getSystemService(UserManager.class);
280 
281         assertWithMessage("isUserRunning() for stopped profile (id=%s) of current user",
282                 profile.id()).that(um.isUserRunning(profile.userHandle()))
283                 .isFalse();
284     }
285 
286     @Test
287     @ApiTest(apis = {"android.os.UserManager#isUserRunning"})
288     @EnsureHasAdditionalUser(switchedToUser = FALSE)
289     @EnsureHasPermission(INTERACT_ACROSS_USERS) // needed to call isUserRunning()
testIsUserRunning_stoppedSecondaryUser()290     public void testIsUserRunning_stoppedSecondaryUser() {
291         Log.d(TAG, "Stopping  user " + sDeviceState.additionalUser()
292                 + " (called from " + sContext.getUser() + ")");
293         sDeviceState.additionalUser().stop();
294 
295         UserManager um =
296                 TestApis.context().instrumentedContext().getSystemService(UserManager.class);
297 
298         assertWithMessage("isUserRunning() for stopped secondary user (id=%s)",
299                 sDeviceState.additionalUser().id())
300                 .that(um.isUserRunning(sDeviceState.additionalUser().userHandle())).isFalse();
301     }
302 
303     @Test
304     @EnsureHasNoWorkProfile
305     @ApiTest(apis = {"android.os.UserManager#createProfile"})
306     @EnsureHasPermission(CREATE_USERS)
testCloneProfile()307     public void testCloneProfile() throws Exception {
308         assumeTrue(mUserManager.supportsMultipleUsers());
309         UserHandle userHandle = null;
310 
311         // Need CREATE_USERS permission to create user in test
312         try {
313             try {
314                 userHandle = mUserManager.createProfile(
315                     "Clone profile", USER_TYPE_PROFILE_CLONE, new HashSet<>());
316             } catch (UserManager.UserOperationException e) {
317                 // Not all devices and user types support these profiles; skip if this one doesn't.
318                 assumeNoException("Couldn't create clone profile", e);
319                 return;
320             }
321             assertThat(userHandle).isNotNull();
322 
323             final Context userContext = sContext.createPackageContextAsUser("system", 0,
324                     userHandle);
325             final UserManager cloneUserManager = userContext.getSystemService(UserManager.class);
326             assertThat(cloneUserManager.isMediaSharedWithParent()).isTrue();
327             assertThat(cloneUserManager.isCredentialSharableWithParent()).isTrue();
328             assertThat(cloneUserManager.isCloneProfile()).isTrue();
329             assertThat(cloneUserManager.isProfile()).isTrue();
330             assertThat(cloneUserManager.isUserOfType(UserManager.USER_TYPE_PROFILE_CLONE)).isTrue();
331 
332             final List<UserInfo> list = mUserManager.getAliveUsers();
333             final UserHandle finalUserHandle = userHandle;
334             final List<UserInfo> cloneUsers = list.stream().filter(
335                     user -> (user.id == finalUserHandle.getIdentifier()
336                             && user.isCloneProfile()))
337                     .collect(Collectors.toList());
338             assertThat(cloneUsers.size()).isEqualTo(1);
339         } finally {
340             removeUser(userHandle);
341         }
342     }
343 
344 
345     @Test
346     @EnsureHasNoWorkProfile
347     @ApiTest(apis = {"android.os.UserManager#createProfile"})
348     @AppModeFull
349     @EnsureHasPermission(CREATE_USERS)
testAddCloneProfile_shouldSendProfileAddedBroadcast()350     public void testAddCloneProfile_shouldSendProfileAddedBroadcast() {
351         assumeTrue(mUserManager.supportsMultipleUsers());
352         BlockingBroadcastReceiver broadcastReceiver = sDeviceState
353                 .registerBroadcastReceiver(Intent.ACTION_PROFILE_ADDED, /* checker= */null);
354         UserHandle userHandle = null;
355             try {
356                 userHandle = mUserManager.createProfile("Clone profile",
357                         USER_TYPE_PROFILE_CLONE, new HashSet<>());
358                 assumeNotNull(userHandle);
359                 broadcastReceiver.awaitForBroadcastOrFail();
360             } catch (UserManager.UserOperationException e) {
361                 assumeNoException("Couldn't create clone profile", e);
362             } finally {
363                 removeUser(userHandle);
364             }
365     }
366 
367     @Test
368     @ApiTest(apis = {"android.os.UserManager#createProfile"})
369     @AppModeFull
370     @EnsureHasNoWorkProfile
371     @RequireFeature(FEATURE_MANAGED_USERS)
372     @EnsureHasPermission(CREATE_USERS)
testCreateManagedProfile_shouldSendProfileAddedBroadcast()373     public void testCreateManagedProfile_shouldSendProfileAddedBroadcast() {
374         BlockingBroadcastReceiver broadcastReceiver = sDeviceState
375                 .registerBroadcastReceiver(Intent.ACTION_PROFILE_ADDED, /* checker= */null);
376         UserHandle userHandle = null;
377             try {
378                 userHandle = mUserManager.createProfile("Managed profile",
379                         USER_TYPE_PROFILE_MANAGED, new HashSet<>());
380                 assumeNotNull(userHandle);
381                 broadcastReceiver.awaitForBroadcastOrFail();
382             } catch (UserManager.UserOperationException e) {
383                 assumeNoException("Couldn't create managed profile", e);
384             } finally {
385                 removeUser(userHandle);
386             }
387     }
388 
389     @Test
390     @EnsureHasNoWorkProfile
391     @ApiTest(apis = {"android.os.UserManager#createProfile"})
392     @AppModeFull
393     @EnsureHasPermission(CREATE_USERS)
testRemoveCloneProfile_shouldSendProfileRemovedBroadcast()394     public void testRemoveCloneProfile_shouldSendProfileRemovedBroadcast() {
395         assumeTrue(mUserManager.supportsMultipleUsers());
396         BlockingBroadcastReceiver broadcastReceiver = null;
397         UserHandle userHandle = null;
398             try {
399                 userHandle = mUserManager.createProfile("Clone profile",
400                         USER_TYPE_PROFILE_CLONE, new HashSet<>());
401                 broadcastReceiver = sDeviceState
402                         .registerBroadcastReceiver(
403                                 Intent.ACTION_PROFILE_REMOVED, userIsEqual(userHandle)
404                 );
405                 assumeNotNull(userHandle);
406                 removeUser(userHandle);
407                 broadcastReceiver.awaitForBroadcastOrFail();
408             } catch (UserManager.UserOperationException e) {
409                 assumeNoException("Couldn't create clone profile", e);
410             }
411     }
412 
413     @Test
414     @ApiTest(apis = {"android.os.UserManager#createProfile"})
415     @AppModeFull
416     @EnsureHasNoWorkProfile
417     @RequireFeature(FEATURE_MANAGED_USERS)
418     @EnsureHasPermission(CREATE_USERS)
testRemoveManagedProfile_shouldSendProfileRemovedBroadcast()419     public void testRemoveManagedProfile_shouldSendProfileRemovedBroadcast() {
420         BlockingBroadcastReceiver broadcastReceiver = null;
421         UserHandle userHandle = null;
422             try {
423                 userHandle = mUserManager.createProfile("Managed profile",
424                         USER_TYPE_PROFILE_MANAGED, new HashSet<>());
425                 broadcastReceiver = sDeviceState
426                         .registerBroadcastReceiver(
427                                 Intent.ACTION_PROFILE_REMOVED, userIsEqual(userHandle)
428                         );
429                 assumeNotNull(userHandle);
430                 removeUser(userHandle);
431                 broadcastReceiver.awaitForBroadcastOrFail();
432             } catch (UserManager.UserOperationException e) {
433                 assumeNoException("Couldn't create managed profile", e);
434             }
435     }
436 
437     @Test
438     @RequireFeature(FEATURE_MANAGED_USERS)
439     @EnsureHasNoWorkProfile
440     @EnsureHasPermission({CREATE_USERS, QUERY_USERS})
441     @ApiTest(apis = {
442             "android.os.UserManager#createProfile",
443             "android.os.UserManager#isManagedProfile",
444             "android.os.UserManager#isProfile",
445             "android.os.UserManager#isUserOfType"})
testManagedProfile()446     public void testManagedProfile() throws Exception {
447         UserHandle userHandle = null;
448 
449         try {
450             try {
451                 userHandle = mUserManager.createProfile(
452                     "Managed profile", UserManager.USER_TYPE_PROFILE_MANAGED, new HashSet<>());
453             } catch (UserManager.UserOperationException e) {
454                 // Not all devices and user types support these profiles; skip if this one doesn't.
455                 assumeNoException("Couldn't create managed profile", e);
456                 return;
457             }
458             assertThat(userHandle).isNotNull();
459 
460             final UserManager umOfProfile = sContext
461                     .createPackageContextAsUser("android", 0, userHandle)
462                     .getSystemService(UserManager.class);
463 
464             assertThat(umOfProfile.isManagedProfile()).isTrue();
465             assertThat(umOfProfile.isManagedProfile(userHandle.getIdentifier())).isTrue();
466             assertThat(umOfProfile.isProfile()).isTrue();
467             assertThat(umOfProfile.isUserOfType(UserManager.USER_TYPE_PROFILE_MANAGED)).isTrue();
468         } finally {
469             removeUser(userHandle);
470         }
471     }
472 
473     @Test
474     @RequireHeadlessSystemUserMode(reason = "Secondary user profile is only available on headless")
475     @ApiTest(apis = {"android.os.UserManager#removeUser"})
476     @EnsureHasAdditionalUser
477     @RequireRunOnInitialUser
478     @EnsureHasWorkProfile(forUser = ADDITIONAL_USER)
479     @EnsureHasPermission(CREATE_USERS)
testRemoveParentUser_withProfiles()480     public void testRemoveParentUser_withProfiles() {
481         UserReference workProfile = sDeviceState.workProfile(/* forUser= */ ADDITIONAL_USER);
482         UserReference parentUser = workProfile.parent();
483         parentUser.remove();
484 
485         // Removing parent user will also remove its profile
486         assertThat(parentUser.exists()).isFalse();
487         assertThat(workProfile.exists()).isFalse();
488     }
489 
490     @Test
491     @RequireHeadlessSystemUserMode(reason = "Secondary user profile is only available on headless")
492     @ApiTest(apis = {"android.os.UserManager#removeUser"})
493     @EnsureHasAdditionalUser
494     @RequireRunOnInitialUser
495     @EnsureHasWorkProfile(forUser = ADDITIONAL_USER)
496     @EnsureHasPermission(CREATE_USERS)
testRemoveUserOnlyProfile_ShouldNotRemoveAnyOtherUserInSameProfileGroupId()497     public void testRemoveUserOnlyProfile_ShouldNotRemoveAnyOtherUserInSameProfileGroupId() {
498         UserHandle parentUser = null;
499 
500         try {
501             UserReference workProfile = sDeviceState.workProfile(/* forUser= */ ADDITIONAL_USER);
502             parentUser = workProfile.parent().userHandle();
503             UserHandle workProfileUser = workProfile.userHandle();
504 
505             try (BlockingBroadcastReceiver receiver = BlockingBroadcastReceiver.create(sContext,
506                     Intent.ACTION_USER_REMOVED, userIsEqual(workProfileUser)).register()) {
507                 removeUser(workProfileUser);
508             }
509 
510             //Removing a profile will only remove the profile and not the parent user
511             assertThat(hasUser(workProfileUser.getIdentifier())).isFalse();
512             assertThat(hasUser(parentUser.getIdentifier())).isTrue();
513         } finally {
514             removeUser(parentUser);
515         }
516     }
517 
518     @Test
519     @RequireHeadlessSystemUserMode(reason = "only headless can have main user as permanent admin.")
520     @ApiTest(apis = {"android.os.UserManager#removeUserWhenPossible"})
521     @EnsureHasAdditionalUser
522     @EnsureHasPermission({CREATE_USERS})
testRemoveMainUser_shouldNotRemoveMainUser()523     public void testRemoveMainUser_shouldNotRemoveMainUser() {
524         assumeTrue("Main user is not permanent admin.", isMainUserPermanentAdmin());
525         UserReference initialUser = sDeviceState.initialUser();
526         UserReference additionalUser = sDeviceState.additionalUser();
527         if (TestApis.users().current() != additionalUser) {
528             additionalUser.switchTo();
529         }
530 
531         assertThat(mUserManager.removeUserWhenPossible(initialUser.userHandle(), false))
532                 .isEqualTo(UserManager.REMOVE_RESULT_ERROR_MAIN_USER_PERMANENT_ADMIN);
533 
534         // Initial/main user should not be removed.
535         assertThat(hasUser(initialUser.id())).isTrue();
536     }
537 
538     @Test
539     @EnsureHasPermission({QUERY_USERS})
540     @ApiTest(apis = {
541             "android.os.UserManager#isSystemUser",
542             "android.os.UserManager#isUserOfType",
543             "android.os.UserManager#isProfile",
544             "android.os.UserManager#isManagedProfile",
545             "android.os.UserManager#isCloneProfile"})
testSystemUser()546     public void testSystemUser() throws Exception {
547         final UserManager umOfSys = sContext
548                 .createPackageContextAsUser("android", 0, UserHandle.SYSTEM)
549                 .getSystemService(UserManager.class);
550 
551         assertThat(umOfSys.isSystemUser()).isTrue();
552         // We cannot demand what type of user SYSTEM is, but we can say some things it isn't.
553         assertThat(umOfSys.isUserOfType(UserManager.USER_TYPE_PROFILE_CLONE)).isFalse();
554         assertThat(umOfSys.isUserOfType(UserManager.USER_TYPE_PROFILE_MANAGED)).isFalse();
555         assertThat(umOfSys.isUserOfType(UserManager.USER_TYPE_FULL_GUEST)).isFalse();
556 
557         assertThat(umOfSys.isProfile()).isFalse();
558         assertThat(umOfSys.isManagedProfile()).isFalse();
559         assertThat(umOfSys.isManagedProfile(UserHandle.USER_SYSTEM)).isFalse();
560         assertThat(umOfSys.isCloneProfile()).isFalse();
561     }
562 
563     @Test
564     @EnsureHasNoWorkProfile
565     @SystemUserOnly(reason = "Restricted users are only supported on system user.")
566     @ApiTest(apis = {
567             "android.os.UserManager#isRestrictedProfile",
568             "android.os.UserManager#getRestrictedProfileParent",
569             "android.os.UserManager#createRestrictedProfile"})
570     @EnsureHasPermission(CREATE_USERS)
testRestrictedUser()571     public void testRestrictedUser() throws Exception {
572         UserHandle user = null;
573         try {
574             // Check that the SYSTEM user is not restricted.
575             assertThat(mUserManager.isRestrictedProfile()).isFalse();
576             assertThat(mUserManager.isRestrictedProfile(UserHandle.SYSTEM)).isFalse();
577             assertThat(mUserManager.getRestrictedProfileParent()).isNull();
578 
579             final UserInfo info = mUserManager.createRestrictedProfile("Restricted user");
580 
581             // If the device supports Restricted users, it must report it correctly.
582             assumeTrue("Couldn't create a restricted profile", info != null);
583 
584             user = UserHandle.of(info.id);
585             assertThat(mUserManager.isRestrictedProfile(user)).isTrue();
586 
587             final Context userContext = sContext.createPackageContextAsUser("system", 0, user);
588             final UserManager userUm = userContext.getSystemService(UserManager.class);
589 
590             assertThat(userUm.isRestrictedProfile()).isTrue();
591             assertThat(userUm.getRestrictedProfileParent().isSystem()).isTrue();
592         } finally {
593             removeUser(user);
594         }
595     }
596 
newUserRequest()597     private NewUserRequest newUserRequest() {
598         final PersistableBundle accountOptions = new PersistableBundle();
599         accountOptions.putString("test_account_option_key", "test_account_option_value");
600 
601         return new NewUserRequest.Builder()
602                 .setName("test_user")
603                 .setUserType(USER_TYPE_FULL_SECONDARY)
604                 .setUserIcon(Bitmap.createBitmap(32, 32, Bitmap.Config.RGB_565))
605                 .setAccountName(mAccountName)
606                 .setAccountType(mAccountType)
607                 .setAccountOptions(accountOptions)
608                 .build();
609     }
610 
611     @Test
612     @EnsureHasPermission(CREATE_USERS)
testSomeUserHasAccount()613     public void testSomeUserHasAccount() {
614         // TODO: (b/233197356): Replace with bedstead annotation.
615         assumeTrue(mUserManager.supportsMultipleUsers());
616         UserHandle user = null;
617 
618         try {
619             assertThat(mUserManager.someUserHasAccount(mAccountName, mAccountType)).isFalse();
620             user = mUserManager.createUser(newUserRequest()).getUser();
621             assertThat(mUserManager.someUserHasAccount(mAccountName, mAccountType)).isTrue();
622         } finally {
623             removeUser(user);
624         }
625     }
626 
627     @Test
628     @EnsureHasPermission(CREATE_USERS)
testSomeUserHasAccount_shouldIgnoreToBeRemovedUsers()629     public void testSomeUserHasAccount_shouldIgnoreToBeRemovedUsers() {
630         // TODO: (b/233197356): Replace with bedstead annotation.
631         assumeTrue(mUserManager.supportsMultipleUsers());
632             final NewUserResponse response = mUserManager.createUser(newUserRequest());
633             assertThat(response.getOperationResult()).isEqualTo(USER_OPERATION_SUCCESS);
634             mUserManager.removeUser(response.getUser());
635             assertThat(mUserManager.someUserHasAccount(mAccountName, mAccountType)).isFalse();
636     }
637 
638     @Test
639     @ApiTest(apis = {
640             "android.os.UserManager#supportsMultipleUsers",
641             "android.os.UserManager#createUser",
642             "android.os.UserManager#getUserName",
643             "android.os.UserManager#isUserNameSet",
644             "android.os.UserManager#getUserType",
645             "android.os.UserManager#isUserOfType"})
646     @EnsureHasPermission(CREATE_USERS)
testCreateUser_withNewUserRequest_shouldCreateUserWithCorrectProperties()647     public void testCreateUser_withNewUserRequest_shouldCreateUserWithCorrectProperties()
648             throws PackageManager.NameNotFoundException {
649         // TODO: (b/233197356): Replace with bedstead annotation.
650         assumeTrue(mUserManager.supportsMultipleUsers());
651         UserHandle user = null;
652 
653         try {
654             final NewUserRequest request = newUserRequest();
655             final NewUserResponse response = mUserManager.createUser(request);
656             user = response.getUser();
657 
658             assertThat(response.getOperationResult()).isEqualTo(USER_OPERATION_SUCCESS);
659             assertThat(response.isSuccessful()).isTrue();
660             assertThat(user).isNotNull();
661 
662             UserManager userManagerOfNewUser = sContext
663                     .createPackageContextAsUser("android", 0, user)
664                     .getSystemService(UserManager.class);
665 
666             assertThat(userManagerOfNewUser.getUserName()).isEqualTo(request.getName());
667             assertThat(userManagerOfNewUser.isUserNameSet()).isTrue();
668             assertThat(userManagerOfNewUser.getUserType()).isEqualTo(request.getUserType());
669             assertThat(userManagerOfNewUser.isUserOfType(request.getUserType())).isEqualTo(true);
670             // We can not test userIcon and accountOptions,
671             // because getters require MANAGE_USERS permission.
672             // And we are already testing accountName and accountType
673             // are set correctly in testSomeUserHasAccount method.
674         } finally {
675             removeUser(user);
676         }
677     }
678 
679     @Test
680     @EnsureHasPermission(CREATE_USERS)
testCreateUser_withNewUserRequest_shouldNotAllowDuplicateUserAccounts()681     public void testCreateUser_withNewUserRequest_shouldNotAllowDuplicateUserAccounts() {
682         // TODO: (b/233197356): Replace with bedstead annotation.
683         assumeTrue(mUserManager.supportsMultipleUsers());
684         UserHandle user1 = null;
685         UserHandle user2 = null;
686 
687         try {
688             final NewUserResponse response1 = mUserManager.createUser(newUserRequest());
689             user1 = response1.getUser();
690 
691             assertThat(response1.getOperationResult()).isEqualTo(USER_OPERATION_SUCCESS);
692             assertThat(response1.isSuccessful()).isTrue();
693             assertThat(user1).isNotNull();
694 
695             final NewUserResponse response2 = mUserManager.createUser(newUserRequest());
696             user2 = response2.getUser();
697 
698             assertThat(response2.getOperationResult()).isEqualTo(
699                     UserManager.USER_OPERATION_ERROR_USER_ACCOUNT_ALREADY_EXISTS);
700             assertThat(response2.isSuccessful()).isFalse();
701             assertThat(user2).isNull();
702         } finally {
703             removeUser(user1);
704             removeUser(user2);
705         }
706     }
707 
708     @Test
709     @AppModeFull
710     @EnsureHasWorkProfile // TODO(b/239961027): should also check for other profiles
711     @EnsureHasPermission(INTERACT_ACROSS_USERS)
getProfileParent_returnsParent()712     public void getProfileParent_returnsParent() {
713         final UserReference parent = TestApis.users().instrumented();
714         for (UserHandle profile : mUserManager.getUserProfiles()) {
715             if (!profile.equals(parent.userHandle())) {
716                 assertThat(mUserManager.getProfileParent(profile)).isEqualTo(parent.userHandle());
717             }
718         }
719     }
720 
721     @Test
722     @AppModeFull
723     @EnsureHasPermission(INTERACT_ACROSS_USERS)
getProfileParent_returnsNullForNonProfile()724     public void getProfileParent_returnsNullForNonProfile() {
725         assertThat(mUserManager.getProfileParent(TestApis.users().system().userHandle())).isNull();
726     }
727 
728     @Test
729     @EnsureHasPermission({CREATE_USERS, QUERY_USERS})
testGetRemainingCreatableUserCount()730     public void testGetRemainingCreatableUserCount() {
731         final int maxAllowedIterations = 15;
732         final String userType = USER_TYPE_FULL_SECONDARY;
733         final NewUserRequest request = new NewUserRequest.Builder().build();
734         final ArrayDeque<UserHandle> usersCreated = new ArrayDeque<>();
735 
736         try {
737             final int initialRemainingCount = mUserManager.getRemainingCreatableUserCount(userType);
738             assertThat(initialRemainingCount).isAtLeast(0);
739 
740             final int numUsersToAdd = Math.min(maxAllowedIterations, initialRemainingCount);
741 
742             for (int i = 0; i < numUsersToAdd; i++) {
743                 usersCreated.push(mUserManager.createUser(request).getUser());
744                 assertThat(mUserManager.getRemainingCreatableUserCount(userType))
745                         .isEqualTo(initialRemainingCount - usersCreated.size());
746             }
747             for (int i = 0; i < numUsersToAdd; i++) {
748                 mUserManager.removeUser(usersCreated.pop());
749                 assertThat(mUserManager.getRemainingCreatableUserCount(userType))
750                         .isEqualTo(initialRemainingCount - usersCreated.size());
751             }
752         } finally {
753             usersCreated.forEach(this::removeUser);
754         }
755     }
756 
757     @Test
758     @EnsureHasPermission({CREATE_USERS, QUERY_USERS})
testGetRemainingCreatableProfileCount()759     public void testGetRemainingCreatableProfileCount() {
760         final int maxAllowedIterations = 15;
761         final String type = USER_TYPE_PROFILE_MANAGED;
762         final ArrayDeque<UserHandle> profilesCreated = new ArrayDeque<>();
763         final Set<String> disallowedPackages = new HashSet<>();
764         try {
765             final int initialRemainingCount =
766                     mUserManager.getRemainingCreatableProfileCount(type);
767             assertThat(initialRemainingCount).isAtLeast(0);
768 
769             final int numUsersToAdd = Math.min(maxAllowedIterations, initialRemainingCount);
770 
771             for (int i = 0; i < numUsersToAdd; i++) {
772                 profilesCreated.push(mUserManager.createProfile(null, type, disallowedPackages));
773                 assertThat(mUserManager.getRemainingCreatableProfileCount(type))
774                         .isEqualTo(initialRemainingCount - profilesCreated.size());
775             }
776             for (int i = 0; i < numUsersToAdd; i++) {
777                 mUserManager.removeUser(profilesCreated.pop());
778                 assertThat(mUserManager.getRemainingCreatableProfileCount(type))
779                         .isEqualTo(initialRemainingCount - profilesCreated.size());
780             }
781         } finally {
782             profilesCreated.forEach(this::removeUser);
783         }
784     }
785 
786     @Test
787     @ApiTest(apis = {"android.os.UserManager#getUserProperties"})
788     @AppModeFull
789     @EnsureHasPermission({CREATE_USERS, QUERY_USERS})
testGetUserProperties_system()790     public void testGetUserProperties_system() {
791         final UserHandle fullUser = TestApis.users().instrumented().userHandle();
792         final UserProperties properties = mUserManager.getUserProperties(fullUser);
793         assertThat(properties).isNotNull();
794 
795         assertThat(properties.getShowInLauncher()).isIn(Arrays.asList(
796                 UserProperties.SHOW_IN_LAUNCHER_WITH_PARENT));
797         assertThat(properties.isMediaSharedWithParent()).isFalse();
798         assertThat(properties.isCredentialShareableWithParent()).isFalse();
799     }
800 
801     @Test
802     @ApiTest(apis = {"android.os.UserManager#getUserProperties"})
803     @AppModeFull
804     @EnsureHasWorkProfile
805     @RequireFeature(FEATURE_MANAGED_USERS)
806     @EnsureHasPermission({CREATE_USERS, QUERY_USERS})
testGetUserProperties_managedProfile()807     public void testGetUserProperties_managedProfile() {
808         final UserHandle profile = sDeviceState.workProfile().userHandle();
809         final UserProperties properties = mUserManager.getUserProperties(profile);
810         assertThat(properties).isNotNull();
811 
812         assertThat(properties.getShowInLauncher()).isIn(Arrays.asList(
813                 UserProperties.SHOW_IN_LAUNCHER_WITH_PARENT,
814                 UserProperties.SHOW_IN_LAUNCHER_SEPARATE));
815     }
816 
817     @Test
818     @ApiTest(apis = {"android.os.UserManager#isMainUser"})
819     @EnsureHasWorkProfile(installInstrumentedApp = TRUE)
820     @EnsureHasAdditionalUser(installInstrumentedApp = TRUE)
821     @EnsureHasPermission({CREATE_USERS, INTERACT_ACROSS_USERS})
testIsMainUser_trueForAtMostOneUser()822     public void testIsMainUser_trueForAtMostOneUser() {
823         //Install instrumented test app on the SYSTEM user which is not covered in annotations.
824         TestApis.packages().instrumented().installExisting(UserReference.of(UserHandle.SYSTEM));
825 
826         final List<UserHandle> userHandles = mUserManager.getUserHandles(false);
827         final List<UserHandle> mainUsers = new ArrayList<>();
828 
829         for (UserHandle user : userHandles) {
830             final Context userContext = getContextForUser(user.getIdentifier());
831             final UserManager userManager = userContext.getSystemService(UserManager.class);
832             if (userManager.isMainUser()) {
833                 mainUsers.add(user);
834             }
835         }
836         assertWithMessage("main users (%s)", mainUsers).that(mainUsers.size()).isLessThan(2);
837     }
838 
839     @Test
840     @ApiTest(apis = {"android.os.UserManager#getMainUser", "android.os.UserManager#isMainUser"})
841     @EnsureHasWorkProfile(installInstrumentedApp = TRUE)
842     @EnsureHasAdditionalUser(installInstrumentedApp = TRUE)
843     @EnsureHasPermission({QUERY_USERS, INTERACT_ACROSS_USERS})
testGetMainUser_returnsMainUser()844     public void testGetMainUser_returnsMainUser() {
845         final UserHandle mainUser = mUserManager.getMainUser();
846         if (mainUser != null) {
847             final Context mainUserContext = getContextForUser(mainUser.getIdentifier());
848             final UserManager mainUserManager = mainUserContext.getSystemService(UserManager.class);
849             assertThat(mainUserManager.isMainUser()).isTrue();
850         }
851     }
852 
853     @Test
854     @ApiTest(apis = {"android.os.UserManager#getPreviousForegroundUser"})
855     @RequireRunOnInitialUser
856     @EnsureHasNoAdditionalUser
857     @EnsureHasPermission({QUERY_USERS})
testGetPreviousForegroundUser_noAdditionalUser()858     public void testGetPreviousForegroundUser_noAdditionalUser() {
859         assertWithMessage("getPreviousUser() with no additional user")
860                 .that(mUserManager.getPreviousForegroundUser()).isNull();
861     }
862 
863     @Test
864     @ApiTest(apis = {"android.os.UserManager#getPreviousForegroundUser"})
865     @RequireRunOnInitialUser
866     @EnsureHasNoAdditionalUser
867     @EnsureHasWorkProfile
868     @EnsureHasPermission({QUERY_USERS})
testGetPreviousForegroundUser_withWorkProfileButNoAdditionalUser()869     public void testGetPreviousForegroundUser_withWorkProfileButNoAdditionalUser() {
870         assertWithMessage("getPreviousForegroundUser() with work profile but no additional user")
871                 .that(mUserManager.getPreviousForegroundUser()).isNull();
872     }
873 
874     @Test
875     @ApiTest(apis = {"android.os.UserManager#getPreviousForegroundUser"})
876     @EnsureHasAdditionalUser
877     @EnsureHasPermission({QUERY_USERS})
testGetPreviousForegroundUser_switchingBetweenInitialAndAdditional()878     public void testGetPreviousForegroundUser_switchingBetweenInitialAndAdditional() {
879         UserReference initialUser = sDeviceState.initialUser();
880         UserReference additionalUser = sDeviceState.additionalUser();
881 
882         if (TestApis.users().current() != initialUser) {
883             initialUser.switchTo();
884         }
885 
886         additionalUser.switchTo();
887         assertThat(mUserManager.getPreviousForegroundUser()).isEqualTo(initialUser.userHandle());
888         initialUser.switchTo();
889         assertThat(mUserManager.getPreviousForegroundUser()).isEqualTo(additionalUser.userHandle());
890     }
891 
892     @Test
893     @CddTest(requirements = {"9.5/H-1-1,H-4-2"})
headlessCannotSupportTelephony()894     public void headlessCannotSupportTelephony() {
895         boolean isHeadless = UserManager.isHeadlessSystemUserMode();
896         boolean hasTelephony =
897                 sContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
898 
899         assertWithMessage("Cannot run in headless system user mode if telephony is present")
900                 .that(isHeadless && hasTelephony).isFalse();
901     }
902 
903     @Test
904     @ApiTest(apis = {"android.os.UserManager#setBootUser"})
905     @EnsureHasAdditionalUser
906     @EnsureHasPermission({CREATE_USERS})
setBootUser_providedUserIsSwitchable()907     public void setBootUser_providedUserIsSwitchable() {
908         UserReference additionalUser = sDeviceState.additionalUser();
909         mUserManager.setBootUser(additionalUser.userHandle());
910 
911         assertThat(mUserManager.getBootUser()).isEqualTo(additionalUser.userHandle());
912     }
913 
914     @Test
915     @ApiTest(apis = {"android.os.UserManager#setBootUser"})
916     @EnsureHasWorkProfile
917     @EnsureHasAdditionalUser
918     @EnsureHasPermission({CREATE_USERS})
919     @RequireNotHeadlessSystemUserMode(reason = "Testing non-HSUM scenario")
setBootUser_providedUserIsNotSwitchable_nonHsum()920     public void setBootUser_providedUserIsNotSwitchable_nonHsum() {
921         UserReference additionalUser = sDeviceState.additionalUser();
922         UserReference workProfile = sDeviceState.workProfile();
923         mUserManager.setBootUser(workProfile.userHandle());
924 
925         // Switch to additional user to make sure there is a previous user that is not the
926         // current user.
927         additionalUser.switchTo();
928 
929         // Boot user will be the system user
930         assertThat(mUserManager.getBootUser())
931                 .isEqualTo(sDeviceState.primaryUser().userHandle());
932     }
933 
934     @Test
935     @ApiTest(apis = {"android.os.UserManager#setBootUser"})
936     @EnsureHasWorkProfile
937     @EnsureHasAdditionalUser
938     @EnsureHasPermission({CREATE_USERS})
939     @RequireHeadlessSystemUserMode(reason = "Testing HSUM scenario")
setBootUser_providedUserIsNotSwitchable_Hsum()940     public void setBootUser_providedUserIsNotSwitchable_Hsum() {
941         UserReference additionalUser = sDeviceState.additionalUser();
942         UserReference workProfile = sDeviceState.workProfile();
943         mUserManager.setBootUser(workProfile.userHandle());
944 
945         // Switch to additional user to make sure there is a previous user that is not the
946         // current user.
947         additionalUser.switchTo();
948 
949         // Boot user will be most recent user
950         assertThat(mUserManager.getBootUser())
951                 .isEqualTo(mUserManager.getPreviousForegroundUser());
952     }
953 
userIsEqual(UserHandle userHandle)954     private Function<Intent, Boolean> userIsEqual(UserHandle userHandle) {
955         try {
956             return (intent) -> userHandle.equals(intent.getParcelableExtra(intent.EXTRA_USER));
957         } catch (NullPointerException e) {
958             assumeNoException("User handle is null", e);
959         }
960         return (intent) -> false;
961     }
962 
963     @Nullable
getUser(int id)964     private UserInfo getUser(int id) {
965         try (PermissionContext p = TestApis.permissions().withPermission(CREATE_USERS)) {
966             return  mUserManager.getUsers()
967                     .stream().filter(user -> user.id == id).findFirst()
968                     .orElse(null);
969         }
970     }
971 
hasUser(int id)972     private boolean hasUser(int id) {
973         return getUser(id) != null;
974     }
975 
isMainUserPermanentAdmin()976     private boolean isMainUserPermanentAdmin() {
977         try {
978             return sContext.getResources().getBoolean(
979                     Resources.getSystem().getIdentifier("config_isMainUserPermanentAdmin",
980                             "bool", "android"));
981         } catch (Resources.NotFoundException e) {
982             // Assume the main user is not permanent admin.
983             return false;
984         }
985     }
986 }
987