1 /*
2 * Copyright (C) 2020 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 @file:JvmName("CommonAssertions")
18
19 package com.android.wm.shell.flicker.utils
20
21 import android.graphics.Region
22 import android.tools.Rotation
23 import android.tools.flicker.legacy.LegacyFlickerTest
24 import android.tools.flicker.subject.layers.LayerTraceEntrySubject
25 import android.tools.flicker.subject.layers.LayersTraceSubject
26 import android.tools.helpers.WindowUtils
27 import android.tools.traces.component.IComponentMatcher
28
LegacyFlickerTestnull29 fun LegacyFlickerTest.appPairsDividerIsVisibleAtEnd() {
30 assertLayersEnd { this.isVisible(APP_PAIR_SPLIT_DIVIDER_COMPONENT) }
31 }
32
LegacyFlickerTestnull33 fun LegacyFlickerTest.appPairsDividerIsInvisibleAtEnd() {
34 assertLayersEnd { this.notContains(APP_PAIR_SPLIT_DIVIDER_COMPONENT) }
35 }
36
appPairsDividerBecomesVisiblenull37 fun LegacyFlickerTest.appPairsDividerBecomesVisible() {
38 assertLayers {
39 this.isInvisible(DOCKED_STACK_DIVIDER_COMPONENT)
40 .then()
41 .isVisible(DOCKED_STACK_DIVIDER_COMPONENT)
42 }
43 }
44
splitScreenEnterednull45 fun LegacyFlickerTest.splitScreenEntered(
46 component1: IComponentMatcher,
47 component2: IComponentMatcher,
48 fromOtherApp: Boolean,
49 appExistAtStart: Boolean = true
50 ) {
51 if (fromOtherApp) {
52 if (appExistAtStart) {
53 appWindowIsInvisibleAtStart(component1)
54 } else {
55 appWindowIsNotContainAtStart(component1)
56 }
57 } else {
58 appWindowIsVisibleAtStart(component1)
59 }
60 if (appExistAtStart) {
61 appWindowIsInvisibleAtStart(component2)
62 } else {
63 appWindowIsNotContainAtStart(component2)
64 }
65 splitScreenDividerIsInvisibleAtStart()
66
67 appWindowIsVisibleAtEnd(component1)
68 appWindowIsVisibleAtEnd(component2)
69 splitScreenDividerIsVisibleAtEnd()
70 }
71
splitScreenDismissednull72 fun LegacyFlickerTest.splitScreenDismissed(
73 component1: IComponentMatcher,
74 component2: IComponentMatcher,
75 toHome: Boolean
76 ) {
77 appWindowIsVisibleAtStart(component1)
78 appWindowIsVisibleAtStart(component2)
79 splitScreenDividerIsVisibleAtStart()
80
81 appWindowIsInvisibleAtEnd(component1)
82 if (toHome) {
83 appWindowIsInvisibleAtEnd(component2)
84 } else {
85 appWindowIsVisibleAtEnd(component2)
86 }
87 splitScreenDividerIsInvisibleAtEnd()
88 }
89
LegacyFlickerTestnull90 fun LegacyFlickerTest.splitScreenDividerIsVisibleAtStart() {
91 assertLayersStart { this.isVisible(SPLIT_SCREEN_DIVIDER_COMPONENT) }
92 }
93
LegacyFlickerTestnull94 fun LegacyFlickerTest.splitScreenDividerIsVisibleAtEnd() {
95 assertLayersEnd { this.isVisible(SPLIT_SCREEN_DIVIDER_COMPONENT) }
96 }
97
splitScreenDividerIsInvisibleAtStartnull98 fun LegacyFlickerTest.splitScreenDividerIsInvisibleAtStart() {
99 assertLayersStart { this.isInvisible(SPLIT_SCREEN_DIVIDER_COMPONENT) }
100 }
101
splitScreenDividerIsInvisibleAtEndnull102 fun LegacyFlickerTest.splitScreenDividerIsInvisibleAtEnd() {
103 assertLayersEnd { this.isInvisible(SPLIT_SCREEN_DIVIDER_COMPONENT) }
104 }
105
LegacyFlickerTestnull106 fun LegacyFlickerTest.splitScreenDividerBecomesVisible() {
107 layerBecomesVisible(SPLIT_SCREEN_DIVIDER_COMPONENT)
108 }
109
splitScreenDividerBecomesInvisiblenull110 fun LegacyFlickerTest.splitScreenDividerBecomesInvisible() {
111 assertLayers {
112 this.isVisible(SPLIT_SCREEN_DIVIDER_COMPONENT)
113 .then()
114 .isInvisible(SPLIT_SCREEN_DIVIDER_COMPONENT)
115 }
116 }
117
layerBecomesVisiblenull118 fun LegacyFlickerTest.layerBecomesVisible(component: IComponentMatcher) {
119 assertLayers { this.isInvisible(component).then().isVisible(component) }
120 }
121
LegacyFlickerTestnull122 fun LegacyFlickerTest.layerBecomesInvisible(component: IComponentMatcher) {
123 assertLayers { this.isVisible(component).then().isInvisible(component) }
124 }
125
LegacyFlickerTestnull126 fun LegacyFlickerTest.layerIsVisibleAtEnd(component: IComponentMatcher) {
127 assertLayersEnd { this.isVisible(component) }
128 }
129
LegacyFlickerTestnull130 fun LegacyFlickerTest.layerKeepVisible(component: IComponentMatcher) {
131 assertLayers { this.isVisible(component) }
132 }
133
LegacyFlickerTestnull134 fun LegacyFlickerTest.splitAppLayerBoundsBecomesVisible(
135 component: IComponentMatcher,
136 landscapePosLeft: Boolean,
137 portraitPosTop: Boolean
138 ) {
139 assertLayers {
140 this.notContains(SPLIT_SCREEN_DIVIDER_COMPONENT.or(component), isOptional = true)
141 .then()
142 .isInvisible(SPLIT_SCREEN_DIVIDER_COMPONENT.or(component))
143 .then()
144 .splitAppLayerBoundsSnapToDivider(
145 component,
146 landscapePosLeft,
147 portraitPosTop,
148 scenario.endRotation
149 )
150 }
151 }
152
splitAppLayerBoundsBecomesVisibleByDragnull153 fun LegacyFlickerTest.splitAppLayerBoundsBecomesVisibleByDrag(component: IComponentMatcher) {
154 assertLayers {
155 this.notContains(SPLIT_SCREEN_DIVIDER_COMPONENT.or(component), isOptional = true)
156 .then()
157 .isInvisible(SPLIT_SCREEN_DIVIDER_COMPONENT.or(component))
158 .then()
159 // TODO(b/245472831): Verify the component should snap to divider.
160 .isVisible(component)
161 }
162 }
163
splitAppLayerBoundsBecomesInvisiblenull164 fun LegacyFlickerTest.splitAppLayerBoundsBecomesInvisible(
165 component: IComponentMatcher,
166 landscapePosLeft: Boolean,
167 portraitPosTop: Boolean
168 ) {
169 assertLayers {
170 this.splitAppLayerBoundsSnapToDivider(
171 component,
172 landscapePosLeft,
173 portraitPosTop,
174 scenario.endRotation
175 )
176 .then()
177 .isVisible(component, true)
178 .then()
179 .isInvisible(component)
180 }
181 }
182
splitAppLayerBoundsIsVisibleAtEndnull183 fun LegacyFlickerTest.splitAppLayerBoundsIsVisibleAtEnd(
184 component: IComponentMatcher,
185 landscapePosLeft: Boolean,
186 portraitPosTop: Boolean
187 ) {
188 assertLayersEnd {
189 splitAppLayerBoundsSnapToDivider(
190 component,
191 landscapePosLeft,
192 portraitPosTop,
193 scenario.endRotation
194 )
195 }
196 }
197
splitAppLayerBoundsKeepVisiblenull198 fun LegacyFlickerTest.splitAppLayerBoundsKeepVisible(
199 component: IComponentMatcher,
200 landscapePosLeft: Boolean,
201 portraitPosTop: Boolean
202 ) {
203 assertLayers {
204 splitAppLayerBoundsSnapToDivider(
205 component,
206 landscapePosLeft,
207 portraitPosTop,
208 scenario.endRotation
209 )
210 }
211 }
212
splitAppLayerBoundsChangesnull213 fun LegacyFlickerTest.splitAppLayerBoundsChanges(
214 component: IComponentMatcher,
215 landscapePosLeft: Boolean,
216 portraitPosTop: Boolean
217 ) {
218 assertLayers {
219 if (landscapePosLeft) {
220 splitAppLayerBoundsSnapToDivider(
221 component,
222 landscapePosLeft,
223 portraitPosTop,
224 scenario.endRotation
225 )
226 } else {
227 splitAppLayerBoundsSnapToDivider(
228 component,
229 landscapePosLeft,
230 portraitPosTop,
231 scenario.endRotation
232 )
233 .then()
234 .isInvisible(component)
235 .then()
236 .splitAppLayerBoundsSnapToDivider(
237 component,
238 landscapePosLeft,
239 portraitPosTop,
240 scenario.endRotation
241 )
242 }
243 }
244 }
245
splitAppLayerBoundsSnapToDividernull246 fun LayersTraceSubject.splitAppLayerBoundsSnapToDivider(
247 component: IComponentMatcher,
248 landscapePosLeft: Boolean,
249 portraitPosTop: Boolean,
250 rotation: Rotation
251 ): LayersTraceSubject {
252 return invoke("splitAppLayerBoundsSnapToDivider") {
253 it.splitAppLayerBoundsSnapToDivider(component, landscapePosLeft, portraitPosTop, rotation)
254 }
255 }
256
LayerTraceEntrySubjectnull257 fun LayerTraceEntrySubject.splitAppLayerBoundsSnapToDivider(
258 component: IComponentMatcher,
259 landscapePosLeft: Boolean,
260 portraitPosTop: Boolean,
261 rotation: Rotation
262 ): LayerTraceEntrySubject {
263 val displayBounds = WindowUtils.getDisplayBounds(rotation)
264 return invoke {
265 val dividerRegion =
266 layer(SPLIT_SCREEN_DIVIDER_COMPONENT)?.visibleRegion?.region?.bounds
267 ?: error("$SPLIT_SCREEN_DIVIDER_COMPONENT component not found")
268 visibleRegion(component).isNotEmpty()
269 visibleRegion(component)
270 .coversAtMost(
271 if (displayBounds.width() > displayBounds.height()) {
272 if (landscapePosLeft) {
273 Region(
274 0,
275 0,
276 (dividerRegion.left + dividerRegion.right) / 2,
277 displayBounds.bottom
278 )
279 } else {
280 Region(
281 (dividerRegion.left + dividerRegion.right) / 2,
282 0,
283 displayBounds.right,
284 displayBounds.bottom
285 )
286 }
287 } else {
288 if (portraitPosTop) {
289 Region(
290 0,
291 0,
292 displayBounds.right,
293 (dividerRegion.top + dividerRegion.bottom) / 2
294 )
295 } else {
296 Region(
297 0,
298 (dividerRegion.top + dividerRegion.bottom) / 2,
299 displayBounds.right,
300 displayBounds.bottom
301 )
302 }
303 }
304 )
305 }
306 }
307
appWindowBecomesVisiblenull308 fun LegacyFlickerTest.appWindowBecomesVisible(component: IComponentMatcher) {
309 assertWm {
310 this.isAppWindowInvisible(component)
311 .then()
312 .notContains(component, isOptional = true)
313 .then()
314 .isAppWindowInvisible(component, isOptional = true)
315 .then()
316 .isAppWindowVisible(component)
317 }
318 }
319
appWindowBecomesInvisiblenull320 fun LegacyFlickerTest.appWindowBecomesInvisible(component: IComponentMatcher) {
321 assertWm { this.isAppWindowVisible(component).then().isAppWindowInvisible(component) }
322 }
323
LegacyFlickerTestnull324 fun LegacyFlickerTest.appWindowIsVisibleAtStart(component: IComponentMatcher) {
325 assertWmStart { this.isAppWindowVisible(component) }
326 }
327
LegacyFlickerTestnull328 fun LegacyFlickerTest.appWindowIsVisibleAtEnd(component: IComponentMatcher) {
329 assertWmEnd { this.isAppWindowVisible(component) }
330 }
331
appWindowIsInvisibleAtStartnull332 fun LegacyFlickerTest.appWindowIsInvisibleAtStart(component: IComponentMatcher) {
333 assertWmStart { this.isAppWindowInvisible(component) }
334 }
335
appWindowIsInvisibleAtEndnull336 fun LegacyFlickerTest.appWindowIsInvisibleAtEnd(component: IComponentMatcher) {
337 assertWmEnd { this.isAppWindowInvisible(component) }
338 }
339
LegacyFlickerTestnull340 fun LegacyFlickerTest.appWindowIsNotContainAtStart(component: IComponentMatcher) {
341 assertWmStart { this.notContains(component) }
342 }
343
appWindowKeepVisiblenull344 fun LegacyFlickerTest.appWindowKeepVisible(component: IComponentMatcher) {
345 assertWm { this.isAppWindowVisible(component) }
346 }
347
dockedStackDividerIsVisibleAtEndnull348 fun LegacyFlickerTest.dockedStackDividerIsVisibleAtEnd() {
349 assertLayersEnd { this.isVisible(DOCKED_STACK_DIVIDER_COMPONENT) }
350 }
351
dockedStackDividerBecomesVisiblenull352 fun LegacyFlickerTest.dockedStackDividerBecomesVisible() {
353 assertLayers {
354 this.isInvisible(DOCKED_STACK_DIVIDER_COMPONENT)
355 .then()
356 .isVisible(DOCKED_STACK_DIVIDER_COMPONENT)
357 }
358 }
359
dockedStackDividerBecomesInvisiblenull360 fun LegacyFlickerTest.dockedStackDividerBecomesInvisible() {
361 assertLayers {
362 this.isVisible(DOCKED_STACK_DIVIDER_COMPONENT)
363 .then()
364 .isInvisible(DOCKED_STACK_DIVIDER_COMPONENT)
365 }
366 }
367
dockedStackDividerNotExistsAtEndnull368 fun LegacyFlickerTest.dockedStackDividerNotExistsAtEnd() {
369 assertLayersEnd { this.notContains(DOCKED_STACK_DIVIDER_COMPONENT) }
370 }
371
LegacyFlickerTestnull372 fun LegacyFlickerTest.appPairsPrimaryBoundsIsVisibleAtEnd(
373 rotation: Rotation,
374 primaryComponent: IComponentMatcher
375 ) {
376 assertLayersEnd {
377 val dividerRegion =
378 layer(APP_PAIR_SPLIT_DIVIDER_COMPONENT)?.visibleRegion?.region
379 ?: error("$APP_PAIR_SPLIT_DIVIDER_COMPONENT component not found")
380 visibleRegion(primaryComponent).overlaps(getPrimaryRegion(dividerRegion, rotation))
381 }
382 }
383
dockedStackPrimaryBoundsIsVisibleAtEndnull384 fun LegacyFlickerTest.dockedStackPrimaryBoundsIsVisibleAtEnd(
385 rotation: Rotation,
386 primaryComponent: IComponentMatcher
387 ) {
388 assertLayersEnd {
389 val dividerRegion =
390 layer(DOCKED_STACK_DIVIDER_COMPONENT)?.visibleRegion?.region
391 ?: error("$DOCKED_STACK_DIVIDER_COMPONENT component not found")
392 visibleRegion(primaryComponent).overlaps(getPrimaryRegion(dividerRegion, rotation))
393 }
394 }
395
appPairsSecondaryBoundsIsVisibleAtEndnull396 fun LegacyFlickerTest.appPairsSecondaryBoundsIsVisibleAtEnd(
397 rotation: Rotation,
398 secondaryComponent: IComponentMatcher
399 ) {
400 assertLayersEnd {
401 val dividerRegion =
402 layer(APP_PAIR_SPLIT_DIVIDER_COMPONENT)?.visibleRegion?.region
403 ?: error("$APP_PAIR_SPLIT_DIVIDER_COMPONENT component not found")
404 visibleRegion(secondaryComponent).overlaps(getSecondaryRegion(dividerRegion, rotation))
405 }
406 }
407
LegacyFlickerTestnull408 fun LegacyFlickerTest.dockedStackSecondaryBoundsIsVisibleAtEnd(
409 rotation: Rotation,
410 secondaryComponent: IComponentMatcher
411 ) {
412 assertLayersEnd {
413 val dividerRegion =
414 layer(DOCKED_STACK_DIVIDER_COMPONENT)?.visibleRegion?.region
415 ?: error("$DOCKED_STACK_DIVIDER_COMPONENT component not found")
416 visibleRegion(secondaryComponent).overlaps(getSecondaryRegion(dividerRegion, rotation))
417 }
418 }
419
getPrimaryRegionnull420 fun getPrimaryRegion(dividerRegion: Region, rotation: Rotation): Region {
421 val displayBounds = WindowUtils.getDisplayBounds(rotation)
422 return if (rotation.isRotated()) {
423 Region(
424 0,
425 0,
426 dividerRegion.bounds.left + WindowUtils.dockedStackDividerInset,
427 displayBounds.bottom
428 )
429 } else {
430 Region(
431 0,
432 0,
433 displayBounds.right,
434 dividerRegion.bounds.top + WindowUtils.dockedStackDividerInset
435 )
436 }
437 }
438
getSecondaryRegionnull439 fun getSecondaryRegion(dividerRegion: Region, rotation: Rotation): Region {
440 val displayBounds = WindowUtils.getDisplayBounds(rotation)
441 return if (rotation.isRotated()) {
442 Region(
443 dividerRegion.bounds.right - WindowUtils.dockedStackDividerInset,
444 0,
445 displayBounds.right,
446 displayBounds.bottom
447 )
448 } else {
449 Region(
450 0,
451 dividerRegion.bounds.bottom - WindowUtils.dockedStackDividerInset,
452 displayBounds.right,
453 displayBounds.bottom
454 )
455 }
456 }
457