Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4ee98d28 authored by Shivangi Dubey's avatar Shivangi Dubey Committed by dshivangi
Browse files

Encapsulate handling of IGNORED device-postures under one entity

Encapsulate handling of IGNORED device-postures under DeviceStateAutoRotateSetting class.
DeviceStateAutoRotateSetting class has get and put methods to be able to access the settings.
The get and put methods under the hood handles IGNORED states and resolves the IGNORED posture to the fallback ones.
DeviceStateAutoRotateSetting to be used to exclusively represent device-state based auto-rotate setting instead of SparseIntArray.

After this change, there wont be an instance where there is a partially resolved device-state based auto-rotate setting.

Fixes: 427892786
Flag: com.android.window.flags.enable_device_state_auto_rotate_setting_refactor
Test: atest DeviceStateAutoRotateSettingManagerImplTest DeviceStateAutoRotateSettingControllerTest
Change-Id: I1a1d3cc774b5c91801e669bd8cab087d8061f46c
parent 153ef06a
Loading
Loading
Loading
Loading
+75 −36
Original line number Diff line number Diff line
@@ -19,8 +19,9 @@ package com.android.settingslib.devicestate;
import android.annotation.Discouraged;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.provider.Settings.Secure.DeviceStateRotationLockKey;
import android.provider.Settings.Secure.DeviceStateRotationLockSetting;
import android.util.Dumpable;
import android.util.SparseIntArray;

import java.util.List;

@@ -52,31 +53,6 @@ public interface DeviceStateAutoRotateSettingManager extends Dumpable {
     */
    void updateSetting(int deviceState, boolean rotationLock);

    /**
     * <p>
     * This method is exclusively for internal use by the
     * {@link com.android.server.wm.DeviceStateAutoRotateSettingController}.
     * </p>
     * <p>
     * Direct invocation by other clients can bypass crucial validation or business
     * logic, potentially leading to an inconsistent or corrupt settings state.
     * </p>
     * <p>
     * The designated API for updating settings is {@link #updateSetting(int, boolean)}. Please
     * use that method.
     * </p>
     *
     * @param proposedSetting Settings maps desired to be written into persisted setting.
     * @param currentSetting  Current settings map
     * @return Resolved proposedSetting map
     */
    @Discouraged(message = "This method is exclusively for internal use. The designated API for "
            + "updating settings is #updateSetting(int, boolean) in com.android.settingslib"
            + ".devicestate.DeviceStateAutoRotateSettingManager. Please use that method.")
    @NonNull
    SparseIntArray updateSetting(@NonNull SparseIntArray proposedSetting,
            @NonNull SparseIntArray currentSetting);

    /**
     * Get {@link DEVICE_STATE_ROTATION_LOCK} setting value for {@code deviceState}.
     * Note that the returned setting values in map are "resolved". This means that for device
@@ -92,23 +68,25 @@ public interface DeviceStateAutoRotateSettingManager extends Dumpable {
    Integer getRotationLockSetting(int deviceState);

    /**
     * Get {@link DEVICE_STATE_ROTATION_LOCK} setting value in form of integer to integer map.
     * Note that the returned setting values are "resolved". This means that for device states where
     * the auto-rotate setting is not user-settable, the value returned will be the same as the
     * value configured for its designated fallback posture.
     * Returns null if string value of {@link DEVICE_STATE_ROTATION_LOCK} is corrupted.
     * Get {@link DEVICE_STATE_ROTATION_LOCK} setting value in form of
     * {@link DeviceStateAutoRotateSetting}. Returns null if string value of
     * {@link DEVICE_STATE_ROTATION_LOCK} is corrupted.
     * <p>
     * If the value is null, system_server will shortly reset the value of
     * {@link DEVICE_STATE_ROTATION_LOCK}. Clients can either subscribe to setting changes or query
     * this API again after a brief delay.
     */
    @Nullable
    SparseIntArray getRotationLockSetting();
    DeviceStateAutoRotateSetting getRotationLockSetting();

    /**
     * Returns true if auto-rotate setting is OFF for {@code deviceState}. Returns null if string
     * value of {@link DEVICE_STATE_ROTATION_LOCK} is corrupted.
     * <p>
     * Note that the returned setting values in map are "resolved". This means that for device
     * states where the auto-rotate setting is not user-settable, the value returned will be the
     * same as the value configured for its designated fallback posture.
     * <p>
     * If the value is null, system_server will shortly reset the value of
     * {@link DEVICE_STATE_ROTATION_LOCK}. Clients can either subscribe to setting changes or query
     * this API again after a brief delay.
@@ -117,8 +95,8 @@ public interface DeviceStateAutoRotateSettingManager extends Dumpable {
    Boolean isRotationLocked(int deviceState);

    /**
     * Returns true if the auto-rotate setting value for all device states is OFF. Returns null if
     * string value of {@link DEVICE_STATE_ROTATION_LOCK} is corrupted.
     * Returns true if the auto-rotate setting value for all settable device states is OFF.
     * Returns null if string value of {@link DEVICE_STATE_ROTATION_LOCK} is corrupted.
     * <p>
     * If the value is null, system_server will shortly reset the value of
     * {@link DEVICE_STATE_ROTATION_LOCK}. Clients can either subscribe to setting changes or query
@@ -133,8 +111,69 @@ public interface DeviceStateAutoRotateSettingManager extends Dumpable {

    /**
     * Returns default value of {@link DEVICE_STATE_ROTATION_LOCK} setting from config, in form of
     * integer to integer map.
     * {@link DeviceStateAutoRotateSetting}.
     */
    @NonNull
    SparseIntArray getDefaultRotationLockSetting();
    DeviceStateAutoRotateSetting getDefaultRotationLockSetting();

    /**
     * Encapsulates device-state auto-rotate setting as a single entity.
     * This interface provides methods to get and set the auto-rotate preference for specific
     * device postures.
     * <p>
     * This object is guaranteed to never hold corrupted or invalid device-state based auto-rotate
     * setting.
     */
    interface DeviceStateAutoRotateSetting extends Cloneable {
        /**
         * Sets the auto-rotate setting for a specific device posture.
         *
         * @param devicePosture The device posture key.
         * @param autoRotate    The desired auto-rotate setting value.
         * @throws IllegalArgumentException if the device posture or auto-rotate value is invalid.
         * @throws IllegalStateException    if the fallback posture for an ignored posture is also
         *                                  ignored (chained fallback link is not supported).
         */
        void set(@DeviceStateRotationLockKey int devicePosture,
                @DeviceStateRotationLockSetting int autoRotate);

        /**
         * Gets the resolved auto-rotate setting for a specific device posture.
         * <p>
         * If the setting for the given {@code devicePosture} is
         * {@link Settings.Secure#DEVICE_STATE_ROTATION_LOCK_IGNORED},
         * this method returns the setting value of its designated fallback posture.
         * </p>
         *
         * @param devicePosture The device posture key.
         * @return true if auto-rotate is unlocked for the resolved setting, false if locked.
         * @throws IllegalArgumentException if the device posture is invalid.
         * @throws IllegalStateException    if the fallback posture for an ignored posture is also
         *                                  ignored (chained fallback link is not supported).
         */
        boolean get(@DeviceStateRotationLockKey int devicePosture);

        /**
         * Write device state auto rotate setting stored in this object into persisted setting.
         * <p>
         * This method is exclusively for internal use by the
         * {@link com.android.server.wm.DeviceStateAutoRotateSettingController}.
         * </p>
         * <p>
         * Direct invocation by other clients can bypass crucial validation or business
         * logic, potentially leading to an inconsistent or corrupt settings state.
         * </p>
         * <p>
         * The designated API for updating settings is {@link #updateSetting(int, boolean)}. Please
         * use that method.
         */
        @Discouraged(message = "This method is exclusively for internal use. The designated API for"
                + " updating settings is #updateSetting(int, boolean) in com.android.settingslib."
                + "devicestate.DeviceStateAutoRotateSettingManager. Please use that method.")
        void write();

        /** Returns a deep copy of this {@link DeviceStateAutoRotateSetting} object. */
        @NonNull
        DeviceStateAutoRotateSetting clone();
    }
}
+224 −208

