Loading libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt +34 −181 Original line number Diff line number Diff line Loading @@ -18,239 +18,92 @@ package com.android.wm.shell.flicker import android.graphics.Region import android.view.Surface import com.android.server.wm.flicker.dsl.LayersAssertionBuilder import com.android.server.wm.flicker.dsl.LayersAssertionBuilderLegacy import com.android.server.wm.flicker.APP_PAIR_SPLIT_DIVIDER import com.android.server.wm.flicker.DOCKED_STACK_DIVIDER import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.helpers.WindowUtils import com.android.server.wm.flicker.traces.layers.getVisibleBounds @JvmOverloads fun LayersAssertionBuilder.appPairsDividerIsVisible(bugId: Int = 0) { end("appPairsDividerIsVisible", bugId) { fun FlickerTestParameter.appPairsDividerIsVisible() { assertLayersEnd { this.isVisible(APP_PAIR_SPLIT_DIVIDER) } } @JvmOverloads fun LayersAssertionBuilder.appPairsDividerIsInvisible(bugId: Int = 0) { end("appPairsDividerIsInVisible", bugId) { fun FlickerTestParameter.appPairsDividerIsInvisible() { assertLayersEnd { this.notExists(APP_PAIR_SPLIT_DIVIDER) } } @JvmOverloads fun LayersAssertionBuilder.appPairsDividerBecomesVisible(bugId: Int = 0) { all("dividerLayerBecomesVisible", bugId) { fun FlickerTestParameter.appPairsDividerBecomesVisible() { assertLayers { this.hidesLayer(DOCKED_STACK_DIVIDER) .then() .showsLayer(DOCKED_STACK_DIVIDER) } } @JvmOverloads fun LayersAssertionBuilder.dockedStackDividerIsVisible(bugId: Int = 0) { end("dockedStackDividerIsVisible", bugId) { fun FlickerTestParameter.dockedStackDividerIsVisible() { assertLayersEnd { this.isVisible(DOCKED_STACK_DIVIDER) } } @JvmOverloads fun LayersAssertionBuilder.dockedStackDividerBecomesVisible(bugId: Int = 0) { all("dividerLayerBecomesVisible", bugId) { fun FlickerTestParameter.dockedStackDividerBecomesVisible() { assertLayers { this.hidesLayer(DOCKED_STACK_DIVIDER) .then() .showsLayer(DOCKED_STACK_DIVIDER) } } @JvmOverloads fun LayersAssertionBuilder.dockedStackDividerBecomesInvisible(bugId: Int = 0) { all("dividerLayerBecomesInvisible", bugId) { fun FlickerTestParameter.dockedStackDividerBecomesInvisible() { assertLayers { this.showsLayer(DOCKED_STACK_DIVIDER) .then() .hidesLayer(DOCKED_STACK_DIVIDER) } } @JvmOverloads fun LayersAssertionBuilder.dockedStackDividerIsInvisible(bugId: Int = 0) { end("dockedStackDividerIsInvisible", bugId) { fun FlickerTestParameter.dockedStackDividerIsInvisible() { assertLayersEnd { this.notExists(DOCKED_STACK_DIVIDER) } } @JvmOverloads fun LayersAssertionBuilder.appPairsPrimaryBoundsIsVisible( rotation: Int, primaryLayerName: String, bugId: Int = 0 ) { end("PrimaryAppBounds", bugId) { fun FlickerTestParameter.appPairsPrimaryBoundsIsVisible(rotation: Int, primaryLayerName: String) { assertLayersEnd { val dividerRegion = entry.getVisibleBounds(APP_PAIR_SPLIT_DIVIDER) this.hasVisibleRegion(primaryLayerName, getPrimaryRegion(dividerRegion, rotation)) } } @JvmOverloads fun LayersAssertionBuilder.appPairsSecondaryBoundsIsVisible( rotation: Int, secondaryLayerName: String, bugId: Int = 0 ) { end("SecondaryAppBounds", bugId) { val dividerRegion = entry.getVisibleBounds(APP_PAIR_SPLIT_DIVIDER) this.hasVisibleRegion(secondaryLayerName, getSecondaryRegion(dividerRegion, rotation)) } } @JvmOverloads fun LayersAssertionBuilder.dockedStackPrimaryBoundsIsVisible( fun FlickerTestParameter.dockedStackPrimaryBoundsIsVisible( rotation: Int, primaryLayerName: String, bugId: Int = 0 primaryLayerName: String ) { end("PrimaryAppBounds", bugId) { assertLayersEnd { val dividerRegion = entry.getVisibleBounds(DOCKED_STACK_DIVIDER) this.hasVisibleRegion(primaryLayerName, getPrimaryRegion(dividerRegion, rotation)) } } @JvmOverloads fun LayersAssertionBuilder.dockedStackSecondaryBoundsIsVisible( fun FlickerTestParameter.appPairsSecondaryBoundsIsVisible( rotation: Int, secondaryLayerName: String, bugId: Int = 0 ) { end("SecondaryAppBounds", bugId) { val dividerRegion = entry.getVisibleBounds(DOCKED_STACK_DIVIDER) this.hasVisibleRegion(secondaryLayerName, getSecondaryRegion(dividerRegion, rotation)) } } @JvmOverloads fun LayersAssertionBuilderLegacy.appPairsDividerIsVisible( bugId: Int = 0, enabled: Boolean = bugId == 0 ) { end("appPairsDividerIsVisible", bugId, enabled) { this.isVisible(APP_PAIR_SPLIT_DIVIDER) } } @JvmOverloads fun LayersAssertionBuilderLegacy.appPairsDividerIsInvisible( bugId: Int = 0, enabled: Boolean = bugId == 0 ) { end("appPairsDividerIsInVisible", bugId, enabled) { this.notExists(APP_PAIR_SPLIT_DIVIDER) } } @JvmOverloads fun LayersAssertionBuilderLegacy.appPairsDividerBecomesVisible( bugId: Int = 0, enabled: Boolean = bugId == 0 ) { all("dividerLayerBecomesVisible", bugId, enabled) { this.hidesLayer(DOCKED_STACK_DIVIDER) .then() .showsLayer(DOCKED_STACK_DIVIDER) } } @JvmOverloads fun LayersAssertionBuilderLegacy.dockedStackDividerIsVisible( bugId: Int = 0, enabled: Boolean = bugId == 0 secondaryLayerName: String ) { end("dockedStackDividerIsVisible", bugId, enabled) { this.isVisible(DOCKED_STACK_DIVIDER) } } @JvmOverloads fun LayersAssertionBuilderLegacy.dockedStackDividerBecomesVisible( bugId: Int = 0, enabled: Boolean = bugId == 0 ) { all("dividerLayerBecomesVisible", bugId, enabled) { this.hidesLayer(DOCKED_STACK_DIVIDER) .then() .showsLayer(DOCKED_STACK_DIVIDER) } } @JvmOverloads fun LayersAssertionBuilderLegacy.dockedStackDividerBecomesInvisible( bugId: Int = 0, enabled: Boolean = bugId == 0 ) { all("dividerLayerBecomesInvisible", bugId, enabled) { this.showsLayer(DOCKED_STACK_DIVIDER) .then() .hidesLayer(DOCKED_STACK_DIVIDER) } } @JvmOverloads fun LayersAssertionBuilderLegacy.dockedStackDividerIsInvisible( bugId: Int = 0, enabled: Boolean = bugId == 0 ) { end("dockedStackDividerIsInvisible", bugId, enabled) { this.notExists(DOCKED_STACK_DIVIDER) } } @JvmOverloads fun LayersAssertionBuilderLegacy.appPairsPrimaryBoundsIsVisible( rotation: Int, primaryLayerName: String, bugId: Int = 0, enabled: Boolean = bugId == 0 ) { end("PrimaryAppBounds", bugId, enabled) { val dividerRegion = entry.getVisibleBounds(APP_PAIR_SPLIT_DIVIDER) this.hasVisibleRegion(primaryLayerName, getPrimaryRegion(dividerRegion, rotation)) } } @JvmOverloads fun LayersAssertionBuilderLegacy.appPairsSecondaryBoundsIsVisible( rotation: Int, secondaryLayerName: String, bugId: Int = 0, enabled: Boolean = bugId == 0 ) { end("SecondaryAppBounds", bugId, enabled) { assertLayersEnd { val dividerRegion = entry.getVisibleBounds(APP_PAIR_SPLIT_DIVIDER) this.hasVisibleRegion(secondaryLayerName, getSecondaryRegion(dividerRegion, rotation)) } } @JvmOverloads fun LayersAssertionBuilderLegacy.dockedStackPrimaryBoundsIsVisible( rotation: Int, primaryLayerName: String, bugId: Int = 0, enabled: Boolean = bugId == 0 ) { end("PrimaryAppBounds", bugId, enabled) { val dividerRegion = entry.getVisibleBounds(DOCKED_STACK_DIVIDER) this.hasVisibleRegion(primaryLayerName, getPrimaryRegion(dividerRegion, rotation)) } } @JvmOverloads fun LayersAssertionBuilderLegacy.dockedStackSecondaryBoundsIsVisible( fun FlickerTestParameter.dockedStackSecondaryBoundsIsVisible( rotation: Int, secondaryLayerName: String, bugId: Int = 0, enabled: Boolean = bugId == 0 secondaryLayerName: String ) { end("SecondaryAppBounds", bugId, enabled) { assertLayersEnd { val dividerRegion = entry.getVisibleBounds(DOCKED_STACK_DIVIDER) this.hasVisibleRegion(secondaryLayerName, getSecondaryRegion(dividerRegion, rotation)) } Loading libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/FlickerTestBase.kt +15 −86 Original line number Diff line number Diff line Loading @@ -16,33 +16,33 @@ package com.android.wm.shell.flicker import android.app.Instrumentation import android.content.pm.PackageManager import android.content.pm.PackageManager.FEATURE_LEANBACK import android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY 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 import org.junit.Assume.assumeFalse import org.junit.Before import org.junit.runners.Parameterized /** * 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) } val packageManager: PackageManager by lazy { instrumentation.context.getPackageManager() } abstract class FlickerTestBase( protected val rotationName: String, protected val rotation: Int ) { val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation() val uiDevice = UiDevice.getInstance(instrumentation) val packageManager: PackageManager = instrumentation.context.packageManager protected val isTelevision: Boolean by lazy { packageManager.run { hasSystemFeature(FEATURE_LEANBACK) || hasSystemFeature(FEATURE_LEANBACK_ONLY) Loading @@ -56,83 +56,12 @@ abstract class FlickerTestBase { @Before open fun televisionSetUp() = assumeFalse(isTelevision) /** * 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 <NAME>__<APP>__<ROTATION> </ROTATION></APP></NAME> */ 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 <NAME>__<APP>__<BEGIN_ROTATION>-<END_ROTATION> </END_ROTATION></BEGIN_ROTATION></APP></NAME> */ 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 <NAME>__<APP></APP>(S)>__<ROTATION></ROTATION>(S)>[__<EXTRA>] </EXTRA></NAME> */ 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 { @Parameterized.Parameters(name = "{0}") @JvmStatic fun getParams(): Collection<Array<Any>> { val supportedRotations = intArrayOf(Surface.ROTATION_0, Surface.ROTATION_90) return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) } } } } libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestCannotPairNonResizeableApps.kt +42 −41 Original line number Diff line number Diff line Loading @@ -18,15 +18,16 @@ 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.FlickerTestRunner import com.android.server.wm.flicker.FlickerTestRunnerFactory 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.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 com.android.wm.shell.flicker.helpers.AppPairsHelper import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters import org.junit.runners.Parameterized Loading @@ -41,18 +42,15 @@ import org.junit.runners.Parameterized */ @RequiresDevice @RunWith(Parameterized::class) @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) class AppPairsTestCannotPairNonResizeableApps( testSpec: FlickerTestRunnerFactory.TestSpec ) : FlickerTestRunner(testSpec) { companion object : AppPairsTransition(InstrumentationRegistry.getInstrumentation()) { @Parameterized.Parameters(name = "{0}") @JvmStatic fun getParams(): List<Array<Any>> { val testSpec: FlickerBuilder.(Bundle) -> Unit = { configuration -> withTestName { buildTestTag(configuration) } testSpec: FlickerTestParameter ) : AppPairsTransition(testSpec) { override val transition: FlickerBuilder.(Bundle) -> Unit get() = { super.transition(this, it) transitions { nonResizeableApp?.launchViaIntent(wmHelper) // TODO pair apps through normal UX flow Loading @@ -60,28 +58,31 @@ class AppPairsTestCannotPairNonResizeableApps( composePairsCommand(primaryTaskId, nonResizeableTaskId, pair = true)) SystemClock.sleep(AppPairsHelper.TIMEOUT_MS) } assertions { presubmit { layersTrace { appPairsDividerIsInvisible() } windowManagerTrace { @Presubmit @Test fun appPairsDividerIsInvisible() = testSpec.appPairsDividerIsInvisible() @Presubmit @Test fun onlyResizeableAppWindowVisible() { val nonResizeableApp = nonResizeableApp require(nonResizeableApp != null) { "Non resizeable app not initialized" } end("onlyResizeableAppWindowVisible") { testSpec.assertWmEnd { isVisible(nonResizeableApp.defaultWindowName) isInvisible(primaryApp.defaultWindowName) } } } } } return FlickerTestRunnerFactory.getInstance().buildTest(instrumentation, transition, testSpec, repetitions = AppPairsHelper.TEST_REPETITIONS) companion object { @Parameterized.Parameters(name = "{0}") @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( repetitions = AppPairsHelper.TEST_REPETITIONS) } } } No newline at end of file libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestPairPrimaryAndSecondaryApps.kt +49 −46 Original line number Diff line number Diff line Loading @@ -18,17 +18,19 @@ 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.FlakyTest import androidx.test.filters.RequiresDevice import androidx.test.platform.app.InstrumentationRegistry import com.android.server.wm.flicker.APP_PAIR_SPLIT_DIVIDER import com.android.server.wm.flicker.FlickerTestRunner import com.android.server.wm.flicker.FlickerTestRunnerFactory 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.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.appPairsDividerIsVisible import com.android.wm.shell.flicker.helpers.AppPairsHelper import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters import org.junit.runners.Parameterized Loading @@ -39,40 +41,39 @@ import org.junit.runners.Parameterized */ @RequiresDevice @RunWith(Parameterized::class) @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) class AppPairsTestPairPrimaryAndSecondaryApps( testSpec: FlickerTestRunnerFactory.TestSpec ) : FlickerTestRunner(testSpec) { companion object : AppPairsTransition(InstrumentationRegistry.getInstrumentation()) { @Parameterized.Parameters(name = "{0}") @JvmStatic fun getParams(): List<Array<Any>> { val testSpec: FlickerBuilder.(Bundle) -> Unit = { configuration -> withTestName { buildTestTag(configuration) } testSpec: FlickerTestParameter ) : AppPairsTransition(testSpec) { override val transition: FlickerBuilder.(Bundle) -> Unit get() = { super.transition(this, it) transitions { // TODO pair apps through normal UX flow executeShellCommand( composePairsCommand(primaryTaskId, secondaryTaskId, pair = true)) SystemClock.sleep(AppPairsHelper.TIMEOUT_MS) } assertions { presubmit { layersTrace { appPairsDividerIsVisible() } windowManagerTrace { end("bothAppWindowsVisible") { @Presubmit @Test fun appPairsDividerIsVisible() = testSpec.appPairsDividerIsVisible() @Presubmit @Test fun bothAppWindowsVisible() { testSpec.assertWmEnd { isVisible(primaryApp.defaultWindowName) isVisible(secondaryApp.defaultWindowName) } } } flaky { layersTrace { end("appsEndingBounds") { @FlakyTest @Test fun appsEndingBounds() { testSpec.assertLayersEnd { val dividerRegion = entry.getVisibleBounds(APP_PAIR_SPLIT_DIVIDER) this.hasVisibleRegion(primaryApp.defaultWindowName, appPairsHelper.getPrimaryBounds(dividerRegion)) Loading @@ -80,11 +81,13 @@ class AppPairsTestPairPrimaryAndSecondaryApps( appPairsHelper.getSecondaryBounds(dividerRegion)) } } } } } return FlickerTestRunnerFactory.getInstance().buildTest(instrumentation, transition, testSpec, repetitions = AppPairsHelper.TEST_REPETITIONS) companion object { @Parameterized.Parameters(name = "{0}") @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( repetitions = AppPairsHelper.TEST_REPETITIONS) } } } libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestUnpairPrimaryAndSecondaryApps.kt +63 −55 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt +34 −181 Original line number Diff line number Diff line Loading @@ -18,239 +18,92 @@ package com.android.wm.shell.flicker import android.graphics.Region import android.view.Surface import com.android.server.wm.flicker.dsl.LayersAssertionBuilder import com.android.server.wm.flicker.dsl.LayersAssertionBuilderLegacy import com.android.server.wm.flicker.APP_PAIR_SPLIT_DIVIDER import com.android.server.wm.flicker.DOCKED_STACK_DIVIDER import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.helpers.WindowUtils import com.android.server.wm.flicker.traces.layers.getVisibleBounds @JvmOverloads fun LayersAssertionBuilder.appPairsDividerIsVisible(bugId: Int = 0) { end("appPairsDividerIsVisible", bugId) { fun FlickerTestParameter.appPairsDividerIsVisible() { assertLayersEnd { this.isVisible(APP_PAIR_SPLIT_DIVIDER) } } @JvmOverloads fun LayersAssertionBuilder.appPairsDividerIsInvisible(bugId: Int = 0) { end("appPairsDividerIsInVisible", bugId) { fun FlickerTestParameter.appPairsDividerIsInvisible() { assertLayersEnd { this.notExists(APP_PAIR_SPLIT_DIVIDER) } } @JvmOverloads fun LayersAssertionBuilder.appPairsDividerBecomesVisible(bugId: Int = 0) { all("dividerLayerBecomesVisible", bugId) { fun FlickerTestParameter.appPairsDividerBecomesVisible() { assertLayers { this.hidesLayer(DOCKED_STACK_DIVIDER) .then() .showsLayer(DOCKED_STACK_DIVIDER) } } @JvmOverloads fun LayersAssertionBuilder.dockedStackDividerIsVisible(bugId: Int = 0) { end("dockedStackDividerIsVisible", bugId) { fun FlickerTestParameter.dockedStackDividerIsVisible() { assertLayersEnd { this.isVisible(DOCKED_STACK_DIVIDER) } } @JvmOverloads fun LayersAssertionBuilder.dockedStackDividerBecomesVisible(bugId: Int = 0) { all("dividerLayerBecomesVisible", bugId) { fun FlickerTestParameter.dockedStackDividerBecomesVisible() { assertLayers { this.hidesLayer(DOCKED_STACK_DIVIDER) .then() .showsLayer(DOCKED_STACK_DIVIDER) } } @JvmOverloads fun LayersAssertionBuilder.dockedStackDividerBecomesInvisible(bugId: Int = 0) { all("dividerLayerBecomesInvisible", bugId) { fun FlickerTestParameter.dockedStackDividerBecomesInvisible() { assertLayers { this.showsLayer(DOCKED_STACK_DIVIDER) .then() .hidesLayer(DOCKED_STACK_DIVIDER) } } @JvmOverloads fun LayersAssertionBuilder.dockedStackDividerIsInvisible(bugId: Int = 0) { end("dockedStackDividerIsInvisible", bugId) { fun FlickerTestParameter.dockedStackDividerIsInvisible() { assertLayersEnd { this.notExists(DOCKED_STACK_DIVIDER) } } @JvmOverloads fun LayersAssertionBuilder.appPairsPrimaryBoundsIsVisible( rotation: Int, primaryLayerName: String, bugId: Int = 0 ) { end("PrimaryAppBounds", bugId) { fun FlickerTestParameter.appPairsPrimaryBoundsIsVisible(rotation: Int, primaryLayerName: String) { assertLayersEnd { val dividerRegion = entry.getVisibleBounds(APP_PAIR_SPLIT_DIVIDER) this.hasVisibleRegion(primaryLayerName, getPrimaryRegion(dividerRegion, rotation)) } } @JvmOverloads fun LayersAssertionBuilder.appPairsSecondaryBoundsIsVisible( rotation: Int, secondaryLayerName: String, bugId: Int = 0 ) { end("SecondaryAppBounds", bugId) { val dividerRegion = entry.getVisibleBounds(APP_PAIR_SPLIT_DIVIDER) this.hasVisibleRegion(secondaryLayerName, getSecondaryRegion(dividerRegion, rotation)) } } @JvmOverloads fun LayersAssertionBuilder.dockedStackPrimaryBoundsIsVisible( fun FlickerTestParameter.dockedStackPrimaryBoundsIsVisible( rotation: Int, primaryLayerName: String, bugId: Int = 0 primaryLayerName: String ) { end("PrimaryAppBounds", bugId) { assertLayersEnd { val dividerRegion = entry.getVisibleBounds(DOCKED_STACK_DIVIDER) this.hasVisibleRegion(primaryLayerName, getPrimaryRegion(dividerRegion, rotation)) } } @JvmOverloads fun LayersAssertionBuilder.dockedStackSecondaryBoundsIsVisible( fun FlickerTestParameter.appPairsSecondaryBoundsIsVisible( rotation: Int, secondaryLayerName: String, bugId: Int = 0 ) { end("SecondaryAppBounds", bugId) { val dividerRegion = entry.getVisibleBounds(DOCKED_STACK_DIVIDER) this.hasVisibleRegion(secondaryLayerName, getSecondaryRegion(dividerRegion, rotation)) } } @JvmOverloads fun LayersAssertionBuilderLegacy.appPairsDividerIsVisible( bugId: Int = 0, enabled: Boolean = bugId == 0 ) { end("appPairsDividerIsVisible", bugId, enabled) { this.isVisible(APP_PAIR_SPLIT_DIVIDER) } } @JvmOverloads fun LayersAssertionBuilderLegacy.appPairsDividerIsInvisible( bugId: Int = 0, enabled: Boolean = bugId == 0 ) { end("appPairsDividerIsInVisible", bugId, enabled) { this.notExists(APP_PAIR_SPLIT_DIVIDER) } } @JvmOverloads fun LayersAssertionBuilderLegacy.appPairsDividerBecomesVisible( bugId: Int = 0, enabled: Boolean = bugId == 0 ) { all("dividerLayerBecomesVisible", bugId, enabled) { this.hidesLayer(DOCKED_STACK_DIVIDER) .then() .showsLayer(DOCKED_STACK_DIVIDER) } } @JvmOverloads fun LayersAssertionBuilderLegacy.dockedStackDividerIsVisible( bugId: Int = 0, enabled: Boolean = bugId == 0 secondaryLayerName: String ) { end("dockedStackDividerIsVisible", bugId, enabled) { this.isVisible(DOCKED_STACK_DIVIDER) } } @JvmOverloads fun LayersAssertionBuilderLegacy.dockedStackDividerBecomesVisible( bugId: Int = 0, enabled: Boolean = bugId == 0 ) { all("dividerLayerBecomesVisible", bugId, enabled) { this.hidesLayer(DOCKED_STACK_DIVIDER) .then() .showsLayer(DOCKED_STACK_DIVIDER) } } @JvmOverloads fun LayersAssertionBuilderLegacy.dockedStackDividerBecomesInvisible( bugId: Int = 0, enabled: Boolean = bugId == 0 ) { all("dividerLayerBecomesInvisible", bugId, enabled) { this.showsLayer(DOCKED_STACK_DIVIDER) .then() .hidesLayer(DOCKED_STACK_DIVIDER) } } @JvmOverloads fun LayersAssertionBuilderLegacy.dockedStackDividerIsInvisible( bugId: Int = 0, enabled: Boolean = bugId == 0 ) { end("dockedStackDividerIsInvisible", bugId, enabled) { this.notExists(DOCKED_STACK_DIVIDER) } } @JvmOverloads fun LayersAssertionBuilderLegacy.appPairsPrimaryBoundsIsVisible( rotation: Int, primaryLayerName: String, bugId: Int = 0, enabled: Boolean = bugId == 0 ) { end("PrimaryAppBounds", bugId, enabled) { val dividerRegion = entry.getVisibleBounds(APP_PAIR_SPLIT_DIVIDER) this.hasVisibleRegion(primaryLayerName, getPrimaryRegion(dividerRegion, rotation)) } } @JvmOverloads fun LayersAssertionBuilderLegacy.appPairsSecondaryBoundsIsVisible( rotation: Int, secondaryLayerName: String, bugId: Int = 0, enabled: Boolean = bugId == 0 ) { end("SecondaryAppBounds", bugId, enabled) { assertLayersEnd { val dividerRegion = entry.getVisibleBounds(APP_PAIR_SPLIT_DIVIDER) this.hasVisibleRegion(secondaryLayerName, getSecondaryRegion(dividerRegion, rotation)) } } @JvmOverloads fun LayersAssertionBuilderLegacy.dockedStackPrimaryBoundsIsVisible( rotation: Int, primaryLayerName: String, bugId: Int = 0, enabled: Boolean = bugId == 0 ) { end("PrimaryAppBounds", bugId, enabled) { val dividerRegion = entry.getVisibleBounds(DOCKED_STACK_DIVIDER) this.hasVisibleRegion(primaryLayerName, getPrimaryRegion(dividerRegion, rotation)) } } @JvmOverloads fun LayersAssertionBuilderLegacy.dockedStackSecondaryBoundsIsVisible( fun FlickerTestParameter.dockedStackSecondaryBoundsIsVisible( rotation: Int, secondaryLayerName: String, bugId: Int = 0, enabled: Boolean = bugId == 0 secondaryLayerName: String ) { end("SecondaryAppBounds", bugId, enabled) { assertLayersEnd { val dividerRegion = entry.getVisibleBounds(DOCKED_STACK_DIVIDER) this.hasVisibleRegion(secondaryLayerName, getSecondaryRegion(dividerRegion, rotation)) } Loading
libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/FlickerTestBase.kt +15 −86 Original line number Diff line number Diff line Loading @@ -16,33 +16,33 @@ package com.android.wm.shell.flicker import android.app.Instrumentation import android.content.pm.PackageManager import android.content.pm.PackageManager.FEATURE_LEANBACK import android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY 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 import org.junit.Assume.assumeFalse import org.junit.Before import org.junit.runners.Parameterized /** * 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) } val packageManager: PackageManager by lazy { instrumentation.context.getPackageManager() } abstract class FlickerTestBase( protected val rotationName: String, protected val rotation: Int ) { val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation() val uiDevice = UiDevice.getInstance(instrumentation) val packageManager: PackageManager = instrumentation.context.packageManager protected val isTelevision: Boolean by lazy { packageManager.run { hasSystemFeature(FEATURE_LEANBACK) || hasSystemFeature(FEATURE_LEANBACK_ONLY) Loading @@ -56,83 +56,12 @@ abstract class FlickerTestBase { @Before open fun televisionSetUp() = assumeFalse(isTelevision) /** * 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 <NAME>__<APP>__<ROTATION> </ROTATION></APP></NAME> */ 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 <NAME>__<APP>__<BEGIN_ROTATION>-<END_ROTATION> </END_ROTATION></BEGIN_ROTATION></APP></NAME> */ 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 <NAME>__<APP></APP>(S)>__<ROTATION></ROTATION>(S)>[__<EXTRA>] </EXTRA></NAME> */ 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 { @Parameterized.Parameters(name = "{0}") @JvmStatic fun getParams(): Collection<Array<Any>> { val supportedRotations = intArrayOf(Surface.ROTATION_0, Surface.ROTATION_90) return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) } } } }
libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestCannotPairNonResizeableApps.kt +42 −41 Original line number Diff line number Diff line Loading @@ -18,15 +18,16 @@ 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.FlickerTestRunner import com.android.server.wm.flicker.FlickerTestRunnerFactory 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.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 com.android.wm.shell.flicker.helpers.AppPairsHelper import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters import org.junit.runners.Parameterized Loading @@ -41,18 +42,15 @@ import org.junit.runners.Parameterized */ @RequiresDevice @RunWith(Parameterized::class) @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) class AppPairsTestCannotPairNonResizeableApps( testSpec: FlickerTestRunnerFactory.TestSpec ) : FlickerTestRunner(testSpec) { companion object : AppPairsTransition(InstrumentationRegistry.getInstrumentation()) { @Parameterized.Parameters(name = "{0}") @JvmStatic fun getParams(): List<Array<Any>> { val testSpec: FlickerBuilder.(Bundle) -> Unit = { configuration -> withTestName { buildTestTag(configuration) } testSpec: FlickerTestParameter ) : AppPairsTransition(testSpec) { override val transition: FlickerBuilder.(Bundle) -> Unit get() = { super.transition(this, it) transitions { nonResizeableApp?.launchViaIntent(wmHelper) // TODO pair apps through normal UX flow Loading @@ -60,28 +58,31 @@ class AppPairsTestCannotPairNonResizeableApps( composePairsCommand(primaryTaskId, nonResizeableTaskId, pair = true)) SystemClock.sleep(AppPairsHelper.TIMEOUT_MS) } assertions { presubmit { layersTrace { appPairsDividerIsInvisible() } windowManagerTrace { @Presubmit @Test fun appPairsDividerIsInvisible() = testSpec.appPairsDividerIsInvisible() @Presubmit @Test fun onlyResizeableAppWindowVisible() { val nonResizeableApp = nonResizeableApp require(nonResizeableApp != null) { "Non resizeable app not initialized" } end("onlyResizeableAppWindowVisible") { testSpec.assertWmEnd { isVisible(nonResizeableApp.defaultWindowName) isInvisible(primaryApp.defaultWindowName) } } } } } return FlickerTestRunnerFactory.getInstance().buildTest(instrumentation, transition, testSpec, repetitions = AppPairsHelper.TEST_REPETITIONS) companion object { @Parameterized.Parameters(name = "{0}") @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( repetitions = AppPairsHelper.TEST_REPETITIONS) } } } No newline at end of file
libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestPairPrimaryAndSecondaryApps.kt +49 −46 Original line number Diff line number Diff line Loading @@ -18,17 +18,19 @@ 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.FlakyTest import androidx.test.filters.RequiresDevice import androidx.test.platform.app.InstrumentationRegistry import com.android.server.wm.flicker.APP_PAIR_SPLIT_DIVIDER import com.android.server.wm.flicker.FlickerTestRunner import com.android.server.wm.flicker.FlickerTestRunnerFactory 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.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.appPairsDividerIsVisible import com.android.wm.shell.flicker.helpers.AppPairsHelper import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters import org.junit.runners.Parameterized Loading @@ -39,40 +41,39 @@ import org.junit.runners.Parameterized */ @RequiresDevice @RunWith(Parameterized::class) @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) class AppPairsTestPairPrimaryAndSecondaryApps( testSpec: FlickerTestRunnerFactory.TestSpec ) : FlickerTestRunner(testSpec) { companion object : AppPairsTransition(InstrumentationRegistry.getInstrumentation()) { @Parameterized.Parameters(name = "{0}") @JvmStatic fun getParams(): List<Array<Any>> { val testSpec: FlickerBuilder.(Bundle) -> Unit = { configuration -> withTestName { buildTestTag(configuration) } testSpec: FlickerTestParameter ) : AppPairsTransition(testSpec) { override val transition: FlickerBuilder.(Bundle) -> Unit get() = { super.transition(this, it) transitions { // TODO pair apps through normal UX flow executeShellCommand( composePairsCommand(primaryTaskId, secondaryTaskId, pair = true)) SystemClock.sleep(AppPairsHelper.TIMEOUT_MS) } assertions { presubmit { layersTrace { appPairsDividerIsVisible() } windowManagerTrace { end("bothAppWindowsVisible") { @Presubmit @Test fun appPairsDividerIsVisible() = testSpec.appPairsDividerIsVisible() @Presubmit @Test fun bothAppWindowsVisible() { testSpec.assertWmEnd { isVisible(primaryApp.defaultWindowName) isVisible(secondaryApp.defaultWindowName) } } } flaky { layersTrace { end("appsEndingBounds") { @FlakyTest @Test fun appsEndingBounds() { testSpec.assertLayersEnd { val dividerRegion = entry.getVisibleBounds(APP_PAIR_SPLIT_DIVIDER) this.hasVisibleRegion(primaryApp.defaultWindowName, appPairsHelper.getPrimaryBounds(dividerRegion)) Loading @@ -80,11 +81,13 @@ class AppPairsTestPairPrimaryAndSecondaryApps( appPairsHelper.getSecondaryBounds(dividerRegion)) } } } } } return FlickerTestRunnerFactory.getInstance().buildTest(instrumentation, transition, testSpec, repetitions = AppPairsHelper.TEST_REPETITIONS) companion object { @Parameterized.Parameters(name = "{0}") @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( repetitions = AppPairsHelper.TEST_REPETITIONS) } } }
libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestUnpairPrimaryAndSecondaryApps.kt +63 −55 File changed.Preview size limit exceeded, changes collapsed. Show changes