Loading libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/Extensions.kt 0 → 100644 +32 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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. */ @file:JvmName("Utils") package com.android.wm.shell.flicker import android.app.ActivityTaskManager import android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT import android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD import android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED fun removeAllTasksButHome() { val ALL_ACTIVITY_TYPE_BUT_HOME = intArrayOf( ACTIVITY_TYPE_STANDARD, ACTIVITY_TYPE_ASSISTANT, ACTIVITY_TYPE_RECENTS, ACTIVITY_TYPE_UNDEFINED) val atm = ActivityTaskManager.getService() atm.removeRootTasksWithActivityTypes(ALL_ACTIVITY_TYPE_BUT_HOME) } libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/ImeAppHelper.kt +6 −8 Original line number Diff line number Diff line Loading @@ -32,13 +32,12 @@ open class ImeAppHelper(instrumentation: Instrumentation) : BaseAppHelper( /** * Opens the IME and wait for it to be displayed * * @param device UIDevice instance to interact with the device * @param wmHelper Helper used to wait for WindowManager states */ @JvmOverloads open fun openIME(device: UiDevice, wmHelper: WindowManagerStateHelper? = null) { open fun openIME(wmHelper: WindowManagerStateHelper? = null) { if (!isTelevision) { val editText = device.wait( val editText = uiDevice.wait( Until.findObject(By.res(getPackage(), "plain_text_input")), FIND_TIMEOUT) Loading @@ -47,7 +46,7 @@ open class ImeAppHelper(instrumentation: Instrumentation) : BaseAppHelper( "was left in an unknown state (e.g. in split screen)" } editText.click() waitAndAssertIMEShown(device, wmHelper) waitAndAssertIMEShown(uiDevice, wmHelper) } else { // If we do the same thing as above - editText.click() - on TV, that's going to force TV // into the touch mode. We really don't want that. Loading @@ -69,16 +68,15 @@ open class ImeAppHelper(instrumentation: Instrumentation) : BaseAppHelper( /** * Opens the IME and wait for it to be gone * * @param device UIDevice instance to interact with the device * @param wmHelper Helper used to wait for WindowManager states */ @JvmOverloads open fun closeIME(device: UiDevice, wmHelper: WindowManagerStateHelper? = null) { open fun closeIME(wmHelper: WindowManagerStateHelper? = null) { if (!isTelevision) { device.pressBack() uiDevice.pressBack() // Using only the AccessibilityInfo it is not possible to identify if the IME is active if (wmHelper == null) { device.waitForIdle() uiDevice.waitForIdle() } else { require(wmHelper.waitImeWindowGone()) { "IME did did not close" } } Loading libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt +81 −12 Original line number Diff line number Diff line Loading @@ -17,17 +17,20 @@ package com.android.wm.shell.flicker.helpers import android.app.Instrumentation import android.graphics.Point import android.media.session.MediaController import android.media.session.MediaSessionManager import android.os.SystemClock import androidx.test.uiautomator.By import androidx.test.uiautomator.BySelector import com.android.server.wm.flicker.helpers.SYSTEMUI_PACKAGE import com.android.server.wm.flicker.helpers.closePipWindow import com.android.server.wm.flicker.helpers.hasPipWindow import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper import com.android.wm.shell.flicker.pip.tv.closeTvPipWindow import com.android.wm.shell.flicker.pip.tv.isFocusedOrHasFocusedChild import com.android.wm.shell.flicker.pip.waitPipWindowGone import com.android.wm.shell.flicker.pip.waitPipWindowShown import com.android.wm.shell.flicker.testapp.Components import org.junit.Assert.fail class PipAppHelper(instrumentation: Instrumentation) : BaseAppHelper( instrumentation, Loading Loading @@ -55,6 +58,17 @@ class PipAppHelper(instrumentation: Instrumentation) : BaseAppHelper( } } /** {@inheritDoc} */ override fun launchViaIntent( wmHelper: WindowManagerStateHelper, expectedWindowName: String, action: String?, stringExtras: Map<String, String> ) { super.launchViaIntent(wmHelper, expectedWindowName, action, stringExtras) wmHelper.waitPipWindowShown() } private fun focusOnObject(selector: BySelector): Boolean { // We expect all the focusable UI elements to be arranged in a way so that it is possible // to "cycle" over all them by clicking the D-Pad DOWN button, going back up to "the top" Loading @@ -69,16 +83,12 @@ class PipAppHelper(instrumentation: Instrumentation) : BaseAppHelper( return false } fun clickEnterPipButton() { @JvmOverloads fun clickEnterPipButton(wmHelper: WindowManagerStateHelper? = null) { clickObject(ENTER_PIP_BUTTON_ID) // TODO(b/172321238): remove this check once hasPipWindow is fixed on TVs if (!isTelevision) { uiDevice.hasPipWindow() } else { // Simply wait for 3 seconds SystemClock.sleep(3_000) } // Wait on WMHelper or simply wait for 3 seconds wmHelper?.waitPipWindowShown() ?: SystemClock.sleep(3_000) } fun clickStartMediaSessionButton() { Loading @@ -97,16 +107,75 @@ class PipAppHelper(instrumentation: Instrumentation) : BaseAppHelper( fun stopMedia() = mediaController?.transportControls?.stop() ?: error("No active media session found") @Deprecated("Use PipAppHelper.closePipWindow(wmHelper) instead", ReplaceWith("closePipWindow(wmHelper)")) fun closePipWindow() { if (isTelevision) { uiDevice.closeTvPipWindow() } else { uiDevice.closePipWindow() } } if (!waitUntilClosed()) { fail("Couldn't close Pip") /** * Expands the pip window and dismisses it by clicking on the X button. * * Note, currently the View coordinates reported by the accessibility are relative to * the window, so the correct coordinates need to be calculated * * For example, in a PIP window located at Rect(508, 1444 - 1036, 1741), the * dismiss button coordinates are shown as Rect(650, 0 - 782, 132), with center in * Point(716, 66), instead of Point(970, 1403) * * See b/179337864 */ fun closePipWindow(wmHelper: WindowManagerStateHelper) { if (isTelevision) { uiDevice.closeTvPipWindow() } else { expandPipWindow(wmHelper) val exitPipObject = uiDevice.findObject(By.res(SYSTEMUI_PACKAGE, "dismiss")) requireNotNull(exitPipObject) { "PIP window dismiss button not found" } val coordinatesInWindow = exitPipObject.visibleBounds val windowOffset = wmHelper.getWindowRegion(component).bounds val newCoordinates = Point(windowOffset.left + coordinatesInWindow.centerX(), windowOffset.top + coordinatesInWindow.centerY()) uiDevice.click(newCoordinates.x, newCoordinates.y) } // Wait for animation to complete. wmHelper.waitPipWindowGone() wmHelper.waitForHomeActivityVisible() } /** * Click once on the PIP window to expand it */ fun expandPipWindow(wmHelper: WindowManagerStateHelper) { val windowRegion = wmHelper.getWindowRegion(component) require(!windowRegion.isEmpty) { "Unable to find a PIP window in the current state" } val windowRect = windowRegion.bounds uiDevice.click(windowRect.centerX(), windowRect.centerY()) // Ensure WindowManagerService wait until all animations have completed wmHelper.waitForAppTransitionIdle() mInstrumentation.uiAutomation.syncInputTransactions() } /** * Double click on the PIP window to reopen to app */ fun expandPipWindowToApp(wmHelper: WindowManagerStateHelper) { val windowRegion = wmHelper.getWindowRegion(component) require(!windowRegion.isEmpty) { "Unable to find a PIP window in the current state" } val windowRect = windowRegion.bounds uiDevice.click(windowRect.centerX(), windowRect.centerY()) uiDevice.click(windowRect.centerX(), windowRect.centerY()) wmHelper.waitPipWindowGone() wmHelper.waitForAppTransitionIdle() } companion object { Loading libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AppTestBase.kt +0 −13 Original line number Diff line number Diff line Loading @@ -16,11 +16,6 @@ package com.android.wm.shell.flicker.pip import android.app.ActivityTaskManager import android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT import android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD import android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED import android.os.SystemClock import com.android.wm.shell.flicker.NonRotationTestBase Loading @@ -29,14 +24,6 @@ abstract class AppTestBase( rotation: Int ) : NonRotationTestBase(rotationName, rotation) { companion object { fun removeAllTasksButHome() { val ALL_ACTIVITY_TYPE_BUT_HOME = intArrayOf( ACTIVITY_TYPE_STANDARD, ACTIVITY_TYPE_ASSISTANT, ACTIVITY_TYPE_RECENTS, ACTIVITY_TYPE_UNDEFINED) val atm = ActivityTaskManager.getService() atm.removeRootTasksWithActivityTypes(ALL_ACTIVITY_TYPE_BUT_HOME) } fun waitForAnimationComplete() { // TODO: UiDevice doesn't have reliable way to wait for the completion of animation. // Consider to introduce WindowManagerStateHelper to access Activity state. Loading libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterExitPipTest.kt +58 −73 Original line number Diff line number Diff line Loading @@ -16,21 +16,21 @@ package com.android.wm.shell.flicker.pip import android.platform.test.annotations.Presubmit import android.os.Bundle import android.view.Surface import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.dsl.runFlicker import androidx.test.platform.app.InstrumentationRegistry import com.android.server.wm.flicker.FlickerTestRunner import com.android.server.wm.flicker.FlickerTestRunnerFactory import com.android.server.wm.flicker.dsl.FlickerBuilder import com.android.server.wm.flicker.helpers.WindowUtils import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen import com.android.wm.shell.flicker.helpers.FixedAppHelper import com.android.wm.shell.flicker.helpers.PipAppHelper import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible import com.android.server.wm.flicker.startRotation import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible import com.android.wm.shell.flicker.testapp.Components.PipActivity.EXTRA_ENTER_PIP import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters import org.junit.runners.Parameterized Loading @@ -39,42 +39,31 @@ import org.junit.runners.Parameterized * Test Pip launch and exit. * To run this test: `atest WMShellFlickerTests:EnterExitPipTest` */ @Presubmit @RequiresDevice @RunWith(Parameterized::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) class EnterExitPipTest( rotationName: String, rotation: Int ) : AppTestBase(rotationName, rotation) { private val pipApp = PipAppHelper(instrumentation) private val testApp = FixedAppHelper(instrumentation) @Test fun testDisplayMetricsPinUnpin() { runFlicker(instrumentation) { withTestName { "testDisplayMetricsPinUnpin" } testSpec: FlickerTestRunnerFactory.TestSpec ) : FlickerTestRunner(testSpec) { companion object : PipTransitionBase(InstrumentationRegistry.getInstrumentation()) { @Parameterized.Parameters(name = "{0}") @JvmStatic fun getParams(): List<Array<Any>> { val testApp = FixedAppHelper(instrumentation) val baseConfig = getTransitionLaunch(eachRun = true) val testSpec: FlickerBuilder.(Bundle) -> Unit = { configuration -> setup { test { removeAllTasksButHome() device.wakeUpAndGoToHomeScreen() pipApp.launchViaIntent(stringExtras = mapOf(EXTRA_ENTER_PIP to "true")) testApp.launchViaIntent() waitForAnimationComplete() eachRun { testApp.launchViaIntent(wmHelper) } } transitions { // This will bring PipApp to fullscreen pipApp.launchViaIntent() waitForAnimationComplete() } teardown { test { removeAllTasksButHome() } pipApp.launchViaIntent(wmHelper) } assertions { val displayBounds = WindowUtils.getDisplayBounds(rotation) val displayBounds = WindowUtils.getDisplayBounds(configuration.startRotation) presubmit { windowManagerTrace { all("pipApp must remain inside visible bounds") { coversAtMostRegion(pipApp.defaultWindowName, displayBounds) Loading Loading @@ -108,13 +97,9 @@ class EnterExitPipTest( } } } companion object { @Parameterized.Parameters(name = "{0}") @JvmStatic fun getParams(): Collection<Array<Any>> { val supportedRotations = intArrayOf(Surface.ROTATION_0) return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) } return FlickerTestRunnerFactory.getInstance().buildTest(instrumentation, baseConfig, testSpec, supportedRotations = listOf(Surface.ROTATION_0), repetitions = 5) } } } No newline at end of file Loading
libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/Extensions.kt 0 → 100644 +32 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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. */ @file:JvmName("Utils") package com.android.wm.shell.flicker import android.app.ActivityTaskManager import android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT import android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD import android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED fun removeAllTasksButHome() { val ALL_ACTIVITY_TYPE_BUT_HOME = intArrayOf( ACTIVITY_TYPE_STANDARD, ACTIVITY_TYPE_ASSISTANT, ACTIVITY_TYPE_RECENTS, ACTIVITY_TYPE_UNDEFINED) val atm = ActivityTaskManager.getService() atm.removeRootTasksWithActivityTypes(ALL_ACTIVITY_TYPE_BUT_HOME) }
libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/ImeAppHelper.kt +6 −8 Original line number Diff line number Diff line Loading @@ -32,13 +32,12 @@ open class ImeAppHelper(instrumentation: Instrumentation) : BaseAppHelper( /** * Opens the IME and wait for it to be displayed * * @param device UIDevice instance to interact with the device * @param wmHelper Helper used to wait for WindowManager states */ @JvmOverloads open fun openIME(device: UiDevice, wmHelper: WindowManagerStateHelper? = null) { open fun openIME(wmHelper: WindowManagerStateHelper? = null) { if (!isTelevision) { val editText = device.wait( val editText = uiDevice.wait( Until.findObject(By.res(getPackage(), "plain_text_input")), FIND_TIMEOUT) Loading @@ -47,7 +46,7 @@ open class ImeAppHelper(instrumentation: Instrumentation) : BaseAppHelper( "was left in an unknown state (e.g. in split screen)" } editText.click() waitAndAssertIMEShown(device, wmHelper) waitAndAssertIMEShown(uiDevice, wmHelper) } else { // If we do the same thing as above - editText.click() - on TV, that's going to force TV // into the touch mode. We really don't want that. Loading @@ -69,16 +68,15 @@ open class ImeAppHelper(instrumentation: Instrumentation) : BaseAppHelper( /** * Opens the IME and wait for it to be gone * * @param device UIDevice instance to interact with the device * @param wmHelper Helper used to wait for WindowManager states */ @JvmOverloads open fun closeIME(device: UiDevice, wmHelper: WindowManagerStateHelper? = null) { open fun closeIME(wmHelper: WindowManagerStateHelper? = null) { if (!isTelevision) { device.pressBack() uiDevice.pressBack() // Using only the AccessibilityInfo it is not possible to identify if the IME is active if (wmHelper == null) { device.waitForIdle() uiDevice.waitForIdle() } else { require(wmHelper.waitImeWindowGone()) { "IME did did not close" } } Loading
libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt +81 −12 Original line number Diff line number Diff line Loading @@ -17,17 +17,20 @@ package com.android.wm.shell.flicker.helpers import android.app.Instrumentation import android.graphics.Point import android.media.session.MediaController import android.media.session.MediaSessionManager import android.os.SystemClock import androidx.test.uiautomator.By import androidx.test.uiautomator.BySelector import com.android.server.wm.flicker.helpers.SYSTEMUI_PACKAGE import com.android.server.wm.flicker.helpers.closePipWindow import com.android.server.wm.flicker.helpers.hasPipWindow import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper import com.android.wm.shell.flicker.pip.tv.closeTvPipWindow import com.android.wm.shell.flicker.pip.tv.isFocusedOrHasFocusedChild import com.android.wm.shell.flicker.pip.waitPipWindowGone import com.android.wm.shell.flicker.pip.waitPipWindowShown import com.android.wm.shell.flicker.testapp.Components import org.junit.Assert.fail class PipAppHelper(instrumentation: Instrumentation) : BaseAppHelper( instrumentation, Loading Loading @@ -55,6 +58,17 @@ class PipAppHelper(instrumentation: Instrumentation) : BaseAppHelper( } } /** {@inheritDoc} */ override fun launchViaIntent( wmHelper: WindowManagerStateHelper, expectedWindowName: String, action: String?, stringExtras: Map<String, String> ) { super.launchViaIntent(wmHelper, expectedWindowName, action, stringExtras) wmHelper.waitPipWindowShown() } private fun focusOnObject(selector: BySelector): Boolean { // We expect all the focusable UI elements to be arranged in a way so that it is possible // to "cycle" over all them by clicking the D-Pad DOWN button, going back up to "the top" Loading @@ -69,16 +83,12 @@ class PipAppHelper(instrumentation: Instrumentation) : BaseAppHelper( return false } fun clickEnterPipButton() { @JvmOverloads fun clickEnterPipButton(wmHelper: WindowManagerStateHelper? = null) { clickObject(ENTER_PIP_BUTTON_ID) // TODO(b/172321238): remove this check once hasPipWindow is fixed on TVs if (!isTelevision) { uiDevice.hasPipWindow() } else { // Simply wait for 3 seconds SystemClock.sleep(3_000) } // Wait on WMHelper or simply wait for 3 seconds wmHelper?.waitPipWindowShown() ?: SystemClock.sleep(3_000) } fun clickStartMediaSessionButton() { Loading @@ -97,16 +107,75 @@ class PipAppHelper(instrumentation: Instrumentation) : BaseAppHelper( fun stopMedia() = mediaController?.transportControls?.stop() ?: error("No active media session found") @Deprecated("Use PipAppHelper.closePipWindow(wmHelper) instead", ReplaceWith("closePipWindow(wmHelper)")) fun closePipWindow() { if (isTelevision) { uiDevice.closeTvPipWindow() } else { uiDevice.closePipWindow() } } if (!waitUntilClosed()) { fail("Couldn't close Pip") /** * Expands the pip window and dismisses it by clicking on the X button. * * Note, currently the View coordinates reported by the accessibility are relative to * the window, so the correct coordinates need to be calculated * * For example, in a PIP window located at Rect(508, 1444 - 1036, 1741), the * dismiss button coordinates are shown as Rect(650, 0 - 782, 132), with center in * Point(716, 66), instead of Point(970, 1403) * * See b/179337864 */ fun closePipWindow(wmHelper: WindowManagerStateHelper) { if (isTelevision) { uiDevice.closeTvPipWindow() } else { expandPipWindow(wmHelper) val exitPipObject = uiDevice.findObject(By.res(SYSTEMUI_PACKAGE, "dismiss")) requireNotNull(exitPipObject) { "PIP window dismiss button not found" } val coordinatesInWindow = exitPipObject.visibleBounds val windowOffset = wmHelper.getWindowRegion(component).bounds val newCoordinates = Point(windowOffset.left + coordinatesInWindow.centerX(), windowOffset.top + coordinatesInWindow.centerY()) uiDevice.click(newCoordinates.x, newCoordinates.y) } // Wait for animation to complete. wmHelper.waitPipWindowGone() wmHelper.waitForHomeActivityVisible() } /** * Click once on the PIP window to expand it */ fun expandPipWindow(wmHelper: WindowManagerStateHelper) { val windowRegion = wmHelper.getWindowRegion(component) require(!windowRegion.isEmpty) { "Unable to find a PIP window in the current state" } val windowRect = windowRegion.bounds uiDevice.click(windowRect.centerX(), windowRect.centerY()) // Ensure WindowManagerService wait until all animations have completed wmHelper.waitForAppTransitionIdle() mInstrumentation.uiAutomation.syncInputTransactions() } /** * Double click on the PIP window to reopen to app */ fun expandPipWindowToApp(wmHelper: WindowManagerStateHelper) { val windowRegion = wmHelper.getWindowRegion(component) require(!windowRegion.isEmpty) { "Unable to find a PIP window in the current state" } val windowRect = windowRegion.bounds uiDevice.click(windowRect.centerX(), windowRect.centerY()) uiDevice.click(windowRect.centerX(), windowRect.centerY()) wmHelper.waitPipWindowGone() wmHelper.waitForAppTransitionIdle() } companion object { Loading
libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AppTestBase.kt +0 −13 Original line number Diff line number Diff line Loading @@ -16,11 +16,6 @@ package com.android.wm.shell.flicker.pip import android.app.ActivityTaskManager import android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT import android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD import android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED import android.os.SystemClock import com.android.wm.shell.flicker.NonRotationTestBase Loading @@ -29,14 +24,6 @@ abstract class AppTestBase( rotation: Int ) : NonRotationTestBase(rotationName, rotation) { companion object { fun removeAllTasksButHome() { val ALL_ACTIVITY_TYPE_BUT_HOME = intArrayOf( ACTIVITY_TYPE_STANDARD, ACTIVITY_TYPE_ASSISTANT, ACTIVITY_TYPE_RECENTS, ACTIVITY_TYPE_UNDEFINED) val atm = ActivityTaskManager.getService() atm.removeRootTasksWithActivityTypes(ALL_ACTIVITY_TYPE_BUT_HOME) } fun waitForAnimationComplete() { // TODO: UiDevice doesn't have reliable way to wait for the completion of animation. // Consider to introduce WindowManagerStateHelper to access Activity state. Loading
libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterExitPipTest.kt +58 −73 Original line number Diff line number Diff line Loading @@ -16,21 +16,21 @@ package com.android.wm.shell.flicker.pip import android.platform.test.annotations.Presubmit import android.os.Bundle import android.view.Surface import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.dsl.runFlicker import androidx.test.platform.app.InstrumentationRegistry import com.android.server.wm.flicker.FlickerTestRunner import com.android.server.wm.flicker.FlickerTestRunnerFactory import com.android.server.wm.flicker.dsl.FlickerBuilder import com.android.server.wm.flicker.helpers.WindowUtils import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen import com.android.wm.shell.flicker.helpers.FixedAppHelper import com.android.wm.shell.flicker.helpers.PipAppHelper import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible import com.android.server.wm.flicker.startRotation import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible import com.android.wm.shell.flicker.testapp.Components.PipActivity.EXTRA_ENTER_PIP import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters import org.junit.runners.Parameterized Loading @@ -39,42 +39,31 @@ import org.junit.runners.Parameterized * Test Pip launch and exit. * To run this test: `atest WMShellFlickerTests:EnterExitPipTest` */ @Presubmit @RequiresDevice @RunWith(Parameterized::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) class EnterExitPipTest( rotationName: String, rotation: Int ) : AppTestBase(rotationName, rotation) { private val pipApp = PipAppHelper(instrumentation) private val testApp = FixedAppHelper(instrumentation) @Test fun testDisplayMetricsPinUnpin() { runFlicker(instrumentation) { withTestName { "testDisplayMetricsPinUnpin" } testSpec: FlickerTestRunnerFactory.TestSpec ) : FlickerTestRunner(testSpec) { companion object : PipTransitionBase(InstrumentationRegistry.getInstrumentation()) { @Parameterized.Parameters(name = "{0}") @JvmStatic fun getParams(): List<Array<Any>> { val testApp = FixedAppHelper(instrumentation) val baseConfig = getTransitionLaunch(eachRun = true) val testSpec: FlickerBuilder.(Bundle) -> Unit = { configuration -> setup { test { removeAllTasksButHome() device.wakeUpAndGoToHomeScreen() pipApp.launchViaIntent(stringExtras = mapOf(EXTRA_ENTER_PIP to "true")) testApp.launchViaIntent() waitForAnimationComplete() eachRun { testApp.launchViaIntent(wmHelper) } } transitions { // This will bring PipApp to fullscreen pipApp.launchViaIntent() waitForAnimationComplete() } teardown { test { removeAllTasksButHome() } pipApp.launchViaIntent(wmHelper) } assertions { val displayBounds = WindowUtils.getDisplayBounds(rotation) val displayBounds = WindowUtils.getDisplayBounds(configuration.startRotation) presubmit { windowManagerTrace { all("pipApp must remain inside visible bounds") { coversAtMostRegion(pipApp.defaultWindowName, displayBounds) Loading Loading @@ -108,13 +97,9 @@ class EnterExitPipTest( } } } companion object { @Parameterized.Parameters(name = "{0}") @JvmStatic fun getParams(): Collection<Array<Any>> { val supportedRotations = intArrayOf(Surface.ROTATION_0) return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) } return FlickerTestRunnerFactory.getInstance().buildTest(instrumentation, baseConfig, testSpec, supportedRotations = listOf(Surface.ROTATION_0), repetitions = 5) } } } No newline at end of file