Loading core/java/android/provider/Settings.java +30 −5 Original line number Diff line number Diff line Loading @@ -10997,21 +10997,46 @@ public final class Settings { public @interface DeviceStateRotationLockSetting { } /** @hide */ public static final int DEVICE_STATE_ROTATION_KEY_UNKNOWN = -1; /** @hide */ public static final int DEVICE_STATE_ROTATION_KEY_FOLDED = 0; /** @hide */ public static final int DEVICE_STATE_ROTATION_KEY_HALF_FOLDED = 1; /** @hide */ public static final int DEVICE_STATE_ROTATION_KEY_UNFOLDED = 2; /** * The different postures that can be used as keys with * {@link #DEVICE_STATE_ROTATION_LOCK}. * @hide */ @IntDef(prefix = {"DEVICE_STATE_ROTATION_KEY_"}, value = { DEVICE_STATE_ROTATION_KEY_UNKNOWN, DEVICE_STATE_ROTATION_KEY_FOLDED, DEVICE_STATE_ROTATION_KEY_HALF_FOLDED, DEVICE_STATE_ROTATION_KEY_UNFOLDED, }) @Retention(RetentionPolicy.SOURCE) public @interface DeviceStateRotationLockKey { } /** * Rotation lock setting keyed on device state. * * This holds a serialized map using int keys that represent Device States and value of * This holds a serialized map using int keys that represent postures in * {@link DeviceStateRotationLockKey} and value of * {@link DeviceStateRotationLockSetting} representing the rotation lock setting for that * device state. * posture. * * Serialized as key0:value0:key1:value1:...:keyN:valueN. * * Example: "0:1:1:2:2:1" * This example represents a map of: * <ul> * <li>0 -> DEVICE_STATE_ROTATION_LOCK_LOCKED</li> * <li>1 -> DEVICE_STATE_ROTATION_LOCK_UNLOCKED</li> * <li>2 -> DEVICE_STATE_ROTATION_LOCK_IGNORED</li> * <li>DEVICE_STATE_ROTATION_KEY_FOLDED -> DEVICE_STATE_ROTATION_LOCK_LOCKED</li> * <li>DEVICE_STATE_ROTATION_KEY_HALF_FOLDED -> DEVICE_STATE_ROTATION_LOCK_UNLOCKED</li> * <li>DEVICE_STATE_ROTATION_KEY_UNFOLDED -> DEVICE_STATE_ROTATION_LOCK_IGNORED</li> * </ul> * * @hide Loading core/res/res/values/config.xml +7 −8 Original line number Diff line number Diff line Loading @@ -736,14 +736,13 @@ display is powered on at the same time. --> <bool name="config_supportsConcurrentInternalDisplays">true</bool> <!-- Map of DeviceState to rotation lock setting. Each entry must be in the format "key:value", for example: "0:1". The keys are device states, and the values are one of <!-- Map of device posture to rotation lock setting. Each entry must be in the format "key:value", or "key:value:fallback_key" for example: "0:1" or "2:0:1". The keys are one of Settings.Secure.DeviceStateRotationLockKey, and the values are one of Settings.Secure.DeviceStateRotationLockSetting. Any device state that doesn't have a default set here will be treated as DEVICE_STATE_ROTATION_LOCK_IGNORED meaning it will not have its own rotation lock setting. If this map is missing, the feature is disabled and only one global rotation lock setting will apply, regardless of device state. --> The fallback is a key to a device posture that can be specified when the value is Settings.Secure.DEVICE_STATE_ROTATION_LOCK_IGNORED. --> <string-array name="config_perDeviceStateRotationLockDefaults" /> <!-- Dock behavior --> Loading packages/SettingsLib/DeviceStateRotationLock/Android.bp +4 −1 Original line number Diff line number Diff line Loading @@ -10,7 +10,10 @@ package { android_library { name: "SettingsLibDeviceStateRotationLock", srcs: ["src/**/*.java"], srcs: [ "src/**/*.java", "src/**/*.kt", ], min_sdk_version: "21", } packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateRotationLockSettingsManager.java +58 −53 Original line number Diff line number Diff line Loading @@ -57,17 +57,19 @@ public final class DeviceStateRotationLockSettingsManager { private final Handler mMainHandler = new Handler(Looper.getMainLooper()); private final Set<DeviceStateRotationLockSettingsListener> mListeners = new HashSet<>(); private final SecureSettings mSecureSettings; private String[] mDeviceStateRotationLockDefaults; private SparseIntArray mDeviceStateRotationLockSettings; private SparseIntArray mDeviceStateDefaultRotationLockSettings; private SparseIntArray mDeviceStateRotationLockFallbackSettings; private final PosturesHelper mPosturesHelper; private String[] mPostureRotationLockDefaults; private SparseIntArray mPostureRotationLockSettings; private SparseIntArray mPostureDefaultRotationLockSettings; private SparseIntArray mPostureRotationLockFallbackSettings; private String mLastSettingValue; private List<SettableDeviceState> mSettableDeviceStates; @VisibleForTesting DeviceStateRotationLockSettingsManager(Context context, SecureSettings secureSettings) { this.mSecureSettings = secureSettings; mDeviceStateRotationLockDefaults = mSecureSettings = secureSettings; mPosturesHelper = new PosturesHelper(context); mPostureRotationLockDefaults = context.getResources() .getStringArray(R.array.config_perDeviceStateRotationLockDefaults); loadDefaults(); Loading Loading @@ -134,13 +136,14 @@ public final class DeviceStateRotationLockSettingsManager { /** Updates the rotation lock setting for a specified device state. */ public void updateSetting(int deviceState, boolean rotationLocked) { if (mDeviceStateRotationLockFallbackSettings.indexOfKey(deviceState) >= 0) { // The setting for this device state is IGNORED, and has a fallback device state. // The setting for that fallback device state should be the changed in this case. deviceState = mDeviceStateRotationLockFallbackSettings.get(deviceState); } mDeviceStateRotationLockSettings.put( deviceState, int posture = mPosturesHelper.deviceStateToPosture(deviceState); if (mPostureRotationLockFallbackSettings.indexOfKey(posture) >= 0) { // The setting for this device posture is IGNORED, and has a fallback posture. // The setting for that fallback posture should be the changed in this case. posture = mPostureRotationLockFallbackSettings.get(posture); } mPostureRotationLockSettings.put( posture, rotationLocked ? DEVICE_STATE_ROTATION_LOCK_LOCKED : DEVICE_STATE_ROTATION_LOCK_UNLOCKED); Loading @@ -159,22 +162,23 @@ public final class DeviceStateRotationLockSettingsManager { */ @Settings.Secure.DeviceStateRotationLockSetting public int getRotationLockSetting(int deviceState) { int rotationLockSetting = mDeviceStateRotationLockSettings.get( deviceState, /* valueIfKeyNotFound= */ DEVICE_STATE_ROTATION_LOCK_IGNORED); int devicePosture = mPosturesHelper.deviceStateToPosture(deviceState); int rotationLockSetting = mPostureRotationLockSettings.get( devicePosture, /* valueIfKeyNotFound= */ DEVICE_STATE_ROTATION_LOCK_IGNORED); if (rotationLockSetting == DEVICE_STATE_ROTATION_LOCK_IGNORED) { rotationLockSetting = getFallbackRotationLockSetting(deviceState); rotationLockSetting = getFallbackRotationLockSetting(devicePosture); } return rotationLockSetting; } private int getFallbackRotationLockSetting(int deviceState) { int indexOfFallbackState = mDeviceStateRotationLockFallbackSettings.indexOfKey(deviceState); if (indexOfFallbackState < 0) { private int getFallbackRotationLockSetting(int devicePosture) { int indexOfFallback = mPostureRotationLockFallbackSettings.indexOfKey(devicePosture); if (indexOfFallback < 0) { Log.w(TAG, "Setting is ignored, but no fallback was specified."); return DEVICE_STATE_ROTATION_LOCK_IGNORED; } int fallbackState = mDeviceStateRotationLockFallbackSettings.valueAt(indexOfFallbackState); return mDeviceStateRotationLockSettings.get(fallbackState, int fallbackPosture = mPostureRotationLockFallbackSettings.valueAt(indexOfFallback); return mPostureRotationLockSettings.get(fallbackPosture, /* valueIfKeyNotFound= */ DEVICE_STATE_ROTATION_LOCK_IGNORED); } Loading @@ -189,8 +193,8 @@ public final class DeviceStateRotationLockSettingsManager { * DEVICE_STATE_ROTATION_LOCK_UNLOCKED}. */ public boolean isRotationLockedForAllStates() { for (int i = 0; i < mDeviceStateRotationLockSettings.size(); i++) { if (mDeviceStateRotationLockSettings.valueAt(i) for (int i = 0; i < mPostureRotationLockSettings.size(); i++) { if (mPostureRotationLockSettings.valueAt(i) == DEVICE_STATE_ROTATION_LOCK_UNLOCKED) { return false; } Loading Loading @@ -221,7 +225,7 @@ public final class DeviceStateRotationLockSettingsManager { fallbackOnDefaults(); return; } mDeviceStateRotationLockSettings = new SparseIntArray(values.length / 2); mPostureRotationLockSettings = new SparseIntArray(values.length / 2); int key; int value; Loading @@ -230,7 +234,7 @@ public final class DeviceStateRotationLockSettingsManager { key = Integer.parseInt(values[i++]); value = Integer.parseInt(values[i++]); boolean isPersistedValueIgnored = value == DEVICE_STATE_ROTATION_LOCK_IGNORED; boolean isDefaultValueIgnored = mDeviceStateDefaultRotationLockSettings.get(key) boolean isDefaultValueIgnored = mPostureDefaultRotationLockSettings.get(key) == DEVICE_STATE_ROTATION_LOCK_IGNORED; if (isPersistedValueIgnored != isDefaultValueIgnored) { Log.w(TAG, "Conflict for ignored device state " + key Loading @@ -238,7 +242,7 @@ public final class DeviceStateRotationLockSettingsManager { fallbackOnDefaults(); return; } mDeviceStateRotationLockSettings.put(key, value); mPostureRotationLockSettings.put(key, value); } catch (NumberFormatException e) { Log.wtf(TAG, "Error deserializing one of the saved settings", e); fallbackOnDefaults(); Loading @@ -253,7 +257,7 @@ public final class DeviceStateRotationLockSettingsManager { */ @VisibleForTesting public void resetStateForTesting(Resources resources) { mDeviceStateRotationLockDefaults = mPostureRotationLockDefaults = resources.getStringArray(R.array.config_perDeviceStateRotationLockDefaults); fallbackOnDefaults(); } Loading @@ -264,23 +268,23 @@ public final class DeviceStateRotationLockSettingsManager { } private void persistSettings() { if (mDeviceStateRotationLockSettings.size() == 0) { if (mPostureRotationLockSettings.size() == 0) { persistSettingIfChanged(/* newSettingValue= */ ""); return; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder .append(mDeviceStateRotationLockSettings.keyAt(0)) .append(mPostureRotationLockSettings.keyAt(0)) .append(SEPARATOR_REGEX) .append(mDeviceStateRotationLockSettings.valueAt(0)); .append(mPostureRotationLockSettings.valueAt(0)); for (int i = 1; i < mDeviceStateRotationLockSettings.size(); i++) { for (int i = 1; i < mPostureRotationLockSettings.size(); i++) { stringBuilder .append(SEPARATOR_REGEX) .append(mDeviceStateRotationLockSettings.keyAt(i)) .append(mPostureRotationLockSettings.keyAt(i)) .append(SEPARATOR_REGEX) .append(mDeviceStateRotationLockSettings.valueAt(i)); .append(mPostureRotationLockSettings.valueAt(i)); } persistSettingIfChanged(stringBuilder.toString()); } Loading @@ -300,22 +304,20 @@ public final class DeviceStateRotationLockSettingsManager { } private void loadDefaults() { mSettableDeviceStates = new ArrayList<>(mDeviceStateRotationLockDefaults.length); mDeviceStateDefaultRotationLockSettings = new SparseIntArray( mDeviceStateRotationLockDefaults.length); mDeviceStateRotationLockSettings = new SparseIntArray( mDeviceStateRotationLockDefaults.length); mDeviceStateRotationLockFallbackSettings = new SparseIntArray(1); for (String entry : mDeviceStateRotationLockDefaults) { mSettableDeviceStates = new ArrayList<>(mPostureRotationLockDefaults.length); mPostureDefaultRotationLockSettings = new SparseIntArray( mPostureRotationLockDefaults.length); mPostureRotationLockSettings = new SparseIntArray(mPostureRotationLockDefaults.length); mPostureRotationLockFallbackSettings = new SparseIntArray(1); for (String entry : mPostureRotationLockDefaults) { String[] values = entry.split(SEPARATOR_REGEX); try { int deviceState = Integer.parseInt(values[0]); int posture = Integer.parseInt(values[0]); int rotationLockSetting = Integer.parseInt(values[1]); if (rotationLockSetting == DEVICE_STATE_ROTATION_LOCK_IGNORED) { if (values.length == 3) { int fallbackDeviceState = Integer.parseInt(values[2]); mDeviceStateRotationLockFallbackSettings.put(deviceState, fallbackDeviceState); int fallbackPosture = Integer.parseInt(values[2]); mPostureRotationLockFallbackSettings.put(posture, fallbackPosture); } else { Log.w(TAG, "Rotation lock setting is IGNORED, but values have unexpected " Loading @@ -324,9 +326,14 @@ public final class DeviceStateRotationLockSettingsManager { } } boolean isSettable = rotationLockSetting != DEVICE_STATE_ROTATION_LOCK_IGNORED; Integer deviceState = mPosturesHelper.postureToDeviceState(posture); if (deviceState != null) { mSettableDeviceStates.add(new SettableDeviceState(deviceState, isSettable)); mDeviceStateRotationLockSettings.put(deviceState, rotationLockSetting); mDeviceStateDefaultRotationLockSettings.put(deviceState, rotationLockSetting); } else { Log.wtf(TAG, "No matching device state for posture: " + posture); } mPostureRotationLockSettings.put(posture, rotationLockSetting); mPostureDefaultRotationLockSettings.put(posture, rotationLockSetting); } catch (NumberFormatException e) { Log.wtf(TAG, "Error parsing settings entry. Entry was: " + entry, e); return; Loading @@ -338,13 +345,11 @@ public final class DeviceStateRotationLockSettingsManager { 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("mPostureRotationLockDefaults: " + Arrays.toString(mPostureRotationLockDefaults)); pw.println("mPostureDefaultRotationLockSettings: " + mPostureDefaultRotationLockSettings); pw.println("mDeviceStateRotationLockSettings: " + mPostureRotationLockSettings); pw.println("mPostureRotationLockFallbackSettings: " + mPostureRotationLockFallbackSettings); pw.println("mSettableDeviceStates: " + mSettableDeviceStates); pw.println("mLastSettingValue: " + mLastSettingValue); pw.decreaseIndent(); Loading packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/PosturesHelper.kt 0 → 100644 +55 −0 Original line number Diff line number Diff line /* * 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.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_UNFOLDED import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_KEY_UNKNOWN import android.provider.Settings.Secure.DeviceStateRotationLockKey import com.android.internal.R /** Helps to convert between device state and posture. */ class PosturesHelper(context: Context) { private val foldedDeviceStates = context.resources.getIntArray(R.array.config_foldedDeviceStates) private val halfFoldedDeviceStates = context.resources.getIntArray(R.array.config_halfFoldedDeviceStates) private val unfoldedDeviceStates = context.resources.getIntArray(R.array.config_openDeviceStates) @DeviceStateRotationLockKey fun deviceStateToPosture(deviceState: Int): Int { return when (deviceState) { in foldedDeviceStates -> DEVICE_STATE_ROTATION_KEY_FOLDED in halfFoldedDeviceStates -> DEVICE_STATE_ROTATION_KEY_HALF_FOLDED in unfoldedDeviceStates -> DEVICE_STATE_ROTATION_KEY_UNFOLDED else -> DEVICE_STATE_ROTATION_KEY_UNKNOWN } } fun postureToDeviceState(@DeviceStateRotationLockKey posture: Int): Int? { return when (posture) { DEVICE_STATE_ROTATION_KEY_FOLDED -> foldedDeviceStates.firstOrNull() DEVICE_STATE_ROTATION_KEY_HALF_FOLDED -> halfFoldedDeviceStates.firstOrNull() DEVICE_STATE_ROTATION_KEY_UNFOLDED -> unfoldedDeviceStates.firstOrNull() else -> null } } } Loading
core/java/android/provider/Settings.java +30 −5 Original line number Diff line number Diff line Loading @@ -10997,21 +10997,46 @@ public final class Settings { public @interface DeviceStateRotationLockSetting { } /** @hide */ public static final int DEVICE_STATE_ROTATION_KEY_UNKNOWN = -1; /** @hide */ public static final int DEVICE_STATE_ROTATION_KEY_FOLDED = 0; /** @hide */ public static final int DEVICE_STATE_ROTATION_KEY_HALF_FOLDED = 1; /** @hide */ public static final int DEVICE_STATE_ROTATION_KEY_UNFOLDED = 2; /** * The different postures that can be used as keys with * {@link #DEVICE_STATE_ROTATION_LOCK}. * @hide */ @IntDef(prefix = {"DEVICE_STATE_ROTATION_KEY_"}, value = { DEVICE_STATE_ROTATION_KEY_UNKNOWN, DEVICE_STATE_ROTATION_KEY_FOLDED, DEVICE_STATE_ROTATION_KEY_HALF_FOLDED, DEVICE_STATE_ROTATION_KEY_UNFOLDED, }) @Retention(RetentionPolicy.SOURCE) public @interface DeviceStateRotationLockKey { } /** * Rotation lock setting keyed on device state. * * This holds a serialized map using int keys that represent Device States and value of * This holds a serialized map using int keys that represent postures in * {@link DeviceStateRotationLockKey} and value of * {@link DeviceStateRotationLockSetting} representing the rotation lock setting for that * device state. * posture. * * Serialized as key0:value0:key1:value1:...:keyN:valueN. * * Example: "0:1:1:2:2:1" * This example represents a map of: * <ul> * <li>0 -> DEVICE_STATE_ROTATION_LOCK_LOCKED</li> * <li>1 -> DEVICE_STATE_ROTATION_LOCK_UNLOCKED</li> * <li>2 -> DEVICE_STATE_ROTATION_LOCK_IGNORED</li> * <li>DEVICE_STATE_ROTATION_KEY_FOLDED -> DEVICE_STATE_ROTATION_LOCK_LOCKED</li> * <li>DEVICE_STATE_ROTATION_KEY_HALF_FOLDED -> DEVICE_STATE_ROTATION_LOCK_UNLOCKED</li> * <li>DEVICE_STATE_ROTATION_KEY_UNFOLDED -> DEVICE_STATE_ROTATION_LOCK_IGNORED</li> * </ul> * * @hide Loading
core/res/res/values/config.xml +7 −8 Original line number Diff line number Diff line Loading @@ -736,14 +736,13 @@ display is powered on at the same time. --> <bool name="config_supportsConcurrentInternalDisplays">true</bool> <!-- Map of DeviceState to rotation lock setting. Each entry must be in the format "key:value", for example: "0:1". The keys are device states, and the values are one of <!-- Map of device posture to rotation lock setting. Each entry must be in the format "key:value", or "key:value:fallback_key" for example: "0:1" or "2:0:1". The keys are one of Settings.Secure.DeviceStateRotationLockKey, and the values are one of Settings.Secure.DeviceStateRotationLockSetting. Any device state that doesn't have a default set here will be treated as DEVICE_STATE_ROTATION_LOCK_IGNORED meaning it will not have its own rotation lock setting. If this map is missing, the feature is disabled and only one global rotation lock setting will apply, regardless of device state. --> The fallback is a key to a device posture that can be specified when the value is Settings.Secure.DEVICE_STATE_ROTATION_LOCK_IGNORED. --> <string-array name="config_perDeviceStateRotationLockDefaults" /> <!-- Dock behavior --> Loading
packages/SettingsLib/DeviceStateRotationLock/Android.bp +4 −1 Original line number Diff line number Diff line Loading @@ -10,7 +10,10 @@ package { android_library { name: "SettingsLibDeviceStateRotationLock", srcs: ["src/**/*.java"], srcs: [ "src/**/*.java", "src/**/*.kt", ], min_sdk_version: "21", }
packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateRotationLockSettingsManager.java +58 −53 Original line number Diff line number Diff line Loading @@ -57,17 +57,19 @@ public final class DeviceStateRotationLockSettingsManager { private final Handler mMainHandler = new Handler(Looper.getMainLooper()); private final Set<DeviceStateRotationLockSettingsListener> mListeners = new HashSet<>(); private final SecureSettings mSecureSettings; private String[] mDeviceStateRotationLockDefaults; private SparseIntArray mDeviceStateRotationLockSettings; private SparseIntArray mDeviceStateDefaultRotationLockSettings; private SparseIntArray mDeviceStateRotationLockFallbackSettings; private final PosturesHelper mPosturesHelper; private String[] mPostureRotationLockDefaults; private SparseIntArray mPostureRotationLockSettings; private SparseIntArray mPostureDefaultRotationLockSettings; private SparseIntArray mPostureRotationLockFallbackSettings; private String mLastSettingValue; private List<SettableDeviceState> mSettableDeviceStates; @VisibleForTesting DeviceStateRotationLockSettingsManager(Context context, SecureSettings secureSettings) { this.mSecureSettings = secureSettings; mDeviceStateRotationLockDefaults = mSecureSettings = secureSettings; mPosturesHelper = new PosturesHelper(context); mPostureRotationLockDefaults = context.getResources() .getStringArray(R.array.config_perDeviceStateRotationLockDefaults); loadDefaults(); Loading Loading @@ -134,13 +136,14 @@ public final class DeviceStateRotationLockSettingsManager { /** Updates the rotation lock setting for a specified device state. */ public void updateSetting(int deviceState, boolean rotationLocked) { if (mDeviceStateRotationLockFallbackSettings.indexOfKey(deviceState) >= 0) { // The setting for this device state is IGNORED, and has a fallback device state. // The setting for that fallback device state should be the changed in this case. deviceState = mDeviceStateRotationLockFallbackSettings.get(deviceState); } mDeviceStateRotationLockSettings.put( deviceState, int posture = mPosturesHelper.deviceStateToPosture(deviceState); if (mPostureRotationLockFallbackSettings.indexOfKey(posture) >= 0) { // The setting for this device posture is IGNORED, and has a fallback posture. // The setting for that fallback posture should be the changed in this case. posture = mPostureRotationLockFallbackSettings.get(posture); } mPostureRotationLockSettings.put( posture, rotationLocked ? DEVICE_STATE_ROTATION_LOCK_LOCKED : DEVICE_STATE_ROTATION_LOCK_UNLOCKED); Loading @@ -159,22 +162,23 @@ public final class DeviceStateRotationLockSettingsManager { */ @Settings.Secure.DeviceStateRotationLockSetting public int getRotationLockSetting(int deviceState) { int rotationLockSetting = mDeviceStateRotationLockSettings.get( deviceState, /* valueIfKeyNotFound= */ DEVICE_STATE_ROTATION_LOCK_IGNORED); int devicePosture = mPosturesHelper.deviceStateToPosture(deviceState); int rotationLockSetting = mPostureRotationLockSettings.get( devicePosture, /* valueIfKeyNotFound= */ DEVICE_STATE_ROTATION_LOCK_IGNORED); if (rotationLockSetting == DEVICE_STATE_ROTATION_LOCK_IGNORED) { rotationLockSetting = getFallbackRotationLockSetting(deviceState); rotationLockSetting = getFallbackRotationLockSetting(devicePosture); } return rotationLockSetting; } private int getFallbackRotationLockSetting(int deviceState) { int indexOfFallbackState = mDeviceStateRotationLockFallbackSettings.indexOfKey(deviceState); if (indexOfFallbackState < 0) { private int getFallbackRotationLockSetting(int devicePosture) { int indexOfFallback = mPostureRotationLockFallbackSettings.indexOfKey(devicePosture); if (indexOfFallback < 0) { Log.w(TAG, "Setting is ignored, but no fallback was specified."); return DEVICE_STATE_ROTATION_LOCK_IGNORED; } int fallbackState = mDeviceStateRotationLockFallbackSettings.valueAt(indexOfFallbackState); return mDeviceStateRotationLockSettings.get(fallbackState, int fallbackPosture = mPostureRotationLockFallbackSettings.valueAt(indexOfFallback); return mPostureRotationLockSettings.get(fallbackPosture, /* valueIfKeyNotFound= */ DEVICE_STATE_ROTATION_LOCK_IGNORED); } Loading @@ -189,8 +193,8 @@ public final class DeviceStateRotationLockSettingsManager { * DEVICE_STATE_ROTATION_LOCK_UNLOCKED}. */ public boolean isRotationLockedForAllStates() { for (int i = 0; i < mDeviceStateRotationLockSettings.size(); i++) { if (mDeviceStateRotationLockSettings.valueAt(i) for (int i = 0; i < mPostureRotationLockSettings.size(); i++) { if (mPostureRotationLockSettings.valueAt(i) == DEVICE_STATE_ROTATION_LOCK_UNLOCKED) { return false; } Loading Loading @@ -221,7 +225,7 @@ public final class DeviceStateRotationLockSettingsManager { fallbackOnDefaults(); return; } mDeviceStateRotationLockSettings = new SparseIntArray(values.length / 2); mPostureRotationLockSettings = new SparseIntArray(values.length / 2); int key; int value; Loading @@ -230,7 +234,7 @@ public final class DeviceStateRotationLockSettingsManager { key = Integer.parseInt(values[i++]); value = Integer.parseInt(values[i++]); boolean isPersistedValueIgnored = value == DEVICE_STATE_ROTATION_LOCK_IGNORED; boolean isDefaultValueIgnored = mDeviceStateDefaultRotationLockSettings.get(key) boolean isDefaultValueIgnored = mPostureDefaultRotationLockSettings.get(key) == DEVICE_STATE_ROTATION_LOCK_IGNORED; if (isPersistedValueIgnored != isDefaultValueIgnored) { Log.w(TAG, "Conflict for ignored device state " + key Loading @@ -238,7 +242,7 @@ public final class DeviceStateRotationLockSettingsManager { fallbackOnDefaults(); return; } mDeviceStateRotationLockSettings.put(key, value); mPostureRotationLockSettings.put(key, value); } catch (NumberFormatException e) { Log.wtf(TAG, "Error deserializing one of the saved settings", e); fallbackOnDefaults(); Loading @@ -253,7 +257,7 @@ public final class DeviceStateRotationLockSettingsManager { */ @VisibleForTesting public void resetStateForTesting(Resources resources) { mDeviceStateRotationLockDefaults = mPostureRotationLockDefaults = resources.getStringArray(R.array.config_perDeviceStateRotationLockDefaults); fallbackOnDefaults(); } Loading @@ -264,23 +268,23 @@ public final class DeviceStateRotationLockSettingsManager { } private void persistSettings() { if (mDeviceStateRotationLockSettings.size() == 0) { if (mPostureRotationLockSettings.size() == 0) { persistSettingIfChanged(/* newSettingValue= */ ""); return; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder .append(mDeviceStateRotationLockSettings.keyAt(0)) .append(mPostureRotationLockSettings.keyAt(0)) .append(SEPARATOR_REGEX) .append(mDeviceStateRotationLockSettings.valueAt(0)); .append(mPostureRotationLockSettings.valueAt(0)); for (int i = 1; i < mDeviceStateRotationLockSettings.size(); i++) { for (int i = 1; i < mPostureRotationLockSettings.size(); i++) { stringBuilder .append(SEPARATOR_REGEX) .append(mDeviceStateRotationLockSettings.keyAt(i)) .append(mPostureRotationLockSettings.keyAt(i)) .append(SEPARATOR_REGEX) .append(mDeviceStateRotationLockSettings.valueAt(i)); .append(mPostureRotationLockSettings.valueAt(i)); } persistSettingIfChanged(stringBuilder.toString()); } Loading @@ -300,22 +304,20 @@ public final class DeviceStateRotationLockSettingsManager { } private void loadDefaults() { mSettableDeviceStates = new ArrayList<>(mDeviceStateRotationLockDefaults.length); mDeviceStateDefaultRotationLockSettings = new SparseIntArray( mDeviceStateRotationLockDefaults.length); mDeviceStateRotationLockSettings = new SparseIntArray( mDeviceStateRotationLockDefaults.length); mDeviceStateRotationLockFallbackSettings = new SparseIntArray(1); for (String entry : mDeviceStateRotationLockDefaults) { mSettableDeviceStates = new ArrayList<>(mPostureRotationLockDefaults.length); mPostureDefaultRotationLockSettings = new SparseIntArray( mPostureRotationLockDefaults.length); mPostureRotationLockSettings = new SparseIntArray(mPostureRotationLockDefaults.length); mPostureRotationLockFallbackSettings = new SparseIntArray(1); for (String entry : mPostureRotationLockDefaults) { String[] values = entry.split(SEPARATOR_REGEX); try { int deviceState = Integer.parseInt(values[0]); int posture = Integer.parseInt(values[0]); int rotationLockSetting = Integer.parseInt(values[1]); if (rotationLockSetting == DEVICE_STATE_ROTATION_LOCK_IGNORED) { if (values.length == 3) { int fallbackDeviceState = Integer.parseInt(values[2]); mDeviceStateRotationLockFallbackSettings.put(deviceState, fallbackDeviceState); int fallbackPosture = Integer.parseInt(values[2]); mPostureRotationLockFallbackSettings.put(posture, fallbackPosture); } else { Log.w(TAG, "Rotation lock setting is IGNORED, but values have unexpected " Loading @@ -324,9 +326,14 @@ public final class DeviceStateRotationLockSettingsManager { } } boolean isSettable = rotationLockSetting != DEVICE_STATE_ROTATION_LOCK_IGNORED; Integer deviceState = mPosturesHelper.postureToDeviceState(posture); if (deviceState != null) { mSettableDeviceStates.add(new SettableDeviceState(deviceState, isSettable)); mDeviceStateRotationLockSettings.put(deviceState, rotationLockSetting); mDeviceStateDefaultRotationLockSettings.put(deviceState, rotationLockSetting); } else { Log.wtf(TAG, "No matching device state for posture: " + posture); } mPostureRotationLockSettings.put(posture, rotationLockSetting); mPostureDefaultRotationLockSettings.put(posture, rotationLockSetting); } catch (NumberFormatException e) { Log.wtf(TAG, "Error parsing settings entry. Entry was: " + entry, e); return; Loading @@ -338,13 +345,11 @@ public final class DeviceStateRotationLockSettingsManager { 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("mPostureRotationLockDefaults: " + Arrays.toString(mPostureRotationLockDefaults)); pw.println("mPostureDefaultRotationLockSettings: " + mPostureDefaultRotationLockSettings); pw.println("mDeviceStateRotationLockSettings: " + mPostureRotationLockSettings); pw.println("mPostureRotationLockFallbackSettings: " + mPostureRotationLockFallbackSettings); pw.println("mSettableDeviceStates: " + mSettableDeviceStates); pw.println("mLastSettingValue: " + mLastSettingValue); pw.decreaseIndent(); Loading
packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/PosturesHelper.kt 0 → 100644 +55 −0 Original line number Diff line number Diff line /* * 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.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_UNFOLDED import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_KEY_UNKNOWN import android.provider.Settings.Secure.DeviceStateRotationLockKey import com.android.internal.R /** Helps to convert between device state and posture. */ class PosturesHelper(context: Context) { private val foldedDeviceStates = context.resources.getIntArray(R.array.config_foldedDeviceStates) private val halfFoldedDeviceStates = context.resources.getIntArray(R.array.config_halfFoldedDeviceStates) private val unfoldedDeviceStates = context.resources.getIntArray(R.array.config_openDeviceStates) @DeviceStateRotationLockKey fun deviceStateToPosture(deviceState: Int): Int { return when (deviceState) { in foldedDeviceStates -> DEVICE_STATE_ROTATION_KEY_FOLDED in halfFoldedDeviceStates -> DEVICE_STATE_ROTATION_KEY_HALF_FOLDED in unfoldedDeviceStates -> DEVICE_STATE_ROTATION_KEY_UNFOLDED else -> DEVICE_STATE_ROTATION_KEY_UNKNOWN } } fun postureToDeviceState(@DeviceStateRotationLockKey posture: Int): Int? { return when (posture) { DEVICE_STATE_ROTATION_KEY_FOLDED -> foldedDeviceStates.firstOrNull() DEVICE_STATE_ROTATION_KEY_HALF_FOLDED -> halfFoldedDeviceStates.firstOrNull() DEVICE_STATE_ROTATION_KEY_UNFOLDED -> unfoldedDeviceStates.firstOrNull() else -> null } } }