1 /* 2 * Copyright (C) 2021 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 com.android.bedstead.nene.users; 18 19 import static android.os.Build.VERSION.SDK_INT; 20 21 import static com.android.bedstead.nene.types.OptionalBoolean.ANY; 22 import static com.android.bedstead.nene.types.OptionalBoolean.FALSE; 23 import static com.android.bedstead.nene.types.OptionalBoolean.TRUE; 24 import static com.android.bedstead.nene.users.UserType.MANAGED_PROFILE_TYPE_NAME; 25 import static com.android.bedstead.nene.users.UserType.SECONDARY_USER_TYPE_NAME; 26 import static com.android.bedstead.nene.users.UserType.SYSTEM_USER_TYPE_NAME; 27 28 import static com.google.common.truth.Truth.assertThat; 29 30 import static org.junit.Assume.assumeTrue; 31 import static org.testng.Assert.assertThrows; 32 33 import android.os.Build; 34 import android.os.UserHandle; 35 36 import com.android.bedstead.harrier.BedsteadJUnit4; 37 import com.android.bedstead.harrier.DeviceState; 38 import com.android.bedstead.harrier.annotations.EnsureCanAddUser; 39 import com.android.bedstead.harrier.annotations.EnsureHasNoSecondaryUser; 40 import com.android.bedstead.harrier.annotations.EnsureHasNoWorkProfile; 41 import com.android.bedstead.harrier.annotations.EnsureHasSecondaryUser; 42 import com.android.bedstead.harrier.annotations.EnsureHasWorkProfile; 43 import com.android.bedstead.harrier.annotations.RequireHeadlessSystemUserMode; 44 import com.android.bedstead.harrier.annotations.RequireRunNotOnSecondaryUser; 45 import com.android.bedstead.harrier.annotations.RequireRunOnPrimaryUser; 46 import com.android.bedstead.harrier.annotations.RequireRunOnSecondaryUser; 47 import com.android.bedstead.harrier.annotations.enterprise.EnsureHasNoDeviceOwner; 48 import com.android.bedstead.nene.TestApis; 49 import com.android.bedstead.nene.exceptions.NeneException; 50 import com.android.bedstead.nene.utils.Poll; 51 52 import org.junit.ClassRule; 53 import org.junit.Ignore; 54 import org.junit.Rule; 55 import org.junit.Test; 56 import org.junit.runner.RunWith; 57 58 import java.util.Iterator; 59 import java.util.Set; 60 61 @RunWith(BedsteadJUnit4.class) 62 public final class UsersTest { 63 64 private static final int MAX_SYSTEM_USERS = 1; 65 private static final int MAX_SYSTEM_USERS_PER_PARENT = UserType.UNLIMITED; 66 private static final String INVALID_TYPE_NAME = "invalidTypeName"; 67 private static final int MAX_MANAGED_PROFILES = UserType.UNLIMITED; 68 private static final int MAX_MANAGED_PROFILES_PER_PARENT = 1; 69 private static final int NON_EXISTING_USER_ID = 10000; 70 private static final int USER_ID = NON_EXISTING_USER_ID; 71 private static final String USER_NAME = "userName"; 72 73 private final UserType mSecondaryUserType = 74 TestApis.users().supportedType(SECONDARY_USER_TYPE_NAME); 75 private final UserType mManagedProfileType = 76 TestApis.users().supportedType(MANAGED_PROFILE_TYPE_NAME); 77 private final UserReference mInstrumentedUser = TestApis.users().instrumented(); 78 79 @ClassRule 80 @Rule 81 public static final DeviceState sDeviceState = new DeviceState(); 82 83 // We don't want to test the exact list of any specific device, so we check that it returns 84 // some known types which will exist on the emulators (used for presubmit tests). 85 86 @Test supportedTypes_containsManagedProfile()87 public void supportedTypes_containsManagedProfile() { 88 UserType managedProfileUserType = 89 TestApis.users().supportedTypes().stream().filter( 90 (ut) -> ut.name().equals(MANAGED_PROFILE_TYPE_NAME)).findFirst().get(); 91 92 assertThat(managedProfileUserType.baseType()).containsExactly(UserType.BaseType.PROFILE); 93 assertThat(managedProfileUserType.enabled()).isTrue(); 94 assertThat(managedProfileUserType.maxAllowed()).isEqualTo(MAX_MANAGED_PROFILES); 95 assertThat(managedProfileUserType.maxAllowedPerParent()) 96 .isEqualTo(MAX_MANAGED_PROFILES_PER_PARENT); 97 } 98 99 @Test supportedTypes_containsSystemUser()100 public void supportedTypes_containsSystemUser() { 101 UserType systemUserType = 102 TestApis.users().supportedTypes().stream().filter( 103 (ut) -> ut.name().equals(SYSTEM_USER_TYPE_NAME)).findFirst().get(); 104 105 assertThat(systemUserType.baseType()).containsExactly( 106 UserType.BaseType.SYSTEM, UserType.BaseType.FULL); 107 assertThat(systemUserType.enabled()).isTrue(); 108 assertThat(systemUserType.maxAllowed()).isEqualTo(MAX_SYSTEM_USERS); 109 assertThat(systemUserType.maxAllowedPerParent()).isEqualTo(MAX_SYSTEM_USERS_PER_PARENT); 110 } 111 112 @Test supportedType_validType_returnsType()113 public void supportedType_validType_returnsType() { 114 UserType managedProfileUserType = 115 TestApis.users().supportedType(MANAGED_PROFILE_TYPE_NAME); 116 117 assertThat(managedProfileUserType.baseType()).containsExactly(UserType.BaseType.PROFILE); 118 assertThat(managedProfileUserType.enabled()).isTrue(); 119 assertThat(managedProfileUserType.maxAllowed()).isEqualTo(MAX_MANAGED_PROFILES); 120 assertThat(managedProfileUserType.maxAllowedPerParent()) 121 .isEqualTo(MAX_MANAGED_PROFILES_PER_PARENT); 122 } 123 124 @Test supportedType_invalidType_returnsNull()125 public void supportedType_invalidType_returnsNull() { 126 assertThat(TestApis.users().supportedType(INVALID_TYPE_NAME)).isNull(); 127 } 128 129 @Test 130 @EnsureCanAddUser all_containsCreatedUser()131 public void all_containsCreatedUser() { 132 UserReference user = TestApis.users().createUser().create(); 133 134 try { 135 assertThat(TestApis.users().all()).contains(user); 136 } finally { 137 user.remove(); 138 } 139 } 140 141 @Test 142 @EnsureCanAddUser(number = 2) all_userAddedSinceLastCallToUsers_containsNewUser()143 public void all_userAddedSinceLastCallToUsers_containsNewUser() { 144 UserReference user = TestApis.users().createUser().create(); 145 TestApis.users().all(); 146 UserReference user2 = TestApis.users().createUser().create(); 147 148 try { 149 assertThat(TestApis.users().all()).contains(user2); 150 } finally { 151 user.remove(); 152 user2.remove(); 153 } 154 } 155 156 @Test 157 @EnsureCanAddUser all_userRemovedSinceLastCallToUsers_doesNotContainRemovedUser()158 public void all_userRemovedSinceLastCallToUsers_doesNotContainRemovedUser() { 159 UserReference user = TestApis.users().createUser().create(); 160 TestApis.users().all(); 161 user.remove(); 162 163 assertThat(TestApis.users().all()).doesNotContain(user); 164 } 165 166 @Test 167 @EnsureCanAddUser find_userExists_returnsUserReference()168 public void find_userExists_returnsUserReference() { 169 UserReference user = TestApis.users().createUser().create(); 170 try { 171 assertThat(TestApis.users().find(user.id())).isEqualTo(user); 172 } finally { 173 user.remove(); 174 } 175 } 176 177 @Test find_userDoesNotExist_returnsUserReference()178 public void find_userDoesNotExist_returnsUserReference() { 179 assertThat(TestApis.users().find(NON_EXISTING_USER_ID)).isNotNull(); 180 } 181 182 @Test find_fromUserHandle_referencesCorrectId()183 public void find_fromUserHandle_referencesCorrectId() { 184 assertThat(TestApis.users().find(UserHandle.of(USER_ID)).id()).isEqualTo(USER_ID); 185 } 186 187 @Test find_constructedReferenceReferencesCorrectId()188 public void find_constructedReferenceReferencesCorrectId() { 189 assertThat(TestApis.users().find(USER_ID).id()).isEqualTo(USER_ID); 190 } 191 192 @Test 193 @EnsureCanAddUser createUser_additionalSystemUser_throwsException()194 public void createUser_additionalSystemUser_throwsException() { 195 assertThrows(NeneException.class, () -> 196 TestApis.users().createUser() 197 .type(TestApis.users().supportedType(SYSTEM_USER_TYPE_NAME)) 198 .create()); 199 } 200 201 @Test 202 @EnsureCanAddUser createUser_userIsCreated()203 public void createUser_userIsCreated() { 204 UserReference user = TestApis.users().createUser().create(); 205 206 try { 207 assertThat(TestApis.users().all()).contains(user); 208 } finally { 209 user.remove(); 210 } 211 } 212 213 @Test 214 @EnsureCanAddUser createUser_createdUserHasCorrectName()215 public void createUser_createdUserHasCorrectName() { 216 UserReference userReference = TestApis.users().createUser() 217 .name(USER_NAME) 218 .create(); 219 220 try { 221 assertThat(userReference.name()).isEqualTo(USER_NAME); 222 } finally { 223 userReference.remove(); 224 } 225 } 226 227 @Test 228 @EnsureCanAddUser createUser_createdUserHasCorrectTypeName()229 public void createUser_createdUserHasCorrectTypeName() { 230 UserReference userReference = TestApis.users().createUser() 231 .type(mSecondaryUserType) 232 .create(); 233 234 try { 235 assertThat(userReference.type()).isEqualTo(mSecondaryUserType); 236 } finally { 237 userReference.remove(); 238 } 239 } 240 241 @Test 242 @EnsureCanAddUser createUser_specifiesNullStringUserType_throwsException()243 public void createUser_specifiesNullStringUserType_throwsException() { 244 UserBuilder userBuilder = TestApis.users().createUser(); 245 246 assertThrows(NullPointerException.class, () -> userBuilder.type((String) null)); 247 } 248 249 @Test 250 @EnsureCanAddUser createUser_specifiesNullUserType_throwsException()251 public void createUser_specifiesNullUserType_throwsException() { 252 UserBuilder userBuilder = TestApis.users().createUser(); 253 254 assertThrows(NullPointerException.class, () -> userBuilder.type((UserType) null)); 255 } 256 257 @Test 258 @EnsureCanAddUser createUser_specifiesSystemUserType_throwsException()259 public void createUser_specifiesSystemUserType_throwsException() { 260 UserType type = TestApis.users().supportedType(SYSTEM_USER_TYPE_NAME); 261 UserBuilder userBuilder = TestApis.users().createUser() 262 .type(type); 263 264 assertThrows(NeneException.class, userBuilder::create); 265 } 266 267 @Test 268 @EnsureCanAddUser createUser_specifiesSecondaryUserType_createsUser()269 public void createUser_specifiesSecondaryUserType_createsUser() { 270 UserReference user = TestApis.users().createUser().type(mSecondaryUserType).create(); 271 272 try { 273 assertThat(user.exists()).isTrue(); 274 } finally { 275 user.remove(); 276 } 277 } 278 279 @Test 280 @EnsureHasNoDeviceOwner // Device Owners can disable managed profiles 281 @EnsureHasNoWorkProfile 282 @EnsureCanAddUser createUser_specifiesManagedProfileUserType_createsUser()283 public void createUser_specifiesManagedProfileUserType_createsUser() { 284 UserReference personalUser = TestApis.users().instrumented(); 285 UserReference user = 286 TestApis.users() 287 .createUser() 288 .type(mManagedProfileType) 289 .parent(personalUser) 290 .create(); 291 292 try { 293 assertThat(user.exists()).isTrue(); 294 } finally { 295 user.remove(); 296 } 297 } 298 299 @Test 300 @EnsureHasNoWorkProfile 301 @EnsureCanAddUser createUser_createsProfile_parentIsSet()302 public void createUser_createsProfile_parentIsSet() { 303 UserReference personalUser = TestApis.users().instrumented(); 304 UserReference user = 305 TestApis.users() 306 .createUser() 307 .type(mManagedProfileType) 308 .parent(personalUser) 309 .create(); 310 311 try { 312 assertThat(user.parent()).isEqualTo(TestApis.users().instrumented()); 313 } finally { 314 user.remove(); 315 } 316 } 317 318 @Test 319 @EnsureCanAddUser createUser_specifiesParentOnNonProfileType_throwsException()320 public void createUser_specifiesParentOnNonProfileType_throwsException() { 321 UserReference systemUser = TestApis.users().system(); 322 UserBuilder userBuilder = TestApis.users().createUser() 323 .type(mSecondaryUserType).parent(systemUser); 324 325 assertThrows(NeneException.class, userBuilder::create); 326 } 327 328 @Test 329 @EnsureCanAddUser createUser_specifiesProfileTypeWithoutParent_throwsException()330 public void createUser_specifiesProfileTypeWithoutParent_throwsException() { 331 UserBuilder userBuilder = TestApis.users().createUser() 332 .type(mManagedProfileType); 333 334 assertThrows(NeneException.class, userBuilder::create); 335 } 336 337 @Test 338 @EnsureCanAddUser createUser_androidLessThanS_createsManagedProfileNotOnSystemUser_throwsException()339 public void createUser_androidLessThanS_createsManagedProfileNotOnSystemUser_throwsException() { 340 assumeTrue("After Android S, managed profiles may be a profile of a non-system user", 341 SDK_INT < Build.VERSION_CODES.S); 342 343 UserReference nonSystemUser = TestApis.users().createUser().create(); 344 345 try { 346 UserBuilder userBuilder = TestApis.users().createUser() 347 .type(mManagedProfileType) 348 .parent(nonSystemUser); 349 350 assertThrows(NeneException.class, userBuilder::create); 351 } finally { 352 nonSystemUser.remove(); 353 } 354 } 355 356 @Test 357 @EnsureCanAddUser createAndStart_isStarted()358 public void createAndStart_isStarted() { 359 UserReference user = null; 360 361 try { 362 user = TestApis.users().createUser().name(USER_NAME).createAndStart(); 363 assertThat(user.isUnlocked()).isTrue(); 364 } finally { 365 if (user != null) { 366 user.remove(); 367 } 368 } 369 } 370 371 @Test system_hasId0()372 public void system_hasId0() { 373 assertThat(TestApis.users().system().id()).isEqualTo(0); 374 } 375 376 @Test instrumented_hasCurrentProccessId()377 public void instrumented_hasCurrentProccessId() { 378 assertThat(TestApis.users().instrumented().id()) 379 .isEqualTo(android.os.Process.myUserHandle().getIdentifier()); 380 } 381 382 @Test 383 @EnsureHasNoSecondaryUser findUsersOfType_noMatching_returnsEmptySet()384 public void findUsersOfType_noMatching_returnsEmptySet() { 385 assertThat(TestApis.users().findUsersOfType(mSecondaryUserType)).isEmpty(); 386 } 387 388 @Test findUsersOfType_nullType_throwsException()389 public void findUsersOfType_nullType_throwsException() { 390 assertThrows(NullPointerException.class, 391 () -> TestApis.users().findUsersOfType(null)); 392 } 393 394 @Test 395 @EnsureHasSecondaryUser 396 @Ignore( 397 "TODO: Re-enable when harrier .secondaryUser() only" 398 + " returns the harrier-managed secondary user") 399 @EnsureCanAddUser findUsersOfType_returnsUsers()400 public void findUsersOfType_returnsUsers() { 401 try (UserReference additionalUser = TestApis.users().createUser().create()) { 402 assertThat(TestApis.users().findUsersOfType(mSecondaryUserType)) 403 .containsExactly(sDeviceState.secondaryUser(), additionalUser); 404 } 405 } 406 407 @Test findUsersOfType_profileType_throwsException()408 public void findUsersOfType_profileType_throwsException() { 409 assertThrows(NeneException.class, 410 () -> TestApis.users().findUsersOfType(mManagedProfileType)); 411 } 412 413 @Test 414 @EnsureHasNoSecondaryUser findUserOfType_noMatching_returnsNull()415 public void findUserOfType_noMatching_returnsNull() { 416 assertThat(TestApis.users().findUserOfType(mSecondaryUserType)).isNull(); 417 } 418 419 @Test findUserOfType_nullType_throwsException()420 public void findUserOfType_nullType_throwsException() { 421 assertThrows(NullPointerException.class, 422 () -> TestApis.users().findUserOfType(null)); 423 } 424 425 @Test 426 @EnsureHasSecondaryUser 427 @EnsureCanAddUser findUserOfType_multipleMatchingUsers_throwsException()428 public void findUserOfType_multipleMatchingUsers_throwsException() { 429 try (UserReference additionalUser = TestApis.users().createUser().create()) { 430 assertThrows(NeneException.class, 431 () -> TestApis.users().findUserOfType(mSecondaryUserType)); 432 } 433 } 434 435 @Test 436 @EnsureHasSecondaryUser findUserOfType_oneMatchingUser_returnsUser()437 public void findUserOfType_oneMatchingUser_returnsUser() { 438 Set<UserReference> users = TestApis.users().findUsersOfType(mSecondaryUserType); 439 Iterator<UserReference> i = users.iterator(); 440 i.next(); // Skip the first one so we leave one 441 while (i.hasNext()) { 442 i.next().remove(); 443 } 444 445 assertThat(TestApis.users().findUserOfType(mSecondaryUserType)).isNotNull(); 446 } 447 448 @Test findUserOfType_profileType_throwsException()449 public void findUserOfType_profileType_throwsException() { 450 assertThrows(NeneException.class, 451 () -> TestApis.users().findUserOfType(mManagedProfileType)); 452 } 453 454 @Test 455 @EnsureHasNoWorkProfile findProfilesOfType_noMatching_returnsEmptySet()456 public void findProfilesOfType_noMatching_returnsEmptySet() { 457 assertThat(TestApis.users().findProfilesOfType(mManagedProfileType, mInstrumentedUser)) 458 .isEmpty(); 459 } 460 461 @Test findProfilesOfType_nullType_throwsException()462 public void findProfilesOfType_nullType_throwsException() { 463 assertThrows(NullPointerException.class, 464 () -> TestApis.users().findProfilesOfType( 465 /* userType= */ null, mInstrumentedUser)); 466 } 467 468 @Test findProfilesOfType_nullParent_throwsException()469 public void findProfilesOfType_nullParent_throwsException() { 470 assertThrows(NullPointerException.class, 471 () -> TestApis.users().findProfilesOfType( 472 mManagedProfileType, /* parent= */ null)); 473 } 474 475 // TODO(scottjonathan): Once we have profiles which support more than one instance, test this 476 477 @Test 478 @EnsureHasNoWorkProfile findProfileOfType_noMatching_returnsNull()479 public void findProfileOfType_noMatching_returnsNull() { 480 assertThat(TestApis.users().findProfileOfType(mManagedProfileType, mInstrumentedUser)) 481 .isNull(); 482 } 483 484 @Test findProfilesOfType_nonProfileType_throwsException()485 public void findProfilesOfType_nonProfileType_throwsException() { 486 assertThrows(NeneException.class, 487 () -> TestApis.users().findProfilesOfType(mSecondaryUserType, mInstrumentedUser)); 488 } 489 490 @Test findProfileOfType_nullType_throwsException()491 public void findProfileOfType_nullType_throwsException() { 492 assertThrows(NullPointerException.class, 493 () -> TestApis.users().findProfileOfType(/* userType= */ null, mInstrumentedUser)); 494 } 495 496 @Test findProfileOfType_nonProfileType_throwsException()497 public void findProfileOfType_nonProfileType_throwsException() { 498 assertThrows(NeneException.class, 499 () -> TestApis.users().findProfileOfType(mSecondaryUserType, mInstrumentedUser)); 500 } 501 502 @Test findProfileOfType_nullParent_throwsException()503 public void findProfileOfType_nullParent_throwsException() { 504 assertThrows(NullPointerException.class, 505 () -> TestApis.users().findProfileOfType(mManagedProfileType, /* parent= */ null)); 506 } 507 508 @Test 509 @EnsureHasWorkProfile // TODO(scottjonathan): This should have a way of specifying exactly 1 findProfileOfType_oneMatchingUser_returnsUser()510 public void findProfileOfType_oneMatchingUser_returnsUser() { 511 assertThat(TestApis.users().findProfileOfType(mManagedProfileType, mInstrumentedUser)) 512 .isNotNull(); 513 } 514 515 @Test nonExisting_userDoesNotExist()516 public void nonExisting_userDoesNotExist() { 517 UserReference userReference = TestApis.users().nonExisting(); 518 519 assertThat(userReference.exists()).isFalse(); 520 } 521 522 @Test 523 @EnsureHasSecondaryUser(switchedToUser = TRUE) currentUser_secondaryUser_returnsCurrentUser()524 public void currentUser_secondaryUser_returnsCurrentUser() { 525 assertThat(TestApis.users().current()).isEqualTo(sDeviceState.secondaryUser()); 526 } 527 528 @Test 529 @RequireRunOnPrimaryUser(switchedToUser = TRUE) currentUser_primaryUser_returnsCurrentUser()530 public void currentUser_primaryUser_returnsCurrentUser() { 531 assertThat(TestApis.users().current()).isEqualTo(sDeviceState.primaryUser()); 532 } 533 534 @Test 535 @RequireRunNotOnSecondaryUser 536 @EnsureHasSecondaryUser 537 @RequireHeadlessSystemUserMode(reason = "stopBgUsersOnSwitch is only for headless") switch_hasSetStopBgUsersOnSwitch_stopsUser()538 public void switch_hasSetStopBgUsersOnSwitch_stopsUser() throws Exception { 539 try { 540 sDeviceState.secondaryUser().switchTo(); 541 TestApis.users().setStopBgUsersOnSwitch(TRUE); 542 TestApis.users().system().switchTo(); 543 544 Poll.forValue("Secondary user running", 545 () -> sDeviceState.secondaryUser().isRunning()) 546 .toBeEqualTo(false) 547 .errorOnFail() 548 .await(); 549 550 assertThat(sDeviceState.secondaryUser().isRunning()).isFalse(); 551 } finally { 552 sDeviceState.secondaryUser().start(); 553 TestApis.users().setStopBgUsersOnSwitch(ANY); 554 } 555 } 556 557 @Test 558 @RequireRunOnSecondaryUser switch_hasSetStopBgUsersOnSwitchFalse_doesNotStopUser()559 public void switch_hasSetStopBgUsersOnSwitchFalse_doesNotStopUser() { 560 try { 561 TestApis.users().setStopBgUsersOnSwitch(FALSE); 562 TestApis.users().system().switchTo(); 563 564 assertThat(sDeviceState.secondaryUser().isRunning()).isTrue(); 565 } finally { 566 TestApis.users().setStopBgUsersOnSwitch(ANY); 567 sDeviceState.secondaryUser().start(); 568 sDeviceState.secondaryUser().switchTo(); 569 } 570 } 571 } 572