diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt index 1e4d23c924e7e..9da51796a8c1c 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt @@ -20,6 +20,7 @@ package com.android.wm.shell.flicker import android.view.Surface import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.helpers.WindowUtils +import com.android.server.wm.flicker.traces.layers.LayersTraceSubject import com.android.server.wm.traces.common.IComponentMatcher import com.android.server.wm.traces.common.region.Region @@ -88,18 +89,13 @@ fun FlickerTestParameter.splitAppLayerBoundsBecomesVisible( splitLeftTop: Boolean ) { assertLayers { - val dividerRegion = this.last().layer(SPLIT_SCREEN_DIVIDER_COMPONENT).visibleRegion.region this.isInvisible(component) .then() - .invoke("splitAppLayerBoundsBecomesVisible") { - it.visibleRegion(component).coversAtMost( - if (splitLeftTop) { - getSplitLeftTopRegion(dividerRegion, endRotation) - } else { - getSplitRightBottomRegion(dividerRegion, endRotation) - } - ) - } + .isInvisible(SPLIT_SCREEN_DIVIDER_COMPONENT) + .isVisible(component) + .then() + .isVisible(SPLIT_SCREEN_DIVIDER_COMPONENT) + .splitAppLayerBoundsSnapToDivider(component, splitLeftTop, endRotation) } } @@ -108,16 +104,7 @@ fun FlickerTestParameter.splitAppLayerBoundsBecomesInvisible( splitLeftTop: Boolean ) { assertLayers { - val dividerRegion = this.first().layer(SPLIT_SCREEN_DIVIDER_COMPONENT).visibleRegion.region - this.invoke("splitAppLayerBoundsBecomesVisible") { - it.visibleRegion(component).coversAtMost( - if (splitLeftTop) { - getSplitLeftTopRegion(dividerRegion, endRotation) - } else { - getSplitRightBottomRegion(dividerRegion, endRotation) - } - ) - } + this.splitAppLayerBoundsSnapToDivider(component, splitLeftTop, endRotation) .then() .isVisible(component, true) .then() @@ -141,6 +128,40 @@ fun FlickerTestParameter.splitAppLayerBoundsIsVisibleAtEnd( } } +fun FlickerTestParameter.splitAppLayerBoundsChanges( + component: IComponentMatcher, + splitLeftTop: Boolean +) { + assertLayers { + if (splitLeftTop) { + this.splitAppLayerBoundsSnapToDivider(component, splitLeftTop, endRotation) + .then() + .isInvisible(component) + .then() + .splitAppLayerBoundsSnapToDivider(component, splitLeftTop, endRotation) + } else { + this.splitAppLayerBoundsSnapToDivider(component, splitLeftTop, endRotation) + } + } +} + +fun LayersTraceSubject.splitAppLayerBoundsSnapToDivider( + component: IComponentMatcher, + splitLeftTop: Boolean, + rotation: Int +): LayersTraceSubject { + return invoke("splitAppLayerBoundsSnapToDivider") { + val dividerRegion = it.layer(SPLIT_SCREEN_DIVIDER_COMPONENT).visibleRegion.region + it.visibleRegion(component).coversAtMost( + if (splitLeftTop) { + getSplitLeftTopRegion(dividerRegion, rotation) + } else { + getSplitRightBottomRegion(dividerRegion, rotation) + } + ) + } +} + fun FlickerTestParameter.appWindowBecomesVisible( component: IComponentMatcher ) { diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt index 3708e5f65485f..8b717a0cb75ef 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt @@ -23,3 +23,4 @@ const val SYSTEM_UI_PACKAGE_NAME = "com.android.systemui" val APP_PAIR_SPLIT_DIVIDER_COMPONENT = ComponentMatcher("", "AppPairSplitDivider#") val DOCKED_STACK_DIVIDER_COMPONENT = ComponentMatcher("", "DockedStackDivider#") val SPLIT_SCREEN_DIVIDER_COMPONENT = ComponentMatcher("", "StageCoordinatorSplitDivider#") +val SPLIT_DECOR_MANAGER = ComponentMatcher("", "SplitDecorManager#") diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt index 4877442bacf7c..42b7b1162d93a 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt @@ -30,6 +30,7 @@ import com.android.launcher3.tapl.LauncherInstrumentation import com.android.server.wm.traces.common.IComponentMatcher import com.android.server.wm.traces.parser.toFlickerComponent import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper +import com.android.wm.shell.flicker.SPLIT_DECOR_MANAGER import com.android.wm.shell.flicker.SYSTEM_UI_PACKAGE_NAME import com.android.wm.shell.flicker.testapp.Components @@ -220,6 +221,23 @@ class SplitScreenHelper( } } + fun dragDividerToResizeAndWait( + device: UiDevice, + wmHelper: WindowManagerStateHelper + ) { + val displayBounds = wmHelper.currentState.layerState + .displays.firstOrNull { !it.isVirtual } + ?.layerStackSpace + ?: error("Display not found") + val dividerBar = device.wait(Until.findObject(dividerBarSelector), TIMEOUT_MS) + dividerBar.drag(Point(displayBounds.width * 2 / 3, displayBounds.height * 2 / 3)) + + wmHelper.StateSyncBuilder() + .withAppTransitionIdle() + .withWindowSurfaceDisappeared(SPLIT_DECOR_MANAGER) + .waitForAndVerify() + } + fun dragDividerToDismissSplit( device: UiDevice, wmHelper: WindowManagerStateHelper diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt new file mode 100644 index 0000000000000..cf2dc39637df6 --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2022 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.wm.shell.flicker.splitscreen + +import android.platform.test.annotations.Postsubmit +import android.platform.test.annotations.Presubmit +import android.view.Surface +import android.view.WindowManagerPolicyConstants +import androidx.test.filters.RequiresDevice +import com.android.server.wm.flicker.FlickerParametersRunnerFactory +import com.android.server.wm.flicker.FlickerTestParameter +import com.android.server.wm.flicker.FlickerTestParameterFactory +import com.android.server.wm.flicker.annotation.Group1 +import com.android.server.wm.flicker.dsl.FlickerBuilder +import com.android.wm.shell.flicker.SPLIT_SCREEN_DIVIDER_COMPONENT +import com.android.wm.shell.flicker.helpers.SplitScreenHelper +import com.android.wm.shell.flicker.splitAppLayerBoundsChanges +import org.junit.Assume +import org.junit.Before +import org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test resize split by dragging the divider bar. + * + * To run this test: `atest WMShellFlickerTests:DragDividerToResize` + */ +@RequiresDevice +@RunWith(Parameterized::class) +@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@Group1 +class DragDividerToResize (testSpec: FlickerTestParameter) : SplitScreenBase(testSpec) { + + // TODO(b/231399940): Remove this once we can use recent shortcut to enter split. + @Before + open fun before() { + Assume.assumeTrue(tapl.isTablet) + } + + override val transition: FlickerBuilder.() -> Unit + get() = { + super.transition(this) + setup { + eachRun { + tapl.goHome() + primaryApp.launchViaIntent(wmHelper) + // TODO(b/231399940): Use recent shortcut to enter split. + tapl.launchedAppState.taskbar + .openAllApps() + .getAppIcon(secondaryApp.appName) + .dragToSplitscreen(secondaryApp.`package`, primaryApp.`package`) + SplitScreenHelper.waitForSplitComplete(wmHelper, primaryApp, secondaryApp) + } + } + transitions { + SplitScreenHelper.dragDividerToResizeAndWait(device, wmHelper) + } + } + + @Presubmit + @Test + fun splitScreenDividerKeepVisible() { + testSpec.assertLayers { + this.isVisible(SPLIT_SCREEN_DIVIDER_COMPONENT) + } + } + + @Presubmit + @Test + fun primaryAppLayerKeepVisible() { + testSpec.assertLayers { + this.isVisible(primaryApp) + } + } + + @Presubmit + @Test + fun secondaryAppLayerVisibilityChanges() { + testSpec.assertLayers { + this.isVisible(secondaryApp) + .then() + .isInvisible(secondaryApp) + .then() + .isVisible(secondaryApp) + } + } + + @Presubmit + @Test + fun primaryAppWindowKeepVisible() { + testSpec.assertWm { + this.isAppWindowVisible(primaryApp) + } + } + + @Presubmit + @Test + fun secondaryAppWindowKeepVisible() { + testSpec.assertWm { + this.isAppWindowVisible(secondaryApp) + } + } + + @Presubmit + @Test + fun primaryAppBoundsChanges() = testSpec.splitAppLayerBoundsChanges( + primaryApp, splitLeftTop = false) + + @Presubmit + @Test + fun secondaryAppBoundsChanges() = testSpec.splitAppLayerBoundsChanges( + secondaryApp, splitLeftTop = true) + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun entireScreenCovered() = + super.entireScreenCovered() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarLayerIsVisibleAtStartAndEnd() = + super.navBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarLayerPositionAtStartAndEnd() = + super.navBarLayerPositionAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun navBarWindowIsAlwaysVisible() = + super.navBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarLayerIsVisibleAtStartAndEnd() = + super.statusBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarLayerPositionAtStartAndEnd() = + super.statusBarLayerPositionAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun statusBarWindowIsAlwaysVisible() = + super.statusBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarLayerIsVisibleAtStartAndEnd() = + super.taskBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun taskBarWindowIsAlwaysVisible() = + super.taskBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun visibleLayersShownMoreThanOneConsecutiveEntry() = + super.visibleLayersShownMoreThanOneConsecutiveEntry() + + /** {@inheritDoc} */ + @Postsubmit + @Test + override fun visibleWindowsShownMoreThanOneConsecutiveEntry() = + super.visibleWindowsShownMoreThanOneConsecutiveEntry() + + companion object { + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): List { + return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( + repetitions = SplitScreenHelper.TEST_REPETITIONS, + supportedRotations = listOf(Surface.ROTATION_0), + // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy. + supportedNavigationModes = + listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY)) + } + } +} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt index c48f3f77858b2..f69eb8f06182b 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt @@ -30,7 +30,6 @@ import com.android.wm.shell.flicker.appWindowIsVisibleAtEnd import com.android.wm.shell.flicker.helpers.SplitScreenHelper import com.android.wm.shell.flicker.layerBecomesVisible import com.android.wm.shell.flicker.layerIsVisibleAtEnd -import com.android.wm.shell.flicker.splitAppLayerBoundsBecomesVisible import com.android.wm.shell.flicker.splitAppLayerBoundsIsVisibleAtEnd import com.android.wm.shell.flicker.splitScreenDividerBecomesVisible import org.junit.Assume @@ -104,7 +103,7 @@ class SwitchBackToSplitFromHome(testSpec: FlickerTestParameter) : SplitScreenBas @Presubmit @Test - fun secondaryAppBoundsBecomesVisible() = testSpec.splitAppLayerBoundsBecomesVisible( + fun secondaryAppBoundsIsVisibleAtEnd() = testSpec.splitAppLayerBoundsIsVisibleAtEnd( secondaryApp, splitLeftTop = true) @Presubmit