Loading tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/open/OpenThirdActivityOverSplitTest.kt 0 → 100644 +170 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.wm.flicker.activityembedding import android.platform.test.annotations.Presubmit import android.tools.common.datatypes.Rect import android.tools.common.traces.component.ComponentNameMatcher import android.tools.device.flicker.junit.FlickerParametersRunnerFactory import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.helpers.ActivityEmbeddingAppHelper import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters import org.junit.runners.Parameterized /** * Test launching a secondary activity over an existing split. By default the new secondary * activity will stack over the previous secondary activity. * * Setup: From Activity A launch a split A|B. * * Transitions: Let B start C, expect C to cover B and end up in split A|C. * * To run this test: `atest FlickerTests:OpenThirdActivityOverSplitTest` */ @RequiresDevice @RunWith(Parameterized::class) @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) class OpenThirdActivityOverSplitTest (flicker: LegacyFlickerTest) : ActivityEmbeddingTestBase(flicker) { /** {@inheritDoc} */ override val transition: FlickerBuilder.() -> Unit = { setup { tapl.setExpectedRotationCheckEnabled(false) // Launch a split. testApp.launchViaIntent(wmHelper) testApp.launchSecondaryActivity(wmHelper) startDisplayBounds = wmHelper.currentState.layerState.physicalDisplayBounds ?: error("Can't get display bounds") } transitions { testApp.launchThirdActivity(wmHelper) } teardown { tapl.goHome() testApp.exit(wmHelper) } } /** Main activity remains visible throughout the transition. */ @Presubmit @Test fun mainActivityWindowAlwaysVisible() { flicker.assertWm { isAppWindowVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) } } /** Main activity remains visible throughout the transition and takes up half of the screen. */ @Presubmit @Test fun mainActivityLayersAlwaysVisible() { flicker.assertLayers { isVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) } flicker.assertLayersStart { val display = this.entry.displays.firstOrNull { it.isOn && !it.isVirtual } ?: error("No non-virtual and on display found") val mainActivityRegion = this.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) val secondaryActivityRegion = this.visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) .region mainActivityRegion .plus(secondaryActivityRegion) .coversExactly(display.layerStackSpace) } flicker.assertLayersEnd { val display = this.entry.displays.firstOrNull { it.isOn && !it.isVirtual } ?: error("No non-virtual and on display found") val mainActivityRegion = this.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) val secondaryActivityRegion = this.visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) secondaryActivityRegion.isEmpty() val thirdActivityRegion = this.visibleRegion(ActivityEmbeddingAppHelper.THIRD_ACTIVITY_COMPONENT) mainActivityRegion .plus(thirdActivityRegion.region) .coversExactly(display.layerStackSpace) } } /** Third activity launches during the transition and covers up secondary activity. */ @Presubmit @Test fun thirdActivityWindowLaunchesIntoSplit() { flicker.assertWm { isAppWindowVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) .isAppWindowInvisible(ActivityEmbeddingAppHelper.THIRD_ACTIVITY_COMPONENT) .then() .isAppWindowVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) .isAppWindowVisible(ActivityEmbeddingAppHelper.THIRD_ACTIVITY_COMPONENT) .then() .isAppWindowVisible(ActivityEmbeddingAppHelper.THIRD_ACTIVITY_COMPONENT) .isAppWindowInvisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) // expectation } } /** Third activity launches during the transition and covers up secondary activity. */ @Presubmit @Test fun thirdActivityLayerLaunchesIntoSplit() { flicker.assertLayers { isVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) .isInvisible(ActivityEmbeddingAppHelper.THIRD_ACTIVITY_COMPONENT) .then() .isVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) .isVisible(ActivityEmbeddingAppHelper.THIRD_ACTIVITY_COMPONENT) .then() .isVisible(ActivityEmbeddingAppHelper.THIRD_ACTIVITY_COMPONENT) .isInvisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) } } /** Assert the background animation layer is never visible during transition. */ @Presubmit @Test fun backgroundLayerNeverVisible() { val backgroundColorLayer = ComponentNameMatcher("", "Animation Background") flicker.assertLayers { isInvisible(backgroundColorLayer) } } companion object { /** {@inheritDoc} */ private var startDisplayBounds = Rect.EMPTY /** * Creates the test configurations. * * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and * navigation modes. */ @Parameterized.Parameters(name = "{0}") @JvmStatic fun getParams() = LegacyFlickerTestFactory.nonRotationTests() } } No newline at end of file tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt +20 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,23 @@ constructor( .waitForAndVerify() } /** Clicks the button to launch a third activity over a secondary activity. */ fun launchThirdActivity(wmHelper: WindowManagerStateHelper) { val launchButton = uiDevice.wait( Until.findObject(By.res(getPackage(), "launch_third_activity_button")), FIND_TIMEOUT ) require(launchButton != null) { "Can't find launch third activity button on screen." } launchButton.click() wmHelper .StateSyncBuilder() .withActivityState(MAIN_ACTIVITY_COMPONENT, PlatformConsts.STATE_RESUMED) .withActivityState(SECONDARY_ACTIVITY_COMPONENT, PlatformConsts.STATE_STOPPED) .withActivityState(THIRD_ACTIVITY_COMPONENT, PlatformConsts.STATE_RESUMED) .waitForAndVerify() } /** * Clicks the button to finishes the secondary activity launched through * [launchSecondaryActivity], waits for the main activity to resume. Loading Loading @@ -166,6 +183,9 @@ constructor( val SECONDARY_ACTIVITY_COMPONENT = ActivityOptions.ActivityEmbedding.SecondaryActivity.COMPONENT.toFlickerComponent() val THIRD_ACTIVITY_COMPONENT = ActivityOptions.ActivityEmbedding.ThirdActivity.COMPONENT.toFlickerComponent() val ALWAYS_EXPAND_ACTIVITY_COMPONENT = ActivityOptions.ActivityEmbedding.AlwaysExpandActivity.COMPONENT.toFlickerComponent() Loading tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml +7 −0 Original line number Diff line number Diff line Loading @@ -199,6 +199,13 @@ android:theme="@style/CutoutShortEdges" android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout" android:exported="false"/> <activity android:name=".ActivityEmbeddingThirdActivity" android:label="ActivityEmbedding Third" android:taskAffinity="com.android.server.wm.flicker.testapp.ActivityEmbedding" android:theme="@style/CutoutShortEdges" android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout" android:exported="false"/> <activity android:name=".ActivityEmbeddingAlwaysExpandActivity" android:label="ActivityEmbedding AlwaysExpand" Loading tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_secondary_activity_layout.xml +8 −0 Original line number Diff line number Diff line Loading @@ -27,4 +27,12 @@ android:layout_height="48dp" android:text="Finish" /> <Button android:id="@+id/launch_third_activity_button" android:layout_width="wrap_content" android:layout_height="48dp" android:layout_centerHorizontal="true" android:onClick="launchThirdActivity" android:text="Launch a third activity" /> </LinearLayout> No newline at end of file tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityEmbeddingSecondaryActivity.java +6 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.wm.flicker.testapp; import android.app.Activity; import android.content.Intent; import android.graphics.Color; import android.os.Bundle; import android.view.View; Loading @@ -40,4 +41,9 @@ public class ActivityEmbeddingSecondaryActivity extends Activity { } }); } public void launchThirdActivity(View view) { startActivity(new Intent().setComponent( ActivityOptions.ActivityEmbedding.ThirdActivity.COMPONENT)); } } Loading
tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/open/OpenThirdActivityOverSplitTest.kt 0 → 100644 +170 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.wm.flicker.activityembedding import android.platform.test.annotations.Presubmit import android.tools.common.datatypes.Rect import android.tools.common.traces.component.ComponentNameMatcher import android.tools.device.flicker.junit.FlickerParametersRunnerFactory import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.helpers.ActivityEmbeddingAppHelper import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters import org.junit.runners.Parameterized /** * Test launching a secondary activity over an existing split. By default the new secondary * activity will stack over the previous secondary activity. * * Setup: From Activity A launch a split A|B. * * Transitions: Let B start C, expect C to cover B and end up in split A|C. * * To run this test: `atest FlickerTests:OpenThirdActivityOverSplitTest` */ @RequiresDevice @RunWith(Parameterized::class) @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) class OpenThirdActivityOverSplitTest (flicker: LegacyFlickerTest) : ActivityEmbeddingTestBase(flicker) { /** {@inheritDoc} */ override val transition: FlickerBuilder.() -> Unit = { setup { tapl.setExpectedRotationCheckEnabled(false) // Launch a split. testApp.launchViaIntent(wmHelper) testApp.launchSecondaryActivity(wmHelper) startDisplayBounds = wmHelper.currentState.layerState.physicalDisplayBounds ?: error("Can't get display bounds") } transitions { testApp.launchThirdActivity(wmHelper) } teardown { tapl.goHome() testApp.exit(wmHelper) } } /** Main activity remains visible throughout the transition. */ @Presubmit @Test fun mainActivityWindowAlwaysVisible() { flicker.assertWm { isAppWindowVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) } } /** Main activity remains visible throughout the transition and takes up half of the screen. */ @Presubmit @Test fun mainActivityLayersAlwaysVisible() { flicker.assertLayers { isVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) } flicker.assertLayersStart { val display = this.entry.displays.firstOrNull { it.isOn && !it.isVirtual } ?: error("No non-virtual and on display found") val mainActivityRegion = this.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) val secondaryActivityRegion = this.visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) .region mainActivityRegion .plus(secondaryActivityRegion) .coversExactly(display.layerStackSpace) } flicker.assertLayersEnd { val display = this.entry.displays.firstOrNull { it.isOn && !it.isVirtual } ?: error("No non-virtual and on display found") val mainActivityRegion = this.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) val secondaryActivityRegion = this.visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) secondaryActivityRegion.isEmpty() val thirdActivityRegion = this.visibleRegion(ActivityEmbeddingAppHelper.THIRD_ACTIVITY_COMPONENT) mainActivityRegion .plus(thirdActivityRegion.region) .coversExactly(display.layerStackSpace) } } /** Third activity launches during the transition and covers up secondary activity. */ @Presubmit @Test fun thirdActivityWindowLaunchesIntoSplit() { flicker.assertWm { isAppWindowVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) .isAppWindowInvisible(ActivityEmbeddingAppHelper.THIRD_ACTIVITY_COMPONENT) .then() .isAppWindowVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) .isAppWindowVisible(ActivityEmbeddingAppHelper.THIRD_ACTIVITY_COMPONENT) .then() .isAppWindowVisible(ActivityEmbeddingAppHelper.THIRD_ACTIVITY_COMPONENT) .isAppWindowInvisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) // expectation } } /** Third activity launches during the transition and covers up secondary activity. */ @Presubmit @Test fun thirdActivityLayerLaunchesIntoSplit() { flicker.assertLayers { isVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) .isInvisible(ActivityEmbeddingAppHelper.THIRD_ACTIVITY_COMPONENT) .then() .isVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) .isVisible(ActivityEmbeddingAppHelper.THIRD_ACTIVITY_COMPONENT) .then() .isVisible(ActivityEmbeddingAppHelper.THIRD_ACTIVITY_COMPONENT) .isInvisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) } } /** Assert the background animation layer is never visible during transition. */ @Presubmit @Test fun backgroundLayerNeverVisible() { val backgroundColorLayer = ComponentNameMatcher("", "Animation Background") flicker.assertLayers { isInvisible(backgroundColorLayer) } } companion object { /** {@inheritDoc} */ private var startDisplayBounds = Rect.EMPTY /** * Creates the test configurations. * * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and * navigation modes. */ @Parameterized.Parameters(name = "{0}") @JvmStatic fun getParams() = LegacyFlickerTestFactory.nonRotationTests() } } No newline at end of file
tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt +20 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,23 @@ constructor( .waitForAndVerify() } /** Clicks the button to launch a third activity over a secondary activity. */ fun launchThirdActivity(wmHelper: WindowManagerStateHelper) { val launchButton = uiDevice.wait( Until.findObject(By.res(getPackage(), "launch_third_activity_button")), FIND_TIMEOUT ) require(launchButton != null) { "Can't find launch third activity button on screen." } launchButton.click() wmHelper .StateSyncBuilder() .withActivityState(MAIN_ACTIVITY_COMPONENT, PlatformConsts.STATE_RESUMED) .withActivityState(SECONDARY_ACTIVITY_COMPONENT, PlatformConsts.STATE_STOPPED) .withActivityState(THIRD_ACTIVITY_COMPONENT, PlatformConsts.STATE_RESUMED) .waitForAndVerify() } /** * Clicks the button to finishes the secondary activity launched through * [launchSecondaryActivity], waits for the main activity to resume. Loading Loading @@ -166,6 +183,9 @@ constructor( val SECONDARY_ACTIVITY_COMPONENT = ActivityOptions.ActivityEmbedding.SecondaryActivity.COMPONENT.toFlickerComponent() val THIRD_ACTIVITY_COMPONENT = ActivityOptions.ActivityEmbedding.ThirdActivity.COMPONENT.toFlickerComponent() val ALWAYS_EXPAND_ACTIVITY_COMPONENT = ActivityOptions.ActivityEmbedding.AlwaysExpandActivity.COMPONENT.toFlickerComponent() Loading
tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml +7 −0 Original line number Diff line number Diff line Loading @@ -199,6 +199,13 @@ android:theme="@style/CutoutShortEdges" android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout" android:exported="false"/> <activity android:name=".ActivityEmbeddingThirdActivity" android:label="ActivityEmbedding Third" android:taskAffinity="com.android.server.wm.flicker.testapp.ActivityEmbedding" android:theme="@style/CutoutShortEdges" android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout" android:exported="false"/> <activity android:name=".ActivityEmbeddingAlwaysExpandActivity" android:label="ActivityEmbedding AlwaysExpand" Loading
tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_secondary_activity_layout.xml +8 −0 Original line number Diff line number Diff line Loading @@ -27,4 +27,12 @@ android:layout_height="48dp" android:text="Finish" /> <Button android:id="@+id/launch_third_activity_button" android:layout_width="wrap_content" android:layout_height="48dp" android:layout_centerHorizontal="true" android:onClick="launchThirdActivity" android:text="Launch a third activity" /> </LinearLayout> No newline at end of file
tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityEmbeddingSecondaryActivity.java +6 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.wm.flicker.testapp; import android.app.Activity; import android.content.Intent; import android.graphics.Color; import android.os.Bundle; import android.view.View; Loading @@ -40,4 +41,9 @@ public class ActivityEmbeddingSecondaryActivity extends Activity { } }); } public void launchThirdActivity(View view) { startActivity(new Intent().setComponent( ActivityOptions.ActivityEmbedding.ThirdActivity.COMPONENT)); } }