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.splitscreen 18 19 import android.platform.test.annotations.Presubmit 20 import android.platform.test.annotations.RequiresDevice 21 import android.tools.common.datatypes.Rect 22 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory 23 import android.tools.device.flicker.legacy.FlickerBuilder 24 import android.tools.device.flicker.legacy.LegacyFlickerTest 25 import android.tools.device.flicker.legacy.LegacyFlickerTestFactory 26 import android.tools.device.traces.parsers.toFlickerComponent 27 import com.android.server.wm.flicker.helpers.ActivityEmbeddingAppHelper 28 import com.android.server.wm.flicker.activityembedding.ActivityEmbeddingTestBase 29 import com.android.server.wm.flicker.testapp.ActivityOptions 30 import com.android.wm.shell.flicker.utils.* 31 import org.junit.FixMethodOrder 32 import org.junit.Ignore 33 import org.junit.Test 34 import org.junit.runner.RunWith 35 import org.junit.runners.MethodSorters 36 import org.junit.runners.Parameterized 37 38 /*** 39 * Test entering System SplitScreen with Activity Embedding Split and another app. 40 * 41 * Setup: Launch A|B in split and secondaryApp, return to home. 42 * Transitions: Let AE Split A|B enter splitscreen with secondaryApp. Resulting in A|B|secondaryApp. 43 * 44 * To run this test: `atest FlickerTestsOther:EnterSystemSplitTest` 45 */ 46 @RequiresDevice 47 @RunWith(Parameterized::class) 48 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) 49 @FixMethodOrder(MethodSorters.NAME_ASCENDING) 50 class EnterSystemSplitTest(flicker: LegacyFlickerTest) : 51 ActivityEmbeddingTestBase(flicker) { 52 53 private val secondaryApp = SplitScreenUtils.getPrimary(instrumentation) 54 override val transition: FlickerBuilder.() -> Unit = { 55 setup { 56 testApp.launchViaIntent(wmHelper) 57 testApp.launchSecondaryActivity(wmHelper) 58 secondaryApp.launchViaIntent(wmHelper) 59 tapl.goHome() 60 wmHelper 61 .StateSyncBuilder() 62 .withAppTransitionIdle() 63 .withHomeActivityVisible() 64 .waitForAndVerify() 65 startDisplayBounds = 66 wmHelper.currentState.layerState.physicalDisplayBounds ?: 67 error("Display not found") 68 } 69 transitions { 70 SplitScreenUtils.enterSplit(wmHelper, tapl, device, testApp, secondaryApp) 71 SplitScreenUtils.waitForSplitComplete(wmHelper, testApp, secondaryApp) 72 } 73 } 74 75 @Presubmit 76 @Test 77 fun splitScreenDividerBecomesVisible() = flicker.splitScreenDividerBecomesVisible() 78 79 @Presubmit 80 @Test 81 fun activityEmbeddingSplitLayerBecomesVisible() { 82 flicker.splitAppLayerBoundsIsVisibleAtEnd( 83 testApp, landscapePosLeft = tapl.isTablet, portraitPosTop = false) 84 } 85 86 @Presubmit 87 @Test 88 fun activityEmbeddingSplitWindowBecomesVisible() = flicker.appWindowIsVisibleAtEnd(testApp) 89 90 @Presubmit 91 @Test 92 fun secondaryLayerBecomesVisible() { 93 flicker.splitAppLayerBoundsIsVisibleAtEnd( 94 secondaryApp, landscapePosLeft = !tapl.isTablet, portraitPosTop = true) 95 } 96 97 @Presubmit 98 @Test 99 fun secondaryAppWindowBecomesVisible() = flicker.appWindowIsVisibleAtEnd(secondaryApp) 100 101 /** 102 * After the transition there should be both ActivityEmbedding activities, 103 * SplitScreenPrimaryActivity and the system split divider on screen. 104 * Verify the layers are in expected sizes. 105 */ 106 @Presubmit 107 @Test 108 fun activityEmbeddingSplitSurfaceAreEven() { 109 flicker.assertLayersEnd { 110 val leftAELayerRegion = 111 visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) 112 val rightAELayerRegion = 113 visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) 114 val secondaryAppLayerRegion = 115 visibleRegion( 116 ActivityOptions.SplitScreen.Primary.COMPONENT.toFlickerComponent()) 117 val systemDivider = visibleRegion(SPLIT_SCREEN_DIVIDER_COMPONENT) 118 leftAELayerRegion 119 .plus(rightAELayerRegion.region) 120 .plus(secondaryAppLayerRegion.region) 121 .plus(systemDivider.region) 122 .coversExactly(startDisplayBounds) 123 check { "ActivityEmbeddingSplitHeight" } 124 .that(leftAELayerRegion.region.height) 125 .isEqual(rightAELayerRegion.region.height) 126 check { "SystemSplitHeight" } 127 .that(rightAELayerRegion.region.height) 128 .isEqual(secondaryAppLayerRegion.region.height) 129 // TODO(b/292283182): Remove this special case handling. 130 check { "ActivityEmbeddingSplitWidth" } 131 .that(Math.abs( 132 leftAELayerRegion.region.width - rightAELayerRegion.region.width)) 133 .isLower(2) 134 check { "SystemSplitWidth" } 135 .that(Math.abs(secondaryAppLayerRegion.region.width - 136 2 * rightAELayerRegion.region.width)) 137 .isLower(2) 138 } 139 } 140 141 /** 142 * Verify the windows are in expected sizes. 143 */ 144 @Presubmit 145 @Test 146 fun activityEmbeddingSplitWindowsAreEven() { 147 flicker.assertWmEnd { 148 val leftAEWindowRegion = 149 visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) 150 val rightAEWindowRegion = 151 visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) 152 // There's no window for the divider bar. 153 val secondaryAppLayerRegion = 154 visibleRegion( 155 ActivityOptions.SplitScreen.Primary.COMPONENT.toFlickerComponent()) 156 check { "ActivityEmbeddingSplitHeight" } 157 .that(leftAEWindowRegion.region.height) 158 .isEqual(rightAEWindowRegion.region.height) 159 check { "SystemSplitHeight" } 160 .that(rightAEWindowRegion.region.height) 161 .isEqual(secondaryAppLayerRegion.region.height) 162 check { "ActivityEmbeddingSplitWidth" } 163 .that(Math.abs( 164 leftAEWindowRegion.region.width - rightAEWindowRegion.region.width)) 165 .isLower(2) 166 check { "SystemSplitWidth" } 167 .that(Math.abs(secondaryAppLayerRegion.region.width - 168 2 * rightAEWindowRegion.region.width)) 169 .isLower(2) 170 } 171 } 172 173 @Ignore("Not applicable to this CUJ.") 174 override fun visibleLayersShownMoreThanOneConsecutiveEntry() {} 175 176 companion object { 177 /** {@inheritDoc} */ 178 private var startDisplayBounds = Rect.EMPTY 179 /** 180 * Creates the test configurations. 181 * 182 * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and 183 * navigation modes. 184 */ 185 @Parameterized.Parameters(name = "{0}") 186 @JvmStatic 187 fun getParams() = LegacyFlickerTestFactory.nonRotationTests() 188 } 189 }