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

Commit 5747d1a5 authored by Michael Wright's avatar Michael Wright
Browse files

Release outstanding suspend blockers when shutting down DPC

Right now DPC removes all messages but doesn't actually clean up all of
the outstanding state that's in flight. In general, this isn't that
harmful for most things as the display is going away at this point, but
if any suspend blockers are being held pending this work then we end up
in a state where the device can never suspend. This causes severe
battery drain that can only be fixed by a reboot.

Test: manual
Fixes: 213407479
Change-Id: I5b61f5bd498f09026d5b398bb3a8ccdaa91601fe
parent a637f955
Loading
Loading
Loading
Loading
+39 −2
Original line number Diff line number Diff line
@@ -461,6 +461,18 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call

    private boolean mIsRbcActive;

    // Whether there's a callback to tell listeners the display has changed scheduled to run. When
    // true it implies a wakelock is being held to guarantee the update happens before we collapse
    // into suspend and so needs to be cleaned up if the thread is exiting.
    // Should only be accessed on the Handler thread.
    private boolean mOnStateChangedPending;

    // Count of proximity messages currently on this DPC's Handler. Used to keep track of how many
    // suspend blocker acquisitions are pending when shutting down this DPC.
    // Should only be accessed on the Handler thread.
    private int mOnProximityPositiveMessages;
    private int mOnProximityNegativeMessages;

    // Animators.
    private ObjectAnimator mColorFadeOnAnimator;
    private ObjectAnimator mColorFadeOffAnimator;
@@ -1091,10 +1103,24 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        mHbmController.stop();
        mBrightnessThrottler.stop();
        mHandler.removeCallbacksAndMessages(null);

        // Release any outstanding wakelocks we're still holding because of pending messages.
        if (mUnfinishedBusiness) {
            mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdUnfinishedBusiness);
            mUnfinishedBusiness = false;
        }
        if (mOnStateChangedPending) {
            mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdOnStateChanged);
            mOnStateChangedPending = false;
        }
        for (int i = 0; i < mOnProximityPositiveMessages; i++) {
            mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdProxPositive);
        }
        mOnProximityPositiveMessages = 0;
        for (int i = 0; i < mOnProximityNegativeMessages; i++) {
            mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdProxNegative);
        }
        mOnProximityNegativeMessages = 0;

        final float brightness = mPowerState != null
            ? mPowerState.getScreenBrightness()
@@ -2248,9 +2274,12 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
    }

    private void sendOnStateChangedWithWakelock() {
        if (!mOnStateChangedPending) {
            mOnStateChangedPending = true;
            mCallbacks.acquireSuspendBlocker(mSuspendBlockerIdOnStateChanged);
            mHandler.post(mOnStateChangedRunnable);
        }
    }

    private void logDisplayPolicyChanged(int newPolicy) {
        LogMaker log = new LogMaker(MetricsEvent.DISPLAY_POLICY);
@@ -2408,6 +2437,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
    private final Runnable mOnStateChangedRunnable = new Runnable() {
        @Override
        public void run() {
            mOnStateChangedPending = false;
            mCallbacks.onStateChanged();
            mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdOnStateChanged);
        }
@@ -2416,17 +2446,20 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
    private void sendOnProximityPositiveWithWakelock() {
        mCallbacks.acquireSuspendBlocker(mSuspendBlockerIdProxPositive);
        mHandler.post(mOnProximityPositiveRunnable);
        mOnProximityPositiveMessages++;
    }

    private final Runnable mOnProximityPositiveRunnable = new Runnable() {
        @Override
        public void run() {
            mOnProximityPositiveMessages--;
            mCallbacks.onProximityPositive();
            mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdProxPositive);
        }
    };

    private void sendOnProximityNegativeWithWakelock() {
        mOnProximityNegativeMessages++;
        mCallbacks.acquireSuspendBlocker(mSuspendBlockerIdProxNegative);
        mHandler.post(mOnProximityNegativeRunnable);
    }
@@ -2434,6 +2467,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
    private final Runnable mOnProximityNegativeRunnable = new Runnable() {
        @Override
        public void run() {
            mOnProximityNegativeMessages--;
            mCallbacks.onProximityNegative();
            mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdProxNegative);
        }
@@ -2533,6 +2567,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        pw.println("  mReportedToPolicy="
                + reportedToPolicyToString(mReportedScreenStateToPolicy));
        pw.println("  mIsRbcActive=" + mIsRbcActive);
        pw.println("  mOnStateChangePending=" + mOnStateChangedPending);
        pw.println("  mOnProximityPositiveMessages=" + mOnProximityPositiveMessages);
        pw.println("  mOnProximityNegativeMessages=" + mOnProximityNegativeMessages);

        if (mScreenBrightnessRampAnimator != null) {
            pw.println("  mScreenBrightnessRampAnimator.isAnimating()="