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

Commit c3e6af87 authored by Michael Wright's avatar Michael Wright
Browse files

Report the display is off when the hardware blanks itself.

Some hardware will blank itself coming out of doze to avoid artifacts
from being shown. In order to perform a graceful transition from doze to
on, tell window manager policy that the display turned off and then
turned on without actually telling the display to enter the off state,
in order to keep the screen on latency low.

Bug: 63531607
Test: manual
Change-Id: I4362905e47d5fb47b639c8701c91d69b50aa1232
parent a6eed85c
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -1889,9 +1889,8 @@
         states. -->
    <bool name="config_dozeAlwaysOnDisplayAvailable">false</bool>

    <!-- Whether the display hardware requires we go to the off state before transitioning
         out of any doze states. -->
    <bool name="config_displayTransitionOffAfterDoze">false</bool>
    <!-- Whether the display blanks itself when transitioning from a doze to a non-doze state -->
    <bool name="config_displayBlanksAfterDoze">false</bool>


    <!-- Power Management: Specifies whether to decouple the auto-suspend state of the
+1 −1
Original line number Diff line number Diff line
@@ -3038,7 +3038,7 @@
  <java-symbol type="bool" name="config_handleVolumeKeysInWindowManager" />
  <java-symbol type="integer" name="config_inCallNotificationVolumeRelative" />
  <java-symbol type="bool" name="config_dozeAlwaysOnDisplayAvailable" />
  <java-symbol type="bool" name="config_displayTransitionOffAfterDoze" />
  <java-symbol type="bool" name="config_displayBlanksAfterDoze" />
  <java-symbol type="integer" name="config_storageManagerDaystoRetainDefault" />
  <java-symbol type="string" name="config_headlineFontFamily" />
  <java-symbol type="string" name="config_headlineFontFamilyLight" />
+41 −38
Original line number Diff line number Diff line
@@ -169,11 +169,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
    // a stylish color fade animation instead.
    private boolean mColorFadeFadesConfig;

    // True if we need to transition to the off state when coming out of a doze state.
    // Some display hardware will show artifacts (flickers, etc) when transitioning from a doze
    // to a fully on state. In order to hide these, we first transition to off to let the system
    // animate the screen on as it normally would, which is a much smoother experience.
    private boolean mTransitionOffAfterDozeConfig;
    // True if we need to fake a transition to off when coming out of a doze state.
    // Some display hardware will blank itself when coming out of doze in order to hide
    // artifacts. For these displays we fake a transition into OFF so that policy can appropriately
    // blank itself and begin an appropriate power on animation.
    private boolean mDisplayBlanksAfterDozeConfig;

    // The pending power request.
    // Initially null until the first call to requestPowerState.
