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.close
18 
19 import android.platform.test.annotations.Presubmit
20 import android.tools.common.datatypes.Rect
21 import android.tools.common.traces.component.ComponentNameMatcher
22 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
23 import android.tools.device.flicker.legacy.FlickerBuilder
24 import android.tools.device.flicker.legacy.LegacyFlickerTest
25 import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
26 import androidx.test.filters.RequiresDevice
27 import com.android.server.wm.flicker.activityembedding.ActivityEmbeddingTestBase
28 import com.android.server.wm.flicker.helpers.ActivityEmbeddingAppHelper
29 import org.junit.FixMethodOrder
30 import org.junit.Test
31 import org.junit.runner.RunWith
32 import org.junit.runners.MethodSorters
33 import org.junit.runners.Parameterized
34 
35 /**
36  * Test closing a secondary activity in a split.
37  *
38  * Setup: Launch A|B in split with B being the secondary activity. Transitions: Finish B and expect
39  * A to become fullscreen.
40  *
41  * To run this test: `atest FlickerTestsOther:CloseSecondaryActivityInSplitTest`
42  */
43 @RequiresDevice
44 @RunWith(Parameterized::class)
45 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
46 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
47 class CloseSecondaryActivityInSplitTest(flicker: LegacyFlickerTest) :
48     ActivityEmbeddingTestBase(flicker) {
49 
50     override val transition: FlickerBuilder.() -> Unit = {
51         setup {
52             tapl.setExpectedRotationCheckEnabled(false)
53             // Launches fullscreen A.
54             testApp.launchViaIntent(wmHelper)
55             // Launches a split A|B and waits for both activities to show.
56             testApp.launchSecondaryActivity(wmHelper)
57             // Get fullscreen bounds
58             startDisplayBounds =
59                 wmHelper.currentState.layerState.physicalDisplayBounds
60                     ?: error("Can't get display bounds")
61         }
62         transitions {
63             // Finish secondary activity B.
64             testApp.finishSecondaryActivity(wmHelper)
65             // Expect the main activity A to expand into fullscreen.
66             wmHelper.StateSyncBuilder().withFullScreenApp(testApp).waitForAndVerify()
67         }
68         teardown {
69             tapl.goHome()
70             testApp.exit(wmHelper)
71         }
72     }
73 
74     /** Main activity is always visible and becomes fullscreen in the end. */
75     @Presubmit
76     @Test
77     fun mainActivityWindowBecomesFullScreen() {
78         flicker.assertWm { isAppWindowVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) }
79         flicker.assertWmEnd {
80             this.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
81                 .coversExactly(startDisplayBounds)
82         }
83     }
84 
85     /** Main activity surface is animated from split to fullscreen. */
86     @Presubmit
87     @Test
88     fun mainActivityLayerIsAlwaysVisible() {
89         flicker.assertLayers {
90             isVisible(
91                 ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT.or(
92                     ComponentNameMatcher.TRANSITION_SNAPSHOT
93                 )
94             )
95         }
96         flicker.assertLayersEnd {
97             isVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
98                 .isInvisible(ComponentNameMatcher.TRANSITION_SNAPSHOT)
99         }
100     }
101 
102     /** Secondary activity should destroy and become invisible. */
103     @Presubmit
104     @Test
105     fun secondaryActivityWindowFinishes() {
106         flicker.assertWm {
107             contains(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
108                 .then()
109                 .notContains(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
110         }
111     }
112 
113     @Presubmit
114     @Test
115     fun secondaryActivityLayerFinishes() {
116         flicker.assertLayers {
117             isVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
118                 .then()
119                 .isInvisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
120         }
121     }
122 
123     companion object {
124         /** {@inheritDoc} */
125         private var startDisplayBounds = Rect.EMPTY
126         /**
127          * Creates the test configurations.
128          *
129          * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
130          * navigation modes.
131          */
132         @Parameterized.Parameters(name = "{0}")
133         @JvmStatic
134         fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
135     }
136 }
137