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 /** Manual overload for java compatibility */ 180 fun isAppWindowInvisible(componentMatcher: IComponentMatcher): WMSubjectType = 181 isAppWindowInvisible(componentMatcher, mustExist = false) 182 183 /** 184 * Asserts the state contains an invisible window [WindowState] matching [componentMatcher]. 185 * 186 * Also, if [componentMatcher] has a package name (i.e., is not a system component), also checks 187 * that it contains an invisible [Activity] matching [componentMatcher]. 188 * 189 * @param componentMatcher Components to search 190 * @param mustExist when true, the test will fail if the component doesn't exist. Otherwise, the 191 * test will automatically pass when the component is not found 192 */ 193 fun isAppWindowInvisible(componentMatcher: IComponentMatcher, mustExist: Boolean): WMSubjectType 194 195 /** Manual overload for java compatibility */ 196 fun isNonAppWindowInvisible(componentMatcher: IComponentMatcher): WMSubjectType = 197 isNonAppWindowInvisible(componentMatcher, mustExist = false) 198 199 /** 200 * Asserts the state contains an invisible window matching [componentMatcher]. 201 * 202 * Also, if [componentMatcher] has a package name (i.e., is not a system component), also checks 203 * that it contains an invisible [Activity] matching [componentMatcher]. 204 * 205 * @param componentMatcher Components to search 206 * @param mustExist when true, the test will fail if the component doesn't exist. Otherwise, the 207 * test will automatically pass when the component is not found 208 */ 209 fun isNonAppWindowInvisible( 210 componentMatcher: IComponentMatcher, 211 mustExist: Boolean, 212 ): WMSubjectType 213 214 /** Asserts the state home activity is visible */ 215 fun isHomeActivityVisible(): WMSubjectType 216 217 /** Asserts the state home activity is invisible */ 218 fun isHomeActivityInvisible(): WMSubjectType 219 220 /** 221 * Asserts that [app] is the focused app 222 * 223 * @param app App to check 224 */ 225 fun isFocusedApp(app: String): WMSubjectType 226 227 /** 228 * Asserts that [app] is not the focused app 229 * 230 * @param app App to check 231 */ 232 fun isNotFocusedApp(app: String): WMSubjectType 233 234 /** 235 * Asserts that [componentMatcher] exists and is pinned (in PIP mode) 236 * 237 * @param componentMatcher Components to search 238 */ 239 fun isPinned(componentMatcher: IComponentMatcher): WMSubjectType 240 241 /** 242 * Asserts that [componentMatcher] exists and is not pinned (not in PIP mode) 243 * 244 * @param componentMatcher Components to search 245 */ 246 fun isNotPinned(componentMatcher: IComponentMatcher): WMSubjectType 247 248 /** 249 * Checks if the activity with matching [componentMatcher] is visible 250 * 251 * In the case that an app is stopped in the background (e.g. OS stopped it to release memory) 252 * the app window will not be immediately visible when switching back to the app. Checking if a 253 * snapshotStartingWindow is present for that app instead can decrease flakiness levels of the 254 * assertion. 255 * 256 * @param componentMatcher Component to search 257 */ 258 fun isAppSnapshotStartingWindowVisibleFor(componentMatcher: IComponentMatcher): WMSubjectType 259 260 /** 261 * Checks if the non-app window matching [componentMatcher] exists above the app windows and is 262 * visible 263 * 264 * @param componentMatcher Components to search 265 */ 266 fun isAboveAppWindowVisible(componentMatcher: IComponentMatcher): WMSubjectType 267 268 /** 269 * Checks if the non-app window matching [componentMatcher] exists above the app windows and is 270 * invisible 271 * 272 * @param componentMatcher Components to search 273 */ 274 fun isAboveAppWindowInvisible(componentMatcher: IComponentMatcher): WMSubjectType 275 276 /** 277 * Checks if the non-app window matching [componentMatcher] exists below the app windows and is 278 * visible 279 * 280 * @param componentMatcher Components to search 281 */ 282 fun isBelowAppWindowVisible(componentMatcher: IComponentMatcher): WMSubjectType 283 284 /** 285 * Checks if the non-app window matching [componentMatcher] exists below the app windows and is 286 * invisible 287 * 288 * @param componentMatcher Components to search 289 */ 290 fun isBelowAppWindowInvisible(componentMatcher: IComponentMatcher): WMSubjectType 291 292 /** Checks if the state contains at least one [DisplayContent] */ 293 fun containsAtLeastOneDisplay(): WMSubjectType 294 } 295