@@ -422,8 +422,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        mColorFadeFadesConfig = resources.getBoolean(
                com.android.internal.R.bool.config_animateScreenLights);

        mTransitionOffAfterDozeConfig = resources.getBoolean(
                com.android.internal.R.bool.config_displayTransitionOffAfterDoze);
        mDisplayBlanksAfterDozeConfig = resources.getBoolean(
                com.android.internal.R.bool.config_displayBlanksAfterDoze);

        if (!DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) {
            mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
@@ -811,7 +811,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        // Notify policy about screen turned on.
        if (ready && state != Display.STATE_OFF
                && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_ON) {
            mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_ON;
            setReportedScreenState(REPORTED_TO_POLICY_SCREEN_ON);
            mWindowManagerPolicy.screenTurnedOn();
        }

@@ -894,10 +894,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
    }

    private boolean setScreenState(int state) {
        return setScreenState(state, false /*force*/);
        return setScreenState(state, false /*reportOnly*/);
    }

    private boolean setScreenState(int state, boolean force) {
    private boolean setScreenState(int state, boolean reportOnly) {
        final boolean isOff = (state == Display.STATE_OFF);
        if (mPowerState.getScreenState() != state) {

@@ -905,27 +905,18 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
            // actually turn the screen off.
            if (isOff && !mScreenOffBecauseOfProximity) {
                if (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_ON) {
                    mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_TURNING_OFF;
                    setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_OFF);
                    blockScreenOff();
                    mWindowManagerPolicy.screenTurningOff(mPendingScreenOffUnblocker);
                    if (force) {
                        // If we're forcing the power state transition then immediately
                        // unblock the screen off event. This keeps the lifecycle consistent,
                        // so WindowManagerPolicy will always see screenTurningOff before
                        // screenTurnedOff, but we don't actually block on them for the state
                        // change.
                    unblockScreenOff();
                    } else {
                        return false;
                    }
                } else if (mPendingScreenOffUnblocker != null) {
                    // Abort doing the state change until screen off is unblocked.
                    return false;
                }
            }

            if (!reportOnly) {
                mPowerState.setScreenState(state);

                // Tell battery stats about the transition.
                try {
                    mBatteryStats.noteScreenState(state);
@@ -933,6 +924,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
                    // same process
                }
            }
        }

        // Tell the window manager policy when the screen is turned off or on unless it's due
        // to the proximity sensor.  We temporarily block turning the screen on until the
@@ -942,7 +934,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        // finished drawing underneath.
        if (isOff && mReportedScreenStateToPolicy != REPORTED_TO_POLICY_SCREEN_OFF
                && !mScreenOffBecauseOfProximity) {
            mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_OFF;
            setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
            unblockScreenOn();
            mWindowManagerPolicy.screenTurnedOff();
        } else if (!isOff
@@ -952,10 +944,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
            // Complete the full state transition on -> turningOff -> off.
            unblockScreenOff();
            mWindowManagerPolicy.screenTurnedOff();
            mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_OFF;
            setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
        }
        if (!isOff && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF) {
            mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_TURNING_ON;
            setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_ON);
            if (mPowerState.getColorFadeLevel() == 0.0f) {
                blockScreenOn();
            } else {
@@ -968,6 +960,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        return mPendingScreenOnUnblocker == null;
    }

    private void setReportedScreenState(int state) {
        Trace.traceCounter(Trace.TRACE_TAG_POWER, "ReportedScreenStateToPolicy", state);
        mReportedScreenStateToPolicy = state;
    }

    private int clampScreenBrightness(int value) {
        return MathUtils.constrain(
                value, mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum);
@@ -997,15 +994,20 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
            mPendingScreenOff = false;
        }

        if (mTransitionOffAfterDozeConfig &&
                Display.isDozeState(mPowerState.getScreenState())
        if (mDisplayBlanksAfterDozeConfig
                && Display.isDozeState(mPowerState.getScreenState())
                && !Display.isDozeState(target)) {
            setScreenState(Display.STATE_OFF, true /*force*/);
            // Skip the screen off animation and add a black surface to hide the
            // contents of the screen. This will also trigger another power state update so that we
            // end up converging on the target state.
            // contents of the screen.
            mPowerState.prepareColorFade(mContext,
                    mColorFadeFadesConfig ? ColorFade.MODE_FADE : ColorFade.MODE_WARM_UP);
            mColorFadeOffAnimator.end();
            return;
            // Some display hardware will blank itself on the transition between doze and non-doze
            // but still on display states. In this case we want to report to policy that the
            // display has turned off so it can prepare the appropriate power on animation, but we
            // don't want to actually transition to the fully off state since that takes
            // significantly longer to transition from.
            setScreenState(Display.STATE_OFF, target != Display.STATE_OFF /*reportOnly*/);
        }

        // If we were in the process of turning off the screen but didn't quite
@@ -1307,7 +1309,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        pw.println("  mAppliedLowPower=" + mAppliedLowPower);
        pw.println("  mPendingScreenOnUnblocker=" + mPendingScreenOnUnblocker);
        pw.println("  mPendingScreenOff=" + mPendingScreenOff);
        pw.println("  mReportedToPolicy=" + reportedToPolicyToString(mReportedScreenStateToPolicy));
        pw.println("  mReportedToPolicy=" +
                reportedToPolicyToString(mReportedScreenStateToPolicy));

        pw.println("  mScreenBrightnessRampAnimator.isAnimating()=" +
                mScreenBrightnessRampAnimator.isAnimating());
+5 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager;
import android.os.Trace;
import android.util.FloatProperty;
import android.util.IntProperty;
import android.util.Slog;
@@ -49,6 +50,7 @@ final class DisplayPowerState {
    private static final String TAG = "DisplayPowerState";

    private static boolean DEBUG = false;
    private static String COUNTER_COLOR_FADE = "ColorFadeLevel";

    private final Handler mHandler;
    private final Choreographer mChoreographer;
@@ -190,6 +192,7 @@ final class DisplayPowerState {
     * Dismisses the color fade surface.
     */
    public void dismissColorFade() {
        Trace.traceCounter(Trace.TRACE_TAG_POWER, COUNTER_COLOR_FADE, 100);
        if (mColorFade != null) mColorFade.dismiss();
        mColorFadePrepared = false;
        mColorFadeReady = true;
@@ -328,6 +331,8 @@ final class DisplayPowerState {

            if (mColorFadePrepared) {
                mColorFade.draw(mColorFadeLevel);
                Trace.traceCounter(Trace.TRACE_TAG_POWER,
                        COUNTER_COLOR_FADE, Math.round(mColorFadeLevel* 100));
            }

            mColorFadeReady = true;
+3 −0
Original line number Diff line number Diff line
@@ -515,6 +515,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
                        try {
                            final int mode = getPowerModeForState(state);
                            SurfaceControl.setDisplayPowerMode(token, mode);
                            Trace.traceCounter(Trace.TRACE_TAG_POWER, "DisplayPowerMode", mode);
                        } finally {
                            Trace.traceEnd(Trace.TRACE_TAG_POWER);
                        }
@@ -530,6 +531,8 @@ final class LocalDisplayAdapter extends DisplayAdapter {
                                + "id=" + displayId + ", brightness=" + brightness + ")");
                        try {
                            mBacklight.setBrightness(brightness);
                            Trace.traceCounter(Trace.TRACE_TAG_POWER,
                                    "DisplayBrightness", brightness);
                        } finally {
                            Trace.traceEnd(Trace.TRACE_TAG_POWER);
                        }