Prototype of withOrientation.

Test: prototype

Change-Id: Iff2d91248ebeb97d17c0054c979bff53b63ef1c1
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/Orientation.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/Orientation.kt
new file mode 100644
index 0000000..c9461c5
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/Orientation.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2021 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 androidx.appcompat
+
+import androidx.test.uiautomator.UiDevice
+
+public enum class Orientation { LEFT, RIGHT }
+
+public fun UiDevice.withOrientation(orientation: Orientation, doThis: () -> Unit) {
+    when (orientation) {
+        Orientation.LEFT -> setOrientationLeft()
+        Orientation.RIGHT -> setOrientationRight()
+    }
+
+    try {
+        doThis()
+    } finally {
+        setOrientationNatural()
+    }
+}
\ No newline at end of file
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeRotateDoesNotRecreateActivityTestCase.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeRotateDoesNotRecreateActivityTestCase.kt
index dbeb17c..ac1157a 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeRotateDoesNotRecreateActivityTestCase.kt
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeRotateDoesNotRecreateActivityTestCase.kt
@@ -18,12 +18,14 @@
 
 import android.content.res.Configuration
 import android.os.Build
+import androidx.appcompat.Orientation
 import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
 import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES
 import androidx.appcompat.testutils.NightModeActivityTestRule
 import androidx.appcompat.testutils.NightModeUtils.NightSetMode
 import androidx.appcompat.testutils.NightModeUtils.assertConfigurationNightModeEquals
 import androidx.appcompat.testutils.NightModeUtils.setNightModeAndWaitForRecreate
+import androidx.appcompat.withOrientation
 import androidx.lifecycle.Lifecycle
 import androidx.test.filters.LargeTest
 import androidx.test.filters.SdkSuppress
@@ -94,19 +96,20 @@
         // Now rotate the device. This should NOT result in a lifecycle event, just a call to
         // onConfigurationChanged.
         nightModeActivity.resetOnConfigurationChange()
-        device.setOrientationLeft()
-        instrumentation.waitForIdleSync()
-        nightModeActivity.expectOnConfigurationChange(5000)
+        device.withOrientation(Orientation.LEFT) {
+            instrumentation.waitForIdleSync()
+            nightModeActivity.expectOnConfigurationChange(5000)
 
-        // Assert that we got the same activity and thus it was not recreated.
-        val rotatedNightModeActivity = activityRule.activity
-        val rotatedConfig = rotatedNightModeActivity.resources.configuration
-        assertSame(nightModeActivity, rotatedNightModeActivity)
-        assertConfigurationNightModeEquals(Configuration.UI_MODE_NIGHT_YES, rotatedConfig)
+            // Assert that we got the same activity and thus it was not recreated.
+            val rotatedNightModeActivity = activityRule.activity
+            val rotatedConfig = rotatedNightModeActivity.resources.configuration
+            assertSame(nightModeActivity, rotatedNightModeActivity)
+            assertConfigurationNightModeEquals(Configuration.UI_MODE_NIGHT_YES, rotatedConfig)
 
-        // On API level 26 and below, the configuration object is going to be identical
-        // across configuration changes, so we need to compare against the cached value.
-        assertNotSame(orientation, rotatedConfig.orientation)
+            // On API level 26 and below, the configuration object is going to be identical
+            // across configuration changes, so we need to compare against the cached value.
+            assertNotSame(orientation, rotatedConfig.orientation)
+        }
     }
 
     public companion object {
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeRotateRecreatesActivityWithConfigTestCase.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeRotateRecreatesActivityWithConfigTestCase.kt
index ed9e6f0..c562d0f 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeRotateRecreatesActivityWithConfigTestCase.kt
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeRotateRecreatesActivityWithConfigTestCase.kt
@@ -20,12 +20,14 @@
 import android.app.Instrumentation
 import android.content.res.Configuration
 import android.os.Build
+import androidx.appcompat.Orientation
 import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
 import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES
 import androidx.appcompat.testutils.NightModeActivityTestRule
 import androidx.appcompat.testutils.NightModeUtils.NightSetMode
 import androidx.appcompat.testutils.NightModeUtils.assertConfigurationNightModeEquals
 import androidx.appcompat.testutils.NightModeUtils.setNightModeAndWaitForRecreate
+import androidx.appcompat.withOrientation
 import androidx.lifecycle.Lifecycle
 import androidx.test.filters.LargeTest
 import androidx.test.filters.SdkSuppress
@@ -97,40 +99,41 @@
 
         // Now rotate the device. This should result in an onDestroy lifecycle event.
         nightModeActivity.resetOnDestroy()
-        rotateDeviceAndWaitForRecreate(nightModeActivity)
-        nightModeActivity.expectOnDestroy(5000)
+        rotateDeviceAndWaitForRecreate(nightModeActivity) {
+            nightModeActivity.expectOnDestroy(5000)
 
-        // Assert that we got a different activity and thus it was recreated.
-        val rotatedNightModeActivity = activityRule.activity
-        val rotatedConfig = rotatedNightModeActivity.resources.configuration
-        assertNotSame(nightModeActivity, rotatedNightModeActivity)
-        assertConfigurationNightModeEquals(Configuration.UI_MODE_NIGHT_YES, rotatedConfig)
+            // Assert that we got a different activity and thus it was recreated.
+            val rotatedNightModeActivity = activityRule.activity
+            val rotatedConfig = rotatedNightModeActivity.resources.configuration
+            assertNotSame(nightModeActivity, rotatedNightModeActivity)
+            assertConfigurationNightModeEquals(Configuration.UI_MODE_NIGHT_YES, rotatedConfig)
 
-        // On API level 26 and below, the configuration object is going to be identical
-        // across configuration changes, so we need to compare against the cached value.
-        assertNotSame(orientation, rotatedConfig.orientation)
+            // On API level 26 and below, the configuration object is going to be identical
+            // across configuration changes, so we need to compare against the cached value.
+            assertNotSame(orientation, rotatedConfig.orientation)
+        }
     }
 
-    private fun rotateDeviceAndWaitForRecreate(activity: Activity) {
+    private fun rotateDeviceAndWaitForRecreate(activity: Activity, doThis: () -> Unit) {
         val monitor = Instrumentation.ActivityMonitor(activity::class.java.name, null, false)
         instrumentation.addMonitor(monitor)
 
-        // Rotate
-        device.setOrientationLeft()
+        device.withOrientation(Orientation.LEFT) {
+            // Wait for the activity to be recreated after rotation
+            var count = 0
+            var lastActivity: Activity? = activity
+            while ((lastActivity == null || activity == lastActivity) && count < 5) {
+                // If this times out, it will return null.
+                lastActivity = monitor.waitForActivityWithTimeout(1000L)
+                count++
+            }
+            instrumentation.waitForIdleSync()
 
-        // Wait for the activity to be recreated after rotation
-        var count = 0
-        var lastActivity: Activity? = activity
-        while ((lastActivity == null || activity == lastActivity) && count < 5) {
-            // If this times out, it will return null.
-            lastActivity = monitor.waitForActivityWithTimeout(1000L)
-            count++
+            // Ensure that we didn't time out
+            assertNotNull("Activity was not recreated within 5000ms", lastActivity)
+            assertNotEquals("Activity was not recreated within 5000ms", activity, lastActivity)
+            doThis()
         }
-        instrumentation.waitForIdleSync()
-
-        // Ensure that we didn't time out
-        assertNotNull("Activity was not recreated within 5000ms", lastActivity)
-        assertNotEquals("Activity was not recreated within 5000ms", activity, lastActivity)
     }
 
     public companion object {