Support flicker DSL

Make the flicker tests use the flicker DSL for easier development and maintenance

Test: atest FlickerTests
Change-Id: If893ba02b52738a48884db4676cd19f4aced178e
diff --git a/tests/FlickerTests/Android.bp b/tests/FlickerTests/Android.bp
index 5161fba..952997e 100644
--- a/tests/FlickerTests/Android.bp
+++ b/tests/FlickerTests/Android.bp
@@ -24,6 +24,7 @@
     test_suites: ["device-tests"],
     libs: ["android.test.runner"],
     static_libs: [
+        "androidx.test.ext.junit",
         "flickertestapplib",
         "flickerlib",
         "truth-prebuilt",
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
new file mode 100644
index 0000000..dcabce8
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
@@ -0,0 +1,133 @@
+/*
+ * 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.server.wm.flicker
+
+import com.android.server.wm.flicker.dsl.LayersAssertion
+import com.android.server.wm.flicker.dsl.WmAssertion
+import com.android.server.wm.flicker.helpers.WindowUtils
+
+@JvmOverloads
+fun WmAssertion.statusBarWindowIsAlwaysVisible(
+    bugId: Int = 0,
+    enabled: Boolean = bugId == 0
+) {
+    all("statusBarWindowIsAlwaysVisible", enabled, bugId) {
+        this.showsAboveAppWindow(FlickerTestBase.STATUS_BAR_WINDOW_TITLE)
+    }
+}
+
+@JvmOverloads
+fun WmAssertion.navBarWindowIsAlwaysVisible(
+    bugId: Int = 0,
+    enabled: Boolean = bugId == 0
+) {
+    all("navBarWindowIsAlwaysVisible", enabled, bugId) {
+        this.showsAboveAppWindow(FlickerTestBase.NAVIGATION_BAR_WINDOW_TITLE)
+    }
+}
+
+@JvmOverloads
+fun LayersAssertion.noUncoveredRegions(
+    beginRotation: Int,
+    endRotation: Int = beginRotation,
+    allStates: Boolean = true,
+    bugId: Int = 0,
+    enabled: Boolean = bugId == 0
+) {
+    val startingBounds = WindowUtils.getDisplayBounds(beginRotation)
+    val endingBounds = WindowUtils.getDisplayBounds(endRotation)
+    if (allStates) {
+        all("noUncoveredRegions", enabled, bugId) {
+            if (startingBounds == endingBounds) {
+                this.coversRegion(startingBounds)
+            } else {
+                this.coversRegion(startingBounds)
+                        .then()
+                        .coversRegion(endingBounds)
+            }
+        }
+    } else {
+        start("noUncoveredRegions_StartingPos") {
+            this.coversRegion(startingBounds)
+        }
+        end("noUncoveredRegions_EndingPos") {
+            this.coversRegion(endingBounds)
+        }
+    }
+}
+
+@JvmOverloads
+fun LayersAssertion.navBarLayerIsAlwaysVisible(
+    bugId: Int = 0,
+    enabled: Boolean = bugId == 0
+) {
+    all("navBarLayerIsAlwaysVisible", enabled, bugId) {
+        this.showsLayer(FlickerTestBase.NAVIGATION_BAR_WINDOW_TITLE)
+    }
+}
+
+@JvmOverloads
+fun LayersAssertion.statusBarLayerIsAlwaysVisible(
+    bugId: Int = 0,
+    enabled: Boolean = bugId == 0
+) {
+    all("statusBarLayerIsAlwaysVisible", enabled, bugId) {
+        this.showsLayer(FlickerTestBase.STATUS_BAR_WINDOW_TITLE)
+    }
+}
+
+@JvmOverloads
+fun LayersAssertion.navBarLayerRotatesAndScales(
+    beginRotation: Int,
+    endRotation: Int = beginRotation,
+    bugId: Int = 0,
+    enabled: Boolean = bugId == 0
+) {
+    val startingPos = WindowUtils.getNavigationBarPosition(beginRotation)
+    val endingPos = WindowUtils.getNavigationBarPosition(endRotation)
+
+    start("navBarLayerRotatesAndScales_StartingPos", enabled, bugId) {
+        this.hasVisibleRegion(FlickerTestBase.NAVIGATION_BAR_WINDOW_TITLE, startingPos)
+    }
+    end("navBarLayerRotatesAndScales_EndingPost", enabled, bugId) {
+        this.hasVisibleRegion(FlickerTestBase.NAVIGATION_BAR_WINDOW_TITLE, endingPos)
+    }
+
+    if (startingPos == endingPos) {
+        all("navBarLayerRotatesAndScales", enabled, bugId) {
+            this.hasVisibleRegion(FlickerTestBase.NAVIGATION_BAR_WINDOW_TITLE, startingPos)
+        }
+    }
+}
+
+@JvmOverloads
+fun LayersAssertion.statusBarLayerRotatesScales(
+    beginRotation: Int,
+    endRotation: Int = beginRotation,
+    bugId: Int = 0,
+    enabled: Boolean = bugId == 0
+) {
+    val startingPos = WindowUtils.getStatusBarPosition(beginRotation)
+    val endingPos = WindowUtils.getStatusBarPosition(endRotation)
+
+    start("statusBarLayerRotatesScales_StartingPos", enabled, bugId) {
+        this.hasVisibleRegion(FlickerTestBase.STATUS_BAR_WINDOW_TITLE, startingPos)
+    }
+    end("statusBarLayerRotatesScales_EndingPos", enabled, bugId) {
+        this.hasVisibleRegion(FlickerTestBase.STATUS_BAR_WINDOW_TITLE, endingPos)
+    }
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.kt
deleted file mode 100644
index b69e6a9..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.kt
+++ /dev/null
@@ -1,446 +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.server.wm.flicker
-
-import android.app.Instrumentation
-import android.content.Context
-import android.content.Intent
-import android.os.RemoteException
-import android.os.SystemClock
-import android.platform.helpers.IAppHelper
-import android.util.Rational
-import android.view.Surface
-import androidx.test.uiautomator.By
-import androidx.test.uiautomator.UiDevice
-import androidx.test.uiautomator.Until
-import com.android.server.wm.flicker.helpers.AutomationUtils
-import com.android.server.wm.flicker.helpers.ImeAppHelper
-import com.android.server.wm.flicker.helpers.PipAppHelper
-
-/**
- * Collection of common transitions which can be used to test different apps or scenarios.
- */
-internal object CommonTransitions {
-    private const val ITERATIONS = 1
-    private const val APP_LAUNCH_TIMEOUT: Long = 10000
-    private fun setRotation(device: UiDevice, 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)
-        }
-    }
-
-    /**
-     * 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> */
-    private 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> */
-    private 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> */
-    private fun buildTestTag(
-        testName: String,
-        app: IAppHelper,
-        beginRotation: Int,
-        endRotation: Int,
-        app2: IAppHelper?,
-        extraInfo: String
-    ): String {
-        val testTag = StringBuilder()
-        testTag.append(testName)
-                .append("__")
-                .append(app.launcherName)
-        if (app2 != null) {
-            testTag.append("-")
-                    .append(app2.launcherName)
-        }
-        testTag.append("__")
-                .append(Surface.rotationToString(beginRotation))
-        if (endRotation != beginRotation) {
-            testTag.append("-")
-                    .append(Surface.rotationToString(endRotation))
-        }
-        if (extraInfo.isNotEmpty()) {
-            testTag.append("__")
-                    .append(extraInfo)
-        }
-        return testTag.toString()
-    }
-
-    fun openAppWarm(
-        testApp: IAppHelper,
-        instrumentation: Instrumentation,
-        device: UiDevice,
-        beginRotation: Int
-    ): TransitionRunner.TransitionBuilder {
-        return TransitionRunner.TransitionBuilder(instrumentation)
-                .withTag(buildTestTag("openAppWarm", testApp, beginRotation))
-                .recordAllRuns()
-                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
-                .runBeforeAll { setRotation(device, beginRotation) }
-                .runBeforeAll { testApp.open() }
-                .runBefore { device.pressHome() }
-                .runBefore { device.waitForIdle() }
-                .runBefore { setRotation(device, beginRotation) }
-                .run { testApp.open() }
-                .runAfterAll { testApp.exit() }
-                .runAfterAll { AutomationUtils.setDefaultWait() }
-                .repeat(ITERATIONS)
-    }
-
-    fun closeAppWithBackKey(
-        testApp: IAppHelper,
-        instrumentation: Instrumentation,
-        device: UiDevice,
-        beginRotation: Int
-    ): TransitionRunner.TransitionBuilder {
-        return TransitionRunner.TransitionBuilder(instrumentation)
-                .withTag(buildTestTag("closeAppWithBackKey", testApp, beginRotation))
-                .recordAllRuns()
-                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
-                .runBefore { testApp.open() }
-                .runBefore { device.waitForIdle() }
-                .run { device.pressBack() }
-                .run { device.waitForIdle() }
-                .runAfterAll { testApp.exit() }
-                .runAfterAll { AutomationUtils.setDefaultWait() }
-                .repeat(ITERATIONS)
-    }
-
-    fun closeAppWithHomeKey(
-        testApp: IAppHelper,
-        instrumentation: Instrumentation,
-        device: UiDevice,
-        beginRotation: Int
-    ): TransitionRunner.TransitionBuilder {
-        return TransitionRunner.TransitionBuilder(instrumentation)
-                .withTag(buildTestTag("closeAppWithHomeKey", testApp, beginRotation))
-                .recordAllRuns()
-                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
-                .runBefore { testApp.open() }
-                .runBefore { device.waitForIdle() }
-                .run { device.pressHome() }
-                .run { device.waitForIdle() }
-                .runAfterAll { testApp.exit() }
-                .runAfterAll { AutomationUtils.setDefaultWait() }
-                .repeat(ITERATIONS)
-    }
-
-    fun openAppCold(
-        testApp: IAppHelper,
-        instrumentation: Instrumentation,
-        device: UiDevice,
-        beginRotation: Int
-    ): TransitionRunner.TransitionBuilder {
-        return TransitionRunner.TransitionBuilder(instrumentation)
-                .withTag(buildTestTag("openAppCold", testApp, beginRotation))
-                .recordAllRuns()
-                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
-                .runBefore { device.pressHome() }
-                .runBeforeAll { setRotation(device, beginRotation) }
-                .runBefore { testApp.exit() }
-                .runBefore { device.waitForIdle() }
-                .run { testApp.open() }
-                .runAfterAll { testApp.exit() }
-                .runAfterAll { setRotation(device, Surface.ROTATION_0) }
-                .repeat(ITERATIONS)
-    }
-
-    fun changeAppRotation(
-        testApp: IAppHelper,
-        instrumentation: Instrumentation,
-        device: UiDevice,
-        beginRotation: Int,
-        endRotation: Int
-    ): TransitionRunner.TransitionBuilder {
-        return TransitionRunner.TransitionBuilder(instrumentation)
-                .withTag(buildTestTag("changeAppRotation", testApp, beginRotation, endRotation))
-                .recordAllRuns()
-                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
-                .runBeforeAll { testApp.open() }
-                .runBefore { setRotation(device, beginRotation) }
-                .run { setRotation(device, endRotation) }
-                .runAfterAll { testApp.exit() }
-                .runAfterAll { setRotation(device, Surface.ROTATION_0) }
-                .repeat(ITERATIONS)
-    }
-
-    fun changeAppRotation(
-        intent: Intent,
-        intentId: String,
-        context: Context,
-        instrumentation: Instrumentation,
-        device: UiDevice,
-        beginRotation: Int,
-        endRotation: Int
-    ): TransitionRunner.TransitionBuilder {
-        val testTag = "changeAppRotation_" + intentId + "_" +
-                Surface.rotationToString(beginRotation) + "_" +
-                Surface.rotationToString(endRotation)
-        return TransitionRunner.TransitionBuilder(instrumentation)
-                .withTag(testTag)
-                .recordAllRuns()
-                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
-                .runBeforeAll {
-                    context.startActivity(intent)
-                    device.wait(Until.hasObject(By.pkg(intent.component?.packageName)
-                            .depth(0)), APP_LAUNCH_TIMEOUT)
-                }
-                .runBefore { setRotation(device, beginRotation) }
-                .run { setRotation(device, endRotation) }
-                .runAfterAll { AutomationUtils.stopPackage(context, intent.component?.packageName) }
-                .runAfterAll { setRotation(device, Surface.ROTATION_0) }
-                .repeat(ITERATIONS)
-    }
-
-    fun appToSplitScreen(
-        testApp: IAppHelper,
-        instrumentation: Instrumentation,
-        device: UiDevice,
-        beginRotation: Int
-    ): TransitionRunner.TransitionBuilder {
-        return TransitionRunner.TransitionBuilder(instrumentation)
-                .withTag(buildTestTag("appToSplitScreen", testApp, beginRotation))
-                .recordAllRuns()
-                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
-                .runBeforeAll { setRotation(device, beginRotation) }
-                .runBefore { testApp.open() }
-                .runBefore { device.waitForIdle() }
-                .runBefore { SystemClock.sleep(500) }
-                .run { AutomationUtils.launchSplitScreen(device) }
-                .runAfter { AutomationUtils.exitSplitScreen(device) }
-                .runAfterAll { testApp.exit() }
-                .repeat(ITERATIONS)
-    }
-
-    fun splitScreenToLauncher(
-        testApp: IAppHelper,
-        instrumentation: Instrumentation,
-        device: UiDevice,
-        beginRotation: Int
-    ): TransitionRunner.TransitionBuilder {
-        return TransitionRunner.TransitionBuilder(instrumentation)
-                .withTag(buildTestTag("splitScreenToLauncher", testApp, beginRotation))
-                .recordAllRuns()
-                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
-                .runBefore { testApp.open() }
-                .runBefore { device.waitForIdle() }
-                .runBefore { AutomationUtils.launchSplitScreen(device) }
-                .run { AutomationUtils.exitSplitScreen(device) }
-                .runAfterAll { testApp.exit() }
-                .repeat(ITERATIONS)
-    }
-
-    fun editTextSetFocus(
-        testApp: ImeAppHelper,
-        instrumentation: Instrumentation,
-        device: UiDevice,
-        beginRotation: Int
-    ): TransitionRunner.TransitionBuilder {
-        return TransitionRunner.TransitionBuilder(instrumentation)
-                .withTag(buildTestTag("editTextSetFocus", testApp, beginRotation))
-                .recordAllRuns()
-                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
-                .runBefore { device.pressHome() }
-                .runBefore { setRotation(device, beginRotation) }
-                .runBefore { testApp.open() }
-                .run { testApp.openIME(device) }
-                .runAfterAll { testApp.exit() }
-                .repeat(ITERATIONS)
-    }
-
-    fun resizeSplitScreen(
-        testAppTop: IAppHelper,
-        testAppBottom: ImeAppHelper,
-        instrumentation: Instrumentation,
-        device: UiDevice,
-        beginRotation: Int,
-        startRatio: Rational,
-        stopRatio: Rational
-    ): TransitionRunner.TransitionBuilder {
-        val description = (startRatio.toString().replace("/", "-") + "_to_" +
-                stopRatio.toString().replace("/", "-"))
-        val testTag = buildTestTag("resizeSplitScreen", testAppTop, beginRotation,
-                beginRotation, testAppBottom, description)
-        return TransitionRunner.TransitionBuilder(instrumentation)
-                .withTag(testTag)
-                .recordAllRuns()
-                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
-                .runBeforeAll { setRotation(device, beginRotation) }
-                .runBeforeAll { AutomationUtils.clearRecents(instrumentation) }
-                .runBefore { testAppBottom.open() }
-                .runBefore { device.pressHome() }
-                .runBefore { testAppTop.open() }
-                .runBefore { device.waitForIdle() }
-                .runBefore { AutomationUtils.launchSplitScreen(device) }
-                .runBefore {
-                    val snapshot = device.findObject(
-                            By.res(device.launcherPackageName, "snapshot"))
-                    snapshot.click()
-                }
-                .runBefore { testAppBottom.openIME(device) }
-                .runBefore { device.pressBack() }
-                .runBefore { AutomationUtils.resizeSplitScreen(device, startRatio) }
-                .run { AutomationUtils.resizeSplitScreen(device, stopRatio) }
-                .runAfter { AutomationUtils.exitSplitScreen(device) }
-                .runAfter { device.pressHome() }
-                .runAfterAll { testAppTop.exit() }
-                .runAfterAll { testAppBottom.exit() }
-                .repeat(ITERATIONS)
-    }
-
-    fun editTextLoseFocusToHome(
-        testApp: ImeAppHelper,
-        instrumentation: Instrumentation,
-        device: UiDevice,
-        beginRotation: Int
-    ): TransitionRunner.TransitionBuilder {
-        return TransitionRunner.TransitionBuilder(instrumentation)
-                .withTag(buildTestTag("editTextLoseFocusToHome", testApp, beginRotation))
-                .recordAllRuns()
-                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
-                .runBefore { device.pressHome() }
-                .runBefore { setRotation(device, beginRotation) }
-                .runBefore { testApp.open() }
-                .runBefore { testApp.openIME(device) }
-                .run { device.pressHome() }
-                .run { device.waitForIdle() }
-                .runAfterAll { testApp.exit() }
-                .repeat(ITERATIONS)
-    }
-
-    fun editTextLoseFocusToApp(
-        testApp: ImeAppHelper,
-        instrumentation: Instrumentation,
-        device: UiDevice,
-        beginRotation: Int
-    ): TransitionRunner.TransitionBuilder {
-        return TransitionRunner.TransitionBuilder(instrumentation)
-                .withTag(buildTestTag("editTextLoseFocusToApp", testApp, beginRotation))
-                .recordAllRuns()
-                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
-                .runBefore { device.pressHome() }
-                .runBefore { setRotation(device, beginRotation) }
-                .runBefore { testApp.open() }
-                .runBefore { testApp.openIME(device) }
-                .run { device.pressBack() }
-                .run { device.waitForIdle() }
-                .runAfterAll { testApp.exit() }
-                .repeat(ITERATIONS)
-    }
-
-    fun enterPipMode(
-        testApp: PipAppHelper,
-        instrumentation: Instrumentation,
-        device: UiDevice,
-        beginRotation: Int
-    ): TransitionRunner.TransitionBuilder {
-        return TransitionRunner.TransitionBuilder(instrumentation)
-                .withTag(buildTestTag("enterPipMode", testApp, beginRotation))
-                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
-                .runBefore { device.pressHome() }
-                .runBefore { setRotation(device, beginRotation) }
-                .runBefore { testApp.open() }
-                .run { testApp.clickEnterPipButton(device) }
-                .runAfter { testApp.closePipWindow(device) }
-                .runAfterAll { testApp.exit() }
-                .repeat(ITERATIONS)
-    }
-
-    fun exitPipModeToHome(
-        testApp: PipAppHelper,
-        instrumentation: Instrumentation,
-        device: UiDevice,
-        beginRotation: Int
-    ): TransitionRunner.TransitionBuilder {
-        return TransitionRunner.TransitionBuilder(instrumentation)
-                .withTag(buildTestTag("exitPipModeToHome", testApp, beginRotation))
-                .recordAllRuns()
-                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
-                .runBefore { device.pressHome() }
-                .runBefore { setRotation(device, beginRotation) }
-                .runBefore { testApp.open() }
-                .run { testApp.clickEnterPipButton(device) }
-                .run { testApp.closePipWindow(device) }
-                .run { device.waitForIdle() }
-                .run { testApp.exit() }
-                .repeat(ITERATIONS)
-    }
-
-    fun exitPipModeToApp(
-        testApp: PipAppHelper,
-        instrumentation: Instrumentation,
-        device: UiDevice,
-        beginRotation: Int
-    ): TransitionRunner.TransitionBuilder {
-        return TransitionRunner.TransitionBuilder(instrumentation)
-                .withTag(buildTestTag("exitPipModeToApp", testApp, beginRotation))
-                .recordAllRuns()
-                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
-                .run { device.pressHome() }
-                .run { setRotation(device, beginRotation) }
-                .run { testApp.open() }
-                .run { testApp.clickEnterPipButton(device) }
-                .run { AutomationUtils.expandPipWindow(device) }
-                .run { device.waitForIdle() }
-                .run { testApp.exit() }
-                .repeat(ITERATIONS)
-    }
-}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.kt
deleted file mode 100644
index 43cfdff..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.kt
+++ /dev/null
@@ -1,190 +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.server.wm.flicker
-
-import android.platform.helpers.IAppHelper
-import android.util.Rational
-import android.view.Surface
-import androidx.test.InstrumentationRegistry
-import androidx.test.filters.FlakyTest
-import androidx.test.filters.LargeTest
-import androidx.test.runner.AndroidJUnit4
-import androidx.test.uiautomator.UiDevice
-import com.android.server.wm.flicker.helpers.ImeAppHelper
-import com.android.server.wm.flicker.helpers.PipAppHelper
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-
-/**
- * Tests to help debug individual transitions, capture video recordings and create test cases.
- *
- * Not actual tests
- */
-@LargeTest
-@FlakyTest
-@RunWith(AndroidJUnit4::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class DebugTest {
-    private val instrumentation = InstrumentationRegistry.getInstrumentation()
-    private val testApp: IAppHelper = StandardAppHelper(instrumentation,
-            "com.android.server.wm.flicker.testapp", "SimpleApp")
-    private val uiDevice = UiDevice.getInstance(instrumentation)
-
-    /**
-     * atest FlickerTests:DebugTest#openAppCold
-     */
-    @Test
-    fun openAppCold() {
-        CommonTransitions.openAppCold(testApp, instrumentation, uiDevice, Surface.ROTATION_0)
-                .recordAllRuns().build().run()
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#openAppWarm
-     */
-    @Test
-    fun openAppWarm() {
-        CommonTransitions.openAppWarm(testApp, instrumentation, uiDevice, Surface.ROTATION_0)
-                .recordAllRuns().build().run()
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#changeOrientationFromNaturalToLeft
-     */
-    @Test
-    fun changeOrientationFromNaturalToLeft() {
-        CommonTransitions.changeAppRotation(testApp, instrumentation, uiDevice, Surface.ROTATION_0,
-                Surface.ROTATION_270).recordAllRuns().build().run()
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#closeAppWithBackKey
-     */
-    @Test
-    fun closeAppWithBackKey() {
-        CommonTransitions.closeAppWithBackKey(testApp, instrumentation, uiDevice,
-                Surface.ROTATION_0).recordAllRuns().build().run()
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#closeAppWithHomeKey
-     */
-    @Test
-    fun closeAppWithHomeKey() {
-        CommonTransitions.closeAppWithHomeKey(testApp, instrumentation, uiDevice,
-                Surface.ROTATION_0).recordAllRuns().build().run()
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#openAppToSplitScreen
-     */
-    @Test
-    fun openAppToSplitScreen() {
-        CommonTransitions.appToSplitScreen(testApp, instrumentation, uiDevice,
-                Surface.ROTATION_0).includeJankyRuns().recordAllRuns()
-                .build().run()
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#splitScreenToLauncher
-     */
-    @Test
-    fun splitScreenToLauncher() {
-        CommonTransitions.splitScreenToLauncher(testApp, instrumentation, uiDevice,
-                Surface.ROTATION_0).includeJankyRuns().recordAllRuns().build().run()
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#resizeSplitScreen
-     */
-    @Test
-    fun resizeSplitScreen() {
-        val bottomApp = ImeAppHelper(instrumentation)
-        CommonTransitions.resizeSplitScreen(
-                testApp,
-                bottomApp,
-                instrumentation,
-                uiDevice,
-                Surface.ROTATION_0,
-                Rational(1, 3), Rational(2, 3)
-        ).includeJankyRuns().build().run()
-    }
-    // IME tests
-    /**
-     * atest FlickerTests:DebugTest#editTextSetFocus
-     */
-    @Test
-    fun editTextSetFocus() {
-        val testApp = ImeAppHelper(instrumentation)
-        CommonTransitions.editTextSetFocus(testApp, instrumentation, uiDevice, Surface.ROTATION_0)
-                .includeJankyRuns()
-                .build().run()
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#editTextLoseFocusToHome
-     */
-    @Test
-    fun editTextLoseFocusToHome() {
-        val testApp = ImeAppHelper(instrumentation)
-        CommonTransitions.editTextLoseFocusToHome(testApp, instrumentation, uiDevice,
-                Surface.ROTATION_0).includeJankyRuns().build().run()
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#editTextLoseFocusToApp
-     */
-    @Test
-    fun editTextLoseFocusToApp() {
-        val testApp = ImeAppHelper(instrumentation)
-        CommonTransitions.editTextLoseFocusToHome(testApp, instrumentation, uiDevice,
-                Surface.ROTATION_0).includeJankyRuns().build().run()
-    }
-    // PIP tests
-    /**
-     * atest FlickerTests:DebugTest#enterPipMode
-     */
-    @Test
-    fun enterPipMode() {
-        val testApp = PipAppHelper(instrumentation)
-        CommonTransitions.enterPipMode(testApp, instrumentation, uiDevice, Surface.ROTATION_0)
-                .includeJankyRuns().build().run()
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#exitPipModeToHome
-     */
-    @Test
-    fun exitPipModeToHome() {
-        val testApp = PipAppHelper(instrumentation)
-        CommonTransitions.exitPipModeToHome(testApp, instrumentation, uiDevice, Surface.ROTATION_0)
-                .includeJankyRuns()
-                .build().run()
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#exitPipModeToApp
-     */
-    @Test
-    fun exitPipModeToApp() {
-        val testApp = PipAppHelper(instrumentation)
-        CommonTransitions.exitPipModeToApp(testApp, instrumentation, uiDevice, Surface.ROTATION_0)
-                .includeJankyRuns().build().run()
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.kt
index d7586d0..eaf4d87 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.kt
@@ -16,15 +16,12 @@
 
 package com.android.server.wm.flicker
 
+import android.os.RemoteException
+import android.os.SystemClock
 import android.platform.helpers.IAppHelper
-import android.util.Log
-import androidx.test.InstrumentationRegistry
+import android.view.Surface
+import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
-import com.android.server.wm.flicker.helpers.AutomationUtils
-import com.google.common.truth.Truth
-import org.junit.After
-import org.junit.AfterClass
-import org.junit.Before
 
 /**
  * Base class of all Flicker test that performs common functions for all flicker tests:
@@ -37,101 +34,96 @@
  * - Fails tests if results are not available for any test due to jank.
  */
 abstract class FlickerTestBase {
-    lateinit var testApp: IAppHelper
-    open val instrumentation by lazy {
+    val instrumentation by lazy {
         InstrumentationRegistry.getInstrumentation()
     }
     val uiDevice by lazy {
         UiDevice.getInstance(instrumentation)
     }
-    lateinit var tesults: List<TransitionResult>
-    private var lastResult: TransitionResult? = null
 
     /**
-     * Runs a transition, returns a cached result if the transition has run before.
-     */
-    fun run(transition: TransitionRunner) {
-        if (transitionResults.containsKey(transition.testTag)) {
-            tesults = transitionResults[transition.testTag]
-                    ?: throw IllegalStateException("Results do not contain test tag " +
-                            transition.testTag)
-            return
+     * 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}"
         }
-        tesults = transition.run().results
-        /* Fail if we don't have any results due to jank */
-        Truth.assertWithMessage("No results to test because all transition runs were invalid " +
-                "because of Jank").that(tesults).isNotEmpty()
-        transitionResults[transition.testTag] = tesults
-    }
-
-    /**
-     * Runs a transition, returns a cached result if the transition has run before.
-     */
-    @Before
-    fun runTransition() {
-        run(transitionToRun)
-    }
-
-    /**
-     * Gets the transition that will be executed
-     */
-    abstract val transitionToRun: TransitionRunner
-
-    /**
-     * Goes through a list of transition results and checks assertions on each result.
-     */
-    fun checkResults(assertion: (TransitionResult) -> Unit) {
-        for (result in tesults) {
-            lastResult = result
-            assertion(result)
+        testTag += "__${Surface.rotationToString(beginRotation)}"
+        if (endRotation != beginRotation) {
+            testTag += "-${Surface.rotationToString(endRotation)}"
         }
-        lastResult = null
+        if (extraInfo.isNotEmpty()) {
+            testTag += "__$extraInfo"
+        }
+        return testTag
     }
 
-    /**
-     * Kludge to mark a file for saving. If `checkResults` fails, the last result is not
-     * cleared. This indicates the assertion failed for the result, so mark it for saving.
-     */
-    @After
-    fun markArtifactsForSaving() {
-        lastResult?.flagForSaving()
+    protected fun Flicker.setRotation(rotation: Int) {
+        try {
+            when (rotation) {
+                Surface.ROTATION_270 -> device.setOrientationLeft()
+                Surface.ROTATION_90 -> device.setOrientationRight()
+                Surface.ROTATION_0 -> device.setOrientationNatural()
+                else -> device.setOrientationNatural()
+            }
+            // Wait for animation to complete
+            SystemClock.sleep(1000)
+        } catch (e: RemoteException) {
+            throw RuntimeException(e)
+        }
     }
 
     companion object {
-        const val TAG = "FLICKER"
         const val NAVIGATION_BAR_WINDOW_TITLE = "NavigationBar"
         const val STATUS_BAR_WINDOW_TITLE = "StatusBar"
         const val DOCKED_STACK_DIVIDER = "DockedStackDivider"
-        private val transitionResults = mutableMapOf<String, List<TransitionResult>>()
-
-        /**
-         * Teardown any system settings and clean up test artifacts from the file system.
-         *
-         * Note: test artifacts for failed tests will remain on the device.
-         */
-        @AfterClass
-        @JvmStatic
-        fun teardown() {
-            AutomationUtils.setDefaultWait()
-            transitionResults.values
-                .flatten()
-                .forEach {
-                    if (it.canDelete()) {
-                        it.delete()
-                    } else {
-                        if (it.layersTraceExists()) {
-                            Log.e(TAG, "Layers trace saved to ${it.layersTracePath}")
-                        }
-                        if (it.windowManagerTraceExists()) {
-                            Log.e(TAG,
-                                    "WindowManager trace saved to ${it.windowManagerTracePath}")
-                        }
-                        if (it.screenCaptureVideoExists()) {
-                            Log.e(TAG,
-                                    "Screen capture video saved to ${it.screenCaptureVideoPath()}")
-                        }
-                    }
-                }
-        }
     }
-}
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/NonRotationTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/NonRotationTestBase.kt
index 1f8150c..e7d1f8e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/NonRotationTestBase.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/NonRotationTestBase.kt
@@ -17,52 +17,20 @@
 package com.android.server.wm.flicker
 
 import android.view.Surface
-import androidx.test.filters.FlakyTest
-import org.junit.Test
 import org.junit.runners.Parameterized
 
 abstract class NonRotationTestBase(
-    beginRotationName: String,
-    protected val beginRotation: Int
+    protected val rotationName: String,
+    protected val rotation: Int
 ) : FlickerTestBase() {
-    @FlakyTest(bugId = 141361128)
-    @Test
-    fun checkCoveredRegion_noUncoveredRegions() {
-        val displayBounds = WindowUtils.getDisplayBounds(beginRotation)
-        checkResults {
-            LayersTraceSubject.assertThat(it).coversRegion(
-                    displayBounds).forAllEntries()
-        }
-    }
-
-    @FlakyTest(bugId = 141361128)
-    @Test
-    fun checkVisibility_navBarLayerIsAlwaysVisible() {
-        checkResults {
-            LayersTraceSubject.assertThat(it)
-                    .showsLayer(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries()
-        }
-    }
-
-    @FlakyTest(bugId = 141361128)
-    @Test
-    fun checkVisibility_statusBarLayerIsAlwaysVisible() {
-        checkResults {
-            LayersTraceSubject.assertThat(it)
-                    .showsLayer(STATUS_BAR_WINDOW_TITLE).forAllEntries()
-        }
-    }
-
     companion object {
+        const val SCREENSHOT_LAYER = "RotationLayer"
+
         @Parameterized.Parameters(name = "{0}")
         @JvmStatic
         fun getParams(): Collection<Array<Any>> {
             val supportedRotations = intArrayOf(Surface.ROTATION_0, Surface.ROTATION_90)
-            val params: MutableCollection<Array<Any>> = ArrayList()
-            for (begin in supportedRotations) {
-                params.add(arrayOf(Surface.rotationToString(begin), begin))
-            }
-            return params
+            return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) }
         }
     }
-}
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/RotationTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/RotationTestBase.kt
index dfc3c07..3b67727 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/RotationTestBase.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/RotationTestBase.kt
@@ -17,8 +17,6 @@
 package com.android.server.wm.flicker
 
 import android.view.Surface
-import androidx.test.filters.FlakyTest
-import org.junit.Test
 import org.junit.runners.Parameterized
 
 abstract class RotationTestBase(
@@ -27,82 +25,7 @@
     protected val beginRotation: Int,
     protected val endRotation: Int
 ) : FlickerTestBase() {
-    @FlakyTest(bugId = 140855415)
-    @Test
-    fun checkVisibility_navBarWindowIsAlwaysVisible() {
-        checkResults {
-            WmTraceSubject.assertThat(it)
-                    .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries()
-        }
-    }
-
-    @FlakyTest(bugId = 140855415)
-    @Test
-    fun checkVisibility_statusBarWindowIsAlwaysVisible() {
-        checkResults {
-            WmTraceSubject.assertThat(it)
-                    .showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE).forAllEntries()
-        }
-    }
-
-    @Test
-    fun checkPosition_navBarLayerRotatesAndScales() {
-        val startingPos = WindowUtils.getNavigationBarPosition(beginRotation)
-        val endingPos = WindowUtils.getNavigationBarPosition(endRotation)
-        if (startingPos == endingPos) {
-            checkResults {
-                LayersTraceSubject.assertThat(it)
-                        .hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, startingPos)
-                        .forAllEntries()
-            }
-        } else {
-            checkResults {
-                LayersTraceSubject.assertThat(it)
-                        .hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, startingPos)
-                        .inTheBeginning()
-            }
-            checkResults {
-                LayersTraceSubject.assertThat(it)
-                        .hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, endingPos)
-                        .atTheEnd()
-            }
-        }
-    }
-
-    @Test
-    fun checkPosition_statusBarLayerRotatesScales() {
-        val startingPos = WindowUtils.getStatusBarPosition(beginRotation)
-        val endingPos = WindowUtils.getStatusBarPosition(endRotation)
-        checkResults {
-            LayersTraceSubject.assertThat(it)
-                    .hasVisibleRegion(STATUS_BAR_WINDOW_TITLE, startingPos)
-                    .inTheBeginning()
-            LayersTraceSubject.assertThat(it)
-                    .hasVisibleRegion(STATUS_BAR_WINDOW_TITLE, endingPos).atTheEnd()
-        }
-    }
-
-    @FlakyTest(bugId = 140855415)
-    @Test
-    fun checkVisibility_navBarLayerIsAlwaysVisible() {
-        checkResults {
-            LayersTraceSubject.assertThat(it)
-                    .showsLayer(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries()
-        }
-    }
-
-    @FlakyTest(bugId = 140855415)
-    @Test
-    fun checkVisibility_statusBarLayerIsAlwaysVisible() {
-        checkResults {
-            LayersTraceSubject.assertThat(it)
-                    .showsLayer(STATUS_BAR_WINDOW_TITLE).forAllEntries()
-        }
-    }
-
     companion object {
-        const val SCREENSHOT_LAYER = "RotationLayer"
-
         @Parameterized.Parameters(name = "{0}-{1}")
         @JvmStatic
         fun getParams(): Collection<Array<Any>> {
@@ -123,4 +46,4 @@
             return params
         }
     }
-}
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt
index 979cbea..aa0d7e0 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt
@@ -29,12 +29,18 @@
     open fun openIME(device: UiDevice) {
         val editText = device.wait(
                 Until.findObject(By.res(getPackage(), "plain_text_input")),
-                AutomationUtils.FIND_TIMEOUT)
+                FIND_TIMEOUT)
         Assert.assertNotNull("Text field not found, this usually happens when the device " +
                 "was left in an unknown state (e.g. in split screen)", editText)
         editText.click()
-        if (!AutomationUtils.waitForIME(device)) {
+        if (!device.waitForIME()) {
             Assert.fail("IME did not appear")
         }
     }
+
+    open fun closeIME(device: UiDevice) {
+        device.pressBack()
+        // Using only the AccessibilityInfo it is not possible to identify if the IME is active
+        device.waitForIdle(1000)
+    }
 }
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
index daee810..ca907d9 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
@@ -27,10 +27,10 @@
         Assert.assertNotNull("Pip button not found, this usually happens when the device " +
                 "was left in an unknown state (e.g. in split screen)", enterPipButton)
         enterPipButton.click()
-        AutomationUtils.hasPipWindow(device)
+        device.hasPipWindow()
     }
 
     fun closePipWindow(device: UiDevice) {
-        AutomationUtils.closePipWindow(device)
+        device.closePipWindow()
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt
index 814cdcf..80d0394 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt
@@ -16,11 +16,19 @@
 
 package com.android.server.wm.flicker.ime
 
-import androidx.test.filters.FlakyTest
+import android.view.Surface
 import androidx.test.filters.LargeTest
-import com.android.server.wm.flicker.CommonTransitions
-import com.android.server.wm.flicker.TransitionRunner
+import com.android.server.wm.flicker.dsl.flicker
 import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
+import com.android.server.wm.flicker.helpers.ImeAppHelper
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -35,33 +43,52 @@
 @RunWith(Parameterized::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 class CloseImeAutoOpenWindowToAppTest(
-    beginRotationName: String,
-    beginRotation: Int
-) : CloseImeWindowToAppTest(beginRotationName, beginRotation) {
-    init {
-        testApp = ImeAppAutoFocusHelper(instrumentation)
-    }
+    rotationName: String,
+    rotation: Int
+) : CloseImeWindowToAppTest(rotationName, rotation) {
+    override val testApp: ImeAppHelper
+        get() = ImeAppAutoFocusHelper(instrumentation)
 
-    override val transitionToRun: TransitionRunner
-        get() = CommonTransitions.editTextLoseFocusToApp(testApp as ImeAppAutoFocusHelper,
-                instrumentation, uiDevice, beginRotation)
-                .includeJankyRuns().build()
-
-    @FlakyTest(bugId = 141458352)
     @Test
-    override fun checkVisibility_imeLayerBecomesInvisible() {
-        super.checkVisibility_imeLayerBecomesInvisible()
-    }
+    override fun test() {
+        flicker(instrumentation) {
+            withTag { buildTestTag("imeToAppAutoOpen", testApp, rotation) }
+            repeat { 1 }
+            setup {
+                eachRun {
+                    device.wakeUpAndGoToHomeScreen()
+                    this.setRotation(rotation)
+                    testApp.open()
+                    testApp.openIME(device)
+                }
+            }
+            teardown {
+                eachRun {
+                    testApp.exit()
+                    this.setRotation(Surface.ROTATION_0)
+                }
+            }
+            transitions {
+                device.pressBack()
+                device.waitForIdle()
+            }
+            assertions {
+                windowManagerTrace {
+                    navBarWindowIsAlwaysVisible()
+                    statusBarWindowIsAlwaysVisible()
+                    imeAppWindowIsAlwaysVisible(testApp, bugId = 141458352)
+                }
 
-    @FlakyTest(bugId = 141458352)
-    @Test
-    override fun checkVisibility_imeAppLayerIsAlwaysVisible() {
-        super.checkVisibility_imeAppLayerIsAlwaysVisible()
-    }
-
-    @FlakyTest(bugId = 141458352)
-    @Test
-    override fun checkVisibility_imeAppWindowIsAlwaysVisible() {
-        super.checkVisibility_imeAppWindowIsAlwaysVisible()
+                layersTrace {
+                    navBarLayerIsAlwaysVisible()
+                    statusBarLayerIsAlwaysVisible()
+                    noUncoveredRegions(rotation)
+                    navBarLayerRotatesAndScales(rotation)
+                    statusBarLayerRotatesScales(rotation)
+                    imeLayerBecomesInvisible(bugId = 141458352)
+                    imeAppLayerIsAlwaysVisible(testApp, bugId = 141458352)
+                }
+            }
+        }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
index c2025b6..31d1fd3 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
@@ -16,11 +16,19 @@
 
 package com.android.server.wm.flicker.ime
 
-import androidx.test.filters.FlakyTest
+import android.view.Surface
 import androidx.test.filters.LargeTest
-import com.android.server.wm.flicker.CommonTransitions
-import com.android.server.wm.flicker.TransitionRunner
+import com.android.server.wm.flicker.dsl.flicker
 import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
+import com.android.server.wm.flicker.helpers.ImeAppHelper
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -35,33 +43,53 @@
 @RunWith(Parameterized::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 class CloseImeAutoOpenWindowToHomeTest(
-    beginRotationName: String,
-    beginRotation: Int
-) : CloseImeWindowToHomeTest(beginRotationName, beginRotation) {
-    init {
-        testApp = ImeAppAutoFocusHelper(instrumentation)
-    }
+    rotationName: String,
+    rotation: Int
+) : CloseImeWindowToHomeTest(rotationName, rotation) {
+    override val testApp: ImeAppHelper
+        get() = ImeAppAutoFocusHelper(instrumentation)
 
-    override val transitionToRun: TransitionRunner
-        get() = CommonTransitions.editTextLoseFocusToHome(testApp as ImeAppAutoFocusHelper,
-                instrumentation, uiDevice, beginRotation)
-                .includeJankyRuns().build()
-
-    @FlakyTest(bugId = 141458352)
     @Test
-    override fun checkVisibility_imeWindowBecomesInvisible() {
-        super.checkVisibility_imeWindowBecomesInvisible()
-    }
+    override fun test() {
+        flicker(instrumentation) {
+            withTag { buildTestTag("imeToHomeAutoOpen", testApp, rotation) }
+            repeat { 1 }
+            setup {
+                eachRun {
+                    device.wakeUpAndGoToHomeScreen()
+                    this.setRotation(rotation)
+                    testApp.open()
+                    testApp.openIME(device)
+                }
+            }
+            teardown {
+                eachRun {
+                    testApp.exit()
+                    this.setRotation(Surface.ROTATION_0)
+                }
+            }
+            transitions {
+                device.pressHome()
+                device.waitForIdle()
+            }
+            assertions {
+                windowManagerTrace {
+                    navBarWindowIsAlwaysVisible()
+                    statusBarWindowIsAlwaysVisible()
+                    imeWindowBecomesInvisible(bugId = 141458352)
+                    imeAppWindowBecomesInvisible(testApp, bugId = 157449248)
+                }
 
-    @FlakyTest(bugId = 141458352)
-    @Test
-    override fun checkVisibility_imeLayerBecomesInvisible() {
-        super.checkVisibility_imeLayerBecomesInvisible()
-    }
-
-    @FlakyTest(bugId = 157449248)
-    @Test
-    override fun checkVisibility_imeAppWindowBecomesInvisible() {
-        super.checkVisibility_imeAppWindowBecomesInvisible()
+                layersTrace {
+                    navBarLayerIsAlwaysVisible()
+                    statusBarLayerIsAlwaysVisible()
+                    noUncoveredRegions(rotation)
+                    navBarLayerRotatesAndScales(rotation)
+                    statusBarLayerRotatesScales(rotation)
+                    imeLayerBecomesInvisible(bugId = 141458352)
+                    imeAppLayerBecomesInvisible(testApp, bugId = 153739621)
+                }
+            }
+        }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt
index b38262e..67c46d3 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt
@@ -16,14 +16,19 @@
 
 package com.android.server.wm.flicker.ime
 
-import androidx.test.filters.FlakyTest
+import android.view.Surface
 import androidx.test.filters.LargeTest
-import com.android.server.wm.flicker.CommonTransitions
-import com.android.server.wm.flicker.LayersTraceSubject
 import com.android.server.wm.flicker.NonRotationTestBase
-import com.android.server.wm.flicker.TransitionRunner
-import com.android.server.wm.flicker.WmTraceSubject
+import com.android.server.wm.flicker.dsl.flicker
 import com.android.server.wm.flicker.helpers.ImeAppHelper
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -38,49 +43,51 @@
 @RunWith(Parameterized::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 open class CloseImeWindowToAppTest(
-    beginRotationName: String,
-    beginRotation: Int
-) : NonRotationTestBase(beginRotationName, beginRotation) {
-    init {
-        testApp = ImeAppHelper(instrumentation)
-    }
-
-    override val transitionToRun: TransitionRunner
-        get() = CommonTransitions.editTextLoseFocusToApp(testApp as ImeAppHelper,
-                instrumentation, uiDevice, beginRotation)
-                .includeJankyRuns().build()
-
-    @FlakyTest
-    @Test
-    open fun checkVisibility_imeLayerBecomesInvisible() {
-        checkResults {
-            LayersTraceSubject.assertThat(it)
-                    .showsLayer(IME_WINDOW_TITLE)
-                    .then()
-                    .hidesLayer(IME_WINDOW_TITLE)
-                    .forAllEntries()
-        }
-    }
+    rotationName: String,
+    rotation: Int
+) : NonRotationTestBase(rotationName, rotation) {
+    open val testApp = ImeAppHelper(instrumentation)
 
     @Test
-    open fun checkVisibility_imeAppLayerIsAlwaysVisible() {
-        checkResults {
-            LayersTraceSubject.assertThat(it)
-                    .showsLayer(testApp.getPackage())
-                    .forAllEntries()
+    open fun test() {
+        flicker(instrumentation) {
+            withTag { buildTestTag("imeToApp", testApp, rotation) }
+            repeat { 1 }
+            setup {
+                eachRun {
+                    device.wakeUpAndGoToHomeScreen()
+                    this.setRotation(rotation)
+                    testApp.open()
+                    testApp.openIME(device)
+                }
+            }
+            teardown {
+                eachRun {
+                    testApp.exit()
+                    this.setRotation(Surface.ROTATION_0)
+                }
+            }
+            transitions {
+                device.pressBack()
+                device.waitForIdle()
+            }
+            assertions {
+                windowManagerTrace {
+                    navBarWindowIsAlwaysVisible()
+                    statusBarWindowIsAlwaysVisible()
+                    imeAppWindowIsAlwaysVisible(testApp)
+                }
+
+                layersTrace {
+                    navBarLayerIsAlwaysVisible()
+                    statusBarLayerIsAlwaysVisible()
+                    noUncoveredRegions(rotation)
+                    navBarLayerRotatesAndScales(rotation)
+                    statusBarLayerRotatesScales(rotation)
+                    imeLayerBecomesInvisible(enabled = false)
+                    imeAppLayerIsAlwaysVisible(testApp)
+                }
+            }
         }
     }
-
-    @Test
-    open fun checkVisibility_imeAppWindowIsAlwaysVisible() {
-        checkResults {
-            WmTraceSubject.assertThat(it)
-                    .showsAppWindowOnTop(testApp.getPackage())
-                    .forAllEntries()
-        }
-    }
-
-    companion object {
-        const val IME_WINDOW_TITLE = "InputMethod"
-    }
-}
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
index ca04bab..b643ec2 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
@@ -16,20 +16,26 @@
 
 package com.android.server.wm.flicker.ime
 
-import androidx.test.filters.FlakyTest
+import android.view.Surface
 import androidx.test.filters.LargeTest
-import com.android.server.wm.flicker.CommonTransitions
-import com.android.server.wm.flicker.LayersTraceSubject
 import com.android.server.wm.flicker.NonRotationTestBase
-import com.android.server.wm.flicker.TransitionRunner
-import com.android.server.wm.flicker.WmTraceSubject
+import com.android.server.wm.flicker.dsl.flicker
 import com.android.server.wm.flicker.helpers.ImeAppHelper
+import com.android.server.wm.flicker.helpers.openQuickstep
+import com.android.server.wm.flicker.helpers.reopenAppFromOverview
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.MethodSorters
 import org.junit.runners.Parameterized
-
 /**
  * Test IME window closing to home transitions.
  * To run this test: `atest FlickerTests:CloseImeWindowToHomeTest`
@@ -38,67 +44,60 @@
 @RunWith(Parameterized::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 open class CloseImeWindowToHomeTest(
-    beginRotationName: String,
-    beginRotation: Int
-) : NonRotationTestBase(beginRotationName, beginRotation) {
-    init {
-        testApp = ImeAppHelper(instrumentation)
-    }
-
-    override val transitionToRun: TransitionRunner
-        get() = CommonTransitions.editTextLoseFocusToHome(testApp as ImeAppHelper,
-                instrumentation, uiDevice, beginRotation)
-                .includeJankyRuns().build()
+    rotationName: String,
+    rotation: Int
+) : NonRotationTestBase(rotationName, rotation) {
+    open val testApp = ImeAppHelper(instrumentation)
 
     @Test
-    open fun checkVisibility_imeWindowBecomesInvisible() {
-        checkResults {
-            WmTraceSubject.assertThat(it)
-                    .showsNonAppWindow(IME_WINDOW_TITLE)
-                    .then()
-                    .hidesNonAppWindow(IME_WINDOW_TITLE)
-                    .forAllEntries()
+    open fun test() {
+        flicker(instrumentation) {
+            withTag { buildTestTag("imeToHome", testApp, rotation) }
+            repeat { 1 }
+            setup {
+                test {
+                    device.wakeUpAndGoToHomeScreen()
+                    this.setRotation(rotation)
+                    testApp.open()
+                }
+                eachRun {
+                    device.openQuickstep()
+                    device.reopenAppFromOverview()
+                    this.setRotation(rotation)
+                    testApp.openIME(device)
+                }
+            }
+            transitions {
+                device.pressHome()
+                device.waitForIdle()
+            }
+            teardown {
+                eachRun {
+                    device.pressHome()
+                }
+                test {
+                    testApp.exit()
+                    this.setRotation(Surface.ROTATION_0)
+                }
+            }
+            assertions {
+                windowManagerTrace {
+                    navBarWindowIsAlwaysVisible()
+                    statusBarWindowIsAlwaysVisible()
+                    imeWindowBecomesInvisible()
+                    imeAppWindowBecomesInvisible(testApp)
+                }
+
+                layersTrace {
+                    navBarLayerIsAlwaysVisible()
+                    statusBarLayerIsAlwaysVisible()
+                    noUncoveredRegions(rotation)
+                    navBarLayerRotatesAndScales(rotation, Surface.ROTATION_0)
+                    statusBarLayerRotatesScales(rotation, Surface.ROTATION_0)
+                    imeLayerBecomesInvisible(bugId = 153739621)
+                    imeAppLayerBecomesInvisible(testApp, bugId = 153739621)
+                }
+            }
         }
     }
-
-    @FlakyTest(bugId = 153739621)
-    @Test
-    open fun checkVisibility_imeLayerBecomesInvisible() {
-        checkResults {
-            LayersTraceSubject.assertThat(it)
-                    .skipUntilFirstAssertion()
-                    .showsLayer(IME_WINDOW_TITLE)
-                    .then()
-                    .hidesLayer(IME_WINDOW_TITLE)
-                    .forAllEntries()
-        }
-    }
-
-    @FlakyTest(bugId = 153739621)
-    @Test
-    fun checkVisibility_imeAppLayerBecomesInvisible() {
-        checkResults {
-            LayersTraceSubject.assertThat(it)
-                    .skipUntilFirstAssertion()
-                    .showsLayer(testApp.getPackage())
-                    .then()
-                    .hidesLayer(testApp.getPackage())
-                    .forAllEntries()
-        }
-    }
-
-    @Test
-    open fun checkVisibility_imeAppWindowBecomesInvisible() {
-        checkResults {
-            WmTraceSubject.assertThat(it)
-                    .showsAppWindowOnTop(testApp.getPackage())
-                    .then()
-                    .appWindowNotOnTop(testApp.getPackage())
-                    .forAllEntries()
-        }
-    }
-
-    companion object {
-        const val IME_WINDOW_TITLE: String = "InputMethod"
-    }
-}
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ImeAssertions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ImeAssertions.kt
new file mode 100644
index 0000000..b2be54f
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ImeAssertions.kt
@@ -0,0 +1,102 @@
+/*
+ * 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.server.wm.flicker.ime
+
+import android.platform.helpers.IAppHelper
+import com.android.server.wm.flicker.dsl.LayersAssertion
+import com.android.server.wm.flicker.dsl.WmAssertion
+
+const val IME_WINDOW_TITLE = "InputMethod"
+
+@JvmOverloads
+fun LayersAssertion.imeLayerBecomesVisible(
+    bugId: Int = 0,
+    enabled: Boolean = bugId == 0
+) {
+    all("imeLayerBecomesVisible", enabled, bugId) {
+        this.hidesLayer(IME_WINDOW_TITLE)
+                .then()
+                .showsLayer(IME_WINDOW_TITLE)
+    }
+}
+
+fun LayersAssertion.imeLayerBecomesInvisible(
+    bugId: Int = 0,
+    enabled: Boolean = bugId == 0
+) {
+    all("imeLayerBecomesInvisible", enabled, bugId) {
+        this.showsLayer(IME_WINDOW_TITLE)
+                .then()
+                .hidesLayer(IME_WINDOW_TITLE)
+    }
+}
+
+fun LayersAssertion.imeAppLayerIsAlwaysVisible(
+    testApp: IAppHelper,
+    bugId: Int = 0,
+    enabled: Boolean = bugId == 0
+) {
+    all("imeAppLayerIsAlwaysVisible", enabled, bugId) {
+        this.showsLayer(testApp.getPackage())
+    }
+}
+
+fun WmAssertion.imeAppWindowIsAlwaysVisible(
+    testApp: IAppHelper,
+    bugId: Int = 0,
+    enabled: Boolean = bugId == 0
+) {
+    all("imeAppWindowIsAlwaysVisible", enabled, bugId) {
+        this.showsAppWindowOnTop(testApp.getPackage())
+    }
+}
+
+fun WmAssertion.imeWindowBecomesInvisible(
+    bugId: Int = 0,
+    enabled: Boolean = bugId == 0
+) {
+    all("imeWindowBecomesInvisible", enabled, bugId) {
+        this.showsNonAppWindow(IME_WINDOW_TITLE)
+                .then()
+                .hidesNonAppWindow(IME_WINDOW_TITLE)
+    }
+}
+
+fun WmAssertion.imeAppWindowBecomesInvisible(
+    testApp: IAppHelper,
+    bugId: Int = 0,
+    enabled: Boolean = bugId == 0
+) {
+    all("imeAppWindowBecomesInvisible", enabled, bugId) {
+        this.showsAppWindowOnTop(testApp.getPackage())
+                .then()
+                .appWindowNotOnTop(testApp.getPackage())
+    }
+}
+
+fun LayersAssertion.imeAppLayerBecomesInvisible(
+    testApp: IAppHelper,
+    bugId: Int = 0,
+    enabled: Boolean = bugId == 0
+) {
+    all("imeAppLayerBecomesInvisible", enabled, bugId) {
+        this.skipUntilFirstAssertion()
+                .showsLayer(testApp.getPackage())
+                .then()
+                .hidesLayer(testApp.getPackage())
+    }
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt
index c7731f3..5874a07 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt
@@ -16,13 +16,19 @@
 
 package com.android.server.wm.flicker.ime
 
+import android.view.Surface
 import androidx.test.filters.LargeTest
-import com.android.server.wm.flicker.CommonTransitions
-import com.android.server.wm.flicker.LayersTraceSubject
 import com.android.server.wm.flicker.NonRotationTestBase
-import com.android.server.wm.flicker.TransitionRunner
-import com.android.server.wm.flicker.WmTraceSubject
+import com.android.server.wm.flicker.dsl.flicker
 import com.android.server.wm.flicker.helpers.ImeAppHelper
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -37,38 +43,58 @@
 @RunWith(Parameterized::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 class OpenImeWindowTest(
-    beginRotationName: String,
-    beginRotation: Int
-) : NonRotationTestBase(beginRotationName, beginRotation) {
-    init {
-        testApp = ImeAppHelper(instrumentation)
-    }
-
-    override val transitionToRun: TransitionRunner
-        get() = CommonTransitions.editTextSetFocus(testApp as ImeAppHelper,
-                instrumentation, uiDevice, beginRotation)
-                .includeJankyRuns().build()
-
+    rotationName: String,
+    rotation: Int
+) : NonRotationTestBase(rotationName, rotation) {
     @Test
-    fun checkVisibility_imeWindowBecomesVisible() {
-        checkResults {
-            WmTraceSubject.assertThat(it)
-                    .skipUntilFirstAssertion()
-                    .hidesNonAppWindow(IME_WINDOW_TITLE)
-                    .then()
-                    .showsNonAppWindow(IME_WINDOW_TITLE)
-                    .forAllEntries()
-        }
-    }
+    fun test() {
+        val testApp = ImeAppHelper(instrumentation)
 
-    @Test
-    fun checkVisibility_imeLayerBecomesVisible() {
-        checkResults {
-            LayersTraceSubject.assertThat(it)
-                    .hidesLayer(IME_WINDOW_TITLE)
-                    .then()
-                    .showsLayer(IME_WINDOW_TITLE)
-                    .forAllEntries()
+        flicker(instrumentation) {
+            withTag { buildTestTag("openIme", testApp, rotation) }
+            repeat { 1 }
+            setup {
+                test {
+                    device.wakeUpAndGoToHomeScreen()
+                    this.setRotation(rotation)
+                    testApp.open()
+                }
+            }
+            transitions {
+                testApp.openIME(device)
+            }
+            teardown {
+                eachRun {
+                    testApp.closeIME(device)
+                }
+                test {
+                    testApp.exit()
+                    this.setRotation(Surface.ROTATION_0)
+                }
+            }
+            assertions {
+                windowManagerTrace {
+                    navBarWindowIsAlwaysVisible()
+                    statusBarWindowIsAlwaysVisible()
+
+                    all("imeWindowBecomesVisible") {
+                        this.skipUntilFirstAssertion()
+                            .hidesNonAppWindow(IME_WINDOW_TITLE)
+                            .then()
+                            .showsNonAppWindow(IME_WINDOW_TITLE)
+                    }
+                }
+
+                layersTrace {
+                    navBarLayerIsAlwaysVisible()
+                    statusBarLayerIsAlwaysVisible()
+                    noUncoveredRegions(rotation)
+                    navBarLayerRotatesAndScales(rotation)
+                    statusBarLayerRotatesScales(rotation)
+
+                    imeLayerBecomesVisible()
+                }
+            }
         }
     }
 
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
index 88b8854..1240e0d 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
@@ -16,14 +16,17 @@
 
 package com.android.server.wm.flicker.launch
 
-import androidx.test.filters.FlakyTest
+import android.view.Surface
 import androidx.test.filters.LargeTest
-import com.android.server.wm.flicker.CommonTransitions
-import com.android.server.wm.flicker.LayersTraceSubject
-import com.android.server.wm.flicker.NonRotationTestBase
-import com.android.server.wm.flicker.StandardAppHelper
-import com.android.server.wm.flicker.TransitionRunner
-import com.android.server.wm.flicker.WmTraceSubject
+import com.android.server.wm.flicker.dsl.flicker
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -38,50 +41,49 @@
 @RunWith(Parameterized::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 class OpenAppColdTest(
-    beginRotationName: String,
-    beginRotation: Int
-) : NonRotationTestBase(beginRotationName, beginRotation) {
-    init {
-        testApp = StandardAppHelper(instrumentation,
-                "com.android.server.wm.flicker.testapp", "SimpleApp")
-    }
-
-    override val transitionToRun: TransitionRunner
-        get() = CommonTransitions.openAppCold(testApp, instrumentation, uiDevice, beginRotation)
-                .includeJankyRuns().build()
-
+    rotationName: String,
+    rotation: Int
+) : OpenAppTestBase(rotationName, rotation) {
     @Test
-    fun checkVisibility_wallpaperWindowBecomesInvisible() {
-        checkResults {
-            WmTraceSubject.assertThat(it)
-                    .showsBelowAppWindow("Wallpaper")
-                    .then()
-                    .hidesBelowAppWindow("Wallpaper")
-                    .forAllEntries()
-        }
-    }
+    fun test() {
+        flicker(instrumentation) {
+            withTag { buildTestTag("openAppCold", testApp, rotation) }
+            repeat { 1 }
+            setup {
+                test {
+                    device.wakeUpAndGoToHomeScreen()
+                }
+                eachRun {
+                    this.setRotation(rotation)
+                }
+            }
+            transitions {
+                testApp.open()
+            }
+            teardown {
+                eachRun {
+                    testApp.exit()
+                    this.setRotation(Surface.ROTATION_0)
+                }
+            }
+            assertions {
+                windowManagerTrace {
+                    navBarWindowIsAlwaysVisible()
+                    statusBarWindowIsAlwaysVisible()
+                    appWindowReplacesLauncherAsTopWindow(bugId = 141361128)
+                    wallpaperWindowBecomesInvisible()
+                }
 
-    @FlakyTest(bugId = 140855415)
-    @Test
-    fun checkZOrder_appWindowReplacesLauncherAsTopWindow() {
-        checkResults {
-            WmTraceSubject.assertThat(it)
-                    .showsAppWindowOnTop(
-                            "com.android.launcher3/.Launcher")
-                    .then()
-                    .showsAppWindowOnTop(testApp.getPackage())
-                    .forAllEntries()
-        }
-    }
-
-    @Test
-    fun checkVisibility_wallpaperLayerBecomesInvisible() {
-        checkResults {
-            LayersTraceSubject.assertThat(it)
-                    .showsLayer("Wallpaper")
-                    .then()
-                    .replaceVisibleLayer("Wallpaper", testApp.getPackage())
-                    .forAllEntries()
+                layersTrace {
+                    noUncoveredRegions(rotation, bugId = 141361128)
+                    // During testing the launcher is always in portrait mode
+                    navBarLayerRotatesAndScales(Surface.ROTATION_0, rotation)
+                    statusBarLayerRotatesScales(Surface.ROTATION_0, rotation)
+                    navBarLayerIsAlwaysVisible(bugId = 141361128)
+                    statusBarLayerIsAlwaysVisible(bugId = 141361128)
+                    wallpaperLayerBecomesInvisible(bugId = 141361128)
+                }
+            }
         }
     }
 }
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTestBase.kt
new file mode 100644
index 0000000..3cec077
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTestBase.kt
@@ -0,0 +1,64 @@
+/*
+ * 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.server.wm.flicker.launch
+
+import com.android.server.wm.flicker.NonRotationTestBase
+import com.android.server.wm.flicker.StandardAppHelper
+import com.android.server.wm.flicker.dsl.LayersAssertion
+import com.android.server.wm.flicker.dsl.WmAssertion
+
+abstract class OpenAppTestBase(
+    rotationName: String,
+    rotation: Int
+) : NonRotationTestBase(rotationName, rotation) {
+    protected val testApp = StandardAppHelper(instrumentation,
+            "com.android.server.wm.flicker.testapp", "SimpleApp")
+
+    protected fun WmAssertion.wallpaperWindowBecomesInvisible(
+        bugId: Int = 0,
+        enabled: Boolean = bugId == 0
+    ) {
+        all("wallpaperWindowBecomesInvisible", enabled, bugId) {
+            this.showsBelowAppWindow("Wallpaper")
+                    .then()
+                    .hidesBelowAppWindow("Wallpaper")
+        }
+    }
+
+    protected fun WmAssertion.appWindowReplacesLauncherAsTopWindow(
+        bugId: Int = 0,
+        enabled: Boolean = bugId == 0
+    ) {
+        all("appWindowReplacesLauncherAsTopWindow", enabled, bugId) {
+            this.showsAppWindowOnTop(
+                    "Launcher")
+                    .then()
+                    .showsAppWindowOnTop(testApp.getPackage())
+        }
+    }
+
+    protected fun LayersAssertion.wallpaperLayerBecomesInvisible(
+        bugId: Int = 0,
+        enabled: Boolean = bugId == 0
+    ) {
+        all("appWindowReplacesLauncherAsTopWindow", enabled, bugId) {
+            this.showsLayer("Wallpaper")
+                    .then()
+                    .replaceVisibleLayer("Wallpaper", testApp.getPackage())
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
index f0bc3f0..98413a1 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
@@ -16,14 +16,18 @@
 
 package com.android.server.wm.flicker.launch
 
-import androidx.test.filters.FlakyTest
+import android.view.Surface
 import androidx.test.filters.LargeTest
-import com.android.server.wm.flicker.CommonTransitions
-import com.android.server.wm.flicker.LayersTraceSubject
-import com.android.server.wm.flicker.NonRotationTestBase
 import com.android.server.wm.flicker.StandardAppHelper
-import com.android.server.wm.flicker.TransitionRunner
-import com.android.server.wm.flicker.WmTraceSubject
+import com.android.server.wm.flicker.dsl.flicker
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -38,50 +42,56 @@
 @RunWith(Parameterized::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 class OpenAppWarmTest(
-    beginRotationName: String,
-    beginRotation: Int
-) : NonRotationTestBase(beginRotationName, beginRotation) {
-    init {
-        testApp = StandardAppHelper(instrumentation,
+    rotationName: String,
+    rotation: Int
+) : OpenAppTestBase(rotationName, rotation) {
+    @Test
+    fun test() {
+        val testApp = StandardAppHelper(instrumentation,
                 "com.android.server.wm.flicker.testapp", "SimpleApp")
-    }
 
-    override val transitionToRun: TransitionRunner
-        get() = CommonTransitions.openAppWarm(testApp, instrumentation, uiDevice, beginRotation)
-                .includeJankyRuns().build()
+        flicker(instrumentation) {
+            withTag { buildTestTag("openAppWarm", testApp, rotation) }
+            repeat { 1 }
+            setup {
+                test {
+                    device.wakeUpAndGoToHomeScreen()
+                    testApp.open()
+                }
+                eachRun {
+                    device.pressHome()
+                    this.setRotation(rotation)
+                }
+            }
+            transitions {
+                testApp.open()
+            }
+            teardown {
+                eachRun {
+                    this.setRotation(Surface.ROTATION_0)
+                }
+                test {
+                    testApp.exit()
+                }
+            }
+            assertions {
+                windowManagerTrace {
+                    navBarWindowIsAlwaysVisible()
+                    statusBarWindowIsAlwaysVisible()
+                    appWindowReplacesLauncherAsTopWindow(bugId = 141361128)
+                    wallpaperWindowBecomesInvisible(enabled = false)
+                }
 
-    @Test
-    fun checkVisibility_wallpaperBecomesInvisible() {
-        checkResults {
-            WmTraceSubject.assertThat(it)
-                    .showsBelowAppWindow("Wallpaper")
-                    .then()
-                    .hidesBelowAppWindow("Wallpaper")
-                    .forAllEntries()
+                layersTrace {
+                    noUncoveredRegions(rotation, bugId = 141361128)
+                    // During testing the launcher is always in portrait mode
+                    navBarLayerRotatesAndScales(Surface.ROTATION_0, rotation)
+                    statusBarLayerRotatesScales(Surface.ROTATION_0, rotation)
+                    navBarLayerIsAlwaysVisible(bugId = 141361128)
+                    statusBarLayerIsAlwaysVisible(bugId = 141361128)
+                    wallpaperLayerBecomesInvisible(bugId = 141361128)
+                }
+            }
         }
     }
-
-    @FlakyTest(bugId = 140855415)
-    @Test
-    fun checkZOrder_appWindowReplacesLauncherAsTopWindow() {
-        checkResults {
-            WmTraceSubject.assertThat(it)
-                    .showsAppWindowOnTop(
-                            "com.android.launcher3/.Launcher")
-                    .then()
-                    .showsAppWindowOnTop(testApp.getPackage())
-                    .forAllEntries()
-        }
-    }
-
-    @Test
-    fun checkVisibility_wallpaperLayerBecomesInvisible() {
-        checkResults {
-            LayersTraceSubject.assertThat(it)
-                    .showsLayer("Wallpaper")
-                    .then()
-                    .replaceVisibleLayer("Wallpaper", testApp.getPackage())
-                    .forAllEntries()
-        }
-    }
-}
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipTestBase.kt
index 79321f9..4afabd4 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipTestBase.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipTestBase.kt
@@ -16,66 +16,36 @@
 
 package com.android.server.wm.flicker.pip
 
-import androidx.test.InstrumentationRegistry
-import androidx.test.filters.LargeTest
-import androidx.test.uiautomator.UiDevice
-import com.android.server.wm.flicker.LayersTraceSubject
+import com.android.server.wm.flicker.dsl.LayersAssertion
 import com.android.server.wm.flicker.NonRotationTestBase
-import com.android.server.wm.flicker.WmTraceSubject
-import com.android.server.wm.flicker.helpers.AutomationUtils
+import com.android.server.wm.flicker.dsl.WmAssertion
 import com.android.server.wm.flicker.helpers.PipAppHelper
-import org.junit.AfterClass
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
 
-@LargeTest
-@RunWith(Parameterized::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
 abstract class PipTestBase(
-    beginRotationName: String,
-    beginRotation: Int
-) : NonRotationTestBase(beginRotationName, beginRotation) {
-    init {
-        testApp = PipAppHelper(instrumentation)
-    }
+    rotationName: String,
+    rotation: Int
+) : NonRotationTestBase(rotationName, rotation) {
+    protected val testApp = PipAppHelper(instrumentation)
 
-    @Test
-    fun checkVisibility_pipWindowBecomesVisible() {
-        checkResults {
-            WmTraceSubject.assertThat(it)
-                    .skipUntilFirstAssertion()
+    protected fun WmAssertion.pipWindowBecomesVisible() {
+        all("pipWindowBecomesVisible") {
+            this.skipUntilFirstAssertion()
                     .showsAppWindowOnTop(sPipWindowTitle)
                     .then()
                     .hidesAppWindow(sPipWindowTitle)
-                    .forAllEntries()
         }
     }
 
-    @Test
-    fun checkVisibility_pipLayerBecomesVisible() {
-        checkResults {
-            LayersTraceSubject.assertThat(it)
-                    .skipUntilFirstAssertion()
+    protected fun LayersAssertion.pipLayerBecomesVisible() {
+        all("pipLayerBecomesVisible") {
+            this.skipUntilFirstAssertion()
                     .showsLayer(sPipWindowTitle)
                     .then()
                     .hidesLayer(sPipWindowTitle)
-                    .forAllEntries()
         }
     }
 
     companion object {
         const val sPipWindowTitle = "PipMenuActivity"
-
-        @AfterClass
-        @JvmStatic
-        fun teardown() {
-            val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
-            if (AutomationUtils.hasPipWindow(device)) {
-                AutomationUtils.closePipWindow(device)
-            }
-        }
     }
-}
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToAppTest.kt
index 89ffb7a..e5a73f7 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToAppTest.kt
@@ -16,12 +16,21 @@
 
 package com.android.server.wm.flicker.pip
 
+import android.view.Surface
 import androidx.test.filters.FlakyTest
 import androidx.test.filters.LargeTest
-import com.android.server.wm.flicker.CommonTransitions
-import com.android.server.wm.flicker.TransitionRunner
-import com.android.server.wm.flicker.WmTraceSubject
-import com.android.server.wm.flicker.helpers.PipAppHelper
+import com.android.server.wm.flicker.dsl.flicker
+import com.android.server.wm.flicker.helpers.closePipWindow
+import com.android.server.wm.flicker.helpers.expandPipWindow
+import com.android.server.wm.flicker.helpers.hasPipWindow
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -37,27 +46,55 @@
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @FlakyTest(bugId = 152738416)
 class PipToAppTest(
-    beginRotationName: String,
-    beginRotation: Int
-) : PipTestBase(beginRotationName, beginRotation) {
-    override val transitionToRun: TransitionRunner
-        get() = CommonTransitions.exitPipModeToApp(testApp as PipAppHelper, instrumentation,
-                uiDevice, beginRotation)
-                .includeJankyRuns().build()
-
+    rotationName: String,
+    rotation: Int
+) : PipTestBase(rotationName, rotation) {
     @Test
-    fun checkVisibility_backgroundWindowVisibleBehindPipLayer() {
-        checkResults {
-            WmTraceSubject.assertThat(it)
-                    .skipUntilFirstAssertion()
-                    .showsAppWindowOnTop(sPipWindowTitle)
-                    .then()
-                    .showsBelowAppWindow("Wallpaper")
-                    .then()
-                    .showsAppWindowOnTop(testApp.getPackage())
-                    .then()
-                    .appWindowNotOnTop(testApp.getPackage())
-                    .forAllEntries()
+    fun test() {
+        flicker(instrumentation) {
+            withTag { buildTestTag("exitPipModeToApp", testApp, rotation) }
+            repeat { 1 }
+            setup {
+                eachRun {
+                    device.wakeUpAndGoToHomeScreen()
+                }
+            }
+            teardown {
+                eachRun {
+                    testApp.exit()
+                    this.setRotation(Surface.ROTATION_0)
+                }
+                test {
+                    if (device.hasPipWindow()) {
+                        device.closePipWindow()
+                    }
+                }
+            }
+            transitions {
+                device.pressHome()
+                this.setRotation(rotation)
+                testApp.open()
+                testApp.clickEnterPipButton(device)
+                device.expandPipWindow()
+                device.waitForIdle()
+                testApp.exit()
+            }
+            assertions {
+                windowManagerTrace {
+                    navBarWindowIsAlwaysVisible()
+                    statusBarWindowIsAlwaysVisible()
+                    pipWindowBecomesVisible()
+                }
+
+                layersTrace {
+                    navBarLayerIsAlwaysVisible()
+                    statusBarLayerIsAlwaysVisible()
+                    noUncoveredRegions(rotation)
+                    navBarLayerRotatesAndScales(rotation)
+                    statusBarLayerRotatesScales(rotation)
+                    pipLayerBecomesVisible()
+                }
+            }
         }
     }
-}
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToHomeTest.kt
index 8591360..f6d9ce2 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToHomeTest.kt
@@ -16,12 +16,20 @@
 
 package com.android.server.wm.flicker.pip
 
+import android.view.Surface
 import androidx.test.filters.FlakyTest
 import androidx.test.filters.LargeTest
-import com.android.server.wm.flicker.CommonTransitions
-import com.android.server.wm.flicker.TransitionRunner
-import com.android.server.wm.flicker.WmTraceSubject
-import com.android.server.wm.flicker.helpers.PipAppHelper
+import com.android.server.wm.flicker.dsl.flicker
+import com.android.server.wm.flicker.helpers.closePipWindow
+import com.android.server.wm.flicker.helpers.hasPipWindow
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -37,24 +45,63 @@
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @FlakyTest(bugId = 152738416)
 class PipToHomeTest(
-    beginRotationName: String,
-    beginRotation: Int
-) : PipTestBase(beginRotationName, beginRotation) {
-    override val transitionToRun: TransitionRunner
-        get() = CommonTransitions.exitPipModeToHome(testApp as PipAppHelper, instrumentation,
-                uiDevice, beginRotation)
-                .includeJankyRuns().build()
-
+    rotationName: String,
+    rotation: Int
+) : PipTestBase(rotationName, rotation) {
     @Test
-    fun checkVisibility_backgroundWindowVisibleBehindPipLayer() {
-        checkResults {
-            WmTraceSubject.assertThat(it)
-                    .showsAppWindowOnTop(sPipWindowTitle)
-                    .then()
-                    .showsBelowAppWindow("Wallpaper")
-                    .then()
-                    .showsAppWindowOnTop("Wallpaper")
-                    .forAllEntries()
+    fun test() {
+        flicker(instrumentation) {
+            withTag { buildTestTag("exitPipModeToApp", testApp, rotation) }
+            repeat { 1 }
+            setup {
+                eachRun {
+                    device.wakeUpAndGoToHomeScreen()
+                    device.pressHome()
+                    this.setRotation(rotation)
+                    testApp.open()
+                }
+            }
+            teardown {
+                eachRun {
+                    testApp.exit()
+                    this.setRotation(Surface.ROTATION_0)
+                }
+                test {
+                    if (device.hasPipWindow()) {
+                        device.closePipWindow()
+                    }
+                }
+            }
+            transitions {
+                testApp.clickEnterPipButton(device)
+                testApp.closePipWindow(device)
+                device.waitForIdle()
+                testApp.exit()
+            }
+            assertions {
+                windowManagerTrace {
+                    navBarWindowIsAlwaysVisible()
+                    statusBarWindowIsAlwaysVisible()
+                    pipWindowBecomesVisible()
+
+                    all {
+                        this.showsAppWindowOnTop(sPipWindowTitle)
+                                .and()
+                                .showsBelowAppWindow("Wallpaper")
+                                .then()
+                                .showsAboveAppWindow("Wallpaper")
+                    }
+                }
+
+                layersTrace {
+                    navBarLayerIsAlwaysVisible()
+                    statusBarLayerIsAlwaysVisible()
+                    noUncoveredRegions(rotation)
+                    navBarLayerRotatesAndScales(rotation)
+                    statusBarLayerRotatesScales(rotation)
+                    pipLayerBecomesVisible()
+                }
+            }
         }
     }
-}
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
index fb1cb39..239c082 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
@@ -16,15 +16,21 @@
 
 package com.android.server.wm.flicker.rotation
 
-import android.util.Log
-import androidx.test.filters.FlakyTest
+import android.view.Surface
 import androidx.test.filters.LargeTest
-import com.android.server.wm.flicker.CommonTransitions
-import com.android.server.wm.flicker.LayersTraceSubject
+import com.android.server.wm.flicker.NonRotationTestBase.Companion.SCREENSHOT_LAYER
 import com.android.server.wm.flicker.RotationTestBase
 import com.android.server.wm.flicker.StandardAppHelper
-import com.android.server.wm.flicker.TransitionRunner
-import com.android.server.wm.flicker.WindowUtils
+import com.android.server.wm.flicker.dsl.flicker
+import com.android.server.wm.flicker.helpers.WindowUtils
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -44,42 +50,76 @@
     beginRotation: Int,
     endRotation: Int
 ) : RotationTestBase(beginRotationName, endRotationName, beginRotation, endRotation) {
-    init {
-        testApp = StandardAppHelper(instrumentation,
+    @Test
+    fun test() {
+        val testApp = StandardAppHelper(instrumentation,
                 "com.android.server.wm.flicker.testapp", "SimpleApp")
-    }
 
-    override val transitionToRun: TransitionRunner
-        get() = CommonTransitions.changeAppRotation(testApp, instrumentation, uiDevice,
-                beginRotation, endRotation)
-                .includeJankyRuns().build()
+        flicker(instrumentation) {
+            withTag {
+                buildTestTag("changeAppRotation", testApp, beginRotation, endRotation)
+            }
+            repeat { 1 }
+            setup {
+                eachRun {
+                    device.wakeUpAndGoToHomeScreen()
+                    testApp.open()
+                    this.setRotation(beginRotation)
+                }
+            }
+            teardown {
+                eachRun {
+                    testApp.exit()
+                    this.setRotation(Surface.ROTATION_0)
+                }
+            }
+            transitions {
+                this.setRotation(endRotation)
+            }
+            assertions {
+                windowManagerTrace {
+                    navBarWindowIsAlwaysVisible(bugId = 140855415)
+                    statusBarWindowIsAlwaysVisible(bugId = 140855415)
+                }
 
-    @Test
-    fun checkPosition_appLayerRotates() {
-        val startingPos = WindowUtils.getAppPosition(beginRotation)
-        val endingPos = WindowUtils.getAppPosition(endRotation)
-        Log.e(TAG, "startingPos=$startingPos endingPos=$endingPos")
-        checkResults {
-            LayersTraceSubject.assertThat(it)
-                    .hasVisibleRegion(testApp.getPackage(), startingPos).inTheBeginning()
-            LayersTraceSubject.assertThat(it)
-                    .hasVisibleRegion(testApp.getPackage(), endingPos).atTheEnd()
+                layersTrace {
+                    navBarLayerIsAlwaysVisible(bugId = 140855415)
+                    statusBarLayerIsAlwaysVisible(bugId = 140855415)
+                    noUncoveredRegions(beginRotation, endRotation, allStates = false)
+                    navBarLayerRotatesAndScales(beginRotation, endRotation)
+                    statusBarLayerRotatesScales(beginRotation, endRotation)
+                }
+
+                layersTrace {
+                    val startingPos = WindowUtils.getDisplayBounds(beginRotation)
+                    val endingPos = WindowUtils.getDisplayBounds(endRotation)
+
+                    start("appLayerRotates_StartingPos") {
+                        this.hasVisibleRegion(testApp.getPackage(), startingPos)
+                    }
+
+                    end("appLayerRotates_EndingPos") {
+                        this.hasVisibleRegion(testApp.getPackage(), endingPos)
+                    }
+
+                    all("screenshotLayerBecomesInvisible", enabled = false) {
+                        this.showsLayer(testApp.getPackage())
+                                .then()
+                                .replaceVisibleLayer(
+                                        testApp.getPackage(),
+                                        SCREENSHOT_LAYER)
+                                .then()
+                                .showsLayer(testApp.getPackage())
+                                .and()
+                                .showsLayer(SCREENSHOT_LAYER)
+                                .then()
+                                .replaceVisibleLayer(
+                                        SCREENSHOT_LAYER,
+                                        testApp.getPackage()
+                                )
+                    }
+                }
+            }
         }
     }
-
-    @FlakyTest
-    @Test
-    fun checkVisibility_screenshotLayerBecomesInvisible() {
-        checkResults {
-            LayersTraceSubject.assertThat(it)
-                    .showsLayer(testApp.getPackage())
-                    .then()
-                    .replaceVisibleLayer(testApp.getPackage(), SCREENSHOT_LAYER)
-                    .then()
-                    .showsLayer(testApp.getPackage()).and().showsLayer(SCREENSHOT_LAYER)
-                    .then()
-                    .replaceVisibleLayer(SCREENSHOT_LAYER, testApp.getPackage())
-                    .forAllEntries()
-        }
-    }
-}
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
index 1cd1998..4746376 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
@@ -17,15 +17,24 @@
 package com.android.server.wm.flicker.rotation
 
 import android.content.Intent
+import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
 import android.view.Surface
-import androidx.test.InstrumentationRegistry
 import androidx.test.filters.FlakyTest
 import androidx.test.filters.LargeTest
-import com.android.server.wm.flicker.CommonTransitions
-import com.android.server.wm.flicker.LayersTraceSubject
+import androidx.test.uiautomator.By
+import androidx.test.uiautomator.Until
 import com.android.server.wm.flicker.RotationTestBase
-import com.android.server.wm.flicker.TransitionRunner
-import com.android.server.wm.flicker.WindowUtils
+import com.android.server.wm.flicker.helpers.WindowUtils
+import com.android.server.wm.flicker.dsl.flicker
+import com.android.server.wm.flicker.helpers.stopPackage
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
 import com.android.server.wm.flicker.testapp.ActivityOptions
 import org.junit.FixMethodOrder
 import org.junit.Test
@@ -42,67 +51,97 @@
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @FlakyTest(bugId = 147659548)
 class SeamlessAppRotationTest(
+    testId: String,
     private val intent: Intent,
     beginRotationName: String,
     endRotationName: String,
     beginRotation: Int,
     endRotation: Int
 ) : RotationTestBase(beginRotationName, endRotationName, beginRotation, endRotation) {
-    override val transitionToRun: TransitionRunner
-        get() {
-            var intentId = ""
-            if (intent.extras?.getBoolean(ActivityOptions.EXTRA_STARVE_UI_THREAD) == true) {
-                intentId = "BUSY_UI_THREAD"
-            }
-            return CommonTransitions.changeAppRotation(intent, intentId,
-                    InstrumentationRegistry.getContext(), instrumentation, uiDevice,
-                    beginRotation, endRotation).build()
+    @Test
+    fun test() {
+        var intentId = ""
+        if (intent.extras?.getBoolean(ActivityOptions.EXTRA_STARVE_UI_THREAD) == true) {
+            intentId = "BUSY_UI_THREAD"
         }
 
-    @Test
-    fun checkPosition_appLayerRotates() {
-        val startingPos = WindowUtils.getAppPosition(beginRotation)
-        val endingPos = WindowUtils.getAppPosition(endRotation)
-        if (startingPos == endingPos) {
-            checkResults {
-                LayersTraceSubject.assertThat(it)
-                        .hasVisibleRegion(intent.component?.packageName ?: "", startingPos)
-                        .forAllEntries()
+        flicker(instrumentation) {
+            withTag {
+                "changeAppRotation_" + intentId + "_" +
+                        Surface.rotationToString(beginRotation) + "_" +
+                        Surface.rotationToString(endRotation)
             }
-        } else {
-            checkResults {
-                LayersTraceSubject.assertThat(it)
-                        .hasVisibleRegion(intent.component?.packageName ?: "", startingPos)
-                        .then()
-                        .hasVisibleRegion(intent.component?.packageName ?: "", endingPos)
-                        .forAllEntries()
+            repeat { 1 }
+            setup {
+                eachRun {
+                    device.wakeUpAndGoToHomeScreen()
+                    instrumentation.targetContext.startActivity(intent)
+                    device.wait(Until.hasObject(By.pkg(intent.component?.packageName)
+                            .depth(0)), APP_LAUNCH_TIMEOUT)
+                    this.setRotation(beginRotation)
+                }
             }
-        }
-    }
+            teardown {
+                eachRun {
+                    stopPackage(
+                            instrumentation.targetContext,
+                            intent.component?.packageName
+                                    ?: error("Unable to determine package name for intent"))
+                    this.setRotation(Surface.ROTATION_0)
+                }
+            }
+            transitions {
+                this.setRotation(endRotation)
+            }
+            assertions {
+                windowManagerTrace {
+                    navBarWindowIsAlwaysVisible(bugId = 140855415)
+                    statusBarWindowIsAlwaysVisible(bugId = 140855415)
+                }
 
-    @Test
-    fun checkCoveredRegion_noUncoveredRegions() {
-        val startingBounds = WindowUtils.getDisplayBounds(beginRotation)
-        val endingBounds = WindowUtils.getDisplayBounds(endRotation)
-        if (startingBounds == endingBounds) {
-            checkResults {
-                LayersTraceSubject.assertThat(it)
-                        .coversRegion(startingBounds)
-                        .forAllEntries()
-            }
-        } else {
-            checkResults {
-                LayersTraceSubject.assertThat(it)
-                        .coversRegion(startingBounds)
-                        .then()
-                        .coversRegion(endingBounds)
-                        .forAllEntries()
+                layersTrace {
+                    navBarLayerIsAlwaysVisible(bugId = 140855415)
+                    statusBarLayerIsAlwaysVisible(bugId = 140855415)
+                    noUncoveredRegions(beginRotation, endRotation, allStates = true)
+                    navBarLayerRotatesAndScales(beginRotation, endRotation)
+                    statusBarLayerRotatesScales(beginRotation, endRotation, enabled = false)
+                }
+
+                layersTrace {
+                    all("appLayerRotates"/*, bugId = 147659548*/) {
+                        val startingPos = WindowUtils.getDisplayBounds(beginRotation)
+                        val endingPos = WindowUtils.getDisplayBounds(endRotation)
+
+                        if (startingPos == endingPos) {
+                            this.hasVisibleRegion(
+                                    intent.component?.packageName ?: "",
+                                    startingPos)
+                        } else {
+                            this.hasVisibleRegion(intent.component?.packageName ?: "", startingPos)
+                                    .then()
+                                    .hasVisibleRegion(intent.component?.packageName
+                                            ?: "", endingPos)
+                        }
+                    }
+
+                    all("noUncoveredRegions"/*, bugId = 147659548*/) {
+                        val startingBounds = WindowUtils.getDisplayBounds(beginRotation)
+                        val endingBounds = WindowUtils.getDisplayBounds(endRotation)
+                        if (startingBounds == endingBounds) {
+                            this.coversRegion(startingBounds)
+                        } else {
+                            this.coversRegion(startingBounds)
+                                    .then()
+                                    .coversRegion(endingBounds)
+                        }
+                    }
+                }
             }
         }
     }
 
     companion object {
-        // launch test activity that supports seamless rotation
+        private const val APP_LAUNCH_TIMEOUT: Long = 10000
 
         // launch test activity that supports seamless rotation with a busy UI thread to miss frames
         // when the app is asked to redraw
@@ -110,18 +149,20 @@
         @JvmStatic
         fun getParams(): Collection<Array<Any>> {
             val supportedRotations = intArrayOf(Surface.ROTATION_0, Surface.ROTATION_90)
-            val params: MutableCollection<Array<Any>> = ArrayList()
-            val testIntents = ArrayList<Intent>()
+            val params = mutableListOf<Array<Any>>()
+            val testIntents = mutableListOf<Intent>()
 
             // launch test activity that supports seamless rotation
             var intent = Intent(Intent.ACTION_MAIN)
             intent.component = ActivityOptions.SEAMLESS_ACTIVITY_COMPONENT_NAME
+            intent.flags = FLAG_ACTIVITY_NEW_TASK
             testIntents.add(intent)
 
             // launch test activity that supports seamless rotation with a busy UI thread to miss frames
             // when the app is asked to redraw
             intent = Intent(intent)
             intent.putExtra(ActivityOptions.EXTRA_STARVE_UI_THREAD, true)
+            intent.flags = FLAG_ACTIVITY_NEW_TASK
             testIntents.add(intent)
             for (testIntent in testIntents) {
                 for (begin in supportedRotations) {
@@ -133,7 +174,13 @@
                                             ActivityOptions.EXTRA_STARVE_UI_THREAD) == true) {
                                 testId += "_" + "BUSY_UI_THREAD"
                             }
-                            params.add(arrayOf(testId, testIntent, begin, end))
+                            params.add(arrayOf(
+                                    testId,
+                                    testIntent,
+                                    Surface.rotationToString(begin),
+                                    Surface.rotationToString(end),
+                                    begin,
+                                    end))
                         }
                     }
                 }
@@ -141,4 +188,4 @@
             return params
         }
     }
-}
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt
index b5611a4..7c19696 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt
@@ -16,13 +16,22 @@
 
 package com.android.server.wm.flicker.splitscreen
 
+import android.os.SystemClock
+import android.view.Surface
 import androidx.test.filters.LargeTest
-import com.android.server.wm.flicker.CommonTransitions
-import com.android.server.wm.flicker.LayersTraceSubject
 import com.android.server.wm.flicker.NonRotationTestBase
 import com.android.server.wm.flicker.StandardAppHelper
-import com.android.server.wm.flicker.TransitionRunner
-import com.android.server.wm.flicker.WmTraceSubject
+import com.android.server.wm.flicker.dsl.flicker
+import com.android.server.wm.flicker.helpers.exitSplitScreen
+import com.android.server.wm.flicker.helpers.launchSplitScreen
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -37,42 +46,63 @@
 @RunWith(Parameterized::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 class OpenAppToSplitScreenTest(
-    beginRotationName: String,
-    beginRotation: Int
-) : NonRotationTestBase(beginRotationName, beginRotation) {
-    init {
-        testApp = StandardAppHelper(instrumentation,
-                "com.android.server.wm.flicker.testapp", "SimpleApp")
-    }
-
-    override val transitionToRun: TransitionRunner
-        get() = CommonTransitions.appToSplitScreen(testApp, instrumentation, uiDevice,
-                beginRotation).includeJankyRuns().build()
-
+    rotationName: String,
+    rotation: Int
+) : NonRotationTestBase(rotationName, rotation) {
     @Test
-    fun checkVisibility_navBarWindowIsAlwaysVisible() {
-        checkResults {
-            WmTraceSubject.assertThat(it)
-                    .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries()
+    fun test() {
+        val testApp = StandardAppHelper(instrumentation,
+        "com.android.server.wm.flicker.testapp", "SimpleApp")
+
+        flicker(instrumentation) {
+            withTag { buildTestTag("appToSplitScreen", testApp, rotation) }
+            repeat { 1 }
+            setup {
+                eachRun {
+                    device.wakeUpAndGoToHomeScreen()
+                    this.setRotation(rotation)
+                    testApp.open()
+                    SystemClock.sleep(500)
+                }
+            }
+            teardown {
+                eachRun {
+                    device.exitSplitScreen()
+                    testApp.exit()
+                }
+            }
+            transitions {
+                device.launchSplitScreen()
+            }
+            assertions {
+                windowManagerTrace {
+                    navBarWindowIsAlwaysVisible()
+                    statusBarWindowIsAlwaysVisible()
+                }
+
+                layersTrace {
+                    navBarLayerIsAlwaysVisible()
+                    statusBarLayerIsAlwaysVisible()
+                    noUncoveredRegions(rotation)
+                    navBarLayerRotatesAndScales(rotation)
+                    statusBarLayerRotatesScales(rotation)
+
+                    all("dividerLayerBecomesVisible") {
+                        this.hidesLayer(DOCKED_STACK_DIVIDER)
+                                .then()
+                                .showsLayer(DOCKED_STACK_DIVIDER)
+                    }
+                }
+            }
         }
     }
 
-    @Test
-    fun checkVisibility_statusBarWindowIsAlwaysVisible() {
-        checkResults {
-            WmTraceSubject.assertThat(it)
-                    .showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE).forAllEntries()
-        }
-    }
-
-    @Test
-    fun checkVisibility_dividerLayerBecomesVisible() {
-        checkResults {
-            LayersTraceSubject.assertThat(it)
-                    .hidesLayer(DOCKED_STACK_DIVIDER)
-                    .then()
-                    .showsLayer(DOCKED_STACK_DIVIDER)
-                    .forAllEntries()
+    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) }
         }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/ResizeSplitScreenTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/ResizeSplitScreenTest.kt
index 6b597e5..1a885bc 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/ResizeSplitScreenTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/ResizeSplitScreenTest.kt
@@ -19,24 +19,28 @@
 import android.graphics.Region
 import android.util.Rational
 import android.view.Surface
-import androidx.test.InstrumentationRegistry
 import androidx.test.filters.FlakyTest
 import androidx.test.filters.LargeTest
-import androidx.test.runner.AndroidJUnit4
-import androidx.test.uiautomator.UiDevice
-import com.android.server.wm.flicker.CommonTransitions
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.uiautomator.By
 import com.android.server.wm.flicker.FlickerTestBase
-import com.android.server.wm.flicker.LayersTrace
-import com.android.server.wm.flicker.LayersTraceSubject
 import com.android.server.wm.flicker.StandardAppHelper
-import com.android.server.wm.flicker.TransitionRunner
-import com.android.server.wm.flicker.TransitionResult
-import com.android.server.wm.flicker.WindowUtils
-import com.android.server.wm.flicker.WmTraceSubject
-import com.android.server.wm.flicker.helpers.AutomationUtils
+import com.android.server.wm.flicker.helpers.WindowUtils
+import com.android.server.wm.flicker.dsl.flicker
 import com.android.server.wm.flicker.helpers.ImeAppHelper
-import com.google.common.truth.Truth
-import org.junit.AfterClass
+import com.android.server.wm.flicker.helpers.clearRecents
+import com.android.server.wm.flicker.helpers.exitSplitScreen
+import com.android.server.wm.flicker.helpers.isInSplitScreen
+import com.android.server.wm.flicker.helpers.launchSplitScreen
+import com.android.server.wm.flicker.helpers.resizeSplitScreen
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -53,146 +57,130 @@
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @FlakyTest(bugId = 159096424)
 class ResizeSplitScreenTest : FlickerTestBase() {
-    init {
-        testApp = StandardAppHelper(instrumentation,
+    @Test
+    fun test() {
+        val testAppTop = StandardAppHelper(instrumentation,
                 "com.android.server.wm.flicker.testapp", "SimpleApp")
-    }
+        val testAppBottom = ImeAppHelper(instrumentation)
 
-    override val transitionToRun: TransitionRunner
-        get() {
-            val bottomApp = ImeAppHelper(instrumentation)
-            return CommonTransitions.resizeSplitScreen(testApp, bottomApp, instrumentation,
-                    uiDevice, Surface.ROTATION_0,
-                    Rational(1, 3), Rational(2, 3))
-                    .includeJankyRuns().build()
-        }
+        flicker(instrumentation) {
+            withTag {
+                val description = (startRatio.toString().replace("/", "-") + "_to_" +
+                        stopRatio.toString().replace("/", "-"))
+                buildTestTag("resizeSplitScreen", testAppTop, rotation,
+                        rotation, testAppBottom, description)
+            }
+            repeat { 1 }
+            setup {
+                eachRun {
+                    device.wakeUpAndGoToHomeScreen()
+                    this.setRotation(rotation)
+                    clearRecents(instrumentation)
+                    testAppBottom.open()
+                    device.pressHome()
+                    testAppTop.open()
+                    device.waitForIdle()
+                    device.launchSplitScreen()
+                    val snapshot = device.findObject(By.res(device.launcherPackageName, "snapshot"))
+                    snapshot.click()
+                    testAppBottom.openIME(device)
+                    device.pressBack()
+                    device.resizeSplitScreen(startRatio)
+                }
+            }
+            teardown {
+                eachRun {
+                    device.exitSplitScreen()
+                    device.pressHome()
+                    testAppTop.exit()
+                    testAppBottom.exit()
+                }
+                test {
+                    if (device.isInSplitScreen()) {
+                        device.exitSplitScreen()
+                    }
+                }
+            }
+            transitions {
+                device.resizeSplitScreen(stopRatio)
+            }
+            assertions {
+                windowManagerTrace {
+                    navBarWindowIsAlwaysVisible()
+                    statusBarWindowIsAlwaysVisible()
 
-    @Test
-    fun checkVisibility_topAppLayerIsAlwaysVisible() {
-        checkResults {
-            LayersTraceSubject.assertThat(it)
-                    .showsLayer(sSimpleActivity)
-                    .forAllEntries()
-        }
-    }
+                    all("topAppWindowIsAlwaysVisible", bugId = 156223549) {
+                        this.showsAppWindow(sSimpleActivity)
+                    }
 
-    @Test
-    fun checkVisibility_bottomAppLayerIsAlwaysVisible() {
-        checkResults {
-            LayersTraceSubject.assertThat(it)
-                    .showsLayer(sImeActivity)
-                    .forAllEntries()
-        }
-    }
+                    all("bottomAppWindowIsAlwaysVisible", bugId = 156223549) {
+                        this.showsAppWindow(sImeActivity)
+                    }
+                }
 
-    @Test
-    fun checkVisibility_dividerLayerIsAlwaysVisible() {
-        checkResults {
-            LayersTraceSubject.assertThat(it)
-                    .showsLayer(DOCKED_STACK_DIVIDER)
-                    .forAllEntries()
-        }
-    }
+                layersTrace {
+                    navBarLayerIsAlwaysVisible()
+                    statusBarLayerIsAlwaysVisible()
+                    noUncoveredRegions(rotation)
+                    navBarLayerRotatesAndScales(rotation)
+                    statusBarLayerRotatesScales(rotation)
 
-    @Test
-    @FlakyTest
-    fun checkPosition_appsStartingBounds() {
-        val displayBounds = WindowUtils.getDisplayBounds()
-        checkResults { result: TransitionResult ->
-            val entries = LayersTrace.parseFrom(result.layersTrace,
-                    result.layersTracePath, result.layersTraceChecksum)
-            Truth.assertThat(entries.entries).isNotEmpty()
-            val startingDividerBounds = entries.entries[0].getVisibleBounds(
-                    DOCKED_STACK_DIVIDER).bounds
-            val startingTopAppBounds = Region(0, 0, startingDividerBounds.right,
-                    startingDividerBounds.top + WindowUtils.getDockedStackDividerInset())
-            val startingBottomAppBounds = Region(0,
-                    startingDividerBounds.bottom - WindowUtils.getDockedStackDividerInset(),
-                    displayBounds.right,
-                    displayBounds.bottom - WindowUtils.getNavigationBarHeight())
-            LayersTraceSubject.assertThat(result)
-                    .hasVisibleRegion("SimpleActivity", startingTopAppBounds)
-                    .inTheBeginning()
-            LayersTraceSubject.assertThat(result)
-                    .hasVisibleRegion("ImeActivity", startingBottomAppBounds)
-                    .inTheBeginning()
-        }
-    }
+                    all("topAppLayerIsAlwaysVisible") {
+                        this.showsLayer(sSimpleActivity)
+                    }
 
-    @Test
-    @FlakyTest
-    fun checkPosition_appsEndingBounds() {
-        val displayBounds = WindowUtils.getDisplayBounds()
-        checkResults { result: TransitionResult ->
-            val entries = LayersTrace.parseFrom(result.layersTrace,
-                    result.layersTracePath, result.layersTraceChecksum)
-            Truth.assertThat(entries.entries).isNotEmpty()
-            val endingDividerBounds = entries.entries[entries.entries.size - 1].getVisibleBounds(
-                    DOCKED_STACK_DIVIDER).bounds
-            val startingTopAppBounds = Region(0, 0, endingDividerBounds.right,
-                    endingDividerBounds.top + WindowUtils.getDockedStackDividerInset())
-            val startingBottomAppBounds = Region(0,
-                    endingDividerBounds.bottom - WindowUtils.getDockedStackDividerInset(),
-                    displayBounds.right,
-                    displayBounds.bottom - WindowUtils.getNavigationBarHeight())
-            LayersTraceSubject.assertThat(result)
-                    .hasVisibleRegion(sSimpleActivity, startingTopAppBounds)
-                    .atTheEnd()
-            LayersTraceSubject.assertThat(result)
-                    .hasVisibleRegion(sImeActivity, startingBottomAppBounds)
-                    .atTheEnd()
-        }
-    }
+                    all("bottomAppLayerIsAlwaysVisible") {
+                        this.showsLayer(sImeActivity)
+                    }
 
-    @Test
-    fun checkVisibility_navBarWindowIsAlwaysVisible() {
-        checkResults {
-            WmTraceSubject.assertThat(it)
-                    .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE)
-                    .forAllEntries()
-        }
-    }
+                    all("dividerLayerIsAlwaysVisible") {
+                        this.showsLayer(DOCKED_STACK_DIVIDER)
+                    }
 
-    @Test
-    fun checkVisibility_statusBarWindowIsAlwaysVisible() {
-        checkResults {
-            WmTraceSubject.assertThat(it)
-                    .showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE)
-                    .forAllEntries()
-        }
-    }
+                    start("appsStartingBounds", enabled = false) {
+                        val displayBounds = WindowUtils.displayBounds
+                        val entry = this.trace.entries.firstOrNull()
+                                ?: throw IllegalStateException("Trace is empty")
+                        val dividerBounds = entry.getVisibleBounds(DOCKED_STACK_DIVIDER).bounds
 
-    @Test
-    @FlakyTest(bugId = 156223549)
-    fun checkVisibility_topAppWindowIsAlwaysVisible() {
-        checkResults {
-            WmTraceSubject.assertThat(it)
-                    .showsAppWindow(sSimpleActivity)
-                    .forAllEntries()
-        }
-    }
+                        val topAppBounds = Region(0, 0, dividerBounds.right,
+                                dividerBounds.top + WindowUtils.dockedStackDividerInset)
+                        val bottomAppBounds = Region(0,
+                                dividerBounds.bottom - WindowUtils.dockedStackDividerInset,
+                                displayBounds.right,
+                                displayBounds.bottom - WindowUtils.navigationBarHeight)
+                        this.hasVisibleRegion("SimpleActivity", topAppBounds)
+                                .and()
+                                .hasVisibleRegion("ImeActivity", bottomAppBounds)
+                    }
 
-    @Test
-    @FlakyTest(bugId = 156223549)
-    fun checkVisibility_bottomAppWindowIsAlwaysVisible() {
-        checkResults {
-            WmTraceSubject.assertThat(it)
-                    .showsAppWindow(sImeActivity)
-                    .forAllEntries()
+                    end("appsEndingBounds", enabled = false) {
+                        val displayBounds = WindowUtils.displayBounds
+                        val entry = this.trace.entries.lastOrNull()
+                                ?: throw IllegalStateException("Trace is empty")
+                        val dividerBounds = entry.getVisibleBounds(DOCKED_STACK_DIVIDER).bounds
+
+                        val topAppBounds = Region(0, 0, dividerBounds.right,
+                                dividerBounds.top + WindowUtils.dockedStackDividerInset)
+                        val bottomAppBounds = Region(0,
+                                dividerBounds.bottom - WindowUtils.dockedStackDividerInset,
+                                displayBounds.right,
+                                displayBounds.bottom - WindowUtils.navigationBarHeight)
+
+                        this.hasVisibleRegion(sSimpleActivity, topAppBounds)
+                                .and()
+                                .hasVisibleRegion(sImeActivity, bottomAppBounds)
+                    }
+                }
+            }
         }
     }
 
     companion object {
         private const val sSimpleActivity = "SimpleActivity"
         private const val sImeActivity = "ImeActivity"
-
-        @AfterClass
-        @JvmStatic
-        fun teardown() {
-            val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
-            if (AutomationUtils.isInSplitScreen(device)) {
-                AutomationUtils.exitSplitScreen(device)
-            }
-        }
+        private val rotation = Surface.ROTATION_0
+        private val startRatio = Rational(1, 3)
+        private val stopRatio = Rational(2, 3)
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/SplitScreenToLauncherTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/SplitScreenToLauncherTest.kt
index fdcafdb..268ba9e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/SplitScreenToLauncherTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/SplitScreenToLauncherTest.kt
@@ -17,19 +17,22 @@
 package com.android.server.wm.flicker.splitscreen
 
 import android.view.Surface
-import androidx.test.InstrumentationRegistry
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
-import androidx.test.runner.AndroidJUnit4
-import androidx.test.uiautomator.UiDevice
-import com.android.server.wm.flicker.CommonTransitions
 import com.android.server.wm.flicker.FlickerTestBase
-import com.android.server.wm.flicker.LayersTraceSubject
 import com.android.server.wm.flicker.StandardAppHelper
-import com.android.server.wm.flicker.TransitionRunner
-import com.android.server.wm.flicker.WindowUtils
-import com.android.server.wm.flicker.WmTraceSubject
-import com.android.server.wm.flicker.helpers.AutomationUtils
-import org.junit.AfterClass
+import com.android.server.wm.flicker.dsl.flicker
+import com.android.server.wm.flicker.helpers.exitSplitScreen
+import com.android.server.wm.flicker.helpers.isInSplitScreen
+import com.android.server.wm.flicker.helpers.launchSplitScreen
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -43,68 +46,63 @@
 @RunWith(AndroidJUnit4::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 class SplitScreenToLauncherTest : FlickerTestBase() {
-    init {
-        testApp = StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
+    private val rotation: Int = Surface.ROTATION_0
+    @Test
+    fun test() {
+        val testApp = StandardAppHelper(instrumentation,
                 "com.android.server.wm.flicker.testapp", "SimpleApp")
-    }
 
-    override val transitionToRun: TransitionRunner
-        get() = CommonTransitions.splitScreenToLauncher(testApp, instrumentation, uiDevice,
-                Surface.ROTATION_0).includeJankyRuns().build()
+        flicker(instrumentation) {
+            withTag { buildTestTag("splitScreenToLauncher", testApp, rotation) }
+            repeat { 1 }
+            setup {
+                eachRun {
+                    device.wakeUpAndGoToHomeScreen()
+                    testApp.open()
+                    this.setRotation(rotation)
+                    device.launchSplitScreen()
+                    device.waitForIdle()
+                }
+            }
+            teardown {
+                eachRun {
+                    testApp.exit()
+                }
+                test {
+                    if (device.isInSplitScreen()) {
+                        device.exitSplitScreen()
+                    }
+                }
+            }
+            transitions {
+                device.exitSplitScreen()
+            }
+            assertions {
+                windowManagerTrace {
+                    navBarWindowIsAlwaysVisible()
+                    statusBarWindowIsAlwaysVisible()
+                }
 
-    @Test
-    fun checkCoveredRegion_noUncoveredRegions() {
-        checkResults {
-            LayersTraceSubject.assertThat(it)
-                    .coversRegion(WindowUtils.getDisplayBounds()).forAllEntries()
-        }
-    }
+                layersTrace {
+                    navBarLayerIsAlwaysVisible()
+                    statusBarLayerIsAlwaysVisible()
+                    noUncoveredRegions(rotation)
+                    navBarLayerRotatesAndScales(rotation)
+                    statusBarLayerRotatesScales(rotation)
 
-    @Test
-    fun checkVisibility_dividerLayerBecomesInVisible() {
-        checkResults {
-            LayersTraceSubject.assertThat(it)
-                    .showsLayer(DOCKED_STACK_DIVIDER)
-                    .then()
-                    .hidesLayer(DOCKED_STACK_DIVIDER)
-                    .forAllEntries()
-        }
-    }
+                    // b/161435597 causes the test not to work on 90 degrees
+                    all("dividerLayerBecomesInvisible") {
+                        this.showsLayer(DOCKED_STACK_DIVIDER)
+                                .then()
+                                .hidesLayer(DOCKED_STACK_DIVIDER)
+                    }
 
-    @Test
-    fun checkVisibility_appLayerBecomesInVisible() {
-        checkResults {
-            LayersTraceSubject.assertThat(it)
-                    .showsLayer(testApp.getPackage())
-                    .then()
-                    .hidesLayer(testApp.getPackage())
-                    .forAllEntries()
-        }
-    }
-
-    @Test
-    fun checkVisibility_navBarWindowIsAlwaysVisible() {
-        checkResults {
-            WmTraceSubject.assertThat(it)
-                    .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries()
-        }
-    }
-
-    @Test
-    fun checkVisibility_statusBarWindowIsAlwaysVisible() {
-        checkResults {
-            WmTraceSubject.assertThat(it)
-                    .showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE).forAllEntries()
-        }
-    }
-
-    companion object {
-        @AfterClass
-        @JvmStatic
-        fun teardown() {
-            val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
-            if (AutomationUtils.isInSplitScreen(device)) {
-                AutomationUtils.exitSplitScreen(device)
+                    all("appLayerBecomesInvisible") {
+                        this.showsLayer(testApp.getPackage())
+                            .then()
+                            .hidesLayer(testApp.getPackage())
+                    }
+                }
             }
         }
     }