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.rotation 18 19 import android.platform.test.annotations.Presubmit 20 import android.tools.common.traces.component.ComponentNameMatcher 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 androidx.test.filters.RequiresDevice 26 import com.android.server.wm.flicker.activityembedding.ActivityEmbeddingTestBase 27 import com.android.server.wm.flicker.helpers.ActivityEmbeddingAppHelper 28 import com.android.server.wm.flicker.rotation.RotationTransition 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 * Tests rotating two activities in an Activity Embedding split. 37 * 38 * Setup: Launch A|B in split with B being the secondary activity. Transitions: Rotate display, and 39 * expect A and B to split evenly in new rotation. 40 * 41 * To run this test: `atest FlickerTestsOther:RotateSplitNoChangeTest` 42 */ 43 @RequiresDevice 44 @RunWith(Parameterized::class) 45 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) 46 @FixMethodOrder(MethodSorters.NAME_ASCENDING) 47 open class RotateSplitNoChangeTest(flicker: LegacyFlickerTest) : RotationTransition(flicker) { 48 49 override val testApp = ActivityEmbeddingAppHelper(instrumentation) 50 override val transition: FlickerBuilder.() -> Unit 51 get() = { 52 super.transition(this) 53 setup { 54 testApp.launchViaIntent(wmHelper) 55 testApp.launchSecondaryActivity(wmHelper) 56 } 57 } 58 59 /** 60 * Checks that the [ComponentNameMatcher.ROTATION] layer appears during the transition, doesn't 61 * flicker, and disappears before the transition is complete 62 */ 63 @Presubmit 64 @Test 65 fun rotationLayerAppearsAndVanishes() { 66 flicker.assertLayers { 67 this.isVisible(testApp) 68 .then() 69 .isVisible(ComponentNameMatcher.ROTATION) 70 .then() 71 .isVisible(testApp) 72 .isInvisible(ComponentNameMatcher.ROTATION) 73 } 74 } 75 76 /** 77 * Overrides inherited assertion because in AE Split, the main and secondary activity are 78 * separate layers, each covering up exactly half of the display. 79 */ 80 @Presubmit 81 @Test 82 override fun appLayerRotates_StartingPos() { 83 flicker.assertLayersStart { 84 this.entry.displays.map { display -> 85 val leftLayerRegion = 86 this.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) 87 val rightLayerRegion = 88 this.visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) 89 // Compare dimensions of two splits, given we're using default split attributes, 90 // both activities take up the same visible size on the display. 91 check { "height" } 92 .that(leftLayerRegion.region.height) 93 .isEqual(rightLayerRegion.region.height) 94 check { "width" } 95 .that(leftLayerRegion.region.width) 96 .isEqual(rightLayerRegion.region.width) 97 leftLayerRegion.notOverlaps(rightLayerRegion.region) 98 // Layers of two activities sum to be fullscreen size on display. 99 leftLayerRegion.plus(rightLayerRegion.region).coversExactly(display.layerStackSpace) 100 } 101 } 102 } 103 104 /** Verifies dimensions of both split activities hold their invariance after transition too. */ 105 @Presubmit 106 @Test 107 override fun appLayerRotates_EndingPos() { 108 flicker.assertLayersEnd { 109 this.entry.displays.map { display -> 110 val leftLayerRegion = 111 this.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) 112 val rightLayerRegion = 113 this.visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) 114 check { "height" } 115 .that(leftLayerRegion.region.height) 116 .isEqual(rightLayerRegion.region.height) 117 check { "width" } 118 .that(leftLayerRegion.region.width) 119 .isEqual(rightLayerRegion.region.width) 120 leftLayerRegion.notOverlaps(rightLayerRegion.region) 121 leftLayerRegion.plus(rightLayerRegion.region).coversExactly(display.layerStackSpace) 122 } 123 } 124 } 125 126 /** Both activities in split should remain visible during rotation. */ 127 @Presubmit 128 @Test 129 fun bothActivitiesAreAlwaysVisible() { 130 flicker.assertWm { isAppWindowVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) } 131 flicker.assertWm { 132 isAppWindowVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) 133 } 134 } 135 136 companion object { 137 /** 138 * Creates the test configurations. 139 * 140 * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and 141 * navigation modes. 142 */ 143 @Parameterized.Parameters(name = "{0}") 144 @JvmStatic 145 fun getParams() = LegacyFlickerTestFactory.rotationTests() 146 } 147 } 148