diff options
| author | 2023-06-05 08:54:18 +0000 | |
|---|---|---|
| committer | 2023-06-05 14:08:19 +0000 | |
| commit | 39fb1e0ce2b4bc6bd4e7d50f0493ce3365dc24ca (patch) | |
| tree | 7da48c3d85338724e84b69279bd2c348d0793192 | |
| parent | 9ce13dd292932c89c09a0931aec865c4353508f8 (diff) | |
Add RepositionFixedPortraitAppTest
Add helpers to reposition app and wait for app to move to expected
bounds. Remove rotation configuration from BaseAppCompat and define in
test instead.
Fix: 283773197
Test: atest WMShellFlickerTests:RepositionFixedPortraitAppTest
Change-Id: Ifae79ba244cc62419c9ea7b5b86fb9528055a3cc
6 files changed, 238 insertions, 19 deletions
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt index 61781565270b..3000008628fe 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt @@ -23,16 +23,15 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.FlickerTest import com.android.server.wm.flicker.helpers.setRotation import com.android.server.wm.flicker.helpers.LetterboxAppHelper -import android.tools.device.flicker.legacy.FlickerTestFactory import android.tools.device.flicker.legacy.IFlickerTestData import com.android.wm.shell.flicker.BaseTest import com.android.wm.shell.flicker.appWindowIsVisibleAtStart import com.android.wm.shell.flicker.appWindowIsVisibleAtEnd +import com.android.wm.shell.flicker.appWindowKeepVisible import com.android.wm.shell.flicker.layerKeepVisible import org.junit.After import org.junit.Assume import org.junit.Before -import org.junit.runners.Parameterized abstract class BaseAppCompat(flicker: FlickerTest) : BaseTest(flicker) { protected val context: Context = instrumentation.context @@ -58,12 +57,13 @@ abstract class BaseAppCompat(flicker: FlickerTest) : BaseTest(flicker) { cmdHelper = CommandsHelper.getInstance(instrumentation) Assume.assumeTrue(tapl.isTablet && isIgnoreOrientationRequest()) letterboxStyle = mapLetterboxStyle() + resetLetterboxStyle() setLetterboxEducationEnabled(false) } @After fun after() { - resetLetterboxEducationEnabled() + resetLetterboxStyle() } private fun mapLetterboxStyle(): HashMap<String, String> { @@ -87,9 +87,8 @@ abstract class BaseAppCompat(flicker: FlickerTest) : BaseTest(flicker) { return letterboxStyle } - private fun resetLetterboxEducationEnabled() { - val enabled = getLetterboxStyle().getValue("Is education enabled") - cmdHelper.executeShellCommand("wm set-letterbox-style --isEducationEnabled $enabled") + private fun resetLetterboxStyle() { + cmdHelper.executeShellCommand("wm reset-letterbox-style") } private fun setLetterboxEducationEnabled(enabled: Boolean) { @@ -126,25 +125,21 @@ abstract class BaseAppCompat(flicker: FlickerTest) : BaseTest(flicker) { flicker.appWindowIsVisibleAtEnd(letterboxApp) } + fun assertLetterboxAppKeepVisible() { + assertLetterboxAppWindowKeepVisible() + assertLetterboxAppLayerKeepVisible() + } + fun assertAppLetterboxedAtEnd() = flicker.assertLayersEnd { isVisible(ComponentNameMatcher.LETTERBOX) } fun assertAppLetterboxedAtStart() = flicker.assertLayersStart { isVisible(ComponentNameMatcher.LETTERBOX) } + fun assertAppStaysLetterboxed() = + flicker.assertLayers { isVisible(ComponentNameMatcher.LETTERBOX) } + fun assertLetterboxAppLayerKeepVisible() = flicker.layerKeepVisible(letterboxApp) - companion object { - /** - * Creates the test configurations. - * - * See [FlickerTestFactory.rotationTests] for configuring screen orientation and - * navigation modes. - */ - @Parameterized.Parameters(name = "{0}") - @JvmStatic - fun getParams(): Collection<FlickerTest> { - return FlickerTestFactory.rotationTests() - } - } + fun assertLetterboxAppWindowKeepVisible() = flicker.appWindowKeepVisible(letterboxApp) } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/OpenAppInSizeCompatModeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/OpenAppInSizeCompatModeTest.kt index c2141a370f10..3d83455932f5 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/OpenAppInSizeCompatModeTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/OpenAppInSizeCompatModeTest.kt @@ -21,6 +21,7 @@ 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.FlickerTest +import android.tools.device.flicker.legacy.FlickerTestFactory import androidx.test.filters.RequiresDevice import org.junit.Test import org.junit.runner.RunWith @@ -90,4 +91,18 @@ class OpenAppInSizeCompatModeTest(flicker: FlickerTest) : BaseAppCompat(flicker) .isInvisible(ComponentNameMatcher.ROTATION) } } + + companion object { + /** + * Creates the test configurations. + * + * See [FlickerTestFactory.rotationTests] for configuring screen orientation and + * navigation modes. + */ + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): Collection<FlickerTest> { + return FlickerTestFactory.rotationTests() + } + } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RepositionFixedPortraitAppTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RepositionFixedPortraitAppTest.kt new file mode 100644 index 000000000000..c3355ede525e --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RepositionFixedPortraitAppTest.kt @@ -0,0 +1,103 @@ +/* + * 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.wm.shell.flicker.appcompat + +import android.platform.test.annotations.Postsubmit +import android.tools.common.Rotation +import android.tools.device.flicker.junit.FlickerParametersRunnerFactory +import android.tools.device.flicker.legacy.FlickerBuilder +import android.tools.device.flicker.legacy.FlickerTest +import android.tools.device.flicker.legacy.FlickerTestFactory +import android.tools.device.helpers.WindowUtils + +import androidx.test.filters.RequiresDevice +import org.junit.Test + +import org.junit.runner.RunWith +import org.junit.runners.Parameterized + +/** + * Test launching a fixed portrait letterboxed app in landscape and repositioning to the right. + * + * To run this test: `atest WMShellFlickerTests:RepositionFixedPortraitAppTest` + * Actions: + * ``` + * Launch a fixed portrait app in landscape to letterbox app + * Double tap to the right to reposition app and wait for app to move + * ``` + * + * Notes: + * ``` + * Some default assertions (e.g., nav bar, status bar and screen covered) + * are inherited [BaseTest] + * ``` + */ +@RequiresDevice +@RunWith(Parameterized::class) +@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) +class RepositionFixedPortraitAppTest(flicker: FlickerTest) : BaseAppCompat(flicker) { + + val displayBounds = WindowUtils.getDisplayBounds(flicker.scenario.startRotation).bounds + /** {@inheritDoc} */ + override val transition: FlickerBuilder.() -> Unit + get() = { + setup { + setStartRotation() + letterboxApp.launchViaIntent(wmHelper) + } + transitions { + letterboxApp.repositionHorizontally(displayBounds, true) + letterboxApp.waitForAppToMoveHorizontallyTo(wmHelper, displayBounds, true) + } + teardown { + letterboxApp.repositionHorizontally(displayBounds, false) + letterboxApp.exit(wmHelper) + } + } + + @Postsubmit + @Test + fun letterboxedAppHasRoundedCorners() = assertLetterboxAppAtEndHasRoundedCorners() + + @Postsubmit + @Test + fun letterboxAppLayerKeepVisible() = assertLetterboxAppLayerKeepVisible() + + @Postsubmit + @Test + fun appStaysLetterboxed() = assertAppStaysLetterboxed() + + @Postsubmit + @Test + fun appKeepVisible() = assertLetterboxAppKeepVisible() + + companion object { + /** + * Creates the test configurations. + * + * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and + * navigation modes. + */ + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): Collection<FlickerTest> { + return FlickerTestFactory.nonRotationTests( + supportedRotations = listOf(Rotation.ROTATION_90) + ) + } + } +}
\ No newline at end of file diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RestartAppInSizeCompatModeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RestartAppInSizeCompatModeTest.kt index b0e1a42306df..c2057d23a2c4 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RestartAppInSizeCompatModeTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RestartAppInSizeCompatModeTest.kt @@ -20,6 +20,7 @@ import android.platform.test.annotations.Postsubmit import android.tools.device.flicker.junit.FlickerParametersRunnerFactory import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.FlickerTest +import android.tools.device.flicker.legacy.FlickerTestFactory import android.tools.device.helpers.WindowUtils import androidx.test.filters.RequiresDevice import org.junit.Test @@ -88,4 +89,18 @@ class RestartAppInSizeCompatModeTest(flicker: FlickerTest) : BaseAppCompat(flick val displayBounds = WindowUtils.getDisplayBounds(flicker.scenario.endRotation) flicker.assertLayersEnd { visibleRegion(letterboxApp).coversAtMost(displayBounds) } } + + companion object { + /** + * Creates the test configurations. + * + * See [FlickerTestFactory.rotationTests] for configuring screen orientation and + * navigation modes. + */ + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): Collection<FlickerTest> { + return FlickerTestFactory.rotationTests() + } + } } diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/GestureHelper.java b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/GestureHelper.java index a8f1b3de564e..eeee7b4dfc6b 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/GestureHelper.java +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/GestureHelper.java @@ -62,6 +62,33 @@ public class GestureHelper { } /** + * Injects a series of {@link MotionEvent}s to simulate tapping. + * + * @param point coordinates of pointer to tap + * @param times the number of times to tap + */ + public boolean tap(@NonNull Tuple point, int times) throws InterruptedException { + PointerProperties ptrProp = getPointerProp(0, MotionEvent.TOOL_TYPE_FINGER); + PointerCoords ptrCoord = getPointerCoord(point.x, point.y, 1, 1); + + for (int i = 0; i <= times; i++) { + // If already tapped, inject delay in between movements + if (times > 0) { + SystemClock.sleep(50L); + } + if (!primaryPointerDown(ptrProp, ptrCoord, SystemClock.uptimeMillis())) { + return false; + } + // Delay before releasing tap + SystemClock.sleep(100L); + if (!primaryPointerUp(ptrProp, ptrCoord, SystemClock.uptimeMillis())) { + return false; + } + } + return true; + } + + /** * Injects a series of {@link MotionEvent}s to simulate a drag gesture without pointer release. * * Simulates a drag gesture without releasing the primary pointer. The primary pointer info diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/LetterboxAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/LetterboxAppHelper.kt index a670d68cabd9..34581bbb4516 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/LetterboxAppHelper.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/LetterboxAppHelper.kt @@ -17,6 +17,8 @@ package com.android.server.wm.flicker.helpers import android.app.Instrumentation +import android.tools.common.datatypes.Region +import android.tools.common.datatypes.Rect import android.tools.common.traces.component.ComponentNameMatcher import android.tools.device.apphelpers.StandardAppHelper import android.tools.device.helpers.FIND_TIMEOUT @@ -36,6 +38,8 @@ constructor( ActivityOptions.NonResizeablePortraitActivity.COMPONENT.toFlickerComponent() ) : StandardAppHelper(instr, launcherName, component) { + private val gestureHelper: GestureHelper = GestureHelper(mInstrumentation) + fun clickRestart(wmHelper: WindowManagerStateHelper) { val restartButton = uiDevice.wait( @@ -56,4 +60,64 @@ constructor( ?: error("Restart dialog button not found") wmHelper.StateSyncBuilder().withAppTransitionIdle().waitForAndVerify() } + + fun repositionHorizontally(displayBounds: Rect, right: Boolean) { + val x = if (right) displayBounds.right - BOUNDS_OFFSET else BOUNDS_OFFSET + reposition(x.toFloat(), displayBounds.centerY().toFloat()) + } + + fun repositionVertically(displayBounds: Rect, bottom: Boolean) { + val y = if (bottom) displayBounds.bottom - BOUNDS_OFFSET else BOUNDS_OFFSET + reposition(displayBounds.centerX().toFloat(), y.toFloat()) + } + + private fun reposition(x: Float, y: Float) { + val coords = GestureHelper.Tuple(x, y) + require(gestureHelper.tap(coords, 2)) { "Failed to reposition letterbox app" } + } + + fun waitForAppToMoveHorizontallyTo( + wmHelper: WindowManagerStateHelper, + displayBounds: Rect, + right: Boolean + ) { + wmHelper.StateSyncBuilder().add("letterboxAppRepositioned") { + val letterboxAppWindow = getWindowRegion(wmHelper) + val appRegionBounds = letterboxAppWindow.bounds + val appWidth = appRegionBounds.width + return@add if (right) appRegionBounds.left == displayBounds.right - appWidth && + appRegionBounds.right == displayBounds.right + else appRegionBounds.left == displayBounds.left && + appRegionBounds.right == displayBounds.left + appWidth + }.waitForAndVerify() + } + + fun waitForAppToMoveVerticallyTo( + wmHelper: WindowManagerStateHelper, + displayBounds: Rect, + navBarHeight: Int, + bottom: Boolean + ) { + wmHelper.StateSyncBuilder().add("letterboxAppRepositioned") { + val letterboxAppWindow = getWindowRegion(wmHelper) + val appRegionBounds = letterboxAppWindow.bounds + val appHeight = appRegionBounds.height + return@add if (bottom) appRegionBounds.bottom == displayBounds.bottom && + appRegionBounds.top == (displayBounds.bottom - appHeight + navBarHeight) + else appRegionBounds.top == displayBounds.top && + appRegionBounds.bottom == displayBounds.top + appHeight + }.waitForAndVerify() + } + + private fun getWindowRegion(wmHelper: WindowManagerStateHelper): Region { + val windowRegion = wmHelper.getWindowRegion(this) + require(!windowRegion.isEmpty) { + "Unable to find letterbox app window in the current state" + } + return windowRegion + } + + companion object { + private const val BOUNDS_OFFSET: Int = 100 + } } |