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

Commit 03044389 authored by Santos Cordon's avatar Santos Cordon
Browse files

Hold Display Suspend blocker when going to Doze

The transition to Doze is asynchronous from the release of the display
suspend blocker.  This created a race condition where we could
potentially suspend before Doze service had a chance to transition to
Doze. This change holds the Display Suspend blocker until Doze service
acquires the DOZE lock.

Bug: 138828701
Test: atest PowerManagerService
Test: Manual, verify no repro of the bug.  Additional verify the device
does release the Display suspend blocker once we are in DOZE.

Change-Id: I777bc7963b1ab445378164b0f4d3f79113510b81
parent c854ee68
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -542,6 +542,10 @@ public final class PowerManagerService extends SystemService
    // True if we in the process of performing a forceSuspend
    private boolean mForceSuspendActive;

    // Transition to Doze is in progress.  We have transitioned to WAKEFULNESS_DOZING,
    // but the DreamService has not yet been told to start (it's an async process).
    private boolean mDozeStartInProgress;

    private final class ForegroundProfileObserver extends SynchronousUserSwitchObserver {
        @Override
        public void onUserSwitching(int newUserId) throws RemoteException {}
@@ -1514,6 +1518,7 @@ public final class PowerManagerService extends SystemService
            mLastSleepTime = eventTime;
            mLastSleepReason = reason;
            mSandmanSummoned = true;
            mDozeStartInProgress = true;
            setWakefulnessLocked(WAKEFULNESS_DOZING, reason, eventTime);

            // Report the number of wake locks that will be cleared by going to sleep.
@@ -1601,6 +1606,10 @@ public final class PowerManagerService extends SystemService
            mWakefulness = wakefulness;
            mWakefulnessChanging = true;
            mDirty |= DIRTY_WAKEFULNESS;

            // This is only valid while we are in wakefulness dozing. Set to false otherwise.
            mDozeStartInProgress &= (mWakefulness == WAKEFULNESS_DOZING);

            if (mNotifier != null) {
                mNotifier.onWakefulnessChangeStarted(wakefulness, reason, eventTime);
            }
@@ -1631,6 +1640,9 @@ public final class PowerManagerService extends SystemService
            if (mWakefulness == WAKEFULNESS_DOZING
                    && (mWakeLockSummary & WAKE_LOCK_DOZE) == 0) {
                return; // wait until dream has enabled dozing
            } else {
                // Doze wakelock acquired (doze started) or device is no longer dozing.
                mDozeStartInProgress = false;
            }
            if (mWakefulness == WAKEFULNESS_DOZING || mWakefulness == WAKEFULNESS_ASLEEP) {
                logSleepTimeoutRecapturedLocked();
@@ -2309,6 +2321,10 @@ public final class PowerManagerService extends SystemService
            isDreaming = false;
        }

        // At this point, we either attempted to start the dream or no attempt will be made,
        // so stop holding the display suspend blocker for Doze.
        mDozeStartInProgress = false;

        // Update dream state.
        synchronized (mLock) {
            // Remember the initial battery level when the dream started.
@@ -2735,6 +2751,16 @@ public final class PowerManagerService extends SystemService
        if (mScreenBrightnessBoostInProgress) {
            return true;
        }

        // When we transition to DOZING, we have to keep the display suspend blocker
        // up until the Doze service has a change to acquire the DOZE wakelock.
        // Here we wait for mWakefulnessChanging to become false since the wakefulness
        // transition to DOZING isn't considered "changed" until the doze wake lock is
        // acquired.
        if (mWakefulness == WAKEFULNESS_DOZING && mDozeStartInProgress) {
            return true;
        }

        // Let the system suspend if the screen is off or dozing.
        return false;
    }