Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cd9b0864 authored by Nataniel Borges's avatar Nataniel Borges Committed by Android (Google) Code Review
Browse files

Merge "Use FlickerParametersRunnerFactory" into sc-dev

parents 0f477048 c39b6444
Loading
Loading
Loading
Loading
+34 −181
Original line number Diff line number Diff line
@@ -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))
    }
+15 −86
Original line number Diff line number Diff line
@@ -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)
@@ -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) }
        }
    }
}
+42 −41
Original line number Diff line number Diff line
@@ -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
@@ -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
@@ -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
+49 −46
Original line number Diff line number Diff line
@@ -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
@@ -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))
@@ -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)
        }
    }
}
+63 −55

File changed.

Preview size limit exceeded, changes collapsed.

Loading