blob: 0f0e512b45ec0da0057e54e0210c5869c65c67a3 [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package android.server.wm;
import static android.app.ActivityTaskManager.INVALID_STACK_ID;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.server.wm.ComponentNameUtils.getActivityName;
import static android.server.wm.ComponentNameUtils.getWindowName;
import static android.server.wm.StateLogger.logAlways;
import static android.server.wm.StateLogger.logE;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
import static com.google.common.truth.Truth.assertWithMessage;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeTrue;
import android.content.ComponentName;
import android.graphics.Rect;
import android.util.SparseArray;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
/** Window Manager State helper class with assert and wait functions. */
public class WindowManagerStateHelper extends WindowManagerState {
/**
* Compute AM and WM state of device, check validity and bounds.
* WM state will include only visible windows, stack and task bounds will be compared.
*
* @param componentNames array of activity names to wait for.
*/
public void computeState(ComponentName... componentNames) {
waitForValidState(Arrays.stream(componentNames)
.map(WaitForValidActivityState::new)
.toArray(WaitForValidActivityState[]::new));
}
/**
* Compute AM and WM state of device, check validity and bounds.
* WM state will include only visible windows, stack and task bounds will be compared.
*
* @param waitForActivitiesVisible array of activity names to wait for.
*/
public void computeState(WaitForValidActivityState... waitForActivitiesVisible) {
waitForValidState(waitForActivitiesVisible);
}
/**
* Wait for the activities to appear and for valid state in AM and WM.
*
* @param activityNames name list of activities to wait for.
*/
public void waitForValidState(ComponentName... activityNames) {
waitForValidState(Arrays.stream(activityNames)
.map(WaitForValidActivityState::new)
.toArray(WaitForValidActivityState[]::new));
}
/**
* Wait for the activities to appear in proper stacks and for valid state in AM and WM.
* @param waitForActivitiesVisible array of activity states to wait for.
*/
public void waitForValidState(WaitForValidActivityState... waitForActivitiesVisible) {
if (!Condition.waitFor("valid stacks and activities states", () -> {
// TODO: Get state of AM and WM at the same time to avoid mismatches caused by
// requesting dump in some intermediate state.
computeState();
return !(shouldWaitForValidityCheck()
|| shouldWaitForValidStacks()
|| shouldWaitForActivities(waitForActivitiesVisible)
|| shouldWaitForWindows());
})) {
logE("***Waiting for states failed: " + Arrays.toString(waitForActivitiesVisible));
}
}
public void waitForAllStoppedActivities() {
if (!Condition.waitFor("all started activities have been removed", () -> {
computeState();
return !containsStartedActivities();
})) {
fail("All started activities have been removed");
}
}
public void waitForAllNonHomeActivitiesToDestroyed() {
Condition.waitFor("all non-home activities to be destroyed", () -> {
computeState();
for (Task rootTask : getRootTasks()) {
final Activity activity = rootTask.getActivity(
(a) -> !a.state.equals(STATE_DESTROYED)
&& a.getActivityType() != ACTIVITY_TYPE_HOME);
if (activity != null) return false;
}
return true;
});
}
/**
* Compute AM and WM state of device, wait for the activity records to be added, and
* wait for debugger window to show up.
*
* This should only be used when starting with -D (debugger) option, where we pop up the
* waiting-for-debugger window, but real activity window won't show up since we're waiting
* for debugger.
*/
public void waitForDebuggerWindowVisible(ComponentName activityName) {
Condition.waitFor("debugger window", () -> {
computeState();
return !shouldWaitForDebuggerWindow(activityName)
&& !shouldWaitForActivityRecords(activityName);
});
}
public void waitForHomeActivityVisible() {
ComponentName homeActivity = getHomeActivityName();
// Sometimes this function is called before we know what Home Activity is
if (homeActivity == null) {
logAlways("Computing state to determine Home Activity");
computeState();
homeActivity = getHomeActivityName();
}
assertNotNull("homeActivity should not be null", homeActivity);
waitForValidState(homeActivity);
}
/** @return {@code true} if the recents is visible; {@code false} if timeout occurs. */
public boolean waitForRecentsActivityVisible() {
if (isHomeRecentsComponent()) {
waitForHomeActivityVisible();
return true;
} else {
return waitForWithAmState(WindowManagerState::isRecentsActivityVisible,
"recents activity to be visible");
}
}
public void waitForDreamGone() {
assertTrue("Dream must be gone",
waitForWithAmState(state -> state.getDreamTask() == null, "DreamActivity gone"));
}
public static boolean isKeyguardShowingAndNotOccluded(WindowManagerState state) {
return state.getKeyguardControllerState().keyguardShowing
&& !state.getKeyguardControllerState().aodShowing
&& !state.getKeyguardControllerState().isKeyguardOccluded(DEFAULT_DISPLAY);
}
public void waitForKeyguardShowingAndNotOccluded() {
waitForWithAmState(WindowManagerStateHelper::isKeyguardShowingAndNotOccluded,
"Keyguard showing");
}
public void waitForKeyguardShowingAndOccluded() {
waitForWithAmState(state -> state.getKeyguardControllerState().keyguardShowing
&& state.getKeyguardControllerState().isKeyguardOccluded(DEFAULT_DISPLAY),
"Keyguard showing and occluded");
}
public void waitForAodShowing() {
waitForWithAmState(state -> state.getKeyguardControllerState().aodShowing, "AOD showing");
}
public void waitForKeyguardGone() {
waitForWithAmState(state -> !state.getKeyguardControllerState().keyguardShowing,
"Keyguard gone");
}
public void waitAndAssertKeyguardGone() {
assertTrue("Keyguard must be gone",
waitForWithAmState(
state -> !state.getKeyguardControllerState().keyguardShowing,
"Keyguard gone"));
}
/** Wait for specific rotation for the default display. Values are Surface#Rotation */
public void waitForRotation(int rotation) {
waitForWithAmState(state -> state.getRotation() == rotation, "Rotation: " + rotation);
}
/**
* Wait for specific orientation for the default display.
* Values are ActivityInfo.ScreenOrientation
*/
public void waitForLastOrientation(int orientation) {
waitForWithAmState(state -> state.getLastOrientation() == orientation,
"LastOrientation: " + orientation);
}
public void waitAndAssertLastOrientation(String message, int screenOrientation) {
if (screenOrientation != getLastOrientation()) {
waitForLastOrientation(screenOrientation);
}
assertEquals(message, screenOrientation, getLastOrientation());
}
/**
* Wait for orientation for the Activity
*/
public void waitForActivityOrientation(ComponentName activityName, int orientation) {
waitForWithAmState(amState -> {
final Task task = amState.getTaskByActivity(activityName);
if (task == null) {
return false;
}
return task.mFullConfiguration.orientation == orientation;
}, "orientation of " + getActivityName(activityName) + " to be " + orientation);
}
public void waitForDisplayUnfrozen() {
waitForWithAmState(state -> !state.isDisplayFrozen(), "Display unfrozen");
}
public void waitForActivityState(ComponentName activityName, String activityState) {
waitForWithAmState(state -> state.hasActivityState(activityName, activityState),
"state of " + getActivityName(activityName) + " to be " + activityState);
}
public void waitForActivityRemoved(ComponentName activityName) {
waitFor((amState) -> !amState.containsActivity(activityName)
&& !amState.containsWindow(getWindowName(activityName)),
getActivityName(activityName) + " to be removed");
}
public void waitAndAssertActivityRemoved(ComponentName activityName) {
waitForActivityRemoved(activityName);
assertNotExist(activityName);
}
public void waitForFocusedStack(int windowingMode, int activityType) {
waitForWithAmState(state ->
(activityType == ACTIVITY_TYPE_UNDEFINED
|| state.getFocusedRootTaskActivityType() == activityType)
&& (windowingMode == WINDOWING_MODE_UNDEFINED
|| state.getFocusedRootTaskWindowingMode() == windowingMode),
"focused stack");
}
public void waitForPendingActivityContain(ComponentName activity) {
waitForWithAmState(state -> state.pendingActivityContain(activity),
getActivityName(activity) + " in pending list");
}
public boolean waitForAppTransitionRunningOnDisplay(int displayId) {
return waitForWithAmState(
state -> WindowManagerState.APP_STATE_RUNNING.equals(
state.getDisplay(displayId).getAppTransitionState()),
"app transition running on Display " + displayId);
}
public boolean waitForAppTransitionIdleOnDisplay(int displayId) {
return waitForWithAmState(
state -> WindowManagerState.APP_STATE_IDLE.equals(
state.getDisplay(displayId).getAppTransitionState()),
"app transition idle on Display " + displayId);
}
void waitAndAssertNavBarShownOnDisplay(int displayId) {
waitAndAssertNavBarShownOnDisplay(displayId, 1 /* expectedNavBarCount */);
}
void waitAndAssertNavBarShownOnDisplay(int displayId, int expectedNavBarCount) {
assertTrue(waitForWithAmState(state -> {
List<WindowState> navWindows = state
.getAndAssertNavBarWindowsOnDisplay(displayId, expectedNavBarCount);
return navWindows != null;
}, "navigation bar #" + displayId + " show"));
}
public void waitAndAssertKeyguardShownOnSecondaryDisplay(int displayId) {
assertTrue("KeyguardDialog must be shown on secondary display " + displayId,
waitForWithAmState(
state -> isKeyguardOnSecondaryDisplay(state, displayId),
"keyguard window to show"));
}
public void waitAndAssertKeyguardGoneOnSecondaryDisplay(int displayId) {
assertTrue("KeyguardDialog must be gone on secondary display " + displayId,
waitForWithAmState(
state -> !isKeyguardOnSecondaryDisplay(state, displayId),
"keyguard window to dismiss"));
}
void waitForWindowSurfaceDisappeared(String windowName) {
waitForWithAmState(state -> {
return !state.isWindowSurfaceShown(windowName);
}, windowName + "'s surface is disappeared");
}
void waitAndAssertWindowSurfaceShown(String windowName, boolean shown) {
assertTrue(
waitForWithAmState(state -> state.isWindowSurfaceShown(windowName) == shown,
windowName + "'s isWindowSurfaceShown to return " + shown));
}
/** A variant of waitForWithAmState with different parameter order for better Kotlin interop. */
public boolean waitForWithAmState(String message, Predicate<WindowManagerState> waitCondition) {
return waitForWithAmState(waitCondition, message);
}
public boolean waitForWithAmState(Predicate<WindowManagerState> waitCondition,
String message) {
return waitFor((amState) -> waitCondition.test(amState), message);
}
public void waitWindowingModeTopFocus(int windowingMode, boolean topFocus, String message) {
waitForWithAmState(amState -> {
final Task rootTask = amState.getStandardRootTaskByWindowingMode(windowingMode);
return rootTask != null
&& topFocus == (amState.getFocusedTaskId() == rootTask.getRootTaskId());
}, message);
}
public void waitForFocusedActivity(final String msg, final ComponentName activityName) {
final String activityComponentName = getActivityName(activityName);
waitFor(msg, wmState -> Objects.equals(activityComponentName, wmState.getFocusedActivity())
&& Objects.equals(activityComponentName, wmState.getFocusedApp()));
}
/** A variant of waitFor with different parameter order for better Kotlin interop. */
public boolean waitFor(String message, Predicate<WindowManagerState> waitCondition) {
return waitFor(waitCondition, message);
}
/** @return {@code true} if the wait is successful; {@code false} if timeout occurs. */
public boolean waitFor(Predicate<WindowManagerState> waitCondition, String message) {
return Condition.waitFor(message, () -> {
computeState();
return waitCondition.test(this);
});
}
/** Waits for non-null result from {@code function} and returns it. */
public <T> T waitForResult(String message, Function<WindowManagerState, T> function) {
return waitForResult(message, function, Objects::nonNull);
}
public <T> T waitForResult(String message, Function<WindowManagerState, T> function,
Predicate<T> validator) {
return Condition.waitForResult(new Condition<T>(message)
.setResultSupplier(() -> {
computeState();
return function.apply(this);
})
.setResultValidator(validator));
}
/**
* @return true if should wait for valid stacks state.
*/
private boolean shouldWaitForValidStacks() {
final int stackCount = getRootTaskCount();
if (stackCount == 0) {
logAlways("***stackCount=" + stackCount);
return true;
}
final int resumedActivitiesCount = getResumedActivitiesCount();
if (!getKeyguardControllerState().keyguardShowing && resumedActivitiesCount < 1) {
logAlways("***resumedActivitiesCount=" + resumedActivitiesCount);
return true;
}
if (getFocusedActivity() == null) {
logAlways("***focusedActivity=null");
return true;
}
return false;
}
public void waitAndAssertAppFocus(String appPackageName, long waitTime) {
final Condition<String> condition = new Condition<>(appPackageName + " to be focused");
Condition.waitFor(condition.setResultSupplier(() -> {
computeState();
return getFocusedApp();
}).setResultValidator(focusedAppName -> {
return focusedAppName != null && appPackageName.equals(
ComponentName.unflattenFromString(focusedAppName).getPackageName());
}).setOnFailure(focusedAppName -> {
fail("Timed out waiting for focus on app "
+ appPackageName + ", last was " + focusedAppName);
}).setRetryIntervalMs(100).setRetryLimit((int) waitTime / 100));
}
/**
* @return true if should wait for some activities to become visible.
*/
private boolean shouldWaitForActivities(WaitForValidActivityState... waitForActivitiesVisible) {
if (waitForActivitiesVisible == null || waitForActivitiesVisible.length == 0) {
return false;
}
// If the caller is interested in us waiting for some particular activity windows to be
// visible before compute the state. Check for the visibility of those activity windows
// and for placing them in correct stacks (if requested).
boolean allActivityWindowsVisible = true;
boolean tasksInCorrectStacks = true;
for (final WaitForValidActivityState state : waitForActivitiesVisible) {
final ComponentName activityName = state.activityName;
final String windowName = state.windowName;
final int stackId = state.stackId;
final int windowingMode = state.windowingMode;
final int activityType = state.activityType;
final List<WindowState> matchingWindowStates =
getMatchingVisibleWindowState(windowName);
boolean activityWindowVisible = !matchingWindowStates.isEmpty();
if (!activityWindowVisible) {
logAlways("Activity window not visible: " + windowName);
allActivityWindowsVisible = false;
} else if (activityName != null
&& !isActivityVisible(activityName)) {
logAlways("Activity not visible: " + getActivityName(activityName));
allActivityWindowsVisible = false;
} else {
// Check if window is already the correct state requested by test.
boolean windowInCorrectState = false;
for (WindowState ws : matchingWindowStates) {
if (stackId != INVALID_STACK_ID && ws.getStackId() != stackId) {
continue;
}
if (!ws.isWindowingModeCompatible(windowingMode)) {
continue;
}
if (activityType != ACTIVITY_TYPE_UNDEFINED
&& ws.getActivityType() != activityType) {
continue;
}
windowInCorrectState = true;
break;
}
if (!windowInCorrectState) {
logAlways("Window in incorrect stack: " + state);
tasksInCorrectStacks = false;
}
}
}
return !allActivityWindowsVisible || !tasksInCorrectStacks;
}
/**
* @return true if should wait valid windows state.
*/
private boolean shouldWaitForWindows() {
if (getFrontWindow() == null) {
logAlways("***frontWindow=null");
return true;
}
if (getFocusedWindow() == null) {
logAlways("***focusedWindow=null");
return true;
}
if (getFocusedApp() == null) {
logAlways("***focusedApp=null");
return true;
}
return false;
}
private boolean shouldWaitForDebuggerWindow(ComponentName activityName) {
List<WindowState> matchingWindowStates =
getMatchingVisibleWindowState(activityName.getPackageName());
for (WindowState ws : matchingWindowStates) {
if (ws.isDebuggerWindow()) {
return false;
}
}
logAlways("Debugger window not available yet");
return true;
}
private boolean shouldWaitForActivityRecords(ComponentName... activityNames) {
// Check if the activity records we're looking for is already added.
for (final ComponentName activityName : activityNames) {
if (!isActivityVisible(activityName)) {
logAlways("ActivityRecord " + getActivityName(activityName) + " not visible yet");
return true;
}
}
return false;
}
private boolean shouldWaitForValidityCheck() {
try {
assertValidity();
} catch (Throwable t) {
logAlways("Waiting for validity check: " + t.toString());
return true;
}
return false;
}
void assertValidity() {
assertThat("Must have root task", getRootTaskCount(), greaterThan(0));
// TODO: Update when keyguard will be shown on multiple displays
if (!getKeyguardControllerState().keyguardShowing) {
assertThat("There should be at least one resumed activity in the system.",
getResumedActivitiesCount(), greaterThanOrEqualTo(1));
}
assertNotNull("Must have focus activity.", getFocusedActivity());
for (Task rootTask : getRootTasks()) {
final int taskId = rootTask.mRootTaskId;
for (Task task : rootTask.getTasks()) {
assertEquals("Root task can only contain its own tasks", taskId,
task.mRootTaskId);
}
}
assertNotNull("Must have front window.", getFrontWindow());
assertNotNull("Must have focused window.", getFocusedWindow());
assertNotNull("Must have app.", getFocusedApp());
}
public void assertContainsStack(String msg, int windowingMode, int activityType) {
assertTrue(msg, containsRootTasks(windowingMode, activityType));
}
public void assertDoesNotContainStack(String msg, int windowingMode, int activityType) {
assertFalse(msg, containsRootTasks(windowingMode, activityType));
}
public void assertFrontStack(String msg, int windowingMode, int activityType) {
assertFrontStackOnDisplay(msg, windowingMode, activityType, DEFAULT_DISPLAY);
}
public void assertFrontStackOnDisplay(String msg, int windowingMode, int activityType,
int displayId) {
if (windowingMode != WINDOWING_MODE_UNDEFINED) {
assertEquals(msg, windowingMode, getFrontRootTaskWindowingMode(displayId));
}
if (activityType != ACTIVITY_TYPE_UNDEFINED) {
assertEquals(msg, activityType, getFrontRootTaskActivityType(displayId));
}
}
public void assertFrontStackActivityType(String msg, int activityType) {
assertEquals(msg, activityType, getFrontRootTaskActivityType(DEFAULT_DISPLAY));
}
void assertFocusedRootTask(String msg, int taskId) {
assertEquals(msg, taskId, getFocusedTaskId());
}
void assertFocusedRootTask(String msg, int windowingMode, int activityType) {
if (windowingMode != WINDOWING_MODE_UNDEFINED) {
assertEquals(msg, windowingMode, getFocusedRootTaskWindowingMode());
}
if (activityType != ACTIVITY_TYPE_UNDEFINED) {
assertEquals(msg, activityType, getFocusedRootTaskActivityType());
}
}
public void assertFocusedActivity(final String msg, final ComponentName activityName) {
final String activityComponentName = getActivityName(activityName);
assertEquals(msg, activityComponentName, getFocusedActivity());
assertEquals(msg, activityComponentName, getFocusedApp());
}
public void assertFocusedAppOnDisplay(final String msg, final ComponentName activityName,
final int displayId) {
final String activityComponentName = getActivityName(activityName);
assertEquals(msg, activityComponentName, getDisplay(displayId).getFocusedApp());
}
public void assertNotFocusedActivity(String msg, ComponentName activityName) {
assertNotEquals(msg, getFocusedActivity(), getActivityName(activityName));
assertNotEquals(msg, getFocusedApp(), getActivityName(activityName));
}
public void assertResumedActivity(final String msg, final ComponentName activityName) {
assertEquals(msg, getActivityName(activityName),
getFocusedActivity());
}
/** Asserts that each display has correct resumed activity. */
public void assertResumedActivities(final String msg,
Consumer<SparseArray<ComponentName>> resumedActivitiesMapping) {
final SparseArray<ComponentName> resumedActivities = new SparseArray<>();
resumedActivitiesMapping.accept(resumedActivities);
for (int i = 0; i < resumedActivities.size(); i++) {
final int displayId = resumedActivities.keyAt(i);
final ComponentName activityComponent = resumedActivities.valueAt(i);
assertEquals("Error asserting resumed activity on display " + displayId + ": " + msg,
activityComponent != null ? getActivityName(activityComponent) : null,
getResumedActivityOnDisplay(displayId));
}
}
public void assertNotResumedActivity(String msg, ComponentName activityName) {
assertNotEquals(msg, getFocusedActivity(), getActivityName(activityName));
}
public void assertFocusedWindow(String msg, String windowName) {
assertEquals(msg, windowName, getFocusedWindow());
}
public void assertNotFocusedWindow(String msg, String windowName) {
assertNotEquals(msg, getFocusedWindow(), windowName);
}
public void assertNotExist(final ComponentName activityName) {
final String windowName = getWindowName(activityName);
assertFalse("Activity=" + getActivityName(activityName) + " must NOT exist.",
containsActivity(activityName));
assertFalse("Window=" + windowName + " must NOT exits.",
containsWindow(windowName));
}
public void waitAndAssertVisibilityGone(final ComponentName activityName) {
// Sometimes the surface can be shown due to the late animation.
// Wait for the animation is done.
waitForWindowSurfaceDisappeared(getWindowName(activityName));
assertVisibility(activityName, false);
}
public void assertVisibility(final ComponentName activityName, final boolean visible) {
final String windowName = getWindowName(activityName);
// Check existence of activity and window.
assertTrue("Activity=" + getActivityName(activityName) + " must exist.",
containsActivity(activityName));
assertTrue("Window=" + windowName + " must exist.", containsWindow(windowName));
// Check visibility of activity and window.
assertEquals("Activity=" + getActivityName(activityName) + " must" + (visible ? "" : " NOT")
+ " be visible.", visible, isActivityVisible(activityName));
assertEquals("Window=" + windowName + " must" + (visible ? "" : " NOT")
+ " have shown surface.",
visible, isWindowSurfaceShown(windowName));
}
public void assertHomeActivityVisible(boolean visible) {
final ComponentName homeActivity = getHomeActivityName();
assertNotNull(homeActivity);
assertVisibility(homeActivity, visible);
}
/**
* Asserts that the device default display minimim width is larger than the minimum task width.
*/
void assertDeviceDefaultDisplaySizeForMultiWindow(String errorMessage) {
computeState();
final int minTaskSizePx = defaultMinimalTaskSize(DEFAULT_DISPLAY);
final WindowManagerState.DisplayContent display = getDisplay(DEFAULT_DISPLAY);
final Rect displayRect = display.getDisplayRect();
if (Math.min(displayRect.width(), displayRect.height()) < minTaskSizePx) {
fail(errorMessage);
}
}
/**
* Asserts that the device default display minimum width is not smaller than the minimum width
* for split-screen required by CDD.
*/
void assertDeviceDefaultDisplaySizeForSplitScreen(String errorMessage) {
computeState();
final int minDisplaySizePx = defaultMinimalDisplaySizeForSplitScreen(DEFAULT_DISPLAY);
final WindowManagerState.DisplayContent display = getDisplay(DEFAULT_DISPLAY);
final Rect displayRect = display.getDisplayRect();
if (Math.max(displayRect.width(), displayRect.height()) < minDisplaySizePx) {
fail(errorMessage);
}
}
public void assertKeyguardShowingAndOccluded() {
assertTrue("Keyguard is showing",
getKeyguardControllerState().keyguardShowing);
assertTrue("Keyguard is occluded",
getKeyguardControllerState().isKeyguardOccluded(DEFAULT_DISPLAY));
}
public void assertKeyguardShowingAndNotOccluded() {
assertTrue("Keyguard is showing",
getKeyguardControllerState().keyguardShowing);
assertFalse("Keyguard is not occluded",
getKeyguardControllerState().isKeyguardOccluded(DEFAULT_DISPLAY));
}
public void assertKeyguardGone() {
assertFalse("Keyguard is not shown",
getKeyguardControllerState().keyguardShowing);
}
void assertKeyguardShownOnSecondaryDisplay(int displayId) {
assertTrue("KeyguardDialog must be shown on display " + displayId,
isKeyguardOnSecondaryDisplay(this, displayId));
}
void assertKeyguardGoneOnSecondaryDisplay(int displayId) {
assertFalse("KeyguardDialog must be gone on display " + displayId,
isKeyguardOnSecondaryDisplay(this, displayId));
}
public void assertAodShowing() {
assertTrue("AOD is showing",
getKeyguardControllerState().aodShowing);
}
public void assertAodNotShowing() {
assertFalse("AOD is not showing",
getKeyguardControllerState().aodShowing);
}
public void assertIllegalTaskState() {
computeState();
final List<Task> tasks = getRootTasks();
for (Task task : tasks) {
task.forAllTasks((t) -> assertWithMessage("Empty task was found, id = " + t.mTaskId)
.that(t.mTasks.size() + t.mActivities.size()).isGreaterThan(0));
if (task.isLeafTask()) {
continue;
}
assertWithMessage("Non-leaf task cannot have affinity set, id = " + task.mTaskId)
.that(task.mAffinity).isEmpty();
}
}
public void assumePendingActivityContain(ComponentName activity) {
assumeTrue(pendingActivityContain(activity));
}
public void assertActivityDisplayed(final ComponentName activityName) {
assertWindowDisplayed(getWindowName(activityName));
}
public void assertWindowDisplayed(final String windowName) {
waitForValidState(WaitForValidActivityState.forWindow(windowName));
assertTrue(windowName + " is visible", isWindowSurfaceShown(windowName));
}
void waitAndAssertImeWindowShownOnDisplay(int displayId) {
final WindowState imeWinState = Condition.waitForResult("IME window",
condition -> condition
.setResultSupplier(this::getImeWindowState)
.setResultValidator(
w -> w != null && w.isSurfaceShown()
&& w.getDisplayId() == displayId));
assertNotNull("IME window must exist", imeWinState);
assertTrue("IME window must be shown", imeWinState.isSurfaceShown());
assertEquals("IME window must be on the given display", displayId,
imeWinState.getDisplayId());
}
WindowState getImeWindowState() {
computeState();
return getInputMethodWindowState();
}
boolean isScreenPortrait(int displayId) {
final Rect displayRect = getDisplay(displayId).getDisplayRect();
return displayRect.height() > displayRect.width();
}
private static boolean isKeyguardOnSecondaryDisplay(
WindowManagerState windowManagerState, int displayId) {
final List<WindowManagerState.WindowState> states =
windowManagerState.getMatchingWindowType(TYPE_KEYGUARD_DIALOG);
for (WindowManagerState.WindowState ws : states) {
if (ws.getDisplayId() == displayId) return true;
}
return false;
}
}