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

Commit cde4801c authored by Hongguang Chen's avatar Hongguang Chen
Browse files

Add new power button behavior that starts or stops dream or sleep

Bug: 402759931
Test: atest PhoneWindowManagerTests
Test: manually verified on device
Flag: NONE. This new behavior doesn't touch existing code.
Change-Id: I4f96421999f81a90b168b922f0a9a8eab4456b7f
parent dafada72
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1219,6 +1219,8 @@
            6 - Lock if keyguard enabled or go to sleep (doze)
            7 - Dream if possible or go to sleep (doze)
            8 - Go to glanceable hub or dream if possible, or sleep if neither is available (doze)
            9 - Go to dream if device is not dreaming, stop dream if device is dreaming, or sleep if
                neither is available (doze)
    -->
    <integer name="config_shortPressOnPowerBehavior">1</integer>

+40 −10
Original line number Diff line number Diff line
@@ -311,6 +311,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    static final int SHORT_PRESS_POWER_LOCK_OR_SLEEP = 6;
    static final int SHORT_PRESS_POWER_DREAM_OR_SLEEP = 7;
    static final int SHORT_PRESS_POWER_HUB_OR_DREAM_OR_SLEEP = 8;
    static final int SHORT_PRESS_POWER_DREAM_OR_AWAKE_OR_SLEEP = 9;

    // must match: config_LongPressOnPowerBehavior in config.xml
    // The config value can be overridden using Settings.Global.POWER_BUTTON_LONG_PRESS
@@ -1234,8 +1235,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                    break;
                }
                case SHORT_PRESS_POWER_DREAM_OR_SLEEP: {
                    attemptToDreamFromShortPowerButtonPress(
                            true,
                    attemptToDreamOrAwakeFromShortPowerButtonPress(
                            /* isScreenOn */ true,
                            /* awakeWhenDream */ false,
                            /* noDreamAction */
                            () -> sleepDefaultDisplayFromPowerButton(eventTime, 0));
                    break;
                }
@@ -1269,13 +1272,22 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                        lockNow(options);
                    } else {
                        // If the hub cannot be run, attempt to dream instead.
                        attemptToDreamFromShortPowerButtonPress(
                        attemptToDreamOrAwakeFromShortPowerButtonPress(
                                /* isScreenOn */ true,
                                /* awakeWhenDream */ false,
                                /* noDreamAction */
                                () -> sleepDefaultDisplayFromPowerButton(eventTime, 0));
                    }
                    break;
                }
                case SHORT_PRESS_POWER_DREAM_OR_AWAKE_OR_SLEEP: {
                    attemptToDreamOrAwakeFromShortPowerButtonPress(
                            /* isScreenOn */ true,
                            /* awakeWhenDream */ true,
                            /* noDreamAction */
                            () -> sleepDefaultDisplayFromPowerButton(eventTime, 0));
                    break;
                }
            }
        }
    }
