From bbf561ac3a0de63003c976242b4cc9f31da0b28f Mon Sep 17 00:00:00 2001 From: Hongwei Wang Date: Wed, 12 Aug 2020 15:32:01 -0700 Subject: [PATCH] Add flicker test for WM Shell Separated folders in libs/WindowManager/Shell/tests - unittest, for unit tests - flicker, for this flicker tests - propose to add functional/ folder for functional tests Note also - Copied over EnterPipTest from existing flicker tests as proof of concept - TODO: need to figure out the next step for the flicker test library itself as it's currently packaged in com.android.server.wm Bug: 161561007 Test: atest WMShellFlickerTests Test: atest WMShellUnitTests Change-Id: Ic06e7cb0f98151591ccb9f5217260939349a9aa5 --- libs/WindowManager/Shell/tests/README.md | 15 ++ .../Shell/tests/flicker/Android.bp | 34 ++++ .../Shell/tests/flicker/AndroidManifest.xml | 43 +++++ .../Shell/tests/flicker/AndroidTest.xml | 40 +++++ .../Shell/tests/flicker/README.md | 10 ++ .../wm/shell/flicker/CommonAssertions.kt | 153 ++++++++++++++++++ .../wm/shell/flicker/FlickerTestBase.kt | 130 +++++++++++++++ .../wm/shell/flicker/NonRotationTestBase.kt | 36 +++++ .../shell/flicker/helpers/FlickerAppHelper.kt | 31 ++++ .../wm/shell/flicker/helpers/PipAppHelper.kt | 45 ++++++ .../wm/shell/flicker/pip/EnterPipTest.kt | 121 ++++++++++++++ .../wm/shell/flicker/pip/PipTestBase.kt} | 27 ++-- .../Shell/tests/flicker/test-apps/Android.bp | 0 .../flicker/test-apps/flickerapp/Android.bp | 20 +++ .../test-apps/flickerapp/AndroidManifest.xml | 37 +++++ .../flickerapp/res/layout/activity_pip.xml | 26 +++ .../wm/shell/flicker/testapp/PipActivity.java | 45 ++++++ .../Shell/tests/{ => unittest}/Android.bp | 2 +- .../tests/{ => unittest}/AndroidManifest.xml | 0 .../tests/{ => unittest}/AndroidTest.xml | 4 +- .../{ => unittest}/res/values/config.xml | 0 .../wm/shell/ShellTaskOrganizerTests.java | 0 .../wm/shell/common/DisplayLayoutTest.java | 0 23 files changed, 799 insertions(+), 20 deletions(-) create mode 100644 libs/WindowManager/Shell/tests/README.md create mode 100644 libs/WindowManager/Shell/tests/flicker/Android.bp create mode 100644 libs/WindowManager/Shell/tests/flicker/AndroidManifest.xml create mode 100644 libs/WindowManager/Shell/tests/flicker/AndroidTest.xml create mode 100644 libs/WindowManager/Shell/tests/flicker/README.md create mode 100644 libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt create mode 100644 libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/FlickerTestBase.kt create mode 100644 libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/NonRotationTestBase.kt create mode 100644 libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/FlickerAppHelper.kt create mode 100644 libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt create mode 100644 libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt rename libs/WindowManager/Shell/tests/{src/com/android/wm/shell/WindowManagerShellTest.java => flicker/src/com/android/wm/shell/flicker/pip/PipTestBase.kt} (60%) create mode 100644 libs/WindowManager/Shell/tests/flicker/test-apps/Android.bp create mode 100644 libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/Android.bp create mode 100644 libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml create mode 100644 libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_pip.xml create mode 100644 libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java rename libs/WindowManager/Shell/tests/{ => unittest}/Android.bp (96%) rename libs/WindowManager/Shell/tests/{ => unittest}/AndroidManifest.xml (100%) rename libs/WindowManager/Shell/tests/{ => unittest}/AndroidTest.xml (90%) rename libs/WindowManager/Shell/tests/{ => unittest}/res/values/config.xml (100%) rename libs/WindowManager/Shell/tests/{ => unittest}/src/com/android/wm/shell/ShellTaskOrganizerTests.java (100%) rename libs/WindowManager/Shell/tests/{ => unittest}/src/com/android/wm/shell/common/DisplayLayoutTest.java (100%) diff --git a/libs/WindowManager/Shell/tests/README.md b/libs/WindowManager/Shell/tests/README.md new file mode 100644 index 0000000000000..c19db76a358c8 --- /dev/null +++ b/libs/WindowManager/Shell/tests/README.md @@ -0,0 +1,15 @@ +# WM Shell Test + +This contains all tests written for WM (WindowManager) Shell and it's currently +divided into 3 categories + +- unittest, tests against individual functions, usually @SmallTest and do not + require UI automation nor real device to run +- integration, this maybe a mix of functional and integration tests. Contains + tests verify the WM Shell as a whole, like talking to WM core. This usually + involves mocking the window manager service or even talking to the real one. + Due to this nature, test cases in this package is normally annotated as + @LargeTest and runs with UI automation on real device +- flicker, similar to functional tests with its sole focus on flickerness. See + [WM Shell Flicker Test Package](http://cs/android/framework/base/libs/WindowManager/Shell/tests/flicker/) + for more details diff --git a/libs/WindowManager/Shell/tests/flicker/Android.bp b/libs/WindowManager/Shell/tests/flicker/Android.bp new file mode 100644 index 0000000000000..5879022218263 --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/Android.bp @@ -0,0 +1,34 @@ +// +// 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. +// + +android_test { + name: "WMShellFlickerTests", + srcs: ["src/**/*.java", "src/**/*.kt"], + manifest: "AndroidManifest.xml", + test_config: "AndroidTest.xml", + platform_apis: true, + certificate: "platform", + test_suites: ["device-tests"], + libs: ["android.test.runner"], + static_libs: [ + "androidx.test.ext.junit", + "flickerlib", + "truth-prebuilt", + "app-helpers-core", + "launcher-helper-lib", + "launcher-aosp-tapl" + ], +} diff --git a/libs/WindowManager/Shell/tests/flicker/AndroidManifest.xml b/libs/WindowManager/Shell/tests/flicker/AndroidManifest.xml new file mode 100644 index 0000000000000..8b2f6681554a4 --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/AndroidManifest.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/WindowManager/Shell/tests/flicker/AndroidTest.xml b/libs/WindowManager/Shell/tests/flicker/AndroidTest.xml new file mode 100644 index 0000000000000..526fc502c0fbd --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/AndroidTest.xml @@ -0,0 +1,40 @@ + + + + diff --git a/libs/WindowManager/Shell/tests/flicker/README.md b/libs/WindowManager/Shell/tests/flicker/README.md new file mode 100644 index 0000000000000..4502d498a65b9 --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/README.md @@ -0,0 +1,10 @@ +# WM Shell Flicker Test Package + +Please reference the following links + +- [Introduction to Flicker Test Library](http://cs/android/platform_testing/libraries/flicker/) +- [Flicker Test in frameworks/base](http://cs/android/frameworks/base/tests/FlickerTests/) + +on what is Flicker Test and how to write a Flicker Test + +To run the Flicker Tests for WM Shell, simply run `atest WMShellFlickerTests` 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 new file mode 100644 index 0000000000000..4ff2bfca3a4ae --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt @@ -0,0 +1,153 @@ +/* + * 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 + +import com.android.server.wm.flicker.dsl.EventLogAssertion +import com.android.server.wm.flicker.dsl.LayersAssertion +import com.android.server.wm.flicker.dsl.WmAssertion +import com.android.server.wm.flicker.helpers.WindowUtils + +@JvmOverloads +fun WmAssertion.statusBarWindowIsAlwaysVisible( + bugId: Int = 0, + enabled: Boolean = bugId == 0 +) { + all("statusBarWindowIsAlwaysVisible", enabled, bugId) { + this.showsAboveAppWindow(FlickerTestBase.STATUS_BAR_WINDOW_TITLE) + } +} + +@JvmOverloads +fun WmAssertion.navBarWindowIsAlwaysVisible( + bugId: Int = 0, + enabled: Boolean = bugId == 0 +) { + all("navBarWindowIsAlwaysVisible", enabled, bugId) { + this.showsAboveAppWindow(FlickerTestBase.NAVIGATION_BAR_WINDOW_TITLE) + } +} + +@JvmOverloads +fun LayersAssertion.noUncoveredRegions( + beginRotation: Int, + endRotation: Int = beginRotation, + allStates: Boolean = true, + bugId: Int = 0, + enabled: Boolean = bugId == 0 +) { + val startingBounds = WindowUtils.getDisplayBounds(beginRotation) + val endingBounds = WindowUtils.getDisplayBounds(endRotation) + if (allStates) { + all("noUncoveredRegions", enabled, bugId) { + if (startingBounds == endingBounds) { + this.coversAtLeastRegion(startingBounds) + } else { + this.coversAtLeastRegion(startingBounds) + .then() + .coversAtLeastRegion(endingBounds) + } + } + } else { + start("noUncoveredRegions_StartingPos") { + this.coversAtLeastRegion(startingBounds) + } + end("noUncoveredRegions_EndingPos") { + this.coversAtLeastRegion(endingBounds) + } + } +} + +@JvmOverloads +fun LayersAssertion.navBarLayerIsAlwaysVisible( + bugId: Int = 0, + enabled: Boolean = bugId == 0 +) { + all("navBarLayerIsAlwaysVisible", enabled, bugId) { + this.showsLayer(FlickerTestBase.NAVIGATION_BAR_WINDOW_TITLE) + } +} + +@JvmOverloads +fun LayersAssertion.statusBarLayerIsAlwaysVisible( + bugId: Int = 0, + enabled: Boolean = bugId == 0 +) { + all("statusBarLayerIsAlwaysVisible", enabled, bugId) { + this.showsLayer(FlickerTestBase.STATUS_BAR_WINDOW_TITLE) + } +} + +@JvmOverloads +fun LayersAssertion.navBarLayerRotatesAndScales( + beginRotation: Int, + endRotation: Int = beginRotation, + bugId: Int = 0, + enabled: Boolean = bugId == 0 +) { + val startingPos = WindowUtils.getNavigationBarPosition(beginRotation) + val endingPos = WindowUtils.getNavigationBarPosition(endRotation) + + start("navBarLayerRotatesAndScales_StartingPos", enabled, bugId) { + this.hasVisibleRegion(FlickerTestBase.NAVIGATION_BAR_WINDOW_TITLE, startingPos) + } + end("navBarLayerRotatesAndScales_EndingPost", enabled, bugId) { + this.hasVisibleRegion(FlickerTestBase.NAVIGATION_BAR_WINDOW_TITLE, endingPos) + } + + if (startingPos == endingPos) { + all("navBarLayerRotatesAndScales", enabled, bugId) { + this.hasVisibleRegion(FlickerTestBase.NAVIGATION_BAR_WINDOW_TITLE, startingPos) + } + } +} + +@JvmOverloads +fun LayersAssertion.statusBarLayerRotatesScales( + beginRotation: Int, + endRotation: Int = beginRotation, + bugId: Int = 0, + enabled: Boolean = bugId == 0 +) { + val startingPos = WindowUtils.getStatusBarPosition(beginRotation) + val endingPos = WindowUtils.getStatusBarPosition(endRotation) + + start("statusBarLayerRotatesScales_StartingPos", enabled, bugId) { + this.hasVisibleRegion(FlickerTestBase.STATUS_BAR_WINDOW_TITLE, startingPos) + } + end("statusBarLayerRotatesScales_EndingPos", enabled, bugId) { + this.hasVisibleRegion(FlickerTestBase.STATUS_BAR_WINDOW_TITLE, endingPos) + } +} + +fun EventLogAssertion.focusChanges( + vararg windows: String, + bugId: Int = 0, + enabled: Boolean = bugId == 0 +) { + all(enabled = enabled, bugId = bugId) { + this.focusChanges(windows) + } +} + +fun EventLogAssertion.focusDoesNotChange( + bugId: Int = 0, + enabled: Boolean = bugId == 0 +) { + all(enabled = enabled, bugId = bugId) { + this.focusDoesNotChange() + } +} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/FlickerTestBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/FlickerTestBase.kt new file mode 100644 index 0000000000000..99f824bb83419 --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/FlickerTestBase.kt @@ -0,0 +1,130 @@ +/* + * 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 + +import android.os.RemoteException +import android.os.SystemClock +import android.platform.helpers.IAppHelper +import android.view.Surface +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.uiautomator.UiDevice +import com.android.server.wm.flicker.Flicker + +/** + * Base class of all Flicker test that performs common functions for all flicker tests: + * + * + * - Caches transitions so that a transition is run once and the transition results are used by + * tests multiple times. This is needed for parameterized tests which call the BeforeClass methods + * multiple times. + * - Keeps track of all test artifacts and deletes ones which do not need to be reviewed. + * - Fails tests if results are not available for any test due to jank. + */ +abstract class FlickerTestBase { + val instrumentation by lazy { + InstrumentationRegistry.getInstrumentation() + } + val uiDevice by lazy { + UiDevice.getInstance(instrumentation) + } + + /** + * Build a test tag for the test + * @param testName Name of the transition(s) being tested + * @param app App being launcher + * @param rotation Initial screen rotation + * + * @return test tag with pattern ____ + */ + protected fun buildTestTag(testName: String, app: IAppHelper, rotation: Int): String { + return buildTestTag( + testName, app, rotation, rotation, app2 = null, extraInfo = "") + } + + /** + * Build a test tag for the test + * @param testName Name of the transition(s) being tested + * @param app App being launcher + * @param beginRotation Initial screen rotation + * @param endRotation End screen rotation (if any, otherwise use same as initial) + * + * @return test tag with pattern ____- + */ + protected fun buildTestTag( + testName: String, + app: IAppHelper, + beginRotation: Int, + endRotation: Int + ): String { + return buildTestTag( + testName, app, beginRotation, endRotation, app2 = null, extraInfo = "") + } + + /** + * Build a test tag for the test + * @param testName Name of the transition(s) being tested + * @param app App being launcher + * @param app2 Second app being launched (if any) + * @param beginRotation Initial screen rotation + * @param endRotation End screen rotation (if any, otherwise use same as initial) + * @param extraInfo Additional information to append to the tag + * + * @return test tag with pattern __(S)>__(S)>[__] + */ + protected fun buildTestTag( + testName: String, + app: IAppHelper, + beginRotation: Int, + endRotation: Int, + app2: IAppHelper?, + extraInfo: String + ): String { + var testTag = "${testName}__${app.launcherName}" + if (app2 != null) { + testTag += "-${app2.launcherName}" + } + testTag += "__${Surface.rotationToString(beginRotation)}" + if (endRotation != beginRotation) { + testTag += "-${Surface.rotationToString(endRotation)}" + } + if (extraInfo.isNotEmpty()) { + testTag += "__$extraInfo" + } + return testTag + } + + protected fun Flicker.setRotation(rotation: Int) { + try { + when (rotation) { + Surface.ROTATION_270 -> device.setOrientationLeft() + Surface.ROTATION_90 -> device.setOrientationRight() + Surface.ROTATION_0 -> device.setOrientationNatural() + else -> device.setOrientationNatural() + } + // Wait for animation to complete + SystemClock.sleep(1000) + } catch (e: RemoteException) { + throw RuntimeException(e) + } + } + + companion object { + const val NAVIGATION_BAR_WINDOW_TITLE = "NavigationBar" + const val STATUS_BAR_WINDOW_TITLE = "StatusBar" + const val DOCKED_STACK_DIVIDER = "DockedStackDivider" + } +} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/NonRotationTestBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/NonRotationTestBase.kt new file mode 100644 index 0000000000000..90334ae91e9d3 --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/NonRotationTestBase.kt @@ -0,0 +1,36 @@ +/* + * 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 + +import android.view.Surface +import org.junit.runners.Parameterized + +abstract class NonRotationTestBase( + protected val rotationName: String, + protected val rotation: Int +) : FlickerTestBase() { + companion object { + const val SCREENSHOT_LAYER = "RotationLayer" + + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): Collection> { + val supportedRotations = intArrayOf(Surface.ROTATION_0, Surface.ROTATION_90) + return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) } + } + } +} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/FlickerAppHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/FlickerAppHelper.kt new file mode 100644 index 0000000000000..308a36efef876 --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/FlickerAppHelper.kt @@ -0,0 +1,31 @@ +/* + * 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.helpers + +import android.app.Instrumentation +import android.support.test.launcherhelper.ILauncherStrategy +import com.android.server.wm.flicker.StandardAppHelper + +abstract class FlickerAppHelper( + instr: Instrumentation, + launcherName: String, + launcherStrategy: ILauncherStrategy +) : StandardAppHelper(instr, sFlickerPackage, launcherName, launcherStrategy) { + companion object { + var sFlickerPackage = "com.android.wm.shell.flicker.testapp" + } +} 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 new file mode 100644 index 0000000000000..539170202b8ad --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt @@ -0,0 +1,45 @@ +/* + * 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.helpers + +import android.app.Instrumentation +import android.support.test.launcherhelper.ILauncherStrategy +import android.support.test.launcherhelper.LauncherStrategyFactory +import androidx.test.uiautomator.By +import androidx.test.uiautomator.UiDevice +import com.android.server.wm.flicker.helpers.hasPipWindow +import com.android.server.wm.flicker.helpers.closePipWindow +import org.junit.Assert + +class PipAppHelper( + instr: Instrumentation, + launcherStrategy: ILauncherStrategy = LauncherStrategyFactory + .getInstance(instr) + .launcherStrategy +) : FlickerAppHelper(instr, "PipApp", launcherStrategy) { + fun clickEnterPipButton(device: UiDevice) { + val enterPipButton = device.findObject(By.res(getPackage(), "enter_pip")) + Assert.assertNotNull("Pip button not found, this usually happens when the device " + + "was left in an unknown state (e.g. in split screen)", enterPipButton) + enterPipButton.click() + device.hasPipWindow() + } + + fun closePipWindow(device: UiDevice) { + device.closePipWindow() + } +} 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 new file mode 100644 index 0000000000000..4b04449bdbc2b --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt @@ -0,0 +1,121 @@ +/* + * 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.LargeTest +import com.android.server.wm.flicker.dsl.flicker +import com.android.server.wm.flicker.helpers.closePipWindow +import com.android.server.wm.flicker.helpers.expandPipWindow +import com.android.server.wm.flicker.helpers.hasPipWindow +import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen +import com.android.wm.shell.flicker.navBarLayerIsAlwaysVisible +import com.android.wm.shell.flicker.navBarLayerRotatesAndScales +import com.android.wm.shell.flicker.navBarWindowIsAlwaysVisible +import com.android.wm.shell.flicker.noUncoveredRegions +import com.android.wm.shell.flicker.statusBarLayerIsAlwaysVisible +import com.android.wm.shell.flicker.statusBarLayerRotatesScales +import com.android.wm.shell.flicker.statusBarWindowIsAlwaysVisible +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 FlickerTests:PipToAppTest` + */ +@LargeTest +@RunWith(Parameterized::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@FlakyTest(bugId = 152738416) +class EnterPipTest( + rotationName: String, + rotation: Int +) : PipTestBase(rotationName, rotation) { + @Test + fun test() { + flicker(instrumentation) { + withTag { buildTestTag("enterPip", testApp, rotation) } + repeat { 1 } + setup { + test { + device.wakeUpAndGoToHomeScreen() + } + eachRun { + device.pressHome() + testApp.open() + this.setRotation(rotation) + } + } + teardown { + eachRun { + if (device.hasPipWindow()) { + device.closePipWindow() + } + testApp.exit() + this.setRotation(Surface.ROTATION_0) + } + test { + if (device.hasPipWindow()) { + device.closePipWindow() + } + } + } + transitions { + testApp.clickEnterPipButton(device) + device.expandPipWindow() + } + assertions { + windowManagerTrace { + navBarWindowIsAlwaysVisible() + statusBarWindowIsAlwaysVisible() + all("pipWindowBecomesVisible") { + this.showsAppWindow(testApp.`package`) + .then() + .showsAppWindow(sPipWindowTitle) + } + } + + layersTrace { + navBarLayerIsAlwaysVisible() + statusBarLayerIsAlwaysVisible() + noUncoveredRegions(rotation, Surface.ROTATION_0, allStates = false) + navBarLayerRotatesAndScales(rotation, Surface.ROTATION_0) + statusBarLayerRotatesScales(rotation, Surface.ROTATION_0) + + all("pipLayerBecomesVisible") { + this.showsLayer(testApp.launcherName) + .then() + .showsLayer(sPipWindowTitle) + } + } + } + } + } + + companion object { + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): Collection> { + val supportedRotations = intArrayOf(Surface.ROTATION_0) + return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) } + } + } +} diff --git a/libs/WindowManager/Shell/tests/src/com/android/wm/shell/WindowManagerShellTest.java b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTestBase.kt similarity index 60% rename from libs/WindowManager/Shell/tests/src/com/android/wm/shell/WindowManagerShellTest.java rename to libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTestBase.kt index f1ead3c8a4419..3822d69a65f50 100644 --- a/libs/WindowManager/Shell/tests/src/com/android/wm/shell/WindowManagerShellTest.java +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTestBase.kt @@ -14,25 +14,18 @@ * limitations under the License. */ -package com.android.wm.shell; +package com.android.wm.shell.flicker.pip -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.SmallTest; +import com.android.wm.shell.flicker.NonRotationTestBase +import com.android.wm.shell.flicker.helpers.PipAppHelper -import org.junit.Test; -import org.junit.runner.RunWith; +abstract class PipTestBase( + rotationName: String, + rotation: Int +) : NonRotationTestBase(rotationName, rotation) { + protected val testApp = PipAppHelper(instrumentation) -/** - * Tests for the shell. - */ -@SmallTest -@RunWith(AndroidJUnit4.class) -public class WindowManagerShellTest { - - WindowManagerShell mShell; - - @Test - public void testNothing() { - // Do nothing + companion object { + const val sPipWindowTitle = "PipMenuActivity" } } diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/Android.bp b/libs/WindowManager/Shell/tests/flicker/test-apps/Android.bp new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/Android.bp b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/Android.bp new file mode 100644 index 0000000000000..d12b492452774 --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/Android.bp @@ -0,0 +1,20 @@ +// 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. + +android_test { + name: "WMShellFlickerTestApp", + srcs: ["**/*.java"], + sdk_version: "current", + test_suites: ["device-tests"], +} diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml new file mode 100644 index 0000000000000..95dc1d48eee8e --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_pip.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_pip.xml new file mode 100644 index 0000000000000..e1870d9c523de --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_pip.xml @@ -0,0 +1,26 @@ + + + +