1 /* 2 * Copyright (C) 2022 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 package com.android.server.pm; 17 18 import static android.os.UserHandle.USER_ALL; 19 import static android.os.UserHandle.USER_CURRENT; 20 import static android.os.UserHandle.USER_CURRENT_OR_SELF; 21 import static android.os.UserHandle.USER_NULL; 22 import static android.os.UserHandle.USER_SYSTEM; 23 import static android.view.Display.DEFAULT_DISPLAY; 24 import static android.view.Display.INVALID_DISPLAY; 25 26 import static com.android.server.pm.UserManagerInternal.USER_ASSIGNMENT_RESULT_FAILURE; 27 import static com.android.server.pm.UserManagerInternal.USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE; 28 import static com.android.server.pm.UserManagerInternal.USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE; 29 import static com.android.server.pm.UserManagerInternal.USER_START_MODE_BACKGROUND; 30 import static com.android.server.pm.UserManagerInternal.USER_START_MODE_BACKGROUND_VISIBLE; 31 import static com.android.server.pm.UserManagerInternal.USER_START_MODE_FOREGROUND; 32 import static com.android.server.pm.UserManagerInternal.userAssignmentResultToString; 33 import static com.android.server.pm.UserVisibilityChangedEvent.onInvisible; 34 import static com.android.server.pm.UserVisibilityChangedEvent.onVisible; 35 import static com.android.server.pm.UserVisibilityMediator.INITIAL_CURRENT_USER_ID; 36 37 import static com.google.common.truth.Truth.assertWithMessage; 38 39 import static org.junit.Assert.assertThrows; 40 41 import android.annotation.UserIdInt; 42 import android.os.Handler; 43 import android.text.TextUtils; 44 import android.util.IntArray; 45 import android.util.Log; 46 47 import com.android.server.DumpableDumperRule; 48 import com.android.server.ExpectableTestCase; 49 50 import org.junit.Before; 51 import org.junit.Test; 52 53 import java.util.Arrays; 54 55 /** 56 * Base class for {@link UserVisibilityMediator} tests. 57 * 58 * <p>It contains common logics and tests for behaviors that should be invariant regardless of the 59 * device mode (for example, whether the device supports concurrent multiple users on multiple 60 * displays or not). 61 * 62 * <p><P>NOTE: <p> rather than adopting the "one test case for method approach", this class (and 63 * its subclass) adds "one test case for scenario" approach, so it can test many properties (if user 64 * is visible, display associated to the user, etc...) for each scenario (full user started on fg, 65 * profile user started on bg, etc...). 66 */ 67 abstract class UserVisibilityMediatorTestCase extends ExpectableTestCase { 68 69 private static final String TAG = UserVisibilityMediatorTestCase.class.getSimpleName(); 70 71 /** 72 * Id for a simple user (that doesn't have profiles). 73 */ 74 protected static final int USER_ID = 600; 75 76 /** 77 * Id for another simple user. 78 */ 79 protected static final int OTHER_USER_ID = 666; 80 81 /** 82 * Id for yeat another simple user. 83 */ 84 protected static final int YET_ANOTHER_USER_ID = 700; 85 86 /** 87 * Id for a user that has one profile (whose id is {@link #PROFILE_USER_ID}. 88 * 89 * <p>You can use {@link #addDefaultProfileAndParent()} to add both of this user to the service. 90 */ 91 protected static final int PARENT_USER_ID = 642; 92 93 /** 94 * Id for a profile whose parent is {@link #PARENTUSER_ID}. 95 * 96 * <p>You can use {@link #addDefaultProfileAndParent()} to add both of this user to the service. 97 */ 98 protected static final int PROFILE_USER_ID = 643; 99 100 /** 101 * Id of a secondary display (i.e, not {@link android.view.Display.DEFAULT_DISPLAY}). 102 */ 103 protected static final int SECONDARY_DISPLAY_ID = 42; 104 105 /** 106 * Id of another secondary display (i.e, not {@link android.view.Display.DEFAULT_DISPLAY}). 107 */ 108 protected static final int OTHER_SECONDARY_DISPLAY_ID = 108; 109 110 protected static final int FG = USER_START_MODE_FOREGROUND; 111 protected static final int BG = USER_START_MODE_BACKGROUND; 112 protected static final int BG_VISIBLE = USER_START_MODE_BACKGROUND_VISIBLE; 113 114 private Handler mHandler; 115 protected AsyncUserVisibilityListener.Factory mListenerFactory; 116 117 private final boolean mBackgroundUsersOnDisplaysEnabled; 118 private final boolean mBackgroundUserOnDefaultDisplayAllowed; 119 120 protected UserVisibilityMediator mMediator; 121 UserVisibilityMediatorTestCase(boolean backgroundUsersOnDisplaysEnabled, boolean backgroundUserOnDefaultDisplayAllowed)122 protected UserVisibilityMediatorTestCase(boolean backgroundUsersOnDisplaysEnabled, 123 boolean backgroundUserOnDefaultDisplayAllowed) { 124 mBackgroundUsersOnDisplaysEnabled = backgroundUsersOnDisplaysEnabled; 125 mBackgroundUserOnDefaultDisplayAllowed = backgroundUserOnDefaultDisplayAllowed; 126 } 127 128 protected final DumpableDumperRule mDumpableDumperRule = new DumpableDumperRule(); 129 130 @Before setFixtures()131 public final void setFixtures() { 132 mHandler = Handler.getMain(); 133 Thread thread = mHandler.getLooper().getThread(); 134 Log.i(TAG, "setFixtures(): using thread " + thread + " (from handler " + mHandler + ")"); 135 mListenerFactory = new AsyncUserVisibilityListener.Factory(mExpect, thread); 136 mMediator = new UserVisibilityMediator(mBackgroundUsersOnDisplaysEnabled, 137 mBackgroundUserOnDefaultDisplayAllowed, mHandler); 138 mDumpableDumperRule.addDumpable(mMediator); 139 } 140 141 @Test testInvalidMode()142 public void testInvalidMode() { 143 assertThrows(IllegalArgumentException.class, () -> new UserVisibilityMediator( 144 /* visibleBackgroundUsersOnDisplaysEnabled= */ false, 145 /* visibleBackgroundUserOnDefaultDisplayAllowed= */ true, mHandler)); 146 } 147 148 @Test testAssignUserToDisplayOnStart_invalidUserIds()149 public final void testAssignUserToDisplayOnStart_invalidUserIds() { 150 assertThrows(IllegalArgumentException.class, () -> mMediator 151 .assignUserToDisplayOnStart(USER_NULL, USER_ID, FG, DEFAULT_DISPLAY)); 152 assertThrows(IllegalArgumentException.class, () -> mMediator 153 .assignUserToDisplayOnStart(USER_ALL, USER_ID, FG, DEFAULT_DISPLAY)); 154 assertThrows(IllegalArgumentException.class, () -> mMediator 155 .assignUserToDisplayOnStart(USER_CURRENT, USER_ID, FG, DEFAULT_DISPLAY)); 156 assertThrows(IllegalArgumentException.class, () -> mMediator 157 .assignUserToDisplayOnStart(USER_CURRENT_OR_SELF, USER_ID, FG, DEFAULT_DISPLAY)); 158 } 159 160 @Test testAssignUserToDisplayOnStart_invalidUserStartMode()161 public final void testAssignUserToDisplayOnStart_invalidUserStartMode() { 162 assertThrows(IllegalArgumentException.class, () -> mMediator 163 .assignUserToDisplayOnStart(USER_ID, USER_ID, 666, DEFAULT_DISPLAY)); 164 } 165 166 @Test testStartFgUser_onSecondaryDisplay()167 public final void testStartFgUser_onSecondaryDisplay() throws Exception { 168 AsyncUserVisibilityListener listener = addListenerForNoEvents(); 169 170 int result = 171 mMediator.assignUserToDisplayOnStart(USER_ID, USER_ID, FG, SECONDARY_DISPLAY_ID); 172 assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE); 173 174 expectUserIsNotVisibleAtAll(USER_ID); 175 expectNoDisplayAssignedToUser(USER_ID); 176 expectInitialCurrentUserAssignedToDisplay(DEFAULT_DISPLAY); 177 178 listener.verify(); 179 } 180 181 @Test testStartBgUser_onDefaultDisplay()182 public final void testStartBgUser_onDefaultDisplay() throws Exception { 183 AsyncUserVisibilityListener listener = addListenerForNoEvents(); 184 185 int result = mMediator.assignUserToDisplayOnStart(USER_ID, USER_ID, BG, DEFAULT_DISPLAY); 186 assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE); 187 188 expectUserIsNotVisibleAtAll(USER_ID); 189 expectNoDisplayAssignedToUser(USER_ID); 190 expectInitialCurrentUserAssignedToDisplay(DEFAULT_DISPLAY); 191 192 assertInvisibleUserCannotBeAssignedExtraDisplay(USER_ID, SECONDARY_DISPLAY_ID); 193 194 listener.verify(); 195 } 196 visibleBgUserCannotBeStartedOnDefaultDisplayTest()197 protected final @UserIdInt int visibleBgUserCannotBeStartedOnDefaultDisplayTest() 198 throws Exception { 199 AsyncUserVisibilityListener listener = addListenerForNoEvents(); 200 201 int result = mMediator.assignUserToDisplayOnStart(USER_ID, USER_ID, BG_VISIBLE, 202 DEFAULT_DISPLAY); 203 assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE); 204 205 expectUserIsNotVisibleAtAll(USER_ID); 206 expectNoDisplayAssignedToUser(USER_ID); 207 208 listener.verify(); 209 210 return USER_ID; 211 } 212 213 @Test testStartBgUser_onSecondaryDisplay()214 public final void testStartBgUser_onSecondaryDisplay() throws Exception { 215 AsyncUserVisibilityListener listener = addListenerForNoEvents(); 216 217 int result = mMediator.assignUserToDisplayOnStart(USER_ID, USER_ID, BG, 218 SECONDARY_DISPLAY_ID); 219 assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE); 220 221 expectUserIsNotVisibleAtAll(USER_ID); 222 expectNoDisplayAssignedToUser(USER_ID); 223 224 assertInvisibleUserCannotBeAssignedExtraDisplay(USER_ID, SECONDARY_DISPLAY_ID); 225 assertInvisibleUserCannotBeAssignedExtraDisplay(USER_ID, OTHER_SECONDARY_DISPLAY_ID); 226 227 listener.verify(); 228 } 229 230 @Test testStartBgSystemUser_onSecondaryDisplay()231 public final void testStartBgSystemUser_onSecondaryDisplay() throws Exception { 232 AsyncUserVisibilityListener listener = addListenerForEvents( 233 onInvisible(INITIAL_CURRENT_USER_ID), 234 onVisible(USER_ID)); 235 // Must explicitly set current user, as USER_SYSTEM is the default current user 236 startForegroundUser(USER_ID); 237 238 int result = mMediator.assignUserToDisplayOnStart(USER_SYSTEM, USER_SYSTEM, BG, 239 SECONDARY_DISPLAY_ID); 240 assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE); 241 242 expectUserIsNotVisibleAtAll(USER_SYSTEM); 243 244 expectNoDisplayAssignedToUser(USER_SYSTEM); 245 expectUserAssignedToDisplay(SECONDARY_DISPLAY_ID, USER_ID); 246 247 assertUserCannotBeAssignedExtraDisplay(USER_SYSTEM, SECONDARY_DISPLAY_ID); 248 assertUserCannotBeAssignedExtraDisplay(USER_SYSTEM, OTHER_SECONDARY_DISPLAY_ID); 249 250 listener.verify(); 251 } 252 253 @Test testStopVisibleBgProfile()254 public final void testStopVisibleBgProfile() throws Exception { 255 AsyncUserVisibilityListener listener = addListenerForEvents( 256 onInvisible(INITIAL_CURRENT_USER_ID), 257 onVisible(PARENT_USER_ID), 258 onVisible(PROFILE_USER_ID), 259 onInvisible(PROFILE_USER_ID)); 260 startDefaultProfile(); 261 262 mMediator.unassignUserFromDisplayOnStop(PROFILE_USER_ID); 263 264 expectUserIsNotVisibleAtAll(PROFILE_USER_ID); 265 expectNoDisplayAssignedToUser(PROFILE_USER_ID); 266 expectUserAssignedToDisplay(DEFAULT_DISPLAY, PARENT_USER_ID); 267 268 listener.verify(); 269 } 270 271 @Test testVisibleBgProfileBecomesInvisibleWhenParentIsSwitchedOut()272 public final void testVisibleBgProfileBecomesInvisibleWhenParentIsSwitchedOut() 273 throws Exception { 274 AsyncUserVisibilityListener listener = addListenerForEvents( 275 onInvisible(INITIAL_CURRENT_USER_ID), 276 onVisible(PARENT_USER_ID), 277 onVisible(PROFILE_USER_ID), 278 onInvisible(PARENT_USER_ID), 279 onInvisible(PROFILE_USER_ID), 280 onVisible(OTHER_USER_ID)); 281 startDefaultProfile(); 282 283 startForegroundUser(OTHER_USER_ID); 284 285 expectUserIsNotVisibleAtAll(PROFILE_USER_ID); 286 expectNoDisplayAssignedToUser(PROFILE_USER_ID); 287 expectUserAssignedToDisplay(DEFAULT_DISPLAY, OTHER_USER_ID); 288 289 assertUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID); 290 291 listener.verify(); 292 } 293 294 @Test testStartVisibleBgProfile_onDefaultDisplay_whenParentIsNotStarted()295 public final void testStartVisibleBgProfile_onDefaultDisplay_whenParentIsNotStarted() 296 throws Exception { 297 AsyncUserVisibilityListener listener = addListenerForNoEvents(); 298 299 int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, 300 BG_VISIBLE, DEFAULT_DISPLAY); 301 assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE); 302 303 expectUserIsNotVisibleAtAll(PROFILE_USER_ID); 304 expectNoDisplayAssignedToUser(PROFILE_USER_ID); 305 306 listener.verify(); 307 } 308 309 @Test testStartVisibleBgProfile_onDefaultDisplay_whenParentIsStartedOnBg()310 public final void testStartVisibleBgProfile_onDefaultDisplay_whenParentIsStartedOnBg() 311 throws Exception { 312 AsyncUserVisibilityListener listener = addListenerForNoEvents(); 313 startBackgroundUser(PARENT_USER_ID); 314 315 int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, 316 BG_VISIBLE, DEFAULT_DISPLAY); 317 assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE); 318 319 expectUserIsNotVisibleAtAll(PROFILE_USER_ID); 320 321 expectNoDisplayAssignedToUser(PROFILE_USER_ID); 322 expectInitialCurrentUserAssignedToDisplay(DEFAULT_DISPLAY); 323 324 assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID); 325 326 listener.verify(); 327 } 328 329 // Not supported - profiles can only be started on default display 330 @Test testStartVisibleBgProfile_onSecondaryDisplay()331 public final void testStartVisibleBgProfile_onSecondaryDisplay() throws Exception { 332 AsyncUserVisibilityListener listener = addListenerForNoEvents(); 333 334 int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, 335 BG_VISIBLE, SECONDARY_DISPLAY_ID); 336 assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE); 337 338 expectUserIsNotVisibleAtAll(PROFILE_USER_ID); 339 expectNoDisplayAssignedToUser(PROFILE_USER_ID); 340 expectInitialCurrentUserAssignedToDisplay(SECONDARY_DISPLAY_ID); 341 342 assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID); 343 assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, 344 OTHER_SECONDARY_DISPLAY_ID); 345 346 listener.verify(); 347 } 348 349 @Test testStartBgProfile_onDefaultDisplay_whenParentIsNotStarted()350 public final void testStartBgProfile_onDefaultDisplay_whenParentIsNotStarted() 351 throws Exception { 352 AsyncUserVisibilityListener listener = addListenerForNoEvents(); 353 354 int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, BG, 355 DEFAULT_DISPLAY); 356 assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE); 357 358 expectUserIsNotVisibleAtAll(PROFILE_USER_ID); 359 expectNoDisplayAssignedToUser(PROFILE_USER_ID); 360 361 listener.verify(); 362 } 363 364 @Test testStartBgProfile_onDefaultDisplay_whenParentIsStartedOnBg()365 public final void testStartBgProfile_onDefaultDisplay_whenParentIsStartedOnBg() 366 throws Exception { 367 AsyncUserVisibilityListener listener = addListenerForNoEvents(); 368 startBackgroundUser(PARENT_USER_ID); 369 370 int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, BG, 371 DEFAULT_DISPLAY); 372 assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE); 373 374 expectUserIsNotVisibleAtAll(PROFILE_USER_ID); 375 376 expectNoDisplayAssignedToUser(PROFILE_USER_ID); 377 expectInitialCurrentUserAssignedToDisplay(DEFAULT_DISPLAY); 378 379 assertUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID); 380 381 listener.verify(); 382 } 383 384 @Test testStartBgProfile_onSecondaryDisplay()385 public final void testStartBgProfile_onSecondaryDisplay() throws Exception { 386 AsyncUserVisibilityListener listener = addListenerForNoEvents(); 387 388 int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, BG, 389 SECONDARY_DISPLAY_ID); 390 assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE); 391 392 expectUserIsNotVisibleAtAll(PROFILE_USER_ID); 393 expectNoDisplayAssignedToUser(PROFILE_USER_ID); 394 expectInitialCurrentUserAssignedToDisplay(SECONDARY_DISPLAY_ID); 395 396 assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID); 397 assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, 398 OTHER_SECONDARY_DISPLAY_ID); 399 400 listener.verify(); 401 } 402 403 @Test testStartFgProfile_onDefaultDisplay()404 public final void testStartFgProfile_onDefaultDisplay() throws Exception { 405 AsyncUserVisibilityListener listener = addListenerForNoEvents(); 406 407 int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, FG, 408 DEFAULT_DISPLAY); 409 assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE); 410 411 expectUserIsNotVisibleAtAll(PROFILE_USER_ID); 412 413 expectNoDisplayAssignedToUser(PROFILE_USER_ID); 414 expectInitialCurrentUserAssignedToDisplay(DEFAULT_DISPLAY); 415 416 assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, DEFAULT_DISPLAY); 417 assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID); 418 419 listener.verify(); 420 } 421 422 @Test testStartFgProfile_onSecondaryDisplay()423 public final void testStartFgProfile_onSecondaryDisplay() throws Exception { 424 AsyncUserVisibilityListener listener = addListenerForNoEvents(); 425 426 int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, FG, 427 SECONDARY_DISPLAY_ID); 428 assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE); 429 430 expectUserIsNotVisibleAtAll(PROFILE_USER_ID); 431 expectNoDisplayAssignedToUser(PROFILE_USER_ID); 432 expectInitialCurrentUserAssignedToDisplay(SECONDARY_DISPLAY_ID); 433 434 assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID); 435 assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, 436 OTHER_SECONDARY_DISPLAY_ID); 437 438 listener.verify(); 439 } 440 441 @Test testIsUserVisible_invalidUsers()442 public final void testIsUserVisible_invalidUsers() throws Exception { 443 expectWithMessage("isUserVisible(%s)", USER_NULL) 444 .that(mMediator.isUserVisible(USER_NULL)) 445 .isFalse(); 446 expectWithMessage("isUserVisible(%s)", USER_NULL) 447 .that(mMediator.isUserVisible(USER_ALL)) 448 .isFalse(); 449 expectWithMessage("isUserVisible(%s)", USER_NULL) 450 .that(mMediator.isUserVisible(USER_CURRENT)) 451 .isFalse(); 452 expectWithMessage("isUserVisible(%s)", USER_NULL) 453 .that(mMediator.isUserVisible(USER_CURRENT_OR_SELF)) 454 .isFalse(); 455 } 456 457 @Test testRemoveListener()458 public final void testRemoveListener() throws Exception { 459 AsyncUserVisibilityListener listener = addListenerForNoEvents(); 460 461 mMediator.removeListener(listener); 462 463 startForegroundUser(USER_ID); 464 listener.verify(); 465 } 466 467 @Test testOnSystemUserVisibilityChanged()468 public final void testOnSystemUserVisibilityChanged() throws Exception { 469 AsyncUserVisibilityListener listener = addListenerForEvents(onVisible(USER_SYSTEM)); 470 471 mMediator.onSystemUserVisibilityChanged(/* visible= */ true); 472 473 listener.verify(); 474 } 475 476 /** 477 * Starts a user in foreground on the default display, asserting it was properly started. 478 * 479 * <p><b>NOTE: </b>should only be used as a helper method, not to test the behavior of the 480 * {@link UserVisibilityMediator#assignUserToDisplayOnStart(int, int, boolean, int)} method per 481 * se. 482 */ startForegroundUser(@serIdInt int userId)483 protected void startForegroundUser(@UserIdInt int userId) { 484 Log.d(TAG, "startForegroundUSer(" + userId + ")"); 485 int result = mMediator.assignUserToDisplayOnStart(userId, userId, FG, DEFAULT_DISPLAY); 486 if (result != USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE) { 487 throw new IllegalStateException("Failed to start foreground user " + userId 488 + ": mediator returned " + userAssignmentResultToString(result)); 489 } 490 } 491 492 /** 493 * Starts a user in background on the default display, asserting it was properly started. 494 * 495 * <p><b>NOTE: </b>should only be used as a helper method, not to test the behavior of the 496 * {@link UserVisibilityMediator#assignUserToDisplayOnStart(int, int, boolean, int)} method per 497 * se. 498 */ startBackgroundUser(@serIdInt int userId)499 protected void startBackgroundUser(@UserIdInt int userId) { 500 Log.d(TAG, "startBackgroundUser(" + userId + ")"); 501 int result = mMediator.assignUserToDisplayOnStart(userId, userId, BG, DEFAULT_DISPLAY); 502 if (result != USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE) { 503 throw new IllegalStateException("Failed to start background user " + userId 504 + ": mediator returned " + userAssignmentResultToString(result)); 505 } 506 } 507 508 /** 509 * Starts the {@link #PROFILE_USER_ID default profile} in background and its 510 * {@link #PARENT_USER_ID parent} in foreground on the main display, asserting that 511 * both were properly started. 512 * 513 * <p><b>NOTE: </b>should only be used as a helper method, not to test the behavior of the 514 * {@link UserVisibilityMediator#assignUserToDisplayOnStart(int, int, boolean, int)} method per 515 * se. 516 */ startDefaultProfile()517 protected void startDefaultProfile() { 518 startForegroundUser(PARENT_USER_ID); 519 Log.d(TAG, "starting default profile (" + PROFILE_USER_ID + ") in background after starting" 520 + " its parent (" + PARENT_USER_ID + ") on foreground"); 521 522 int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, 523 BG_VISIBLE, DEFAULT_DISPLAY); 524 if (result != USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE) { 525 throw new IllegalStateException("Failed to start profile user " + PROFILE_USER_ID 526 + ": mediator returned " + userAssignmentResultToString(result)); 527 } 528 } 529 530 /** 531 * Starts a user in background on the secondary display, asserting it was properly started. 532 * 533 * <p><b>NOTE: </b>should only be used as a helper method, not to test the behavior of the 534 * {@link UserVisibilityMediator#assignUserToDisplayOnStart(int, int, boolean, int)} method per 535 * se. 536 */ startUserInSecondaryDisplay(@serIdInt int userId, int displayId)537 protected final void startUserInSecondaryDisplay(@UserIdInt int userId, int displayId) { 538 Log.d(TAG, "startUserInSecondaryDisplay(" + userId + ", " + displayId + ")"); 539 int result = mMediator.assignUserToDisplayOnStart(userId, userId, BG_VISIBLE, displayId); 540 if (result != USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE) { 541 throw new IllegalStateException("Failed to startuser " + userId 542 + " on background: mediator returned " + userAssignmentResultToString(result)); 543 } 544 } 545 addListenerForNoEvents()546 protected AsyncUserVisibilityListener addListenerForNoEvents() { 547 AsyncUserVisibilityListener listener = mListenerFactory.forNoEvents(); 548 mMediator.addListener(listener); 549 return listener; 550 } 551 addListenerForEvents( UserVisibilityChangedEvent... events)552 protected AsyncUserVisibilityListener addListenerForEvents( 553 UserVisibilityChangedEvent... events) { 554 AsyncUserVisibilityListener listener = mListenerFactory.forEvents(events); 555 mMediator.addListener(listener); 556 return listener; 557 } 558 assertStartUserResult(int actualResult, int expectedResult)559 protected void assertStartUserResult(int actualResult, int expectedResult) { 560 assertStartUserResult(actualResult, expectedResult, ""); 561 } 562 563 @SuppressWarnings("AnnotateFormatMethod") assertStartUserResult(int actualResult, int expectedResult, String extraMessageFormat, Object... extraMessageArguments)564 protected void assertStartUserResult(int actualResult, int expectedResult, 565 String extraMessageFormat, Object... extraMessageArguments) { 566 String extraMessage = String.format(extraMessageFormat, extraMessageArguments); 567 assertWithMessage("startUser() result %s(where %s=%s and %s=%s)", extraMessage, 568 expectedResult, userAssignmentResultToString(expectedResult), 569 actualResult, userAssignmentResultToString(actualResult)) 570 .that(actualResult).isEqualTo(expectedResult); 571 } 572 assertBgUserBecomesInvisibleOnStop(@serIdInt int userId)573 protected void assertBgUserBecomesInvisibleOnStop(@UserIdInt int userId) { 574 Log.d(TAG, "Stopping user " + userId); 575 mMediator.unassignUserFromDisplayOnStop(userId); 576 expectUserIsNotVisibleAtAll(userId); 577 } 578 579 /** 580 * Assigns and unassigns the user to / from an extra display, asserting the visibility state in 581 * between. 582 * 583 * <p>It assumes the user was not visible in the display beforehand. 584 */ assertUserCanBeAssignedExtraDisplay(@serIdInt int userId, int displayId)585 protected void assertUserCanBeAssignedExtraDisplay(@UserIdInt int userId, int displayId) { 586 assertUserCanBeAssignedExtraDisplay(userId, displayId, /* unassign= */ true); 587 } 588 assertUserCanBeAssignedExtraDisplay(@serIdInt int userId, int displayId, boolean unassign)589 protected void assertUserCanBeAssignedExtraDisplay(@UserIdInt int userId, int displayId, 590 boolean unassign) { 591 592 expectUserIsNotVisibleOnDisplay(userId, displayId); 593 594 Log.d(TAG, "Calling assignUserToExtraDisplay(" + userId + ", " + displayId + ")"); 595 assertWithMessage("assignUserToExtraDisplay(%s, %s)", userId, displayId) 596 .that(mMediator.assignUserToExtraDisplay(userId, displayId)) 597 .isTrue(); 598 expectUserIsVisibleOnDisplay(userId, displayId); 599 expectDisplaysAssignedToUserContainsDisplayId(userId, displayId); 600 601 if (unassign) { 602 Log.d(TAG, "Calling unassignUserFromExtraDisplay(" + userId + ", " + displayId + ")"); 603 assertWithMessage("unassignUserFromExtraDisplay(%s, %s)", userId, displayId) 604 .that(mMediator.unassignUserFromExtraDisplay(userId, displayId)) 605 .isTrue(); 606 expectUserIsNotVisibleOnDisplay(userId, displayId); 607 expectDisplaysAssignedToUserDoesNotContainDisplayId(userId, displayId); 608 } 609 } 610 611 /** 612 * Asserts that a user (already visible or not) cannot be assigned to an extra display (and 613 * hence won't be visible on that display). 614 */ assertUserCannotBeAssignedExtraDisplay(@serIdInt int userId, int displayId)615 protected void assertUserCannotBeAssignedExtraDisplay(@UserIdInt int userId, int displayId) { 616 expectWithMessage("assignUserToExtraDisplay(%s, %s)", userId, displayId) 617 .that(mMediator.assignUserToExtraDisplay(userId, displayId)) 618 .isFalse(); 619 expectUserIsNotVisibleOnDisplay(userId, displayId); 620 } 621 622 /** 623 * Asserts that an invisible user cannot be assigned to an extra display. 624 */ assertInvisibleUserCannotBeAssignedExtraDisplay(@serIdInt int userId, int displayId)625 protected void assertInvisibleUserCannotBeAssignedExtraDisplay(@UserIdInt int userId, 626 int displayId) { 627 assertUserCannotBeAssignedExtraDisplay(userId, displayId); 628 expectNoDisplayAssignedToUser(userId); 629 expectInitialCurrentUserAssignedToDisplay(displayId); 630 } 631 expectUserIsVisible(@serIdInt int userId)632 protected void expectUserIsVisible(@UserIdInt int userId) { 633 expectWithMessage("isUserVisible(%s)", userId) 634 .that(mMediator.isUserVisible(userId)) 635 .isTrue(); 636 } 637 expectVisibleUsers(@serIdInt Integer... userIds)638 protected void expectVisibleUsers(@UserIdInt Integer... userIds) { 639 IntArray visibleUsers = mMediator.getVisibleUsers(); 640 expectWithMessage("getVisibleUsers()").that(visibleUsers).isNotNull(); 641 expectWithMessage("getVisibleUsers()").that(visibleUsers.toArray()).asList() 642 .containsExactlyElementsIn(Arrays.asList(userIds)); 643 } 644 expectUserIsVisibleOnDisplay(@serIdInt int userId, int displayId)645 protected void expectUserIsVisibleOnDisplay(@UserIdInt int userId, int displayId) { 646 expectWithMessage("isUserVisible(%s, %s)", userId, displayId) 647 .that(mMediator.isUserVisible(userId, displayId)) 648 .isTrue(); 649 } 650 expectUserIsNotVisibleOnDisplay(@serIdInt int userId, int displayId)651 protected void expectUserIsNotVisibleOnDisplay(@UserIdInt int userId, int displayId) { 652 expectWithMessage("isUserVisible(%s, %s)", userId, displayId) 653 .that(mMediator.isUserVisible(userId, displayId)) 654 .isFalse(); 655 } 656 expectUserIsNotVisibleOnDisplay(String when, @UserIdInt int userId, int displayId)657 protected void expectUserIsNotVisibleOnDisplay(String when, @UserIdInt int userId, 658 int displayId) { 659 String suffix = TextUtils.isEmpty(when) ? "" : " on " + when; 660 expectWithMessage("isUserVisible(%s, %s)%s", userId, displayId, suffix) 661 .that(mMediator.isUserVisible(userId, displayId)) 662 .isFalse(); 663 } 664 expectUserIsNotVisibleAtAll(@serIdInt int userId)665 protected void expectUserIsNotVisibleAtAll(@UserIdInt int userId) { 666 expectWithMessage("isUserVisible(%s)", userId) 667 .that(mMediator.isUserVisible(userId)) 668 .isFalse(); 669 expectUserIsNotVisibleOnDisplay(userId, DEFAULT_DISPLAY); 670 expectUserIsNotVisibleOnDisplay(userId, INVALID_DISPLAY); 671 expectUserIsNotVisibleOnDisplay(userId, SECONDARY_DISPLAY_ID); 672 expectUserIsNotVisibleOnDisplay(userId, OTHER_SECONDARY_DISPLAY_ID); 673 expectDisplaysAssignedToUserIsEmpty(userId); 674 } 675 expectDisplayAssignedToUser(@serIdInt int userId, int displayId)676 protected void expectDisplayAssignedToUser(@UserIdInt int userId, int displayId) { 677 expectWithMessage("getMainDisplayAssignedToUser(%s)", userId) 678 .that(mMediator.getMainDisplayAssignedToUser(userId)).isEqualTo(displayId); 679 } 680 expectNoDisplayAssignedToUser(@serIdInt int userId)681 protected void expectNoDisplayAssignedToUser(@UserIdInt int userId) { 682 expectWithMessage("getMainDisplayAssignedToUser(%s)", userId) 683 .that(mMediator.getMainDisplayAssignedToUser(userId)).isEqualTo(INVALID_DISPLAY); 684 } 685 expectDisplaysAssignedToUserContainsDisplayId( @serIdInt int userId, int displayId)686 protected void expectDisplaysAssignedToUserContainsDisplayId( 687 @UserIdInt int userId, int displayId) { 688 expectWithMessage("getDisplaysAssignedToUser(%s)", userId) 689 .that(mMediator.getDisplaysAssignedToUser(userId)).asList().contains(displayId); 690 } 691 expectDisplaysAssignedToUserDoesNotContainDisplayId( @serIdInt int userId, int displayId)692 protected void expectDisplaysAssignedToUserDoesNotContainDisplayId( 693 @UserIdInt int userId, int displayId) { 694 expectWithMessage("getDisplaysAssignedToUser(%s)", userId) 695 .that(mMediator.getDisplaysAssignedToUser(userId)).asList() 696 .doesNotContain(displayId); 697 } 698 expectDisplaysAssignedToUserIsEmpty(@serIdInt int userId)699 protected void expectDisplaysAssignedToUserIsEmpty(@UserIdInt int userId) { 700 expectWithMessage("getDisplaysAssignedToUser(%s)", userId) 701 .that(mMediator.getDisplaysAssignedToUser(userId)).isNull(); 702 } 703 expectUserCannotBeUnassignedFromDisplay(@serIdInt int userId, int displayId)704 protected void expectUserCannotBeUnassignedFromDisplay(@UserIdInt int userId, int displayId) { 705 expectWithMessage("unassignUserFromExtraDisplay(%s, %s)", userId, displayId) 706 .that(mMediator.unassignUserFromExtraDisplay(userId, displayId)).isFalse(); 707 } 708 expectUserAssignedToDisplay(int displayId, @UserIdInt int userId)709 protected void expectUserAssignedToDisplay(int displayId, @UserIdInt int userId) { 710 expectWithMessage("getUserAssignedToDisplay(%s)", displayId) 711 .that(mMediator.getUserAssignedToDisplay(displayId)).isEqualTo(userId); 712 } 713 expectInitialCurrentUserAssignedToDisplay(int displayId)714 protected void expectInitialCurrentUserAssignedToDisplay(int displayId) { 715 expectWithMessage("getUserAssignedToDisplay(%s)", displayId) 716 .that(mMediator.getUserAssignedToDisplay(displayId)) 717 .isEqualTo(INITIAL_CURRENT_USER_ID); 718 } 719 } 720