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

Commit 4fbab201 authored by Robert Horvath's avatar Robert Horvath
Browse files

Go to sleep on boot when booting in quiescent mode

In quiescent mode, the display is forced to be off.
But the device was still in an awake state, even though the display was
off, leading to some unexpected behaviours.
For example, the device considers itself interactive, which it normally
doesn't when the display is off. Due to that, a power button press would
put the device to sleep, instead of coming out of quiescent mode and
turning the display on.

With this change, the device goes to sleep after boot is completed
if quiescent mode is set, and the quiescent flag is cleared when waking up.
On a wakeup the display will turn on as expected.

Bug: 145265927
Test: Reboot in quiescent mode (`adb reboot quiescent`),
      connect remote, press power button.
      Expected result: device wakes up, display turns on
Test: atest PowerManagerServiceTest

Change-Id: Id3fca6fa9fcf77da989ecb764e1380e21be0e041
parent bd15451f
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -432,9 +432,15 @@ public final class PowerManager {
    public static final int GO_TO_SLEEP_REASON_INATTENTIVE = 9;

    /**
     * Go to sleep reason code: Going to sleep due to quiescent boot.
     * @hide
     */
    public static final int GO_TO_SLEEP_REASON_MAX = GO_TO_SLEEP_REASON_INATTENTIVE;
    public static final int GO_TO_SLEEP_REASON_QUIESCENT = 10;

    /**
     * @hide
     */
    public static final int GO_TO_SLEEP_REASON_MAX = GO_TO_SLEEP_REASON_QUIESCENT;

    /**
     * @hide
+14 −3
Original line number Diff line number Diff line
@@ -678,9 +678,20 @@ public class Notifier {
        final int powerState;
        synchronized (mLock) {
            if (mBroadcastedInteractiveState == INTERACTIVE_STATE_UNKNOWN) {
                // Broadcasted power state is unknown.  Send wake up.
                // Broadcasted power state is unknown.
                // Send wake up or go to sleep.
                switch (mPendingInteractiveState) {
                    case INTERACTIVE_STATE_ASLEEP:
                        mPendingGoToSleepBroadcast = false;
                        mBroadcastedInteractiveState = INTERACTIVE_STATE_ASLEEP;
                        break;

                    case INTERACTIVE_STATE_AWAKE:
                    default:
                        mPendingWakeUpBroadcast = false;
                        mBroadcastedInteractiveState = INTERACTIVE_STATE_AWAKE;
                        break;
                }
            } else if (mBroadcastedInteractiveState == INTERACTIVE_STATE_AWAKE) {
                // Broadcasted power state is awake.  Send asleep if needed.
                if (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
+20 −8
Original line number Diff line number Diff line
@@ -347,6 +347,7 @@ public final class PowerManagerService extends SystemService
    private boolean mSystemReady;

    // True if boot completed occurred. We keep the screen on until this happens.
    // The screen will be off if we are in quiescent mode.
    private boolean mBootCompleted;

    // True if auto-suspend mode is enabled.
@@ -864,6 +865,12 @@ public final class PowerManagerService extends SystemService
                mBatterySaverStateMachine.onBootCompleted();
                userActivityNoUpdateLocked(
                        now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);

                if (sQuiescent) {
                    goToSleepNoUpdateLocked(SystemClock.uptimeMillis(),
                            PowerManager.GO_TO_SLEEP_REASON_QUIESCENT,
                            PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE, Process.SYSTEM_UID);
                }
                updatePowerStateLocked();
            }
        }
@@ -1430,8 +1437,7 @@ public final class PowerManagerService extends SystemService
                    + ", uid=" + uid);
        }

        if (eventTime < mLastSleepTime || eventTime < mLastWakeTime
                || !mBootCompleted || !mSystemReady) {
        if (eventTime < mLastSleepTime || eventTime < mLastWakeTime || !mSystemReady) {
            return false;
        }

@@ -1508,7 +1514,7 @@ public final class PowerManagerService extends SystemService
        }

        if (eventTime < mLastSleepTime || mWakefulness == WAKEFULNESS_AWAKE
                || !mBootCompleted || !mSystemReady || mForceSuspendActive) {
                || mForceSuspendActive || !mSystemReady) {
            return false;
        }

@@ -1530,6 +1536,10 @@ public final class PowerManagerService extends SystemService
            mNotifier.onWakeUp(reason, details, reasonUid, opPackageName, opUid);
            userActivityNoUpdateLocked(
                    eventTime, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, reasonUid);

            if (sQuiescent) {
                mDirty |= DIRTY_QUIESCENT;
            }
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_POWER);
        }
@@ -1561,7 +1571,8 @@ public final class PowerManagerService extends SystemService
        if (eventTime < mLastWakeTime
                || mWakefulness == WAKEFULNESS_ASLEEP
                || mWakefulness == WAKEFULNESS_DOZING
                || !mBootCompleted || !mSystemReady) {
                || !mSystemReady
                || !mBootCompleted) {
            return false;
        }

@@ -2645,6 +2656,10 @@ public final class PowerManagerService extends SystemService
                | DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED
                | DIRTY_SETTINGS | DIRTY_SCREEN_BRIGHTNESS_BOOST | DIRTY_VR_MODE_CHANGED |
                DIRTY_QUIESCENT)) != 0) {
            if ((dirty & DIRTY_QUIESCENT) != 0) {
                sQuiescent = false;
            }

            mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked();

            // Determine appropriate screen brightness and auto-brightness adjustments.
@@ -2694,9 +2709,6 @@ public final class PowerManagerService extends SystemService
                    mRequestWaitForNegativeProximity);
            mRequestWaitForNegativeProximity = false;

            if ((dirty & DIRTY_QUIESCENT) != 0) {
                sQuiescent = false;
            }
            if (DEBUG_SPEW) {
                Slog.d(TAG, "updateDisplayPowerStateLocked: mDisplayReady=" + mDisplayReady
                        + ", policy=" + mDisplayPowerRequest.policy
+52 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
@@ -752,4 +753,55 @@ public class PowerManagerServiceTest {
        SystemClock.sleep(11);
        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
    }

    @Test
    public void testBoot_ShouldBeAwake() throws Exception {
        createService();
        startSystem();

        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
        verify(mNotifierMock, never()).onWakefulnessChangeStarted(anyInt(), anyInt(), anyLong());
    }

    @Test
    public void testBoot_DesiredScreenPolicyShouldBeBright() throws Exception {
        createService();
        startSystem();

        assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
                DisplayPowerRequest.POLICY_BRIGHT);
    }

    @Test
    public void testQuiescentBoot_ShouldBeAsleep() throws Exception {
        when(mSystemPropertiesMock.get(eq(SYSTEM_PROPERTY_QUIESCENT), any())).thenReturn("1");
        createService();
        startSystem();

        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
        verify(mNotifierMock).onWakefulnessChangeStarted(eq(WAKEFULNESS_ASLEEP), anyInt(),
                anyLong());
    }

    @Test
    public void testQuiescentBoot_DesiredScreenPolicyShouldBeOff() throws Exception {
        when(mSystemPropertiesMock.get(eq(SYSTEM_PROPERTY_QUIESCENT), any())).thenReturn("1");
        createService();
        assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
                DisplayPowerRequest.POLICY_OFF);

        startSystem();
        assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
                DisplayPowerRequest.POLICY_OFF);
    }

    @Test
    public void testQuiescentBoot_WakeUp_DesiredScreenPolicyShouldBeBright() throws Exception {
        when(mSystemPropertiesMock.get(eq(SYSTEM_PROPERTY_QUIESCENT), any())).thenReturn("1");
        createService();
        startSystem();
        forceAwake();
        assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
                DisplayPowerRequest.POLICY_BRIGHT);
    }
}