1 /* 2 * Copyright (C) 2016 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.server.wm; 18 19 import static android.app.ActivityTaskManager.INVALID_STACK_ID; 20 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; 21 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; 22 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; 23 import static android.server.wm.ComponentNameUtils.getActivityName; 24 import static android.server.wm.ComponentNameUtils.getWindowName; 25 import static android.server.wm.StateLogger.logAlways; 26 import static android.server.wm.StateLogger.logE; 27 import static android.view.Display.DEFAULT_DISPLAY; 28 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; 29 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG; 30 31 import static com.google.common.truth.Truth.assertWithMessage; 32 33 import static org.hamcrest.Matchers.greaterThan; 34 import static org.hamcrest.Matchers.greaterThanOrEqualTo; 35 import static org.junit.Assert.assertEquals; 36 import static org.junit.Assert.assertFalse; 37 import static org.junit.Assert.assertNotEquals; 38 import static org.junit.Assert.assertNotNull; 39 import static org.junit.Assert.assertThat; 40 import static org.junit.Assert.assertTrue; 41 import static org.junit.Assert.fail; 42 import static org.junit.Assume.assumeTrue; 43 44 import android.content.ComponentName; 45 import android.graphics.Rect; 46 import android.util.SparseArray; 47 48 import java.util.Arrays; 49 import java.util.List; 50 import java.util.Objects; 51 import java.util.function.Consumer; 52 import java.util.function.Function; 53 import java.util.function.Predicate; 54 import java.util.stream.Stream; 55 56 /** Window Manager State helper class with assert and wait functions. */ 57 public class WindowManagerStateHelper extends WindowManagerState { 58 59 /** 60 * Compute AM and WM state of device, check validity and bounds. 61 * WM state will include only visible windows, stack and task bounds will be compared. 62 * 63 * @param componentNames array of activity names to wait for. 64 */ computeState(ComponentName... componentNames)65 public void computeState(ComponentName... componentNames) { 66 waitForValidState(Arrays.stream(componentNames) 67 .map(WaitForValidActivityState::new) 68 .toArray(WaitForValidActivityState[]::new)); 69 } 70 71 /** 72 * Compute AM and WM state of device, check validity and bounds. 73 * WM state will include only visible windows, stack and task bounds will be compared. 74 * 75 * @param waitForActivitiesVisible array of activity names to wait for. 76 */ computeState(WaitForValidActivityState... waitForActivitiesVisible)77 public void computeState(WaitForValidActivityState... waitForActivitiesVisible) { 78 waitForValidState(waitForActivitiesVisible); 79 } 80 81 /** 82 * Wait for the activities to appear and for valid state in AM and WM. 83 * 84 * @param activityNames name list of activities to wait for. 85 */ waitForValidState(ComponentName... activityNames)86 public void waitForValidState(ComponentName... activityNames) { 87 waitForValidState(Arrays.stream(activityNames) 88 .map(WaitForValidActivityState::new) 89 .toArray(WaitForValidActivityState[]::new)); 90 91 } 92 93 /** 94 * Wait for the activities to appear in proper stacks and for valid state in AM and WM. 95 * @param waitForActivitiesVisible array of activity states to wait for. 96 */ waitForValidState(WaitForValidActivityState... waitForActivitiesVisible)97 public void waitForValidState(WaitForValidActivityState... waitForActivitiesVisible) { 98 if (!Condition.waitFor("valid stacks and activities states", () -> { 99 // TODO: Get state of AM and WM at the same time to avoid mismatches caused by 100 // requesting dump in some intermediate state. 101 computeState(); 102 return !(shouldWaitForValidityCheck() 103 || shouldWaitForValidStacks() 104 || shouldWaitForActivities(waitForActivitiesVisible) 105 || shouldWaitForWindows()); 106 })) { 107 logE("***Waiting for states failed: " + Arrays.toString(waitForActivitiesVisible)); 108 } 109 } 110 waitForAllStoppedActivities()111 public void waitForAllStoppedActivities() { 112 if (!Condition.waitFor("all started activities have been removed", () -> { 113 computeState(); 114 return !containsStartedActivities(); 115 })) { 116 fail("All started activities have been removed"); 117 } 118 } 119 waitForAllNonHomeActivitiesToDestroyed()120 public void waitForAllNonHomeActivitiesToDestroyed() { 121 Condition.waitFor("all non-home activities to be destroyed", () -> { 122 computeState(); 123 for (Task rootTask : getRootTasks()) { 124 final Activity activity = rootTask.getActivity( 125 (a) -> !a.state.equals(STATE_DESTROYED) 126 && a.getActivityType() != ACTIVITY_TYPE_HOME); 127 if (activity != null) return false; 128 } 129 return true; 130 }); 131 } 132 133 /** 134 * Compute AM and WM state of device, wait for the activity records to be added, and 135 * wait for debugger window to show up. 136 * 137 * This should only be used when starting with -D (debugger) option, where we pop up the 138 * waiting-for-debugger window, but real activity window won't show up since we're waiting 139 * for debugger. 140 */ waitForDebuggerWindowVisible(ComponentName activityName)141 public void waitForDebuggerWindowVisible(ComponentName activityName) { 142 Condition.waitFor("debugger window", () -> { 143 computeState(); 144 return !shouldWaitForDebuggerWindow(activityName) 145 && !shouldWaitForActivityRecords(activityName); 146 }); 147 } 148 waitForHomeActivityVisible()149 public void waitForHomeActivityVisible() { 150 ComponentName homeActivity = getHomeActivityName(); 151 // Sometimes this function is called before we know what Home Activity is 152 if (homeActivity == null) { 153 logAlways("Computing state to determine Home Activity"); 154 computeState(); 155 homeActivity = getHomeActivityName(); 156 } 157 assertNotNull("homeActivity should not be null", homeActivity); 158 waitForValidState(homeActivity); 159 } 160 161 /** @return {@code true} if the recents is visible; {@code false} if timeout occurs. */ waitForRecentsActivityVisible()162 public boolean waitForRecentsActivityVisible() { 163 if (isHomeRecentsComponent()) { 164 waitForHomeActivityVisible(); 165 return true; 166 } else { 167 return waitForWithAmState(WindowManagerState::isRecentsActivityVisible, 168 "recents activity to be visible"); 169 } 170 } 171 waitForDreamGone()172 public void waitForDreamGone() { 173 assertTrue("Dream must be gone", 174 waitForWithAmState(state -> state.getDreamTask() == null, "DreamActivity gone")); 175 } 176 isKeyguardShowingAndNotOccluded(WindowManagerState state)177 public static boolean isKeyguardShowingAndNotOccluded(WindowManagerState state) { 178 return state.getKeyguardControllerState().keyguardShowing 179 && state.getKeyguardServiceDelegateState().isKeyguardAwake() 180 && !state.getKeyguardControllerState().aodShowing 181 && !state.getKeyguardControllerState().isKeyguardOccluded(DEFAULT_DISPLAY); 182 } 183 waitForKeyguardShowingAndNotOccluded()184 public void waitForKeyguardShowingAndNotOccluded() { 185 waitForWithAmState(WindowManagerStateHelper::isKeyguardShowingAndNotOccluded, 186 "Keyguard showing"); 187 } 188 waitForKeyguardShowingAndOccluded()189 public void waitForKeyguardShowingAndOccluded() { 190 waitForWithAmState(state -> state.getKeyguardControllerState().keyguardShowing 191 && state.getKeyguardControllerState().isKeyguardOccluded(DEFAULT_DISPLAY), 192 "Keyguard showing and occluded"); 193 } 194 waitAndAssertWindowShown(int windowType, boolean show)195 void waitAndAssertWindowShown(int windowType, boolean show) { 196 assertTrue(waitFor(state -> { 197 Stream<WindowState> windows = getMatchingWindows( 198 ws -> ws.isSurfaceShown() == show && ws.getType() == windowType); 199 return windows.findAny().isPresent(); 200 }, "wait for window surface " + (show ? "show" : "hide"))); 201 } 202 waitForAodShowing()203 public void waitForAodShowing() { 204 waitForWithAmState(state -> state.getKeyguardControllerState().aodShowing, "AOD showing"); 205 } 206 waitForKeyguardGone()207 public void waitForKeyguardGone() { 208 waitForWithAmState(state -> !state.getKeyguardControllerState().keyguardShowing, 209 "Keyguard gone"); 210 } 211 waitAndAssertKeyguardGone()212 public void waitAndAssertKeyguardGone() { 213 assertTrue("Keyguard must be gone", 214 waitForWithAmState( 215 state -> !state.getKeyguardControllerState().keyguardShowing, 216 "Keyguard gone")); 217 } 218 219 /** 220 * Wait for specific rotation for the default display. 221 * @param rotation Surface#Rotation 222 */ waitForRotation(int rotation)223 public boolean waitForRotation(int rotation) { 224 return waitForWithAmState(state -> state.getRotation() == rotation, 225 "Rotation: " + rotation); 226 } 227 228 /** 229 * Wait for specific orientation for the default display. 230 * @param screenOrientation ActivityInfo#ScreenOrientation 231 */ waitForLastOrientation(int screenOrientation)232 public void waitForLastOrientation(int screenOrientation) { 233 waitForWithAmState(state -> state.getLastOrientation() == screenOrientation, 234 "LastOrientation: " + screenOrientation); 235 } 236 237 /** 238 * @param message log message 239 * @param screenOrientation ActivityInfo#ScreenOrientation 240 */ waitAndAssertLastOrientation(String message, int screenOrientation)241 public void waitAndAssertLastOrientation(String message, int screenOrientation) { 242 if (screenOrientation != getLastOrientation()) { 243 waitForLastOrientation(screenOrientation); 244 } 245 assertEquals(message, screenOrientation, getLastOrientation()); 246 } 247 248 /** Waits for the configuration orientation (landscape or portrait) of the default display. 249 * @param configOrientation Configuration#Orientation 250 */ waitForDisplayOrientation(int configOrientation)251 public void waitForDisplayOrientation(int configOrientation) { 252 waitForWithAmState(state -> state.getDisplay(DEFAULT_DISPLAY) 253 .mFullConfiguration.orientation == configOrientation, 254 "orientation of default display to be " + configOrientation); 255 } 256 257 /** 258 * Wait for the configuration orientation of the Activity. 259 * @param activityName activity 260 * @param configOrientation Configuration#Orientation 261 */ waitForActivityOrientation(ComponentName activityName, int configOrientation)262 public boolean waitForActivityOrientation(ComponentName activityName, int configOrientation) { 263 return waitForWithAmState(amState -> { 264 final Activity activity = amState.getActivity(activityName); 265 return activity != null && activity.mFullConfiguration.orientation == configOrientation; 266 }, "orientation of " + getActivityName(activityName) + " to be " + configOrientation); 267 } 268 waitForDisplayUnfrozen()269 public void waitForDisplayUnfrozen() { 270 waitForWithAmState(state -> !state.isDisplayFrozen(), "Display unfrozen"); 271 } 272 waitForActivityState(ComponentName activityName, String activityState)273 public boolean waitForActivityState(ComponentName activityName, String activityState) { 274 return waitForWithAmState(state -> state.hasActivityState(activityName, activityState), 275 "state of " + getActivityName(activityName) + " to be " + activityState); 276 } 277 waitAndAssertActivityState(ComponentName activityName, String activityState)278 public void waitAndAssertActivityState(ComponentName activityName, String activityState) { 279 assertTrue(waitForActivityState(activityName, activityState)); 280 } 281 waitForActivityRemoved(ComponentName activityName)282 public void waitForActivityRemoved(ComponentName activityName) { 283 waitFor((amState) -> !amState.containsActivity(activityName) 284 && !amState.containsWindow(getWindowName(activityName)), 285 getActivityName(activityName) + " to be removed"); 286 } 287 waitAndAssertActivityRemoved(ComponentName activityName)288 public void waitAndAssertActivityRemoved(ComponentName activityName) { 289 waitForActivityRemoved(activityName); 290 assertNotExist(activityName); 291 } 292 waitForFocusedStack(int windowingMode, int activityType)293 public void waitForFocusedStack(int windowingMode, int activityType) { 294 waitForWithAmState(state -> 295 (activityType == ACTIVITY_TYPE_UNDEFINED 296 || state.getFocusedRootTaskActivityType() == activityType) 297 && (windowingMode == WINDOWING_MODE_UNDEFINED 298 || state.getFocusedRootTaskWindowingMode() == windowingMode), 299 "focused stack"); 300 } 301 waitForPendingActivityContain(ComponentName activity)302 public void waitForPendingActivityContain(ComponentName activity) { 303 waitForWithAmState(state -> state.pendingActivityContain(activity), 304 getActivityName(activity) + " in pending list"); 305 } 306 waitForAppTransitionRunningOnDisplay(int displayId)307 public boolean waitForAppTransitionRunningOnDisplay(int displayId) { 308 return waitForWithAmState( 309 state -> WindowManagerState.APP_STATE_RUNNING.equals( 310 state.getDisplay(displayId).getAppTransitionState()), 311 "app transition running on Display " + displayId); 312 } 313 waitForAppTransitionIdleOnDisplay(int displayId)314 public boolean waitForAppTransitionIdleOnDisplay(int displayId) { 315 return waitForWithAmState( 316 state -> WindowManagerState.APP_STATE_IDLE.equals( 317 state.getDisplay(displayId).getAppTransitionState()), 318 "app transition idle on Display " + displayId); 319 } 320 waitAndAssertNavBarShownOnDisplay(int displayId)321 void waitAndAssertNavBarShownOnDisplay(int displayId) { 322 waitAndAssertNavBarShownOnDisplay(displayId, 1 /* expectedNavBarCount */); 323 } 324 waitAndAssertNavBarShownOnDisplay(int displayId, int expectedNavBarCount)325 void waitAndAssertNavBarShownOnDisplay(int displayId, int expectedNavBarCount) { 326 assertTrue(waitForWithAmState(state -> { 327 List<WindowState> navWindows = state 328 .getAndAssertNavBarWindowsOnDisplay(displayId, expectedNavBarCount); 329 330 return navWindows != null; 331 }, "navigation bar #" + displayId + " show")); 332 } 333 waitAndAssertKeyguardShownOnSecondaryDisplay(int displayId)334 public void waitAndAssertKeyguardShownOnSecondaryDisplay(int displayId) { 335 assertTrue("KeyguardDialog must be shown on secondary display " + displayId, 336 waitForWithAmState( 337 state -> isKeyguardOnSecondaryDisplay(state, displayId), 338 "keyguard window to show")); 339 } 340 waitAndAssertKeyguardGoneOnSecondaryDisplay(int displayId)341 public void waitAndAssertKeyguardGoneOnSecondaryDisplay(int displayId) { 342 assertTrue("KeyguardDialog must be gone on secondary display " + displayId, 343 waitForWithAmState( 344 state -> !isKeyguardOnSecondaryDisplay(state, displayId), 345 "keyguard window to dismiss")); 346 } 347 waitForWindowSurfaceShown(String windowName, boolean shown)348 boolean waitForWindowSurfaceShown(String windowName, boolean shown) { 349 final String message = windowName + "'s isWindowSurfaceShown to return " + shown; 350 return Condition.waitFor(new Condition<>(message, () -> { 351 computeState(); 352 return isWindowSurfaceShown(windowName) == shown; 353 }).setRetryIntervalMs(200).setRetryLimit(20)); 354 } 355 356 void waitForWindowSurfaceDisappeared(String windowName) { 357 waitForWindowSurfaceShown(windowName, false); 358 } 359 360 public void waitAndAssertWindowSurfaceShown(String windowName, boolean shown) { 361 assertTrue(waitForWindowSurfaceShown(windowName, shown)); 362 } 363 364 /** A variant of waitForWithAmState with different parameter order for better Kotlin interop. */ 365 public boolean waitForWithAmState(String message, Predicate<WindowManagerState> waitCondition) { 366 return waitForWithAmState(waitCondition, message); 367 } 368 369 public boolean waitForWithAmState(Predicate<WindowManagerState> waitCondition, 370 String message) { 371 return waitFor(waitCondition, message); 372 } 373 374 public void waitWindowingModeTopFocus(int windowingMode, boolean topFocus, String message) { 375 waitForWithAmState(amState -> { 376 final Task rootTask = amState.getStandardRootTaskByWindowingMode(windowingMode); 377 return rootTask != null 378 && topFocus == (amState.getFocusedTaskId() == rootTask.getRootTaskId()); 379 }, message); 380 } 381 382 public boolean waitForFocusedActivity(final String msg, final ComponentName activityName) { 383 final String activityComponentName = getActivityName(activityName); 384 return waitFor(msg, wmState -> 385 Objects.equals(activityComponentName, wmState.getFocusedActivity()) 386 && Objects.equals(activityComponentName, wmState.getFocusedApp())); 387 } 388 389 /** A variant of waitFor with different parameter order for better Kotlin interop. */ 390 public boolean waitFor(String message, Predicate<WindowManagerState> waitCondition) { 391 return waitFor(waitCondition, message); 392 } 393 394 /** @return {@code true} if the wait is successful; {@code false} if timeout occurs. */ 395 public boolean waitFor(Predicate<WindowManagerState> waitCondition, String message) { 396 return Condition.waitFor(message, () -> { 397 computeState(); 398 return waitCondition.test(this); 399 }); 400 } 401 402 /** Waits for non-null result from {@code function} and returns it. */ 403 public <T> T waitForResult(String message, Function<WindowManagerState, T> function) { 404 return waitForResult(message, function, Objects::nonNull); 405 } 406 407 public <T> T waitForResult(String message, Function<WindowManagerState, T> function, 408 Predicate<T> validator) { 409 return Condition.waitForResult(new Condition<T>(message) 410 .setResultSupplier(() -> { 411 computeState(); 412 return function.apply(this); 413 }) 414 .setResultValidator(validator)); 415 } 416 417 /** 418 * @return true if should wait for valid stacks state. 419 */ 420 private boolean shouldWaitForValidStacks() { 421 final int stackCount = getRootTaskCount(); 422 if (stackCount == 0) { 423 logAlways("***stackCount=" + stackCount); 424 return true; 425 } 426 final int resumedActivitiesCount = getResumedActivitiesCount(); 427 if (!getKeyguardControllerState().keyguardShowing && resumedActivitiesCount < 1) { 428 logAlways("***resumedActivitiesCount=" + resumedActivitiesCount); 429 return true; 430 } 431 if (getFocusedActivity() == null) { 432 logAlways("***focusedActivity=null"); 433 return true; 434 } 435 return false; 436 } 437 438 public void waitAndAssertAppFocus(String appPackageName, long waitTime) { 439 final Condition<String> condition = new Condition<>(appPackageName + " to be focused"); 440 Condition.waitFor(condition.setResultSupplier(() -> { 441 computeState(); 442 return getFocusedApp(); 443 }).setResultValidator(focusedAppName -> { 444 return focusedAppName != null && appPackageName.equals( 445 ComponentName.unflattenFromString(focusedAppName).getPackageName()); 446 }).setOnFailure(focusedAppName -> { 447 fail("Timed out waiting for focus on app " 448 + appPackageName + ", last was " + focusedAppName); 449 }).setRetryIntervalMs(100).setRetryLimit((int) waitTime / 100)); 450 } 451 452 /** 453 * @return true if should wait for some activities to become visible. 454 */ 455 private boolean shouldWaitForActivities(WaitForValidActivityState... waitForActivitiesVisible) { 456 if (waitForActivitiesVisible == null || waitForActivitiesVisible.length == 0) { 457 return false; 458 } 459 // If the caller is interested in us waiting for some particular activity windows to be 460 // visible before compute the state. Check for the visibility of those activity windows 461 // and for placing them in correct stacks (if requested). 462 boolean allActivityWindowsVisible = true; 463 boolean tasksInCorrectStacks = true; 464 for (final WaitForValidActivityState state : waitForActivitiesVisible) { 465 final ComponentName activityName = state.activityName; 466 final String windowName = state.windowName; 467 final int stackId = state.stackId; 468 final int windowingMode = state.windowingMode; 469 final int activityType = state.activityType; 470 471 final List<WindowState> matchingWindowStates = 472 getMatchingVisibleWindowState(windowName); 473 boolean activityWindowVisible = !matchingWindowStates.isEmpty(); 474 if (!activityWindowVisible) { 475 logAlways("Activity window not visible: " + windowName); 476 allActivityWindowsVisible = false; 477 } else if (activityName != null 478 && !isActivityVisible(activityName)) { 479 logAlways("Activity not visible: " + getActivityName(activityName)); 480 allActivityWindowsVisible = false; 481 } else { 482 // Check if window is already the correct state requested by test. 483 boolean windowInCorrectState = false; 484 for (WindowState ws : matchingWindowStates) { 485 if (stackId != INVALID_STACK_ID && ws.getStackId() != stackId) { 486 continue; 487 } 488 if (!ws.isWindowingModeCompatible(windowingMode)) { 489 continue; 490 } 491 if (activityType != ACTIVITY_TYPE_UNDEFINED 492 && ws.getActivityType() != activityType) { 493 continue; 494 } 495 windowInCorrectState = true; 496 break; 497 } 498 499 if (!windowInCorrectState) { 500 logAlways("Window in incorrect stack: " + state); 501 tasksInCorrectStacks = false; 502 } 503 } 504 } 505 return !allActivityWindowsVisible || !tasksInCorrectStacks; 506 } 507 508 /** 509 * @return true if should wait valid windows state. 510 */ 511 private boolean shouldWaitForWindows() { 512 if (getFrontWindow() == null) { 513 logAlways("***frontWindow=null"); 514 return true; 515 } 516 if (getFocusedWindow() == null) { 517 logAlways("***focusedWindow=null"); 518 return true; 519 } 520 if (getFocusedApp() == null) { 521 logAlways("***focusedApp=null"); 522 return true; 523 } 524 525 return false; 526 } 527 528 private boolean shouldWaitForDebuggerWindow(ComponentName activityName) { 529 List<WindowState> matchingWindowStates = 530 getMatchingVisibleWindowState(activityName.getPackageName()); 531 for (WindowState ws : matchingWindowStates) { 532 if (ws.isDebuggerWindow()) { 533 return false; 534 } 535 } 536 logAlways("Debugger window not available yet"); 537 return true; 538 } 539 540 private boolean shouldWaitForActivityRecords(ComponentName... activityNames) { 541 // Check if the activity records we're looking for is already added. 542 for (final ComponentName activityName : activityNames) { 543 if (!isActivityVisible(activityName)) { 544 logAlways("ActivityRecord " + getActivityName(activityName) + " not visible yet"); 545 return true; 546 } 547 } 548 return false; 549 } 550 551 private boolean shouldWaitForValidityCheck() { 552 try { 553 assertValidity(); 554 } catch (Throwable t) { 555 logAlways("Waiting for validity check: " + t.toString()); 556 return true; 557 } 558 return false; 559 } 560 561 void assertValidity() { 562 assertThat("Must have root task", getRootTaskCount(), greaterThan(0)); 563 // TODO: Update when keyguard will be shown on multiple displays 564 if (!getKeyguardControllerState().keyguardShowing) { 565 assertThat("There should be at least one resumed activity in the system.", 566 getResumedActivitiesCount(), greaterThanOrEqualTo(1)); 567 } 568 assertNotNull("Must have focus activity.", getFocusedActivity()); 569 570 for (Task rootTask : getRootTasks()) { 571 final int taskId = rootTask.mRootTaskId; 572 for (Task task : rootTask.getTasks()) { 573 assertEquals("Root task can only contain its own tasks", taskId, 574 task.mRootTaskId); 575 } 576 } 577 578 assertNotNull("Must have front window.", getFrontWindow()); 579 assertNotNull("Must have focused window.", getFocusedWindow()); 580 assertNotNull("Must have app.", getFocusedApp()); 581 } 582 583 public void assertContainsStack(String msg, int windowingMode, int activityType) { 584 assertTrue(msg, containsRootTasks(windowingMode, activityType)); 585 } 586 587 public void assertDoesNotContainStack(String msg, int windowingMode, int activityType) { 588 assertFalse(msg, containsRootTasks(windowingMode, activityType)); 589 } 590 591 public void assertFrontStack(String msg, int windowingMode, int activityType) { 592 assertFrontStackOnDisplay(msg, windowingMode, activityType, DEFAULT_DISPLAY); 593 } 594 595 public void assertFrontStackOnDisplay(String msg, int windowingMode, int activityType, 596 int displayId) { 597 if (windowingMode != WINDOWING_MODE_UNDEFINED) { 598 assertEquals(msg, windowingMode, getFrontRootTaskWindowingMode(displayId)); 599 } 600 if (activityType != ACTIVITY_TYPE_UNDEFINED) { 601 assertEquals(msg, activityType, getFrontRootTaskActivityType(displayId)); 602 } 603 } 604 605 public void assertFrontStackActivityType(String msg, int activityType) { 606 assertEquals(msg, activityType, getFrontRootTaskActivityType(DEFAULT_DISPLAY)); 607 } 608 609 void assertFocusedRootTask(String msg, int taskId) { 610 assertEquals(msg, taskId, getFocusedTaskId()); 611 } 612 613 void assertFocusedRootTask(String msg, int windowingMode, int activityType) { 614 if (windowingMode != WINDOWING_MODE_UNDEFINED) { 615 assertEquals(msg, windowingMode, getFocusedRootTaskWindowingMode()); 616 } 617 if (activityType != ACTIVITY_TYPE_UNDEFINED) { 618 assertEquals(msg, activityType, getFocusedRootTaskActivityType()); 619 } 620 } 621 622 public void assertFocusedActivity(final String msg, final ComponentName activityName) { 623 final String activityComponentName = getActivityName(activityName); 624 assertEquals(msg, activityComponentName, getFocusedActivity()); 625 assertEquals(msg, activityComponentName, getFocusedApp()); 626 } 627 628 public void assertFocusedAppOnDisplay(final String msg, final ComponentName activityName, 629 final int displayId) { 630 final String activityComponentName = getActivityName(activityName); 631 assertEquals(msg, activityComponentName, getDisplay(displayId).getFocusedApp()); 632 } 633 634 public void assertNotFocusedActivity(String msg, ComponentName activityName) { 635 assertNotEquals(msg, getFocusedActivity(), getActivityName(activityName)); 636 assertNotEquals(msg, getFocusedApp(), getActivityName(activityName)); 637 } 638 639 public void assertResumedActivity(final String msg, final ComponentName activityName) { 640 assertEquals(msg, getActivityName(activityName), 641 getFocusedActivity()); 642 } 643 644 /** Asserts that each display has correct resumed activity. */ 645 public void assertResumedActivities(final String msg, 646 Consumer<SparseArray<ComponentName>> resumedActivitiesMapping) { 647 final SparseArray<ComponentName> resumedActivities = new SparseArray<>(); 648 resumedActivitiesMapping.accept(resumedActivities); 649 for (int i = 0; i < resumedActivities.size(); i++) { 650 final int displayId = resumedActivities.keyAt(i); 651 final ComponentName activityComponent = resumedActivities.valueAt(i); 652 assertEquals("Error asserting resumed activity on display " + displayId + ": " + msg, 653 activityComponent != null ? getActivityName(activityComponent) : null, 654 getResumedActivityOnDisplay(displayId)); 655 } 656 } 657 658 public void assertNotResumedActivity(String msg, ComponentName activityName) { 659 assertNotEquals(msg, getFocusedActivity(), getActivityName(activityName)); 660 } 661 662 public void assertFocusedWindow(String msg, String windowName) { 663 assertEquals(msg, windowName, getFocusedWindow()); 664 } 665 666 public void assertNotFocusedWindow(String msg, String windowName) { 667 assertNotEquals(msg, getFocusedWindow(), windowName); 668 } 669 670 public void assertNotExist(final ComponentName activityName) { 671 final String windowName = getWindowName(activityName); 672 assertFalse("Activity=" + getActivityName(activityName) + " must NOT exist.", 673 containsActivity(activityName)); 674 assertFalse("Window=" + windowName + " must NOT exits.", 675 containsWindow(windowName)); 676 } 677 678 public void waitAndAssertVisibilityGone(final ComponentName activityName) { 679 // Sometimes the surface can be shown due to the late animation. 680 // Wait for the animation is done. 681 waitForWindowSurfaceDisappeared(getWindowName(activityName)); 682 assertVisibility(activityName, false); 683 } 684 685 public void assertVisibility(final ComponentName activityName, final boolean visible) { 686 final String windowName = getWindowName(activityName); 687 // Check existence of activity and window. 688 assertTrue("Activity=" + getActivityName(activityName) + " must exist.", 689 containsActivity(activityName)); 690 assertTrue("Window=" + windowName + " must exist.", containsWindow(windowName)); 691 692 // Check visibility of activity and window. 693 assertEquals("Activity=" + getActivityName(activityName) + " must" + (visible ? "" : " NOT") 694 + " be visible.", visible, isActivityVisible(activityName)); 695 assertEquals("Window=" + windowName + " must" + (visible ? "" : " NOT") 696 + " have shown surface.", 697 visible, isWindowSurfaceShown(windowName)); 698 } 699 700 public void assertHomeActivityVisible(boolean visible) { 701 final ComponentName homeActivity = getHomeActivityName(); 702 assertNotNull(homeActivity); 703 assertVisibility(homeActivity, visible); 704 } 705 706 /** 707 * Asserts that the device default display minimum width is larger than the minimum task width. 708 */ 709 void assertDeviceDefaultDisplaySizeForMultiWindow(String errorMessage) { 710 computeState(); 711 final int minTaskSizePx = defaultMinimalTaskSize(DEFAULT_DISPLAY); 712 final WindowManagerState.DisplayContent display = getDisplay(DEFAULT_DISPLAY); 713 final Rect displayRect = display.getDisplayRect(); 714 if (Math.min(displayRect.width(), displayRect.height()) < minTaskSizePx) { 715 fail(errorMessage); 716 } 717 } 718 719 /** 720 * Asserts that the device default display minimum width is not smaller than the minimum width 721 * for split-screen required by CDD. 722 */ 723 void assertDeviceDefaultDisplaySizeForSplitScreen(String errorMessage) { 724 computeState(); 725 final int minDisplaySizePx = defaultMinimalDisplaySizeForSplitScreen(DEFAULT_DISPLAY); 726 final WindowManagerState.DisplayContent display = getDisplay(DEFAULT_DISPLAY); 727 final Rect displayRect = display.getDisplayRect(); 728 if (Math.max(displayRect.width(), displayRect.height()) < minDisplaySizePx) { 729 fail(errorMessage); 730 } 731 } 732 733 public void assertKeyguardShowingAndOccluded() { 734 assertTrue("Keyguard is showing", 735 getKeyguardControllerState().keyguardShowing); 736 assertFalse("keygaurd is not going away", 737 getKeyguardControllerState().mKeyguardGoingAway); 738 assertTrue("Keyguard is occluded", 739 getKeyguardControllerState().isKeyguardOccluded(DEFAULT_DISPLAY)); 740 } 741 742 public void assertKeyguardShowingAndNotOccluded() { 743 assertTrue("Keyguard is showing", 744 getKeyguardControllerState().keyguardShowing); 745 assertFalse("keygaurd is not going away", 746 getKeyguardControllerState().mKeyguardGoingAway); 747 assertFalse("Keyguard is not occluded", 748 getKeyguardControllerState().isKeyguardOccluded(DEFAULT_DISPLAY)); 749 } 750 751 public void assertKeyguardGone() { 752 assertFalse("Keyguard is not shown", 753 getKeyguardControllerState().keyguardShowing); 754 } 755 756 void assertKeyguardShownOnSecondaryDisplay(int displayId) { 757 assertTrue("KeyguardDialog must be shown on display " + displayId, 758 isKeyguardOnSecondaryDisplay(this, displayId)); 759 } 760 761 void assertKeyguardGoneOnSecondaryDisplay(int displayId) { 762 assertFalse("KeyguardDialog must be gone on display " + displayId, 763 isKeyguardOnSecondaryDisplay(this, displayId)); 764 } 765 766 public void assertAodShowing() { 767 assertTrue("AOD is showing", 768 getKeyguardControllerState().aodShowing); 769 } 770 771 public void assertAodNotShowing() { 772 assertFalse("AOD is not showing", 773 getKeyguardControllerState().aodShowing); 774 } 775 776 public void assertIllegalTaskState() { 777 computeState(); 778 final List<Task> tasks = getRootTasks(); 779 for (Task task : tasks) { 780 task.forAllTasks((t) -> assertWithMessage("Empty task was found, id = " + t.mTaskId) 781 .that(t.mTasks.size() + t.mTaskFragments.size() + t.mActivities.size()) 782 .isGreaterThan(0)); 783 if (task.isLeafTask()) { 784 continue; 785 } 786 assertWithMessage("Non-leaf task cannot have affinity set, id = " + task.mTaskId) 787 .that(task.mAffinity).isEmpty(); 788 } 789 } 790 791 public void assumePendingActivityContain(ComponentName activity) { 792 assumeTrue(pendingActivityContain(activity)); 793 } 794 795 public void assertActivityDisplayed(final ComponentName activityName) { 796 assertWindowDisplayed(getWindowName(activityName)); 797 } 798 799 public void assertWindowDisplayed(final String windowName) { 800 waitForValidState(WaitForValidActivityState.forWindow(windowName)); 801 assertTrue(windowName + " is visible", isWindowSurfaceShown(windowName)); 802 } 803 804 public void waitAndAssertImePickerShownOnDisplay(int displayId, String message) { 805 if (!Condition.waitFor(message, () -> { 806 computeState(); 807 return getMatchingWindowType(TYPE_INPUT_METHOD_DIALOG).stream().anyMatch( 808 w -> w.getDisplayId() == displayId && w.isSurfaceShown()); 809 })) { 810 fail(message); 811 } 812 } 813 814 void waitAndAssertImeWindowShownOnDisplay(int displayId) { 815 final WindowState imeWinState = Condition.waitForResult("IME window", 816 condition -> condition 817 .setResultSupplier(this::getImeWindowState) 818 .setResultValidator( 819 w -> w != null && w.isSurfaceShown() 820 && w.getDisplayId() == displayId)); 821 822 assertNotNull("IME window must exist", imeWinState); 823 assertTrue("IME window must be shown", imeWinState.isSurfaceShown()); 824 assertEquals("IME window must be on the given display", displayId, 825 imeWinState.getDisplayId()); 826 } 827 828 WindowState getImeWindowState() { 829 computeState(); 830 return getInputMethodWindowState(); 831 } 832 833 /** 834 * @return the window state for the given {@param activityName}'s window. 835 */ 836 WindowState getWindowState(ComponentName activityName) { 837 String windowName = getWindowName(activityName); 838 computeState(activityName); 839 final List<WindowManagerState.WindowState> tempWindowList = 840 getMatchingVisibleWindowState(windowName); 841 return tempWindowList.get(0); 842 } 843 844 boolean isScreenPortrait(int displayId) { 845 final Rect displayRect = getDisplay(displayId).getDisplayRect(); 846 return displayRect.height() > displayRect.width(); 847 } 848 849 private static boolean isKeyguardOnSecondaryDisplay( 850 WindowManagerState windowManagerState, int displayId) { 851 final List<WindowManagerState.WindowState> states = 852 windowManagerState.getMatchingWindowType(TYPE_KEYGUARD_DIALOG); 853 for (WindowManagerState.WindowState ws : states) { 854 if (ws.getDisplayId() == displayId) return true; 855 } 856 return false; 857 } 858 } 859