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 com.android.server.wm.flicker.activityembedding.open
18 
19 import android.graphics.Rect
20 import android.platform.test.annotations.Presubmit
21 import android.tools.flicker.junit.FlickerParametersRunnerFactory
22 import android.tools.flicker.legacy.FlickerBuilder
23 import android.tools.flicker.legacy.LegacyFlickerTest
24 import android.tools.flicker.legacy.LegacyFlickerTestFactory
25 import androidx.test.filters.RequiresDevice
26 import com.android.server.wm.flicker.activityembedding.ActivityEmbeddingTestBase
27 import com.android.server.wm.flicker.helpers.ActivityEmbeddingAppHelper
28 import org.junit.FixMethodOrder
29 import org.junit.Test
30 import org.junit.runner.RunWith
31 import org.junit.runners.MethodSorters
32 import org.junit.runners.Parameterized
33 
34 /**
35  * Test launching a secondary activity over an existing split. By default the new secondary activity
36  * will stack over the previous secondary activity.
37  *
38  * Setup: From Activity A launch a split A|B.
39  *
40  * Transitions: Let B start C, expect C to cover B and end up in split A|C.
41  *
42  * To run this test: `atest FlickerTestsActivityEmbedding:OpenThirdActivityOverSplitTest`
43  */
44 @RequiresDevice
45 @RunWith(Parameterized::class)
46 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
47 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
48 class OpenThirdActivityOverSplitTest(flicker: LegacyFlickerTest) :
49     ActivityEmbeddingTestBase(flicker) {
50     /** {@inheritDoc} */
<lambda>null51     override val transition: FlickerBuilder.() -> Unit = {
52         setup {
53             tapl.setExpectedRotationCheckEnabled(false)
54             // Launch a split.
55             testApp.launchViaIntent(wmHelper)
56             testApp.launchSecondaryActivity(wmHelper)
57 
58             startDisplayBounds =
59                 wmHelper.currentState.layerState.physicalDisplayBounds
60                     ?: error("Can't get display bounds")
61         }
62         transitions { testApp.launchThirdActivity(wmHelper) }
63         teardown {
64             tapl.goHome()
65             testApp.exit(wmHelper)
66         }
67     }
68 
69     /** Main activity remains visible throughout the transition. */
70     @Presubmit
71     @Test
mainActivityWindowAlwaysVisiblenull72     fun mainActivityWindowAlwaysVisible() {
73         flicker.assertWm { isAppWindowVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) }
74     }
75 
76     /** Main activity remains visible throughout the transition and takes up half of the screen. */
77     @Presubmit
78     @Test
mainActivityLayersAlwaysVisiblenull79     fun mainActivityLayersAlwaysVisible() {
80         flicker.assertLayers { isVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) }
81 
82         flicker.assertLayersStart {
83             val display =
84                 this.entry.displays.firstOrNull { it.isOn && !it.isVirtual }
85                     ?: error("No non-virtual and on display found")
86             val mainActivityRegion =
87                 this.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
88             val secondaryActivityRegion =
89                 this.visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT).region
90             mainActivityRegion.plus(secondaryActivityRegion).coversExactly(display.layerStackSpace)
91         }
92 
93         flicker.assertLayersEnd {
94             val display =
95                 this.entry.displays.firstOrNull { it.isOn && !it.isVirtual }
96                     ?: error("No non-virtual and on display found")
97             val mainActivityRegion =
98                 this.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
99             val secondaryActivityRegion =
100                 this.visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
101             secondaryActivityRegion.isEmpty()
102             val thirdActivityRegion =
103                 this.visibleRegion(ActivityEmbeddingAppHelper.THIRD_ACTIVITY_COMPONENT)
104             mainActivityRegion
105                 .plus(thirdActivityRegion.region)
106                 .coversExactly(display.layerStackSpace)
107         }
108     }
109 
110     /** Third activity launches during the transition and covers up secondary activity. */
111     @Presubmit
112     @Test
thirdActivityWindowLaunchesIntoSplitnull113     fun thirdActivityWindowLaunchesIntoSplit() {
114         flicker.assertWm {
115             isAppWindowVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
116                 .isAppWindowInvisible(ActivityEmbeddingAppHelper.THIRD_ACTIVITY_COMPONENT)
117                 .then()
118                 .isAppWindowVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
119                 .isAppWindowVisible(ActivityEmbeddingAppHelper.THIRD_ACTIVITY_COMPONENT)
120                 .then()
121                 .isAppWindowVisible(ActivityEmbeddingAppHelper.THIRD_ACTIVITY_COMPONENT)
122                 .isAppWindowInvisible(
123                     ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT
124                 ) // expectation
125         }
126     }
127 
128     /** Third activity launches during the transition and covers up secondary activity. */
129     @Presubmit
130     @Test
thirdActivityLayerLaunchesIntoSplitnull131     fun thirdActivityLayerLaunchesIntoSplit() {
132         flicker.assertLayers {
133             isVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
134                 .isInvisible(ActivityEmbeddingAppHelper.THIRD_ACTIVITY_COMPONENT)
135                 .then()
136                 .isVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
137                 .isVisible(ActivityEmbeddingAppHelper.THIRD_ACTIVITY_COMPONENT)
138                 .then()
139                 .isVisible(ActivityEmbeddingAppHelper.THIRD_ACTIVITY_COMPONENT)
140                 .isInvisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
141         }
142     }
143 
144     companion object {
145         /** {@inheritDoc} */
146         private var startDisplayBounds = Rect()
147         /**
148          * Creates the test configurations.
149          *
150          * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
151          * navigation modes.
152          */
153         @Parameterized.Parameters(name = "{0}")
154         @JvmStatic
getParamsnull155         fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
156     }
157 }
158