1 /* 2 * Copyright (C) 2023 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.tools.flicker.subject.wm 18 19 import android.tools.PlatformConsts 20 import android.tools.Rotation 21 import android.tools.traces.component.IComponentMatcher 22 import android.tools.traces.wm.Activity 23 import android.tools.traces.wm.DisplayContent 24 import android.tools.traces.wm.WindowState 25 26 /** Base interface for WM trace and state assertions */ 27 interface IWindowManagerSubject<WMSubjectType, RegionSubjectType> { 28 /** Asserts the current WindowManager state doesn't contain [WindowState]s */ isEmptynull29 fun isEmpty(): WMSubjectType 30 31 /** Asserts the current WindowManager state contains [WindowState]s */ 32 fun isNotEmpty(): WMSubjectType 33 34 /** 35 * Obtains the region occupied by all windows matching [componentMatcher] 36 * 37 * @param componentMatcher Components to search 38 */ 39 fun visibleRegion(componentMatcher: IComponentMatcher? = null): RegionSubjectType 40 41 /** 42 * Asserts the state contains a [WindowState] matching [componentMatcher] above the app windows 43 * 44 * @param componentMatcher Component to search 45 */ 46 fun containsAboveAppWindow(componentMatcher: IComponentMatcher): WMSubjectType 47 48 /** 49 * Asserts the state contains a [WindowState] matching [componentMatcher] below the app windows 50 * 51 * @param componentMatcher Component to search 52 */ 53 fun containsBelowAppWindow(componentMatcher: IComponentMatcher): WMSubjectType 54 55 /** 56 * Asserts the state contains [WindowState]s matching [aboveWindowComponentMatcher] and 57 * [belowWindowComponentMatcher], and that [aboveWindowComponentMatcher] is above 58 * [belowWindowComponentMatcher] 59 * 60 * This assertion can be used, for example, to assert that a PIP window is shown above other 61 * apps. 62 * 63 * @param aboveWindowComponentMatcher name of the window that should be above 64 * @param belowWindowComponentMatcher name of the window that should be below 65 */ 66 fun isAboveWindow( 67 aboveWindowComponentMatcher: IComponentMatcher, 68 belowWindowComponentMatcher: IComponentMatcher 69 ): WMSubjectType 70 71 /** 72 * Asserts the state contains a non-app [WindowState] matching [componentMatcher] 73 * 74 * @param componentMatcher Component to search 75 */ 76 fun containsNonAppWindow(componentMatcher: IComponentMatcher): WMSubjectType 77 78 /** 79 * Asserts the top visible app window in the state matches [componentMatcher] 80 * 81 * @param componentMatcher Component to search 82 */ 83 fun isAppWindowOnTop(componentMatcher: IComponentMatcher): WMSubjectType 84 85 /** 86 * Asserts the top visible app window in the state doesn't match [componentMatcher] 87 * 88 * @param componentMatcher Component to search 89 */ 90 fun isAppWindowNotOnTop(componentMatcher: IComponentMatcher): WMSubjectType 91 92 /** 93 * Asserts the bounds of the [WindowState] matching [componentMatcher] don't overlap. 94 * 95 * @param componentMatcher Component to search 96 */ 97 fun doNotOverlap(vararg componentMatcher: IComponentMatcher): WMSubjectType 98 99 /** 100 * Asserts the state contains an app [WindowState] matching [componentMatcher] 101 * 102 * @param componentMatcher Component to search 103 */ 104 fun containsAppWindow(componentMatcher: IComponentMatcher): WMSubjectType 105 106 /** 107 * Asserts the display with id [displayId] has rotation [rotation] 108 * 109 * @param rotation to assert 110 * @param displayId of the target display 111 */ 112 fun hasRotation( 113 rotation: Rotation, 114 displayId: Int = PlatformConsts.DEFAULT_DISPLAY 115 ): WMSubjectType 116 117 /** 118 * Asserts the state contains a [WindowState] matching [componentMatcher]. 119 * 120 * @param componentMatcher Components to search 121 */ 122 fun contains(componentMatcher: IComponentMatcher): WMSubjectType 123 124 /** 125 * Asserts the state doesn't contain a [WindowState] nor an [Activity] matching 126 * [componentMatcher]. 127 * 128 * @param componentMatcher Components to search 129 */ 130 fun notContainsAppWindow(componentMatcher: IComponentMatcher): WMSubjectType 131 132 /** 133 * Asserts the state doesn't contain a [WindowState] matching [componentMatcher]. 134 * 135 * @param componentMatcher Components to search 136 */ 137 fun notContains(componentMatcher: IComponentMatcher): WMSubjectType 138 139 fun isRecentsActivityVisible(): WMSubjectType 140 141 fun isRecentsActivityInvisible(): WMSubjectType 142 143 /** 144 * Asserts the state is valid, that is, if it has: 145 * - a resumed activity 146 * - a focused activity 147 * - a focused window 148 * - a front window 149 * - a focused app 150 */ 151 fun isValid(): WMSubjectType 152 153 /** 154 * Asserts the state contains a visible [WindowState] matching [componentMatcher]. 155 * 156 * Also, if [componentMatcher] has a package name (i.e., is not a system component), also checks 157 * that it contains a visible [Activity] matching [componentMatcher]. 158 * 159 * @param componentMatcher Components to search 160 */ 161 fun isNonAppWindowVisible(componentMatcher: IComponentMatcher): WMSubjectType 162 163 /** 164 * Asserts the state contains a visible [WindowState] matching [componentMatcher]. 165 * 166 * Also, if [componentMatcher] has a package name (i.e., is not a system component), also checks 167 * that it contains a visible [Activity] matching [componentMatcher]. 168 * 169 * @param componentMatcher Components to search 170 */ 171 fun isAppWindowVisible(componentMatcher: IComponentMatcher): WMSubjectType 172 173 /** Asserts the state contains no visible app windows. */ 174 fun hasNoVisibleAppWindow(): WMSubjectType 175 176 /** Asserts the state contains no visible app windows. */ 177 fun isKeyguardShowing(): WMSubjectType 178 179 /** 180 * Asserts the state contains an invisible window [WindowState] matching [componentMatcher]. 181 * 182 * Also, if [componentMatcher] has a package name (i.e., is not a system component), also checks 183 * that it contains an invisible [Activity] matching [componentMatcher]. 184 * 185 * @param componentMatcher Components to search 186 */ 187 fun isAppWindowInvisible(componentMatcher: IComponentMatcher): WMSubjectType 188 189 /** 190 * Asserts the state contains an invisible window matching [componentMatcher]. 191 * 192 * Also, if [componentMatcher] has a package name (i.e., is not a system component), also checks 193 * that it contains an invisible [Activity] matching [componentMatcher]. 194 * 195 * @param componentMatcher Components to search 196 */ 197 fun isNonAppWindowInvisible(componentMatcher: IComponentMatcher): WMSubjectType 198 199 /** Asserts the state home activity is visible */ 200 fun isHomeActivityVisible(): WMSubjectType 201 202 /** Asserts the state home activity is invisible */ 203 fun isHomeActivityInvisible(): WMSubjectType 204 205 /** 206 * Asserts that [app] is the focused app 207 * 208 * @param app App to check 209 */ 210 fun isFocusedApp(app: String): WMSubjectType 211 212 /** 213 * Asserts that [app] is not the focused app 214 * 215 * @param app App to check 216 */ 217 fun isNotFocusedApp(app: String): WMSubjectType 218 219 /** 220 * Asserts that [componentMatcher] exists and is pinned (in PIP mode) 221 * 222 * @param componentMatcher Components to search 223 */ 224 fun isPinned(componentMatcher: IComponentMatcher): WMSubjectType 225 226 /** 227 * Asserts that [componentMatcher] exists and is not pinned (not in PIP mode) 228 * 229 * @param componentMatcher Components to search 230 */ 231 fun isNotPinned(componentMatcher: IComponentMatcher): WMSubjectType 232 233 /** 234 * Checks if the activity with matching [componentMatcher] is visible 235 * 236 * In the case that an app is stopped in the background (e.g. OS stopped it to release memory) 237 * the app window will not be immediately visible when switching back to the app. Checking if a 238 * snapshotStartingWindow is present for that app instead can decrease flakiness levels of the 239 * assertion. 240 * 241 * @param componentMatcher Component to search 242 */ 243 fun isAppSnapshotStartingWindowVisibleFor(componentMatcher: IComponentMatcher): WMSubjectType 244 245 /** 246 * Checks if the non-app window matching [componentMatcher] exists above the app windows and is 247 * visible 248 * 249 * @param componentMatcher Components to search 250 */ 251 fun isAboveAppWindowVisible(componentMatcher: IComponentMatcher): WMSubjectType 252 253 /** 254 * Checks if the non-app window matching [componentMatcher] exists above the app windows and is 255 * invisible 256 * 257 * @param componentMatcher Components to search 258 */ 259 fun isAboveAppWindowInvisible(componentMatcher: IComponentMatcher): WMSubjectType 260 261 /** 262 * Checks if the non-app window matching [componentMatcher] exists below the app windows and is 263 * visible 264 * 265 * @param componentMatcher Components to search 266 */ 267 fun isBelowAppWindowVisible(componentMatcher: IComponentMatcher): WMSubjectType 268 269 /** 270 * Checks if the non-app window matching [componentMatcher] exists below the app windows and is 271 * invisible 272 * 273 * @param componentMatcher Components to search 274 */ 275 fun isBelowAppWindowInvisible(componentMatcher: IComponentMatcher): WMSubjectType 276 277 /** Checks if the state contains at least one [DisplayContent] */ 278 fun containsAtLeastOneDisplay(): WMSubjectType 279 } 280