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)
+    }
+}
