blob: e530dd46aa48aef1ff27c3b8fd0f0b10bf516d2c [file] [log] [blame]
Wale Ogunwalecd739102020-01-29 06:15:52 -08001/*
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
17package android.server.wm;
18
19import static android.app.ActivityTaskManager.INVALID_STACK_ID;
20import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
Wale Ogunwalecd739102020-01-29 06:15:52 -080021import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
22import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Wale Ogunwalecd739102020-01-29 06:15:52 -080023import static android.server.wm.ComponentNameUtils.getActivityName;
24import static android.server.wm.ComponentNameUtils.getWindowName;
25import static android.server.wm.StateLogger.logAlways;
26import static android.server.wm.StateLogger.logE;
27import static android.view.Display.DEFAULT_DISPLAY;
Chris Li86337ed2020-03-24 22:18:44 -070028import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
Wale Ogunwalecd739102020-01-29 06:15:52 -080029
30import static com.google.common.truth.Truth.assertWithMessage;
31
32import static org.hamcrest.Matchers.greaterThan;
33import static org.hamcrest.Matchers.greaterThanOrEqualTo;
34import static org.junit.Assert.assertEquals;
35import static org.junit.Assert.assertFalse;
36import static org.junit.Assert.assertNotEquals;
37import static org.junit.Assert.assertNotNull;
38import static org.junit.Assert.assertThat;
39import static org.junit.Assert.assertTrue;
40import static org.junit.Assert.fail;
41import static org.junit.Assume.assumeTrue;
42
43import android.content.ComponentName;
44import android.graphics.Rect;
45import android.util.SparseArray;
46
47import java.util.Arrays;
48import java.util.List;
49import java.util.function.Consumer;
50import java.util.function.Predicate;
51
52/** Window Manager State helper class with assert and wait functions. */
53public class WindowManagerStateHelper extends WindowManagerState {
54
55 /**
56 * Compute AM and WM state of device, check sanity and bounds.
57 * WM state will include only visible windows, stack and task bounds will be compared.
58 *
59 * @param componentNames array of activity names to wait for.
60 */
61 public void computeState(ComponentName... componentNames) {
62 waitForValidState(Arrays.stream(componentNames)
63 .map(WaitForValidActivityState::new)
64 .toArray(WaitForValidActivityState[]::new));
65 }
66
67 /**
68 * Compute AM and WM state of device, check sanity and bounds.
69 * WM state will include only visible windows, stack and task bounds will be compared.
70 *
71 * @param waitForActivitiesVisible array of activity names to wait for.
72 */
73 public void computeState(WaitForValidActivityState... waitForActivitiesVisible) {
74 waitForValidState(waitForActivitiesVisible);
75 }
76
77 /**
78 * Wait for the activities to appear and for valid state in AM and WM.
79 *
80 * @param activityNames name list of activities to wait for.
81 */
82 public void waitForValidState(ComponentName... activityNames) {
83 waitForValidState(Arrays.stream(activityNames)
84 .map(WaitForValidActivityState::new)
85 .toArray(WaitForValidActivityState[]::new));
86
87 }
88
89 /**
90 * Wait for the activities to appear in proper stacks and for valid state in AM and WM.
91 * @param waitForActivitiesVisible array of activity states to wait for.
92 */
93 void waitForValidState(WaitForValidActivityState... waitForActivitiesVisible) {
94 if (!Condition.waitFor("valid stacks and activities states", () -> {
95 // TODO: Get state of AM and WM at the same time to avoid mismatches caused by
96 // requesting dump in some intermediate state.
97 computeState();
98 return !(shouldWaitForSanityCheck()
99 || shouldWaitForValidStacks()
100 || shouldWaitForActivities(waitForActivitiesVisible)
101 || shouldWaitForWindows());
102 })) {
103 logE("***Waiting for states failed: " + Arrays.toString(waitForActivitiesVisible));
104 }
105 }
106
107 void waitForAllStoppedActivities() {
108 if (!Condition.waitFor("all started activities have been removed", () -> {
109 computeState();
110 return !containsStartedActivities();
111 })) {
112 fail("All started activities have been removed");
113 }
114 }
115
116 /**
117 * Compute AM and WM state of device, wait for the activity records to be added, and
118 * wait for debugger window to show up.
119 *
120 * This should only be used when starting with -D (debugger) option, where we pop up the
121 * waiting-for-debugger window, but real activity window won't show up since we're waiting
122 * for debugger.
123 */
124 void waitForDebuggerWindowVisible(ComponentName activityName) {
125 Condition.waitFor("debugger window", () -> {
126 computeState();
127 return !shouldWaitForDebuggerWindow(activityName)
128 && !shouldWaitForActivityRecords(activityName);
129 });
130 }
131
132 void waitForHomeActivityVisible() {
133 ComponentName homeActivity = getHomeActivityName();
134 // Sometimes this function is called before we know what Home Activity is
135 if (homeActivity == null) {
136 logAlways("Computing state to determine Home Activity");
137 computeState();
138 homeActivity = getHomeActivityName();
139 }
140 assertNotNull("homeActivity should not be null", homeActivity);
141 waitForValidState(homeActivity);
142 }
143
Toshiki Kikuchiedabca92020-10-29 17:26:07 +0900144 /** @return {@code true} if the recents is visible; {@code false} if timeout occurs. */
145 boolean waitForRecentsActivityVisible() {
Wale Ogunwalecd739102020-01-29 06:15:52 -0800146 if (isHomeRecentsComponent()) {
147 waitForHomeActivityVisible();
Toshiki Kikuchiedabca92020-10-29 17:26:07 +0900148 return true;
Wale Ogunwalecd739102020-01-29 06:15:52 -0800149 } else {
Toshiki Kikuchiedabca92020-10-29 17:26:07 +0900150 return waitForWithAmState(WindowManagerState::isRecentsActivityVisible,
Wale Ogunwalecd739102020-01-29 06:15:52 -0800151 "recents activity to be visible");
152 }
153 }
154
155 void waitForKeyguardShowingAndNotOccluded() {
156 waitForWithAmState(state -> state.getKeyguardControllerState().keyguardShowing
157 && !state.getKeyguardControllerState().isKeyguardOccluded(DEFAULT_DISPLAY),
158 "Keyguard showing");
159 }
160
161 void waitForKeyguardShowingAndOccluded() {
162 waitForWithAmState(state -> state.getKeyguardControllerState().keyguardShowing
163 && state.getKeyguardControllerState().isKeyguardOccluded(DEFAULT_DISPLAY),
164 "Keyguard showing and occluded");
165 }
166
167 void waitForAodShowing() {
168 waitForWithAmState(state -> state.getKeyguardControllerState().aodShowing, "AOD showing");
169 }
170
171 void waitForKeyguardGone() {
172 waitForWithAmState(state -> !state.getKeyguardControllerState().keyguardShowing,
173 "Keyguard gone");
174 }
175
Chris Li86337ed2020-03-24 22:18:44 -0700176 void waitAndAssertKeyguardGone() {
177 assertTrue("Keyguard must be gone",
178 waitForWithAmState(
179 state -> !state.getKeyguardControllerState().keyguardShowing,
180 "Keyguard gone"));
181 }
182
Wale Ogunwalecd739102020-01-29 06:15:52 -0800183 /** Wait for specific rotation for the default display. Values are Surface#Rotation */
184 void waitForRotation(int rotation) {
185 waitForWithAmState(state -> state.getRotation() == rotation, "Rotation: " + rotation);
186 }
187
188 /**
189 * Wait for specific orientation for the default display.
190 * Values are ActivityInfo.ScreenOrientation
191 */
192 void waitForLastOrientation(int orientation) {
193 waitForWithAmState(state -> state.getLastOrientation() == orientation,
194 "LastOrientation: " + orientation);
195 }
196
Riddle Hsu6ad8ac52020-03-27 18:53:48 +0800197 void waitAndAssertLastOrientation(String message, int screenOrientation) {
198 if (screenOrientation != getLastOrientation()) {
199 waitForLastOrientation(screenOrientation);
200 }
201 assertEquals(message, screenOrientation, getLastOrientation());
202 }
203
Wale Ogunwalecd739102020-01-29 06:15:52 -0800204 /**
205 * Wait for orientation for the Activity
206 */
207 void waitForActivityOrientation(ComponentName activityName, int orientation) {
208 waitForWithAmState(amState -> {
209 final ActivityTask task = amState.getTaskByActivity(activityName);
210 if (task == null) {
211 return false;
212 }
213 return task.mFullConfiguration.orientation == orientation;
214 }, "orientation of " + getActivityName(activityName) + " to be " + orientation);
215 }
216
217 void waitForDisplayUnfrozen() {
218 waitForWithAmState(state -> !state.isDisplayFrozen(), "Display unfrozen");
219 }
220
221 public void waitForActivityState(ComponentName activityName, String activityState) {
222 waitForWithAmState(state -> state.hasActivityState(activityName, activityState),
223 "state of " + getActivityName(activityName) + " to be " + activityState);
224 }
225
226 public void waitForActivityRemoved(ComponentName activityName) {
227 waitFor((amState) -> !amState.containsActivity(activityName)
228 && !amState.containsWindow(getWindowName(activityName)),
229 getActivityName(activityName) + " to be removed");
230 }
231
232 void waitAndAssertActivityRemoved(ComponentName activityName) {
233 waitForActivityRemoved(activityName);
234 assertNotExist(activityName);
235 }
236
237 void waitForFocusedStack(int windowingMode, int activityType) {
238 waitForWithAmState(state ->
239 (activityType == ACTIVITY_TYPE_UNDEFINED
240 || state.getFocusedStackActivityType() == activityType)
241 && (windowingMode == WINDOWING_MODE_UNDEFINED
242 || state.getFocusedStackWindowingMode() == windowingMode),
243 "focused stack");
244 }
245
246 void waitForPendingActivityContain(ComponentName activity) {
247 waitForWithAmState(state -> state.pendingActivityContain(activity),
248 getActivityName(activity) + " in pending list");
249 }
250
251 void waitForAppTransitionIdleOnDisplay(int displayId) {
252 waitForWithAmState(
253 state -> WindowManagerState.APP_STATE_IDLE.equals(
254 state.getDisplay(displayId).getAppTransitionState()),
255 "app transition idle on Display " + displayId);
256 }
257
258 void waitAndAssertNavBarShownOnDisplay(int displayId) {
259 assertTrue(waitForWithAmState(
260 state -> state.getAndAssertSingleNavBarWindowOnDisplay(displayId) != null,
261 "navigation bar #" + displayId + " show"));
262 }
263
Chris Li86337ed2020-03-24 22:18:44 -0700264 void waitAndAssertKeyguardShownOnSecondaryDisplay(int displayId) {
265 assertTrue("KeyguardDialog must be shown on secondary display " + displayId,
266 waitForWithAmState(
267 state -> isKeyguardOnSecondaryDisplay(state, displayId),
268 "keyguard window to show"));
269 }
270
271 void waitAndAssertKeyguardGoneOnSecondaryDisplay(int displayId) {
272 assertTrue("KeyguardDialog must be gone on secondary display " + displayId,
273 waitForWithAmState(
274 state -> !isKeyguardOnSecondaryDisplay(state, displayId),
275 "keyguard window to dismiss"));
276 }
277
Yuncheol Heo03299222020-06-03 21:08:04 -0700278 void waitForWindowSurfaceDisappeared(String windowName) {
279 waitForWithAmState(state -> {
280 return !state.isWindowSurfaceShown(windowName);
281 }, windowName + "'s surface is disappeared");
282 }
283
Wale Ogunwalecd739102020-01-29 06:15:52 -0800284 public boolean waitForWithAmState(Predicate<WindowManagerState> waitCondition,
285 String message) {
286 return waitFor((amState) -> waitCondition.test(amState), message);
287 }
288
289 public void waitWindowingModeTopFocus(int windowingMode, boolean topFocus, String message) {
290 waitForWithAmState(amState -> {
291 final ActivityTask stack = amState.getStandardStackByWindowingMode(windowingMode);
292 return stack != null
293 && topFocus == (amState.getFocusedStackId() == stack.getRootTaskId());
294 }, message);
295 }
296
297 /** @return {@code true} if the wait is successful; {@code false} if timeout occurs. */
298 boolean waitFor(Predicate<WindowManagerState> waitCondition, String message) {
299 return Condition.waitFor(message, () -> {
300 computeState();
301 return waitCondition.test(this);
302 });
303 }
304
305 /**
306 * @return true if should wait for valid stacks state.
307 */
308 private boolean shouldWaitForValidStacks() {
309 final int stackCount = getStackCount();
310 if (stackCount == 0) {
311 logAlways("***stackCount=" + stackCount);
312 return true;
313 }
314 final int resumedActivitiesCount = getResumedActivitiesCount();
315 if (!getKeyguardControllerState().keyguardShowing && resumedActivitiesCount < 1) {
316 logAlways("***resumedActivitiesCount=" + resumedActivitiesCount);
317 return true;
318 }
319 if (getFocusedActivity() == null) {
320 logAlways("***focusedActivity=null");
321 return true;
322 }
323 return false;
324 }
325
326 void waitAndAssertAppFocus(String appPackageName, long waitTime) {
327 final Condition<String> condition = new Condition<>(appPackageName + " to be focused");
328 Condition.waitFor(condition.setResultSupplier(() -> {
329 computeState();
330 return getFocusedApp();
331 }).setResultValidator(focusedAppName -> {
332 return focusedAppName != null && appPackageName.equals(
333 ComponentName.unflattenFromString(focusedAppName).getPackageName());
334 }).setOnFailure(focusedAppName -> {
335 fail("Timed out waiting for focus on app "
336 + appPackageName + ", last was " + focusedAppName);
337 }).setRetryIntervalMs(100).setRetryLimit((int) waitTime / 100));
338 }
339
340 /**
341 * @return true if should wait for some activities to become visible.
342 */
343 private boolean shouldWaitForActivities(WaitForValidActivityState... waitForActivitiesVisible) {
344 if (waitForActivitiesVisible == null || waitForActivitiesVisible.length == 0) {
345 return false;
346 }
347 // If the caller is interested in us waiting for some particular activity windows to be
348 // visible before compute the state. Check for the visibility of those activity windows
349 // and for placing them in correct stacks (if requested).
350 boolean allActivityWindowsVisible = true;
351 boolean tasksInCorrectStacks = true;
352 for (final WaitForValidActivityState state : waitForActivitiesVisible) {
353 final ComponentName activityName = state.activityName;
354 final String windowName = state.windowName;
355 final int stackId = state.stackId;
356 final int windowingMode = state.windowingMode;
357 final int activityType = state.activityType;
358
359 final List<WindowState> matchingWindowStates =
360 getMatchingVisibleWindowState(windowName);
361 boolean activityWindowVisible = !matchingWindowStates.isEmpty();
362 if (!activityWindowVisible) {
363 logAlways("Activity window not visible: " + windowName);
364 allActivityWindowsVisible = false;
365 } else if (activityName != null
366 && !isActivityVisible(activityName)) {
367 logAlways("Activity not visible: " + getActivityName(activityName));
368 allActivityWindowsVisible = false;
369 } else {
370 // Check if window is already the correct state requested by test.
371 boolean windowInCorrectState = false;
372 for (WindowState ws : matchingWindowStates) {
373 if (stackId != INVALID_STACK_ID && ws.getStackId() != stackId) {
374 continue;
375 }
376 if (!ws.isWindowingModeCompatible(windowingMode)) {
377 continue;
378 }
379 if (activityType != ACTIVITY_TYPE_UNDEFINED
380 && ws.getActivityType() != activityType) {
381 continue;
382 }
383 windowInCorrectState = true;
384 break;
385 }
386
387 if (!windowInCorrectState) {
388 logAlways("Window in incorrect stack: " + state);
389 tasksInCorrectStacks = false;
390 }
391 }
392 }
393 return !allActivityWindowsVisible || !tasksInCorrectStacks;
394 }
395
396 /**
397 * @return true if should wait valid windows state.
398 */
399 private boolean shouldWaitForWindows() {
400 if (getFrontWindow() == null) {
401 logAlways("***frontWindow=null");
402 return true;
403 }
404 if (getFocusedWindow() == null) {
405 logAlways("***focusedWindow=null");
406 return true;
407 }
408 if (getFocusedApp() == null) {
409 logAlways("***focusedApp=null");
410 return true;
411 }
412
413 return false;
414 }
415
416 private boolean shouldWaitForDebuggerWindow(ComponentName activityName) {
417 List<WindowState> matchingWindowStates =
418 getMatchingVisibleWindowState(activityName.getPackageName());
419 for (WindowState ws : matchingWindowStates) {
420 if (ws.isDebuggerWindow()) {
421 return false;
422 }
423 }
424 logAlways("Debugger window not available yet");
425 return true;
426 }
427
428 private boolean shouldWaitForActivityRecords(ComponentName... activityNames) {
429 // Check if the activity records we're looking for is already added.
430 for (final ComponentName activityName : activityNames) {
431 if (!isActivityVisible(activityName)) {
432 logAlways("ActivityRecord " + getActivityName(activityName) + " not visible yet");
433 return true;
434 }
435 }
436 return false;
437 }
438
439 private boolean shouldWaitForSanityCheck() {
440 try {
441 assertSanity();
442 } catch (Throwable t) {
443 logAlways("Waiting for sanity check: " + t.toString());
444 return true;
445 }
446 return false;
447 }
448
449 void assertSanity() {
450 assertThat("Must have stacks", getStackCount(), greaterThan(0));
451 // TODO: Update when keyguard will be shown on multiple displays
452 if (!getKeyguardControllerState().keyguardShowing) {
453 assertThat("There should be at least one resumed activity in the system.",
454 getResumedActivitiesCount(), greaterThanOrEqualTo(1));
455 }
456 assertNotNull("Must have focus activity.", getFocusedActivity());
457
458 for (ActivityTask aStack : getRootTasks()) {
459 final int stackId = aStack.mRootTaskId;
460 for (ActivityTask aTask : aStack.getTasks()) {
461 assertEquals("Stack can only contain its own tasks", stackId, aTask.mRootTaskId);
462 }
463 }
464
465 assertNotNull("Must have front window.", getFrontWindow());
466 assertNotNull("Must have focused window.", getFocusedWindow());
467 assertNotNull("Must have app.", getFocusedApp());
468 }
469
470 void assertContainsStack(String msg, int windowingMode, int activityType) {
471 assertTrue(msg, containsStack(windowingMode, activityType));
472 }
473
474 void assertDoesNotContainStack(String msg, int windowingMode, int activityType) {
475 assertFalse(msg, containsStack(windowingMode, activityType));
476 }
477
478 public void assertFrontStack(String msg, int windowingMode, int activityType) {
479 assertFrontStackOnDisplay(msg, windowingMode, activityType, DEFAULT_DISPLAY);
480 }
481
482 void assertFrontStackOnDisplay(String msg, int windowingMode, int activityType, int displayId) {
483 if (windowingMode != WINDOWING_MODE_UNDEFINED) {
484 assertEquals(msg, windowingMode,
485 getFrontStackWindowingMode(displayId));
486 }
487 if (activityType != ACTIVITY_TYPE_UNDEFINED) {
488 assertEquals(msg, activityType, getFrontStackActivityType(displayId));
489 }
490 }
491
492 void assertFrontStackActivityType(String msg, int activityType) {
493 assertEquals(msg, activityType, getFrontStackActivityType(DEFAULT_DISPLAY));
494 }
495
496 void assertFocusedStack(String msg, int stackId) {
497 assertEquals(msg, stackId, getFocusedStackId());
498 }
499
500 void assertFocusedStack(String msg, int windowingMode, int activityType) {
501 if (windowingMode != WINDOWING_MODE_UNDEFINED) {
502 assertEquals(msg, windowingMode, getFocusedStackWindowingMode());
503 }
504 if (activityType != ACTIVITY_TYPE_UNDEFINED) {
505 assertEquals(msg, activityType, getFocusedStackActivityType());
506 }
507 }
508
509 public void assertFocusedActivity(final String msg, final ComponentName activityName) {
510 final String activityComponentName = getActivityName(activityName);
511 assertEquals(msg, activityComponentName, getFocusedActivity());
512 assertEquals(msg, activityComponentName, getFocusedApp());
513 }
514
515 void assertFocusedAppOnDisplay(final String msg, final ComponentName activityName,
516 final int displayId) {
517 final String activityComponentName = getActivityName(activityName);
518 assertEquals(msg, activityComponentName, getDisplay(displayId).getFocusedApp());
519 }
520
521 void assertNotFocusedActivity(String msg, ComponentName activityName) {
522 assertNotEquals(msg, getFocusedActivity(), getActivityName(activityName));
523 assertNotEquals(msg, getFocusedApp(), getActivityName(activityName));
524 }
525
526 public void assertResumedActivity(final String msg, final ComponentName activityName) {
527 assertEquals(msg, getActivityName(activityName),
528 getFocusedActivity());
529 }
530
531 /** Asserts that each display has correct resumed activity. */
532 public void assertResumedActivities(final String msg,
533 Consumer<SparseArray<ComponentName>> resumedActivitiesMapping) {
534 final SparseArray<ComponentName> resumedActivities = new SparseArray<>();
535 resumedActivitiesMapping.accept(resumedActivities);
536 for (int i = 0; i < resumedActivities.size(); i++) {
537 final int displayId = resumedActivities.keyAt(i);
538 final ComponentName activityComponent = resumedActivities.valueAt(i);
539 assertEquals("Error asserting resumed activity on display " + displayId + ": " + msg,
540 activityComponent != null ? getActivityName(activityComponent) : null,
541 getResumedActivityOnDisplay(displayId));
542 }
543 }
544
545 void assertNotResumedActivity(String msg, ComponentName activityName) {
546 assertNotEquals(msg, getFocusedActivity(), getActivityName(activityName));
547 }
548
549 void assertFocusedWindow(String msg, String windowName) {
550 assertEquals(msg, windowName, getFocusedWindow());
551 }
552
553 void assertNotFocusedWindow(String msg, String windowName) {
554 assertNotEquals(msg, getFocusedWindow(), windowName);
555 }
556
557 void assertNotExist(final ComponentName activityName) {
558 final String windowName = getWindowName(activityName);
559 assertFalse("Activity=" + getActivityName(activityName) + " must NOT exist.",
560 containsActivity(activityName));
561 assertFalse("Window=" + windowName + " must NOT exits.",
562 containsWindow(windowName));
563 }
564
Yuncheol Heo03299222020-06-03 21:08:04 -0700565 public void waitAndAssertVisibilityGone(final ComponentName activityName) {
566 // Sometimes the surface can be shown due to the late animation.
567 // Wait for the animation is done.
568 waitForWindowSurfaceDisappeared(getWindowName(activityName));
569 assertVisibility(activityName, false);
570 }
571
Wale Ogunwalecd739102020-01-29 06:15:52 -0800572 public void assertVisibility(final ComponentName activityName, final boolean visible) {
573 final String windowName = getWindowName(activityName);
574 // Check existence of activity and window.
575 assertTrue("Activity=" + getActivityName(activityName) + " must exist.",
576 containsActivity(activityName));
577 assertTrue("Window=" + windowName + " must exist.", containsWindow(windowName));
578
579 // Check visibility of activity and window.
580 assertEquals("Activity=" + getActivityName(activityName) + " must" + (visible ? "" : " NOT")
581 + " be visible.", visible, isActivityVisible(activityName));
Jorim Jaggid9785c62020-03-10 01:21:30 +0100582 assertEquals("Window=" + windowName + " must" + (visible ? "" : " NOT")
583 + " have shown surface.",
584 visible, isWindowSurfaceShown(windowName));
Wale Ogunwalecd739102020-01-29 06:15:52 -0800585 }
586
587 void assertHomeActivityVisible(boolean visible) {
588 final ComponentName homeActivity = getHomeActivityName();
589 assertNotNull(homeActivity);
590 assertVisibility(homeActivity, visible);
591 }
592
593 /**
594 * Asserts that the device default display minimim width is larger than the minimum task width.
595 */
596 void assertDeviceDefaultDisplaySize(String errorMessage) {
597 computeState();
598 final int minTaskSizePx = defaultMinimalTaskSize(DEFAULT_DISPLAY);
599 final WindowManagerState.DisplayContent display = getDisplay(DEFAULT_DISPLAY);
600 final Rect displayRect = display.getDisplayRect();
601 if (Math.min(displayRect.width(), displayRect.height()) < minTaskSizePx) {
602 fail(errorMessage);
603 }
604 }
605
606 public void assertKeyguardShowingAndOccluded() {
607 assertTrue("Keyguard is showing",
608 getKeyguardControllerState().keyguardShowing);
609 assertTrue("Keyguard is occluded",
610 getKeyguardControllerState().isKeyguardOccluded(DEFAULT_DISPLAY));
611 }
612
613 public void assertKeyguardShowingAndNotOccluded() {
614 assertTrue("Keyguard is showing",
615 getKeyguardControllerState().keyguardShowing);
616 assertFalse("Keyguard is not occluded",
617 getKeyguardControllerState().isKeyguardOccluded(DEFAULT_DISPLAY));
618 }
619
620 public void assertKeyguardGone() {
621 assertFalse("Keyguard is not shown",
622 getKeyguardControllerState().keyguardShowing);
623 }
624
Chris Li86337ed2020-03-24 22:18:44 -0700625 void assertKeyguardShownOnSecondaryDisplay(int displayId) {
626 assertTrue("KeyguardDialog must be shown on display " + displayId,
627 isKeyguardOnSecondaryDisplay(this, displayId));
628 }
629
630 void assertKeyguardGoneOnSecondaryDisplay(int displayId) {
631 assertFalse("KeyguardDialog must be gone on display " + displayId,
632 isKeyguardOnSecondaryDisplay(this, displayId));
633 }
634
Wale Ogunwalecd739102020-01-29 06:15:52 -0800635 public void assertAodShowing() {
636 assertTrue("AOD is showing",
637 getKeyguardControllerState().aodShowing);
638 }
639
640 public void assertAodNotShowing() {
641 assertFalse("AOD is not showing",
642 getKeyguardControllerState().aodShowing);
643 }
644
Wale Ogunwaleeb9f0802020-02-04 07:17:17 -0800645 public void assertNoneEmptyTasks() {
Wale Ogunwalecd739102020-01-29 06:15:52 -0800646 computeState();
Wale Ogunwaleeb9f0802020-02-04 07:17:17 -0800647 final List<ActivityTask> tasks = getRootTasks();
648 for (ActivityTask task : tasks) {
649 task.forAllTasks((t) -> assertWithMessage("Empty task was found, id = " + t.mTaskId)
650 .that(t.mTasks.size() + t.mActivities.size()).isGreaterThan(0));
Wale Ogunwalecd739102020-01-29 06:15:52 -0800651 }
652 }
653
654 public void assumePendingActivityContain(ComponentName activity) {
655 assumeTrue(pendingActivityContain(activity));
656 }
657
658 public void assertActivityDisplayed(final ComponentName activityName) {
659 assertWindowDisplayed(getWindowName(activityName));
660 }
661
662 public void assertWindowDisplayed(final String windowName) {
663 waitForValidState(WaitForValidActivityState.forWindow(windowName));
Jorim Jaggid9785c62020-03-10 01:21:30 +0100664 assertTrue(windowName + "is visible", isWindowSurfaceShown(windowName));
Wale Ogunwalecd739102020-01-29 06:15:52 -0800665 }
666
667 void waitAndAssertImeWindowShownOnDisplay(int displayId) {
668 final WindowState imeWinState = Condition.waitForResult("IME window",
669 condition -> condition
670 .setResultSupplier(this::getImeWindowState)
671 .setResultValidator(
Jorim Jaggid9785c62020-03-10 01:21:30 +0100672 w -> w != null && w.isSurfaceShown()
673 && w.getDisplayId() == displayId));
Wale Ogunwalecd739102020-01-29 06:15:52 -0800674
675 assertNotNull("IME window must exist", imeWinState);
Jorim Jaggid9785c62020-03-10 01:21:30 +0100676 assertTrue("IME window must be shown", imeWinState.isSurfaceShown());
Wale Ogunwalecd739102020-01-29 06:15:52 -0800677 assertEquals("IME window must be on the given display", displayId,
678 imeWinState.getDisplayId());
679 }
680
681 WindowState getImeWindowState() {
682 computeState();
683 return getInputMethodWindowState();
684 }
685
686 boolean isScreenPortrait() {
687 final int displayId = getStandardStackByWindowingMode(
688 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY).mDisplayId;
689 return isScreenPortrait(displayId);
690 }
691
692 boolean isScreenPortrait(int displayId) {
693 final Rect displayRect = getDisplay(displayId).getDisplayRect();
694 return displayRect.height() > displayRect.width();
695 }
696
Chris Li86337ed2020-03-24 22:18:44 -0700697 private static boolean isKeyguardOnSecondaryDisplay(
698 WindowManagerState windowManagerState, int displayId) {
699 final List<WindowManagerState.WindowState> states =
700 windowManagerState.getMatchingWindowType(TYPE_KEYGUARD_DIALOG);
701 for (WindowManagerState.WindowState ws : states) {
702 if (ws.getDisplayId() == displayId) return true;
703 }
704 return false;
705 }
Wale Ogunwalecd739102020-01-29 06:15:52 -0800706}