Device state rotation: fallback to defaults for invalid ignored state

Detect when we have a persisted invalid ignored state, and fallback to
defaults.
This can happen when the ids of device states change.

This will cause persisted settings to be wiped, and defaults to be
used.

+ Add more logging for easier debugging

Bug: 269822414
Bug: 261968395
Test: Unit tests
Test: Dumpsys
Change-Id: I6d1845c758cac80ba5af14a6f6b2de40120bec0d
diff --git a/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateRotationLockSettingsManager.java b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateRotationLockSettingsManager.java
index 4ed7e19..10b004e 100644
--- a/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateRotationLockSettingsManager.java
+++ b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateRotationLockSettingsManager.java
@@ -29,6 +29,7 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.text.TextUtils;
+import android.util.IndentingPrintWriter;
 import android.util.Log;
 import android.util.SparseIntArray;
 
@@ -36,6 +37,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Objects;
@@ -57,6 +59,7 @@
     private final SecureSettings mSecureSettings;
     private String[] mDeviceStateRotationLockDefaults;
     private SparseIntArray mDeviceStateRotationLockSettings;
+    private SparseIntArray mDeviceStateDefaultRotationLockSettings;
     private SparseIntArray mDeviceStateRotationLockFallbackSettings;
     private String mLastSettingValue;
     private List<SettableDeviceState> mSettableDeviceStates;
@@ -93,9 +96,7 @@
     /** Returns true if device-state based rotation lock settings are enabled. */
     public static boolean isDeviceStateRotationLockEnabled(Context context) {
         return context.getResources()
-                        .getStringArray(R.array.config_perDeviceStateRotationLockDefaults)
-                        .length
-                > 0;
+                .getStringArray(R.array.config_perDeviceStateRotationLockDefaults).length > 0;
     }
 
     private void listenForSettingsChange() {
@@ -228,6 +229,15 @@
             try {
                 key = Integer.parseInt(values[i++]);
                 value = Integer.parseInt(values[i++]);
+                boolean isPersistedValueIgnored = value == DEVICE_STATE_ROTATION_LOCK_IGNORED;
+                boolean isDefaultValueIgnored = mDeviceStateDefaultRotationLockSettings.get(key)
+                        == DEVICE_STATE_ROTATION_LOCK_IGNORED;
+                if (isPersistedValueIgnored != isDefaultValueIgnored) {
+                    Log.w(TAG, "Conflict for ignored device state " + key
+                            + ". Falling back on defaults");
+                    fallbackOnDefaults();
+                    return;
+                }
                 mDeviceStateRotationLockSettings.put(key, value);
             } catch (NumberFormatException e) {
                 Log.wtf(TAG, "Error deserializing one of the saved settings", e);
@@ -276,6 +286,9 @@
     }
 
     private void persistSettingIfChanged(String newSettingValue) {
+        Log.v(TAG, "persistSettingIfChanged: "
+                + "last=" + mLastSettingValue + ", "
+                + "new=" + newSettingValue);
         if (TextUtils.equals(mLastSettingValue, newSettingValue)) {
             return;
         }
@@ -288,6 +301,8 @@
 
     private void loadDefaults() {
         mSettableDeviceStates = new ArrayList<>(mDeviceStateRotationLockDefaults.length);
+        mDeviceStateDefaultRotationLockSettings = new SparseIntArray(
+                mDeviceStateRotationLockDefaults.length);
         mDeviceStateRotationLockSettings = new SparseIntArray(
                 mDeviceStateRotationLockDefaults.length);
         mDeviceStateRotationLockFallbackSettings = new SparseIntArray(1);
@@ -311,6 +326,7 @@
                 boolean isSettable = rotationLockSetting != DEVICE_STATE_ROTATION_LOCK_IGNORED;
                 mSettableDeviceStates.add(new SettableDeviceState(deviceState, isSettable));
                 mDeviceStateRotationLockSettings.put(deviceState, rotationLockSetting);
+                mDeviceStateDefaultRotationLockSettings.put(deviceState, rotationLockSetting);
             } catch (NumberFormatException e) {
                 Log.wtf(TAG, "Error parsing settings entry. Entry was: " + entry, e);
                 return;
@@ -318,6 +334,22 @@
         }
     }
 
+    /** Dumps internal state. */
+    public void dump(IndentingPrintWriter pw) {
+        pw.println("DeviceStateRotationLockSettingsManager");
+        pw.increaseIndent();
+        pw.println("mDeviceStateRotationLockDefaults: " + Arrays.toString(
+                mDeviceStateRotationLockDefaults));
+        pw.println("mDeviceStateDefaultRotationLockSettings: "
+                + mDeviceStateDefaultRotationLockSettings);
+        pw.println("mDeviceStateRotationLockSettings: " + mDeviceStateRotationLockSettings);
+        pw.println("mDeviceStateRotationLockFallbackSettings: "
+                + mDeviceStateRotationLockFallbackSettings);
+        pw.println("mSettableDeviceStates: " + mSettableDeviceStates);
+        pw.println("mLastSettingValue: " + mLastSettingValue);
+        pw.decreaseIndent();
+    }
+
     /**
      * Called when the persisted settings have changed, requiring a reinitialization of the
      * in-memory map.
@@ -372,5 +404,13 @@
         public int hashCode() {
             return Objects.hash(mDeviceState, mIsSettable);
         }
+
+        @Override
+        public String toString() {
+            return "SettableDeviceState{"
+                    + "mDeviceState=" + mDeviceState
+                    + ", mIsSettable=" + mIsSettable
+                    + '}';
+        }
     }
 }
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateRotationLockSettingsManagerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateRotationLockSettingsManagerTest.java
index 81006dd..0fa15eb 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateRotationLockSettingsManagerTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateRotationLockSettingsManagerTest.java
@@ -33,7 +33,10 @@
 import com.android.internal.R;
 import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager.SettableDeviceState;
 
+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;
@@ -45,6 +48,8 @@
 @RunWith(AndroidJUnit4.class)
 public class DeviceStateRotationLockSettingsManagerTest {
 
+    @Rule public Expect mExpect = Expect.create();
+
     @Mock private Context mMockContext;
     @Mock private Resources mMockResources;
 
@@ -117,4 +122,40 @@
                 new SettableDeviceState(/* deviceState= */ 0, /* isSettable= */ false)
         ).inOrder();
     }