File changed.

Preview size limit exceeded, changes collapsed.

+10 −16
Original line number Diff line number Diff line
@@ -140,20 +140,12 @@ public final class DeviceStateRotationLockSettingsManager implements
    }

    @Override
    @NonNull
    public SparseIntArray updateSetting(@NonNull SparseIntArray proposedSetting,
            @NonNull SparseIntArray currentSetting) {
        // This method is not supported in this implementation. Use updateSetting(int, boolean)
        // instead. This overload is intended for a refactored settings manager.
    public DeviceStateAutoRotateSetting getRotationLockSetting() {
        // This method is not supported in this implementation.
        throw new UnsupportedOperationException(
                "This API is only support by refactored settings manager.");
    }

    @Override
    public SparseIntArray getRotationLockSetting() {
        return mPostureRotationLockSettings.clone();
    }

    /**
     * Returns the {@link Settings.Secure.DeviceStateRotationLockSetting} for the given device
     * state.
@@ -217,12 +209,6 @@ public final class DeviceStateRotationLockSettingsManager implements
        return new ArrayList<>(mSettableDeviceStates);
    }

    @NonNull
    @Override
    public SparseIntArray getDefaultRotationLockSetting() {
        return mPostureDefaultRotationLockSettings.clone();
    }

    private void initializeInMemoryMap() {
        String serializedSetting = getPersistedSettingValue();
        if (TextUtils.isEmpty(serializedSetting)) {
@@ -263,6 +249,14 @@ public final class DeviceStateRotationLockSettingsManager implements
        }
    }

    @NonNull
    @Override
    public DeviceStateAutoRotateSetting getDefaultRotationLockSetting() {
        // This method is not supported in this implementation.
        throw new UnsupportedOperationException(
                "This API is only support by refactored settings manager.");
    }

    /**
     * Resets the state of the class and saved settings back to the default values provided by the
     * resources config.
+247 −169

File changed.

Preview size limit exceeded, changes collapsed.

+11 −3
Original line number Diff line number Diff line
@@ -35,7 +35,6 @@ import android.hardware.devicestate.DeviceState;
import android.hardware.devicestate.DeviceStateManager;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.SparseIntArray;

import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
@@ -193,10 +192,19 @@ public class DeviceStateRotationLockSettingsManagerTest {
    }

    @Test
    public void updateSettingMap_throwsUnsupportedOperationException() {
    public void getDefaultRotationLockSetting_throwsUnsupportedOperationException() {
        final UnsupportedOperationException exception = assertThrows(
                UnsupportedOperationException.class,
                () -> mManager.updateSetting(new SparseIntArray(), new SparseIntArray()));
                () -> mManager.getDefaultRotationLockSetting());
        assertThat(exception.getMessage()).isEqualTo(
                "This API is only support by refactored settings manager.");
    }

    @Test
    public void getRotationLockSetting_throwsUnsupportedOperationException() {
        final UnsupportedOperationException exception = assertThrows(
                UnsupportedOperationException.class,
                () -> mManager.getRotationLockSetting());
        assertThat(exception.getMessage()).isEqualTo(
                "This API is only support by refactored settings manager.");
    }
Loading