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, false)); 152 assertThrows(IllegalArgumentException.class, () -> mMediator 153 .assignUserToDisplayOnStart(USER_ALL, USER_ID, FG, DEFAULT_DISPLAY, false)); 154 assertThrows(IllegalArgumentException.class, () -> mMediator 155 .assignUserToDisplayOnStart(USER_CURRENT, USER_ID, FG, DEFAULT_DISPLAY, false)); 156 assertThrows(IllegalArgumentException.class, () -> mMediator 157 .assignUserToDisplayOnStart(USER_CURRENT_OR_SELF, USER_ID, FG, DEFAULT_DISPLAY, 158 false)); 159 } 160 161 @Test testAssignUserToDisplayOnStart_invalidUserStartMode()162 public final void testAssignUserToDisplayOnStart_invalidUserStartMode() { 163 assertThrows(IllegalArgumentException.class, () -> mMediator 164 .assignUserToDisplayOnStart(USER_ID, USER_ID, 666, DEFAULT_DISPLAY, false)); 165 } 166 167 @Test testStartFgUser_onSecondaryDisplay()168 public final void testStartFgUser_onSecondaryDisplay() throws Exception { 169 AsyncUserVisibilityListener listener = addListenerForNoEvents(); 170 171 int result = mMediator.assignUserToDisplayOnStart(USER_ID, USER_ID, FG, 172 SECONDARY_DISPLAY_ID, false); 173 assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE); 174 175 expectUserIsNotVisibleAtAll(USER_ID); 176 expectNoDisplayAssignedToUser(USER_ID); 177 expectInitialCurrentUserAssignedToDisplay(DEFAULT_DISPLAY); 178 179 listener.verify(); 180 } 181 182 @Test testStartBgUser_onDefaultDisplay()183 public final void testStartBgUser_onDefaultDisplay() throws Exception { 184 AsyncUserVisibilityListener listener = addListenerForNoEvents(); 185 186 int result = mMediator.assignUserToDisplayOnStart(USER_ID, USER_ID, BG, DEFAULT_DISPLAY, 187 false); 188 assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE); 189 190 expectUserIsNotVisibleAtAll(USER_ID); 191 expectNoDisplayAssignedToUser(USER_ID); 192 expectInitialCurrentUserAssignedToDisplay(DEFAULT_DISPLAY); 193 194 assertInvisibleUserCannotBeAssignedExtraDisplay(USER_ID, SECONDARY_DISPLAY_ID); 195 196 listener.verify(); 197 } 198 visibleBgUserCannotBeStartedOnDefaultDisplayTest()199 protected final @UserIdInt int visibleBgUserCannotBeStartedOnDefaultDisplayTest() 200 throws Exception { 201 AsyncUserVisibilityListener listener = addListenerForNoEvents(); 202 203 int result = mMediator.assignUserToDisplayOnStart(USER_ID, USER_ID, BG_VISIBLE, 204 DEFAULT_DISPLAY, false); 205 assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE); 206 207 expectUserIsNotVisibleAtAll(USER_ID); 208 expectNoDisplayAssignedToUser(USER_ID); 209 210 listener.verify(); 211 212 return USER_ID; 213 } 214 215 @Test testStartBgUser_onSecondaryDisplay()216 public final void testStartBgUser_onSecondaryDisplay() throws Exception { 217 AsyncUserVisibilityListener listener = addListenerForNoEvents(); 218 219 int result = mMediator.assignUserToDisplayOnStart(USER_ID, USER_ID, BG, 220 SECONDARY_DISPLAY_ID, false); 221 assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE); 222 223 expectUserIsNotVisibleAtAll(USER_ID); 224 expectNoDisplayAssignedToUser(USER_ID); 225 226 assertInvisibleUserCannotBeAssignedExtraDisplay(USER_ID, SECONDARY_DISPLAY_ID); 227 assertInvisibleUserCannotBeAssignedExtraDisplay(USER_ID, OTHER_SECONDARY_DISPLAY_ID); 228 229 listener.verify(); 230 } 231 232 @Test testStartBgSystemUser_onSecondaryDisplay()233 public final void testStartBgSystemUser_onSecondaryDisplay() throws Exception { 234 AsyncUserVisibilityListener listener = addListenerForEvents( 235 onInvisible(INITIAL_CURRENT_USER_ID), 236 onVisible(USER_ID)); 237 // Must explicitly set current user, as USER_SYSTEM is the default current user 238 startForegroundUser(USER_ID); 239 240 int result = mMediator.assignUserToDisplayOnStart(USER_SYSTEM, USER_SYSTEM, BG, 241 SECONDARY_DISPLAY_ID, false); 242 assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE); 243 244 expectUserIsNotVisibleAtAll(USER_SYSTEM); 245 246 expectNoDisplayAssignedToUser(USER_SYSTEM); 247 expectUserAssignedToDisplay(SECONDARY_DISPLAY_ID, USER_ID); 248 249 assertUserCannotBeAssignedExtraDisplay(USER_SYSTEM, SECONDARY_DISPLAY_ID); 250 assertUserCannotBeAssignedExtraDisplay(USER_SYSTEM, OTHER_SECONDARY_DISPLAY_ID); 251 252 listener.verify(); 253 } 254 255 @Test testStopVisibleBgProfile()256 public final void testStopVisibleBgProfile() throws Exception { 257 AsyncUserVisibilityListener listener = addListenerForEvents( 258 onInvisible(INITIAL_CURRENT_USER_ID), 259 onVisible(PARENT_USER_ID), 260 onVisible(PROFILE_USER_ID), 261 onInvisible(PROFILE_USER_ID)); 262 startDefaultProfile(); 263 264 mMediator.unassignUserFromDisplayOnStop(PROFILE_USER_ID); 265 266 expectUserIsNotVisibleAtAll(PROFILE_USER_ID); 267 expectNoDisplayAssignedToUser(PROFILE_USER_ID); 268 expectUserAssignedToDisplay(DEFAULT_DISPLAY, PARENT_USER_ID); 269 270 listener.verify(); 271 } 272 273 @Test testVisibleBgProfileBecomesInvisibleWhenParentIsSwitchedOut()274 public final void testVisibleBgProfileBecomesInvisibleWhenParentIsSwitchedOut() 275 throws Exception { 276 AsyncUserVisibilityListener listener = addListenerForEvents( 277 onInvisible(INITIAL_CURRENT_USER_ID), 278 onVisible(PARENT_USER_ID), 279 onVisible(PROFILE_USER_ID), 280 onInvisible(PARENT_USER_ID), 281 onInvisible(PROFILE_USER_ID), 282 onVisible(OTHER_USER_ID)); 283 startDefaultProfile(); 284 285 startForegroundUser(OTHER_USER_ID); 286 287 expectUserIsNotVisibleAtAll(PROFILE_USER_ID); 288 expectNoDisplayAssignedToUser(PROFILE_USER_ID); 289 expectUserAssignedToDisplay(DEFAULT_DISPLAY, OTHER_USER_ID); 290 291 assertUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID); 292 293 listener.verify(); 294 } 295 296 @Test testStartVisibleBgProfile_onDefaultDisplay_whenParentIsNotStarted()297 public final void testStartVisibleBgProfile_onDefaultDisplay_whenParentIsNotStarted() 298 throws Exception { 299 AsyncUserVisibilityListener listener = addListenerForNoEvents(); 300 301 int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, 302 BG_VISIBLE, DEFAULT_DISPLAY, false); 303 assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE); 304 305 expectUserIsNotVisibleAtAll(PROFILE_USER_ID); 306 expectNoDisplayAssignedToUser(PROFILE_USER_ID); 307 308 listener.verify(); 309 } 310 311 @Test testStartVisibleBgProfile_onDefaultDisplay_whenParentIsStartedOnBg()312 public final void testStartVisibleBgProfile_onDefaultDisplay_whenParentIsStartedOnBg() 313 throws Exception { 314 AsyncUserVisibilityListener listener = addListenerForNoEvents(); 315 startBackgroundUser(PARENT_USER_ID); 316 317 int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, 318 BG_VISIBLE, DEFAULT_DISPLAY, false); 319 assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE); 320 321 expectUserIsNotVisibleAtAll(PROFILE_USER_ID); 322 323 expectNoDisplayAssignedToUser(PROFILE_USER_ID); 324 expectInitialCurrentUserAssignedToDisplay(DEFAULT_DISPLAY); 325 326 assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID); 327 328 listener.verify(); 329 } 330 331 // Not supported - profiles can only be started on default display 332 @Test testStartVisibleBgProfile_onSecondaryDisplay()333 public final void testStartVisibleBgProfile_onSecondaryDisplay() throws Exception { 334 AsyncUserVisibilityListener listener = addListenerForNoEvents(); 335 336 int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, 337 BG_VISIBLE, SECONDARY_DISPLAY_ID, false); 338 assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE); 339 340 expectUserIsNotVisibleAtAll(PROFILE_USER_ID); 341 expectNoDisplayAssignedToUser(PROFILE_USER_ID); 342 expectInitialCurrentUserAssignedToDisplay(SECONDARY_DISPLAY_ID); 343 344 assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID); 345 assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, 346 OTHER_SECONDARY_DISPLAY_ID); 347 348 listener.verify(); 349 } 350 351 @Test testStartBgProfile_onDefaultDisplay_whenParentIsNotStarted()352 public final void testStartBgProfile_onDefaultDisplay_whenParentIsNotStarted() 353 throws Exception { 354 AsyncUserVisibilityListener listener = addListenerForNoEvents(); 355 356 int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, BG, 357 DEFAULT_DISPLAY, false); 358 assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE); 359 360 expectUserIsNotVisibleAtAll(PROFILE_USER_ID); 361 expectNoDisplayAssignedToUser(PROFILE_USER_ID); 362 363 listener.verify(); 364 } 365 366 @Test testStartBgProfile_onDefaultDisplay_whenParentIsStartedOnBg()367 public final void testStartBgProfile_onDefaultDisplay_whenParentIsStartedOnBg() 368 throws Exception { 369 AsyncUserVisibilityListener listener = addListenerForNoEvents(); 370 startBackgroundUser(PARENT_USER_ID); 371 372 int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, BG, 373 DEFAULT_DISPLAY, false); 374 assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE); 375 376 expectUserIsNotVisibleAtAll(PROFILE_USER_ID); 377 378 expectNoDisplayAssignedToUser(PROFILE_USER_ID); 379 expectInitialCurrentUserAssignedToDisplay(DEFAULT_DISPLAY); 380 381 assertUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID); 382 383 listener.verify(); 384 } 385 386 @Test testStartBgProfile_onSecondaryDisplay()387 public final void testStartBgProfile_onSecondaryDisplay() throws Exception { 388 AsyncUserVisibilityListener listener = addListenerForNoEvents(); 389 390 int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, BG, 391 SECONDARY_DISPLAY_ID, false); 392 assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE); 393 394 expectUserIsNotVisibleAtAll(PROFILE_USER_ID); 395 expectNoDisplayAssignedToUser(PROFILE_USER_ID); 396 expectInitialCurrentUserAssignedToDisplay(SECONDARY_DISPLAY_ID); 397 398 assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID); 399 assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, 400 OTHER_SECONDARY_DISPLAY_ID); 401 402 listener.verify(); 403 } 404 405 @Test testStartFgProfile_onDefaultDisplay()406 public final void testStartFgProfile_onDefaultDisplay() throws Exception { 407 AsyncUserVisibilityListener listener = addListenerForNoEvents(); 408 409 int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, FG, 410 DEFAULT_DISPLAY, false); 411 assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE); 412 413 expectUserIsNotVisibleAtAll(PROFILE_USER_ID); 414 415 expectNoDisplayAssignedToUser(PROFILE_USER_ID); 416 expectInitialCurrentUserAssignedToDisplay(DEFAULT_DISPLAY); 417 418 assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, DEFAULT_DISPLAY); 419 assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID); 420 421 listener.verify(); 422 } 423 424 @Test testStartFgProfile_onSecondaryDisplay()425 public final void testStartFgProfile_onSecondaryDisplay() throws Exception { 426 AsyncUserVisibilityListener listener = addListenerForNoEvents(); 427 428 int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, FG, 429 SECONDARY_DISPLAY_ID, false); 430 assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE); 431 432 expectUserIsNotVisibleAtAll(PROFILE_USER_ID); 433 expectNoDisplayAssignedToUser(PROFILE_USER_ID); 434 expectInitialCurrentUserAssignedToDisplay(SECONDARY_DISPLAY_ID); 435 436 assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID); 437 assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, 438 OTHER_SECONDARY_DISPLAY_ID); 439 440 listener.verify(); 441 } 442 443 @Test testIsUserVisible_invalidUsers()444 public final void testIsUserVisible_invalidUsers() throws Exception { 445 expectWithMessage("isUserVisible(%s)", USER_NULL) 446 .that(mMediator.isUserVisible(USER_NULL)) 447 .isFalse(); 448 expectWithMessage("isUserVisible(%s)", USER_NULL) 449 .that(mMediator.isUserVisible(USER_ALL)) 450 .isFalse(); 451 expectWithMessage("isUserVisible(%s)", USER_NULL) 452 .that(mMediator.isUserVisible(USER_CURRENT)) 453 .isFalse(); 454 expectWithMessage("isUserVisible(%s)", USER_NULL) 455 .that(mMediator.isUserVisible(USER_CURRENT_OR_SELF)) 456 .isFalse(); 457 } 458 459 @Test testRemoveListener()460 public final void testRemoveListener() throws Exception { 461 AsyncUserVisibilityListener listener = addListenerForNoEvents(); 462 463 mMediator.removeListener(listener); 464 465 startForegroundUser(USER_ID); 466 listener.verify(); 467 } 468 469 @Test testOnSystemUserVisibilityChanged()470 public final void testOnSystemUserVisibilityChanged() throws Exception { 471 AsyncUserVisibilityListener listener = addListenerForEvents(onVisible(USER_SYSTEM)); 472 473 mMediator.onSystemUserVisibilityChanged(/* visible= */ true); 474 475 listener.verify(); 476 } 477 478 /** 479 * Starts a user in foreground on the default display, asserting it was properly started. 480 * 481 * <p><b>NOTE: </b>should only be used as a helper method, not to test the behavior of the 482 * {@link UserVisibilityMediator#assignUserToDisplayOnStart(int, int, boolean, int)} method per 483 * se. 484 */ startForegroundUser(@serIdInt int userId)485 protected void startForegroundUser(@UserIdInt int userId) { 486 Log.d(TAG, "startForegroundUSer(" + userId + ")"); 487 int result = mMediator.assignUserToDisplayOnStart(userId, userId, FG, DEFAULT_DISPLAY, 488 false); 489 if (result != USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE) { 490 throw new IllegalStateException("Failed to start foreground user " + userId 491 + ": mediator returned " + userAssignmentResultToString(result)); 492 } 493 } 494 495 /** 496 * Starts a user in background on the default display, asserting it was properly started. 497 * 498 * <p><b>NOTE: </b>should only be used as a helper method, not to test the behavior of the 499 * {@link UserVisibilityMediator#assignUserToDisplayOnStart(int, int, boolean, int)} method per 500 * se. 501 */ startBackgroundUser(@serIdInt int userId)502 protected void startBackgroundUser(@UserIdInt int userId) { 503 Log.d(TAG, "startBackgroundUser(" + userId + ")"); 504 int result = mMediator.assignUserToDisplayOnStart(userId, userId, BG, DEFAULT_DISPLAY, 505 false); 506 if (result != USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE) { 507 throw new IllegalStateException("Failed to start background user " + userId 508 + ": mediator returned " + userAssignmentResultToString(result)); 509 } 510 } 511 512 /** 513 * Starts the {@link #PROFILE_USER_ID default profile} in background and its 514 * {@link #PARENT_USER_ID parent} in foreground on the main display, asserting that 515 * both were properly started. 516 * 517 * <p><b>NOTE: </b>should only be used as a helper method, not to test the behavior of the 518 * {@link UserVisibilityMediator#assignUserToDisplayOnStart(int, int, boolean, int)} method per 519 * se. 520 */ startDefaultProfile()521 protected void startDefaultProfile() { 522 startForegroundUser(PARENT_USER_ID); 523 Log.d(TAG, "starting default profile (" + PROFILE_USER_ID + ") in background after starting" 524 + " its parent (" + PARENT_USER_ID + ") on foreground"); 525 526 int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, 527 BG_VISIBLE, DEFAULT_DISPLAY, false); 528 if (result != USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE) { 529 throw new IllegalStateException("Failed to start profile user " + PROFILE_USER_ID 530 + ": mediator returned " + userAssignmentResultToString(result)); 531 } 532 } 533 534 /** 535 * Starts a user in background on the secondary display, asserting it was properly started. 536 * 537 * <p><b>NOTE: </b>should only be used as a helper method, not to test the behavior of the 538 * {@link UserVisibilityMediator#assignUserToDisplayOnStart(int, int, boolean, int)} method per 539 * se. 540 */ startUserInSecondaryDisplay(@serIdInt int userId, int displayId)541 protected final void startUserInSecondaryDisplay(@UserIdInt int userId, int displayId) { 542 Log.d(TAG, "startUserInSecondaryDisplay(" + userId + ", " + displayId + ")"); 543 int result = mMediator.assignUserToDisplayOnStart(userId, userId, BG_VISIBLE, displayId, 544 false); 545 if (result != USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE) { 546 throw new IllegalStateException("Failed to startuser " + userId 547 + " on background: mediator returned " + userAssignmentResultToString(result)); 548 } 549 } 550 addListenerForNoEvents()551 protected AsyncUserVisibilityListener addListenerForNoEvents() { 552 AsyncUserVisibilityListener listener = mListenerFactory.forNoEvents(); 553 mMediator.addListener(listener); 554 return listener; 555 } 556 addListenerForEvents( UserVisibilityChangedEvent... events)557 protected AsyncUserVisibilityListener addListenerForEvents( 558 UserVisibilityChangedEvent... events) { 559 AsyncUserVisibilityListener listener = mListenerFactory.forEvents(events); 560 mMediator.addListener(listener); 561 return listener; 562 } 563 assertStartUserResult(int actualResult, int expectedResult)564 protected void assertStartUserResult(int actualResult, int expectedResult) { 565 assertStartUserResult(actualResult, expectedResult, ""); 566 } 567 568 @SuppressWarnings("AnnotateFormatMethod") assertStartUserResult(int actualResult, int expectedResult, String extraMessageFormat, Object... extraMessageArguments)569 protected void assertStartUserResult(int actualResult, int expectedResult, 570 String extraMessageFormat, Object... extraMessageArguments) { 571 String extraMessage = String.format(extraMessageFormat, extraMessageArguments); 572 assertWithMessage("startUser() result %s(where %s=%s and %s=%s)", extraMessage, 573 expectedResult, userAssignmentResultToString(expectedResult), 574 actualResult, userAssignmentResultToString(actualResult)) 575 .that(actualResult).isEqualTo(expectedResult); 576 } 577 assertBgUserBecomesInvisibleOnStop(@serIdInt int userId)578 protected void assertBgUserBecomesInvisibleOnStop(@UserIdInt int userId) { 579 Log.d(TAG, "Stopping user " + userId); 580 mMediator.unassignUserFromDisplayOnStop(userId); 581 expectUserIsNotVisibleAtAll(userId); 582 } 583 584 /** 585 * Assigns and unassigns the user to / from an extra display, asserting the visibility state in 586 * between. 587 * 588 * <p>It assumes the user was not visible in the display beforehand. 589 */ assertUserCanBeAssignedExtraDisplay(@serIdInt int userId, int displayId)590 protected void assertUserCanBeAssignedExtraDisplay(@UserIdInt int userId, int displayId) { 591 assertUserCanBeAssignedExtraDisplay(userId, displayId, /* unassign= */ true); 592 } 593 assertUserCanBeAssignedExtraDisplay(@serIdInt int userId, int displayId, boolean unassign)594 protected void assertUserCanBeAssignedExtraDisplay(@UserIdInt int userId, int displayId, 595 boolean unassign) { 596 597 expectUserIsNotVisibleOnDisplay(userId, displayId); 598 599 Log.d(TAG, "Calling assignUserToExtraDisplay(" + userId + ", " + displayId + ")"); 600 assertWithMessage("assignUserToExtraDisplay(%s, %s)", userId, displayId) 601 .that(mMediator.assignUserToExtraDisplay(userId, displayId)) 602 .isTrue(); 603 expectUserIsVisibleOnDisplay(userId, displayId); 604 expectDisplaysAssignedToUserContainsDisplayId(userId, displayId); 605 606 if (unassign) { 607 Log.d(TAG, "Calling unassignUserFromExtraDisplay(" + userId + ", " + displayId + ")"); 608 assertWithMessage("unassignUserFromExtraDisplay(%s, %s)", userId, displayId) 609 .that(mMediator.unassignUserFromExtraDisplay(userId, displayId)) 610 .isTrue(); 611 expectUserIsNotVisibleOnDisplay(userId, displayId); 612 expectDisplaysAssignedToUserDoesNotContainDisplayId(userId, displayId); 613 } 614 } 615 616 /** 617 * Asserts that a user (already visible or not) cannot be assigned to an extra display (and 618 * hence won't be visible on that display). 619 */ assertUserCannotBeAssignedExtraDisplay(@serIdInt int userId, int displayId)620 protected void assertUserCannotBeAssignedExtraDisplay(@UserIdInt int userId, int displayId) { 621 expectWithMessage("assignUserToExtraDisplay(%s, %s)", userId, displayId) 622 .that(mMediator.assignUserToExtraDisplay(userId, displayId)) 623 .isFalse(); 624 expectUserIsNotVisibleOnDisplay(userId, displayId); 625 } 626 627 /** 628 * Asserts that an invisible user cannot be assigned to an extra display. 629 */ assertInvisibleUserCannotBeAssignedExtraDisplay(@serIdInt int userId, int displayId)630 protected void assertInvisibleUserCannotBeAssignedExtraDisplay(@UserIdInt int userId, 631 int displayId) { 632 assertUserCannotBeAssignedExtraDisplay(userId, displayId); 633 expectNoDisplayAssignedToUser(userId); 634 expectInitialCurrentUserAssignedToDisplay(displayId); 635 } 636 expectUserIsVisible(@serIdInt int userId)637 protected void expectUserIsVisible(@UserIdInt int userId) { 638 expectWithMessage("isUserVisible(%s)", userId) 639 .that(mMediator.isUserVisible(userId)) 640 .isTrue(); 641 } 642 expectVisibleUsers(@serIdInt Integer... userIds)643 protected void expectVisibleUsers(@UserIdInt Integer... userIds) { 644 IntArray visibleUsers = mMediator.getVisibleUsers(); 645 expectWithMessage("getVisibleUsers()").that(visibleUsers).isNotNull(); 646 expectWithMessage("getVisibleUsers()").that(visibleUsers.toArray()).asList() 647 .containsExactlyElementsIn(Arrays.asList(userIds)); 648 } 649 expectUserIsVisibleOnDisplay(@serIdInt int userId, int displayId)650 protected void expectUserIsVisibleOnDisplay(@UserIdInt int userId, int displayId) { 651 expectWithMessage("isUserVisible(%s, %s)", userId, displayId) 652 .that(mMediator.isUserVisible(userId, displayId)) 653 .isTrue(); 654 } 655 expectUserIsNotVisibleOnDisplay(@serIdInt int userId, int displayId)656 protected void expectUserIsNotVisibleOnDisplay(@UserIdInt int userId, int displayId) { 657 expectWithMessage("isUserVisible(%s, %s)", userId, displayId) 658 .that(mMediator.isUserVisible(userId, displayId)) 659 .isFalse(); 660 } 661 expectUserIsNotVisibleOnDisplay(String when, @UserIdInt int userId, int displayId)662 protected void expectUserIsNotVisibleOnDisplay(String when, @UserIdInt int userId, 663 int displayId) { 664 String suffix = TextUtils.isEmpty(when) ? "" : " on " + when; 665 expectWithMessage("isUserVisible(%s, %s)%s", userId, displayId, suffix) 666 .that(mMediator.isUserVisible(userId, displayId)) 667 .isFalse(); 668 } 669 expectUserIsNotVisibleAtAll(@serIdInt int userId)670 protected void expectUserIsNotVisibleAtAll(@UserIdInt int userId) { 671 expectWithMessage("isUserVisible(%s)", userId) 672 .that(mMediator.isUserVisible(userId)) 673 .isFalse(); 674 expectUserIsNotVisibleOnDisplay(userId, DEFAULT_DISPLAY); 675 expectUserIsNotVisibleOnDisplay(userId, INVALID_DISPLAY); 676 expectUserIsNotVisibleOnDisplay(userId, SECONDARY_DISPLAY_ID); 677 expectUserIsNotVisibleOnDisplay(userId, OTHER_SECONDARY_DISPLAY_ID); 678 expectDisplaysAssignedToUserIsEmpty(userId); 679 } 680 expectDisplayAssignedToUser(@serIdInt int userId, int displayId)681 protected void expectDisplayAssignedToUser(@UserIdInt int userId, int displayId) { 682 expectWithMessage("getMainDisplayAssignedToUser(%s)", userId) 683 .that(mMediator.getMainDisplayAssignedToUser(userId)).isEqualTo(displayId); 684 } 685 expectNoDisplayAssignedToUser(@serIdInt int userId)686 protected void expectNoDisplayAssignedToUser(@UserIdInt int userId) { 687 expectWithMessage("getMainDisplayAssignedToUser(%s)", userId) 688 .that(mMediator.getMainDisplayAssignedToUser(userId)).isEqualTo(INVALID_DISPLAY); 689 } 690 expectDisplaysAssignedToUserContainsDisplayId( @serIdInt int userId, int displayId)691 protected void expectDisplaysAssignedToUserContainsDisplayId( 692 @UserIdInt int userId, int displayId) { 693 expectWithMessage("getDisplaysAssignedToUser(%s)", userId) 694 .that(mMediator.getDisplaysAssignedToUser(userId)).asList().contains(displayId); 695 } 696 expectDisplaysAssignedToUserDoesNotContainDisplayId( @serIdInt int userId, int displayId)697 protected void expectDisplaysAssignedToUserDoesNotContainDisplayId( 698 @UserIdInt int userId, int displayId) { 699 expectWithMessage("getDisplaysAssignedToUser(%s)", userId) 700 .that(mMediator.getDisplaysAssignedToUser(userId)).asList() 701 .doesNotContain(displayId); 702 } 703 expectDisplaysAssignedToUserIsEmpty(@serIdInt int userId)704 protected void expectDisplaysAssignedToUserIsEmpty(@UserIdInt int userId) { 705 expectWithMessage("getDisplaysAssignedToUser(%s)", userId) 706 .that(mMediator.getDisplaysAssignedToUser(userId)).isNull(); 707 } 708 expectUserCannotBeUnassignedFromDisplay(@serIdInt int userId, int displayId)709 protected void expectUserCannotBeUnassignedFromDisplay(@UserIdInt int userId, int displayId) { 710 expectWithMessage("unassignUserFromExtraDisplay(%s, %s)", userId, displayId) 711 .that(mMediator.unassignUserFromExtraDisplay(userId, displayId)).isFalse(); 712 } 713 expectUserAssignedToDisplay(int displayId, @UserIdInt int userId)714 protected void expectUserAssignedToDisplay(int displayId, @UserIdInt int userId) { 715 expectWithMessage("getUserAssignedToDisplay(%s)", displayId) 716 .that(mMediator.getUserAssignedToDisplay(displayId)).isEqualTo(userId); 717 } 718 expectInitialCurrentUserAssignedToDisplay(int displayId)719 protected void expectInitialCurrentUserAssignedToDisplay(int displayId) { 720 expectWithMessage("getUserAssignedToDisplay(%s)", displayId) 721 .that(mMediator.getUserAssignedToDisplay(displayId)) 722 .isEqualTo(INITIAL_CURRENT_USER_ID); 723 } 724 } 725