diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt index d4b4e5daf7cbc..3f860b5cc2d60 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt @@ -17,11 +17,14 @@ package com.android.wm.shell.flicker.helpers import android.app.Instrumentation +import android.graphics.Rect 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 androidx.test.uiautomator.Until +import com.android.server.wm.flicker.helpers.FIND_TIMEOUT import com.android.server.wm.flicker.helpers.SYSTEMUI_PACKAGE import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper import com.android.wm.shell.flicker.pip.tv.closeTvPipWindow @@ -113,25 +116,25 @@ class PipAppHelper(instrumentation: Instrumentation) : BaseAppHelper( } } + private fun getWindowRect(wmHelper: WindowManagerStateHelper): Rect { + val windowRegion = wmHelper.getWindowRegion(component) + require(!windowRegion.isEmpty) { + "Unable to find a PIP window in the current state" + } + return windowRegion.bounds + } + /** * 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 windowRect = getWindowRect(wmHelper) + uiDevice.click(windowRect.centerX(), windowRect.centerY()) val exitPipObject = uiDevice.findObject(By.res(SYSTEMUI_PACKAGE, "dismiss")) - requireNotNull(exitPipObject) { "PIP window dismiss button not found" } + ?: error("PIP window dismiss button not found") val dismissButtonBounds = exitPipObject.visibleBounds uiDevice.click(dismissButtonBounds.centerX(), dismissButtonBounds.centerY()) } @@ -142,32 +145,28 @@ class PipAppHelper(instrumentation: Instrumentation) : BaseAppHelper( } /** - * Click once on the PIP window to expand it + * Close the pip window by pressing the expand button */ - 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 + fun expandPipWindowToApp(wmHelper: WindowManagerStateHelper) { + val windowRect = getWindowRect(wmHelper) uiDevice.click(windowRect.centerX(), windowRect.centerY()) - // Ensure WindowManagerService wait until all animations have completed - wmHelper.waitForAppTransitionIdle() - mInstrumentation.uiAutomation.syncInputTransactions() + // search and interact with the expand button + val expandSelector = By.res(SYSTEMUI_PACKAGE, "expand_button") + uiDevice.wait(Until.hasObject(expandSelector), FIND_TIMEOUT) + val expandPipObject = uiDevice.findObject(expandSelector) + ?: error("PIP window expand button not found") + val expandButtonBounds = expandPipObject.visibleBounds + uiDevice.click(expandButtonBounds.centerX(), expandButtonBounds.centerY()) + wmHelper.waitFor("!hasPipWindow") { !it.wmState.hasPipWindow() } } /** - * Double click on the PIP window to reopen to app + * Double click on the PIP window to expand it */ - 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 + fun doubleClickPipWindow(wmHelper: WindowManagerStateHelper) { + val windowRect = getWindowRect(wmHelper) uiDevice.click(windowRect.centerX(), windowRect.centerY()) uiDevice.click(windowRect.centerX(), windowRect.centerY()) - wmHelper.waitFor("!hasPipWindow") { !it.wmState.hasPipWindow() } wmHelper.waitForAppTransitionIdle() } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt index 0f0a4abe30ef9..9c6c7b1e60fff 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt @@ -45,7 +45,6 @@ class EnterPipTest(testSpec: FlickerTestParameter) : PipTransition(testSpec) { get() = buildTransition(eachRun = true, stringExtras = emptyMap()) { transitions { pipApp.clickEnterPipButton(wmHelper) - pipApp.expandPipWindow(wmHelper) } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppTransition.kt new file mode 100644 index 0000000000000..faaaecb8da463 --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppTransition.kt @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2020 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.pip + +import android.platform.test.annotations.Presubmit +import com.android.server.wm.flicker.FlickerTestParameter +import com.android.server.wm.traces.parser.toLayerName +import com.android.wm.shell.flicker.helpers.FixedAppHelper +import org.junit.Test + +/** + * Base class for pip expand tests + */ +abstract class ExitPipToAppTransition(testSpec: FlickerTestParameter) : PipTransition(testSpec) { + protected val testApp = FixedAppHelper(instrumentation) + + /** + * Checks that the pip app window remains inside the display bounds throughout the whole + * animation + */ + @Presubmit + @Test + open fun pipAppWindowRemainInsideVisibleBounds() { + testSpec.assertWm { + coversAtMost(displayBounds, pipApp.component) + } + } + + /** + * Checks that the pip app layer remains inside the display bounds throughout the whole + * animation + */ + @Presubmit + @Test + open fun pipAppLayerRemainInsideVisibleBounds() { + testSpec.assertLayers { + coversAtMost(displayBounds, pipApp.component) + } + } + + /** + * Checks both app windows are visible at the start of the transition (with [pipApp] on top). + * Then, during the transition, [testApp] becomes invisible and [pipApp] remains visible + */ + @Presubmit + @Test + open fun showBothAppWindowsThenHidePip() { + testSpec.assertWm { + // when the activity is STOPPING, sometimes it becomes invisible in an entry before + // the window, sometimes in the same entry. This occurs because we log 1x per frame + // thus we ignore activity here + isAppWindowVisible(testApp.component, ignoreActivity = true) + .isAppWindowOnTop(pipApp.component) + .then() + .isAppWindowInvisible(testApp.component) + .isAppWindowVisible(pipApp.component) + } + } + + /** + * Checks both app layers are visible at the start of the transition. Then, during the + * transition, [testApp] becomes invisible and [pipApp] remains visible + */ + @Presubmit + @Test + open fun showBothAppLayersThenHidePip() { + testSpec.assertLayers { + isVisible(testApp.component) + .isVisible(pipApp.component) + .then() + .isInvisible(testApp.component) + .isVisible(pipApp.component) + } + } + + /** + * Checks that the visible region of [testApp] plus the visible region of [pipApp] + * cover the full display area at the start of the transition + */ + @Presubmit + @Test + open fun testPlusPipAppsCoverFullScreenAtStart() { + testSpec.assertLayersStart { + val pipRegion = visibleRegion(pipApp.component).region + visibleRegion(testApp.component) + .plus(pipRegion) + .coversExactly(displayBounds) + } + } + + /** + * Checks that the visible region of [pipApp] covers the full display area at the end of + * the transition + */ + @Presubmit + @Test + open fun pipAppCoversFullScreenAtEnd() { + testSpec.assertLayersEnd { + visibleRegion(pipApp.component).coversExactly(displayBounds) + } + } + + /** + * Checks that the visible region of [pipApp] always expands during the animation + */ + @Presubmit + @Test + open fun pipLayerExpands() { + val layerName = pipApp.component.toLayerName() + testSpec.assertLayers { + val pipLayerList = this.layers { it.name.contains(layerName) && it.isVisible } + pipLayerList.zipWithNext { previous, current -> + current.visibleRegion.coversAtLeast(previous.visibleRegion.region) + } + } + } +} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt new file mode 100644 index 0000000000000..1ece34eba3ec6 --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt @@ -0,0 +1,92 @@ +/* + * 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. + */ + +package com.android.wm.shell.flicker.pip + +import android.platform.test.annotations.Postsubmit +import android.view.Surface +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.Group3 +import com.android.server.wm.flicker.dsl.FlickerBuilder +import org.junit.FixMethodOrder +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test expanding a pip window back to full screen via the expand button + * + * To run this test: `atest WMShellFlickerTests:ExitPipViaExpandButtonClickTest` + * + * Actions: + * Launch an app in pip mode [pipApp], + * Launch another full screen mode [testApp] + * Expand [pipApp] app to full screen by clicking on the pip window and + * then on the expand button + * + * Notes: + * 1. Some default assertions (e.g., nav bar, status bar and screen covered) + * are inherited [PipTransition] + * 2. Part of the test setup occurs automatically via + * [com.android.server.wm.flicker.TransitionRunnerWithRules], + * including configuring navigation mode, initial orientation and ensuring no + * apps are running before setup + */ +@RequiresDevice +@RunWith(Parameterized::class) +@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@Group3 +@Postsubmit +class ExitPipViaExpandButtonClickTest( + testSpec: FlickerTestParameter +) : ExitPipToAppTransition(testSpec) { + + /** + * Defines the transition used to run the test + */ + override val transition: FlickerBuilder.(Map) -> Unit + get() = buildTransition(eachRun = true) { + setup { + eachRun { + // launch an app behind the pip one + testApp.launchViaIntent(wmHelper) + } + } + transitions { + // This will bring PipApp to fullscreen + pipApp.expandPipWindowToApp(wmHelper) + } + } + + companion object { + /** + * Creates the test configurations. + * + * See [FlickerTestParameterFactory.getConfigNonRotationTests] for configuring + * repetitions, screen orientation and navigation modes. + */ + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): List { + return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( + supportedRotations = listOf(Surface.ROTATION_0), repetitions = 5) + } + } +} \ No newline at end of file diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterExitPipTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt similarity index 55% rename from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterExitPipTest.kt rename to libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt index 39e89fbd9b718..fbfa448cb877e 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterExitPipTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt @@ -17,7 +17,6 @@ package com.android.wm.shell.flicker.pip import android.platform.test.annotations.Postsubmit -import android.platform.test.annotations.Presubmit import android.view.Surface import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.FlickerParametersRunnerFactory @@ -25,7 +24,6 @@ import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.FlickerTestParameterFactory import com.android.server.wm.flicker.annotation.Group3 import com.android.server.wm.flicker.dsl.FlickerBuilder -import com.android.wm.shell.flicker.helpers.FixedAppHelper import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith @@ -33,23 +31,38 @@ import org.junit.runners.MethodSorters import org.junit.runners.Parameterized /** - * Test Pip launch and exit. - * To run this test: `atest WMShellFlickerTests:EnterExitPipTest` + * Test expanding a pip window back to full screen via an intent + * + * To run this test: `atest WMShellFlickerTests:ExitPipViaIntentTest` + * + * Actions: + * Launch an app in pip mode [pipApp], + * Launch another full screen mode [testApp] + * Expand [pipApp] app to full screen via an intent + * + * Notes: + * 1. Some default assertions (e.g., nav bar, status bar and screen covered) + * are inherited from [PipTransition] + * 2. Part of the test setup occurs automatically via + * [com.android.server.wm.flicker.TransitionRunnerWithRules], + * including configuring navigation mode, initial orientation and ensuring no + * apps are running before setup */ @RequiresDevice @RunWith(Parameterized::class) @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) @Group3 -class EnterExitPipTest( - testSpec: FlickerTestParameter -) : PipTransition(testSpec) { - private val testApp = FixedAppHelper(instrumentation) +class ExitPipViaIntentTest(testSpec: FlickerTestParameter) : ExitPipToAppTransition(testSpec) { + /** + * Defines the transition used to run the test + */ override val transition: FlickerBuilder.(Map) -> Unit get() = buildTransition(eachRun = true) { setup { eachRun { + // launch an app behind the pip one testApp.launchViaIntent(wmHelper) } } @@ -59,57 +72,17 @@ class EnterExitPipTest( } } - @Presubmit - @Test - fun pipAppRemainInsideVisibleBounds() { - testSpec.assertWm { - coversAtMost(displayBounds, pipApp.component) - } - } - @Postsubmit @Test - fun showBothAppWindowsThenHidePip() { - testSpec.assertWm { - // when the activity is STOPPING, sometimes it becomes invisible in an entry before - // the window, sometimes in the same entry. This occurs because we log 1x per frame - // thus we ignore activity here - isAppWindowVisible(testApp.component, ignoreActivity = true) - .isAppWindowOnTop(pipApp.component) - .then() - .isAppWindowInvisible(testApp.component) - } - } - - @Presubmit - @Test - fun showBothAppLayersThenHidePip() { - testSpec.assertLayers { - isVisible(testApp.component) - .isVisible(pipApp.component) - .then() - .isInvisible(testApp.component) - } - } - - @Presubmit - @Test - fun testAppCoversFullScreenWithPipOnDisplay() { - testSpec.assertLayersStart { - visibleRegion(testApp.component).coversExactly(displayBounds) - visibleRegion(pipApp.component).coversAtMost(displayBounds) - } - } - - @Presubmit - @Test - fun pipAppCoversFullScreen() { - testSpec.assertLayersEnd { - visibleRegion(pipApp.component).coversExactly(displayBounds) - } - } + override fun pipLayerExpands() = super.pipLayerExpands() companion object { + /** + * Creates the test configurations. + * + * See [FlickerTestParameterFactory.getConfigNonRotationTests] for configuring + * repetitions, screen orientation and navigation modes. + */ @Parameterized.Parameters(name = "{0}") @JvmStatic fun getParams(): List { diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt new file mode 100644 index 0000000000000..649d4168c9e42 --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2020 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.pip + +import android.platform.test.annotations.Postsubmit +import android.view.Surface +import androidx.test.filters.FlakyTest +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.LAUNCHER_COMPONENT +import com.android.server.wm.flicker.annotation.Group3 +import com.android.server.wm.flicker.dsl.FlickerBuilder +import com.android.server.wm.traces.parser.toLayerName +import org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test expanding a pip window by double clicking it + * + * To run this test: `atest WMShellFlickerTests:ExpandPipOnDoubleClickTest` + * + * Actions: + * Launch an app in pip mode [pipApp], + * Expand [pipApp] app to its maximum pip size by double clicking on it + * + * Notes: + * 1. Some default assertions (e.g., nav bar, status bar and screen covered) + * are inherited [PipTransition] + * 2. Part of the test setup occurs automatically via + * [com.android.server.wm.flicker.TransitionRunnerWithRules], + * including configuring navigation mode, initial orientation and ensuring no + * apps are running before setup + */ +@RequiresDevice +@RunWith(Parameterized::class) +@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@Group3 +@Postsubmit +class ExpandPipOnDoubleClickTest(testSpec: FlickerTestParameter) : PipTransition(testSpec) { + override val transition: FlickerBuilder.(Map) -> Unit + get() = buildTransition(eachRun = true) { + transitions { + pipApp.doubleClickPipWindow(wmHelper) + } + } + + /** + * Checks that the pip app window remains inside the display bounds throughout the whole + * animation + */ + @Test + fun pipWindowRemainInsideVisibleBounds() { + testSpec.assertWm { + coversAtMost(displayBounds, pipApp.component) + } + } + + /** + * Checks that the pip app layer remains inside the display bounds throughout the whole + * animation + */ + @Test + fun pipLayerRemainInsideVisibleBounds() { + testSpec.assertLayers { + coversAtMost(displayBounds, pipApp.component) + } + } + + /** + * Checks [pipApp] window remains visible throughout the animation + */ + @Test + fun pipWindowIsAlwaysVisible() { + testSpec.assertWm { + isAppWindowVisible(pipApp.component) + } + } + + /** + * Checks [pipApp] layer remains visible throughout the animation + */ + @Test + fun pipLayerIsAlwaysVisible() { + testSpec.assertLayers { + isVisible(pipApp.component) + } + } + + /** + * Checks that the visible region of [pipApp] always expands during the animation + */ + @Test + fun pipLayerExpands() { + val layerName = pipApp.component.toLayerName() + testSpec.assertLayers { + val pipLayerList = this.layers { it.name.contains(layerName) && it.isVisible } + pipLayerList.zipWithNext { previous, current -> + current.visibleRegion.coversAtLeast(previous.visibleRegion.region) + } + } + } + + @Test + fun windowIsAlwaysPinned() { + testSpec.assertWm { + this.invoke("hasPipWindow") { it.isPinned(pipApp.component) } + } + } + + /** + * Checks [pipApp] layer remains visible throughout the animation + */ + @Test + fun launcherIsAlwaysVisible() { + testSpec.assertLayers { + isVisible(LAUNCHER_COMPONENT) + } + } + + /** + * Checks that the focus doesn't change between windows during the transition + */ + @FlakyTest + @Test + fun focusDoesNotChange() { + testSpec.assertEventLog { + this.focusDoesNotChange() + } + } + + companion object { + /** + * Creates the test configurations. + * + * See [FlickerTestParameterFactory.getConfigNonRotationTests] for configuring + * repetitions, screen orientation and navigation modes. + */ + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): List { + return FlickerTestParameterFactory.getInstance() + .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0), + repetitions = 5) + } + } +} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipToAppTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipToAppTest.kt deleted file mode 100644 index 5abcf39f3fbd5..0000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipToAppTest.kt +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2020 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.pip - -import android.view.Surface -import androidx.test.filters.FlakyTest -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.LAUNCHER_COMPONENT -import com.android.server.wm.flicker.annotation.Group3 -import com.android.server.wm.flicker.dsl.FlickerBuilder -import com.android.server.wm.flicker.helpers.setRotation -import com.android.server.wm.flicker.startRotation -import org.junit.FixMethodOrder -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.MethodSorters -import org.junit.runners.Parameterized - -/** - * Test Pip launch. - * To run this test: `atest WMShellFlickerTests:PipToAppTest` - */ -@RequiresDevice -@RunWith(Parameterized::class) -@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -@Group3 -class PipToAppTest(testSpec: FlickerTestParameter) : PipTransition(testSpec) { - override val transition: FlickerBuilder.(Map) -> Unit - get() = buildTransition(eachRun = true) { configuration -> - setup { - eachRun { - this.setRotation(configuration.startRotation) - } - } - teardown { - eachRun { - this.setRotation(Surface.ROTATION_0) - } - } - transitions { - pipApp.expandPipWindowToApp(wmHelper) - } - } - - @FlakyTest - @Test - fun appReplacesPipWindow() { - testSpec.assertWm { - this.invoke("hasPipWindow") { it.isPinned(pipApp.component) } - .isAppWindowOnTop(pipApp.component) - .then() - .invoke("hasNotPipWindow") { it.isNotPinned(pipApp.component) } - .isAppWindowOnTop(pipApp.component) - } - } - - @FlakyTest - @Test - fun appReplacesPipLayer() { - testSpec.assertLayers { - this.isVisible(pipApp.component) - .isVisible(LAUNCHER_COMPONENT) - .then() - .isVisible(pipApp.component) - .isInvisible(LAUNCHER_COMPONENT) - } - } - - @FlakyTest - @Test - fun testAppCoversFullScreen() { - testSpec.assertLayersStart { - visibleRegion(pipApp.component).coversExactly(displayBounds) - } - } - - @FlakyTest(bugId = 151179149) - @Test - fun focusChanges() { - testSpec.assertEventLog { - this.focusChanges("NexusLauncherActivity", - pipApp.launcherName, "NexusLauncherActivity") - } - } - - companion object { - @Parameterized.Parameters(name = "{0}") - @JvmStatic - fun getParams(): List { - return FlickerTestParameterFactory.getInstance() - .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0), - repetitions = 5) - } - } -}