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