diff options
10 files changed, 664 insertions, 477 deletions
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTest.kt deleted file mode 100644 index 5d07f4ba8d4d..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTest.kt +++ /dev/null @@ -1,227 +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.apppairs - -import android.os.SystemClock -import android.platform.test.annotations.Presubmit -import android.view.Surface -import androidx.test.filters.RequiresDevice -import com.android.server.wm.flicker.dsl.FlickerBuilder -import com.android.server.wm.flicker.dsl.runWithFlicker -import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen -import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible -import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible -import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible -import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible -import com.android.server.wm.flicker.traces.layers.getVisibleBounds -import com.android.wm.shell.flicker.appPairsDividerIsInvisible -import com.android.wm.shell.flicker.appPairsDividerIsVisible -import com.android.wm.shell.flicker.helpers.AppPairsHelper -import com.android.wm.shell.flicker.helpers.AppPairsHelper.Companion.TEST_REPETITIONS -import org.junit.FixMethodOrder -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.MethodSorters -import org.junit.runners.Parameterized - -/** - * Test AppPairs launch. - * To run this test: `atest WMShellFlickerTests:AppPairsTest` - */ -@Presubmit -@RequiresDevice -@RunWith(Parameterized::class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -class AppPairsTest( - rotationName: String, - rotation: Int -) : AppPairsTestBase(rotationName, rotation) { - private val appPairsSetup: FlickerBuilder - get() = FlickerBuilder(instrumentation).apply { - val testLaunchActivity = "launch_appPairs_primary_secondary_activities" - withTestName { - testLaunchActivity - } - setup { - eachRun { - uiDevice.wakeUpAndGoToHomeScreen() - primaryApp.launchViaIntent() - secondaryApp.launchViaIntent() - nonResizeableApp.launchViaIntent() - updateTasksId() - } - } - teardown { - eachRun { - executeShellCommand(composePairsCommand( - primaryTaskId, secondaryTaskId, false /* pair */)) - executeShellCommand(composePairsCommand( - primaryTaskId, nonResizeableTaskId, false /* pair */)) - primaryApp.exit() - secondaryApp.exit() - nonResizeableApp.exit() - } - } - assertions { - layersTrace { - navBarLayerIsAlwaysVisible() - statusBarLayerIsAlwaysVisible() - } - windowManagerTrace { - navBarWindowIsAlwaysVisible() - statusBarWindowIsAlwaysVisible() - } - } - } - - @Test - fun testAppPairs_pairPrimaryAndSecondaryApps() { - val testTag = "testAppPairs_pairPrimaryAndSecondaryApps" - runWithFlicker(appPairsSetup) { - withTestName { testTag } - repeat { - TEST_REPETITIONS - } - transitions { - // TODO pair apps through normal UX flow - executeShellCommand(composePairsCommand( - primaryTaskId, secondaryTaskId, true /* pair */)) - SystemClock.sleep(AppPairsHelper.TIMEOUT_MS) - } - assertions { - layersTrace { - appPairsDividerIsVisible() - end("appsEndingBounds", enabled = false) { - val entry = this.trace.entries.firstOrNull() - ?: throw IllegalStateException("Trace is empty") - val dividerRegion = entry.getVisibleBounds(APP_PAIR_SPLIT_DIVIDER) - this.hasVisibleRegion(primaryApp.defaultWindowName, - appPairsHelper.getPrimaryBounds(dividerRegion)) - .hasVisibleRegion(secondaryApp.defaultWindowName, - appPairsHelper.getSecondaryBounds(dividerRegion)) - } - } - windowManagerTrace { - end { - showsAppWindow(primaryApp.defaultWindowName) - .showsAppWindow(secondaryApp.defaultWindowName) - } - } - } - } - } - - @Test - fun testAppPairs_unpairPrimaryAndSecondary() { - val testTag = "testAppPairs_unpairPrimaryAndSecondary" - runWithFlicker(appPairsSetup) { - withTestName { testTag } - repeat { - TEST_REPETITIONS - } - setup { - executeShellCommand(composePairsCommand( - primaryTaskId, secondaryTaskId, true /* pair */)) - SystemClock.sleep(AppPairsHelper.TIMEOUT_MS) - } - transitions { - // TODO pair apps through normal UX flow - executeShellCommand(composePairsCommand( - primaryTaskId, secondaryTaskId, false /* pair */)) - SystemClock.sleep(AppPairsHelper.TIMEOUT_MS) - } - assertions { - layersTrace { - appPairsDividerIsInvisible() - start("appsStartingBounds", enabled = false) { - val entry = this.trace.entries.firstOrNull() - ?: throw IllegalStateException("Trace is empty") - val dividerRegion = entry.getVisibleBounds(APP_PAIR_SPLIT_DIVIDER) - this.hasVisibleRegion(primaryApp.defaultWindowName, - appPairsHelper.getPrimaryBounds(dividerRegion)) - .hasVisibleRegion(secondaryApp.defaultWindowName, - appPairsHelper.getSecondaryBounds(dividerRegion)) - } - end("appsEndingBounds", enabled = false) { - this.hasNotLayer(primaryApp.defaultWindowName) - .hasNotLayer(secondaryApp.defaultWindowName) - } - } - windowManagerTrace { - end { - hidesAppWindow(primaryApp.defaultWindowName) - .hidesAppWindow(secondaryApp.defaultWindowName) - } - } - } - } - } - - @Test - fun testAppPairs_canNotPairNonResizeableApps() { - val testTag = "testAppPairs_canNotPairNonResizeableApps" - runWithFlicker(appPairsSetup) { - withTestName { testTag } - repeat { - TEST_REPETITIONS - } - transitions { - // TODO pair apps through normal UX flow - executeShellCommand(composePairsCommand( - primaryTaskId, nonResizeableTaskId, true /* pair */)) - SystemClock.sleep(AppPairsHelper.TIMEOUT_MS) - } - - assertions { - layersTrace { - appPairsDividerIsInvisible() - } - windowManagerTrace { - end { - showsAppWindow(nonResizeableApp.defaultWindowName) - .hidesAppWindow(primaryApp.defaultWindowName) - } - } - } - } - } - - fun updateTasksId() { - if (primaryAppComponent != null) { - primaryTaskId = getTaskIdForActivity( - primaryAppComponent.packageName, primaryAppComponent.className).toString() - } - if (secondaryAppComponent != null) { - secondaryTaskId = getTaskIdForActivity( - secondaryAppComponent.packageName, secondaryAppComponent.className).toString() - } - if (nonResizeableAppComponent != null) { - nonResizeableTaskId = getTaskIdForActivity( - nonResizeableAppComponent.packageName, - nonResizeableAppComponent.className).toString() - } - } - - 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) } - } - } -}
\ No newline at end of file diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestBase.kt deleted file mode 100644 index 35db7978efb7..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestBase.kt +++ /dev/null @@ -1,84 +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.apppairs - -import android.system.helpers.ActivityHelper -import android.util.Log -import com.android.compatibility.common.util.SystemUtil -import com.android.wm.shell.flicker.NonRotationTestBase -import com.android.wm.shell.flicker.TEST_APP_NONRESIZEABLE_LABEL -import com.android.wm.shell.flicker.TEST_APP_SPLITSCREEN_PRIMARY_LABEL -import com.android.wm.shell.flicker.TEST_APP_SPLITSCREEN_SECONDARY_LABEL -import com.android.wm.shell.flicker.helpers.AppPairsHelper -import com.android.wm.shell.flicker.helpers.SplitScreenHelper -import com.android.wm.shell.flicker.testapp.Components -import java.io.IOException - -abstract class AppPairsTestBase( - rotationName: String, - rotation: Int -) : NonRotationTestBase(rotationName, rotation) { - val activityHelper = ActivityHelper.getInstance() - - val appPairsHelper = AppPairsHelper(instrumentation, - TEST_APP_SPLITSCREEN_PRIMARY_LABEL, - Components.SplitScreenActivity()) - val primaryApp = SplitScreenHelper(instrumentation, - TEST_APP_SPLITSCREEN_PRIMARY_LABEL, - Components.SplitScreenActivity()) - val secondaryApp = SplitScreenHelper(instrumentation, - TEST_APP_SPLITSCREEN_SECONDARY_LABEL, - Components.SplitScreenSecondaryActivity()) - val nonResizeableApp = SplitScreenHelper(instrumentation, - TEST_APP_NONRESIZEABLE_LABEL, - Components.NonResizeableActivity()) - - val primaryAppComponent = primaryApp.openAppIntent.component - val secondaryAppComponent = secondaryApp.openAppIntent.component - val nonResizeableAppComponent = nonResizeableApp.openAppIntent.component - - var primaryTaskId = "" - var secondaryTaskId = "" - var nonResizeableTaskId = "" - - fun composePairsCommand( - primaryApp: String, - secondaryApp: String, - pair: Boolean - ): String = buildString { - // dumpsys activity service SystemUIService WMShell {pair|unpair} ${TASK_ID_1} ${TASK_ID_2} - append("dumpsys activity service SystemUIService WMShell ") - if (pair) { - append("pair ") - } else { - append("unpair ") - } - append(primaryApp + " " + secondaryApp) - } - - fun executeShellCommand(cmd: String) { - try { - SystemUtil.runShellCommand(instrumentation, cmd) - } catch (e: IOException) { - Log.d("AppPairsTest", "executeShellCommand error!" + e) - } - } - - fun getTaskIdForActivity(pkgName: String, activityName: String): Int { - return activityHelper.getTaskIdForActivity(pkgName, activityName) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestCannotPairNonResizeableApps.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestCannotPairNonResizeableApps.kt new file mode 100644 index 000000000000..b5d5d0fe8a38 --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestCannotPairNonResizeableApps.kt @@ -0,0 +1,91 @@ +/* + * 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.apppairs + +import android.os.Bundle +import android.platform.test.annotations.Presubmit +import android.os.SystemClock +import androidx.test.filters.RequiresDevice +import androidx.test.platform.app.InstrumentationRegistry +import com.android.server.wm.flicker.Flicker +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.buildTestTag +import com.android.wm.shell.flicker.helpers.AppPairsHelper +import com.android.wm.shell.flicker.appPairsDividerIsInvisible +import org.junit.FixMethodOrder +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test AppPairs launch. + * To run this test: `atest WMShellFlickerTests:AppPairsTest` + */ +/** + * Test cold launch app from launcher. + * To run this test: `atest WMShellFlickerTests:AppPairsTestCannotPairNonResizeableApps` + */ +@Presubmit +@RequiresDevice +@RunWith(Parameterized::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +class AppPairsTestCannotPairNonResizeableApps( + testName: String, + flickerProvider: () -> Flicker, + cleanUp: Boolean +) : FlickerTestRunner(testName, flickerProvider, cleanUp) { + companion object : AppPairsTransition(InstrumentationRegistry.getInstrumentation()) { + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): List<Array<Any>> { + val testTag = "testAppPairs_unpairPrimaryAndSecondaryApps" + val testSpec: FlickerBuilder.(Bundle) -> Unit = { configuration -> + withTestName { + buildTestTag(testTag, configuration) + } + transitions { + nonResizeableApp?.launchViaIntent(wmHelper) + // TODO pair apps through normal UX flow + executeShellCommand( + composePairsCommand(primaryTaskId, nonResizeableTaskId, pair = true)) + SystemClock.sleep(AppPairsHelper.TIMEOUT_MS) + } + assertions { + layersTrace { + appPairsDividerIsInvisible() + } + windowManagerTrace { + end { + val nonResizeableApp = nonResizeableApp + require(nonResizeableApp != null) { + "Non resizeable app not initialized" + } + isVisible(nonResizeableApp.defaultWindowName) + isInvisible(primaryApp.defaultWindowName) + } + } + } + } + + return FlickerTestRunnerFactory(instrumentation, + repetitions = AppPairsHelper.TEST_REPETITIONS) + .buildTest(transition, testSpec) + } + } +}
\ No newline at end of file diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestPairPrimaryAndSecondaryApps.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestPairPrimaryAndSecondaryApps.kt new file mode 100644 index 000000000000..54e074c9c25d --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestPairPrimaryAndSecondaryApps.kt @@ -0,0 +1,90 @@ +/* + * 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.apppairs + +import android.os.Bundle +import android.os.SystemClock +import android.platform.test.annotations.Presubmit +import androidx.test.filters.RequiresDevice +import androidx.test.platform.app.InstrumentationRegistry +import com.android.server.wm.flicker.Flicker +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.buildTestTag +import com.android.server.wm.flicker.traces.layers.getVisibleBounds +import com.android.wm.shell.flicker.FlickerTestBase +import com.android.wm.shell.flicker.appPairsDividerIsVisible +import com.android.wm.shell.flicker.helpers.AppPairsHelper +import org.junit.FixMethodOrder +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test cold launch app from launcher. + * To run this test: `atest WMShellFlickerTests:AppPairsTestPairPrimaryAndSecondaryApps` + */ +@Presubmit +@RequiresDevice +@RunWith(Parameterized::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +class AppPairsTestPairPrimaryAndSecondaryApps( + testName: String, + flickerProvider: () -> Flicker, + cleanUp: Boolean +) : FlickerTestRunner(testName, flickerProvider, cleanUp) { + companion object : AppPairsTransition(InstrumentationRegistry.getInstrumentation()) { + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): List<Array<Any>> { + val testTag = "testAppPairs_pairPrimaryAndSecondaryApps" + val testSpec: FlickerBuilder.(Bundle) -> Unit = { configuration -> + withTestName { + buildTestTag(testTag, configuration) + } + transitions { + // TODO pair apps through normal UX flow + executeShellCommand( + composePairsCommand(primaryTaskId, secondaryTaskId, pair = true)) + SystemClock.sleep(AppPairsHelper.TIMEOUT_MS) + } + assertions { + layersTrace { + appPairsDividerIsVisible() + end("appsEndingBounds", enabled = false) { + val dividerRegion = entry.getVisibleBounds( + FlickerTestBase.APP_PAIR_SPLIT_DIVIDER) + this.hasVisibleRegion(primaryApp.defaultWindowName, + appPairsHelper.getPrimaryBounds(dividerRegion)) + .hasVisibleRegion(secondaryApp.defaultWindowName, + appPairsHelper.getSecondaryBounds(dividerRegion)) + } + } + windowManagerTrace { + end { + isVisible(primaryApp.defaultWindowName) + isVisible(secondaryApp.defaultWindowName) + } + } + } + } + return FlickerTestRunnerFactory(instrumentation, + repetitions = AppPairsHelper.TEST_REPETITIONS).buildTest(transition, testSpec) + } + } +} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestUnpairPrimaryAndSecondaryApps.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestUnpairPrimaryAndSecondaryApps.kt new file mode 100644 index 000000000000..854a5041f631 --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestUnpairPrimaryAndSecondaryApps.kt @@ -0,0 +1,99 @@ +/* + * 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.apppairs + +import android.os.Bundle +import android.os.SystemClock +import android.platform.test.annotations.Presubmit +import androidx.test.filters.RequiresDevice +import androidx.test.platform.app.InstrumentationRegistry +import com.android.server.wm.flicker.Flicker +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.buildTestTag +import com.android.server.wm.flicker.traces.layers.getVisibleBounds +import com.android.wm.shell.flicker.FlickerTestBase +import com.android.wm.shell.flicker.appPairsDividerIsInvisible +import com.android.wm.shell.flicker.helpers.AppPairsHelper +import org.junit.FixMethodOrder +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test cold launch app from launcher. + * To run this test: `atest WMShellFlickerTests:AppPairsTestUnpairPrimaryAndSecondaryApps` + */ +@Presubmit +@RequiresDevice +@RunWith(Parameterized::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +class AppPairsTestUnpairPrimaryAndSecondaryApps( + testName: String, + flickerProvider: () -> Flicker, + cleanUp: Boolean +) : FlickerTestRunner(testName, flickerProvider, cleanUp) { + companion object : AppPairsTransition(InstrumentationRegistry.getInstrumentation()) { + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): List<Array<Any>> { + val testTag = "testAppPairs_unpairPrimaryAndSecondaryApps" + val testSpec: FlickerBuilder.(Bundle) -> Unit = { configuration -> + withTestName { + buildTestTag(testTag, configuration) + } + setup { + executeShellCommand( + composePairsCommand(primaryTaskId, secondaryTaskId, pair = true)) + SystemClock.sleep(AppPairsHelper.TIMEOUT_MS) + } + transitions { + // TODO pair apps through normal UX flow + executeShellCommand( + composePairsCommand(primaryTaskId, secondaryTaskId, pair = false)) + SystemClock.sleep(AppPairsHelper.TIMEOUT_MS) + } + assertions { + layersTrace { + appPairsDividerIsInvisible() + start("appsStartingBounds", enabled = false) { + val dividerRegion = entry.getVisibleBounds( + FlickerTestBase.APP_PAIR_SPLIT_DIVIDER) + this.hasVisibleRegion(primaryApp.defaultWindowName, + appPairsHelper.getPrimaryBounds(dividerRegion)) + .hasVisibleRegion(secondaryApp.defaultWindowName, + appPairsHelper.getSecondaryBounds(dividerRegion)) + } + end("appsEndingBounds", enabled = false) { + this.notExists(primaryApp.defaultWindowName) + .notExists(secondaryApp.defaultWindowName) + } + } + windowManagerTrace { + end { + isInvisible(primaryApp.defaultWindowName) + isInvisible(secondaryApp.defaultWindowName) + } + } + } + } + return FlickerTestRunnerFactory(instrumentation, + repetitions = AppPairsHelper.TEST_REPETITIONS).buildTest(transition, testSpec) + } + } +} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTransition.kt new file mode 100644 index 000000000000..78a938aef69e --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTransition.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.apppairs + +import android.app.Instrumentation +import android.os.Bundle +import android.system.helpers.ActivityHelper +import android.util.Log +import com.android.compatibility.common.util.SystemUtil +import com.android.server.wm.flicker.dsl.FlickerBuilder +import com.android.server.wm.flicker.helpers.setRotation +import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen +import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible +import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible +import com.android.server.wm.flicker.startRotation +import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible +import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible +import com.android.wm.shell.flicker.helpers.AppPairsHelper +import com.android.wm.shell.flicker.helpers.SplitScreenHelper +import com.android.wm.shell.flicker.testapp.Components +import java.io.IOException + +open class AppPairsTransition( + protected val instrumentation: Instrumentation +) { + internal val activityHelper = ActivityHelper.getInstance() + + internal val appPairsHelper = AppPairsHelper(instrumentation, + Components.SplitScreenActivity.LABEL, + Components.SplitScreenActivity.COMPONENT) + + internal val primaryApp = SplitScreenHelper.getPrimary(instrumentation) + internal val secondaryApp = SplitScreenHelper.getSecondary(instrumentation) + internal open val nonResizeableApp: SplitScreenHelper? = + SplitScreenHelper.getNonResizeable(instrumentation) + internal var primaryTaskId = "" + internal var secondaryTaskId = "" + internal var nonResizeableTaskId = "" + + internal open val transition: FlickerBuilder.(Bundle) -> Unit + get() = { configuration -> + setup { + test { + device.wakeUpAndGoToHomeScreen() + } + eachRun { + this.setRotation(configuration.startRotation) + primaryApp.launchViaIntent(wmHelper) + secondaryApp.launchViaIntent(wmHelper) + nonResizeableApp?.launchViaIntent(wmHelper) + updateTasksId() + } + } + teardown { + eachRun { + executeShellCommand(composePairsCommand( + primaryTaskId, secondaryTaskId, pair = false)) + executeShellCommand(composePairsCommand( + primaryTaskId, nonResizeableTaskId, pair = false)) + primaryApp.exit() + secondaryApp.exit() + nonResizeableApp?.exit() + } + } + + assertions { + layersTrace { + navBarLayerIsAlwaysVisible() + statusBarLayerIsAlwaysVisible() + } + windowManagerTrace { + navBarWindowIsAlwaysVisible() + statusBarWindowIsAlwaysVisible() + } + } + } + + protected fun updateTasksId() { + primaryTaskId = getTaskIdForActivity( + primaryApp.component.packageName, primaryApp.component.className).toString() + secondaryTaskId = getTaskIdForActivity( + secondaryApp.component.packageName, secondaryApp.component.className).toString() + val nonResizeableApp = nonResizeableApp + if (nonResizeableApp != null) { + nonResizeableTaskId = getTaskIdForActivity( + nonResizeableApp.component.packageName, + nonResizeableApp.component.className).toString() + } + } + + private fun getTaskIdForActivity(pkgName: String, activityName: String): Int { + return activityHelper.getTaskIdForActivity(pkgName, activityName) + } + + internal fun executeShellCommand(cmd: String) { + try { + SystemUtil.runShellCommand(instrumentation, cmd) + } catch (e: IOException) { + Log.d("AppPairsTest", "executeShellCommand error! $e") + } + } + + internal fun composePairsCommand( + primaryApp: String, + secondaryApp: String, + pair: Boolean + ): String = buildString { + // dumpsys activity service SystemUIService WMShell {pair|unpair} ${TASK_ID_1} ${TASK_ID_2} + append("dumpsys activity service SystemUIService WMShell ") + if (pair) { + append("pair ") + } else { + append("unpair ") + } + append("$primaryApp $secondaryApp") + } +}
\ No newline at end of file diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppTest.kt deleted file mode 100644 index 55359d7a1716..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppTest.kt +++ /dev/null @@ -1,166 +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.apppairs - -import android.os.SystemClock -import android.view.Surface -import androidx.test.filters.RequiresDevice -import com.android.server.wm.flicker.dsl.FlickerBuilder -import com.android.server.wm.flicker.dsl.runWithFlicker -import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen -import com.android.server.wm.flicker.navBarLayerRotatesAndScales -import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible -import com.android.server.wm.flicker.statusBarLayerRotatesScales -import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible -import com.android.wm.shell.flicker.appPairsDividerIsVisible -import com.android.wm.shell.flicker.appPairsPrimaryBoundsIsVisible -import com.android.wm.shell.flicker.appPairsSecondaryBoundsIsVisible -import com.android.wm.shell.flicker.helpers.AppPairsHelper -import com.android.wm.shell.flicker.helpers.SplitScreenHelper -import org.junit.FixMethodOrder -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.MethodSorters -import org.junit.runners.Parameterized - -/** - * Test open apps to app pairs and rotate. - * To run this test: `atest WMShellFlickerTests:RotateTwoLaunchedAppTest` - */ -@RequiresDevice -@RunWith(Parameterized::class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -class RotateTwoLaunchedAppTest( - rotationName: String, - rotation: Int -) : AppPairsTestBase(rotationName, rotation) { - private val appPairsRotationSetup: FlickerBuilder - get() = FlickerBuilder(instrumentation).apply { - val testSetupRotation = "testSetupRotation" - withTestName { - testSetupRotation - } - setup { - test { - uiDevice.wakeUpAndGoToHomeScreen() - primaryApp.launchViaIntent() - secondaryApp.launchViaIntent() - updateTasksId() - } - } - teardown { - eachRun { - executeShellCommand(composePairsCommand( - primaryTaskId, secondaryTaskId, false /* pair */)) - primaryApp.exit() - secondaryApp.exit() - } - } - } - - @Test - fun testRotateInAppPairsMode() { - val testTag = "testRotateInAppPairsMode" - runWithFlicker(appPairsRotationSetup) { - withTestName { testTag } - repeat { - SplitScreenHelper.TEST_REPETITIONS - } - transitions { - executeShellCommand(composePairsCommand( - primaryTaskId, secondaryTaskId, true /* pair */)) - SystemClock.sleep(AppPairsHelper.TIMEOUT_MS) - setRotation(rotation) - } - assertions { - layersTrace { - navBarLayerRotatesAndScales(Surface.ROTATION_0, rotation) - statusBarLayerRotatesScales(Surface.ROTATION_0, rotation) - appPairsDividerIsVisible() - appPairsPrimaryBoundsIsVisible( - rotation, primaryApp.defaultWindowName, 172776659) - appPairsSecondaryBoundsIsVisible( - rotation, secondaryApp.defaultWindowName, 172776659) - } - windowManagerTrace { - navBarWindowIsAlwaysVisible() - statusBarWindowIsAlwaysVisible() - end { - showsAppWindow(primaryApp.defaultWindowName) - .showsAppWindow(secondaryApp.defaultWindowName) - } - } - } - } - } - - @Test - fun testRotateAndEnterAppPairsMode() { - val testTag = "testRotateAndEnterAppPairsMode" - runWithFlicker(appPairsRotationSetup) { - withTestName { testTag } - repeat { - SplitScreenHelper.TEST_REPETITIONS - } - transitions { - setRotation(rotation) - executeShellCommand(composePairsCommand( - primaryTaskId, secondaryTaskId, true /* pair */)) - SystemClock.sleep(AppPairsHelper.TIMEOUT_MS) - } - assertions { - layersTrace { - navBarLayerRotatesAndScales(Surface.ROTATION_0, rotation) - statusBarLayerRotatesScales(Surface.ROTATION_0, rotation) - appPairsDividerIsVisible() - appPairsPrimaryBoundsIsVisible( - rotation, primaryApp.defaultWindowName, 172776659) - appPairsSecondaryBoundsIsVisible( - rotation, secondaryApp.defaultWindowName, 172776659) - } - windowManagerTrace { - navBarWindowIsAlwaysVisible() - statusBarWindowIsAlwaysVisible() - end { - showsAppWindow(primaryApp.defaultWindowName) - .showsAppWindow(secondaryApp.defaultWindowName) - } - } - } - } - } - - fun updateTasksId() { - if (primaryAppComponent != null) { - primaryTaskId = getTaskIdForActivity( - primaryAppComponent.packageName, primaryAppComponent.className).toString() - } - if (secondaryAppComponent != null) { - secondaryTaskId = getTaskIdForActivity( - secondaryAppComponent.packageName, secondaryAppComponent.className).toString() - } - } - - companion object { - @Parameterized.Parameters(name = "{0}") - @JvmStatic - fun getParams(): Collection<Array<Any>> { - val supportedRotations = intArrayOf(Surface.ROTATION_90, Surface.ROTATION_270) - return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) } - } - } -}
\ No newline at end of file diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppsInAppPairsMode.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppsInAppPairsMode.kt new file mode 100644 index 000000000000..32ffd80a2741 --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppsInAppPairsMode.kt @@ -0,0 +1,100 @@ +/* + * 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.apppairs + +import android.os.Bundle +import android.os.SystemClock +import android.view.Surface +import androidx.test.filters.RequiresDevice +import androidx.test.platform.app.InstrumentationRegistry +import com.android.server.wm.flicker.Flicker +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.endRotation +import com.android.server.wm.flicker.helpers.buildTestTag +import com.android.server.wm.flicker.helpers.setRotation +import com.android.server.wm.flicker.navBarLayerRotatesAndScales +import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible +import com.android.server.wm.flicker.statusBarLayerRotatesScales +import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible +import com.android.wm.shell.flicker.appPairsDividerIsVisible +import com.android.wm.shell.flicker.appPairsPrimaryBoundsIsVisible +import com.android.wm.shell.flicker.appPairsSecondaryBoundsIsVisible +import com.android.wm.shell.flicker.helpers.AppPairsHelper +import com.android.wm.shell.flicker.helpers.SplitScreenHelper +import org.junit.FixMethodOrder +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test open apps to app pairs and rotate. + * To run this test: `atest WMShellFlickerTests:RotateTwoLaunchedAppsInAppPairsMode` + */ +@RequiresDevice +@RunWith(Parameterized::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +class RotateTwoLaunchedAppsInAppPairsMode( + testName: String, + flickerProvider: () -> Flicker, + cleanUp: Boolean +) : FlickerTestRunner(testName, flickerProvider, cleanUp) { + companion object : RotateTwoLaunchedAppsTransition( + InstrumentationRegistry.getInstrumentation()) { + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): Collection<Array<Any>> { + val instrumentation = InstrumentationRegistry.getInstrumentation() + val testSpec: FlickerBuilder.(Bundle) -> Unit = { configuration -> + withTestName { + buildTestTag("testRotateAndEnterAppPairsMode", configuration) + } + transitions { + executeShellCommand(composePairsCommand( + primaryTaskId, secondaryTaskId, true /* pair */)) + SystemClock.sleep(AppPairsHelper.TIMEOUT_MS) + setRotation(configuration.endRotation) + } + assertions { + layersTrace { + navBarLayerRotatesAndScales(Surface.ROTATION_0, configuration.endRotation) + statusBarLayerRotatesScales(Surface.ROTATION_0, configuration.endRotation) + appPairsDividerIsVisible() + appPairsPrimaryBoundsIsVisible(configuration.endRotation, + primaryApp.defaultWindowName, 172776659) + appPairsSecondaryBoundsIsVisible(configuration.endRotation, + secondaryApp.defaultWindowName, 172776659) + } + windowManagerTrace { + navBarWindowIsAlwaysVisible() + statusBarWindowIsAlwaysVisible() + end { + isVisible(primaryApp.defaultWindowName) + .isVisible(secondaryApp.defaultWindowName) + } + } + } + } + + return FlickerTestRunnerFactory(instrumentation, + repetitions = SplitScreenHelper.TEST_REPETITIONS, + supportedRotations = listOf(Surface.ROTATION_90, Surface.ROTATION_270) + ).buildTest(transition, testSpec) + } + } +}
\ No newline at end of file diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppsRotateAndEnterAppPairsMode.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppsRotateAndEnterAppPairsMode.kt new file mode 100644 index 000000000000..5820e78c897b --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppsRotateAndEnterAppPairsMode.kt @@ -0,0 +1,100 @@ +/* + * 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.apppairs + +import android.os.Bundle +import android.os.SystemClock +import android.view.Surface +import androidx.test.filters.RequiresDevice +import androidx.test.platform.app.InstrumentationRegistry +import com.android.server.wm.flicker.Flicker +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.endRotation +import com.android.server.wm.flicker.helpers.buildTestTag +import com.android.server.wm.flicker.helpers.setRotation +import com.android.server.wm.flicker.navBarLayerRotatesAndScales +import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible +import com.android.server.wm.flicker.statusBarLayerRotatesScales +import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible +import com.android.wm.shell.flicker.appPairsDividerIsVisible +import com.android.wm.shell.flicker.appPairsPrimaryBoundsIsVisible +import com.android.wm.shell.flicker.appPairsSecondaryBoundsIsVisible +import com.android.wm.shell.flicker.helpers.AppPairsHelper +import com.android.wm.shell.flicker.helpers.SplitScreenHelper +import org.junit.FixMethodOrder +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test open apps to app pairs and rotate. + * To run this test: `atest WMShellFlickerTests:RotateTwoLaunchedAppsRotateAndEnterAppPairsMode` + */ +@RequiresDevice +@RunWith(Parameterized::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +class RotateTwoLaunchedAppsRotateAndEnterAppPairsMode( + testName: String, + flickerProvider: () -> Flicker, + cleanUp: Boolean +) : FlickerTestRunner(testName, flickerProvider, cleanUp) { + companion object : RotateTwoLaunchedAppsTransition( + InstrumentationRegistry.getInstrumentation()) { + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): Collection<Array<Any>> { + val instrumentation = InstrumentationRegistry.getInstrumentation() + val testSpec: FlickerBuilder.(Bundle) -> Unit = { configuration -> + withTestName { + buildTestTag("testRotateAndEnterAppPairsMode", configuration) + } + transitions { + this.setRotation(configuration.endRotation) + executeShellCommand( + composePairsCommand(primaryTaskId, secondaryTaskId, pair = true)) + SystemClock.sleep(AppPairsHelper.TIMEOUT_MS) + } + assertions { + layersTrace { + navBarLayerRotatesAndScales(Surface.ROTATION_0, configuration.endRotation) + statusBarLayerRotatesScales(Surface.ROTATION_0, configuration.endRotation) + appPairsDividerIsVisible() + appPairsPrimaryBoundsIsVisible(configuration.endRotation, + primaryApp.defaultWindowName, 172776659) + appPairsSecondaryBoundsIsVisible(configuration.endRotation, + secondaryApp.defaultWindowName, 172776659) + } + windowManagerTrace { + navBarWindowIsAlwaysVisible() + statusBarWindowIsAlwaysVisible() + end { + isVisible(primaryApp.defaultWindowName) + isVisible(secondaryApp.defaultWindowName) + } + } + } + } + + return FlickerTestRunnerFactory(instrumentation, + repetitions = SplitScreenHelper.TEST_REPETITIONS, + supportedRotations = listOf(Surface.ROTATION_90, Surface.ROTATION_270) + ).buildTest(transition, testSpec) + } + } +}
\ No newline at end of file diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppsTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppsTransition.kt new file mode 100644 index 000000000000..8ea2544fcf61 --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppsTransition.kt @@ -0,0 +1,53 @@ +/* + * 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.apppairs + +import android.app.Instrumentation +import android.os.Bundle +import android.view.Surface +import com.android.server.wm.flicker.dsl.FlickerBuilder +import com.android.server.wm.flicker.helpers.setRotation +import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen +import com.android.wm.shell.flicker.helpers.SplitScreenHelper + +open class RotateTwoLaunchedAppsTransition( + instrumentation: Instrumentation +) : AppPairsTransition(instrumentation) { + override val nonResizeableApp: SplitScreenHelper? + get() = null + + override val transition: FlickerBuilder.(Bundle) -> Unit + get() = { + setup { + test { + device.wakeUpAndGoToHomeScreen() + this.setRotation(Surface.ROTATION_0) + primaryApp.launchViaIntent() + secondaryApp.launchViaIntent() + updateTasksId() + } + } + teardown { + eachRun { + executeShellCommand(composePairsCommand( + primaryTaskId, secondaryTaskId, pair = false)) + primaryApp.exit() + secondaryApp.exit() + } + } + } +}
\ No newline at end of file |