@@ -1319,15 +1331,18 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    }

    /**
     * Attempt to dream from a power button press.
     * Attempt to dream, awake or sleep from a power button press.
     *
     * @param isScreenOn Whether the screen is currently on.
     * @param awakeWhenDream When it's set to {@code true}, awake the device from dreaming.
     *        Otherwise, go to sleep.
     * @param noDreamAction The action to perform if dreaming is not possible.
     */
    private void attemptToDreamFromShortPowerButtonPress(
            boolean isScreenOn, Runnable noDreamAction) {
    private void attemptToDreamOrAwakeFromShortPowerButtonPress(
            boolean isScreenOn, boolean awakeWhenDream, Runnable noDreamAction) {
        if (mShortPressOnPowerBehavior != SHORT_PRESS_POWER_DREAM_OR_SLEEP
                && mShortPressOnPowerBehavior != SHORT_PRESS_POWER_HUB_OR_DREAM_OR_SLEEP) {
                && mShortPressOnPowerBehavior != SHORT_PRESS_POWER_HUB_OR_DREAM_OR_SLEEP
                && mShortPressOnPowerBehavior != SHORT_PRESS_POWER_DREAM_OR_AWAKE_OR_SLEEP) {
            // If the power button behavior isn't one that should be able to trigger the dream, give
            // up.
            noDreamAction.run();
@@ -1335,9 +1350,24 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        }

        final DreamManagerInternal dreamManagerInternal = getDreamManagerInternal();
        if (dreamManagerInternal == null || !dreamManagerInternal.canStartDreaming(isScreenOn)) {
            Slog.d(TAG, "Can't start dreaming when attempting to dream from short power"
                    + " press (isScreenOn=" + isScreenOn + ")");
        if (dreamManagerInternal == null) {
            Slog.d(TAG,
                    "Can't access dream manager dreaming when attempting to start or stop dream "
                    + "from short power press (isScreenOn="
                            + isScreenOn + ", awakeWhenDream=" + awakeWhenDream + ")");
            noDreamAction.run();
            return;
        }

        if (!dreamManagerInternal.canStartDreaming(isScreenOn)) {
            if (awakeWhenDream && dreamManagerInternal.isDreaming()) {
                dreamManagerInternal.stopDream(false /*immediate*/, "short press power" /*reason*/);
                return;
            }
            Slog.d(TAG,
                    "Can't start dreaming and the device is not dreaming when attempting to start "
                    + "or stop dream from short power press (isScreenOn="
                            + isScreenOn + ", awakeWhenDream=" + awakeWhenDream + ")");
            noDreamAction.run();
            return;
        }
+72 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
import static com.android.server.policy.PhoneWindowManager.EXTRA_TRIGGER_HUB;
import static com.android.server.policy.PhoneWindowManager.SHORT_PRESS_POWER_DREAM_OR_AWAKE_OR_SLEEP;
import static com.android.server.policy.PhoneWindowManager.SHORT_PRESS_POWER_HUB_OR_DREAM_OR_SLEEP;

import static com.google.common.truth.Truth.assertThat;
@@ -322,6 +323,77 @@ public class PhoneWindowManagerTests {
        verify(mDreamManagerInternal).requestDream();
    }

    @Test
    public void powerPress_dreamOrAwakeOrSleep_awakeFromDream() {
        when(mDisplayPolicy.isAwake()).thenReturn(true);
        initPhoneWindowManager();

        // Set power button behavior.
        Settings.Global.putInt(mContext.getContentResolver(),
                Settings.Global.POWER_BUTTON_SHORT_PRESS,
                SHORT_PRESS_POWER_DREAM_OR_AWAKE_OR_SLEEP);
        mPhoneWindowManager.updateSettings(null);

        // Can not dream when device is dreaming.
        when(mDreamManagerInternal.canStartDreaming(any(Boolean.class))).thenReturn(false);
        // Device is dreaming.
        when(mDreamManagerInternal.isDreaming()).thenReturn(true);

        // Power button pressed.
        int eventTime = 0;
        mPhoneWindowManager.powerPress(eventTime, 1, 0);

        // Dream is stopped.
        verify(mDreamManagerInternal)
                .stopDream(false /*immediate*/, "short press power" /*reason*/);
    }

    @Test
    public void powerPress_dreamOrAwakeOrSleep_canNotDreamGoToSleep() {
        when(mDisplayPolicy.isAwake()).thenReturn(true);
        initPhoneWindowManager();

        // Set power button behavior.
        Settings.Global.putInt(mContext.getContentResolver(),
                Settings.Global.POWER_BUTTON_SHORT_PRESS,
                SHORT_PRESS_POWER_DREAM_OR_AWAKE_OR_SLEEP);
        mPhoneWindowManager.updateSettings(null);

        // Can not dream for other reasons.
        when(mDreamManagerInternal.canStartDreaming(any(Boolean.class))).thenReturn(false);
        // Device is not dreaming.
        when(mDreamManagerInternal.isDreaming()).thenReturn(false);

        // Power button pressed.
        int eventTime = 0;
        mPhoneWindowManager.powerPress(eventTime, 1, 0);

        // Device goes to sleep.
        verify(mPowerManager).goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
    }

    @Test
    public void powerPress_dreamOrAwakeOrSleep_dreamFromActive() {
        when(mDisplayPolicy.isAwake()).thenReturn(true);
        initPhoneWindowManager();

        // Set power button behavior.
        Settings.Global.putInt(mContext.getContentResolver(),
                Settings.Global.POWER_BUTTON_SHORT_PRESS,
                SHORT_PRESS_POWER_DREAM_OR_AWAKE_OR_SLEEP);
        mPhoneWindowManager.updateSettings(null);

        // Can dream when active.
        when(mDreamManagerInternal.canStartDreaming(any(Boolean.class))).thenReturn(true);

        // Power button pressed.
        int eventTime = 0;
        mPhoneWindowManager.powerPress(eventTime, 1, 0);

        // Dream is requested.
        verify(mDreamManagerInternal).requestDream();
    }

    private void initPhoneWindowManager() {
        mPhoneWindowManager.mDefaultDisplayPolicy = mDisplayPolicy;
        mPhoneWindowManager.mDefaultDisplayRotation = mock(DisplayRotation.class);