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 android.tools.flicker.subject.region.RegionSubject 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 launching a trampoline activity and resulting in a split state. 37 * 38 * Setup: Launch Activity A in fullscreen. 39 * 40 * Transitions: From A launch a trampoline Activity T, T launches secondary Activity B and finishes 41 * itself, end up in split A|B. 42 * 43 * To run this test: `atest FlickerTestsActivityEmbedding:OpenTrampolineActivityTest` 44 */ 45 @RequiresDevice 46 @RunWith(Parameterized::class) 47 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) 48 @FixMethodOrder(MethodSorters.NAME_ASCENDING) 49 class OpenTrampolineActivityTest(flicker: LegacyFlickerTest) : ActivityEmbeddingTestBase(flicker) { <lambda>null50 override val transition: FlickerBuilder.() -> Unit = { 51 setup { 52 tapl.setExpectedRotationCheckEnabled(false) 53 testApp.launchViaIntent(wmHelper) 54 startDisplayBounds = 55 wmHelper.currentState.layerState.physicalDisplayBounds 56 ?: error("Can't get display bounds") 57 } 58 transitions { testApp.launchTrampolineActivity(wmHelper) } 59 teardown { 60 tapl.goHome() 61 testApp.exit(wmHelper) 62 } 63 } 64 65 /** Trampoline activity should finish itself before the end of this test. */ 66 @Presubmit 67 @Test trampolineActivityFinishesnull68 fun trampolineActivityFinishes() { 69 flicker.assertWmEnd { 70 notContains(ActivityEmbeddingAppHelper.TRAMPOLINE_ACTIVITY_COMPONENT) 71 } 72 } 73 74 @Presubmit 75 @Test trampolineLayerNeverVisiblenull76 fun trampolineLayerNeverVisible() { 77 flicker.assertLayers { 78 isInvisible(ActivityEmbeddingAppHelper.TRAMPOLINE_ACTIVITY_COMPONENT) 79 } 80 } 81 82 /** Main activity is always visible throughout this test. */ 83 @Presubmit 84 @Test mainActivityWindowAlwaysVisiblenull85 fun mainActivityWindowAlwaysVisible() { 86 flicker.assertWm { isAppWindowVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) } 87 } 88 89 // TODO(b/289140963): After this is fixed, assert the main Activity window is visible 90 // throughout the test instead. 91 /** Main activity layer is visible before and after the transition. */ 92 @Presubmit 93 @Test mainActivityLayerAlwaysVisiblenull94 fun mainActivityLayerAlwaysVisible() { 95 flicker.assertLayersStart { isVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) } 96 flicker.assertLayersEnd { isVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) } 97 } 98 99 /** Secondary activity is launched from the trampoline activity. */ 100 @Presubmit 101 @Test secondaryActivityWindowLaunchedFromTrampolinenull102 fun secondaryActivityWindowLaunchedFromTrampoline() { 103 flicker.assertWm { 104 notContains(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) 105 .then() 106 .isAppWindowInvisible( 107 ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT, 108 isOptional = true 109 ) 110 .then() 111 .isAppWindowVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) 112 } 113 } 114 115 /** Secondary activity is launched from the trampoline activity. */ 116 @Presubmit 117 @Test secondaryActivityLayerLaunchedFromTrampolinenull118 fun secondaryActivityLayerLaunchedFromTrampoline() { 119 flicker.assertLayers { 120 isInvisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) 121 .then() 122 .isVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) 123 } 124 } 125 126 /** Main activity should go from fullscreen to being a split with secondary activity. */ 127 @Presubmit 128 @Test mainActivityWindowGoesFromFullscreenToSplitnull129 fun mainActivityWindowGoesFromFullscreenToSplit() { 130 flicker.assertWm { 131 this.invoke("mainActivityStartsInFullscreen") { 132 it.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) 133 .coversExactly(startDisplayBounds) 134 } 135 // Begin of transition. 136 .then() 137 .isAppWindowInvisible( 138 ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT, 139 isOptional = true 140 ) 141 .then() 142 .invoke("mainAndSecondaryInSplit") { 143 val mainActivityRegion = 144 RegionSubject( 145 it.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) 146 .region, 147 it.timestamp 148 ) 149 val secondaryActivityRegion = 150 RegionSubject( 151 it.visibleRegion( 152 ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT 153 ) 154 .region, 155 it.timestamp 156 ) 157 check { "height" } 158 .that(mainActivityRegion.region.bounds.height()) 159 .isEqual(secondaryActivityRegion.region.bounds.height()) 160 check { "width" } 161 .that(mainActivityRegion.region.bounds.width()) 162 .isEqual(secondaryActivityRegion.region.bounds.width()) 163 mainActivityRegion 164 .plus(secondaryActivityRegion.region) 165 .coversExactly(startDisplayBounds) 166 } 167 } 168 } 169 170 /** Main activity should go from fullscreen to being a split with secondary activity. */ 171 @Test mainActivityLayerGoesFromFullscreenToSplitnull172 fun mainActivityLayerGoesFromFullscreenToSplit() { 173 flicker.assertLayers { 174 this.invoke("mainActivityStartsInFullscreen") { 175 it.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) 176 .coversExactly(startDisplayBounds) 177 } 178 .then() 179 .isInvisible( 180 ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT, 181 isOptional = true 182 ) 183 .then() 184 .isVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) 185 } 186 flicker.assertLayersEnd { 187 val leftLayerRegion = visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) 188 val rightLayerRegion = 189 visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) 190 // Compare dimensions of two splits, given we're using default split attributes, 191 // both activities take up the same visible size on the display. 192 check { "height" } 193 .that(leftLayerRegion.region.bounds.height()) 194 .isEqual(rightLayerRegion.region.bounds.height()) 195 check { "width" } 196 .that(leftLayerRegion.region.bounds.width()) 197 .isEqual(rightLayerRegion.region.bounds.width()) 198 leftLayerRegion.notOverlaps(rightLayerRegion.region) 199 // Layers of two activities sum to be fullscreen size on display. 200 leftLayerRegion.plus(rightLayerRegion.region).coversExactly(startDisplayBounds) 201 } 202 } 203 204 @Test visibleLayersShownMoreThanOneConsecutiveEntrynull205 override fun visibleLayersShownMoreThanOneConsecutiveEntry() { 206 super.visibleLayersShownMoreThanOneConsecutiveEntry() 207 } 208 209 companion object { 210 /** {@inheritDoc} */ 211 private var startDisplayBounds = Rect() 212 213 /** 214 * Creates the test configurations. 215 * 216 * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and 217 * navigation modes. 218 */ 219 @Parameterized.Parameters(name = "{0}") 220 @JvmStatic getParamsnull221 fun getParams() = LegacyFlickerTestFactory.nonRotationTests() 222 } 223 } 224