+
+    @Test
+    public void persistedInvalidIgnoredState_returnsDefaults() {
+        when(mMockResources.getStringArray(
+                R.array.config_perDeviceStateRotationLockDefaults)).thenReturn(
+                new String[]{"0:1", "1:0:2", "2:2"});
+        // Here 2 has IGNORED, and in the defaults 1 has IGNORED.
+        persistSettings("0:2:2:0:1:2");
+        DeviceStateRotationLockSettingsManager manager =
+                new DeviceStateRotationLockSettingsManager(mMockContext, mFakeSecureSettings);
+
+        mExpect.that(manager.getRotationLockSetting(0)).isEqualTo(1);
+        mExpect.that(manager.getRotationLockSetting(1)).isEqualTo(2);
+        mExpect.that(manager.getRotationLockSetting(2)).isEqualTo(2);
+    }
+
+    @Test
+    public void persistedValidValues_returnsPersistedValues() {
+        when(mMockResources.getStringArray(
+                R.array.config_perDeviceStateRotationLockDefaults)).thenReturn(
+                new String[]{"0:1", "1:0:2", "2:2"});
+        persistSettings("0:2:1:0:2:1");
+        DeviceStateRotationLockSettingsManager manager =
+                new DeviceStateRotationLockSettingsManager(mMockContext, mFakeSecureSettings);
+
+        mExpect.that(manager.getRotationLockSetting(0)).isEqualTo(2);
+        mExpect.that(manager.getRotationLockSetting(1)).isEqualTo(1);
+        mExpect.that(manager.getRotationLockSetting(2)).isEqualTo(1);
+    }
+
+    private void persistSettings(String value) {
+        mFakeSecureSettings.putStringForUser(
+                Settings.Secure.DEVICE_STATE_ROTATION_LOCK,
+                value,
+                UserHandle.USER_CURRENT);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/DeviceStateAutoRotationLog.java b/packages/SystemUI/src/com/android/systemui/log/dagger/DeviceStateAutoRotationLog.java
new file mode 100644
index 0000000..beb725e6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/DeviceStateAutoRotationLog.java
@@ -0,0 +1,30 @@
+/*
+ * 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.systemui.log.dagger;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Qualifier;
+
+@Qualifier
+@Documented
+@Retention(RUNTIME)
+public @interface DeviceStateAutoRotationLog {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
index 642c9f7..98b6d70 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
@@ -370,6 +370,16 @@
     }
 
     /**
+     * Provides a {@link LogBuffer} for Device State Auto-Rotation logs.
+     */
+    @Provides
+    @SysUISingleton
+    @DeviceStateAutoRotationLog
+    public static LogBuffer provideDeviceStateAutoRotationLogBuffer(LogBufferFactory factory) {
+        return factory.create("DeviceStateAutoRotationLog", 100);
+    }
+
+    /**
      * Provides a {@link LogBuffer} for bluetooth-related logs.
      */
     @Provides
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingController.java
index 7acdaff..01fabcc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingController.java
@@ -22,13 +22,18 @@
 import android.annotation.Nullable;
 import android.hardware.devicestate.DeviceStateManager;
 import android.os.Trace;
-import android.util.Log;
+import android.util.IndentingPrintWriter;
+
+import androidx.annotation.NonNull;
 
 import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
+import com.android.systemui.Dumpable;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.dump.DumpManager;
 import com.android.systemui.util.wrapper.RotationPolicyWrapper;
 
+import java.io.PrintWriter;
 import java.util.concurrent.Executor;
 
 import javax.inject.Inject;
@@ -39,19 +44,19 @@
  */
 @SysUISingleton
 public final class DeviceStateRotationLockSettingController
-        implements Listenable, RotationLockController.RotationLockControllerCallback {
-
-    private static final String TAG = "DSRotateLockSettingCon";
+        implements Listenable, RotationLockController.RotationLockControllerCallback, Dumpable {
 
     private final RotationPolicyWrapper mRotationPolicyWrapper;
     private final DeviceStateManager mDeviceStateManager;
     private final Executor mMainExecutor;
     private final DeviceStateRotationLockSettingsManager mDeviceStateRotationLockSettingsManager;
+    private final DeviceStateRotationLockSettingControllerLogger mLogger;
 
     // On registration for DeviceStateCallback, we will receive a callback with the current state
     // and this will be initialized.
     private int mDeviceState = -1;
-    @Nullable private DeviceStateManager.DeviceStateCallback mDeviceStateCallback;
+    @Nullable
+    private DeviceStateManager.DeviceStateCallback mDeviceStateCallback;
     private DeviceStateRotationLockSettingsManager.DeviceStateRotationLockSettingsListener
             mDeviceStateRotationLockSettingsListener;
 
@@ -60,21 +65,27 @@
             RotationPolicyWrapper rotationPolicyWrapper,
             DeviceStateManager deviceStateManager,
             @Main Executor executor,
-            DeviceStateRotationLockSettingsManager deviceStateRotationLockSettingsManager) {
+            DeviceStateRotationLockSettingsManager deviceStateRotationLockSettingsManager,
+            DeviceStateRotationLockSettingControllerLogger logger,
+            DumpManager dumpManager) {
         mRotationPolicyWrapper = rotationPolicyWrapper;
         mDeviceStateManager = deviceStateManager;
         mMainExecutor = executor;
         mDeviceStateRotationLockSettingsManager = deviceStateRotationLockSettingsManager;
+        mLogger = logger;
+        dumpManager.registerDumpable(this);
     }
 
     @Override
     public void setListening(boolean listening) {
+        mLogger.logListeningChange(listening);
         if (listening) {
             // Note that this is called once with the initial state of the device, even if there
             // is no user action.
             mDeviceStateCallback = this::updateDeviceState;
             mDeviceStateManager.registerCallback(mMainExecutor, mDeviceStateCallback);
-            mDeviceStateRotationLockSettingsListener = () -> readPersistedSetting(mDeviceState);
+            mDeviceStateRotationLockSettingsListener = () ->
+                    readPersistedSetting("deviceStateRotationLockChange", mDeviceState);
             mDeviceStateRotationLockSettingsManager.registerListener(
                     mDeviceStateRotationLockSettingsListener);
         } else {
@@ -89,35 +100,28 @@
     }
 
     @Override
-    public void onRotationLockStateChanged(boolean rotationLocked, boolean affordanceVisible) {
-        if (mDeviceState == -1) {
-            Log.wtf(TAG, "Device state was not initialized.");
+    public void onRotationLockStateChanged(boolean newRotationLocked, boolean affordanceVisible) {
+        int deviceState = mDeviceState;
+        boolean currentRotationLocked = mDeviceStateRotationLockSettingsManager
+                .isRotationLocked(deviceState);
+        mLogger.logRotationLockStateChanged(deviceState, newRotationLocked, currentRotationLocked);
+        if (deviceState == -1) {
             return;
         }
-
-        if (rotationLocked
-                == mDeviceStateRotationLockSettingsManager.isRotationLocked(mDeviceState)) {
-            Log.v(TAG, "Rotation lock same as the current setting, no need to update.");
+        if (newRotationLocked == currentRotationLocked) {
             return;
         }
-
-        saveNewRotationLockSetting(rotationLocked);
+        saveNewRotationLockSetting(newRotationLocked);
     }
 
     private void saveNewRotationLockSetting(boolean isRotationLocked) {
-        Log.v(
-                TAG,
-                "saveNewRotationLockSetting [state="
-                        + mDeviceState
-                        + "] [isRotationLocked="
-                        + isRotationLocked
-                        + "]");
-
-        mDeviceStateRotationLockSettingsManager.updateSetting(mDeviceState, isRotationLocked);
+        int deviceState = mDeviceState;
+        mLogger.logSaveNewRotationLockSetting(isRotationLocked, deviceState);
+        mDeviceStateRotationLockSettingsManager.updateSetting(deviceState, isRotationLocked);
     }
 
     private void updateDeviceState(int state) {
-        Log.v(TAG, "updateDeviceState [state=" + state + "]");
+        mLogger.logUpdateDeviceState(mDeviceState, state);
         if (Trace.isEnabled()) {
             Trace.traceBegin(
                     Trace.TRACE_TAG_APP, "updateDeviceState [state=" + state + "]");
@@ -127,22 +131,26 @@
                 return;
             }
 
-            readPersistedSetting(state);
+            readPersistedSetting("updateDeviceState", state);
         } finally {
             Trace.endSection();
         }
     }
 
-    private void readPersistedSetting(int state) {
+    private void readPersistedSetting(String caller, int state) {
         int rotationLockSetting =
                 mDeviceStateRotationLockSettingsManager.getRotationLockSetting(state);
+        boolean shouldBeLocked = rotationLockSetting == DEVICE_STATE_ROTATION_LOCK_LOCKED;
+        boolean isLocked = mRotationPolicyWrapper.isRotationLocked();
+
+        mLogger.readPersistedSetting(caller, state, rotationLockSetting, shouldBeLocked, isLocked);
+
         if (rotationLockSetting == DEVICE_STATE_ROTATION_LOCK_IGNORED) {
             // This should not happen. Device states that have an ignored setting, should also
             // specify a fallback device state which is not ignored.
             // We won't handle this device state. The same rotation lock setting as before should
             // apply and any changes to the rotation lock setting will be written for the previous
             // valid device state.
-            Log.w(TAG, "Missing fallback. Ignoring new device state: " + state);
             return;
         }
 
@@ -150,9 +158,18 @@
         mDeviceState = state;
 
         // Update the rotation policy, if needed, for this new device state
-        boolean newRotationLockSetting = rotationLockSetting == DEVICE_STATE_ROTATION_LOCK_LOCKED;
-        if (newRotationLockSetting != mRotationPolicyWrapper.isRotationLocked()) {
-            mRotationPolicyWrapper.setRotationLock(newRotationLockSetting);
+        if (shouldBeLocked != isLocked) {
+            mRotationPolicyWrapper.setRotationLock(shouldBeLocked);
         }
     }
+
+    @Override
+    public void dump(@NonNull PrintWriter printWriter, @NonNull String[] args) {
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter);
+        mDeviceStateRotationLockSettingsManager.dump(pw);
+        pw.println("DeviceStateRotationLockSettingController");
+        pw.increaseIndent();
+        pw.println("mDeviceState: " + mDeviceState);
+        pw.decreaseIndent();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingControllerLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingControllerLogger.kt
new file mode 100644
index 0000000..aa502bc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingControllerLogger.kt
@@ -0,0 +1,140 @@
+/*
+ * 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.systemui.statusbar.policy
+
+import android.content.Context
+import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_LOCK_IGNORED
+import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_LOCK_LOCKED
+import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_LOCK_UNLOCKED
+import com.android.internal.R
+import com.android.systemui.log.dagger.DeviceStateAutoRotationLog
+import com.android.systemui.plugins.log.LogBuffer
+import com.android.systemui.plugins.log.LogLevel.VERBOSE
+import javax.inject.Inject
+
+class DeviceStateRotationLockSettingControllerLogger
+@Inject
+constructor(@DeviceStateAutoRotationLog private val logBuffer: LogBuffer, context: Context) {
+
+    private val foldedStates = context.resources.getIntArray(R.array.config_foldedDeviceStates)
+    private val halfFoldedStates =
+        context.resources.getIntArray(R.array.config_halfFoldedDeviceStates)
+    private val unfoldedStates = context.resources.getIntArray(R.array.config_openDeviceStates)
+
+    fun logListeningChange(listening: Boolean) {
+        logBuffer.log(TAG, VERBOSE, { bool1 = listening }, { "setListening: $bool1" })
+    }
+
+    fun logRotationLockStateChanged(
+        state: Int,
+        newRotationLocked: Boolean,
+        currentRotationLocked: Boolean
+    ) {
+        logBuffer.log(
+            TAG,
+            VERBOSE,
+            {
+                int1 = state
+                bool1 = newRotationLocked
+                bool2 = currentRotationLocked
+            },
+            {
+                "onRotationLockStateChanged: " +
+                    "state=$int1 [${int1.toDevicePostureString()}], " +
+                    "newRotationLocked=$bool1, " +
+                    "currentRotationLocked=$bool2"
+            }
+        )
+    }
+
+    fun logSaveNewRotationLockSetting(isRotationLocked: Boolean, state: Int) {
+        logBuffer.log(
+            TAG,
+            VERBOSE,
+            {
+                bool1 = isRotationLocked
+                int1 = state
+            },
+            { "saveNewRotationLockSetting: isRotationLocked=$bool1, state=$int1" }
+        )
+    }
+
+    fun logUpdateDeviceState(currentState: Int, newState: Int) {
+        logBuffer.log(
+            TAG,
+            VERBOSE,
+            {
+                int1 = currentState
+                int2 = newState
+            },
+            {
+                "updateDeviceState: " +
+                    "current=$int1 [${int1.toDevicePostureString()}], " +
+                    "new=$int2 [${int2.toDevicePostureString()}]"
+            }
+        )
+    }
+
+    fun readPersistedSetting(
+        caller: String,
+        state: Int,
+        rotationLockSetting: Int,
+        shouldBeLocked: Boolean,
+        isLocked: Boolean
+    ) {
+        logBuffer.log(
+            TAG,
+            VERBOSE,
+            {
+                str1 = caller
+                int1 = state
+                int2 = rotationLockSetting
+                bool1 = shouldBeLocked
+                bool2 = isLocked
+            },
+            {
+                "readPersistedSetting: " +
+                    "caller=$str1, " +
+                    "state=$int1 [${int1.toDevicePostureString()}], " +
+                    "rotationLockSettingForState: ${int2.toRotationLockSettingString()}, " +
+                    "shouldBeLocked=$bool1, " +
+                    "isLocked=$bool2"
+            }
+        )
+    }
+
+    private fun Int.toDevicePostureString(): String {
+        return when (this) {
+            in foldedStates -> "Folded"
+            in unfoldedStates -> "Unfolded"
+            in halfFoldedStates -> "Half-Folded"
+            -1 -> "Uninitialized"
+            else -> "Unknown"
+        }
+    }
+}
+
+private fun Int.toRotationLockSettingString(): String {
+    return when (this) {
+        DEVICE_STATE_ROTATION_LOCK_IGNORED -> "IGNORED"
+        DEVICE_STATE_ROTATION_LOCK_LOCKED -> "LOCKED"
+        DEVICE_STATE_ROTATION_LOCK_UNLOCKED -> "UNLOCKED"
+        else -> "Unknown"
+    }
+}
+
+private const val TAG = "DSRotateLockSettingCon"
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingControllerTest.java
index 48b1732..481d453 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingControllerTest.java
@@ -38,6 +38,7 @@
 import com.android.internal.view.RotationPolicy;
 import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.dump.DumpManager;
 import com.android.systemui.util.concurrency.FakeExecutor;
 import com.android.systemui.util.time.FakeSystemClock;
 import com.android.systemui.util.wrapper.RotationPolicyWrapper;
@@ -55,10 +56,12 @@
 
     private static final String[] DEFAULT_SETTINGS = new String[]{"0:1", "2:0:1", "1:2"};
 
+    @Mock private DeviceStateManager mDeviceStateManager;
+    @Mock private DeviceStateRotationLockSettingControllerLogger mLogger;
+    @Mock private DumpManager mDumpManager;
+
     private final FakeSystemClock mFakeSystemClock = new FakeSystemClock();
     private final FakeExecutor mFakeExecutor = new FakeExecutor(mFakeSystemClock);
-    @Mock
-    private DeviceStateManager mDeviceStateManager;
     private final RotationPolicyWrapper mFakeRotationPolicy = new FakeRotationPolicy();
     private DeviceStateRotationLockSettingController mDeviceStateRotationLockSettingController;
     private DeviceStateManager.DeviceStateCallback mDeviceStateCallback;
@@ -78,7 +81,13 @@
         mSettingsManager = DeviceStateRotationLockSettingsManager.getInstance(mContext);
         mDeviceStateRotationLockSettingController =
                 new DeviceStateRotationLockSettingController(
-                        mFakeRotationPolicy, mDeviceStateManager, mFakeExecutor, mSettingsManager);
+                        mFakeRotationPolicy,
+                        mDeviceStateManager,
+                        mFakeExecutor,
+                        mSettingsManager,
+                        mLogger,
+                        mDumpManager
+                );
 
         mDeviceStateRotationLockSettingController.setListening(true);
         verify(mDeviceStateManager)
@@ -173,15 +182,11 @@
     }
 
     @Test
-    public void whenDeviceStateSwitchedToIgnoredState_usePreviousSetting() {
-        initializeSettingsWith(
-                0, DEVICE_STATE_ROTATION_LOCK_IGNORED, 1, DEVICE_STATE_ROTATION_LOCK_UNLOCKED);
-        mFakeRotationPolicy.setRotationLock(true);
-
-        mDeviceStateCallback.onStateChanged(1);
-        assertThat(mFakeRotationPolicy.isRotationLocked()).isFalse();
-
+    public void whenDeviceStateSwitchedToIgnoredState_useFallbackSetting() {
         mDeviceStateCallback.onStateChanged(0);
+        assertThat(mFakeRotationPolicy.isRotationLocked()).isTrue();
+
+        mDeviceStateCallback.onStateChanged(2);
         assertThat(mFakeRotationPolicy.isRotationLocked()).isFalse();
     }