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