Foldable auto-rotation: Add support for rear display device state

Bug: 279014881
Test: atest SettingsLibTests:com.android.settingslib.devicestate.PosturesHelperTest
Change-Id: I37a43740d5940f1bae208e36f289f9d3e3dc85f5
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 3487b01..79e7574 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -11496,6 +11496,8 @@
         public static final int DEVICE_STATE_ROTATION_KEY_HALF_FOLDED = 1;
         /** @hide */
         public static final int DEVICE_STATE_ROTATION_KEY_UNFOLDED = 2;
+        /** @hide */
+        public static final int DEVICE_STATE_ROTATION_KEY_REAR_DISPLAY = 3;
 
         /**
          * The different postures that can be used as keys with
@@ -11507,6 +11509,7 @@
                 DEVICE_STATE_ROTATION_KEY_FOLDED,
                 DEVICE_STATE_ROTATION_KEY_HALF_FOLDED,
                 DEVICE_STATE_ROTATION_KEY_UNFOLDED,
+                DEVICE_STATE_ROTATION_KEY_REAR_DISPLAY,
         })
         @Retention(RetentionPolicy.SOURCE)
         public @interface DeviceStateRotationLockKey {
diff --git a/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/PosturesHelper.kt b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/PosturesHelper.kt
index 9c70be9..6a13eb8 100644
--- a/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/PosturesHelper.kt
+++ b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/PosturesHelper.kt
@@ -19,6 +19,7 @@
 import android.content.Context
 import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_KEY_FOLDED
 import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_KEY_HALF_FOLDED
+import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_KEY_REAR_DISPLAY
 import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_KEY_UNFOLDED
 import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_KEY_UNKNOWN
 import android.provider.Settings.Secure.DeviceStateRotationLockKey
@@ -33,6 +34,8 @@
         context.resources.getIntArray(R.array.config_halfFoldedDeviceStates)
     private val unfoldedDeviceStates =
         context.resources.getIntArray(R.array.config_openDeviceStates)
+    private val rearDisplayDeviceStates =
+        context.resources.getIntArray(R.array.config_rearDisplayDeviceStates)
 
     @DeviceStateRotationLockKey
     fun deviceStateToPosture(deviceState: Int): Int {
@@ -40,6 +43,7 @@
             in foldedDeviceStates -> DEVICE_STATE_ROTATION_KEY_FOLDED
             in halfFoldedDeviceStates -> DEVICE_STATE_ROTATION_KEY_HALF_FOLDED
             in unfoldedDeviceStates -> DEVICE_STATE_ROTATION_KEY_UNFOLDED
+            in rearDisplayDeviceStates -> DEVICE_STATE_ROTATION_KEY_REAR_DISPLAY
             else -> DEVICE_STATE_ROTATION_KEY_UNKNOWN
         }
     }
@@ -49,6 +53,7 @@
             DEVICE_STATE_ROTATION_KEY_FOLDED -> foldedDeviceStates.firstOrNull()
             DEVICE_STATE_ROTATION_KEY_HALF_FOLDED -> halfFoldedDeviceStates.firstOrNull()
             DEVICE_STATE_ROTATION_KEY_UNFOLDED -> unfoldedDeviceStates.firstOrNull()
+            DEVICE_STATE_ROTATION_KEY_REAR_DISPLAY -> rearDisplayDeviceStates.firstOrNull()
             else -> null
         }
     }
diff --git a/packages/SettingsLib/tests/integ/Android.bp b/packages/SettingsLib/tests/integ/Android.bp
index d463170..ff3eeec 100644
--- a/packages/SettingsLib/tests/integ/Android.bp
+++ b/packages/SettingsLib/tests/integ/Android.bp
@@ -30,7 +30,10 @@
 
     certificate: "platform",
 
-    srcs: ["src/**/*.java"],
+    srcs: [
+        "src/**/*.java",
+        "src/**/*.kt",
+    ],
 
     libs: [
         "android.test.runner",
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/PosturesHelperTest.kt b/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/PosturesHelperTest.kt
new file mode 100644
index 0000000..d91c2fa
--- /dev/null
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/PosturesHelperTest.kt
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2023 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.settingslib.devicestate
+
+import android.content.Context
+import android.content.res.Resources
+import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_KEY_FOLDED
+import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_KEY_HALF_FOLDED
+import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_KEY_REAR_DISPLAY
+import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_KEY_UNFOLDED
+import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_KEY_UNKNOWN
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.internal.R
+import com.google.common.truth.Expect
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.`when` as whenever
+import org.mockito.MockitoAnnotations
+
+private const val DEVICE_STATE_UNKNOWN = 0
+private const val DEVICE_STATE_CLOSED = 1
+private const val DEVICE_STATE_HALF_FOLDED = 2
+private const val DEVICE_STATE_OPEN = 3
+private const val DEVICE_STATE_REAR_DISPLAY = 4
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class PosturesHelperTest {
+
+    @get:Rule val expect: Expect = Expect.create()
+
+    @Mock private lateinit var context: Context
+
+    @Mock private lateinit var resources: Resources
+
+    private lateinit var posturesHelper: PosturesHelper
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+
+        whenever(context.resources).thenReturn(resources)
+        whenever(resources.getIntArray(R.array.config_foldedDeviceStates))
+            .thenReturn(intArrayOf(DEVICE_STATE_CLOSED))
+        whenever(resources.getIntArray(R.array.config_halfFoldedDeviceStates))
+            .thenReturn(intArrayOf(DEVICE_STATE_HALF_FOLDED))
+        whenever(resources.getIntArray(R.array.config_openDeviceStates))
+            .thenReturn(intArrayOf(DEVICE_STATE_OPEN))
+        whenever(resources.getIntArray(R.array.config_rearDisplayDeviceStates))
+            .thenReturn(intArrayOf(DEVICE_STATE_REAR_DISPLAY))
+
+        posturesHelper = PosturesHelper(context)
+    }
+
+    @Test
+    fun deviceStateToPosture_mapsCorrectly() {
+        expect
+            .that(posturesHelper.deviceStateToPosture(DEVICE_STATE_CLOSED))
+            .isEqualTo(DEVICE_STATE_ROTATION_KEY_FOLDED)
+        expect
+            .that(posturesHelper.deviceStateToPosture(DEVICE_STATE_HALF_FOLDED))
+            .isEqualTo(DEVICE_STATE_ROTATION_KEY_HALF_FOLDED)
+        expect
+            .that(posturesHelper.deviceStateToPosture(DEVICE_STATE_OPEN))
+            .isEqualTo(DEVICE_STATE_ROTATION_KEY_UNFOLDED)
+        expect
+            .that(posturesHelper.deviceStateToPosture(DEVICE_STATE_REAR_DISPLAY))
+            .isEqualTo(DEVICE_STATE_ROTATION_KEY_REAR_DISPLAY)
+        expect
+            .that(posturesHelper.deviceStateToPosture(DEVICE_STATE_UNKNOWN))
+            .isEqualTo(DEVICE_STATE_ROTATION_KEY_UNKNOWN)
+    }
+
+    @Test
+    fun postureToDeviceState_mapsCorrectly() {
+        expect
+            .that(posturesHelper.postureToDeviceState(DEVICE_STATE_ROTATION_KEY_FOLDED))
+            .isEqualTo(DEVICE_STATE_CLOSED)
+        expect
+            .that(posturesHelper.postureToDeviceState(DEVICE_STATE_ROTATION_KEY_HALF_FOLDED))
+            .isEqualTo(DEVICE_STATE_HALF_FOLDED)
+        expect
+            .that(posturesHelper.postureToDeviceState(DEVICE_STATE_ROTATION_KEY_UNFOLDED))
+            .isEqualTo(DEVICE_STATE_OPEN)
+        expect
+            .that(posturesHelper.postureToDeviceState(DEVICE_STATE_ROTATION_KEY_REAR_DISPLAY))
+            .isEqualTo(DEVICE_STATE_REAR_DISPLAY)
+        expect.that(posturesHelper.postureToDeviceState(DEVICE_STATE_ROTATION_KEY_UNKNOWN)).isNull()
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingControllerLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingControllerLogger.kt
index aa502bc..f61f3b7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingControllerLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingControllerLogger.kt
@@ -34,6 +34,8 @@
     private val halfFoldedStates =
         context.resources.getIntArray(R.array.config_halfFoldedDeviceStates)
     private val unfoldedStates = context.resources.getIntArray(R.array.config_openDeviceStates)
+    private val rearDisplayStates =
+        context.resources.getIntArray(R.array.config_rearDisplayDeviceStates)
 
     fun logListeningChange(listening: Boolean) {
         logBuffer.log(TAG, VERBOSE, { bool1 = listening }, { "setListening: $bool1" })
@@ -122,6 +124,7 @@
             in foldedStates -> "Folded"
             in unfoldedStates -> "Unfolded"
             in halfFoldedStates -> "Half-Folded"
+            in rearDisplayStates -> "Rear display"
             -1 -> "Uninitialized"
             else -> "Unknown"
         }