1 /*
<lambda>null2  * 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 com.android.wm.shell.flicker.pip.common
18 
19 import android.platform.test.annotations.Postsubmit
20 import android.platform.test.annotations.Presubmit
21 import android.tools.Rotation
22 import android.tools.flicker.legacy.LegacyFlickerTest
23 import android.tools.flicker.legacy.LegacyFlickerTestFactory
24 import android.tools.traces.component.ComponentNameMatcher
25 import com.android.server.wm.flicker.helpers.SimpleAppHelper
26 import org.junit.Test
27 import org.junit.runners.Parameterized
28 
29 /** Base class for pip expand tests */
30 abstract class ExitPipToAppTransition(flicker: LegacyFlickerTest) : PipTransition(flicker) {
31     protected val testApp = SimpleAppHelper(instrumentation)
32 
33     /**
34      * Checks that the pip app window remains inside the display bounds throughout the whole
35      * animation
36      */
37     @Presubmit
38     @Test
39     open fun pipAppWindowRemainInsideVisibleBounds() {
40         flicker.assertWmVisibleRegion(pipApp.or(ComponentNameMatcher.TRANSITION_SNAPSHOT)) {
41             coversAtMost(displayBounds)
42         }
43     }
44 
45     /**
46      * Checks that the pip app layer remains inside the display bounds throughout the whole
47      * animation
48      */
49     @Presubmit
50     @Test
51     open fun pipAppLayerRemainInsideVisibleBounds() {
52         flicker.assertLayersVisibleRegion(pipApp.or(ComponentNameMatcher.TRANSITION_SNAPSHOT)) {
53             coversAtMost(displayBounds)
54         }
55     }
56 
57     /**
58      * Checks both app windows are visible at the start of the transition (with [pipApp] on top).
59      * Then, during the transition, [testApp] becomes invisible and [pipApp] remains visible
60      */
61     @Presubmit
62     @Test
63     open fun showBothAppWindowsThenHidePip() {
64         flicker.assertWm {
65             // when the activity is STOPPING, sometimes it becomes invisible in an entry before
66             // the window, sometimes in the same entry. This occurs because we log 1x per frame
67             // thus we ignore activity here
68             isAppWindowVisible(testApp)
69                 .isAppWindowOnTop(pipApp)
70                 .then()
71                 .isAppWindowInvisible(testApp)
72                 .isAppWindowVisible(pipApp)
73         }
74     }
75 
76     /**
77      * Checks both app layers are visible at the start of the transition. Then, during the
78      * transition, [testApp] becomes invisible and [pipApp] remains visible
79      */
80     @Presubmit
81     @Test
82     open fun showBothAppLayersThenHidePip() {
83         flicker.assertLayers {
84             isVisible(testApp)
85                 .isVisible(pipApp.or(ComponentNameMatcher.TRANSITION_SNAPSHOT))
86                 .then()
87                 .isInvisible(testApp)
88                 .isVisible(pipApp)
89         }
90     }
91 
92     /**
93      * Checks that the visible region of [testApp] plus the visible region of [pipApp] cover the
94      * full display area at the start of the transition
95      */
96     @Presubmit
97     @Test
98     open fun testPlusPipAppsCoverFullScreenAtStart() {
99         flicker.assertLayersStart {
100             val pipRegion = visibleRegion(pipApp).region
101             visibleRegion(testApp).plus(pipRegion).coversExactly(displayBounds)
102         }
103     }
104 
105     /**
106      * Checks that the visible region oft [pipApp] covers the full display area at the end of the
107      * transition
108      */
109     @Presubmit
110     @Test
111     open fun pipAppCoversFullScreenAtEnd() {
112         flicker.assertLayersEnd { visibleRegion(pipApp).coversExactly(displayBounds) }
113     }
114 
115     /** Checks that the visible region of [pipApp] always expands during the animation */
116     @Presubmit
117     @Test
118     open fun pipLayerExpands() {
119         flicker.assertLayers {
120             val pipLayerList = this.layers { pipApp.layerMatchesAnyOf(it) && it.isVisible }
121             pipLayerList.zipWithNext { previous, current ->
122                 current.visibleRegion.coversAtLeast(previous.visibleRegion.region)
123             }
124         }
125     }
126 
127     @Postsubmit
128     @Test
129     override fun pipLayerHasCorrectCornersAtEnd() {
130         flicker.assertLayersEnd { hasNoRoundedCorners(pipApp) }
131     }
132 
133     /** {@inheritDoc} */
134     @Presubmit @Test override fun entireScreenCovered() = super.entireScreenCovered()
135 
136     companion object {
137         /**
138          * Creates the test configurations.
139          *
140          * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
141          * navigation modes.
142          */
143         @Parameterized.Parameters(name = "{0}")
144         @JvmStatic
145         fun getParams() =
146             LegacyFlickerTestFactory.nonRotationTests(
147                 supportedRotations = listOf(Rotation.ROTATION_0)
148             )
149     }
150 }
151