• 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.MANAGE_USERS;
23 import static android.Manifest.permission.MODIFY_QUIET_MODE;
24 import static android.Manifest.permission.QUERY_USERS;
25 import static android.content.pm.PackageManager.FEATURE_MANAGED_USERS;
26 import static android.multiuser.cts.TestingUtils.assumeTvNotSupported;
27 import static android.multiuser.cts.TestingUtils.getBooleanProperty;
28 import static android.multiuser.cts.TestingUtils.getContextForOtherUser;
29 import static android.multiuser.cts.TestingUtils.getContextForUser;
30 import static android.multiuser.cts.TestingUtils.sContext;
31 import static android.os.UserManager.USER_OPERATION_SUCCESS;
32 import static android.os.UserManager.USER_TYPE_FULL_SECONDARY;
33 import static android.os.UserManager.USER_TYPE_PROFILE_CLONE;
34 import static android.os.UserManager.USER_TYPE_PROFILE_MANAGED;
35 import static android.os.UserManager.USER_TYPE_PROFILE_SUPERVISING;
36 
37 import static com.android.bedstead.enterprise.EnterpriseDeviceStateExtensionsKt.workProfile;
38 import static com.android.bedstead.harrier.UserType.ADDITIONAL_USER;
39 import static com.android.bedstead.harrier.UserType.ANY;
40 import static com.android.bedstead.multiuser.MultiUserDeviceStateExtensionsKt.additionalUser;
41 import static com.android.bedstead.multiuser.MultiUserDeviceStateExtensionsKt.privateProfile;
42 import static com.android.bedstead.nene.types.OptionalBoolean.FALSE;
43 import static com.android.bedstead.nene.types.OptionalBoolean.TRUE;
44 
45 import static com.google.common.truth.Truth.assertThat;
46 import static com.google.common.truth.Truth.assertWithMessage;
47 
48 import static org.junit.Assert.assertFalse;
49 import static org.junit.Assert.assertTrue;
50 import static org.junit.Assert.fail;
51 import static org.junit.Assume.assumeNoException;
52 import static org.junit.Assume.assumeNotNull;
53 import static org.junit.Assume.assumeTrue;
54 
55 import android.app.Instrumentation;
56 import android.content.Context;
57 import android.content.Intent;
58 import android.content.pm.PackageManager;
59 import android.content.pm.UserInfo;
60 import android.content.pm.UserProperties;
61 import android.content.res.Resources;
62 import android.graphics.Bitmap;
63 import android.os.NewUserRequest;
64 import android.os.NewUserResponse;
65 import android.os.PersistableBundle;
66 import android.os.UserHandle;
67 import android.os.UserManager;
68 import android.platform.test.annotations.AppModeFull;
69 import android.platform.test.annotations.RequiresFlagsEnabled;
70 import android.platform.test.annotations.SystemUserOnly;
71 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
72 import android.util.Log;
73 
74 import androidx.annotation.Nullable;
75 import androidx.test.platform.app.InstrumentationRegistry;
76 
77 import com.android.bedstead.accounts.annotations.EnsureHasNoAccounts;
78 import com.android.bedstead.enterprise.annotations.EnsureHasNoWorkProfile;
79 import com.android.bedstead.enterprise.annotations.EnsureHasWorkProfile;
80 import com.android.bedstead.enterprise.annotations.RequireRunOnWorkProfile;
81 import com.android.bedstead.harrier.BedsteadJUnit4;
82 import com.android.bedstead.harrier.DeviceState;
83 import com.android.bedstead.harrier.annotations.EnsurePasswordNotSet;
84 import com.android.bedstead.harrier.annotations.RequireFeature;
85 import com.android.bedstead.harrier.annotations.RequireResourcesIntegerValue;
86 import com.android.bedstead.harrier.annotations.RequireRunOnInitialUser;
87 import com.android.bedstead.multiuser.annotations.EnsureCanAddUser;
88 import com.android.bedstead.multiuser.annotations.EnsureHasAdditionalUser;
89 import com.android.bedstead.multiuser.annotations.EnsureHasNoAdditionalUser;
90 import com.android.bedstead.multiuser.annotations.EnsureHasPrivateProfile;
91 import com.android.bedstead.multiuser.annotations.RequireHeadlessSystemUserMode;
92 import com.android.bedstead.multiuser.annotations.RequireMultiUserSupport;
93 import com.android.bedstead.multiuser.annotations.RequireNotHeadlessSystemUserMode;
94 import com.android.bedstead.multiuser.annotations.RequirePrivateSpaceSupported;
95 import com.android.bedstead.multiuser.annotations.RequireRunOnPrivateProfile;
96 import com.android.bedstead.multiuser.annotations.RequireRunOnSecondaryUser;
97 import com.android.bedstead.nene.TestApis;
98 import com.android.bedstead.nene.users.UserReference;
99 import com.android.bedstead.nene.utils.BlockingBroadcastReceiver;
100 import com.android.bedstead.permissions.PermissionContext;
101 import com.android.bedstead.permissions.annotations.EnsureDoesNotHavePermission;
102 import com.android.bedstead.permissions.annotations.EnsureHasPermission;
103 import com.android.compatibility.common.util.ApiTest;
104 
105 import org.junit.Before;
106 import org.junit.ClassRule;
107 import org.junit.Rule;
108 import org.junit.Test;
109 import org.junit.rules.RuleChain;
110 import org.junit.rules.TestRule;
111 import org.junit.runner.RunWith;
112 
113 import java.util.ArrayDeque;
114 import java.util.ArrayList;
115 import java.util.Arrays;
116 import java.util.HashSet;
117 import java.util.List;
118 import java.util.Set;
119 import java.util.function.Function;
120 import java.util.stream.Collectors;
121 
122 @RunWith(BedsteadJUnit4.class)
123 public final class UserManagerTest {
124 
125     private static final String TAG = UserManagerTest.class.getSimpleName();
126 
127     @ClassRule
128     public static final DeviceState sDeviceState = new DeviceState();
129 
130     @Rule
131     public TestRule chain = RuleChain
132             .outerRule(DeviceFlagsValueProvider.createCheckFlagsRule())
133             .around(sDeviceState);
134 
135     private final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
136     private UserManager mUserManager;
137 
138     private final String mAccountName = "test_account_name";
139     private final String mAccountType = "test_account_type";
140 
141     @Before
setUp()142     public void setUp() {
143         mUserManager = sContext.getSystemService(UserManager.class);
144         assertWithMessage("UserManager service").that(mUserManager).isNotNull();
145     }
146 
147     @EnsureHasPermission(CREATE_USERS)
removeUser(UserHandle userHandle)148     private void removeUser(UserHandle userHandle) {
149         if (userHandle == null) {
150             return;
151         }
152 
153         assertThat(mUserManager.removeUser(userHandle)).isTrue();
154     }
155 
156     /**
157      * Verify that the isUserAGoat() method always returns false for API level 30. This is
158      * because apps targeting R no longer have access to package queries by default.
159      */
160     @Test
testUserGoat_api30()161     public void testUserGoat_api30() {
162         assertWithMessage("isUserAGoat()").that(mUserManager.isUserAGoat()).isFalse();
163     }
164 
165     /**
166      * Verify that isAdminUser() can be called without any permissions and returns true for the
167      * initial user which is an admin user.
168      */
169     @Test
170     @ApiTest(apis = {"android.os.UserManager#isAdminUser"})
171     @RequireRunOnInitialUser
testIsAdminUserOnInitialUser_noPermission()172     public void testIsAdminUserOnInitialUser_noPermission() {
173         assertTrue(mUserManager.isAdminUser());
174     }
175 
176     /**
177      * Verify that isAdminUser() throws SecurityException when called for a different user context
178      * without any permission.
179      */
180     @Test
181     @ApiTest(apis = {"android.os.UserManager#isAdminUser"})
182     @EnsureHasAdditionalUser(installInstrumentedApp = TRUE)
183     @EnsureDoesNotHavePermission({CREATE_USERS, QUERY_USERS, MANAGE_USERS})
testIsAdminUserForOtherUserContextFailsWithoutPermission()184     public void testIsAdminUserForOtherUserContextFailsWithoutPermission() {
185         UserReference additionalUser = additionalUser(sDeviceState);
186         additionalUser.switchTo();
187         Context userContext;
188         try (PermissionContext p =
189                      TestApis.permissions().withPermission(INTERACT_ACROSS_USERS_FULL)) {
190             userContext = getContextForUser(additionalUser.id());
191         }
192 
193         UserManager um = userContext.getSystemService(UserManager.class);
194         try {
195             um.isAdminUser();
196             fail("Expecting Exception to be thrown when permission is not granted.");
197         } catch (Exception e) {
198             assertTrue("Expected SecurityException, but got " + e.getClass().getSimpleName(),
199                     e instanceof SecurityException);
200         }
201     }
202 
203     /**
204      * Verify that isAdminUser() works fine when called for a different user context
205      * with required permission.
206      */
207     @Test
208     @ApiTest(apis = {"android.os.UserManager#isAdminUser"})
209     @EnsureHasAdditionalUser(installInstrumentedApp = TRUE)
210     @EnsureHasPermission(CREATE_USERS)
testIsAdminUserForOtherUserContextWithPermission()211     public void testIsAdminUserForOtherUserContextWithPermission() {
212         UserReference additionalUser = additionalUser(sDeviceState);
213         Context userContext;
214         try (PermissionContext p =
215                      TestApis.permissions().withPermission(INTERACT_ACROSS_USERS_FULL)) {
216             userContext = getContextForUser(additionalUser.id());
217         }
218 
219         UserManager um = userContext.getSystemService(UserManager.class);
220         assertFalse(um.isAdminUser());
221     }
222 
223     @Test
testIsRemoveResultSuccessful()224     public void testIsRemoveResultSuccessful() {
225         assertThat(UserManager.isRemoveResultSuccessful(UserManager.REMOVE_RESULT_REMOVED))
226                 .isTrue();
227         assertThat(UserManager.isRemoveResultSuccessful(UserManager.REMOVE_RESULT_DEFERRED))
228                 .isTrue();
229         assertThat(UserManager
230                 .isRemoveResultSuccessful(UserManager.REMOVE_RESULT_ALREADY_BEING_REMOVED))
231                         .isTrue();
232         assertThat(UserManager.isRemoveResultSuccessful(UserManager.REMOVE_RESULT_ERROR_UNKNOWN))
233                 .isFalse();
234         assertThat(UserManager
235                 .isRemoveResultSuccessful(UserManager.REMOVE_RESULT_ERROR_USER_RESTRICTION))
236                         .isFalse();
237         assertThat(UserManager
238                 .isRemoveResultSuccessful(UserManager.REMOVE_RESULT_ERROR_USER_NOT_FOUND))
239                         .isFalse();
240         assertThat(
241                 UserManager.isRemoveResultSuccessful(UserManager.REMOVE_RESULT_ERROR_SYSTEM_USER))
242                         .isFalse();
243     }
244 
245     @Test
testIsHeadlessSystemUserMode()246     public void testIsHeadlessSystemUserMode() throws Exception {
247         boolean expected = getBooleanProperty(mInstrumentation,
248                 "ro.fw.mu.headless_system_user");
249         assertWithMessage("isHeadlessSystemUserMode()")
250                 .that(UserManager.isHeadlessSystemUserMode()).isEqualTo(expected);
251     }
252 
253     @Test
254     @ApiTest(apis = {"android.os.UserManager#isUserForeground"})
255     @RequireRunOnInitialUser
256     @EnsureDoesNotHavePermission({MANAGE_USERS, INTERACT_ACROSS_USERS})
testIsUserForeground_differentContext_noPermission()257     public void testIsUserForeground_differentContext_noPermission() throws Exception {
258         // Skip test for devices that support only a single user, since we cannot get a different
259         // user's context for such devices.
260         assumeTrue(mUserManager.supportsMultipleUsers());
261         Context context = getContextForOtherUser();
262         UserManager um = context.getSystemService(UserManager.class);
263 
264         try {
265             um.isUserForeground();
266             fail("Expecting Exception to be thrown when permission is not granted.");
267         } catch (Exception e) {
268             assertTrue("Expected SecurityException, but got " + e.getClass().getSimpleName(),
269                     e instanceof SecurityException);
270         }
271     }
272 
273     @Test
274     @ApiTest(apis = {"android.os.UserManager#isUserForeground"})
275     @EnsureHasPermission(INTERACT_ACROSS_USERS)
testIsUserForeground_differentContext_withPermission()276     public void testIsUserForeground_differentContext_withPermission() throws Exception {
277         // Skip test for devices that support only a single user, since we cannot get a different
278         // user's context for such devices.
279         assumeTrue(mUserManager.supportsMultipleUsers());
280         Context userContext = getContextForOtherUser();
281         UserManager um = userContext.getSystemService(UserManager.class);
282 
283         assertWithMessage("isUserForeground() for unknown user").that(um.isUserForeground())
284                 .isFalse();
285     }
286 
287     @Test
288     @ApiTest(apis = {"android.os.UserManager#isUserForeground"})
289     @RequireRunOnInitialUser
testIsUserForeground_currentUser()290     public void testIsUserForeground_currentUser() throws Exception {
291         assertWithMessage("isUserForeground() for current user")
292                 .that(mUserManager.isUserForeground()).isTrue();
293     }
294 
295     @Test
296     @ApiTest(apis = {"android.os.UserManager#isUserForeground"})
297     @RequireRunOnSecondaryUser(switchedToUser = FALSE)
testIsUserForeground_backgroundUser()298     public void testIsUserForeground_backgroundUser() throws Exception {
299         assertWithMessage("isUserForeground() for bg user (%s)", sContext.getUser())
300                 .that(mUserManager.isUserForeground()).isFalse();
301     }
302 
303     @Test
304     @ApiTest(apis = {"android.os.UserManager#isUserForeground"})
305     @RequireRunOnWorkProfile // TODO(b/239961027): should be @RequireRunOnProfile instead
testIsUserForeground_profileOfCurrentUser()306     public void testIsUserForeground_profileOfCurrentUser() throws Exception {
307         assertWithMessage("isUserForeground() for profile(%s) of current user", sContext.getUser())
308                 .that(mUserManager.isUserForeground()).isFalse();
309     }
310 
311     /**
312      * Verify that isForegroundUserAdmin() returns true when called on the foreground initial
313      * user, which is an admin user, regardless of whether there are other users.
314      */
315     @Test
316     @ApiTest(apis = {"android.os.UserManager#isForegroundUserAdmin"})
317     @RequiresFlagsEnabled(android.multiuser.Flags.FLAG_SUPPORT_COMMUNAL_PROFILE_NEXTGEN)
318     @RequireRunOnInitialUser
testIsForegroundUserAdminUser_admin()319     public void testIsForegroundUserAdminUser_admin() {
320         assertTrue(mUserManager.isForegroundUserAdmin());
321     }
322 
323     /**
324      * Verify that isForegroundUserAdmin() returns the correct value when called on a
325      * (foreground) secondary user, which generally will not be an admin, regardless of the Context.
326      */
327     @Test
328     @ApiTest(apis = {"android.os.UserManager#isForegroundUserAdmin"})
329     @RequiresFlagsEnabled(android.multiuser.Flags.FLAG_SUPPORT_COMMUNAL_PROFILE_NEXTGEN)
330     @RequireRunOnInitialUser
331     @EnsureHasAdditionalUser(installInstrumentedApp = TRUE)
testIsForegroundUserAdminUser_withAdditionalUser()332     public void testIsForegroundUserAdminUser_withAdditionalUser() {
333         UserReference additionalUserRef = additionalUser(sDeviceState);
334         final UserManager initialUm = mUserManager;
335         Context additionalUserContext;
336         try (PermissionContext p =
337                      TestApis.permissions().withPermission(INTERACT_ACROSS_USERS_FULL)) {
338             additionalUserContext = getContextForUser(additionalUserRef.id());
339         }
340         final UserManager additionalUm = additionalUserContext.getSystemService(UserManager.class);
341 
342         // The initial user is an admin, so we should get true (regardless of who is asking).
343         assertTrue(initialUm.isForegroundUserAdmin());
344         assertTrue(additionalUm.isForegroundUserAdmin());
345 
346         additionalUserRef.switchTo();
347 
348         // The additional user is most likely a non-admin, but just in case, let's be more general.
349         final boolean isAdditionalUserAdmin = additionalUserRef.isAdmin();
350         if (isAdditionalUserAdmin) {
351             Log.i(TAG, "WARNING: the additional user " + additionalUserRef.id() + " is admin");
352         }
353         assertThat(initialUm.isForegroundUserAdmin()).isEqualTo(isAdditionalUserAdmin);
354         assertThat(additionalUm.isForegroundUserAdmin()).isEqualTo(isAdditionalUserAdmin);
355     }
356 
357     @Test
358     @ApiTest(apis = {"android.os.UserManager#isUserRunning"})
359     @RequireRunOnInitialUser
360     @EnsureHasWorkProfile(installInstrumentedApp = TRUE)
361     @EnsureHasPermission(INTERACT_ACROSS_USERS) // needed to call isUserRunning()
testIsUserRunning_stoppedProfileOfCurrentUser()362     public void testIsUserRunning_stoppedProfileOfCurrentUser() {
363         UserReference profile = workProfile(sDeviceState);
364         Log.d(TAG, "Stopping profile " + profile + " (called from " + sContext.getUser() + ")");
365         profile.stop();
366 
367         Context context = getContextForUser(profile.userHandle().getIdentifier());
368         UserManager um = context.getSystemService(UserManager.class);
369 
370         assertWithMessage("isUserRunning() for stopped profile (id=%s) of current user",
371                 profile.id()).that(um.isUserRunning(profile.userHandle()))
372                 .isFalse();
373     }
374 
375     @Test
376     @ApiTest(apis = {"android.os.UserManager#isUserRunning"})
377     @EnsureHasAdditionalUser(switchedToUser = FALSE)
378     @EnsureHasPermission(INTERACT_ACROSS_USERS) // needed to call isUserRunning()
testIsUserRunning_stoppedSecondaryUser()379     public void testIsUserRunning_stoppedSecondaryUser() {
380         Log.d(TAG, "Stopping  user " + additionalUser(sDeviceState)
381                 + " (called from " + sContext.getUser() + ")");
382         additionalUser(sDeviceState).stop();
383 
384         UserManager um =
385                 TestApis.context().instrumentedContext().getSystemService(UserManager.class);
386 
387         assertWithMessage("isUserRunning() for stopped secondary user (id=%s)",
388                 additionalUser(sDeviceState).id())
389                 .that(um.isUserRunning(additionalUser(sDeviceState).userHandle())).isFalse();
390     }
391 
392     @Test
393     @EnsureHasNoWorkProfile
394     @ApiTest(apis = {"android.os.UserManager#createProfile",
395             "android.os.UserManager#getUserBadge"})
396     @EnsureHasPermission({CREATE_USERS, INTERACT_ACROSS_USERS})
testCloneProfile()397     public void testCloneProfile() throws Exception {
398         assumeTrue(mUserManager.supportsMultipleUsers());
399         UserHandle userHandle = null;
400 
401         // Need CREATE_USERS permission to create user in test
402         try {
403             try {
404                 userHandle = mUserManager.createProfile(
405                     "Clone profile", USER_TYPE_PROFILE_CLONE, new HashSet<>());
406             } catch (UserManager.UserOperationException e) {
407                 // Not all devices and user types support these profiles; skip if this one doesn't.
408                 assumeNoException("Couldn't create clone profile", e);
409                 return;
410             }
411             assertThat(userHandle).isNotNull();
412 
413             final Context userContext = sContext.createPackageContextAsUser("system", 0,
414                     userHandle);
415             final UserManager cloneUserManager = userContext.getSystemService(UserManager.class);
416             assertThat(cloneUserManager.isMediaSharedWithParent()).isTrue();
417             assertThat(cloneUserManager.isCredentialSharableWithParent()).isTrue();
418             assertThat(cloneUserManager.isCloneProfile()).isTrue();
419             assertThat(cloneUserManager.isProfile()).isTrue();
420             assertThat(cloneUserManager.isUserOfType(UserManager.USER_TYPE_PROFILE_CLONE)).isTrue();
421             assertThat(cloneUserManager.getUserBadge()).isNotNull();
422 
423             final List<UserInfo> list = mUserManager.getAliveUsers();
424             final UserHandle finalUserHandle = userHandle;
425             final List<UserInfo> cloneUsers = list.stream().filter(
426                     user -> (user.id == finalUserHandle.getIdentifier()
427                             && user.isCloneProfile()))
428                     .collect(Collectors.toList());
429             assertThat(cloneUsers.size()).isEqualTo(1);
430         } finally {
431             removeUser(userHandle);
432         }
433     }
434 
435     @Test
436     @ApiTest(apis = {"android.os.UserManager#isCommunalProfile"})
437     @RequiresFlagsEnabled(android.multiuser.Flags.FLAG_SUPPORT_COMMUNAL_PROFILE)
438     @RequireMultiUserSupport
439     @EnsureHasPermission({QUERY_USERS, CREATE_USERS, INTERACT_ACROSS_USERS})
testCommunalProfile()440     public void testCommunalProfile() throws Exception {
441         final UserHandle communalUser = mUserManager.getCommunalProfile();
442         // Not all devices will have a communal profile on it. If they don't, bypass the test.
443         assumeNotNull(communalUser);
444 
445         final UserManager umOfCommunal = sContext
446                 .createPackageContextAsUser("android", 0, communalUser)
447                 .getSystemService(UserManager.class);
448 
449         assertThat(umOfCommunal.isCommunalProfile()).isTrue();
450         assertThat(umOfCommunal.isProfile()).isTrue();
451         if (umOfCommunal.isUserRunning(communalUser)) {
452             // Communal Profile should always be visible (if it exists and is running).
453             assertThat(umOfCommunal.isUserVisible()).isTrue();
454         }
455 
456         // Make sure that there can be only one.
457         final List<UserInfo> communalUsers = mUserManager.getAliveUsers().stream()
458                 .filter(UserInfo::isCommunalProfile).toList();
459         assertThat(communalUsers.size()).isEqualTo(1);
460         assertThat(communalUsers.get(0).id).isEqualTo(communalUser.getIdentifier());
461     }
462 
463     @Test
464     @ApiTest(apis = {"android.os.UserManager#USER_TYPE_PROFILE_SUPERVISING"})
465     @RequiresFlagsEnabled(android.multiuser.Flags.FLAG_ALLOW_SUPERVISING_PROFILE)
466     @RequireMultiUserSupport
467     @EnsureHasPermission({QUERY_USERS, CREATE_USERS, INTERACT_ACROSS_USERS})
testSupervisingProfile()468     public void testSupervisingProfile() throws Exception {
469         UserInfo userInfo = null;
470         List<UserHandle> createdUsers = new ArrayList<>();
471 
472         List<UserInfo> supervisingUsers =
473                 mUserManager.getAliveUsers().stream()
474                         .filter(UserInfo::isSupervisingProfile)
475                         .toList();
476         // There can be a maximum of 1 supervising profile
477         assertThat(supervisingUsers.size()).isLessThan(2);
478         if (!supervisingUsers.isEmpty()) {
479             userInfo = supervisingUsers.getFirst();
480         }
481         try {
482             if (userInfo == null) {
483                 userInfo =
484                         mUserManager.createUser(
485                                 "Supervising profile", USER_TYPE_PROFILE_SUPERVISING, 0);
486                 // Bypass the test if the supervising profile is not supported.
487                 assumeNotNull(userInfo);
488                 createdUsers.add(userInfo.getUserHandle());
489             }
490             final Context userContext =
491                     sContext.createPackageContextAsUser("system", 0, userInfo.getUserHandle());
492             final UserManager umSupervising = userContext.getSystemService(UserManager.class);
493             assertThat(umSupervising.isProfile()).isTrue();
494             assertThat(umSupervising.isUserOfType(UserManager.USER_TYPE_PROFILE_SUPERVISING))
495                     .isTrue();
496 
497             // Ensure that a second supervising profile cannot be created
498             final UserInfo secondUser =
499                     mUserManager.createUser("Second supervising", USER_TYPE_PROFILE_SUPERVISING, 0);
500             if (secondUser != null) {
501                 createdUsers.add(secondUser.getUserHandle());
502             }
503             assertThat(secondUser).isNull();
504             supervisingUsers =
505                     mUserManager.getAliveUsers().stream()
506                             .filter(UserInfo::isSupervisingProfile)
507                             .toList();
508             assertThat(supervisingUsers.size()).isEqualTo(1);
509         } finally {
510             for (UserHandle userHandle : createdUsers) {
511                 removeUser(userHandle);
512             }
513         }
514     }
515 
516     @Test
517     @EnsureHasNoWorkProfile
518     @ApiTest(apis = {"android.os.UserManager#createProfile"})
519     @AppModeFull
520     @EnsureHasPermission(CREATE_USERS)
testAddCloneProfile_shouldSendProfileAddedBroadcast()521     public void testAddCloneProfile_shouldSendProfileAddedBroadcast() {
522         assumeTrue(mUserManager.supportsMultipleUsers());
523         BlockingBroadcastReceiver broadcastReceiver = sDeviceState
524                 .registerBroadcastReceiver(Intent.ACTION_PROFILE_ADDED, /* checker= */null);
525         UserHandle userHandle = null;
526             try {
527                 userHandle = mUserManager.createProfile("Clone profile",
528                         USER_TYPE_PROFILE_CLONE, new HashSet<>());
529                 assumeNotNull(userHandle);
530                 broadcastReceiver.awaitForBroadcastOrFail();
531             } catch (UserManager.UserOperationException e) {
532                 assumeNoException("Couldn't create clone profile", e);
533             } finally {
534                 removeUser(userHandle);
535             }
536     }
537 
538     @Test
539     @ApiTest(apis = {"android.os.UserManager#createProfile"})
540     @AppModeFull
541     @EnsureHasNoWorkProfile
542     @RequireFeature(FEATURE_MANAGED_USERS)
543     @EnsureHasPermission(CREATE_USERS)
testCreateManagedProfile_shouldSendProfileAddedBroadcast()544     public void testCreateManagedProfile_shouldSendProfileAddedBroadcast() {
545         BlockingBroadcastReceiver broadcastReceiver = sDeviceState
546                 .registerBroadcastReceiver(Intent.ACTION_PROFILE_ADDED, /* checker= */null);
547         UserHandle userHandle = null;
548             try {
549                 userHandle = mUserManager.createProfile("Managed profile",
550                         USER_TYPE_PROFILE_MANAGED, new HashSet<>());
551                 assumeNotNull(userHandle);
552                 broadcastReceiver.awaitForBroadcastOrFail();
553             } catch (UserManager.UserOperationException e) {
554                 assumeNoException("Couldn't create managed profile", e);
555             } finally {
556                 removeUser(userHandle);
557             }
558     }
559 
560     @Test
561     @EnsureHasNoWorkProfile
562     @ApiTest(apis = {"android.os.UserManager#createProfile"})
563     @AppModeFull
564     @EnsureHasPermission(CREATE_USERS)
testRemoveCloneProfile_shouldSendProfileRemovedBroadcast()565     public void testRemoveCloneProfile_shouldSendProfileRemovedBroadcast() {
566         assumeTrue(mUserManager.supportsMultipleUsers());
567         BlockingBroadcastReceiver broadcastReceiver = null;
568         final ArrayDeque<UserHandle> usersCreated = new ArrayDeque<>();
569         UserHandle userHandle;
570         try {
571             userHandle = mUserManager.createProfile("Clone profile",
572                     USER_TYPE_PROFILE_CLONE, new HashSet<>());
573             usersCreated.push(userHandle);
574             broadcastReceiver = sDeviceState
575                     .registerBroadcastReceiver(
576                             Intent.ACTION_PROFILE_REMOVED, userIsEqual(userHandle)
577                     );
578             assumeNotNull(userHandle);
579             removeUser(usersCreated.pop());
580             broadcastReceiver.awaitForBroadcastOrFail();
581         } catch (UserManager.UserOperationException e) {
582             assumeNoException("Couldn't create clone profile", e);
583         } finally {
584             usersCreated.forEach(this::removeUser);
585         }
586     }
587 
588     @Test
589     @ApiTest(apis = {"android.os.UserManager#createProfile"})
590     @AppModeFull
591     @EnsureHasNoWorkProfile
592     @RequireFeature(FEATURE_MANAGED_USERS)
593     @EnsureHasPermission(CREATE_USERS)
testRemoveManagedProfile_shouldSendProfileRemovedBroadcast()594     public void testRemoveManagedProfile_shouldSendProfileRemovedBroadcast() {
595         BlockingBroadcastReceiver broadcastReceiver = null;
596         UserHandle userHandle;
597         final ArrayDeque<UserHandle> usersCreated = new ArrayDeque<>();
598         try {
599             userHandle = mUserManager.createProfile("Managed profile",
600                     USER_TYPE_PROFILE_MANAGED, new HashSet<>());
601             usersCreated.push(userHandle);
602             broadcastReceiver = sDeviceState
603                     .registerBroadcastReceiver(
604                             Intent.ACTION_PROFILE_REMOVED, userIsEqual(userHandle)
605                     );
606             assumeNotNull(userHandle);
607             removeUser(usersCreated.pop());
608             broadcastReceiver.awaitForBroadcastOrFail();
609         } catch (UserManager.UserOperationException e) {
610             assumeNoException("Couldn't create managed profile", e);
611         } finally {
612             usersCreated.forEach(this::removeUser);
613         }
614     }
615 
616     @Test
617     @AppModeFull
618     @RequireFeature(FEATURE_MANAGED_USERS)
619     @EnsureHasNoWorkProfile
620     @EnsureHasPermission({CREATE_USERS, QUERY_USERS, INTERACT_ACROSS_USERS})
621     @ApiTest(apis = {
622             "android.os.UserManager#createProfile",
623             "android.os.UserManager#isManagedProfile",
624             "android.os.UserManager#isProfile",
625             "android.os.UserManager#isUserOfType",
626             "android.os.UserManager#getUserBadge"})
testManagedProfile()627     public void testManagedProfile() throws Exception {
628         UserHandle userHandle = null;
629 
630         try {
631             try {
632                 userHandle = mUserManager.createProfile(
633                         "Managed profile", UserManager.USER_TYPE_PROFILE_MANAGED, new HashSet<>());
634             } catch (UserManager.UserOperationException e) {
635                 // Not all devices and user types support these profiles; skip if this one doesn't.
636                 assumeNoException("Couldn't create managed profile", e);
637                 return;
638             }
639             assertThat(userHandle).isNotNull();
640 
641             final UserManager umOfProfile = sContext
642                     .createPackageContextAsUser("android", 0, userHandle)
643                     .getSystemService(UserManager.class);
644 
645             assertThat(umOfProfile.isManagedProfile()).isTrue();
646             assertThat(umOfProfile.isManagedProfile(userHandle.getIdentifier())).isTrue();
647             assertThat(umOfProfile.isProfile()).isTrue();
648             assertThat(umOfProfile.isUserOfType(UserManager.USER_TYPE_PROFILE_MANAGED)).isTrue();
649             assertThat(umOfProfile.getUserBadge()).isNotNull();
650         } finally {
651             removeUser(userHandle);
652         }
653     }
654 
655     @Test
656     @RequirePrivateSpaceSupported
657     @EnsureHasPermission({CREATE_USERS, QUERY_USERS, INTERACT_ACROSS_USERS})
658     @RequireRunOnInitialUser
659     @ApiTest(apis = {
660             "android.os.UserManager#createProfile",
661             "android.os.UserManager#isPrivateProfile",
662             "android.os.UserManager#isProfile",
663             "android.os.UserManager#isUserOfType",
664             "android.os.UserManager#getUserBadge"})
665     @RequiresFlagsEnabled({android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
666             android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES})
testPrivateProfile()667     public void testPrivateProfile() throws Exception {
668         UserHandle userHandle = null;
669 
670         try {
671             try {
672                 userHandle = mUserManager.createProfile(
673                     "Private profile", UserManager.USER_TYPE_PROFILE_PRIVATE, new HashSet<>());
674             } catch (UserManager.UserOperationException e) {
675                 // Not all devices and user types support these profiles; skip if this one doesn't.
676                 assumeNoException("Couldn't create private profile", e);
677                 return;
678             }
679             assertThat(userHandle).isNotNull();
680 
681             final UserManager umOfProfile = sContext
682                     .createPackageContextAsUser("android", 0, userHandle)
683                     .getSystemService(UserManager.class);
684 
685             assertThat(umOfProfile.isPrivateProfile()).isTrue();
686             assertThat(umOfProfile.isProfile()).isTrue();
687             assertThat(umOfProfile.isUserOfType(UserManager.USER_TYPE_PROFILE_PRIVATE)).isTrue();
688             final List<UserInfo> list = mUserManager.getAliveUsers();
689             final UserHandle finalUserHandle = userHandle;
690             final List<UserInfo> privateUsers = list.stream().filter(
691                     user -> (user.id == finalUserHandle.getIdentifier()
692                             && user.isPrivateProfile()))
693                     .collect(Collectors.toList());
694             assertThat(privateUsers.size()).isEqualTo(1);
695             assertThat(umOfProfile.getUserBadge()).isNotNull();
696         } finally {
697             removeUser(userHandle);
698         }
699     }
700 
701     @Test
702     @RequireHeadlessSystemUserMode(reason = "Secondary user profile is only available on headless")
703     @ApiTest(apis = {"android.os.UserManager#removeUser"})
704     @EnsureHasAdditionalUser
705     @RequireRunOnInitialUser
706     @EnsureHasWorkProfile(forUser = ADDITIONAL_USER)
707     @EnsureHasPermission(CREATE_USERS)
testRemoveParentUser_withProfiles()708     public void testRemoveParentUser_withProfiles() {
709         UserReference workProfile = workProfile(sDeviceState, /* forUser= */ ADDITIONAL_USER);
710         UserReference parentUser = workProfile.parent();
711         parentUser.remove();
712 
713         // Removing parent user will also remove its profile
714         assertThat(parentUser.exists()).isFalse();
715         assertThat(workProfile.exists()).isFalse();
716     }
717 
718     @Test
719     @RequireHeadlessSystemUserMode(reason = "Secondary user profile is only available on headless")
720     @ApiTest(apis = {"android.os.UserManager#removeUser"})
721     @EnsureHasAdditionalUser
722     @RequireRunOnInitialUser
723     @EnsureHasWorkProfile(forUser = ADDITIONAL_USER)
724     @EnsureHasPermission(CREATE_USERS)
testRemoveUserOnlyProfile_ShouldNotRemoveAnyOtherUserInSameProfileGroupId()725     public void testRemoveUserOnlyProfile_ShouldNotRemoveAnyOtherUserInSameProfileGroupId() {
726         UserHandle parentUser = null;
727 
728         try {
729             UserReference workProfile = workProfile(sDeviceState, /* forUser= */ ADDITIONAL_USER);
730             parentUser = workProfile.parent().userHandle();
731             UserHandle workProfileUser = workProfile.userHandle();
732 
733             try (BlockingBroadcastReceiver receiver = BlockingBroadcastReceiver.create(sContext,
734                     Intent.ACTION_USER_REMOVED, userIsEqual(workProfileUser)).register()) {
735                 removeUser(workProfileUser);
736             }
737 
738             //Removing a profile will only remove the profile and not the parent user
739             assertThat(hasUser(workProfileUser.getIdentifier())).isFalse();
740             assertThat(hasUser(parentUser.getIdentifier())).isTrue();
741         } finally {
742             removeUser(parentUser);
743         }
744     }
745 
746     @Test
747     @RequireHeadlessSystemUserMode(reason = "only headless can have main user as permanent admin.")
748     @ApiTest(apis = {"android.os.UserManager#removeUserWhenPossible"})
749     @EnsureHasAdditionalUser
750     @EnsureHasPermission({CREATE_USERS})
testRemoveMainUser_shouldNotRemoveMainUser()751     public void testRemoveMainUser_shouldNotRemoveMainUser() {
752         assumeTrue("Main user is not permanent admin.", isMainUserPermanentAdmin());
753         UserReference initialUser = sDeviceState.initialUser();
754         UserReference additionalUser = additionalUser(sDeviceState);
755         if (TestApis.users().current() != additionalUser) {
756             additionalUser.switchTo();
757         }
758 
759         assertThat(mUserManager.removeUserWhenPossible(initialUser.userHandle(), false))
760                 .isEqualTo(UserManager.REMOVE_RESULT_ERROR_MAIN_USER_PERMANENT_ADMIN);
761 
762         // Initial/main user should not be removed.
763         assertThat(hasUser(initialUser.id())).isTrue();
764     }
765 
766     @Test
767     @EnsureHasPermission({QUERY_USERS})
768     @ApiTest(apis = {
769             "android.os.UserManager#isSystemUser",
770             "android.os.UserManager#isUserOfType",
771             "android.os.UserManager#isProfile",
772             "android.os.UserManager#isManagedProfile",
773             "android.os.UserManager#isCloneProfile"})
testSystemUser()774     public void testSystemUser() throws Exception {
775         final UserManager umOfSys = sContext
776                 .createPackageContextAsUser("android", 0, UserHandle.SYSTEM)
777                 .getSystemService(UserManager.class);
778 
779         assertThat(umOfSys.isSystemUser()).isTrue();
780         // We cannot demand what type of user SYSTEM is, but we can say some things it isn't.
781         assertThat(umOfSys.isUserOfType(UserManager.USER_TYPE_PROFILE_CLONE)).isFalse();
782         assertThat(umOfSys.isUserOfType(UserManager.USER_TYPE_PROFILE_MANAGED)).isFalse();
783         assertThat(umOfSys.isUserOfType(UserManager.USER_TYPE_FULL_GUEST)).isFalse();
784 
785         assertThat(umOfSys.isProfile()).isFalse();
786         assertThat(umOfSys.isManagedProfile()).isFalse();
787         assertThat(umOfSys.isManagedProfile(UserHandle.USER_SYSTEM)).isFalse();
788         assertThat(umOfSys.isCloneProfile()).isFalse();
789         if (android.multiuser.Flags.supportCommunalProfile()) {
790             assertThat(umOfSys.isCommunalProfile()).isFalse();
791         }
792         if (android.os.Flags.allowPrivateProfile()
793                 && android.multiuser.Flags.enablePrivateSpaceFeatures()) {
794             assertThat(umOfSys.isPrivateProfile()).isFalse();
795         }
796     }
797 
798     @Test
799     @EnsureHasNoWorkProfile
800     @SystemUserOnly(reason = "Restricted users are only supported on system user.")
801     @ApiTest(apis = {
802             "android.os.UserManager#isRestrictedProfile",
803             "android.os.UserManager#getRestrictedProfileParent",
804             "android.os.UserManager#createRestrictedProfile"})
805     @EnsureHasPermission(CREATE_USERS)
testRestrictedUser()806     public void testRestrictedUser() throws Exception {
807         UserHandle user = null;
808         try {
809             // Check that the SYSTEM user is not restricted.
810             assertThat(mUserManager.isRestrictedProfile()).isFalse();
811             assertThat(mUserManager.isRestrictedProfile(UserHandle.SYSTEM)).isFalse();
812             assertThat(mUserManager.getRestrictedProfileParent()).isNull();
813 
814             final UserInfo info = mUserManager.createRestrictedProfile("Restricted user");
815 
816             // If the device supports Restricted users, it must report it correctly.
817             assumeTrue("Couldn't create a restricted profile", info != null);
818 
819             user = UserHandle.of(info.id);
820             assertThat(mUserManager.isRestrictedProfile(user)).isTrue();
821 
822             final Context userContext = sContext.createPackageContextAsUser("system", 0, user);
823             final UserManager userUm = userContext.getSystemService(UserManager.class);
824 
825             assertThat(userUm.isRestrictedProfile()).isTrue();
826             assertThat(userUm.getRestrictedProfileParent().isSystem()).isTrue();
827         } finally {
828             removeUser(user);
829         }
830     }
831 
newUserRequest()832     private NewUserRequest newUserRequest() {
833         final PersistableBundle accountOptions = new PersistableBundle();
834         accountOptions.putString("test_account_option_key", "test_account_option_value");
835 
836         return new NewUserRequest.Builder()
837                 .setName("test_user")
838                 .setUserType(USER_TYPE_FULL_SECONDARY)
839                 .setUserIcon(Bitmap.createBitmap(32, 32, Bitmap.Config.RGB_565))
840                 .setAccountName(mAccountName)
841                 .setAccountType(mAccountType)
842                 .setAccountOptions(accountOptions)
843                 .build();
844     }
845 
846     @Test
847     @EnsureHasPermission(CREATE_USERS)
848     @EnsureHasNoAdditionalUser
849     @EnsureCanAddUser
850     @EnsureHasNoAccounts
testSomeUserHasAccount()851     public void testSomeUserHasAccount() {
852         // TODO: (b/233197356): Replace with bedstead annotation.
853         assumeTrue(mUserManager.supportsMultipleUsers());
854         UserHandle user = null;
855 
856         try {
857             assertThat(mUserManager.someUserHasAccount(mAccountName, mAccountType)).isFalse();
858             user = mUserManager.createUser(newUserRequest()).getUser();
859             assertThat(mUserManager.someUserHasAccount(mAccountName, mAccountType)).isTrue();
860         } finally {
861             removeUser(user);
862         }
863     }
864 
865     @Test
866     @EnsureHasPermission(CREATE_USERS)
867     @EnsureHasNoAdditionalUser
868     @EnsureCanAddUser
869     @EnsureHasNoAccounts
testSomeUserHasAccount_shouldIgnoreToBeRemovedUsers()870     public void testSomeUserHasAccount_shouldIgnoreToBeRemovedUsers() {
871         // TODO: (b/233197356): Replace with bedstead annotation.
872         assumeTrue(mUserManager.supportsMultipleUsers());
873         final ArrayDeque<UserHandle> usersCreated = new ArrayDeque<>();
874         try {
875             final NewUserResponse response = mUserManager.createUser(newUserRequest());
876             usersCreated.push(response.getUser());
877             assertThat(response.getOperationResult()).isEqualTo(USER_OPERATION_SUCCESS);
878             mUserManager.removeUser(usersCreated.pop());
879             assertThat(mUserManager.someUserHasAccount(mAccountName, mAccountType)).isFalse();
880         } finally {
881             usersCreated.forEach(this::removeUser);
882         }
883     }
884 
885     @Test
886     @ApiTest(apis = {
887             "android.os.UserManager#supportsMultipleUsers",
888             "android.os.UserManager#createUser",
889             "android.os.UserManager#getUserName",
890             "android.os.UserManager#isUserNameSet",
891             "android.os.UserManager#getUserType",
892             "android.os.UserManager#isUserOfType"})
893     @EnsureHasPermission(CREATE_USERS)
894     @EnsureHasNoAdditionalUser
895     @EnsureCanAddUser
896     @EnsureHasNoAccounts
testCreateUser_withNewUserRequest_shouldCreateUserWithCorrectProperties()897     public void testCreateUser_withNewUserRequest_shouldCreateUserWithCorrectProperties()
898             throws PackageManager.NameNotFoundException {
899         // TODO: (b/233197356): Replace with bedstead annotation.
900         assumeTrue(mUserManager.supportsMultipleUsers());
901         UserHandle user = null;
902 
903         try {
904             final NewUserRequest request = newUserRequest();
905             final NewUserResponse response = mUserManager.createUser(request);
906             user = response.getUser();
907 
908             assertThat(response.getOperationResult()).isEqualTo(USER_OPERATION_SUCCESS);
909             assertThat(response.isSuccessful()).isTrue();
910             assertThat(user).isNotNull();
911 
912             UserManager userManagerOfNewUser = sContext
913                     .createPackageContextAsUser("android", 0, user)
914                     .getSystemService(UserManager.class);
915 
916             assertThat(userManagerOfNewUser.getUserName()).isEqualTo(request.getName());
917             assertThat(userManagerOfNewUser.isUserNameSet()).isTrue();
918             assertThat(userManagerOfNewUser.getUserType()).isEqualTo(request.getUserType());
919             assertThat(userManagerOfNewUser.isUserOfType(request.getUserType())).isEqualTo(true);
920             // We can not test userIcon and accountOptions,
921             // because getters require MANAGE_USERS permission.
922             // And we are already testing accountName and accountType
923             // are set correctly in testSomeUserHasAccount method.
924         } finally {
925             removeUser(user);
926         }
927     }
928 
929     @Test
930     @EnsureHasPermission(CREATE_USERS)
931     @EnsureHasNoAdditionalUser
932     @EnsureCanAddUser
933     @EnsureHasNoAccounts
testCreateUser_withNewUserRequest_shouldNotAllowDuplicateUserAccounts()934     public void testCreateUser_withNewUserRequest_shouldNotAllowDuplicateUserAccounts() {
935         // TODO: (b/233197356): Replace with bedstead annotation.
936         assumeTrue(mUserManager.supportsMultipleUsers());
937         UserHandle user1 = null;
938         UserHandle user2 = null;
939 
940         try {
941             final NewUserResponse response1 = mUserManager.createUser(newUserRequest());
942             user1 = response1.getUser();
943 
944             assertThat(response1.getOperationResult()).isEqualTo(USER_OPERATION_SUCCESS);
945             assertThat(response1.isSuccessful()).isTrue();
946             assertThat(user1).isNotNull();
947 
948             final NewUserResponse response2 = mUserManager.createUser(newUserRequest());
949             user2 = response2.getUser();
950 
951             assertThat(response2.getOperationResult()).isEqualTo(
952                     UserManager.USER_OPERATION_ERROR_USER_ACCOUNT_ALREADY_EXISTS);
953             assertThat(response2.isSuccessful()).isFalse();
954             assertThat(user2).isNull();
955         } finally {
956             removeUser(user1);
957             removeUser(user2);
958         }
959     }
960 
961     @Test
962     @AppModeFull
963     @EnsureHasWorkProfile // TODO(b/239961027): should also check for other profiles
964     @EnsureHasPermission(INTERACT_ACROSS_USERS)
getProfileParent_returnsParent()965     public void getProfileParent_returnsParent() {
966         final UserReference parent = TestApis.users().instrumented();
967         for (UserHandle profile : mUserManager.getUserProfiles()) {
968             if (!profile.equals(parent.userHandle())) {
969                 assertThat(mUserManager.getProfileParent(profile)).isEqualTo(parent.userHandle());
970             }
971         }
972     }
973 
974     @Test
975     @AppModeFull
976     @EnsureHasPermission(INTERACT_ACROSS_USERS)
getProfileParent_returnsNullForNonProfile()977     public void getProfileParent_returnsNullForNonProfile() {
978         assertThat(mUserManager.getProfileParent(TestApis.users().system().userHandle())).isNull();
979     }
980 
981     @Test
982     @EnsureHasPermission({CREATE_USERS, QUERY_USERS})
testGetRemainingCreatableUserCount()983     public void testGetRemainingCreatableUserCount() {
984         final int maxAllowedIterations = 15;
985         final String userType = USER_TYPE_FULL_SECONDARY;
986         final NewUserRequest request = new NewUserRequest.Builder().build();
987         final ArrayDeque<UserHandle> usersCreated = new ArrayDeque<>();
988 
989         try {
990             final int initialRemainingCount = mUserManager.getRemainingCreatableUserCount(userType);
991             assertThat(initialRemainingCount).isAtLeast(0);
992 
993             final int numUsersToAdd = Math.min(maxAllowedIterations, initialRemainingCount);
994 
995             for (int i = 0; i < numUsersToAdd; i++) {
996                 usersCreated.push(mUserManager.createUser(request).getUser());
997                 assertThat(mUserManager.getRemainingCreatableUserCount(userType))
998                         .isEqualTo(initialRemainingCount - usersCreated.size());
999             }
1000             for (int i = 0; i < numUsersToAdd; i++) {
1001                 mUserManager.removeUser(usersCreated.pop());
1002                 assertThat(mUserManager.getRemainingCreatableUserCount(userType))
1003                         .isEqualTo(initialRemainingCount - usersCreated.size());
1004             }
1005         } finally {
1006             usersCreated.forEach(this::removeUser);
1007         }
1008     }
1009 
1010     @Test
1011     @EnsureHasPermission({CREATE_USERS, QUERY_USERS})
testGetRemainingCreatableProfileCount()1012     public void testGetRemainingCreatableProfileCount() {
1013         final int maxAllowedIterations = 15;
1014         final String type = USER_TYPE_PROFILE_MANAGED;
1015         final ArrayDeque<UserHandle> profilesCreated = new ArrayDeque<>();
1016         final Set<String> disallowedPackages = new HashSet<>();
1017         try {
1018             final int initialRemainingCount =
1019                     mUserManager.getRemainingCreatableProfileCount(type);
1020             assertThat(initialRemainingCount).isAtLeast(0);
1021 
1022             final int numUsersToAdd = Math.min(maxAllowedIterations, initialRemainingCount);
1023 
1024             for (int i = 0; i < numUsersToAdd; i++) {
1025                 profilesCreated.push(mUserManager.createProfile(null, type, disallowedPackages));
1026                 assertThat(mUserManager.getRemainingCreatableProfileCount(type))
1027                         .isEqualTo(initialRemainingCount - profilesCreated.size());
1028             }
1029             for (int i = 0; i < numUsersToAdd; i++) {
1030                 mUserManager.removeUser(profilesCreated.pop());
1031                 assertThat(mUserManager.getRemainingCreatableProfileCount(type))
1032                         .isEqualTo(initialRemainingCount - profilesCreated.size());
1033             }
1034         } catch (UserManager.UserOperationException e) {
1035             // Not all devices and user types support these profiles; skip if this one doesn't.
1036             assumeNoException("Couldn't create managed profile", e);
1037             return;
1038         } finally {
1039             profilesCreated.forEach(this::removeUser);
1040         }
1041     }
1042 
1043     @Test
1044     @ApiTest(apis = {"android.os.UserManager#getUserProperties"})
1045     @AppModeFull
1046     @EnsureHasPermission({CREATE_USERS, QUERY_USERS})
testGetUserProperties_system()1047     public void testGetUserProperties_system() {
1048         final UserHandle fullUser = TestApis.users().instrumented().userHandle();
1049         final UserProperties properties = mUserManager.getUserProperties(fullUser);
1050         assertThat(properties).isNotNull();
1051 
1052         assertThat(properties.getShowInLauncher()).isIn(Arrays.asList(
1053                 UserProperties.SHOW_IN_LAUNCHER_WITH_PARENT));
1054         assertThat(properties.isMediaSharedWithParent()).isFalse();
1055         assertThat(properties.isCredentialShareableWithParent()).isFalse();
1056     }
1057 
1058     @Test
1059     @ApiTest(apis = {"android.os.UserManager#getUserProperties"})
1060     @AppModeFull
1061     @EnsureHasWorkProfile
1062     @RequireFeature(FEATURE_MANAGED_USERS)
1063     @EnsureHasPermission({CREATE_USERS, QUERY_USERS})
testGetUserProperties_managedProfile()1064     public void testGetUserProperties_managedProfile() {
1065         final UserHandle profile = workProfile(sDeviceState).userHandle();
1066         final UserProperties properties = mUserManager.getUserProperties(profile);
1067         assertThat(properties).isNotNull();
1068 
1069         assertThat(properties.getShowInLauncher()).isIn(Arrays.asList(
1070                 UserProperties.SHOW_IN_LAUNCHER_WITH_PARENT,
1071                 UserProperties.SHOW_IN_LAUNCHER_SEPARATE));
1072     }
1073 
1074     @Test
1075     @ApiTest(apis = {"android.os.UserManager#isMainUser"})
1076     @EnsureHasWorkProfile(installInstrumentedApp = TRUE)
1077     @EnsureHasAdditionalUser(installInstrumentedApp = TRUE)
1078     @EnsureHasPermission({CREATE_USERS, INTERACT_ACROSS_USERS})
testIsMainUser_trueForAtMostOneUser()1079     public void testIsMainUser_trueForAtMostOneUser() {
1080         final List<UserHandle> userHandles = mUserManager.getUserHandles(false);
1081         final List<UserHandle> mainUsers = new ArrayList<>();
1082 
1083         for (UserHandle user : userHandles) {
1084             //Install instrumented test app on the user
1085             TestApis.packages().instrumented().installExisting(UserReference.of(user));
1086             final Context userContext = getContextForUser(user.getIdentifier());
1087             final UserManager userManager = userContext.getSystemService(UserManager.class);
1088             if (userManager.isMainUser()) {
1089                 mainUsers.add(user);
1090             }
1091         }
1092         assertWithMessage("main users (%s)", mainUsers).that(mainUsers.size()).isEqualTo(1);
1093     }
1094 
1095     @Test
1096     @ApiTest(apis = {"android.os.UserManager#getMainUser", "android.os.UserManager#isMainUser"})
1097     @EnsureHasWorkProfile(installInstrumentedApp = TRUE)
1098     @EnsureHasAdditionalUser(installInstrumentedApp = TRUE)
1099     @EnsureHasPermission({QUERY_USERS, INTERACT_ACROSS_USERS})
testGetMainUser_returnsMainUser()1100     public void testGetMainUser_returnsMainUser() {
1101         final UserHandle mainUser = mUserManager.getMainUser();
1102         if (mainUser != null) {
1103             final Context mainUserContext = getContextForUser(mainUser.getIdentifier());
1104             final UserManager mainUserManager = mainUserContext.getSystemService(UserManager.class);
1105             assertThat(mainUserManager.isMainUser()).isTrue();
1106         }
1107     }
1108 
1109     @Test
1110     @ApiTest(apis = {"android.os.UserManager#getPreviousForegroundUser"})
1111     @RequireRunOnInitialUser
1112     @EnsureHasNoAdditionalUser
1113     @EnsureHasPermission({QUERY_USERS})
testGetPreviousForegroundUser_noAdditionalUser()1114     public void testGetPreviousForegroundUser_noAdditionalUser() {
1115         assertWithMessage("getPreviousUser() with no additional user")
1116                 .that(mUserManager.getPreviousForegroundUser()).isNull();
1117     }
1118 
1119     @Test
1120     @ApiTest(apis = {"android.os.UserManager#getPreviousForegroundUser"})
1121     @RequireRunOnInitialUser
1122     @EnsureHasNoAdditionalUser
1123     @EnsureHasWorkProfile
1124     @EnsureHasPermission({QUERY_USERS})
testGetPreviousForegroundUser_withWorkProfileButNoAdditionalUser()1125     public void testGetPreviousForegroundUser_withWorkProfileButNoAdditionalUser() {
1126         assertWithMessage("getPreviousForegroundUser() with work profile but no additional user")
1127                 .that(mUserManager.getPreviousForegroundUser()).isNull();
1128     }
1129 
1130     @Test
1131     @ApiTest(apis = {"android.os.UserManager#getPreviousForegroundUser"})
1132     @EnsureHasAdditionalUser
1133     @EnsureHasPermission({QUERY_USERS})
testGetPreviousForegroundUser_switchingBetweenInitialAndAdditional()1134     public void testGetPreviousForegroundUser_switchingBetweenInitialAndAdditional() {
1135         UserReference initialUser = sDeviceState.initialUser();
1136         UserReference additionalUser = additionalUser(sDeviceState);
1137 
1138         if (TestApis.users().current() != initialUser) {
1139             initialUser.switchTo();
1140         }
1141 
1142         additionalUser.switchTo();
1143         assertThat(mUserManager.getPreviousForegroundUser()).isEqualTo(initialUser.userHandle());
1144         initialUser.switchTo();
1145         assertThat(mUserManager.getPreviousForegroundUser()).isEqualTo(additionalUser.userHandle());
1146     }
1147 
1148     @Test
1149     @ApiTest(apis = {"android.os.UserManager#setBootUser"})
1150     @EnsureHasAdditionalUser
1151     @EnsureHasPermission({CREATE_USERS})
setBootUser_providedUserIsSwitchable()1152     public void setBootUser_providedUserIsSwitchable() {
1153         UserReference additionalUser = additionalUser(sDeviceState);
1154         mUserManager.setBootUser(additionalUser.userHandle());
1155 
1156         assertThat(mUserManager.getBootUser()).isEqualTo(additionalUser.userHandle());
1157     }
1158 
1159     @Test
1160     @ApiTest(apis = {"android.os.UserManager#setBootUser"})
1161     @EnsureHasWorkProfile
1162     @EnsureHasAdditionalUser
1163     @EnsureHasPermission({CREATE_USERS})
1164     @RequireNotHeadlessSystemUserMode(reason = "Testing non-HSUM scenario")
setBootUser_providedUserIsNotSwitchable_nonHsum()1165     public void setBootUser_providedUserIsNotSwitchable_nonHsum() {
1166         UserReference additionalUser = additionalUser(sDeviceState);
1167         UserReference workProfile = workProfile(sDeviceState);
1168         mUserManager.setBootUser(workProfile.userHandle());
1169 
1170         // Switch to additional user to make sure there is a previous user that is not the
1171         // current user.
1172         additionalUser.switchTo();
1173 
1174         // Boot user will be the system user
1175         assertThat(mUserManager.getBootUser())
1176                 .isEqualTo(sDeviceState.primaryUser().userHandle());
1177     }
1178 
1179     @Test
1180     @ApiTest(apis = {"android.os.UserManager#setBootUser"})
1181     @EnsureHasWorkProfile
1182     @EnsureHasAdditionalUser
1183     @EnsureHasPermission({CREATE_USERS})
1184     @RequireHeadlessSystemUserMode(reason = "Testing HSUM scenario")
1185     @RequireResourcesIntegerValue(configName = "config_hsumBootStrategy", requiredValue = 0)
setBootUser_providedUserIsNotSwitchable_Hsum()1186     public void setBootUser_providedUserIsNotSwitchable_Hsum() {
1187         UserReference additionalUser = additionalUser(sDeviceState);
1188         UserReference workProfile = workProfile(sDeviceState);
1189         mUserManager.setBootUser(workProfile.userHandle());
1190 
1191         // Switch to additional user to make sure there is a previous user that is not the
1192         // current user.
1193         additionalUser.switchTo();
1194 
1195         // Boot user will be most recent user
1196         assertThat(mUserManager.getBootUser())
1197                 .isEqualTo(mUserManager.getPreviousForegroundUser());
1198     }
1199 
1200     @Test
1201     @EnsureHasAdditionalUser(switchedToUser = FALSE)
1202     @EnsurePasswordNotSet(forUser = ANY)
testSwitchFromNonCredentialToCredentialUser()1203     public void testSwitchFromNonCredentialToCredentialUser() {
1204         assumeTvNotSupported();
1205 
1206         UserReference initialUser = sDeviceState.initialUser();
1207         UserReference additionalUser = additionalUser(sDeviceState);
1208 
1209         initialUser.setScreenLockDisabled(true);
1210         additionalUser.setPassword("1234");
1211 
1212         // This will crash the system if the keyguard is not shown in 20 seconds.
1213         additionalUser.switchTo();
1214     }
1215 
1216     @Test
1217     @EnsureHasPrivateProfile
1218     @EnsureHasPermission({MODIFY_QUIET_MODE})
1219     @AppModeFull
1220     @RequiresFlagsEnabled({android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
1221             android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES})
testRequestQuietModeOnPrivateProfile_shouldSendProfileUnavailableBroadcast()1222     public void testRequestQuietModeOnPrivateProfile_shouldSendProfileUnavailableBroadcast() {
1223         final UserHandle profileHandle = privateProfile(sDeviceState).userHandle();
1224         presetQuietModeStatus(false, profileHandle);
1225         BlockingBroadcastReceiver broadcastReceiver = sDeviceState
1226                 .registerBroadcastReceiver(Intent.ACTION_PROFILE_UNAVAILABLE, /* checker= */null);
1227         mUserManager.requestQuietModeEnabled(true, profileHandle);
1228         broadcastReceiver.awaitForBroadcastOrFail();
1229     }
1230 
1231     @Test
1232     @EnsureHasPrivateProfile
1233     @EnsureHasPermission({MODIFY_QUIET_MODE})
1234     @AppModeFull
1235     @RequiresFlagsEnabled({android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
1236             android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES})
testRequestQuietModeOnPrivateProfile_disableQuietMode_needUserCredentials()1237     public void testRequestQuietModeOnPrivateProfile_disableQuietMode_needUserCredentials() {
1238         UserReference privateProfile = privateProfile(sDeviceState);
1239         final UserHandle profileHandle = privateProfile.userHandle();
1240         privateProfile.setSetupComplete(true);
1241         presetQuietModeStatus(true, profileHandle);
1242         assertThat(mUserManager.requestQuietModeEnabled(false, profileHandle))
1243                 .isFalse();
1244     }
1245 
1246     @Test
1247     @EnsureHasWorkProfile
1248     @EnsureHasPermission({MODIFY_QUIET_MODE})
1249     @RequiresFlagsEnabled({android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
1250             android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES})
testRequestQuietModeOnManaged_shouldSendProfileUnavailableBroadcast()1251     public void testRequestQuietModeOnManaged_shouldSendProfileUnavailableBroadcast() {
1252         final UserHandle profileHandle = workProfile(sDeviceState).userHandle();
1253         presetQuietModeStatus(false, profileHandle);
1254         BlockingBroadcastReceiver broadcastReceiver = sDeviceState
1255                 .registerBroadcastReceiver(Intent.ACTION_PROFILE_UNAVAILABLE, /* checker= */
1256                         null);
1257         mUserManager.requestQuietModeEnabled(true, profileHandle);
1258         broadcastReceiver.awaitForBroadcastOrFail();
1259     }
1260 
1261     @Test
1262     @EnsureHasWorkProfile
1263     @EnsureHasPermission({MODIFY_QUIET_MODE})
1264     @RequiresFlagsEnabled({android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
1265             android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES})
testRequestQuietModeOnManaged_shouldSendProfileAvailableBroadcast()1266     public void testRequestQuietModeOnManaged_shouldSendProfileAvailableBroadcast() {
1267         final UserHandle profileHandle = workProfile(sDeviceState).userHandle();
1268         presetQuietModeStatus(true, profileHandle);
1269         BlockingBroadcastReceiver broadcastReceiver = sDeviceState
1270                 .registerBroadcastReceiver(Intent.ACTION_PROFILE_AVAILABLE, /* checker= */
1271                         null);
1272         mUserManager.requestQuietModeEnabled(false, profileHandle);
1273         broadcastReceiver.awaitForBroadcastOrFail();
1274     }
1275 
1276     @Test
1277     @EnsureHasWorkProfile
1278     @EnsureHasPermission({MODIFY_QUIET_MODE})
testRequestQuietModeOnManaged_shouldSendManagedProfileUnavailableBroadcast()1279     public void testRequestQuietModeOnManaged_shouldSendManagedProfileUnavailableBroadcast() {
1280         final UserHandle profileHandle = workProfile(sDeviceState).userHandle();
1281         presetQuietModeStatus(false, profileHandle);
1282         BlockingBroadcastReceiver broadcastReceiver = sDeviceState
1283                 .registerBroadcastReceiver(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE, /* checker= */
1284                         null);
1285         mUserManager.requestQuietModeEnabled(true, profileHandle);
1286         broadcastReceiver.awaitForBroadcastOrFail();
1287     }
1288 
1289     @Test
1290     @EnsureHasWorkProfile
1291     @EnsureHasPermission({MODIFY_QUIET_MODE})
testRequestQuietModeOnManaged_shouldSendManagedProfileAvailableBroadcast()1292     public void testRequestQuietModeOnManaged_shouldSendManagedProfileAvailableBroadcast() {
1293         final UserHandle profileHandle = workProfile(sDeviceState).userHandle();
1294         presetQuietModeStatus(true, profileHandle);
1295         BlockingBroadcastReceiver broadcastReceiver = sDeviceState
1296                 .registerBroadcastReceiver(Intent.ACTION_MANAGED_PROFILE_AVAILABLE, /* checker= */
1297                         null);
1298         mUserManager.requestQuietModeEnabled(false, profileHandle);
1299         broadcastReceiver.awaitForBroadcastOrFail();
1300     }
1301 
1302     @Test
1303     @EnsureHasPrivateProfile
1304     @RequireRunOnPrivateProfile
1305     @ApiTest(apis = {"android.os.UserManager#getProfileLabel"})
1306     @EnsureHasPermission({CREATE_USERS, INTERACT_ACROSS_USERS})
1307     @RequiresFlagsEnabled({android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
1308             android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES})
testPrivateProfileLabel_shouldNotBeNull()1309     public void testPrivateProfileLabel_shouldNotBeNull() {
1310         final UserManager umOfProfile = sContext.getSystemService(UserManager.class);
1311         assert umOfProfile != null;
1312         assertThat(umOfProfile.getProfileLabel()).isNotNull();
1313     }
1314 
presetQuietModeStatus(boolean enableQuietMode, UserHandle profileHandle)1315     private void presetQuietModeStatus(boolean enableQuietMode, UserHandle profileHandle) {
1316         if (mUserManager.isQuietModeEnabled(profileHandle) != enableQuietMode) {
1317             mUserManager.requestQuietModeEnabled(enableQuietMode, profileHandle);
1318         }
1319     }
1320 
userIsEqual(UserHandle userHandle)1321     private Function<Intent, Boolean> userIsEqual(UserHandle userHandle) {
1322         try {
1323             return (intent) -> userHandle.equals(intent.getParcelableExtra(intent.EXTRA_USER));
1324         } catch (NullPointerException e) {
1325             assumeNoException("User handle is null", e);
1326         }
1327         return (intent) -> false;
1328     }
1329 
1330     @Nullable
getUser(int id)1331     private UserInfo getUser(int id) {
1332         try (PermissionContext p = TestApis.permissions().withPermission(CREATE_USERS)) {
1333             return  mUserManager.getUsers()
1334                     .stream().filter(user -> user.id == id).findFirst()
1335                     .orElse(null);
1336         }
1337     }
1338 
hasUser(int id)1339     private boolean hasUser(int id) {
1340         return getUser(id) != null;
1341     }
1342 
isMainUserPermanentAdmin()1343     private boolean isMainUserPermanentAdmin() {
1344         try {
1345             return sContext.getResources().getBoolean(
1346                     Resources.getSystem().getIdentifier("config_isMainUserPermanentAdmin",
1347                             "bool", "android"));
1348         } catch (Resources.NotFoundException e) {
1349             // Assume the main user is not permanent admin.
1350             return false;
1351         }
1352     }
1353 }
1354