diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index abdc708ff7fca..2e9c9cf47efda 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -431,6 +431,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub applyTransaction(wct, -1 /* syncId */, transition, caller); mTransitionController.requestStartTransition(transition, null /* startTask */, null /* remoteTransition */, null /* displayChange */); + transition.setAllReady(); return; } @@ -469,6 +470,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub mTransitionController.requestStartTransition(nextTransition, null /* startTask */, null /* remoteTransition */, null /* displayChange */); + nextTransition.setAllReady(); } else { nextTransition.abort(); } diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplit.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplitTest.kt similarity index 64% rename from tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplit.kt rename to tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplitTest.kt index ea67729814362..7f2e057febf13 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplit.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplitTest.kt @@ -33,13 +33,13 @@ import org.junit.runners.Parameterized * Test opening an activity that will launch another activity as ActivityEmbedding placeholder in * split. * - * To run this test: `atest FlickerTests:OpenActivityEmbeddingPlaceholderSplit` + * To run this test: `atest FlickerTests:OpenActivityEmbeddingPlaceholderSplitTest` */ @RequiresDevice @RunWith(Parameterized::class) @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) -class OpenActivityEmbeddingPlaceholderSplit(flicker: FlickerTest) : +class OpenActivityEmbeddingPlaceholderSplitTest(flicker: FlickerTest) : ActivityEmbeddingTestBase(flicker) { /** {@inheritDoc} */ @@ -55,9 +55,21 @@ class OpenActivityEmbeddingPlaceholderSplit(flicker: FlickerTest) : } } + /** Main activity should become invisible after launching the placeholder primary activity. */ @Presubmit @Test - fun mainActivityBecomesInvisible() { + fun mainActivityWindowBecomesInvisible() { + flicker.assertWm { + isAppWindowVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) + .then() + .isAppWindowInvisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) + } + } + + /** Main activity should become invisible after launching the placeholder primary activity. */ + @Presubmit + @Test + fun mainActivityLayerBecomesInvisible() { flicker.assertLayers { isVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) .then() @@ -65,76 +77,41 @@ class OpenActivityEmbeddingPlaceholderSplit(flicker: FlickerTest) : } } + /** + * Placeholder primary and secondary should become visible after launch. The windows are not + * necessarily to become visible at the same time. + */ @Presubmit @Test - fun placeholderSplitBecomesVisible() { - flicker.assertLayers { - isInvisible(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT) + fun placeholderSplitWindowsBecomeVisible() { + flicker.assertWm { + notContains(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT) .then() - .isVisible(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT) + .isAppWindowInvisible(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT) + .then() + .isAppWindowVisible(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT) } - flicker.assertLayers { - isInvisible(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT) + flicker.assertWm { + notContains(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT) .then() - .isVisible(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT) + .isAppWindowInvisible(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT) + .then() + .isAppWindowVisible(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT) } } - /** {@inheritDoc} */ - @Presubmit @Test override fun entireScreenCovered() = super.entireScreenCovered() - - /** {@inheritDoc} */ + /** Placeholder primary and secondary should become visible together after launch. */ @Presubmit @Test - override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd() - - /** {@inheritDoc} */ - @Presubmit - @Test - override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible() - - /** {@inheritDoc} */ - @Presubmit - @Test - override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd() - - /** {@inheritDoc} */ - @Presubmit - @Test - override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible() - - /** {@inheritDoc} */ - @Presubmit - @Test - override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd() - - /** {@inheritDoc} */ - @Presubmit - @Test - override fun statusBarLayerIsVisibleAtStartAndEnd() = - super.statusBarLayerIsVisibleAtStartAndEnd() - - /** {@inheritDoc} */ - @Presubmit - @Test - override fun statusBarLayerPositionAtStartAndEnd() = super.statusBarLayerPositionAtStartAndEnd() - - /** {@inheritDoc} */ - @Presubmit - @Test - override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible() - - /** {@inheritDoc} */ - @Presubmit - @Test - override fun visibleWindowsShownMoreThanOneConsecutiveEntry() = - super.visibleWindowsShownMoreThanOneConsecutiveEntry() - - /** {@inheritDoc} */ - @Presubmit - @Test - override fun visibleLayersShownMoreThanOneConsecutiveEntry() = - super.visibleLayersShownMoreThanOneConsecutiveEntry() + fun placeholderSplitLayersBecomeVisible() { + flicker.assertLayers { + isInvisible(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT) + isInvisible(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT) + .then() + .isVisible(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT) + .isVisible(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT) + } + } companion object { /** diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingSecondaryToSplitTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingSecondaryToSplitTest.kt new file mode 100644 index 0000000000000..5fff15c946b7f --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingSecondaryToSplitTest.kt @@ -0,0 +1,124 @@ +/* + * 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 androidx.test.filters.RequiresDevice +import com.android.server.wm.flicker.FlickerBuilder +import com.android.server.wm.flicker.FlickerTest +import com.android.server.wm.flicker.FlickerTestFactory +import com.android.server.wm.flicker.helpers.ActivityEmbeddingAppHelper +import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory +import com.android.server.wm.traces.common.ComponentNameMatcher +import org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test opening a secondary activity that will split with the main activity. + * + * To run this test: `atest FlickerTests:OpenActivityEmbeddingSecondaryToSplitTest` + */ +@RequiresDevice +@RunWith(Parameterized::class) +@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +class OpenActivityEmbeddingSecondaryToSplitTest(flicker: FlickerTest) : + ActivityEmbeddingTestBase(flicker) { + + /** {@inheritDoc} */ + override val transition: FlickerBuilder.() -> Unit = { + setup { + tapl.setExpectedRotationCheckEnabled(false) + testApp.launchViaIntent(wmHelper) + } + transitions { testApp.launchSecondaryActivity(wmHelper) } + teardown { + tapl.goHome() + testApp.exit(wmHelper) + } + } + + /** Main activity should remain visible when enter split from fullscreen. */ + @Presubmit + @Test + fun mainActivityWindowIsAlwaysVisible() { + flicker.assertWm { + isAppWindowVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) + } + } + + /** + * Main activity surface is animated from fullscreen to ActivityEmbedding split. + * During the transition, there is a period of time that it is covered by a snapshot of itself. + */ + @Presubmit + @Test + fun mainActivityLayerIsAlwaysVisible() { + flicker.assertLayers { + isVisible( + ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT.or( + ComponentNameMatcher.TRANSITION_SNAPSHOT + ) + ) + } + flicker.assertLayersEnd { + isVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) + .isInvisible(ComponentNameMatcher.TRANSITION_SNAPSHOT) + } + } + + /** Secondary activity should become visible after launching into split. */ + @Presubmit + @Test + fun secondaryActivityWindowBecomesVisible() { + flicker.assertWm { + notContains(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) + .then() + .isAppWindowInvisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) + .then() + .isAppWindowVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) + } + } + + /** Secondary activity should become visible after launching into split. */ + @Presubmit + @Test + fun secondaryActivityLayerBecomesVisible() { + flicker.assertLayers { + isInvisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) + .then() + .isVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT) + } + } + + companion object { + /** + * Creates the test configurations. + * + * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and + * navigation modes. + */ + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): Collection { + return FlickerTestFactory.nonRotationTests() + } + } +} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt index 368cc56d83b47..a2db587a35b41 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt @@ -38,6 +38,25 @@ constructor( component: ComponentNameMatcher = MAIN_ACTIVITY_COMPONENT ) : StandardAppHelper(instr, launcherName, component) { + /** + * Clicks the button to launch the secondary activity, which should split with the main activity + * based on the split pair rule. + */ + fun launchSecondaryActivity(wmHelper: WindowManagerStateHelper) { + val launchButton = + uiDevice.wait( + Until.findObject(By.res(getPackage(), "launch_secondary_activity_button")), + FIND_TIMEOUT + ) + require(launchButton != null) { "Can't find launch secondary activity button on screen." } + launchButton.click() + wmHelper + .StateSyncBuilder() + .withActivityState(SECONDARY_ACTIVITY_COMPONENT, STATE_RESUMED) + .withActivityState(MAIN_ACTIVITY_COMPONENT, STATE_RESUMED) + .waitForAndVerify() + } + /** * Clicks the button to launch the placeholder primary activity, which should launch the * placeholder secondary activity based on the placeholder rule. @@ -63,6 +82,9 @@ constructor( val MAIN_ACTIVITY_COMPONENT = ActivityOptions.ActivityEmbedding.MainActivity.COMPONENT.toFlickerComponent() + val SECONDARY_ACTIVITY_COMPONENT = + ActivityOptions.ActivityEmbedding.SecondaryActivity.COMPONENT.toFlickerComponent() + val PLACEHOLDER_PRIMARY_COMPONENT = ActivityOptions.ActivityEmbedding.PlaceholderPrimaryActivity.COMPONENT .toFlickerComponent() diff --git a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml index cd47f6039abfc..5361d73f93b55 100644 --- a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml +++ b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml @@ -178,6 +178,13 @@ + +