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.layoutchange
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.FlakyTest
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 changing split ratio at runtime on a horizona split.
37  *
38  * Setup: Launch A|B in horizontal split with B being the secondary activity, by default A and B
39  * windows are equal in size. B is on the top and A is on the bottom. Transitions: Change the split
40  * ratio to A:B=0.7:0.3, expect bounds change for both A and B.
41  *
42  * To run this test: `atest FlickerTestsActivityEmbedding:HorizontalSplitChangeRatioTest`
43  */
44 @RequiresDevice
45 @RunWith(Parameterized::class)
46 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
47 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
48 class HorizontalSplitChangeRatioTest(flicker: LegacyFlickerTest) :
49     ActivityEmbeddingTestBase(flicker) {
50     /** {@inheritDoc} */
<lambda>null51     override val transition: FlickerBuilder.() -> Unit = {
52         setup {
53             tapl.setExpectedRotationCheckEnabled(false)
54             testApp.launchViaIntent(wmHelper)
55             testApp.launchSecondaryActivityHorizontally(wmHelper)
56             startDisplayBounds =
57                 wmHelper.currentState.layerState.physicalDisplayBounds ?: error("Display not found")
58         }
59         transitions { testApp.changeSecondaryActivityRatio(wmHelper) }
60         teardown {
61             tapl.goHome()
62             testApp.exit(wmHelper)
63         }
64     }
65 
66     @FlakyTest(bugId = 293075402)
67     @Test
backgroundLayerNeverVisiblenull68     override fun backgroundLayerNeverVisible() = super.backgroundLayerNeverVisible()
69 
70     @FlakyTest(bugId = 293075402)
71     @Test
72     override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
73         super.visibleLayersShownMoreThanOneConsecutiveEntry()
74 
75     /** Assert the Main activity window is always visible. */
76     @Presubmit
77     @Test
78     fun mainActivityWindowIsAlwaysVisible() {
79         flicker.assertWm { isAppWindowVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) }
80     }
81 
82     /** Assert the Main activity window is always visible. */
83     @Presubmit
84     @Test
mainActivityLayerIsAlwaysVisiblenull85     fun mainActivityLayerIsAlwaysVisible() {
86         flicker.assertLayers { isVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) }
87     }
88 
89     /** Assert the Secondary activity window is always visible. */
90     @Presubmit
91     @Test
secondaryActivityWindowIsAlwaysVisiblenull92     fun secondaryActivityWindowIsAlwaysVisible() {
93         flicker.assertWm {
94             isAppWindowVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
95         }
96     }
97 
98     /** Assert the Secondary activity window is always visible. */
99     @Presubmit
100     @Test
secondaryActivityLayerIsAlwaysVisiblenull101     fun secondaryActivityLayerIsAlwaysVisible() {
102         flicker.assertLayers { isVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) }
103     }
104 
105     /** Assert the Main and Secondary activity change height during the transition. */
106     @Presubmit
107     @Test
secondaryActivityAdjustsHeightRuntimenull108     fun secondaryActivityAdjustsHeightRuntime() {
109         flicker.assertLayersStart {
110             val topLayerRegion =
111                 this.visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
112             val bottomLayerRegion =
113                 this.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
114             // Compare dimensions of two splits, given we're using default split attributes,
115             // both activities take up the same visible size on the display.
116             check { "height" }
117                 .that(topLayerRegion.region.bounds.height())
118                 .isEqual(bottomLayerRegion.region.bounds.height())
119             check { "width" }
120                 .that(topLayerRegion.region.bounds.width())
121                 .isEqual(bottomLayerRegion.region.bounds.width())
122             topLayerRegion.notOverlaps(bottomLayerRegion.region)
123             // Layers of two activities sum to be fullscreen size on display.
124             topLayerRegion.plus(bottomLayerRegion.region).coversExactly(startDisplayBounds)
125         }
126 
127         flicker.assertLayersEnd {
128             val topLayerRegion =
129                 this.visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
130             val bottomLayerRegion =
131                 this.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
132             // Compare dimensions of two splits, given we're using default split attributes,
133             // both activities take up the same visible size on the display.
134             check { "height" }
135                 .that(topLayerRegion.region.bounds.height())
136                 .isLower(bottomLayerRegion.region.bounds.height())
137             check { "height" }
138                 .that(
139                     topLayerRegion.region.bounds.height() / 0.3f -
140                         bottomLayerRegion.region.bounds.height() / 0.7f
141                 )
142                 .isLower(0.1f)
143             check { "width" }
144                 .that(topLayerRegion.region.bounds.width())
145                 .isEqual(bottomLayerRegion.region.bounds.width())
146             topLayerRegion.notOverlaps(bottomLayerRegion.region)
147             // Layers of two activities sum to be fullscreen size on display.
148             topLayerRegion.plus(bottomLayerRegion.region).coversExactly(startDisplayBounds)
149         }
150     }
151 
152     companion object {
153         /** {@inheritDoc} */
154         private var startDisplayBounds = Rect()
155 
156         /**
157          * Creates the test configurations.
158          *
159          * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
160          * navigation modes.
161          */
162         @Parameterized.Parameters(name = "{0}")
163         @JvmStatic
getParamsnull164         fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
165     }
166 }
167