• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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