Merge "Device state rotation: fallback to defaults for invalid ignored state" into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
4e0e3b7056
@@ -29,6 +29,7 @@ import android.os.Looper;
|
|||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import android.util.IndentingPrintWriter;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.SparseIntArray;
|
import android.util.SparseIntArray;
|
||||||
|
|
||||||
@@ -36,6 +37,7 @@ import com.android.internal.R;
|
|||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -57,6 +59,7 @@ public final class DeviceStateRotationLockSettingsManager {
|
|||||||
private final SecureSettings mSecureSettings;
|
private final SecureSettings mSecureSettings;
|
||||||
private String[] mDeviceStateRotationLockDefaults;
|
private String[] mDeviceStateRotationLockDefaults;
|
||||||
private SparseIntArray mDeviceStateRotationLockSettings;
|
private SparseIntArray mDeviceStateRotationLockSettings;
|
||||||
|
private SparseIntArray mDeviceStateDefaultRotationLockSettings;
|
||||||
private SparseIntArray mDeviceStateRotationLockFallbackSettings;
|
private SparseIntArray mDeviceStateRotationLockFallbackSettings;
|
||||||
private String mLastSettingValue;
|
private String mLastSettingValue;
|
||||||
private List<SettableDeviceState> mSettableDeviceStates;
|
private List<SettableDeviceState> mSettableDeviceStates;
|
||||||
@@ -93,9 +96,7 @@ public final class DeviceStateRotationLockSettingsManager {
|
|||||||
/** Returns true if device-state based rotation lock settings are enabled. */
|
/** Returns true if device-state based rotation lock settings are enabled. */
|
||||||
public static boolean isDeviceStateRotationLockEnabled(Context context) {
|
public static boolean isDeviceStateRotationLockEnabled(Context context) {
|
||||||
return context.getResources()
|
return context.getResources()
|
||||||
.getStringArray(R.array.config_perDeviceStateRotationLockDefaults)
|
.getStringArray(R.array.config_perDeviceStateRotationLockDefaults).length > 0;
|
||||||
.length
|
|
||||||
> 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void listenForSettingsChange() {
|
private void listenForSettingsChange() {
|
||||||
@@ -228,6 +229,15 @@ public final class DeviceStateRotationLockSettingsManager {
|
|||||||
try {
|
try {
|
||||||
key = Integer.parseInt(values[i++]);
|
key = Integer.parseInt(values[i++]);
|
||||||
value = 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);
|
mDeviceStateRotationLockSettings.put(key, value);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
Log.wtf(TAG, "Error deserializing one of the saved settings", e);
|
Log.wtf(TAG, "Error deserializing one of the saved settings", e);
|
||||||
@@ -276,6 +286,9 @@ public final class DeviceStateRotationLockSettingsManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void persistSettingIfChanged(String newSettingValue) {
|
private void persistSettingIfChanged(String newSettingValue) {
|
||||||
|
Log.v(TAG, "persistSettingIfChanged: "
|
||||||
|
+ "last=" + mLastSettingValue + ", "
|
||||||
|
+ "new=" + newSettingValue);
|
||||||
if (TextUtils.equals(mLastSettingValue, newSettingValue)) {
|
if (TextUtils.equals(mLastSettingValue, newSettingValue)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -288,6 +301,8 @@ public final class DeviceStateRotationLockSettingsManager {
|
|||||||
|
|
||||||
private void loadDefaults() {
|
private void loadDefaults() {
|
||||||
mSettableDeviceStates = new ArrayList<>(mDeviceStateRotationLockDefaults.length);
|
mSettableDeviceStates = new ArrayList<>(mDeviceStateRotationLockDefaults.length);
|
||||||
|
mDeviceStateDefaultRotationLockSettings = new SparseIntArray(
|
||||||
|
mDeviceStateRotationLockDefaults.length);
|
||||||
mDeviceStateRotationLockSettings = new SparseIntArray(
|
mDeviceStateRotationLockSettings = new SparseIntArray(
|
||||||
mDeviceStateRotationLockDefaults.length);
|
mDeviceStateRotationLockDefaults.length);
|
||||||
mDeviceStateRotationLockFallbackSettings = new SparseIntArray(1);
|
mDeviceStateRotationLockFallbackSettings = new SparseIntArray(1);
|
||||||
@@ -311,6 +326,7 @@ public final class DeviceStateRotationLockSettingsManager {
|
|||||||
boolean isSettable = rotationLockSetting != DEVICE_STATE_ROTATION_LOCK_IGNORED;
|
boolean isSettable = rotationLockSetting != DEVICE_STATE_ROTATION_LOCK_IGNORED;
|
||||||
mSettableDeviceStates.add(new SettableDeviceState(deviceState, isSettable));
|
mSettableDeviceStates.add(new SettableDeviceState(deviceState, isSettable));
|
||||||
mDeviceStateRotationLockSettings.put(deviceState, rotationLockSetting);
|
mDeviceStateRotationLockSettings.put(deviceState, rotationLockSetting);
|
||||||
|
mDeviceStateDefaultRotationLockSettings.put(deviceState, rotationLockSetting);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
Log.wtf(TAG, "Error parsing settings entry. Entry was: " + entry, e);
|
Log.wtf(TAG, "Error parsing settings entry. Entry was: " + entry, e);
|
||||||
return;
|
return;
|
||||||
@@ -318,6 +334,22 @@ public final class DeviceStateRotationLockSettingsManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 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
|
* Called when the persisted settings have changed, requiring a reinitialization of the
|
||||||
* in-memory map.
|
* in-memory map.
|
||||||
@@ -372,5 +404,13 @@ public final class DeviceStateRotationLockSettingsManager {
|
|||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(mDeviceState, mIsSettable);
|
return Objects.hash(mDeviceState, mIsSettable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "SettableDeviceState{"
|
||||||
|
+ "mDeviceState=" + mDeviceState
|
||||||
|
+ ", mIsSettable=" + mIsSettable
|
||||||
|
+ '}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,10 @@ import androidx.test.runner.AndroidJUnit4;
|
|||||||
import com.android.internal.R;
|
import com.android.internal.R;
|
||||||
import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager.SettableDeviceState;
|
import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager.SettableDeviceState;
|
||||||
|
|
||||||
|
import com.google.common.truth.Expect;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
@@ -45,6 +48,8 @@ import java.util.List;
|
|||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
public class DeviceStateRotationLockSettingsManagerTest {
|
public class DeviceStateRotationLockSettingsManagerTest {
|
||||||
|
|
||||||
|
@Rule public Expect mExpect = Expect.create();
|
||||||
|
|
||||||
@Mock private Context mMockContext;
|
@Mock private Context mMockContext;
|
||||||
@Mock private Resources mMockResources;
|
@Mock private Resources mMockResources;
|
||||||
|
|
||||||
@@ -117,4 +122,40 @@ public class DeviceStateRotationLockSettingsManagerTest {
|
|||||||
new SettableDeviceState(/* deviceState= */ 0, /* isSettable= */ false)
|
new SettableDeviceState(/* deviceState= */ 0, /* isSettable= */ false)
|
||||||
).inOrder();
|
).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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
}
|
||||||
@@ -369,6 +369,16 @@ public class LogModule {
|
|||||||
return factory.create("KeyguardFaceAuthManagerLog", 300);
|
return factory.create("KeyguardFaceAuthManagerLog", 300);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 a {@link LogBuffer} for bluetooth-related logs.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -22,13 +22,18 @@ import static android.provider.Settings.Secure.DEVICE_STATE_ROTATION_LOCK_LOCKED
|
|||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.hardware.devicestate.DeviceStateManager;
|
import android.hardware.devicestate.DeviceStateManager;
|
||||||
import android.os.Trace;
|
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.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
|
||||||
|
import com.android.systemui.Dumpable;
|
||||||
import com.android.systemui.dagger.SysUISingleton;
|
import com.android.systemui.dagger.SysUISingleton;
|
||||||
import com.android.systemui.dagger.qualifiers.Main;
|
import com.android.systemui.dagger.qualifiers.Main;
|
||||||
|
import com.android.systemui.dump.DumpManager;
|
||||||
import com.android.systemui.util.wrapper.RotationPolicyWrapper;
|
import com.android.systemui.util.wrapper.RotationPolicyWrapper;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@@ -39,19 +44,19 @@ import javax.inject.Inject;
|
|||||||
*/
|
*/
|
||||||
@SysUISingleton
|
@SysUISingleton
|
||||||
public final class DeviceStateRotationLockSettingController
|
public final class DeviceStateRotationLockSettingController
|
||||||
implements Listenable, RotationLockController.RotationLockControllerCallback {
|
implements Listenable, RotationLockController.RotationLockControllerCallback, Dumpable {
|
||||||
|
|
||||||
private static final String TAG = "DSRotateLockSettingCon";
|
|
||||||
|
|
||||||
private final RotationPolicyWrapper mRotationPolicyWrapper;
|
private final RotationPolicyWrapper mRotationPolicyWrapper;
|
||||||
private final DeviceStateManager mDeviceStateManager;
|
private final DeviceStateManager mDeviceStateManager;
|
||||||
private final Executor mMainExecutor;
|
private final Executor mMainExecutor;
|
||||||
private final DeviceStateRotationLockSettingsManager mDeviceStateRotationLockSettingsManager;
|
private final DeviceStateRotationLockSettingsManager mDeviceStateRotationLockSettingsManager;
|
||||||
|
private final DeviceStateRotationLockSettingControllerLogger mLogger;
|
||||||
|
|
||||||
// On registration for DeviceStateCallback, we will receive a callback with the current state
|
// On registration for DeviceStateCallback, we will receive a callback with the current state
|
||||||
// and this will be initialized.
|
// and this will be initialized.
|
||||||
private int mDeviceState = -1;
|
private int mDeviceState = -1;
|
||||||
@Nullable private DeviceStateManager.DeviceStateCallback mDeviceStateCallback;
|
@Nullable
|
||||||
|
private DeviceStateManager.DeviceStateCallback mDeviceStateCallback;
|
||||||
private DeviceStateRotationLockSettingsManager.DeviceStateRotationLockSettingsListener
|
private DeviceStateRotationLockSettingsManager.DeviceStateRotationLockSettingsListener
|
||||||
mDeviceStateRotationLockSettingsListener;
|
mDeviceStateRotationLockSettingsListener;
|
||||||
|
|
||||||
@@ -60,21 +65,27 @@ public final class DeviceStateRotationLockSettingController
|
|||||||
RotationPolicyWrapper rotationPolicyWrapper,
|
RotationPolicyWrapper rotationPolicyWrapper,
|
||||||
DeviceStateManager deviceStateManager,
|
DeviceStateManager deviceStateManager,
|
||||||
@Main Executor executor,
|
@Main Executor executor,
|
||||||
DeviceStateRotationLockSettingsManager deviceStateRotationLockSettingsManager) {
|
DeviceStateRotationLockSettingsManager deviceStateRotationLockSettingsManager,
|
||||||
|
DeviceStateRotationLockSettingControllerLogger logger,
|
||||||
|
DumpManager dumpManager) {
|
||||||
mRotationPolicyWrapper = rotationPolicyWrapper;
|
mRotationPolicyWrapper = rotationPolicyWrapper;
|
||||||
mDeviceStateManager = deviceStateManager;
|
mDeviceStateManager = deviceStateManager;
|
||||||
mMainExecutor = executor;
|
mMainExecutor = executor;
|
||||||
mDeviceStateRotationLockSettingsManager = deviceStateRotationLockSettingsManager;
|
mDeviceStateRotationLockSettingsManager = deviceStateRotationLockSettingsManager;
|
||||||
|
mLogger = logger;
|
||||||
|
dumpManager.registerDumpable(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setListening(boolean listening) {
|
public void setListening(boolean listening) {
|
||||||
|
mLogger.logListeningChange(listening);
|
||||||
if (listening) {
|
if (listening) {
|
||||||
// Note that this is called once with the initial state of the device, even if there
|
// Note that this is called once with the initial state of the device, even if there
|
||||||
// is no user action.
|
// is no user action.
|
||||||
mDeviceStateCallback = this::updateDeviceState;
|
mDeviceStateCallback = this::updateDeviceState;
|
||||||
mDeviceStateManager.registerCallback(mMainExecutor, mDeviceStateCallback);
|
mDeviceStateManager.registerCallback(mMainExecutor, mDeviceStateCallback);
|
||||||
mDeviceStateRotationLockSettingsListener = () -> readPersistedSetting(mDeviceState);
|
mDeviceStateRotationLockSettingsListener = () ->
|
||||||
|
readPersistedSetting("deviceStateRotationLockChange", mDeviceState);
|
||||||
mDeviceStateRotationLockSettingsManager.registerListener(
|
mDeviceStateRotationLockSettingsManager.registerListener(
|
||||||
mDeviceStateRotationLockSettingsListener);
|
mDeviceStateRotationLockSettingsListener);
|
||||||
} else {
|
} else {
|
||||||
@@ -89,35 +100,28 @@ public final class DeviceStateRotationLockSettingController
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRotationLockStateChanged(boolean rotationLocked, boolean affordanceVisible) {
|
public void onRotationLockStateChanged(boolean newRotationLocked, boolean affordanceVisible) {
|
||||||
if (mDeviceState == -1) {
|
int deviceState = mDeviceState;
|
||||||
Log.wtf(TAG, "Device state was not initialized.");
|
boolean currentRotationLocked = mDeviceStateRotationLockSettingsManager
|
||||||
|
.isRotationLocked(deviceState);
|
||||||
|
mLogger.logRotationLockStateChanged(deviceState, newRotationLocked, currentRotationLocked);
|
||||||
|
if (deviceState == -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (newRotationLocked == currentRotationLocked) {
|
||||||
if (rotationLocked
|
|
||||||
== mDeviceStateRotationLockSettingsManager.isRotationLocked(mDeviceState)) {
|
|
||||||
Log.v(TAG, "Rotation lock same as the current setting, no need to update.");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
saveNewRotationLockSetting(newRotationLocked);
|
||||||
saveNewRotationLockSetting(rotationLocked);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveNewRotationLockSetting(boolean isRotationLocked) {
|
private void saveNewRotationLockSetting(boolean isRotationLocked) {
|
||||||
Log.v(
|
int deviceState = mDeviceState;
|
||||||
TAG,
|
mLogger.logSaveNewRotationLockSetting(isRotationLocked, deviceState);
|
||||||
"saveNewRotationLockSetting [state="
|
mDeviceStateRotationLockSettingsManager.updateSetting(deviceState, isRotationLocked);
|
||||||
+ mDeviceState
|
|
||||||
+ "] [isRotationLocked="
|
|
||||||
+ isRotationLocked
|
|
||||||
+ "]");
|
|
||||||
|
|
||||||
mDeviceStateRotationLockSettingsManager.updateSetting(mDeviceState, isRotationLocked);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateDeviceState(int state) {
|
private void updateDeviceState(int state) {
|
||||||
Log.v(TAG, "updateDeviceState [state=" + state + "]");
|
mLogger.logUpdateDeviceState(mDeviceState, state);
|
||||||
if (Trace.isEnabled()) {
|
if (Trace.isEnabled()) {
|
||||||
Trace.traceBegin(
|
Trace.traceBegin(
|
||||||
Trace.TRACE_TAG_APP, "updateDeviceState [state=" + state + "]");
|
Trace.TRACE_TAG_APP, "updateDeviceState [state=" + state + "]");
|
||||||
@@ -127,22 +131,26 @@ public final class DeviceStateRotationLockSettingController
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
readPersistedSetting(state);
|
readPersistedSetting("updateDeviceState", state);
|
||||||
} finally {
|
} finally {
|
||||||
Trace.endSection();
|
Trace.endSection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readPersistedSetting(int state) {
|
private void readPersistedSetting(String caller, int state) {
|
||||||
int rotationLockSetting =
|
int rotationLockSetting =
|
||||||
mDeviceStateRotationLockSettingsManager.getRotationLockSetting(state);
|
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) {
|
if (rotationLockSetting == DEVICE_STATE_ROTATION_LOCK_IGNORED) {
|
||||||
// This should not happen. Device states that have an ignored setting, should also
|
// This should not happen. Device states that have an ignored setting, should also
|
||||||
// specify a fallback device state which is not ignored.
|
// specify a fallback device state which is not ignored.
|
||||||
// We won't handle this device state. The same rotation lock setting as before should
|
// 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
|
// apply and any changes to the rotation lock setting will be written for the previous
|
||||||
// valid device state.
|
// valid device state.
|
||||||
Log.w(TAG, "Missing fallback. Ignoring new device state: " + state);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,9 +158,18 @@ public final class DeviceStateRotationLockSettingController
|
|||||||
mDeviceState = state;
|
mDeviceState = state;
|
||||||
|
|
||||||
// Update the rotation policy, if needed, for this new device state
|
// Update the rotation policy, if needed, for this new device state
|
||||||
boolean newRotationLockSetting = rotationLockSetting == DEVICE_STATE_ROTATION_LOCK_LOCKED;
|
if (shouldBeLocked != isLocked) {
|
||||||
if (newRotationLockSetting != mRotationPolicyWrapper.isRotationLocked()) {
|
mRotationPolicyWrapper.setRotationLock(shouldBeLocked);
|
||||||
mRotationPolicyWrapper.setRotationLock(newRotationLockSetting);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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"
|
||||||
@@ -38,6 +38,7 @@ import com.android.internal.R;
|
|||||||
import com.android.internal.view.RotationPolicy;
|
import com.android.internal.view.RotationPolicy;
|
||||||
import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
|
import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
|
||||||
import com.android.systemui.SysuiTestCase;
|
import com.android.systemui.SysuiTestCase;
|
||||||
|
import com.android.systemui.dump.DumpManager;
|
||||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
import com.android.systemui.util.concurrency.FakeExecutor;
|
||||||
import com.android.systemui.util.time.FakeSystemClock;
|
import com.android.systemui.util.time.FakeSystemClock;
|
||||||
import com.android.systemui.util.wrapper.RotationPolicyWrapper;
|
import com.android.systemui.util.wrapper.RotationPolicyWrapper;
|
||||||
@@ -55,10 +56,12 @@ public class DeviceStateRotationLockSettingControllerTest extends SysuiTestCase
|
|||||||
|
|
||||||
private static final String[] DEFAULT_SETTINGS = new String[]{"0:1", "2:0:1", "1:2"};
|
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 FakeSystemClock mFakeSystemClock = new FakeSystemClock();
|
||||||
private final FakeExecutor mFakeExecutor = new FakeExecutor(mFakeSystemClock);
|
private final FakeExecutor mFakeExecutor = new FakeExecutor(mFakeSystemClock);
|
||||||
@Mock
|
|
||||||
private DeviceStateManager mDeviceStateManager;
|
|
||||||
private final RotationPolicyWrapper mFakeRotationPolicy = new FakeRotationPolicy();
|
private final RotationPolicyWrapper mFakeRotationPolicy = new FakeRotationPolicy();
|
||||||
private DeviceStateRotationLockSettingController mDeviceStateRotationLockSettingController;
|
private DeviceStateRotationLockSettingController mDeviceStateRotationLockSettingController;
|
||||||
private DeviceStateManager.DeviceStateCallback mDeviceStateCallback;
|
private DeviceStateManager.DeviceStateCallback mDeviceStateCallback;
|
||||||
@@ -78,7 +81,13 @@ public class DeviceStateRotationLockSettingControllerTest extends SysuiTestCase
|
|||||||
mSettingsManager = DeviceStateRotationLockSettingsManager.getInstance(mContext);
|
mSettingsManager = DeviceStateRotationLockSettingsManager.getInstance(mContext);
|
||||||
mDeviceStateRotationLockSettingController =
|
mDeviceStateRotationLockSettingController =
|
||||||
new DeviceStateRotationLockSettingController(
|
new DeviceStateRotationLockSettingController(
|
||||||
mFakeRotationPolicy, mDeviceStateManager, mFakeExecutor, mSettingsManager);
|
mFakeRotationPolicy,
|
||||||
|
mDeviceStateManager,
|
||||||
|
mFakeExecutor,
|
||||||
|
mSettingsManager,
|
||||||
|
mLogger,
|
||||||
|
mDumpManager
|
||||||
|
);
|
||||||
|
|
||||||
mDeviceStateRotationLockSettingController.setListening(true);
|
mDeviceStateRotationLockSettingController.setListening(true);
|
||||||
verify(mDeviceStateManager)
|
verify(mDeviceStateManager)
|
||||||
@@ -173,15 +182,11 @@ public class DeviceStateRotationLockSettingControllerTest extends SysuiTestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenDeviceStateSwitchedToIgnoredState_usePreviousSetting() {
|
public void whenDeviceStateSwitchedToIgnoredState_useFallbackSetting() {
|
||||||
initializeSettingsWith(
|
|
||||||
0, DEVICE_STATE_ROTATION_LOCK_IGNORED, 1, DEVICE_STATE_ROTATION_LOCK_UNLOCKED);
|
|
||||||
mFakeRotationPolicy.setRotationLock(true);
|
|
||||||
|
|
||||||
mDeviceStateCallback.onStateChanged(1);
|
|
||||||
assertThat(mFakeRotationPolicy.isRotationLocked()).isFalse();
|
|
||||||
|
|
||||||
mDeviceStateCallback.onStateChanged(0);
|
mDeviceStateCallback.onStateChanged(0);
|
||||||
|
assertThat(mFakeRotationPolicy.isRotationLocked()).isTrue();
|
||||||
|
|
||||||
|
mDeviceStateCallback.onStateChanged(2);
|
||||||
assertThat(mFakeRotationPolicy.isRotationLocked()).isFalse();
|
assertThat(mFakeRotationPolicy.isRotationLocked()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user