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.platform.test.annotations.Presubmit 20 import android.tools.common.datatypes.Rect 21 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory 22 import android.tools.device.flicker.legacy.FlickerBuilder 23 import android.tools.device.flicker.legacy.LegacyFlickerTest 24 import android.tools.device.flicker.legacy.LegacyFlickerTestFactory 25 import com.android.server.wm.flicker.activityembedding.ActivityEmbeddingTestBase 26 import com.android.server.wm.flicker.helpers.ActivityEmbeddingAppHelper 27 import androidx.test.filters.RequiresDevice 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 changing split ratio at runtime on a horizona split. 36 * 37 * Setup: Launch A|B in horizontal split with B being the secondary activity, by default A and B 38 * windows are equal in size. B is on the top and A is on the bottom. 39 * Transitions: 40 * Change the split ratio to A:B=0.7:0.3, expect bounds change for both A and B. 41 * 42 * To run this test: `atest FlickerTestsOther: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} */ 51 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 58 ?: error("Display not found") 59 } 60 transitions { 61 testApp.changeSecondaryActivityRatio(wmHelper) 62 } 63 teardown { 64 tapl.goHome() 65 testApp.exit(wmHelper) 66 } 67 } 68 69 /** Assert the Main activity window is always visible. */ 70 @Presubmit 71 @Test 72 fun mainActivityWindowIsAlwaysVisible() { 73 flicker.assertWm { isAppWindowVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) } 74 } 75 76 /** Assert the Main activity window is always visible. */ 77 @Presubmit 78 @Test 79 fun mainActivityLayerIsAlwaysVisible() { 80 flicker.assertLayers { isVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) } 81 } 82 83 /** Assert the Secondary activity window is always visible. */ 84 @Presubmit 85 @Test 86 fun secondaryActivityWindowIsAlwaysVisible() { 87 flicker.assertWm { 88 isAppWindowVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) } 89 } 90 91 /** Assert the Secondary activity window is always visible. */ 92 @Presubmit 93 @Test 94 fun secondaryActivityLayerIsAlwaysVisible() { 95 flicker.assertLayers { isVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) } 96 } 97 98 /** Assert the Main and Secondary activity change height during the transition. */ 99 @Presubmit 100 @Test 101 fun secondaryActivityAdjustsHeightRuntime() { 102 flicker.assertLayersStart { 103 val topLayerRegion = 104 this.visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) 105 val bottomLayerRegion = 106 this.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) 107 // Compare dimensions of two splits, given we're using default split attributes, 108 // both activities take up the same visible size on the display. 109 check { "height" } 110 .that(topLayerRegion.region.height).isEqual(bottomLayerRegion.region.height) 111 check { "width" } 112 .that(topLayerRegion.region.width).isEqual(bottomLayerRegion.region.width) 113 topLayerRegion.notOverlaps(bottomLayerRegion.region) 114 // Layers of two activities sum to be fullscreen size on display. 115 topLayerRegion.plus(bottomLayerRegion.region).coversExactly(startDisplayBounds) 116 } 117 118 flicker.assertLayersEnd { 119 val topLayerRegion = 120 this.visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) 121 val bottomLayerRegion = 122 this.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) 123 // Compare dimensions of two splits, given we're using default split attributes, 124 // both activities take up the same visible size on the display. 125 check { "height" } 126 .that(topLayerRegion.region.height).isLower(bottomLayerRegion.region.height) 127 check { "height" } 128 .that( 129 topLayerRegion.region.height / 0.3f - 130 bottomLayerRegion.region.height / 0.7f) 131 .isLower(0.1f) 132 check { "width" } 133 .that(topLayerRegion.region.width).isEqual(bottomLayerRegion.region.width) 134 topLayerRegion.notOverlaps(bottomLayerRegion.region) 135 // Layers of two activities sum to be fullscreen size on display. 136 topLayerRegion.plus(bottomLayerRegion.region).coversExactly(startDisplayBounds) 137 } 138 } 139 140 companion object { 141 /** {@inheritDoc} */ 142 private var startDisplayBounds = Rect.EMPTY 143 /** 144 * Creates the test configurations. 145 * 146 * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and 147 * navigation modes. 148 */ 149 @Parameterized.Parameters(name = "{0}") 150 @JvmStatic 151 fun getParams() = LegacyFlickerTestFactory.nonRotationTests() 152 } 153 }