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 Merged-In: I4362905e47d5fb47b639c8701c91d69b50aa1232 Change-Id: I4362905e47d5fb47b639c8701c91d69b50aa1232
This commit is contained in:
@@ -1854,9 +1854,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
|
||||
|
||||
@@ -3052,7 +3052,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" />
|
||||
|
||||
@@ -165,11 +165,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.
|
||||
@@ -416,8 +416,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);
|
||||
@@ -803,7 +803,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();
|
||||
}
|
||||
|
||||
@@ -886,10 +886,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) {
|
||||
|
||||
@@ -897,32 +897,24 @@ 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;
|
||||
}
|
||||
unblockScreenOff();
|
||||
} else if (mPendingScreenOffUnblocker != null) {
|
||||
// Abort doing the state change until screen off is unblocked.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
mPowerState.setScreenState(state);
|
||||
|
||||
// Tell battery stats about the transition.
|
||||
try {
|
||||
mBatteryStats.noteScreenState(state);
|
||||
} catch (RemoteException ex) {
|
||||
// same process
|
||||
if (!reportOnly) {
|
||||
mPowerState.setScreenState(state);
|
||||
// Tell battery stats about the transition.
|
||||
try {
|
||||
mBatteryStats.noteScreenState(state);
|
||||
} catch (RemoteException ex) {
|
||||
// same process
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -934,7 +926,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
|
||||
@@ -944,10 +936,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 {
|
||||
@@ -960,6 +952,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);
|
||||
@@ -989,15 +986,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
|
||||
@@ -1295,7 +1297,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());
|
||||
|
||||
@@ -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);
|
||||
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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user