Convert flicker tests to kotlin

This will allow us to replace the Consumer/Runnable based assertions for lambdas, making the code easier to read and maintain.

Test: atest FlickerTests
Change-Id: I3c6a6bd8cd18f7eae0d5daa4510d30a8020d3f6b
diff --git a/tests/FlickerTests/Android.bp b/tests/FlickerTests/Android.bp
index baff952..070dacb 100644
--- a/tests/FlickerTests/Android.bp
+++ b/tests/FlickerTests/Android.bp
@@ -16,7 +16,7 @@
 
 android_test {
     name: "FlickerTests",
-    srcs: ["src/**/*.java"],
+    srcs: ["src/**/*.java", "src/**/*.kt"],
     manifest: "AndroidManifest.xml",
     test_config: "AndroidTest.xml",
     platform_apis: true,
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.java
deleted file mode 100644
index ed6f33e..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2018 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 static android.view.Surface.rotationToString;
-
-import static com.android.server.wm.flicker.CommonTransitions.changeAppRotation;
-import static com.android.server.wm.flicker.WindowUtils.getAppPosition;
-import static com.android.server.wm.flicker.WindowUtils.getNavigationBarPosition;
-import static com.android.server.wm.flicker.WindowUtils.getStatusBarPosition;
-import static com.android.server.wm.flicker.WmTraceSubject.assertThat;
-
-import android.graphics.Rect;
-import android.util.Log;
-import android.view.Surface;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.FlakyTest;
-import androidx.test.filters.LargeTest;
-
-import org.junit.FixMethodOrder;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.MethodSorters;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-/**
- * Cycle through supported app rotations.
- * To run this test: {@code atest FlickerTest:ChangeAppRotationTest}
- */
-@LargeTest
-@RunWith(Parameterized.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class ChangeAppRotationTest extends FlickerTestBase {
-    private int mBeginRotation;
-    private int mEndRotation;
-
-    public ChangeAppRotationTest(String beginRotationName, String endRotationName,
-            int beginRotation, int endRotation) {
-        this.mTestApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
-                "com.android.server.wm.flicker.testapp", "SimpleApp");
-        this.mBeginRotation = beginRotation;
-        this.mEndRotation = endRotation;
-    }
-
-    @Parameters(name = "{0}-{1}")
-    public static Collection<Object[]> getParams() {
-        int[] supportedRotations =
-                {Surface.ROTATION_0, Surface.ROTATION_90};
-        Collection<Object[]> params = new ArrayList<>();
-        for (int begin : supportedRotations) {
-            for (int end : supportedRotations) {
-                if (begin != end) {
-                    params.add(new Object[]{rotationToString(begin), rotationToString(end), begin,
-                            end});
-                }
-            }
-        }
-        return params;
-    }
-
-    @Override
-    TransitionRunner getTransitionToRun() {
-        return changeAppRotation(mTestApp, mUiDevice, mBeginRotation, mEndRotation)
-                .includeJankyRuns().build();
-    }
-
-    @FlakyTest(bugId = 140855415)
-    @Ignore("Waiting bug feedback")
-    @Test
-    public void checkVisibility_navBarWindowIsAlwaysVisible() {
-        checkResults(result -> assertThat(result)
-                .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries());
-    }
-
-    @FlakyTest(bugId = 140855415)
-    @Ignore("Waiting bug feedback")
-    @Test
-    public void checkVisibility_statusBarWindowIsAlwaysVisible() {
-        checkResults(result -> assertThat(result)
-                .showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE).forAllEntries());
-    }
-
-    @Test
-    public void checkPosition_navBarLayerRotatesAndScales() {
-        Rect startingPos = getNavigationBarPosition(mBeginRotation);
-        Rect endingPos = getNavigationBarPosition(mEndRotation);
-        checkResults(result -> {
-                    LayersTraceSubject.assertThat(result)
-                            .hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, startingPos)
-                            .inTheBeginning();
-                    LayersTraceSubject.assertThat(result)
-                            .hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, endingPos).atTheEnd();
-                }
-        );
-    }
-
-    @Test
-    public void checkPosition_appLayerRotates() {
-        Rect startingPos = getAppPosition(mBeginRotation);
-        Rect endingPos = getAppPosition(mEndRotation);
-        Log.e(TAG, "startingPos=" + startingPos + " endingPos=" + endingPos);
-        checkResults(result -> {
-                    LayersTraceSubject.assertThat(result)
-                            .hasVisibleRegion(mTestApp.getPackage(), startingPos).inTheBeginning();
-                    LayersTraceSubject.assertThat(result)
-                            .hasVisibleRegion(mTestApp.getPackage(), endingPos).atTheEnd();
-                }
-        );
-    }
-
-    @Test
-    public void checkPosition_statusBarLayerScales() {
-        Rect startingPos = getStatusBarPosition(mBeginRotation);
-        Rect endingPos = getStatusBarPosition(mEndRotation);
-        checkResults(result -> {
-                    LayersTraceSubject.assertThat(result)
-                            .hasVisibleRegion(STATUS_BAR_WINDOW_TITLE, startingPos)
-                            .inTheBeginning();
-                    LayersTraceSubject.assertThat(result)
-                            .hasVisibleRegion(STATUS_BAR_WINDOW_TITLE, endingPos).atTheEnd();
-                }
-        );
-    }
-
-    @Ignore("Flaky. Pending debug")
-    @Test
-    public void checkVisibility_screenshotLayerBecomesInvisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(mTestApp.getPackage())
-                .then()
-                .replaceVisibleLayer(mTestApp.getPackage(), SCREENSHOT_LAYER)
-                .then()
-                .showsLayer(mTestApp.getPackage()).and().showsLayer(SCREENSHOT_LAYER)
-                .then()
-                .replaceVisibleLayer(SCREENSHOT_LAYER, mTestApp.getPackage())
-                .forAllEntries());
-    }
-
-    @FlakyTest(bugId = 140855415)
-    @Ignore("Waiting bug feedback")
-    @Test
-    public void checkVisibility_navBarLayerIsAlwaysVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries());
-    }
-
-    @FlakyTest(bugId = 140855415)
-    @Ignore("Waiting bug feedback")
-    @Test
-    public void checkVisibility_statusBarLayerIsAlwaysVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(STATUS_BAR_WINDOW_TITLE).forAllEntries());
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.kt
new file mode 100644
index 0000000..d16fcf7
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.kt
@@ -0,0 +1,80 @@
+/*
+ * 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.util.Log
+import androidx.test.InstrumentationRegistry
+import androidx.test.filters.LargeTest
+import org.junit.FixMethodOrder
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Cycle through supported app rotations.
+ * To run this test: `atest FlickerTest:ChangeAppRotationTest`
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class ChangeAppRotationTest(
+    beginRotationName: String,
+    endRotationName: String,
+    beginRotation: Int,
+    endRotation: Int
+) : RotationTestBase(beginRotationName, endRotationName, beginRotation, endRotation) {
+    init {
+        testApp = StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
+                "com.android.server.wm.flicker.testapp", "SimpleApp")
+    }
+
+    override val transitionToRun: TransitionRunner
+        get() = CommonTransitions.changeAppRotation(testApp, uiDevice,
+                beginRotation, endRotation)
+                .includeJankyRuns().build()
+
+    @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()
+        }
+    }
+
+    @Ignore("Flaky. Pending debug")
+    @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()
+        }
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeAutoOpenWindowToAppTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeAutoOpenWindowToAppTest.java
deleted file mode 100644
index 58dcb99..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeAutoOpenWindowToAppTest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2019 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 static com.android.server.wm.flicker.CommonTransitions.editTextLoseFocusToApp;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.FlakyTest;
-import androidx.test.filters.LargeTest;
-
-import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper;
-
-import org.junit.FixMethodOrder;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.MethodSorters;
-import org.junit.runners.Parameterized;
-
-/**
- * Test IME window closing back to app window transitions.
- * To run this test: {@code atest FlickerTests:CloseImeWindowToAppTest}
- */
-@LargeTest
-@RunWith(Parameterized.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class CloseImeAutoOpenWindowToAppTest extends CloseImeWindowToAppTest {
-
-    public CloseImeAutoOpenWindowToAppTest(String beginRotationName, int beginRotation) {
-        super(beginRotationName, beginRotation);
-
-        mTestApp = new ImeAppAutoFocusHelper(InstrumentationRegistry.getInstrumentation());
-    }
-
-    @Override
-    TransitionRunner getTransitionToRun() {
-        return editTextLoseFocusToApp((ImeAppAutoFocusHelper) mTestApp, mUiDevice, mBeginRotation)
-                .includeJankyRuns().build();
-    }
-
-    @FlakyTest(bugId = 141458352)
-    @Ignore("Waiting bug feedback")
-    @Test
-    public void checkVisibility_imeLayerBecomesInvisible() {
-        super.checkVisibility_imeLayerBecomesInvisible();
-    }
-
-    @FlakyTest(bugId = 141458352)
-    @Ignore("Waiting bug feedback")
-    @Test
-    public void checkVisibility_imeAppLayerIsAlwaysVisible() {
-        super.checkVisibility_imeAppLayerIsAlwaysVisible();
-    }
-
-    @FlakyTest(bugId = 141458352)
-    @Ignore("Waiting bug feedback")
-    @Test
-    public void checkVisibility_imeAppWindowIsAlwaysVisible() {
-        super.checkVisibility_imeAppWindowIsAlwaysVisible();
-    }
-
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeAutoOpenWindowToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeAutoOpenWindowToAppTest.kt
new file mode 100644
index 0000000..214d469
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeAutoOpenWindowToAppTest.kt
@@ -0,0 +1,70 @@
+/*
+ * 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 androidx.test.InstrumentationRegistry
+import androidx.test.filters.FlakyTest
+import androidx.test.filters.LargeTest
+import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
+import org.junit.FixMethodOrder
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test IME window closing back to app window transitions.
+ * To run this test: `atest FlickerTests:CloseImeWindowToAppTest`
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class CloseImeAutoOpenWindowToAppTest(
+    beginRotationName: String,
+    beginRotation: Int
+) : CloseImeWindowToAppTest(beginRotationName, beginRotation) {
+    init {
+        testApp = ImeAppAutoFocusHelper(InstrumentationRegistry.getInstrumentation())
+    }
+
+    override val transitionToRun: TransitionRunner
+        get() = CommonTransitions.editTextLoseFocusToApp(testApp as ImeAppAutoFocusHelper,
+                uiDevice, beginRotation)
+                .includeJankyRuns().build()
+
+    @FlakyTest(bugId = 141458352)
+    @Ignore("Waiting bug feedback")
+    @Test
+    override fun checkVisibility_imeLayerBecomesInvisible() {
+        super.checkVisibility_imeLayerBecomesInvisible()
+    }
+
+    @FlakyTest(bugId = 141458352)
+    @Ignore("Waiting bug feedback")
+    @Test
+    override fun checkVisibility_imeAppLayerIsAlwaysVisible() {
+        super.checkVisibility_imeAppLayerIsAlwaysVisible()
+    }
+
+    @FlakyTest(bugId = 141458352)
+    @Ignore("Waiting bug feedback")
+    @Test
+    override fun checkVisibility_imeAppWindowIsAlwaysVisible() {
+        super.checkVisibility_imeAppWindowIsAlwaysVisible()
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeAutoOpenWindowToHomeTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeAutoOpenWindowToHomeTest.java
deleted file mode 100644
index 7f610a6..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeAutoOpenWindowToHomeTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2019 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 static com.android.server.wm.flicker.CommonTransitions.editTextLoseFocusToHome;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.FlakyTest;
-import androidx.test.filters.LargeTest;
-
-import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper;
-
-import org.junit.FixMethodOrder;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.MethodSorters;
-import org.junit.runners.Parameterized;
-
-/**
- * Test IME window closing back to app window transitions.
- * To run this test: {@code atest FlickerTests:CloseImeWindowToAppTest}
- */
-@LargeTest
-@RunWith(Parameterized.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class CloseImeAutoOpenWindowToHomeTest extends CloseImeWindowToHomeTest {
-
-    public CloseImeAutoOpenWindowToHomeTest(String beginRotationName, int beginRotation) {
-        super(beginRotationName, beginRotation);
-
-        mTestApp = new ImeAppAutoFocusHelper(InstrumentationRegistry.getInstrumentation());
-    }
-
-    @Override
-    TransitionRunner getTransitionToRun() {
-        return editTextLoseFocusToHome((ImeAppAutoFocusHelper) mTestApp, mUiDevice, mBeginRotation)
-                .includeJankyRuns().build();
-    }
-
-    @FlakyTest(bugId = 141458352)
-    @Ignore("Waiting bug feedback")
-    @Test
-    public void checkVisibility_imeWindowBecomesInvisible() {
-        super.checkVisibility_imeWindowBecomesInvisible();
-    }
-
-    @FlakyTest(bugId = 141458352)
-    @Ignore("Waiting bug feedback")
-    @Test
-    public void checkVisibility_imeLayerBecomesInvisible() {
-        super.checkVisibility_imeLayerBecomesInvisible();
-    }
-
-    @FlakyTest(bugId = 157449248)
-    @Ignore("Waiting bug feedback")
-    @Test
-    public void checkVisibility_imeAppWindowBecomesInvisible() {
-        super.checkVisibility_imeAppWindowBecomesInvisible();
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeAutoOpenWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeAutoOpenWindowToHomeTest.kt
new file mode 100644
index 0000000..d0512cb
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeAutoOpenWindowToHomeTest.kt
@@ -0,0 +1,70 @@
+/*
+ * 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 androidx.test.InstrumentationRegistry
+import androidx.test.filters.FlakyTest
+import androidx.test.filters.LargeTest
+import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
+import org.junit.FixMethodOrder
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test IME window closing back to app window transitions.
+ * To run this test: `atest FlickerTests:CloseImeWindowToAppTest`
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class CloseImeAutoOpenWindowToHomeTest(
+    beginRotationName: String,
+    beginRotation: Int
+) : CloseImeWindowToHomeTest(beginRotationName, beginRotation) {
+    init {
+        testApp = ImeAppAutoFocusHelper(InstrumentationRegistry.getInstrumentation())
+    }
+
+    override val transitionToRun: TransitionRunner
+        get() = CommonTransitions.editTextLoseFocusToHome(testApp as ImeAppAutoFocusHelper,
+                uiDevice, beginRotation)
+                .includeJankyRuns().build()
+
+    @FlakyTest(bugId = 141458352)
+    @Ignore("Waiting bug feedback")
+    @Test
+    override fun checkVisibility_imeWindowBecomesInvisible() {
+        super.checkVisibility_imeWindowBecomesInvisible()
+    }
+
+    @FlakyTest(bugId = 141458352)
+    @Ignore("Waiting bug feedback")
+    @Test
+    override fun checkVisibility_imeLayerBecomesInvisible() {
+        super.checkVisibility_imeLayerBecomesInvisible()
+    }
+
+    @FlakyTest(bugId = 157449248)
+    @Ignore("Waiting bug feedback")
+    @Test
+    override fun checkVisibility_imeAppWindowBecomesInvisible() {
+        super.checkVisibility_imeAppWindowBecomesInvisible()
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToAppTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToAppTest.java
deleted file mode 100644
index 57ad7e7..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToAppTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2018 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 static com.android.server.wm.flicker.CommonTransitions.editTextLoseFocusToApp;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.LargeTest;
-
-import com.android.server.wm.flicker.helpers.ImeAppHelper;
-
-import org.junit.FixMethodOrder;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.MethodSorters;
-import org.junit.runners.Parameterized;
-
-/**
- * Test IME window closing back to app window transitions.
- * To run this test: {@code atest FlickerTests:CloseImeWindowToAppTest}
- */
-@LargeTest
-@RunWith(Parameterized.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class CloseImeWindowToAppTest extends NonRotationTestBase {
-
-    static final String IME_WINDOW_TITLE = "InputMethod";
-
-    public CloseImeWindowToAppTest(String beginRotationName, int beginRotation) {
-        super(beginRotationName, beginRotation);
-
-        mTestApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation());
-    }
-
-    @Override
-    TransitionRunner getTransitionToRun() {
-        return editTextLoseFocusToApp((ImeAppHelper) mTestApp, mUiDevice, mBeginRotation)
-                .includeJankyRuns().build();
-    }
-
-    @Ignore("Flaky. Pending debug")
-    @Test
-    public void checkVisibility_imeLayerBecomesInvisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(IME_WINDOW_TITLE)
-                .then()
-                .hidesLayer(IME_WINDOW_TITLE)
-                .forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_imeAppLayerIsAlwaysVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(mTestApp.getPackage())
-                .forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_imeAppWindowIsAlwaysVisible() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .showsAppWindowOnTop(mTestApp.getPackage())
-                .forAllEntries());
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToAppTest.kt
new file mode 100644
index 0000000..7ed0272
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToAppTest.kt
@@ -0,0 +1,82 @@
+/*
+ * 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 androidx.test.InstrumentationRegistry
+import androidx.test.filters.LargeTest
+import com.android.server.wm.flicker.helpers.ImeAppHelper
+import org.junit.FixMethodOrder
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test IME window closing back to app window transitions.
+ * To run this test: `atest FlickerTests:CloseImeWindowToAppTest`
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+open class CloseImeWindowToAppTest(
+    beginRotationName: String,
+    beginRotation: Int
+) : NonRotationTestBase(beginRotationName, beginRotation) {
+    init {
+        testApp = ImeAppHelper(InstrumentationRegistry.getInstrumentation())
+    }
+
+    override val transitionToRun: TransitionRunner
+        get() = CommonTransitions.editTextLoseFocusToApp(testApp as ImeAppHelper,
+                uiDevice, beginRotation)
+                .includeJankyRuns().build()
+
+    @Ignore("Flaky. Pending debug")
+    @Test
+    open fun checkVisibility_imeLayerBecomesInvisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .showsLayer(IME_WINDOW_TITLE)
+                    .then()
+                    .hidesLayer(IME_WINDOW_TITLE)
+                    .forAllEntries()
+        }
+    }
+
+    @Test
+    open fun checkVisibility_imeAppLayerIsAlwaysVisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .showsLayer(testApp.getPackage())
+                    .forAllEntries()
+        }
+    }
+
+    @Test
+    open fun checkVisibility_imeAppWindowIsAlwaysVisible() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .showsAppWindowOnTop(testApp.getPackage())
+                    .forAllEntries()
+        }
+    }
+
+    companion object {
+        const val IME_WINDOW_TITLE = "InputMethod"
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToHomeTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToHomeTest.java
deleted file mode 100644
index 12d1179..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToHomeTest.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2018 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 static com.android.server.wm.flicker.CommonTransitions.editTextLoseFocusToHome;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.FlakyTest;
-import androidx.test.filters.LargeTest;
-
-import com.android.server.wm.flicker.helpers.ImeAppHelper;
-
-import org.junit.FixMethodOrder;
-import org.junit.Ignore;
-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: {@code atest FlickerTests:CloseImeWindowToHomeTest}
- */
-@LargeTest
-@RunWith(Parameterized.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class CloseImeWindowToHomeTest extends NonRotationTestBase {
-
-    static final String IME_WINDOW_TITLE = "InputMethod";
-
-    public CloseImeWindowToHomeTest(String beginRotationName, int beginRotation) {
-        super(beginRotationName, beginRotation);
-
-        mTestApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation());
-    }
-
-    @Override
-    TransitionRunner getTransitionToRun() {
-        return editTextLoseFocusToHome((ImeAppHelper) mTestApp, mUiDevice, mBeginRotation)
-                .includeJankyRuns().build();
-    }
-
-    @Test
-    public void checkVisibility_imeWindowBecomesInvisible() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .showsImeWindow(IME_WINDOW_TITLE)
-                .then()
-                .hidesImeWindow(IME_WINDOW_TITLE)
-                .forAllEntries());
-    }
-
-    @FlakyTest(bugId = 153739621)
-    @Ignore
-    @Test
-    public void checkVisibility_imeLayerBecomesInvisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .skipUntilFirstAssertion()
-                .showsLayer(IME_WINDOW_TITLE)
-                .then()
-                .hidesLayer(IME_WINDOW_TITLE)
-                .forAllEntries());
-    }
-
-    @FlakyTest(bugId = 153739621)
-    @Ignore
-    @Test
-    public void checkVisibility_imeAppLayerBecomesInvisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .skipUntilFirstAssertion()
-                .showsLayer(mTestApp.getPackage())
-                .then()
-                .hidesLayer(mTestApp.getPackage())
-                .forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_imeAppWindowBecomesInvisible() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .showsAppWindowOnTop(mTestApp.getPackage())
-                .then()
-                .hidesAppWindowOnTop(mTestApp.getPackage())
-                .forAllEntries());
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToHomeTest.kt
new file mode 100644
index 0000000..54b8e76
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToHomeTest.kt
@@ -0,0 +1,103 @@
+/*
+ * 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 androidx.test.InstrumentationRegistry
+import androidx.test.filters.FlakyTest
+import androidx.test.filters.LargeTest
+import com.android.server.wm.flicker.helpers.ImeAppHelper
+import org.junit.FixMethodOrder
+import org.junit.Ignore
+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`
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+open class CloseImeWindowToHomeTest(
+    beginRotationName: String,
+    beginRotation: Int
+) : NonRotationTestBase(beginRotationName, beginRotation) {
+    init {
+        testApp = ImeAppHelper(InstrumentationRegistry.getInstrumentation())
+    }
+
+    override val transitionToRun: TransitionRunner
+        get() = CommonTransitions.editTextLoseFocusToHome(testApp as ImeAppHelper,
+                uiDevice, beginRotation)
+                .includeJankyRuns().build()
+
+    @Test
+    open fun checkVisibility_imeWindowBecomesInvisible() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .showsImeWindow(IME_WINDOW_TITLE)
+                    .then()
+                    .hidesImeWindow(IME_WINDOW_TITLE)
+                    .forAllEntries()
+        }
+    }
+
+    @FlakyTest(bugId = 153739621)
+    @Ignore
+    @Test
+    open fun checkVisibility_imeLayerBecomesInvisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .skipUntilFirstAssertion()
+                    .showsLayer(IME_WINDOW_TITLE)
+                    .then()
+                    .hidesLayer(IME_WINDOW_TITLE)
+                    .forAllEntries()
+        }
+    }
+
+    @FlakyTest(bugId = 153739621)
+    @Ignore
+    @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()
+                    .hidesAppWindowOnTop(testApp.getPackage())
+                    .forAllEntries()
+        }
+    }
+
+    companion object {
+        const val IME_WINDOW_TITLE: String = "InputMethod"
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.java b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.java
deleted file mode 100644
index b1854c3..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.java
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * Copyright (C) 2018 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 static android.os.SystemClock.sleep;
-import static android.view.Surface.rotationToString;
-
-import static com.android.server.wm.flicker.helpers.AutomationUtils.clearRecents;
-import static com.android.server.wm.flicker.helpers.AutomationUtils.exitSplitScreen;
-import static com.android.server.wm.flicker.helpers.AutomationUtils.expandPipWindow;
-import static com.android.server.wm.flicker.helpers.AutomationUtils.launchSplitScreen;
-import static com.android.server.wm.flicker.helpers.AutomationUtils.stopPackage;
-
-import android.app.Instrumentation;
-import android.content.Context;
-import android.content.Intent;
-import android.os.RemoteException;
-import android.platform.helpers.IAppHelper;
-import android.util.Rational;
-import android.view.Surface;
-
-import androidx.annotation.Nullable;
-import androidx.test.uiautomator.By;
-import androidx.test.uiautomator.UiDevice;
-import androidx.test.uiautomator.UiObject2;
-import androidx.test.uiautomator.Until;
-
-import com.android.server.wm.flicker.TransitionRunner.TransitionBuilder;
-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.
- */
-class CommonTransitions {
-
-    public static final int ITERATIONS = 1;
-    private static final String TAG = "FLICKER";
-    private static final long APP_LAUNCH_TIMEOUT = 10000;
-
-    private static void setRotation(UiDevice device, int rotation) {
-        try {
-            switch (rotation) {
-                case Surface.ROTATION_270:
-                    device.setOrientationLeft();
-                    break;
-
-                case Surface.ROTATION_90:
-                    device.setOrientationRight();
-                    break;
-
-                case Surface.ROTATION_0:
-                default:
-                    device.setOrientationNatural();
-            }
-            // Wait for animation to complete
-            sleep(1000);
-        } catch (RemoteException e) {
-            throw new 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>
-     */
-    private static String buildTestTag(String testName, IAppHelper app, int rotation) {
-        return buildTestTag(
-                testName, app, /* app2 */ null, rotation, rotation, /* description */ "");
-    }
-
-    /**
-     * 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>
-     */
-    private static String buildTestTag(String testName, IAppHelper app, int beginRotation,
-            int endRotation) {
-        return buildTestTag(
-                testName, app, /* app2 */ null, beginRotation, endRotation, /* description */ "");
-    }
-
-    /**
-     * 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(S)>__<ROTATION(S)>[__<EXTRA>]
-     */
-    private static String buildTestTag(String testName, IAppHelper app, @Nullable IAppHelper app2,
-            int beginRotation, int endRotation, String extraInfo) {
-        StringBuilder testTag = new StringBuilder();
-        testTag.append(testName)
-                .append("__")
-                .append(app.getLauncherName());
-
-        if (app2 != null) {
-            testTag.append("-")
-                    .append(app2.getLauncherName());
-        }
-
-        testTag.append("__")
-                .append(rotationToString(beginRotation));
-
-        if (endRotation != beginRotation) {
-            testTag.append("-")
-                    .append(rotationToString(endRotation));
-        }
-
-        if (!extraInfo.isEmpty()) {
-            testTag.append("__")
-                    .append(extraInfo);
-        }
-
-        return testTag.toString();
-    }
-
-    static TransitionBuilder openAppWarm(IAppHelper testApp, UiDevice
-            device, int beginRotation) {
-        return TransitionRunner.newBuilder()
-                .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);
-    }
-
-    static TransitionBuilder closeAppWithBackKey(IAppHelper testApp, UiDevice
-            device, int beginRotation) {
-        return TransitionRunner.newBuilder()
-                .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);
-    }
-
-    static TransitionBuilder closeAppWithHomeKey(IAppHelper testApp, UiDevice
-            device, int beginRotation) {
-        return TransitionRunner.newBuilder()
-                .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);
-    }
-
-    static TransitionBuilder openAppCold(IAppHelper testApp,
-            UiDevice device, int beginRotation) {
-        return TransitionRunner.newBuilder()
-                .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);
-    }
-
-    static TransitionBuilder changeAppRotation(IAppHelper testApp, UiDevice
-            device, int beginRotation, int endRotation) {
-        return TransitionRunner.newBuilder()
-                .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);
-    }
-
-    static TransitionBuilder changeAppRotation(Intent intent, String intentId, Context context,
-            UiDevice device, int beginRotation, int endRotation) {
-        final String testTag = "changeAppRotation_" + intentId + "_" +
-                rotationToString(beginRotation) + "_" + rotationToString(endRotation);
-        return TransitionRunner.newBuilder()
-                .withTag(testTag)
-                .recordAllRuns()
-                .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
-                .runBeforeAll(() -> {
-                            context.startActivity(intent);
-                            device.wait(Until.hasObject(By.pkg(intent.getComponent()
-                                        .getPackageName()).depth(0)), APP_LAUNCH_TIMEOUT);
-                        }
-                )
-                .runBefore(() -> setRotation(device, beginRotation))
-                .run(() -> setRotation(device, endRotation))
-                .runAfterAll(() -> stopPackage(context, intent.getComponent().getPackageName()))
-                .runAfterAll(() -> setRotation(device, Surface.ROTATION_0))
-                .repeat(ITERATIONS);
-    }
-
-    static TransitionBuilder appToSplitScreen(IAppHelper testApp, UiDevice device,
-            int beginRotation) {
-        return TransitionRunner.newBuilder()
-                .withTag(buildTestTag("appToSplitScreen", testApp, beginRotation))
-                .recordAllRuns()
-                .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
-                .runBeforeAll(() -> setRotation(device, beginRotation))
-                .runBefore(testApp::open)
-                .runBefore(device::waitForIdle)
-                .runBefore(() -> sleep(500))
-                .run(() -> launchSplitScreen(device))
-                .runAfter(() -> exitSplitScreen(device))
-                .runAfterAll(testApp::exit)
-                .repeat(ITERATIONS);
-    }
-
-    static TransitionBuilder splitScreenToLauncher(IAppHelper testApp, UiDevice device,
-            int beginRotation) {
-        return TransitionRunner.newBuilder()
-                .withTag(buildTestTag("splitScreenToLauncher", testApp, beginRotation))
-                .recordAllRuns()
-                .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
-                .runBeforeAll(() -> setRotation(device, beginRotation))
-                .runBefore(testApp::open)
-                .runBefore(device::waitForIdle)
-                .runBefore(() -> launchSplitScreen(device))
-                .run(() -> exitSplitScreen(device))
-                .runAfterAll(testApp::exit)
-                .repeat(ITERATIONS);
-    }
-
-    static TransitionBuilder editTextSetFocus(ImeAppHelper testApp, UiDevice device,
-            int beginRotation) {
-        return TransitionRunner.newBuilder()
-                .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);
-    }
-
-    static TransitionBuilder resizeSplitScreen(Instrumentation instr, IAppHelper testAppTop,
-            ImeAppHelper testAppBottom, UiDevice device, int beginRotation, Rational startRatio,
-            Rational stopRatio) {
-        String description = startRatio.toString().replace("/", "-") + "_to_"
-                + stopRatio.toString().replace("/", "-");
-        String testTag = buildTestTag("resizeSplitScreen", testAppTop, testAppBottom,
-                beginRotation, beginRotation, description);
-        return TransitionRunner.newBuilder()
-                .withTag(testTag)
-                .recordAllRuns()
-                .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
-                .runBeforeAll(() -> setRotation(device, beginRotation))
-                .runBeforeAll(() -> clearRecents(instr))
-                .runBefore(testAppBottom::open)
-                .runBefore(device::pressHome)
-                .runBefore(testAppTop::open)
-                .runBefore(device::waitForIdle)
-                .runBefore(() -> launchSplitScreen(device))
-                .runBefore(() -> {
-                    UiObject2 snapshot = device.findObject(
-                            By.res(device.getLauncherPackageName(), "snapshot"));
-                    snapshot.click();
-                })
-                .runBefore(() -> testAppBottom.openIME(device))
-                .runBefore(device::pressBack)
-                .runBefore(() -> AutomationUtils.resizeSplitScreen(device, startRatio))
-                .run(() -> AutomationUtils.resizeSplitScreen(device, stopRatio))
-                .runAfter(() -> exitSplitScreen(device))
-                .runAfter(device::pressHome)
-                .runAfterAll(testAppTop::exit)
-                .runAfterAll(testAppBottom::exit)
-                .repeat(ITERATIONS);
-    }
-
-    static TransitionBuilder editTextLoseFocusToHome(ImeAppHelper testApp, UiDevice device,
-            int beginRotation) {
-        return TransitionRunner.newBuilder()
-                .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);
-    }
-
-    static TransitionBuilder editTextLoseFocusToApp(ImeAppHelper testApp, UiDevice device,
-            int beginRotation) {
-        return TransitionRunner.newBuilder()
-                .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);
-    }
-
-    static TransitionBuilder enterPipMode(PipAppHelper testApp, UiDevice device,
-            int beginRotation) {
-        return TransitionRunner.newBuilder()
-                .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);
-    }
-
-    static TransitionBuilder exitPipModeToHome(PipAppHelper testApp, UiDevice device,
-            int beginRotation) {
-        return TransitionRunner.newBuilder()
-                .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);
-    }
-
-    static TransitionBuilder exitPipModeToApp(PipAppHelper testApp, UiDevice device,
-            int beginRotation) {
-        return TransitionRunner.newBuilder()
-                .withTag(buildTestTag("exitPipModeToApp", testApp, beginRotation))
-                .recordAllRuns()
-                .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
-                .run(device::pressHome)
-                .run(() -> setRotation(device, beginRotation))
-                .run(testApp::open)
-                .run(() -> testApp.clickEnterPipButton(device))
-                .run(() -> expandPipWindow(device))
-                .run(device::waitForIdle)
-                .run(testApp::exit)
-                .repeat(ITERATIONS);
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.kt
new file mode 100644
index 0000000..9a61dee
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.kt
@@ -0,0 +1,430 @@
+/*
+ * 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.TransitionRunner.TransitionBuilder
+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 TAG = "FLICKER"
+    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, /* app2 */null, rotation, rotation, /* description */"")
+    }
+
+    /**
+     * 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, /* app2 */null, beginRotation, endRotation, /* description */"")
+    }
+
+    /**
+     * 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,
+        app2: IAppHelper?,
+        beginRotation: Int,
+        endRotation: Int,
+        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, device: UiDevice, beginRotation: Int): TransitionBuilder {
+        return TransitionRunner.newBuilder()
+                .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,
+        device: UiDevice,
+        beginRotation: Int
+    ): TransitionBuilder {
+        return TransitionRunner.newBuilder()
+                .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,
+        device: UiDevice,
+        beginRotation: Int
+    ): TransitionBuilder {
+        return TransitionRunner.newBuilder()
+                .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,
+        device: UiDevice,
+        beginRotation: Int
+    ): TransitionBuilder {
+        return TransitionRunner.newBuilder()
+                .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,
+        device: UiDevice,
+        beginRotation: Int,
+        endRotation: Int
+    ): TransitionBuilder {
+        return TransitionRunner.newBuilder()
+                .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,
+        device: UiDevice,
+        beginRotation: Int,
+        endRotation: Int
+    ): TransitionBuilder {
+        val testTag = "changeAppRotation_" + intentId + "_" +
+                Surface.rotationToString(beginRotation) + "_" +
+                Surface.rotationToString(endRotation)
+        return TransitionRunner.newBuilder()
+                .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,
+        device: UiDevice,
+        beginRotation: Int
+    ): TransitionBuilder {
+        return TransitionRunner.newBuilder()
+                .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,
+        device: UiDevice,
+        beginRotation: Int
+    ): TransitionBuilder {
+        return TransitionRunner.newBuilder()
+                .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,
+        device: UiDevice,
+        beginRotation: Int
+    ): TransitionBuilder {
+        return TransitionRunner.newBuilder()
+                .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(
+        instr: Instrumentation,
+        testAppTop: IAppHelper,
+        testAppBottom: ImeAppHelper,
+        device: UiDevice,
+        beginRotation: Int,
+        startRatio: Rational,
+        stopRatio: Rational
+    ): TransitionBuilder {
+        val description = (startRatio.toString().replace("/", "-") + "_to_" +
+                stopRatio.toString().replace("/", "-"))
+        val testTag = buildTestTag("resizeSplitScreen", testAppTop, testAppBottom,
+                beginRotation, beginRotation, description)
+        return TransitionRunner.newBuilder()
+                .withTag(testTag)
+                .recordAllRuns()
+                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
+                .runBeforeAll { setRotation(device, beginRotation) }
+                .runBeforeAll { AutomationUtils.clearRecents(instr) }
+                .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,
+        device: UiDevice,
+        beginRotation: Int
+    ): TransitionBuilder {
+        return TransitionRunner.newBuilder()
+                .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,
+        device: UiDevice,
+        beginRotation: Int
+    ): TransitionBuilder {
+        return TransitionRunner.newBuilder()
+                .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,
+        device: UiDevice,
+        beginRotation: Int
+    ): TransitionBuilder {
+        return TransitionRunner.newBuilder()
+                .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,
+        device: UiDevice,
+        beginRotation: Int
+    ): TransitionBuilder {
+        return TransitionRunner.newBuilder()
+                .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,
+        device: UiDevice,
+        beginRotation: Int
+    ): TransitionBuilder {
+        return TransitionRunner.newBuilder()
+                .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)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.java
deleted file mode 100644
index dec5680..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 2018 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.platform.helpers.IAppHelper;
-import android.util.Rational;
-import android.view.Surface;
-
-import androidx.test.InstrumentationRegistry;
-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.Ignore;
-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.
- */
-@LargeTest
-@Ignore("Used for debugging transitions used in FlickerTests.")
-@RunWith(AndroidJUnit4.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class DebugTest {
-    private IAppHelper testApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
-            "com.android.server.wm.flicker.testapp", "SimpleApp");
-    private UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
-
-    /**
-     * atest FlickerTests:DebugTest#openAppCold
-     */
-    @Test
-    public void openAppCold() {
-        CommonTransitions.openAppCold(testApp, uiDevice, Surface.ROTATION_0)
-                .recordAllRuns().build().run();
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#openAppWarm
-     */
-    @Test
-    public void openAppWarm() {
-        CommonTransitions.openAppWarm(testApp, uiDevice, Surface.ROTATION_0)
-                .recordAllRuns().build().run();
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#changeOrientationFromNaturalToLeft
-     */
-    @Test
-    public void changeOrientationFromNaturalToLeft() {
-        CommonTransitions.changeAppRotation(testApp, uiDevice, Surface.ROTATION_0,
-                Surface.ROTATION_270).recordAllRuns().build().run();
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#closeAppWithBackKey
-     */
-    @Test
-    public void closeAppWithBackKey() {
-        CommonTransitions.closeAppWithBackKey(testApp, uiDevice, Surface.ROTATION_0)
-                .recordAllRuns().build().run();
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#closeAppWithHomeKey
-     */
-    @Test
-    public void closeAppWithHomeKey() {
-        CommonTransitions.closeAppWithHomeKey(testApp, uiDevice, Surface.ROTATION_0)
-                .recordAllRuns().build().run();
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#openAppToSplitScreen
-     */
-    @Test
-    public void openAppToSplitScreen() {
-        CommonTransitions.appToSplitScreen(testApp, uiDevice,
-                Surface.ROTATION_0).includeJankyRuns().recordAllRuns()
-                .build().run();
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#splitScreenToLauncher
-     */
-    @Test
-    public void splitScreenToLauncher() {
-        CommonTransitions.splitScreenToLauncher(testApp, uiDevice, Surface.ROTATION_0)
-                .includeJankyRuns().recordAllRuns().build().run();
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#resizeSplitScreen
-     */
-    @Test
-    public void resizeSplitScreen() {
-        Instrumentation instr = InstrumentationRegistry.getInstrumentation();
-        ImeAppHelper bottomApp = new ImeAppHelper(instr);
-        CommonTransitions.resizeSplitScreen(instr, testApp, bottomApp, uiDevice, Surface.ROTATION_0,
-                new Rational(1, 3), new Rational(2, 3))
-                .includeJankyRuns().build().run();
-    }
-
-    // IME tests
-
-    /**
-     * atest FlickerTests:DebugTest#editTextSetFocus
-     */
-    @Test
-    public void editTextSetFocus() {
-        ImeAppHelper testApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation());
-        CommonTransitions.editTextSetFocus(testApp, uiDevice, Surface.ROTATION_0)
-                .includeJankyRuns()
-                .build().run();
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#editTextLoseFocusToHome
-     */
-    @Test
-    public void editTextLoseFocusToHome() {
-        ImeAppHelper testApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation());
-        CommonTransitions.editTextLoseFocusToHome(testApp, uiDevice, Surface.ROTATION_0)
-                .includeJankyRuns()
-                .build().run();
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#editTextLoseFocusToApp
-     */
-    @Test
-    public void editTextLoseFocusToApp() {
-        ImeAppHelper testApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation());
-        CommonTransitions.editTextLoseFocusToHome(testApp, uiDevice, Surface.ROTATION_0)
-                .includeJankyRuns()
-                .build().run();
-    }
-
-    // PIP tests
-
-    /**
-     * atest FlickerTests:DebugTest#enterPipMode
-     */
-    @Test
-    public void enterPipMode() {
-        PipAppHelper testApp = new PipAppHelper(InstrumentationRegistry.getInstrumentation());
-        CommonTransitions.enterPipMode(testApp, uiDevice, Surface.ROTATION_0).includeJankyRuns()
-                .build().run();
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#exitPipModeToHome
-     */
-    @Test
-    public void exitPipModeToHome() {
-        PipAppHelper testApp = new PipAppHelper(InstrumentationRegistry.getInstrumentation());
-        CommonTransitions.exitPipModeToHome(testApp, uiDevice, Surface.ROTATION_0)
-                .includeJankyRuns()
-                .build().run();
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#exitPipModeToApp
-     */
-    @Test
-    public void exitPipModeToApp() {
-        PipAppHelper testApp = new PipAppHelper(InstrumentationRegistry.getInstrumentation());
-        CommonTransitions.exitPipModeToApp(testApp, uiDevice, Surface.ROTATION_0).includeJankyRuns()
-                .build().run();
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.kt
new file mode 100644
index 0000000..796d9a0
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.kt
@@ -0,0 +1,186 @@
+/*
+ * 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.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.Ignore
+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.
+ */
+@LargeTest
+@Ignore("Used for debugging transitions used in FlickerTests.")
+@RunWith(AndroidJUnit4::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class DebugTest {
+    private val testApp: IAppHelper = StandardAppHelper(
+            InstrumentationRegistry.getInstrumentation(),
+            "com.android.server.wm.flicker.testapp", "SimpleApp")
+    private val uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+
+    /**
+     * atest FlickerTests:DebugTest#openAppCold
+     */
+    @Test
+    fun openAppCold() {
+        CommonTransitions.openAppCold(testApp, uiDevice, Surface.ROTATION_0)
+                .recordAllRuns().build().run()
+    }
+
+    /**
+     * atest FlickerTests:DebugTest#openAppWarm
+     */
+    @Test
+    fun openAppWarm() {
+        CommonTransitions.openAppWarm(testApp, uiDevice, Surface.ROTATION_0)
+                .recordAllRuns().build().run()
+    }
+
+    /**
+     * atest FlickerTests:DebugTest#changeOrientationFromNaturalToLeft
+     */
+    @Test
+    fun changeOrientationFromNaturalToLeft() {
+        CommonTransitions.changeAppRotation(testApp, uiDevice, Surface.ROTATION_0,
+                Surface.ROTATION_270).recordAllRuns().build().run()
+    }
+
+    /**
+     * atest FlickerTests:DebugTest#closeAppWithBackKey
+     */
+    @Test
+    fun closeAppWithBackKey() {
+        CommonTransitions.closeAppWithBackKey(testApp, uiDevice, Surface.ROTATION_0)
+                .recordAllRuns().build().run()
+    }
+
+    /**
+     * atest FlickerTests:DebugTest#closeAppWithHomeKey
+     */
+    @Test
+    fun closeAppWithHomeKey() {
+        CommonTransitions.closeAppWithHomeKey(testApp, uiDevice, Surface.ROTATION_0)
+                .recordAllRuns().build().run()
+    }
+
+    /**
+     * atest FlickerTests:DebugTest#openAppToSplitScreen
+     */
+    @Test
+    fun openAppToSplitScreen() {
+        CommonTransitions.appToSplitScreen(testApp, uiDevice,
+                Surface.ROTATION_0).includeJankyRuns().recordAllRuns()
+                .build().run()
+    }
+
+    /**
+     * atest FlickerTests:DebugTest#splitScreenToLauncher
+     */
+    @Test
+    fun splitScreenToLauncher() {
+        CommonTransitions.splitScreenToLauncher(testApp, uiDevice, Surface.ROTATION_0)
+                .includeJankyRuns().recordAllRuns().build().run()
+    }
+
+    /**
+     * atest FlickerTests:DebugTest#resizeSplitScreen
+     */
+    @Test
+    fun resizeSplitScreen() {
+        val instr = InstrumentationRegistry.getInstrumentation()
+        val bottomApp = ImeAppHelper(instr)
+        CommonTransitions.resizeSplitScreen(instr, testApp, bottomApp, 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(InstrumentationRegistry.getInstrumentation())
+        CommonTransitions.editTextSetFocus(testApp, uiDevice, Surface.ROTATION_0)
+                .includeJankyRuns()
+                .build().run()
+    }
+
+    /**
+     * atest FlickerTests:DebugTest#editTextLoseFocusToHome
+     */
+    @Test
+    fun editTextLoseFocusToHome() {
+        val testApp = ImeAppHelper(InstrumentationRegistry.getInstrumentation())
+        CommonTransitions.editTextLoseFocusToHome(testApp, uiDevice, Surface.ROTATION_0)
+                .includeJankyRuns()
+                .build().run()
+    }
+
+    /**
+     * atest FlickerTests:DebugTest#editTextLoseFocusToApp
+     */
+    @Test
+    fun editTextLoseFocusToApp() {
+        val testApp = ImeAppHelper(InstrumentationRegistry.getInstrumentation())
+        CommonTransitions.editTextLoseFocusToHome(testApp, uiDevice, Surface.ROTATION_0)
+                .includeJankyRuns()
+                .build().run()
+    }
+    // PIP tests
+    /**
+     * atest FlickerTests:DebugTest#enterPipMode
+     */
+    @Test
+    fun enterPipMode() {
+        val testApp = PipAppHelper(InstrumentationRegistry.getInstrumentation())
+        CommonTransitions.enterPipMode(testApp, uiDevice, Surface.ROTATION_0).includeJankyRuns()
+                .build().run()
+    }
+
+    /**
+     * atest FlickerTests:DebugTest#exitPipModeToHome
+     */
+    @Test
+    fun exitPipModeToHome() {
+        val testApp = PipAppHelper(InstrumentationRegistry.getInstrumentation())
+        CommonTransitions.exitPipModeToHome(testApp, uiDevice, Surface.ROTATION_0)
+                .includeJankyRuns()
+                .build().run()
+    }
+
+    /**
+     * atest FlickerTests:DebugTest#exitPipModeToApp
+     */
+    @Test
+    fun exitPipModeToApp() {
+        val testApp = PipAppHelper(InstrumentationRegistry.getInstrumentation())
+        CommonTransitions.exitPipModeToApp(testApp, uiDevice, Surface.ROTATION_0).includeJankyRuns()
+                .build().run()
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.java b/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.java
deleted file mode 100644
index 6bbf684..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2018 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 static com.android.server.wm.flicker.helpers.AutomationUtils.setDefaultWait;
-
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.platform.helpers.IAppHelper;
-import android.util.Log;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.uiautomator.UiDevice;
-
-import com.android.server.wm.flicker.TransitionRunner.TransitionResult;
-
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.function.Consumer;
-
-/**
- * Base class of all Flicker test that performs common functions for all flicker tests:
- * <p>
- * - Caches transitions so that a transition is run once and the transition results are used by
- * tests multiple times. This is needed for parameterized tests which call the BeforeClass methods
- * multiple times.
- * - Keeps track of all test artifacts and deletes ones which do not need to be reviewed.
- * - Fails tests if results are not available for any test due to jank.
- */
-public abstract class FlickerTestBase {
-    public static final String TAG = "FLICKER";
-    static final String SCREENSHOT_LAYER = "RotationLayer";
-    static final String NAVIGATION_BAR_WINDOW_TITLE = "NavigationBar";
-    static final String STATUS_BAR_WINDOW_TITLE = "StatusBar";
-    static final String DOCKED_STACK_DIVIDER = "DockedStackDivider";
-    private static HashMap<String, List<TransitionResult>> transitionResults =
-            new HashMap<>();
-    IAppHelper mTestApp;
-    UiDevice mUiDevice;
-    private List<TransitionResult> mResults;
-    private TransitionResult mLastResult = null;
-
-    @Before
-    public void setUp() {
-        mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
-    }
-
-    /**
-     * 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
-    public static void teardown() {
-        setDefaultWait();
-        transitionResults.values().stream()
-                .flatMap(List::stream)
-                .forEach(result -> {
-                    if (result.canDelete()) {
-                        result.delete();
-                    } else {
-                        if (result.layersTraceExists()) {
-                            Log.e(TAG, "Layers trace saved to " + result.getLayersTracePath());
-                        }
-                        if (result.windowManagerTraceExists()) {
-                            Log.e(TAG, "WindowManager trace saved to " + result
-                                    .getWindowManagerTracePath
-                                            ());
-                        }
-                        if (result.screenCaptureVideoExists()) {
-                            Log.e(TAG, "Screen capture video saved to " + result
-                                    .screenCaptureVideoPath().toString());
-                        }
-                    }
-                });
-    }
-
-    /**
-     * Runs a transition, returns a cached result if the transition has run before.
-     */
-    void run(TransitionRunner transition) {
-        if (transitionResults.containsKey(transition.getTestTag())) {
-            mResults = transitionResults.get(transition.getTestTag());
-            return;
-        }
-        mResults = transition.run().getResults();
-        /* Fail if we don't have any results due to jank */
-        assertWithMessage("No results to test because all transition runs were invalid because "
-                + "of Jank").that(mResults).isNotEmpty();
-        transitionResults.put(transition.getTestTag(), mResults);
-    }
-
-    /**
-     * Runs a transition, returns a cached result if the transition has run before.
-     */
-    @Before
-    public void runTransition() {
-        run(getTransitionToRun());
-    }
-
-    /**
-     * Gets the transition that will be executed
-     */
-    abstract TransitionRunner getTransitionToRun();
-
-    /**
-     * Goes through a list of transition results and checks assertions on each result.
-     */
-    void checkResults(Consumer<TransitionResult> assertion) {
-
-        for (TransitionResult result : mResults) {
-            mLastResult = result;
-            assertion.accept(result);
-        }
-        mLastResult = null;
-    }
-
-    /**
-     * Kludge to mark a file for saving. If {@code checkResults} fails, the last result is not
-     * cleared. This indicates the assertion failed for the result, so mark it for saving.
-     */
-    @After
-    public void markArtifactsForSaving() {
-        if (mLastResult != null) {
-            mLastResult.flagForSaving();
-        }
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.kt
new file mode 100644
index 0000000..17c8d91
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.kt
@@ -0,0 +1,135 @@
+/*
+ * 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.Log
+import androidx.test.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import com.android.server.wm.flicker.TransitionRunner.TransitionResult
+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:
+ *
+ *
+ * - Caches transitions so that a transition is run once and the transition results are used by
+ * tests multiple times. This is needed for parameterized tests which call the BeforeClass methods
+ * multiple times.
+ * - Keeps track of all test artifacts and deletes ones which do not need to be reviewed.
+ * - Fails tests if results are not available for any test due to jank.
+ */
+abstract class FlickerTestBase {
+    lateinit var testApp: IAppHelper
+    val uiDevice: UiDevice by lazy {
+        UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+    }
+    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
+        }
+        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)
+        }
+        lastResult = null
+    }
+
+    /**
+     * 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()
+    }
+
+    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()}")
+                        }
+                    }
+                }
+        }
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/NonRotationTestBase.java b/tests/FlickerTests/src/com/android/server/wm/flicker/NonRotationTestBase.java
deleted file mode 100644
index 54941dc..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/NonRotationTestBase.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2019 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 static android.view.Surface.rotationToString;
-
-import static com.android.server.wm.flicker.WindowUtils.getDisplayBounds;
-
-import android.graphics.Rect;
-import android.view.Surface;
-
-import androidx.test.filters.FlakyTest;
-
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runners.Parameterized.Parameters;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-public abstract class NonRotationTestBase extends FlickerTestBase {
-
-    int mBeginRotation;
-
-    public NonRotationTestBase(String beginRotationName, int beginRotation) {
-        this.mBeginRotation = beginRotation;
-    }
-
-    @Parameters(name = "{0}")
-    public static Collection<Object[]> getParams() {
-        int[] supportedRotations =
-                {Surface.ROTATION_0, Surface.ROTATION_90};
-        Collection<Object[]> params = new ArrayList<>();
-
-        for (int begin : supportedRotations) {
-            params.add(new Object[]{rotationToString(begin), begin});
-        }
-
-        return params;
-    }
-
-    @FlakyTest(bugId = 141361128)
-    @Ignore("Waiting bug feedback")
-    @Test
-    public void checkCoveredRegion_noUncoveredRegions() {
-        Rect displayBounds = getDisplayBounds(mBeginRotation);
-        checkResults(result -> LayersTraceSubject.assertThat(result).coversRegion(
-                displayBounds).forAllEntries());
-    }
-
-    @FlakyTest(bugId = 141361128)
-    @Ignore("Waiting bug feedback")
-    @Test
-    public void checkVisibility_navBarLayerIsAlwaysVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries());
-    }
-
-    @FlakyTest(bugId = 141361128)
-    @Ignore("Waiting bug feedback")
-    @Test
-    public void checkVisibility_statusBarLayerIsAlwaysVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(STATUS_BAR_WINDOW_TITLE).forAllEntries());
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/NonRotationTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/NonRotationTestBase.kt
new file mode 100644
index 0000000..653fecd
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/NonRotationTestBase.kt
@@ -0,0 +1,72 @@
+/*
+ * 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.view.Surface
+import androidx.test.filters.FlakyTest
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runners.Parameterized
+
+abstract class NonRotationTestBase(
+    beginRotationName: String,
+    protected val beginRotation: Int
+) : FlickerTestBase() {
+    @FlakyTest(bugId = 141361128)
+    @Ignore("Waiting bug feedback")
+    @Test
+    fun checkCoveredRegion_noUncoveredRegions() {
+        val displayBounds = WindowUtils.getDisplayBounds(beginRotation)
+        checkResults {
+            LayersTraceSubject.assertThat(it).coversRegion(
+                    displayBounds).forAllEntries()
+        }
+    }
+
+    @FlakyTest(bugId = 141361128)
+    @Ignore("Waiting bug feedback")
+    @Test
+    fun checkVisibility_navBarLayerIsAlwaysVisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .showsLayer(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries()
+        }
+    }
+
+    @FlakyTest(bugId = 141361128)
+    @Ignore("Waiting bug feedback")
+    @Test
+    fun checkVisibility_statusBarLayerIsAlwaysVisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .showsLayer(STATUS_BAR_WINDOW_TITLE).forAllEntries()
+        }
+    }
+
+    companion object {
+        @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
+        }
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppColdTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppColdTest.java
deleted file mode 100644
index c150e09..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppColdTest.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2018 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 static com.android.server.wm.flicker.CommonTransitions.openAppCold;
-import static com.android.server.wm.flicker.WmTraceSubject.assertThat;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.FlakyTest;
-import androidx.test.filters.LargeTest;
-
-import org.junit.FixMethodOrder;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.MethodSorters;
-import org.junit.runners.Parameterized;
-
-/**
- * Test cold launch app from launcher.
- * To run this test: {@code atest FlickerTests:OpenAppColdTest}
- */
-@LargeTest
-@RunWith(Parameterized.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class OpenAppColdTest extends NonRotationTestBase {
-
-    public OpenAppColdTest(String beginRotationName, int beginRotation) {
-        super(beginRotationName, beginRotation);
-
-        this.mTestApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
-                "com.android.server.wm.flicker.testapp", "SimpleApp");
-    }
-
-    @Override
-    TransitionRunner getTransitionToRun() {
-        return openAppCold(mTestApp, mUiDevice, mBeginRotation)
-                .includeJankyRuns().build();
-    }
-
-    @Test
-    public void checkVisibility_wallpaperWindowBecomesInvisible() {
-        checkResults(result -> assertThat(result)
-                .showsBelowAppWindow("Wallpaper")
-                .then()
-                .hidesBelowAppWindow("Wallpaper")
-                .forAllEntries());
-    }
-
-    @FlakyTest(bugId = 140855415)
-    @Ignore("Waiting bug feedback")
-    @Test
-    public void checkZOrder_appWindowReplacesLauncherAsTopWindow() {
-        checkResults(result -> assertThat(result)
-                .showsAppWindowOnTop(
-                        "com.android.launcher3/.Launcher")
-                .then()
-                .showsAppWindowOnTop(mTestApp.getPackage())
-                .forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_wallpaperLayerBecomesInvisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer("Wallpaper")
-                .then()
-                .replaceVisibleLayer("Wallpaper", mTestApp.getPackage())
-                .forAllEntries());
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppColdTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppColdTest.kt
new file mode 100644
index 0000000..b7eb22f
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppColdTest.kt
@@ -0,0 +1,84 @@
+/*
+ * 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 androidx.test.InstrumentationRegistry
+import androidx.test.filters.FlakyTest
+import androidx.test.filters.LargeTest
+import org.junit.FixMethodOrder
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test cold launch app from launcher.
+ * To run this test: `atest FlickerTests:OpenAppColdTest`
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class OpenAppColdTest(
+    beginRotationName: String,
+    beginRotation: Int
+) : NonRotationTestBase(beginRotationName, beginRotation) {
+    init {
+        testApp = StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
+                "com.android.server.wm.flicker.testapp", "SimpleApp")
+    }
+
+    override val transitionToRun: TransitionRunner
+        get() = CommonTransitions.openAppCold(testApp, uiDevice, beginRotation)
+                .includeJankyRuns().build()
+
+    @Test
+    fun checkVisibility_wallpaperWindowBecomesInvisible() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .showsBelowAppWindow("Wallpaper")
+                    .then()
+                    .hidesBelowAppWindow("Wallpaper")
+                    .forAllEntries()
+        }
+    }
+
+    @FlakyTest(bugId = 140855415)
+    @Ignore("Waiting bug feedback")
+    @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/OpenAppToSplitScreenTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppToSplitScreenTest.java
deleted file mode 100644
index 00da62f..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppToSplitScreenTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2018 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 static com.android.server.wm.flicker.CommonTransitions.appToSplitScreen;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.LargeTest;
-
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.MethodSorters;
-import org.junit.runners.Parameterized;
-
-/**
- * Test open app to split screen.
- * To run this test: {@code atest FlickerTests:OpenAppToSplitScreenTest}
- */
-@LargeTest
-@RunWith(Parameterized.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class OpenAppToSplitScreenTest extends NonRotationTestBase {
-
-    public OpenAppToSplitScreenTest(String beginRotationName, int beginRotation) {
-        super(beginRotationName, beginRotation);
-
-        this.mTestApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
-                "com.android.server.wm.flicker.testapp", "SimpleApp");
-    }
-
-    @Override
-    TransitionRunner getTransitionToRun() {
-        return appToSplitScreen(mTestApp, mUiDevice, mBeginRotation)
-                .includeJankyRuns()
-                .build();
-    }
-
-    @Test
-    public void checkVisibility_navBarWindowIsAlwaysVisible() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_statusBarWindowIsAlwaysVisible() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE).forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_dividerLayerBecomesVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .hidesLayer(DOCKED_STACK_DIVIDER)
-                .then()
-                .showsLayer(DOCKED_STACK_DIVIDER)
-                .forAllEntries());
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppToSplitScreenTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppToSplitScreenTest.kt
new file mode 100644
index 0000000..5e0be58
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppToSplitScreenTest.kt
@@ -0,0 +1,74 @@
+/*
+ * 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 androidx.test.InstrumentationRegistry
+import androidx.test.filters.LargeTest
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test open app to split screen.
+ * To run this test: `atest FlickerTests:OpenAppToSplitScreenTest`
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class OpenAppToSplitScreenTest(
+    beginRotationName: String,
+    beginRotation: Int
+) : NonRotationTestBase(beginRotationName, beginRotation) {
+    init {
+        testApp = StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
+                "com.android.server.wm.flicker.testapp", "SimpleApp")
+    }
+
+    override val transitionToRun: TransitionRunner
+        get() = CommonTransitions.appToSplitScreen(testApp, uiDevice, beginRotation)
+                .includeJankyRuns()
+                .build()
+
+    @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()
+        }
+    }
+
+    @Test
+    fun checkVisibility_dividerLayerBecomesVisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .hidesLayer(DOCKED_STACK_DIVIDER)
+                    .then()
+                    .showsLayer(DOCKED_STACK_DIVIDER)
+                    .forAllEntries()
+        }
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppWarmTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppWarmTest.java
deleted file mode 100644
index 62ae254..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppWarmTest.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2018 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 static com.android.server.wm.flicker.CommonTransitions.openAppWarm;
-import static com.android.server.wm.flicker.WmTraceSubject.assertThat;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.FlakyTest;
-import androidx.test.filters.LargeTest;
-
-import org.junit.FixMethodOrder;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.MethodSorters;
-import org.junit.runners.Parameterized;
-
-/**
- * Test warm launch app.
- * To run this test: {@code atest FlickerTests:OpenAppWarmTest}
- */
-@LargeTest
-@RunWith(Parameterized.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class OpenAppWarmTest extends NonRotationTestBase {
-
-    public OpenAppWarmTest(String beginRotationName, int beginRotation) {
-        super(beginRotationName, beginRotation);
-
-        this.mTestApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
-                "com.android.server.wm.flicker.testapp", "SimpleApp");
-    }
-
-    @Override
-    TransitionRunner getTransitionToRun() {
-        return openAppWarm(mTestApp, mUiDevice, mBeginRotation)
-                .includeJankyRuns().build();
-    }
-
-    @Test
-    public void checkVisibility_wallpaperBecomesInvisible() {
-        checkResults(result -> assertThat(result)
-                .showsBelowAppWindow("Wallpaper")
-                .then()
-                .hidesBelowAppWindow("Wallpaper")
-                .forAllEntries());
-    }
-
-    @FlakyTest(bugId = 140855415)
-    @Ignore("Waiting bug feedback")
-    @Test
-    public void checkZOrder_appWindowReplacesLauncherAsTopWindow() {
-        checkResults(result -> assertThat(result)
-                .showsAppWindowOnTop(
-                        "com.android.launcher3/.Launcher")
-                .then()
-                .showsAppWindowOnTop(mTestApp.getPackage())
-                .forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_wallpaperLayerBecomesInvisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer("Wallpaper")
-                .then()
-                .replaceVisibleLayer("Wallpaper", mTestApp.getPackage())
-                .forAllEntries());
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppWarmTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppWarmTest.kt
new file mode 100644
index 0000000..cc77a72
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppWarmTest.kt
@@ -0,0 +1,84 @@
+/*
+ * 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 androidx.test.InstrumentationRegistry
+import androidx.test.filters.FlakyTest
+import androidx.test.filters.LargeTest
+import org.junit.FixMethodOrder
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test warm launch app.
+ * To run this test: `atest FlickerTests:OpenAppWarmTest`
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class OpenAppWarmTest(
+    beginRotationName: String,
+    beginRotation: Int
+) : NonRotationTestBase(beginRotationName, beginRotation) {
+    init {
+        testApp = StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
+                "com.android.server.wm.flicker.testapp", "SimpleApp")
+    }
+
+    override val transitionToRun: TransitionRunner
+        get() = CommonTransitions.openAppWarm(testApp, uiDevice, beginRotation)
+                .includeJankyRuns().build()
+
+    @Test
+    fun checkVisibility_wallpaperBecomesInvisible() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .showsBelowAppWindow("Wallpaper")
+                    .then()
+                    .hidesBelowAppWindow("Wallpaper")
+                    .forAllEntries()
+        }
+    }
+
+    @FlakyTest(bugId = 140855415)
+    @Ignore("Waiting bug feedback")
+    @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()
+        }
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenImeWindowTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenImeWindowTest.java
deleted file mode 100644
index fcb022c..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenImeWindowTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2018 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 static com.android.server.wm.flicker.CommonTransitions.editTextSetFocus;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.LargeTest;
-
-import com.android.server.wm.flicker.helpers.ImeAppHelper;
-
-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 opening transitions.
- * To run this test: {@code atest FlickerTests:OpenImeWindowTest}
- */
-@LargeTest
-@RunWith(Parameterized.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class OpenImeWindowTest extends NonRotationTestBase {
-
-    private static final String IME_WINDOW_TITLE = "InputMethod";
-
-    public OpenImeWindowTest(String beginRotationName, int beginRotation) {
-        super(beginRotationName, beginRotation);
-
-        mTestApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation());
-    }
-
-    @Override
-    TransitionRunner getTransitionToRun() {
-        return editTextSetFocus((ImeAppHelper) mTestApp, mUiDevice, mBeginRotation)
-                .includeJankyRuns().build();
-    }
-
-    @Test
-    public void checkVisibility_imeWindowBecomesVisible() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .skipUntilFirstAssertion()
-                .hidesImeWindow(IME_WINDOW_TITLE)
-                .then()
-                .showsImeWindow(IME_WINDOW_TITLE)
-                .forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_imeLayerBecomesVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .hidesLayer(IME_WINDOW_TITLE)
-                .then()
-                .showsLayer(IME_WINDOW_TITLE)
-                .forAllEntries());
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenImeWindowTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenImeWindowTest.kt
new file mode 100644
index 0000000..d01b3b7
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenImeWindowTest.kt
@@ -0,0 +1,74 @@
+/*
+ * 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 androidx.test.InstrumentationRegistry
+import androidx.test.filters.LargeTest
+import com.android.server.wm.flicker.helpers.ImeAppHelper
+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 opening transitions.
+ * To run this test: `atest FlickerTests:OpenImeWindowTest`
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class OpenImeWindowTest(
+    beginRotationName: String,
+    beginRotation: Int
+) : NonRotationTestBase(beginRotationName, beginRotation) {
+    init {
+        testApp = ImeAppHelper(InstrumentationRegistry.getInstrumentation())
+    }
+
+    override val transitionToRun: TransitionRunner
+        get() = CommonTransitions.editTextSetFocus(testApp as ImeAppHelper,
+                uiDevice, beginRotation)
+                .includeJankyRuns().build()
+
+    @Test
+    fun checkVisibility_imeWindowBecomesVisible() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .skipUntilFirstAssertion()
+                    .hidesImeWindow(IME_WINDOW_TITLE)
+                    .then()
+                    .showsImeWindow(IME_WINDOW_TITLE)
+                    .forAllEntries()
+        }
+    }
+
+    @Test
+    fun checkVisibility_imeLayerBecomesVisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .hidesLayer(IME_WINDOW_TITLE)
+                    .then()
+                    .showsLayer(IME_WINDOW_TITLE)
+                    .forAllEntries()
+        }
+    }
+
+    companion object {
+        private const val IME_WINDOW_TITLE = "InputMethod"
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/PipTestBase.java b/tests/FlickerTests/src/com/android/server/wm/flicker/PipTestBase.java
deleted file mode 100644
index cf51d78..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/PipTestBase.java
+++ /dev/null
@@ -1,75 +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 static com.android.server.wm.flicker.helpers.AutomationUtils.closePipWindow;
-import static com.android.server.wm.flicker.helpers.AutomationUtils.hasPipWindow;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.LargeTest;
-import androidx.test.uiautomator.UiDevice;
-
-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)
-public abstract class PipTestBase extends NonRotationTestBase {
-    static final String sPipWindowTitle = "PipMenuActivity";
-
-    public PipTestBase(String beginRotationName, int beginRotation) {
-        super(beginRotationName, beginRotation);
-
-        this.mTestApp = new PipAppHelper(InstrumentationRegistry.getInstrumentation());
-    }
-
-    @AfterClass
-    public static void teardown() {
-        UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
-
-        if (hasPipWindow(device)) {
-            closePipWindow(device);
-        }
-    }
-
-    @Test
-    public void checkVisibility_pipWindowBecomesVisible() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .skipUntilFirstAssertion()
-                .showsAppWindowOnTop(sPipWindowTitle)
-                .then()
-                .hidesAppWindow(sPipWindowTitle)
-                .forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_pipLayerBecomesVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .skipUntilFirstAssertion()
-                .showsLayer(sPipWindowTitle)
-                .then()
-                .hidesLayer(sPipWindowTitle)
-                .forAllEntries());
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/PipTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/PipTestBase.kt
new file mode 100644
index 0000000..7ca06b5
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/PipTestBase.kt
@@ -0,0 +1,78 @@
+/*
+ * 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 androidx.test.InstrumentationRegistry
+import androidx.test.filters.LargeTest
+import androidx.test.uiautomator.UiDevice
+import com.android.server.wm.flicker.helpers.AutomationUtils
+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(InstrumentationRegistry.getInstrumentation())
+    }
+
+    @Test
+    fun checkVisibility_pipWindowBecomesVisible() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .skipUntilFirstAssertion()
+                    .showsAppWindowOnTop(sPipWindowTitle)
+                    .then()
+                    .hidesAppWindow(sPipWindowTitle)
+                    .forAllEntries()
+        }
+    }
+
+    @Test
+    fun checkVisibility_pipLayerBecomesVisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .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)
+            }
+        }
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/PipToAppTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/PipToAppTest.java
deleted file mode 100644
index 5e67ada..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/PipToAppTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2019 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 static com.android.server.wm.flicker.CommonTransitions.exitPipModeToApp;
-
-import androidx.test.filters.FlakyTest;
-import androidx.test.filters.LargeTest;
-
-import com.android.server.wm.flicker.helpers.PipAppHelper;
-
-import org.junit.FixMethodOrder;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.MethodSorters;
-import org.junit.runners.Parameterized;
-
-/**
- * Test Pip launch.
- * To run this test: {@code atest FlickerTests:PipToAppTest}
- */
-@LargeTest
-@RunWith(Parameterized.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@FlakyTest(bugId = 152738416)
-@Ignore("Waiting bug feedback")
-public class PipToAppTest extends PipTestBase {
-    public PipToAppTest(String beginRotationName, int beginRotation) {
-        super(beginRotationName, beginRotation);
-    }
-
-    @Override
-    TransitionRunner getTransitionToRun() {
-        return exitPipModeToApp((PipAppHelper) mTestApp, mUiDevice, mBeginRotation)
-                .includeJankyRuns().build();
-    }
-
-    @Test
-    public void checkVisibility_backgroundWindowVisibleBehindPipLayer() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .skipUntilFirstAssertion()
-                .showsAppWindowOnTop(sPipWindowTitle)
-                .then()
-                .showsBelowAppWindow("Wallpaper")
-                .then()
-                .showsAppWindowOnTop(mTestApp.getPackage())
-                .then()
-                .hidesAppWindowOnTop(mTestApp.getPackage())
-                .forAllEntries());
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/PipToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/PipToAppTest.kt
new file mode 100644
index 0000000..6656b86
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/PipToAppTest.kt
@@ -0,0 +1,62 @@
+/*
+ * 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 androidx.test.filters.FlakyTest
+import androidx.test.filters.LargeTest
+import com.android.server.wm.flicker.helpers.PipAppHelper
+import org.junit.FixMethodOrder
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test Pip launch.
+ * To run this test: `atest FlickerTests:PipToAppTest`
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@FlakyTest(bugId = 152738416)
+@Ignore("Waiting bug feedback")
+class PipToAppTest(
+    beginRotationName: String,
+    beginRotation: Int
+) : PipTestBase(beginRotationName, beginRotation) {
+    override val transitionToRun: TransitionRunner
+        get() = CommonTransitions.exitPipModeToApp(testApp as PipAppHelper,
+                uiDevice, beginRotation)
+                .includeJankyRuns().build()
+
+    @Test
+    fun checkVisibility_backgroundWindowVisibleBehindPipLayer() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .skipUntilFirstAssertion()
+                    .showsAppWindowOnTop(sPipWindowTitle)
+                    .then()
+                    .showsBelowAppWindow("Wallpaper")
+                    .then()
+                    .showsAppWindowOnTop(testApp.getPackage())
+                    .then()
+                    .hidesAppWindowOnTop(testApp.getPackage())
+                    .forAllEntries()
+        }
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/PipToHomeTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/PipToHomeTest.java
deleted file mode 100644
index af713c7..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/PipToHomeTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2019 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 static com.android.server.wm.flicker.CommonTransitions.exitPipModeToHome;
-
-import androidx.test.filters.FlakyTest;
-import androidx.test.filters.LargeTest;
-
-import com.android.server.wm.flicker.helpers.PipAppHelper;
-
-import org.junit.FixMethodOrder;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.MethodSorters;
-import org.junit.runners.Parameterized;
-
-/**
- * Test Pip launch.
- * To run this test: {@code atest FlickerTests:PipToHomeTest}
- */
-@LargeTest
-@RunWith(Parameterized.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@FlakyTest(bugId = 152738416)
-@Ignore("Waiting bug feedback")
-public class PipToHomeTest extends PipTestBase {
-    public PipToHomeTest(String beginRotationName, int beginRotation) {
-        super(beginRotationName, beginRotation);
-    }
-
-    @Override
-    TransitionRunner getTransitionToRun() {
-        return exitPipModeToHome((PipAppHelper) mTestApp, mUiDevice, mBeginRotation)
-                .includeJankyRuns().build();
-    }
-
-    @Ignore
-    @Test
-    public void checkVisibility_backgroundWindowVisibleBehindPipLayer() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .showsAppWindowOnTop(sPipWindowTitle)
-                .then()
-                .showsBelowAppWindow("Wallpaper")
-                .then()
-                .showsAppWindowOnTop("Wallpaper")
-                .forAllEntries());
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/PipToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/PipToHomeTest.kt
new file mode 100644
index 0000000..9619c58
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/PipToHomeTest.kt
@@ -0,0 +1,60 @@
+/*
+ * 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 androidx.test.filters.FlakyTest
+import androidx.test.filters.LargeTest
+import com.android.server.wm.flicker.helpers.PipAppHelper
+import org.junit.FixMethodOrder
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test Pip launch.
+ * To run this test: `atest FlickerTests:PipToHomeTest`
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@FlakyTest(bugId = 152738416)
+@Ignore("Waiting bug feedback")
+class PipToHomeTest(
+    beginRotationName: String,
+    beginRotation: Int
+) : PipTestBase(beginRotationName, beginRotation) {
+    override val transitionToRun: TransitionRunner
+        get() = CommonTransitions.exitPipModeToHome(testApp as PipAppHelper,
+                uiDevice, beginRotation)
+                .includeJankyRuns().build()
+
+    @Ignore
+    @Test
+    fun checkVisibility_backgroundWindowVisibleBehindPipLayer() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .showsAppWindowOnTop(sPipWindowTitle)
+                    .then()
+                    .showsBelowAppWindow("Wallpaper")
+                    .then()
+                    .showsAppWindowOnTop("Wallpaper")
+                    .forAllEntries()
+        }
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ResizeSplitScreenTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/ResizeSplitScreenTest.java
deleted file mode 100644
index 9516af6..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ResizeSplitScreenTest.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2018 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 static com.android.server.wm.flicker.CommonTransitions.resizeSplitScreen;
-import static com.android.server.wm.flicker.WindowUtils.getDisplayBounds;
-import static com.android.server.wm.flicker.WindowUtils.getDockedStackDividerInset;
-import static com.android.server.wm.flicker.WindowUtils.getNavigationBarHeight;
-import static com.android.server.wm.flicker.helpers.AutomationUtils.exitSplitScreen;
-import static com.android.server.wm.flicker.helpers.AutomationUtils.isInSplitScreen;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.Instrumentation;
-import android.graphics.Rect;
-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 org.junit.AfterClass;
-import org.junit.FixMethodOrder;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.MethodSorters;
-
-/**
- * Test split screen resizing window transitions.
- * To run this test: {@code atest FlickerTests:ResizeSplitScreenTest}
- *
- * Currently it runs only in 0 degrees because of b/156100803
- */
-@LargeTest
-@RunWith(AndroidJUnit4.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@FlakyTest(bugId = 159096424)
-@Ignore("Waiting bug feedback")
-public class ResizeSplitScreenTest extends FlickerTestBase {
-
-    private static String sSimpleActivity = "SimpleActivity";
-    private static String sImeActivity = "ImeActivity";
-
-    public ResizeSplitScreenTest() {
-        this.mTestApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
-                "com.android.server.wm.flicker.testapp", "SimpleApp");
-    }
-
-    @Override
-    TransitionRunner getTransitionToRun() {
-        Instrumentation instr = InstrumentationRegistry.getInstrumentation();
-        ImeAppHelper bottomApp = new ImeAppHelper(instr);
-        return resizeSplitScreen(instr, mTestApp, bottomApp, mUiDevice, Surface.ROTATION_0,
-                new Rational(1, 3), new Rational(2, 3))
-                .includeJankyRuns().build();
-    }
-
-    @Test
-    public void checkVisibility_topAppLayerIsAlwaysVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(sSimpleActivity)
-                .forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_bottomAppLayerIsAlwaysVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(sImeActivity)
-                .forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_dividerLayerIsAlwaysVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(DOCKED_STACK_DIVIDER)
-                .forAllEntries());
-    }
-
-    @Test
-    @Ignore("Waiting feedback")
-    public void checkPosition_appsStartingBounds() {
-        Rect displayBounds = getDisplayBounds();
-        checkResults(result -> {
-            LayersTrace entries = LayersTrace.parseFrom(result.getLayersTrace(),
-                    result.getLayersTracePath(), result.getLayersTraceChecksum());
-
-            assertThat(entries.getEntries()).isNotEmpty();
-            Rect startingDividerBounds = entries.getEntries().get(0).getVisibleBounds
-                    (DOCKED_STACK_DIVIDER);
-
-            Rect startingTopAppBounds = new Rect(0, 0, startingDividerBounds.right,
-                    startingDividerBounds.top + getDockedStackDividerInset());
-
-            Rect startingBottomAppBounds = new Rect(0,
-                    startingDividerBounds.bottom - getDockedStackDividerInset(),
-                    displayBounds.right,
-                    displayBounds.bottom - getNavigationBarHeight());
-
-            LayersTraceSubject.assertThat(result)
-                    .hasVisibleRegion("SimpleActivity", startingTopAppBounds)
-                    .inTheBeginning();
-
-            LayersTraceSubject.assertThat(result)
-                    .hasVisibleRegion("ImeActivity", startingBottomAppBounds)
-                    .inTheBeginning();
-        });
-    }
-
-    @Test
-    @Ignore("Waiting feedback")
-    public void checkPosition_appsEndingBounds() {
-        Rect displayBounds = getDisplayBounds();
-        checkResults(result -> {
-            LayersTrace entries = LayersTrace.parseFrom(result.getLayersTrace(),
-                    result.getLayersTracePath(), result.getLayersTraceChecksum());
-
-            assertThat(entries.getEntries()).isNotEmpty();
-            Rect endingDividerBounds = entries.getEntries().get(
-                    entries.getEntries().size() - 1).getVisibleBounds(
-                    DOCKED_STACK_DIVIDER);
-
-            Rect startingTopAppBounds = new Rect(0, 0, endingDividerBounds.right,
-                    endingDividerBounds.top + getDockedStackDividerInset());
-
-            Rect startingBottomAppBounds = new Rect(0,
-                    endingDividerBounds.bottom - getDockedStackDividerInset(),
-                    displayBounds.right,
-                    displayBounds.bottom - getNavigationBarHeight());
-
-            LayersTraceSubject.assertThat(result)
-                    .hasVisibleRegion(sSimpleActivity, startingTopAppBounds)
-                    .atTheEnd();
-
-            LayersTraceSubject.assertThat(result)
-                    .hasVisibleRegion(sImeActivity, startingBottomAppBounds)
-                    .atTheEnd();
-        });
-    }
-
-    @Test
-    public void checkVisibility_navBarWindowIsAlwaysVisible() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE)
-                .forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_statusBarWindowIsAlwaysVisible() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE)
-                .forAllEntries());
-    }
-
-    @Test
-    @FlakyTest(bugId = 156223549)
-    @Ignore("Waiting bug feedback")
-    public void checkVisibility_topAppWindowIsAlwaysVisible() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .showsAppWindow(sSimpleActivity)
-                .forAllEntries());
-    }
-
-    @Test
-    @FlakyTest(bugId = 156223549)
-    @Ignore("Waiting bug feedback")
-    public void checkVisibility_bottomAppWindowIsAlwaysVisible() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .showsAppWindow(sImeActivity)
-                .forAllEntries());
-    }
-
-    @AfterClass
-    public static void teardown() {
-        UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
-
-        if (isInSplitScreen(device)) {
-            exitSplitScreen(device);
-        }
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ResizeSplitScreenTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ResizeSplitScreenTest.kt
new file mode 100644
index 0000000..3eaad49
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ResizeSplitScreenTest.kt
@@ -0,0 +1,195 @@
+/*
+ * 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.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.TransitionRunner.TransitionResult
+import com.android.server.wm.flicker.helpers.AutomationUtils
+import com.android.server.wm.flicker.helpers.ImeAppHelper
+import com.google.common.truth.Truth
+import org.junit.AfterClass
+import org.junit.FixMethodOrder
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+
+/**
+ * Test split screen resizing window transitions.
+ * To run this test: `atest FlickerTests:ResizeSplitScreenTest`
+ *
+ * Currently it runs only in 0 degrees because of b/156100803
+ */
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@FlakyTest(bugId = 159096424)
+@Ignore("Waiting bug feedback")
+class ResizeSplitScreenTest : FlickerTestBase() {
+    init {
+        testApp = StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
+                "com.android.server.wm.flicker.testapp", "SimpleApp")
+    }
+
+    override val transitionToRun: TransitionRunner
+        get() {
+            val instr = InstrumentationRegistry.getInstrumentation()
+            val bottomApp = ImeAppHelper(instr)
+            return CommonTransitions.resizeSplitScreen(instr, testApp, bottomApp,
+                    uiDevice, Surface.ROTATION_0,
+                    Rational(1, 3), Rational(2, 3))
+                    .includeJankyRuns().build()
+        }
+
+    @Test
+    fun checkVisibility_topAppLayerIsAlwaysVisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .showsLayer(sSimpleActivity)
+                    .forAllEntries()
+        }
+    }
+
+    @Test
+    fun checkVisibility_bottomAppLayerIsAlwaysVisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .showsLayer(sImeActivity)
+                    .forAllEntries()
+        }
+    }
+
+    @Test
+    fun checkVisibility_dividerLayerIsAlwaysVisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .showsLayer(DOCKED_STACK_DIVIDER)
+                    .forAllEntries()
+        }
+    }
+
+    @Test
+    @Ignore("Waiting feedback")
+    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()
+        }
+    }
+
+    @Test
+    @Ignore("Waiting feedback")
+    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()
+        }
+    }
+
+    @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()
+        }
+    }
+
+    @Test
+    @FlakyTest(bugId = 156223549)
+    @Ignore("Waiting bug feedback")
+    fun checkVisibility_topAppWindowIsAlwaysVisible() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .showsAppWindow(sSimpleActivity)
+                    .forAllEntries()
+        }
+    }
+
+    @Test
+    @FlakyTest(bugId = 156223549)
+    @Ignore("Waiting bug feedback")
+    fun checkVisibility_bottomAppWindowIsAlwaysVisible() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .showsAppWindow(sImeActivity)
+                    .forAllEntries()
+        }
+    }
+
+    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)
+            }
+        }
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/RotationTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/RotationTestBase.kt
new file mode 100644
index 0000000..873d607
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/RotationTestBase.kt
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker
+
+import android.view.Surface
+import androidx.test.filters.FlakyTest
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runners.Parameterized
+
+abstract class RotationTestBase(
+    beginRotationName: String,
+    endRotationName: String,
+    protected val beginRotation: Int,
+    protected val endRotation: Int
+) : FlickerTestBase() {
+    @FlakyTest(bugId = 140855415)
+    @Ignore("Waiting bug feedback")
+    @Test
+    fun checkVisibility_navBarWindowIsAlwaysVisible() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries()
+        }
+    }
+
+    @FlakyTest(bugId = 140855415)
+    @Ignore("Waiting bug feedback")
+    @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)
+    @Ignore("Waiting bug feedback")
+    @Test
+    fun checkVisibility_navBarLayerIsAlwaysVisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .showsLayer(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries()
+        }
+    }
+
+    @FlakyTest(bugId = 140855415)
+    @Ignore("Waiting bug feedback")
+    @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>> {
+            val supportedRotations = intArrayOf(Surface.ROTATION_0, Surface.ROTATION_90)
+            val params: MutableCollection<Array<Any>> = mutableListOf()
+            for (begin in supportedRotations) {
+                for (end in supportedRotations) {
+                    if (begin != end) {
+                        params.add(arrayOf(
+                                Surface.rotationToString(begin),
+                                Surface.rotationToString(end),
+                                begin,
+                                end
+                        ))
+                    }
+                }
+            }
+            return params
+        }
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/SeamlessAppRotationTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/SeamlessAppRotationTest.java
deleted file mode 100644
index 3cff868..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/SeamlessAppRotationTest.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2018 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 static android.view.Surface.rotationToString;
-
-import static com.android.server.wm.flicker.CommonTransitions.changeAppRotation;
-import static com.android.server.wm.flicker.WindowUtils.getAppPosition;
-import static com.android.server.wm.flicker.WindowUtils.getDisplayBounds;
-import static com.android.server.wm.flicker.WindowUtils.getNavigationBarPosition;
-import static com.android.server.wm.flicker.testapp.ActivityOptions.EXTRA_STARVE_UI_THREAD;
-import static com.android.server.wm.flicker.testapp.ActivityOptions.SEAMLESS_ACTIVITY_COMPONENT_NAME;
-
-import android.content.Intent;
-import android.graphics.Rect;
-import android.view.Surface;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.FlakyTest;
-import androidx.test.filters.LargeTest;
-
-import org.junit.FixMethodOrder;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.MethodSorters;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-/**
- * Cycle through supported app rotations using seamless rotations.
- * To run this test: {@code atest FlickerTests:SeamlessAppRotationTest}
- */
-@LargeTest
-@RunWith(Parameterized.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@FlakyTest(bugId = 147659548)
-@Ignore("Waiting bug feedback")
-public class SeamlessAppRotationTest extends FlickerTestBase {
-    private int mBeginRotation;
-    private int mEndRotation;
-    private Intent mIntent;
-
-    public SeamlessAppRotationTest(String testId, Intent intent, int beginRotation,
-            int endRotation) {
-        this.mIntent = intent;
-        this.mBeginRotation = beginRotation;
-        this.mEndRotation = endRotation;
-    }
-
-    @Parameters(name = "{0}")
-    public static Collection<Object[]> getParams() {
-        int[] supportedRotations =
-                {Surface.ROTATION_0, Surface.ROTATION_90};
-        Collection<Object[]> params = new ArrayList<>();
-
-        ArrayList<Intent> testIntents = new ArrayList<>();
-
-        // launch test activity that supports seamless rotation
-        Intent intent = new Intent(Intent.ACTION_MAIN);
-        intent.setComponent(SEAMLESS_ACTIVITY_COMPONENT_NAME);
-        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 = new Intent(intent);
-        intent.putExtra(EXTRA_STARVE_UI_THREAD, true);
-        testIntents.add(intent);
-
-        for (Intent testIntent : testIntents) {
-            for (int begin : supportedRotations) {
-                for (int end : supportedRotations) {
-                    if (begin != end) {
-                        String testId = rotationToString(begin) + "_" + rotationToString(end);
-                        if (testIntent.getExtras() != null &&
-                                testIntent.getExtras().getBoolean(EXTRA_STARVE_UI_THREAD)) {
-                            testId += "_" + "BUSY_UI_THREAD";
-                        }
-                        params.add(new Object[]{testId, testIntent, begin, end});
-                    }
-                }
-            }
-        }
-        return params;
-    }
-
-    @Override
-    TransitionRunner getTransitionToRun() {
-        String intentId = "";
-        if (mIntent.getExtras() != null &&
-                mIntent.getExtras().getBoolean(EXTRA_STARVE_UI_THREAD)) {
-            intentId = "BUSY_UI_THREAD";
-        }
-
-        return changeAppRotation(mIntent, intentId, InstrumentationRegistry.getContext(),
-                mUiDevice, mBeginRotation, mEndRotation).build();
-    }
-
-    @Test
-    public void checkVisibility_navBarWindowIsAlwaysVisible() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries());
-    }
-
-    @Test
-    public void checkPosition_navBarLayerRotatesAndScales() {
-        Rect startingPos = getNavigationBarPosition(mBeginRotation);
-        Rect endingPos = getNavigationBarPosition(mEndRotation);
-        if (startingPos.equals(endingPos)) {
-            checkResults(result -> LayersTraceSubject.assertThat(result)
-                    .hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, startingPos)
-                    .forAllEntries());
-        } else {
-            checkResults(result -> LayersTraceSubject.assertThat(result)
-                    .hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, startingPos)
-                    .inTheBeginning());
-            checkResults(result -> LayersTraceSubject.assertThat(result)
-                    .hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, endingPos)
-                    .atTheEnd());
-        }
-    }
-
-    @Test
-    public void checkPosition_appLayerRotates() {
-        Rect startingPos = getAppPosition(mBeginRotation);
-        Rect endingPos = getAppPosition(mEndRotation);
-        if (startingPos.equals(endingPos)) {
-            checkResults(result -> LayersTraceSubject.assertThat(result)
-                    .hasVisibleRegion(mIntent.getComponent().getPackageName(), startingPos)
-                    .forAllEntries());
-        } else {
-            checkResults(result -> LayersTraceSubject.assertThat(result)
-                    .hasVisibleRegion(mIntent.getComponent().getPackageName(), startingPos)
-                    .then()
-                    .hasVisibleRegion(mIntent.getComponent().getPackageName(), endingPos)
-                    .forAllEntries());
-        }
-    }
-
-    @Test
-    public void checkCoveredRegion_noUncoveredRegions() {
-        Rect startingBounds = getDisplayBounds(mBeginRotation);
-        Rect endingBounds = getDisplayBounds(mEndRotation);
-        if (startingBounds.equals(endingBounds)) {
-            checkResults(result ->
-                    LayersTraceSubject.assertThat(result)
-                            .coversRegion(startingBounds)
-                            .forAllEntries());
-        } else {
-            checkResults(result ->
-                    LayersTraceSubject.assertThat(result)
-                            .coversRegion(startingBounds)
-                            .then()
-                            .coversRegion(endingBounds)
-                            .forAllEntries());
-        }
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/SeamlessAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/SeamlessAppRotationTest.kt
new file mode 100644
index 0000000..a003cce
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/SeamlessAppRotationTest.kt
@@ -0,0 +1,141 @@
+/*
+ * 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.content.Intent
+import android.view.Surface
+import androidx.test.InstrumentationRegistry
+import androidx.test.filters.FlakyTest
+import androidx.test.filters.LargeTest
+import com.android.server.wm.flicker.testapp.ActivityOptions
+import org.junit.FixMethodOrder
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Cycle through supported app rotations using seamless rotations.
+ * To run this test: `atest FlickerTests:SeamlessAppRotationTest`
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@FlakyTest(bugId = 147659548)
+@Ignore("Waiting bug feedback")
+class SeamlessAppRotationTest(
+    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(), uiDevice,
+                    beginRotation, endRotation).build()
+        }
+
+    @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()
+            }
+        } else {
+            checkResults {
+                LayersTraceSubject.assertThat(it)
+                        .hasVisibleRegion(intent.component?.packageName ?: "", startingPos)
+                        .then()
+                        .hasVisibleRegion(intent.component?.packageName ?: "", endingPos)
+                        .forAllEntries()
+            }
+        }
+    }
+
+    @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()
+            }
+        }
+    }
+
+    companion object {
+        // launch test activity that supports seamless rotation
+
+        // launch test activity that supports seamless rotation with a busy UI thread to miss frames
+        // when the app is asked to redraw
+        @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()
+            val testIntents = ArrayList<Intent>()
+
+            // launch test activity that supports seamless rotation
+            var intent = Intent(Intent.ACTION_MAIN)
+            intent.component = ActivityOptions.SEAMLESS_ACTIVITY_COMPONENT_NAME
+            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)
+            testIntents.add(intent)
+            for (testIntent in testIntents) {
+                for (begin in supportedRotations) {
+                    for (end in supportedRotations) {
+                        if (begin != end) {
+                            var testId: String = Surface.rotationToString(begin) +
+                                    "_" + Surface.rotationToString(end)
+                            if (testIntent.extras?.getBoolean(
+                                            ActivityOptions.EXTRA_STARVE_UI_THREAD) == true) {
+                                testId += "_" + "BUSY_UI_THREAD"
+                            }
+                            params.add(arrayOf(testId, testIntent, begin, end))
+                        }
+                    }
+                }
+            }
+            return params
+        }
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/SplitScreenToLauncherTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/SplitScreenToLauncherTest.java
deleted file mode 100644
index 9e9c829..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/SplitScreenToLauncherTest.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2018 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 static com.android.server.wm.flicker.CommonTransitions.splitScreenToLauncher;
-import static com.android.server.wm.flicker.WindowUtils.getDisplayBounds;
-import static com.android.server.wm.flicker.helpers.AutomationUtils.exitSplitScreen;
-import static com.android.server.wm.flicker.helpers.AutomationUtils.isInSplitScreen;
-
-import android.view.Surface;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.LargeTest;
-import androidx.test.runner.AndroidJUnit4;
-import androidx.test.uiautomator.UiDevice;
-
-import org.junit.AfterClass;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.MethodSorters;
-
-/**
- * Test open app to split screen.
- * To run this test: {@code atest FlickerTests:SplitScreenToLauncherTest}
- */
-@LargeTest
-@RunWith(AndroidJUnit4.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class SplitScreenToLauncherTest extends FlickerTestBase {
-
-    public SplitScreenToLauncherTest() {
-        this.mTestApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
-                "com.android.server.wm.flicker.testapp", "SimpleApp");
-    }
-
-    @Override
-    TransitionRunner getTransitionToRun() {
-        return splitScreenToLauncher(mTestApp, mUiDevice, Surface.ROTATION_0)
-                .includeJankyRuns().build();
-    }
-
-    @Test
-    public void checkCoveredRegion_noUncoveredRegions() {
-        checkResults(result ->
-                LayersTraceSubject.assertThat(result)
-                        .coversRegion(getDisplayBounds()).forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_dividerLayerBecomesInVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(DOCKED_STACK_DIVIDER)
-                .then()
-                .hidesLayer(DOCKED_STACK_DIVIDER)
-                .forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_appLayerBecomesInVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(mTestApp.getPackage())
-                .then()
-                .hidesLayer(mTestApp.getPackage())
-                .forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_navBarWindowIsAlwaysVisible() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_statusBarWindowIsAlwaysVisible() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE).forAllEntries());
-    }
-
-    @AfterClass
-    public static void teardown() {
-        UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
-
-        if (isInSplitScreen(device)) {
-            exitSplitScreen(device);
-        }
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/SplitScreenToLauncherTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/SplitScreenToLauncherTest.kt
new file mode 100644
index 0000000..907cc40
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/SplitScreenToLauncherTest.kt
@@ -0,0 +1,104 @@
+/*
+ * 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.view.Surface
+import androidx.test.InstrumentationRegistry
+import androidx.test.filters.LargeTest
+import androidx.test.runner.AndroidJUnit4
+import androidx.test.uiautomator.UiDevice
+import com.android.server.wm.flicker.helpers.AutomationUtils
+import org.junit.AfterClass
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+
+/**
+ * Test open app to split screen.
+ * To run this test: `atest FlickerTests:SplitScreenToLauncherTest`
+ */
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class SplitScreenToLauncherTest : FlickerTestBase() {
+    init {
+        testApp = StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
+                "com.android.server.wm.flicker.testapp", "SimpleApp")
+    }
+
+    override val transitionToRun: TransitionRunner
+        get() = CommonTransitions.splitScreenToLauncher(testApp, uiDevice, Surface.ROTATION_0)
+                .includeJankyRuns().build()
+
+    @Test
+    fun checkCoveredRegion_noUncoveredRegions() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .coversRegion(WindowUtils.getDisplayBounds()).forAllEntries()
+        }
+    }
+
+    @Test
+    fun checkVisibility_dividerLayerBecomesInVisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .showsLayer(DOCKED_STACK_DIVIDER)
+                    .then()
+                    .hidesLayer(DOCKED_STACK_DIVIDER)
+                    .forAllEntries()
+        }
+    }
+
+    @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)
+            }
+        }
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerAppHelper.java b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerAppHelper.java
deleted file mode 100644
index 42977f5..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerAppHelper.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2019 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.helpers;
-
-import android.app.Instrumentation;
-
-import com.android.server.wm.flicker.StandardAppHelper;
-
-public abstract class FlickerAppHelper extends StandardAppHelper {
-
-    static int sFindTimeout = 10000;
-    static String sFlickerPackage = "com.android.server.wm.flicker.testapp";
-
-    public FlickerAppHelper(Instrumentation instr, String launcherName) {
-        super(instr, sFlickerPackage, launcherName);
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerAppHelper.kt
new file mode 100644
index 0000000..e579533
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerAppHelper.kt
@@ -0,0 +1,30 @@
+/*
+ * 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.helpers
+
+import android.app.Instrumentation
+import com.android.server.wm.flicker.StandardAppHelper
+
+abstract class FlickerAppHelper(
+    instr: Instrumentation,
+    launcherName: String
+) : StandardAppHelper(instr, sFlickerPackage, launcherName) {
+    companion object {
+        var sFindTimeout = 10000
+        var sFlickerPackage = "com.android.server.wm.flicker.testapp"
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.java b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.kt
similarity index 61%
rename from tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.java
rename to tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.kt
index 1b2c484..d587f1e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * 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.
@@ -14,19 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.server.wm.flicker.helpers;
+package com.android.server.wm.flicker.helpers
 
-import android.app.Instrumentation;
+import android.app.Instrumentation
+import androidx.test.uiautomator.UiDevice
 
-import androidx.test.uiautomator.UiDevice;
-
-public class ImeAppAutoFocusHelper extends ImeAppHelper {
-
-    public ImeAppAutoFocusHelper(Instrumentation instr) {
-        super(instr, "ImeAppAutoFocus");
-    }
-
-    public void openIME(UiDevice device) {
+class ImeAppAutoFocusHelper(instr: Instrumentation) : ImeAppHelper(instr, "ImeAppAutoFocus") {
+    override fun openIME(device: UiDevice) {
         // do nothing (the app is focused automatically)
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.java b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.java
deleted file mode 100644
index 095722d..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2019 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.helpers;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-
-import android.app.Instrumentation;
-
-import androidx.test.uiautomator.By;
-import androidx.test.uiautomator.UiDevice;
-import androidx.test.uiautomator.UiObject2;
-import androidx.test.uiautomator.Until;
-
-public class ImeAppHelper extends FlickerAppHelper {
-
-    ImeAppHelper(Instrumentation instr, String launcherName) {
-        super(instr, launcherName);
-    }
-
-    public ImeAppHelper(Instrumentation instr) {
-        this(instr, "ImeApp");
-    }
-
-    public void openIME(UiDevice device) {
-        UiObject2 editText = device.wait(
-                Until.findObject(By.res(getPackage(), "plain_text_input")),
-                AutomationUtils.FIND_TIMEOUT);
-        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)) {
-            fail("IME did not appear");
-        }
-    }
-}
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
new file mode 100644
index 0000000..979cbea
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt
@@ -0,0 +1,40 @@
+/*
+ * 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.helpers
+
+import android.app.Instrumentation
+import androidx.test.uiautomator.By
+import androidx.test.uiautomator.UiDevice
+import androidx.test.uiautomator.Until
+import org.junit.Assert
+
+open class ImeAppHelper(
+    instr: Instrumentation,
+    launcherName: String = "ImeApp"
+) : FlickerAppHelper(instr, launcherName) {
+    open fun openIME(device: UiDevice) {
+        val editText = device.wait(
+                Until.findObject(By.res(getPackage(), "plain_text_input")),
+                AutomationUtils.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)) {
+            Assert.fail("IME did not appear")
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.java b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.java
deleted file mode 100644
index f2b7a7e3..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2019 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.helpers;
-
-import static com.android.server.wm.flicker.helpers.AutomationUtils.hasPipWindow;
-
-import static org.junit.Assert.assertNotNull;
-
-import android.app.Instrumentation;
-
-import androidx.test.uiautomator.By;
-import androidx.test.uiautomator.UiDevice;
-import androidx.test.uiautomator.UiObject2;
-
-public class PipAppHelper extends FlickerAppHelper {
-
-    public PipAppHelper(Instrumentation instr) {
-        super(instr, "PipApp");
-    }
-
-    public void clickEnterPipButton(UiDevice device) {
-        UiObject2 enterPipButton = device.findObject(By.res(getPackage(), "enter_pip"));
-        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();
-        hasPipWindow(device);
-    }
-
-    public void closePipWindow(UiDevice device) {
-        AutomationUtils.closePipWindow(device);
-    }
-
-}
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
new file mode 100644
index 0000000..daee810
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.helpers
+
+import android.app.Instrumentation
+import androidx.test.uiautomator.By
+import androidx.test.uiautomator.UiDevice
+import org.junit.Assert
+
+class PipAppHelper(instr: Instrumentation) : FlickerAppHelper(instr, "PipApp") {
+    fun clickEnterPipButton(device: UiDevice) {
+        val enterPipButton = device.findObject(By.res(getPackage(), "enter_pip"))
+        Assert.assertNotNull("Pip button not found, this usually happens when the device " +
+                "was left in an unknown state (e.g. in split screen)", enterPipButton)
+        enterPipButton.click()
+        AutomationUtils.hasPipWindow(device)
+    }
+
+    fun closePipWindow(device: UiDevice) {
+        AutomationUtils.closePipWindow(device)
+    }
+}