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