Merge "Add HDR-HBM support into framework." into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
35ab69b632
@@ -33,7 +33,8 @@ public final class BrightnessInfo implements Parcelable {
|
|||||||
|
|
||||||
@IntDef(prefix = {"HIGH_BRIGHTNESS_MODE_"}, value = {
|
@IntDef(prefix = {"HIGH_BRIGHTNESS_MODE_"}, value = {
|
||||||
HIGH_BRIGHTNESS_MODE_OFF,
|
HIGH_BRIGHTNESS_MODE_OFF,
|
||||||
HIGH_BRIGHTNESS_MODE_SUNLIGHT
|
HIGH_BRIGHTNESS_MODE_SUNLIGHT,
|
||||||
|
HIGH_BRIGHTNESS_MODE_HDR
|
||||||
})
|
})
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
public @interface HighBrightnessMode {}
|
public @interface HighBrightnessMode {}
|
||||||
@@ -50,6 +51,12 @@ public final class BrightnessInfo implements Parcelable {
|
|||||||
*/
|
*/
|
||||||
public static final int HIGH_BRIGHTNESS_MODE_SUNLIGHT = 1;
|
public static final int HIGH_BRIGHTNESS_MODE_SUNLIGHT = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* High brightness mode is ON due to high ambient light (sunlight). The high brightness range is
|
||||||
|
* currently accessible to the user.
|
||||||
|
*/
|
||||||
|
public static final int HIGH_BRIGHTNESS_MODE_HDR = 2;
|
||||||
|
|
||||||
/** Brightness */
|
/** Brightness */
|
||||||
public final float brightness;
|
public final float brightness;
|
||||||
|
|
||||||
@@ -73,6 +80,21 @@ public final class BrightnessInfo implements Parcelable {
|
|||||||
this.highBrightnessMode = highBrightnessMode;
|
this.highBrightnessMode = highBrightnessMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return User-friendly string for specified {@link HighBrightnessMode} parameter.
|
||||||
|
*/
|
||||||
|
public static String hbmToString(@HighBrightnessMode int highBrightnessMode) {
|
||||||
|
switch (highBrightnessMode) {
|
||||||
|
case HIGH_BRIGHTNESS_MODE_OFF:
|
||||||
|
return "off";
|
||||||
|
case HIGH_BRIGHTNESS_MODE_HDR:
|
||||||
|
return "hdr";
|
||||||
|
case HIGH_BRIGHTNESS_MODE_SUNLIGHT:
|
||||||
|
return "sunlight";
|
||||||
|
}
|
||||||
|
return "invalid";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int describeContents() {
|
public int describeContents() {
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -738,13 +738,19 @@ class AutomaticBrightnessController {
|
|||||||
float value = mBrightnessMapper.getBrightness(mAmbientLux, mForegroundAppPackageName,
|
float value = mBrightnessMapper.getBrightness(mAmbientLux, mForegroundAppPackageName,
|
||||||
mForegroundAppCategory);
|
mForegroundAppCategory);
|
||||||
float newScreenAutoBrightness = clampScreenBrightness(value);
|
float newScreenAutoBrightness = clampScreenBrightness(value);
|
||||||
|
|
||||||
|
// The min/max range can change for brightness due to HBM. See if the current brightness
|
||||||
|
// value still falls within the current range (which could have changed).
|
||||||
|
final boolean currentBrightnessWithinAllowedRange = BrightnessSynchronizer.floatEquals(
|
||||||
|
mScreenAutoBrightness, clampScreenBrightness(mScreenAutoBrightness));
|
||||||
// If screenAutoBrightness is set, we should have screen{Brightening,Darkening}Threshold,
|
// If screenAutoBrightness is set, we should have screen{Brightening,Darkening}Threshold,
|
||||||
// in which case we ignore the new screen brightness if it doesn't differ enough from the
|
// in which case we ignore the new screen brightness if it doesn't differ enough from the
|
||||||
// previous one.
|
// previous one.
|
||||||
if (!Float.isNaN(mScreenAutoBrightness)
|
if (!Float.isNaN(mScreenAutoBrightness)
|
||||||
&& !isManuallySet
|
&& !isManuallySet
|
||||||
&& newScreenAutoBrightness > mScreenDarkeningThreshold
|
&& newScreenAutoBrightness > mScreenDarkeningThreshold
|
||||||
&& newScreenAutoBrightness < mScreenBrighteningThreshold) {
|
&& newScreenAutoBrightness < mScreenBrighteningThreshold
|
||||||
|
&& currentBrightnessWithinAllowedRange) {
|
||||||
if (mLoggingEnabled) {
|
if (mLoggingEnabled) {
|
||||||
Slog.d(TAG, "ignoring newScreenAutoBrightness: "
|
Slog.d(TAG, "ignoring newScreenAutoBrightness: "
|
||||||
+ mScreenDarkeningThreshold + " < " + newScreenAutoBrightness
|
+ mScreenDarkeningThreshold + " < " + newScreenAutoBrightness
|
||||||
|
|||||||
@@ -20,5 +20,8 @@ package com.android.server.display;
|
|||||||
* Interface used to update the actual display state.
|
* Interface used to update the actual display state.
|
||||||
*/
|
*/
|
||||||
public interface DisplayBlanker {
|
public interface DisplayBlanker {
|
||||||
void requestDisplayState(int displayId, int state, float brightness);
|
/**
|
||||||
|
* Requests the specified display state and brightness levels for the specified displayId.
|
||||||
|
*/
|
||||||
|
void requestDisplayState(int displayId, int state, float brightness, float sdrBrightness);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -156,10 +156,12 @@ abstract class DisplayDevice {
|
|||||||
*
|
*
|
||||||
* @param state The new display state.
|
* @param state The new display state.
|
||||||
* @param brightnessState The new display brightnessState.
|
* @param brightnessState The new display brightnessState.
|
||||||
|
* @param sdrBrightnessState The new display brightnessState for SDR layers.
|
||||||
* @return A runnable containing work to be deferred until after we have
|
* @return A runnable containing work to be deferred until after we have
|
||||||
* exited the critical section, or null if none.
|
* exited the critical section, or null if none.
|
||||||
*/
|
*/
|
||||||
public Runnable requestDisplayStateLocked(int state, float brightnessState) {
|
public Runnable requestDisplayStateLocked(int state, float brightnessState,
|
||||||
|
float sdrBrightnessState) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ public class DisplayDeviceConfig {
|
|||||||
private float mBrightnessRampSlowIncrease = Float.NaN;
|
private float mBrightnessRampSlowIncrease = Float.NaN;
|
||||||
private Spline mBrightnessToBacklightSpline;
|
private Spline mBrightnessToBacklightSpline;
|
||||||
private Spline mBacklightToBrightnessSpline;
|
private Spline mBacklightToBrightnessSpline;
|
||||||
|
private Spline mBacklightToNitsSpline;
|
||||||
private List<String> mQuirks;
|
private List<String> mQuirks;
|
||||||
private boolean mIsHighBrightnessModeEnabled = false;
|
private boolean mIsHighBrightnessModeEnabled = false;
|
||||||
private HighBrightnessModeData mHbmData;
|
private HighBrightnessModeData mHbmData;
|
||||||
@@ -218,6 +219,20 @@ public class DisplayDeviceConfig {
|
|||||||
return mBrightnessToBacklightSpline.interpolate(brightness);
|
return mBrightnessToBacklightSpline.interpolate(brightness);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the nits value for the specified backlight value if a mapping exists.
|
||||||
|
*
|
||||||
|
* @return The mapped nits or 0 if no mapping exits.
|
||||||
|
*/
|
||||||
|
public float getNitsFromBacklight(float backlight) {
|
||||||
|
if (mBacklightToNitsSpline == null) {
|
||||||
|
Slog.wtf(TAG, "requesting nits when no mapping exists.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
backlight = Math.max(backlight, mBacklightMinimum);
|
||||||
|
return mBacklightToNitsSpline.interpolate(backlight);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an array of equal length to backlight and nits, that covers the entire system
|
* Return an array of equal length to backlight and nits, that covers the entire system
|
||||||
* brightness range of 0.0-1.0.
|
* brightness range of 0.0-1.0.
|
||||||
@@ -257,6 +272,13 @@ public class DisplayDeviceConfig {
|
|||||||
return mAmbientLightSensor;
|
return mAmbientLightSensor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if a nits to backlight mapping is defined in this config, false otherwise.
|
||||||
|
*/
|
||||||
|
public boolean hasNitsMapping() {
|
||||||
|
return mBacklightToNitsSpline != null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param quirkValue The quirk to test.
|
* @param quirkValue The quirk to test.
|
||||||
* @return {@code true} if the specified quirk is present in this configuration,
|
* @return {@code true} if the specified quirk is present in this configuration,
|
||||||
@@ -584,6 +606,7 @@ public class DisplayDeviceConfig {
|
|||||||
}
|
}
|
||||||
mBrightnessToBacklightSpline = Spline.createSpline(mBrightness, mBacklight);
|
mBrightnessToBacklightSpline = Spline.createSpline(mBrightness, mBacklight);
|
||||||
mBacklightToBrightnessSpline = Spline.createSpline(mBacklight, mBrightness);
|
mBacklightToBrightnessSpline = Spline.createSpline(mBacklight, mBrightness);
|
||||||
|
mBacklightToNitsSpline = Spline.createSpline(mBacklight, mNits);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadQuirks(DisplayConfiguration config) {
|
private void loadQuirks(DisplayConfiguration config) {
|
||||||
|
|||||||
@@ -257,7 +257,8 @@ public final class DisplayManagerService extends SystemService {
|
|||||||
private final DisplayBlanker mDisplayBlanker = new DisplayBlanker() {
|
private final DisplayBlanker mDisplayBlanker = new DisplayBlanker() {
|
||||||
// Synchronized to avoid race conditions when updating multiple display states.
|
// Synchronized to avoid race conditions when updating multiple display states.
|
||||||
@Override
|
@Override
|
||||||
public synchronized void requestDisplayState(int displayId, int state, float brightness) {
|
public synchronized void requestDisplayState(int displayId, int state, float brightness,
|
||||||
|
float sdrBrightness) {
|
||||||
boolean allInactive = true;
|
boolean allInactive = true;
|
||||||
boolean allOff = true;
|
boolean allOff = true;
|
||||||
final boolean stateChanged;
|
final boolean stateChanged;
|
||||||
@@ -288,7 +289,7 @@ public final class DisplayManagerService extends SystemService {
|
|||||||
|
|
||||||
// The order of operations is important for legacy reasons.
|
// The order of operations is important for legacy reasons.
|
||||||
if (state == Display.STATE_OFF) {
|
if (state == Display.STATE_OFF) {
|
||||||
requestDisplayStateInternal(displayId, state, brightness);
|
requestDisplayStateInternal(displayId, state, brightness, sdrBrightness);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stateChanged) {
|
if (stateChanged) {
|
||||||
@@ -296,7 +297,7 @@ public final class DisplayManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (state != Display.STATE_OFF) {
|
if (state != Display.STATE_OFF) {
|
||||||
requestDisplayStateInternal(displayId, state, brightness);
|
requestDisplayStateInternal(displayId, state, brightness, sdrBrightness);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -316,7 +317,7 @@ public final class DisplayManagerService extends SystemService {
|
|||||||
|
|
||||||
// A map from LogicalDisplay ID to display brightness.
|
// A map from LogicalDisplay ID to display brightness.
|
||||||
@GuardedBy("mSyncRoot")
|
@GuardedBy("mSyncRoot")
|
||||||
private final SparseArray<Float> mDisplayBrightnesses = new SparseArray<>();
|
private final SparseArray<BrightnessPair> mDisplayBrightnesses = new SparseArray<>();
|
||||||
|
|
||||||
// Set to true when there are pending display changes that have yet to be applied
|
// Set to true when there are pending display changes that have yet to be applied
|
||||||
// to the surface flinger state.
|
// to the surface flinger state.
|
||||||
@@ -667,11 +668,8 @@ public final class DisplayManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void requestDisplayStateInternal(int displayId, int state, float brightnessState) {
|
private float clampBrightness(int displayState, float brightnessState) {
|
||||||
if (state == Display.STATE_UNKNOWN) {
|
if (displayState == Display.STATE_OFF) {
|
||||||
state = Display.STATE_ON;
|
|
||||||
}
|
|
||||||
if (state == Display.STATE_OFF) {
|
|
||||||
brightnessState = PowerManager.BRIGHTNESS_OFF_FLOAT;
|
brightnessState = PowerManager.BRIGHTNESS_OFF_FLOAT;
|
||||||
} else if (brightnessState != PowerManager.BRIGHTNESS_OFF_FLOAT
|
} else if (brightnessState != PowerManager.BRIGHTNESS_OFF_FLOAT
|
||||||
&& brightnessState < PowerManager.BRIGHTNESS_MIN) {
|
&& brightnessState < PowerManager.BRIGHTNESS_MIN) {
|
||||||
@@ -679,6 +677,17 @@ public final class DisplayManagerService extends SystemService {
|
|||||||
} else if (brightnessState > PowerManager.BRIGHTNESS_MAX) {
|
} else if (brightnessState > PowerManager.BRIGHTNESS_MAX) {
|
||||||
brightnessState = PowerManager.BRIGHTNESS_MAX;
|
brightnessState = PowerManager.BRIGHTNESS_MAX;
|
||||||
}
|
}
|
||||||
|
return brightnessState;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void requestDisplayStateInternal(int displayId, int state, float brightnessState,
|
||||||
|
float sdrBrightnessState) {
|
||||||
|
if (state == Display.STATE_UNKNOWN) {
|
||||||
|
state = Display.STATE_ON;
|
||||||
|
}
|
||||||
|
|
||||||
|
brightnessState = clampBrightness(state, brightnessState);
|
||||||
|
sdrBrightnessState = clampBrightness(state, sdrBrightnessState);
|
||||||
|
|
||||||
// Update the display state within the lock.
|
// Update the display state within the lock.
|
||||||
// Note that we do not need to schedule traversals here although it
|
// Note that we do not need to schedule traversals here although it
|
||||||
@@ -688,20 +697,26 @@ public final class DisplayManagerService extends SystemService {
|
|||||||
synchronized (mSyncRoot) {
|
synchronized (mSyncRoot) {
|
||||||
final int index = mDisplayStates.indexOfKey(displayId);
|
final int index = mDisplayStates.indexOfKey(displayId);
|
||||||
|
|
||||||
|
final BrightnessPair brightnessPair =
|
||||||
|
index < 0 ? null : mDisplayBrightnesses.valueAt(index);
|
||||||
if (index < 0 || (mDisplayStates.valueAt(index) == state
|
if (index < 0 || (mDisplayStates.valueAt(index) == state
|
||||||
&& BrightnessSynchronizer.floatEquals(mDisplayBrightnesses.valueAt(index),
|
&& BrightnessSynchronizer.floatEquals(
|
||||||
brightnessState))) {
|
brightnessPair.brightness, brightnessState)
|
||||||
|
&& BrightnessSynchronizer.floatEquals(
|
||||||
|
brightnessPair.sdrBrightness, sdrBrightnessState))) {
|
||||||
return; // Display no longer exists or no change.
|
return; // Display no longer exists or no change.
|
||||||
}
|
}
|
||||||
|
|
||||||
traceMessage = "requestDisplayStateInternal("
|
traceMessage = "requestDisplayStateInternal("
|
||||||
+ displayId + ", "
|
+ displayId + ", "
|
||||||
+ Display.stateToString(state)
|
+ Display.stateToString(state)
|
||||||
+ ", brightness=" + brightnessState + ")";
|
+ ", brightness=" + brightnessState
|
||||||
|
+ ", sdrBrightness=" + sdrBrightnessState + ")";
|
||||||
Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, traceMessage, displayId);
|
Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, traceMessage, displayId);
|
||||||
|
|
||||||
mDisplayStates.setValueAt(index, state);
|
mDisplayStates.setValueAt(index, state);
|
||||||
mDisplayBrightnesses.setValueAt(index, brightnessState);
|
brightnessPair.brightness = brightnessState;
|
||||||
|
brightnessPair.sdrBrightness = sdrBrightnessState;
|
||||||
runnable = updateDisplayStateLocked(mLogicalDisplayMapper.getDisplayLocked(displayId)
|
runnable = updateDisplayStateLocked(mLogicalDisplayMapper.getDisplayLocked(displayId)
|
||||||
.getPrimaryDisplayDeviceLocked());
|
.getPrimaryDisplayDeviceLocked());
|
||||||
}
|
}
|
||||||
@@ -1235,7 +1250,9 @@ public final class DisplayManagerService extends SystemService {
|
|||||||
addDisplayPowerControllerLocked(display);
|
addDisplayPowerControllerLocked(display);
|
||||||
mDisplayStates.append(displayId, Display.STATE_UNKNOWN);
|
mDisplayStates.append(displayId, Display.STATE_UNKNOWN);
|
||||||
|
|
||||||
mDisplayBrightnesses.append(displayId, display.getDisplayInfoLocked().brightnessDefault);
|
final float brightnessDefault = display.getDisplayInfoLocked().brightnessDefault;
|
||||||
|
mDisplayBrightnesses.append(displayId,
|
||||||
|
new BrightnessPair(brightnessDefault, brightnessDefault));
|
||||||
|
|
||||||
DisplayManagerGlobal.invalidateLocalDisplayInfoCaches();
|
DisplayManagerGlobal.invalidateLocalDisplayInfoCaches();
|
||||||
|
|
||||||
@@ -1265,11 +1282,6 @@ public final class DisplayManagerService extends SystemService {
|
|||||||
// this point.
|
// this point.
|
||||||
sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
|
sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
|
||||||
scheduleTraversalLocked(false);
|
scheduleTraversalLocked(false);
|
||||||
|
|
||||||
DisplayPowerController dpc = mDisplayPowerControllers.get(displayId);
|
|
||||||
if (dpc != null) {
|
|
||||||
dpc.onDisplayChanged();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleLogicalDisplayFrameRateOverridesChangedLocked(
|
private void handleLogicalDisplayFrameRateOverridesChangedLocked(
|
||||||
@@ -1301,6 +1313,11 @@ public final class DisplayManagerService extends SystemService {
|
|||||||
if (work != null) {
|
if (work != null) {
|
||||||
mHandler.post(work);
|
mHandler.post(work);
|
||||||
}
|
}
|
||||||
|
final int displayId = display.getDisplayIdLocked();
|
||||||
|
DisplayPowerController dpc = mDisplayPowerControllers.get(displayId);
|
||||||
|
if (dpc != null) {
|
||||||
|
dpc.onDisplayChanged();
|
||||||
|
}
|
||||||
handleLogicalDisplayChangedLocked(display);
|
handleLogicalDisplayChangedLocked(display);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1326,8 +1343,9 @@ public final class DisplayManagerService extends SystemService {
|
|||||||
|
|
||||||
// Only send a request for display state if display state has already been initialized.
|
// Only send a request for display state if display state has already been initialized.
|
||||||
if (state != Display.STATE_UNKNOWN) {
|
if (state != Display.STATE_UNKNOWN) {
|
||||||
final float brightness = mDisplayBrightnesses.get(displayId);
|
final BrightnessPair brightnessPair = mDisplayBrightnesses.get(displayId);
|
||||||
return device.requestDisplayStateLocked(state, brightness);
|
return device.requestDisplayStateLocked(state, brightnessPair.brightness,
|
||||||
|
brightnessPair.sdrBrightness);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -1935,10 +1953,11 @@ public final class DisplayManagerService extends SystemService {
|
|||||||
for (int i = 0; i < displayStateCount; i++) {
|
for (int i = 0; i < displayStateCount; i++) {
|
||||||
final int displayId = mDisplayStates.keyAt(i);
|
final int displayId = mDisplayStates.keyAt(i);
|
||||||
final int displayState = mDisplayStates.valueAt(i);
|
final int displayState = mDisplayStates.valueAt(i);
|
||||||
final float brightness = mDisplayBrightnesses.valueAt(i);
|
final BrightnessPair brightnessPair = mDisplayBrightnesses.valueAt(i);
|
||||||
pw.println(" Display Id=" + displayId);
|
pw.println(" Display Id=" + displayId);
|
||||||
pw.println(" Display State=" + Display.stateToString(displayState));
|
pw.println(" Display State=" + Display.stateToString(displayState));
|
||||||
pw.println(" Display Brightness=" + brightness);
|
pw.println(" Display Brightness=" + brightnessPair.brightness);
|
||||||
|
pw.println(" Display SdrBrightness=" + brightnessPair.sdrBrightness);
|
||||||
}
|
}
|
||||||
|
|
||||||
IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
|
IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
|
||||||
@@ -3277,6 +3296,16 @@ public final class DisplayManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private class BrightnessPair {
|
||||||
|
public float brightness;
|
||||||
|
public float sdrBrightness;
|
||||||
|
|
||||||
|
BrightnessPair(float brightness, float sdrBrightness) {
|
||||||
|
this.brightness = brightness;
|
||||||
|
this.sdrBrightness = sdrBrightness;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Functional interface for providing time.
|
* Functional interface for providing time.
|
||||||
* TODO(b/184781936): merge with PowerManagerService.Clock
|
* TODO(b/184781936): merge with PowerManagerService.Clock
|
||||||
@@ -3288,5 +3317,4 @@ public final class DisplayManagerService extends SystemService {
|
|||||||
*/
|
*/
|
||||||
long uptimeMillis();
|
long uptimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
|
|||||||
import android.metrics.LogMaker;
|
import android.metrics.LogMaker;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
import android.os.IBinder;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
@@ -61,6 +62,7 @@ import com.android.internal.logging.MetricsLogger;
|
|||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||||
import com.android.server.LocalServices;
|
import com.android.server.LocalServices;
|
||||||
import com.android.server.am.BatteryStatsService;
|
import com.android.server.am.BatteryStatsService;
|
||||||
|
import com.android.server.display.RampAnimator.DualRampAnimator;
|
||||||
import com.android.server.display.color.ColorDisplayService.ColorDisplayServiceInternal;
|
import com.android.server.display.color.ColorDisplayService.ColorDisplayServiceInternal;
|
||||||
import com.android.server.display.color.ColorDisplayService.ReduceBrightColorsListener;
|
import com.android.server.display.color.ColorDisplayService.ReduceBrightColorsListener;
|
||||||
import com.android.server.display.whitebalance.DisplayWhiteBalanceController;
|
import com.android.server.display.whitebalance.DisplayWhiteBalanceController;
|
||||||
@@ -223,6 +225,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
|||||||
@GuardedBy("mCachedBrightnessInfo")
|
@GuardedBy("mCachedBrightnessInfo")
|
||||||
private final CachedBrightnessInfo mCachedBrightnessInfo = new CachedBrightnessInfo();
|
private final CachedBrightnessInfo mCachedBrightnessInfo = new CachedBrightnessInfo();
|
||||||
|
|
||||||
|
private DisplayDevice mDisplayDevice;
|
||||||
|
|
||||||
// True if we should fade the screen while turning it off, false if we should play
|
// True if we should fade the screen while turning it off, false if we should play
|
||||||
// a stylish color fade animation instead.
|
// a stylish color fade animation instead.
|
||||||
private boolean mColorFadeFadesConfig;
|
private boolean mColorFadeFadesConfig;
|
||||||
@@ -424,7 +428,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
|||||||
// Animators.
|
// Animators.
|
||||||
private ObjectAnimator mColorFadeOnAnimator;
|
private ObjectAnimator mColorFadeOnAnimator;
|
||||||
private ObjectAnimator mColorFadeOffAnimator;
|
private ObjectAnimator mColorFadeOffAnimator;
|
||||||
private RampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator;
|
private DualRampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator;
|
||||||
private BrightnessSetting.BrightnessSettingListener mBrightnessSettingListener;
|
private BrightnessSetting.BrightnessSettingListener mBrightnessSettingListener;
|
||||||
|
|
||||||
// True if this DisplayPowerController has been stopped and should no longer be running.
|
// True if this DisplayPowerController has been stopped and should no longer be running.
|
||||||
@@ -442,6 +446,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
|||||||
Runnable onBrightnessChangeRunnable) {
|
Runnable onBrightnessChangeRunnable) {
|
||||||
mLogicalDisplay = logicalDisplay;
|
mLogicalDisplay = logicalDisplay;
|
||||||
mDisplayId = mLogicalDisplay.getDisplayIdLocked();
|
mDisplayId = mLogicalDisplay.getDisplayIdLocked();
|
||||||
|
mDisplayDevice = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
|
||||||
mHandler = new DisplayControllerHandler(handler.getLooper());
|
mHandler = new DisplayControllerHandler(handler.getLooper());
|
||||||
|
|
||||||
if (mDisplayId == Display.DEFAULT_DISPLAY) {
|
if (mDisplayId == Display.DEFAULT_DISPLAY) {
|
||||||
@@ -780,12 +785,29 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
|||||||
* when displays get swapped on foldable devices. For example, different brightness properties
|
* when displays get swapped on foldable devices. For example, different brightness properties
|
||||||
* of each display need to be properly reflected in AutomaticBrightnessController.
|
* of each display need to be properly reflected in AutomaticBrightnessController.
|
||||||
*/
|
*/
|
||||||
|
@GuardedBy("DisplayManagerService.mSyncRoot")
|
||||||
public void onDisplayChanged() {
|
public void onDisplayChanged() {
|
||||||
// TODO: b/175821789 - Support high brightness on multiple (folding) displays
|
final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
|
||||||
mUniqueDisplayId = mLogicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId();
|
if (device == null) {
|
||||||
mDisplayDeviceConfig = mLogicalDisplay.getPrimaryDisplayDeviceLocked()
|
Slog.wtf(TAG, "Display Device is null in DisplayPowerController for display: "
|
||||||
.getDisplayDeviceConfig();
|
+ mLogicalDisplay.getDisplayIdLocked());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String uniqueId = device.getUniqueId();
|
||||||
|
final DisplayDeviceConfig config = device.getDisplayDeviceConfig();
|
||||||
|
final IBinder token = device.getDisplayTokenLocked();
|
||||||
|
mHandler.post(() -> {
|
||||||
|
if (mDisplayDevice == device) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mDisplayDevice = device;
|
||||||
|
mUniqueDisplayId = uniqueId;
|
||||||
|
mDisplayDeviceConfig = config;
|
||||||
|
|
||||||
loadAmbientLightSensor();
|
loadAmbientLightSensor();
|
||||||
|
mHbmController.resetHbmData(token, config.getHighBrightnessModeData());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -855,8 +877,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
|||||||
mColorFadeOffAnimator.addListener(mAnimatorListener);
|
mColorFadeOffAnimator.addListener(mAnimatorListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
mScreenBrightnessRampAnimator = new RampAnimator<>(
|
mScreenBrightnessRampAnimator = new DualRampAnimator<>(mPowerState,
|
||||||
mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS_FLOAT);
|
DisplayPowerState.SCREEN_BRIGHTNESS_FLOAT,
|
||||||
|
DisplayPowerState.SCREEN_SDR_BRIGHTNESS_FLOAT);
|
||||||
mScreenBrightnessRampAnimator.setListener(mRampAnimatorListener);
|
mScreenBrightnessRampAnimator.setListener(mRampAnimatorListener);
|
||||||
|
|
||||||
noteScreenState(mPowerState.getScreenState());
|
noteScreenState(mPowerState.getScreenState());
|
||||||
@@ -902,6 +925,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
|||||||
/** Clean up all resources that are accessed via the {@link #mHandler} thread. */
|
/** Clean up all resources that are accessed via the {@link #mHandler} thread. */
|
||||||
private void cleanupHandlerThreadAfterStop() {
|
private void cleanupHandlerThreadAfterStop() {
|
||||||
setProximitySensorEnabled(false);
|
setProximitySensorEnabled(false);
|
||||||
|
mHbmController.stop();
|
||||||
mHandler.removeCallbacksAndMessages(null);
|
mHandler.removeCallbacksAndMessages(null);
|
||||||
if (mUnfinishedBusiness) {
|
if (mUnfinishedBusiness) {
|
||||||
mCallbacks.releaseSuspendBlocker();
|
mCallbacks.releaseSuspendBlocker();
|
||||||
@@ -1205,9 +1229,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
|||||||
// timeout is about to expire.
|
// timeout is about to expire.
|
||||||
if (mPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
|
if (mPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
|
||||||
if (brightnessState > PowerManager.BRIGHTNESS_MIN) {
|
if (brightnessState > PowerManager.BRIGHTNESS_MIN) {
|
||||||
brightnessState = Math.max(Math.min(brightnessState
|
brightnessState = Math.max(
|
||||||
- SCREEN_DIM_MINIMUM_REDUCTION_FLOAT,
|
Math.min(brightnessState - SCREEN_DIM_MINIMUM_REDUCTION_FLOAT,
|
||||||
mScreenBrightnessDimConfig), PowerManager.BRIGHTNESS_MIN);
|
mScreenBrightnessDimConfig),
|
||||||
|
PowerManager.BRIGHTNESS_MIN);
|
||||||
mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_DIMMED);
|
mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_DIMMED);
|
||||||
}
|
}
|
||||||
if (!mAppliedDimming) {
|
if (!mAppliedDimming) {
|
||||||
@@ -1282,12 +1307,27 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
|||||||
// transformations to the brightness have pushed it outside of the currently
|
// transformations to the brightness have pushed it outside of the currently
|
||||||
// allowed range.
|
// allowed range.
|
||||||
float animateValue = clampScreenBrightness(brightnessState);
|
float animateValue = clampScreenBrightness(brightnessState);
|
||||||
|
|
||||||
|
// If there are any HDR layers on the screen, we have a special brightness value that we
|
||||||
|
// use instead. We still preserve the calculated brightness for Standard Dynamic Range
|
||||||
|
// (SDR) layers, but the main brightness value will be the one for HDR.
|
||||||
|
float sdrAnimateValue = animateValue;
|
||||||
|
if (mHbmController.getHighBrightnessMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR
|
||||||
|
&& ((mBrightnessReason.modifier & BrightnessReason.MODIFIER_DIMMED) == 0
|
||||||
|
|| (mBrightnessReason.modifier & BrightnessReason.MODIFIER_LOW_POWER) == 0)) {
|
||||||
|
animateValue = mHbmController.getHdrBrightnessValue();
|
||||||
|
}
|
||||||
|
|
||||||
final float currentBrightness = mPowerState.getScreenBrightness();
|
final float currentBrightness = mPowerState.getScreenBrightness();
|
||||||
|
final float currentSdrBrightness = mPowerState.getSdrScreenBrightness();
|
||||||
if (isValidBrightnessValue(animateValue)
|
if (isValidBrightnessValue(animateValue)
|
||||||
&& !BrightnessSynchronizer.floatEquals(animateValue, currentBrightness)) {
|
&& (!BrightnessSynchronizer.floatEquals(animateValue, currentBrightness)
|
||||||
|
|| !BrightnessSynchronizer.floatEquals(
|
||||||
|
sdrAnimateValue, currentSdrBrightness))) {
|
||||||
if (initialRampSkip || hasBrightnessBuckets
|
if (initialRampSkip || hasBrightnessBuckets
|
||||||
|| wasOrWillBeInVr || !isDisplayContentVisible || brightnessIsTemporary) {
|
|| wasOrWillBeInVr || !isDisplayContentVisible || brightnessIsTemporary) {
|
||||||
animateScreenBrightness(animateValue, SCREEN_ANIMATION_RATE_MINIMUM);
|
animateScreenBrightness(animateValue, sdrAnimateValue,
|
||||||
|
SCREEN_ANIMATION_RATE_MINIMUM);
|
||||||
} else {
|
} else {
|
||||||
boolean isIncreasing = animateValue > currentBrightness;
|
boolean isIncreasing = animateValue > currentBrightness;
|
||||||
final float rampSpeed;
|
final float rampSpeed;
|
||||||
@@ -1300,7 +1340,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
|||||||
} else {
|
} else {
|
||||||
rampSpeed = mBrightnessRampRateFastDecrease;
|
rampSpeed = mBrightnessRampRateFastDecrease;
|
||||||
}
|
}
|
||||||
animateScreenBrightness(animateValue, rampSpeed);
|
animateScreenBrightness(animateValue, sdrAnimateValue, rampSpeed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1446,9 +1486,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
|||||||
private HighBrightnessModeController createHbmController() {
|
private HighBrightnessModeController createHbmController() {
|
||||||
final DisplayDeviceConfig ddConfig =
|
final DisplayDeviceConfig ddConfig =
|
||||||
mLogicalDisplay.getPrimaryDisplayDeviceLocked().getDisplayDeviceConfig();
|
mLogicalDisplay.getPrimaryDisplayDeviceLocked().getDisplayDeviceConfig();
|
||||||
|
final IBinder displayToken =
|
||||||
|
mLogicalDisplay.getPrimaryDisplayDeviceLocked().getDisplayTokenLocked();
|
||||||
final DisplayDeviceConfig.HighBrightnessModeData hbmData =
|
final DisplayDeviceConfig.HighBrightnessModeData hbmData =
|
||||||
ddConfig != null ? ddConfig.getHighBrightnessModeData() : null;
|
ddConfig != null ? ddConfig.getHighBrightnessModeData() : null;
|
||||||
return new HighBrightnessModeController(mHandler, PowerManager.BRIGHTNESS_MIN,
|
return new HighBrightnessModeController(mHandler, displayToken, PowerManager.BRIGHTNESS_MIN,
|
||||||
PowerManager.BRIGHTNESS_MAX, hbmData,
|
PowerManager.BRIGHTNESS_MAX, hbmData,
|
||||||
() -> {
|
() -> {
|
||||||
sendUpdatePowerStateLocked();
|
sendUpdatePowerStateLocked();
|
||||||
@@ -1596,11 +1638,12 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
|||||||
&& brightnessState <= PowerManager.BRIGHTNESS_MAX;
|
&& brightnessState <= PowerManager.BRIGHTNESS_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void animateScreenBrightness(float target, float rate) {
|
private void animateScreenBrightness(float target, float sdrTarget, float rate) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Slog.d(TAG, "Animating brightness: target=" + target +", rate=" + rate);
|
Slog.d(TAG, "Animating brightness: target=" + target + ", sdrTarget=" + sdrTarget
|
||||||
|
+ ", rate=" + rate);
|
||||||
}
|
}
|
||||||
if (mScreenBrightnessRampAnimator.animateTo(target, rate)) {
|
if (mScreenBrightnessRampAnimator.animateTo(target, sdrTarget, rate)) {
|
||||||
Trace.traceCounter(Trace.TRACE_TAG_POWER, "TargetScreenBrightness", (int) target);
|
Trace.traceCounter(Trace.TRACE_TAG_POWER, "TargetScreenBrightness", (int) target);
|
||||||
// TODO(b/153319140) remove when we can get this from the above trace invocation
|
// TODO(b/153319140) remove when we can get this from the above trace invocation
|
||||||
SystemProperties.set("debug.tracing.screen_brightness", String.valueOf(target));
|
SystemProperties.set("debug.tracing.screen_brightness", String.valueOf(target));
|
||||||
@@ -2295,6 +2338,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
handleSettingsChange(false /*userSwitch*/);
|
handleSettingsChange(false /*userSwitch*/);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2392,7 +2436,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
|||||||
|
|
||||||
static final int MODIFIER_DIMMED = 0x1;
|
static final int MODIFIER_DIMMED = 0x1;
|
||||||
static final int MODIFIER_LOW_POWER = 0x2;
|
static final int MODIFIER_LOW_POWER = 0x2;
|
||||||
static final int MODIFIER_MASK = 0x3;
|
static final int MODIFIER_HDR = 0x4;
|
||||||
|
static final int MODIFIER_MASK = MODIFIER_DIMMED | MODIFIER_LOW_POWER | MODIFIER_HDR;
|
||||||
|
|
||||||
// ADJUSTMENT_*
|
// ADJUSTMENT_*
|
||||||
// These things can happen at any point, even if the main brightness reason doesn't
|
// These things can happen at any point, even if the main brightness reason doesn't
|
||||||
@@ -2464,6 +2509,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
|||||||
if ((modifier & MODIFIER_DIMMED) != 0) {
|
if ((modifier & MODIFIER_DIMMED) != 0) {
|
||||||
sb.append(" dim");
|
sb.append(" dim");
|
||||||
}
|
}
|
||||||
|
if ((modifier & MODIFIER_HDR) != 0) {
|
||||||
|
sb.append(" hdr");
|
||||||
|
}
|
||||||
int strlen = sb.length();
|
int strlen = sb.length();
|
||||||
if (sb.charAt(strlen - 1) == '[') {
|
if (sb.charAt(strlen - 1) == '[') {
|
||||||
sb.setLength(strlen - 2);
|
sb.setLength(strlen - 2);
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ final class DisplayPowerState {
|
|||||||
|
|
||||||
private int mScreenState;
|
private int mScreenState;
|
||||||
private float mScreenBrightness;
|
private float mScreenBrightness;
|
||||||
|
private float mSdrScreenBrightness;
|
||||||
private boolean mScreenReady;
|
private boolean mScreenReady;
|
||||||
private boolean mScreenUpdatePending;
|
private boolean mScreenUpdatePending;
|
||||||
|
|
||||||
@@ -92,6 +93,7 @@ final class DisplayPowerState {
|
|||||||
mScreenState = displayState;
|
mScreenState = displayState;
|
||||||
mScreenBrightness = (displayState != Display.STATE_OFF) ? PowerManager.BRIGHTNESS_MAX
|
mScreenBrightness = (displayState != Display.STATE_OFF) ? PowerManager.BRIGHTNESS_MAX
|
||||||
: PowerManager.BRIGHTNESS_OFF_FLOAT;
|
: PowerManager.BRIGHTNESS_OFF_FLOAT;
|
||||||
|
mSdrScreenBrightness = mScreenBrightness;
|
||||||
scheduleScreenUpdate();
|
scheduleScreenUpdate();
|
||||||
|
|
||||||
mColorFadePrepared = false;
|
mColorFadePrepared = false;
|
||||||
@@ -126,6 +128,19 @@ final class DisplayPowerState {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static final FloatProperty<DisplayPowerState> SCREEN_SDR_BRIGHTNESS_FLOAT =
|
||||||
|
new FloatProperty<DisplayPowerState>("sdrScreenBrightnessFloat") {
|
||||||
|
@Override
|
||||||
|
public void setValue(DisplayPowerState object, float value) {
|
||||||
|
object.setSdrScreenBrightness(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Float get(DisplayPowerState object) {
|
||||||
|
return object.getSdrScreenBrightness();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether the screen is on, off, or dozing.
|
* Sets whether the screen is on, off, or dozing.
|
||||||
*/
|
*/
|
||||||
@@ -148,13 +163,39 @@ final class DisplayPowerState {
|
|||||||
return mScreenState;
|
return mScreenState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the display's SDR brightness.
|
||||||
|
*
|
||||||
|
* @param brightness The brightness, ranges from 0.0f (minimum / off) to 1.0f (brightest).
|
||||||
|
*/
|
||||||
|
public void setSdrScreenBrightness(float brightness) {
|
||||||
|
if (!BrightnessSynchronizer.floatEquals(mSdrScreenBrightness, brightness)) {
|
||||||
|
if (DEBUG) {
|
||||||
|
Slog.d(TAG, "setSdrScreenBrightness: brightness=" + brightness);
|
||||||
|
}
|
||||||
|
|
||||||
|
mSdrScreenBrightness = brightness;
|
||||||
|
if (mScreenState != Display.STATE_OFF) {
|
||||||
|
mScreenReady = false;
|
||||||
|
scheduleScreenUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the screen SDR brightness.
|
||||||
|
*/
|
||||||
|
public float getSdrScreenBrightness() {
|
||||||
|
return mSdrScreenBrightness;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the display brightness.
|
* Sets the display brightness.
|
||||||
*
|
*
|
||||||
* @param brightness The brightness, ranges from 0.0f (minimum / off) to 1.0f (brightest).
|
* @param brightness The brightness, ranges from 0.0f (minimum / off) to 1.0f (brightest).
|
||||||
*/
|
*/
|
||||||
public void setScreenBrightness(float brightness) {
|
public void setScreenBrightness(float brightness) {
|
||||||
if (mScreenBrightness != brightness) {
|
if (!BrightnessSynchronizer.floatEquals(mScreenBrightness, brightness)) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Slog.d(TAG, "setScreenBrightness: brightness=" + brightness);
|
Slog.d(TAG, "setScreenBrightness: brightness=" + brightness);
|
||||||
}
|
}
|
||||||
@@ -286,6 +327,7 @@ final class DisplayPowerState {
|
|||||||
pw.println(" mStopped=" + mStopped);
|
pw.println(" mStopped=" + mStopped);
|
||||||
pw.println(" mScreenState=" + Display.stateToString(mScreenState));
|
pw.println(" mScreenState=" + Display.stateToString(mScreenState));
|
||||||
pw.println(" mScreenBrightness=" + mScreenBrightness);
|
pw.println(" mScreenBrightness=" + mScreenBrightness);
|
||||||
|
pw.println(" mSdrScreenBrightness=" + mSdrScreenBrightness);
|
||||||
pw.println(" mScreenReady=" + mScreenReady);
|
pw.println(" mScreenReady=" + mScreenReady);
|
||||||
pw.println(" mScreenUpdatePending=" + mScreenUpdatePending);
|
pw.println(" mScreenUpdatePending=" + mScreenUpdatePending);
|
||||||
pw.println(" mColorFadePrepared=" + mColorFadePrepared);
|
pw.println(" mColorFadePrepared=" + mColorFadePrepared);
|
||||||
@@ -332,7 +374,10 @@ final class DisplayPowerState {
|
|||||||
|
|
||||||
float brightnessState = mScreenState != Display.STATE_OFF
|
float brightnessState = mScreenState != Display.STATE_OFF
|
||||||
&& mColorFadeLevel > 0f ? mScreenBrightness : PowerManager.BRIGHTNESS_OFF_FLOAT;
|
&& mColorFadeLevel > 0f ? mScreenBrightness : PowerManager.BRIGHTNESS_OFF_FLOAT;
|
||||||
if (mPhotonicModulator.setState(mScreenState, brightnessState)) {
|
float sdrBrightnessState = mScreenState != Display.STATE_OFF
|
||||||
|
&& mColorFadeLevel > 0f
|
||||||
|
? mSdrScreenBrightness : PowerManager.BRIGHTNESS_OFF_FLOAT;
|
||||||
|
if (mPhotonicModulator.setState(mScreenState, brightnessState, sdrBrightnessState)) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Slog.d(TAG, "Screen ready");
|
Slog.d(TAG, "Screen ready");
|
||||||
}
|
}
|
||||||
@@ -373,8 +418,10 @@ final class DisplayPowerState {
|
|||||||
|
|
||||||
private int mPendingState = INITIAL_SCREEN_STATE;
|
private int mPendingState = INITIAL_SCREEN_STATE;
|
||||||
private float mPendingBacklight = INITIAL_BACKLIGHT_FLOAT;
|
private float mPendingBacklight = INITIAL_BACKLIGHT_FLOAT;
|
||||||
|
private float mPendingSdrBacklight = INITIAL_BACKLIGHT_FLOAT;
|
||||||
private int mActualState = INITIAL_SCREEN_STATE;
|
private int mActualState = INITIAL_SCREEN_STATE;
|
||||||
private float mActualBacklight = INITIAL_BACKLIGHT_FLOAT;
|
private float mActualBacklight = INITIAL_BACKLIGHT_FLOAT;
|
||||||
|
private float mActualSdrBacklight = INITIAL_BACKLIGHT_FLOAT;
|
||||||
private boolean mStateChangeInProgress;
|
private boolean mStateChangeInProgress;
|
||||||
private boolean mBacklightChangeInProgress;
|
private boolean mBacklightChangeInProgress;
|
||||||
|
|
||||||
@@ -382,11 +429,13 @@ final class DisplayPowerState {
|
|||||||
super("PhotonicModulator");
|
super("PhotonicModulator");
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setState(int state, float brightnessState) {
|
public boolean setState(int state, float brightnessState, float sdrBrightnessState) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
boolean stateChanged = state != mPendingState;
|
boolean stateChanged = state != mPendingState;
|
||||||
boolean backlightChanged = !BrightnessSynchronizer.floatEquals(
|
boolean backlightChanged =
|
||||||
brightnessState, mPendingBacklight);
|
!BrightnessSynchronizer.floatEquals(brightnessState, mPendingBacklight)
|
||||||
|
|| !BrightnessSynchronizer.floatEquals(
|
||||||
|
sdrBrightnessState, mPendingSdrBacklight);
|
||||||
if (stateChanged || backlightChanged) {
|
if (stateChanged || backlightChanged) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Slog.d(TAG, "Requesting new screen state: state="
|
Slog.d(TAG, "Requesting new screen state: state="
|
||||||
@@ -395,6 +444,7 @@ final class DisplayPowerState {
|
|||||||
|
|
||||||
mPendingState = state;
|
mPendingState = state;
|
||||||
mPendingBacklight = brightnessState;
|
mPendingBacklight = brightnessState;
|
||||||
|
mPendingSdrBacklight = sdrBrightnessState;
|
||||||
boolean changeInProgress = mStateChangeInProgress || mBacklightChangeInProgress;
|
boolean changeInProgress = mStateChangeInProgress || mBacklightChangeInProgress;
|
||||||
mStateChangeInProgress = stateChanged || mStateChangeInProgress;
|
mStateChangeInProgress = stateChanged || mStateChangeInProgress;
|
||||||
mBacklightChangeInProgress = backlightChanged || mBacklightChangeInProgress;
|
mBacklightChangeInProgress = backlightChanged || mBacklightChangeInProgress;
|
||||||
@@ -413,8 +463,10 @@ final class DisplayPowerState {
|
|||||||
pw.println("Photonic Modulator State:");
|
pw.println("Photonic Modulator State:");
|
||||||
pw.println(" mPendingState=" + Display.stateToString(mPendingState));
|
pw.println(" mPendingState=" + Display.stateToString(mPendingState));
|
||||||
pw.println(" mPendingBacklight=" + mPendingBacklight);
|
pw.println(" mPendingBacklight=" + mPendingBacklight);
|
||||||
|
pw.println(" mPendingSdrBacklight=" + mPendingSdrBacklight);
|
||||||
pw.println(" mActualState=" + Display.stateToString(mActualState));
|
pw.println(" mActualState=" + Display.stateToString(mActualState));
|
||||||
pw.println(" mActualBacklight=" + mActualBacklight);
|
pw.println(" mActualBacklight=" + mActualBacklight);
|
||||||
|
pw.println(" mActualSdrBacklight=" + mActualSdrBacklight);
|
||||||
pw.println(" mStateChangeInProgress=" + mStateChangeInProgress);
|
pw.println(" mStateChangeInProgress=" + mStateChangeInProgress);
|
||||||
pw.println(" mBacklightChangeInProgress=" + mBacklightChangeInProgress);
|
pw.println(" mBacklightChangeInProgress=" + mBacklightChangeInProgress);
|
||||||
}
|
}
|
||||||
@@ -427,13 +479,17 @@ final class DisplayPowerState {
|
|||||||
final int state;
|
final int state;
|
||||||
final boolean stateChanged;
|
final boolean stateChanged;
|
||||||
final float brightnessState;
|
final float brightnessState;
|
||||||
|
final float sdrBrightnessState;
|
||||||
final boolean backlightChanged;
|
final boolean backlightChanged;
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
state = mPendingState;
|
state = mPendingState;
|
||||||
stateChanged = (state != mActualState);
|
stateChanged = (state != mActualState);
|
||||||
brightnessState = mPendingBacklight;
|
brightnessState = mPendingBacklight;
|
||||||
backlightChanged = !BrightnessSynchronizer.floatEquals(
|
sdrBrightnessState = mPendingSdrBacklight;
|
||||||
brightnessState, mActualBacklight);
|
backlightChanged =
|
||||||
|
!BrightnessSynchronizer.floatEquals(brightnessState, mActualBacklight)
|
||||||
|
|| !BrightnessSynchronizer.floatEquals(
|
||||||
|
sdrBrightnessState, mActualSdrBacklight);
|
||||||
if (!stateChanged) {
|
if (!stateChanged) {
|
||||||
// State changed applied, notify outer class.
|
// State changed applied, notify outer class.
|
||||||
postScreenUpdateThreadSafe();
|
postScreenUpdateThreadSafe();
|
||||||
@@ -454,14 +510,17 @@ final class DisplayPowerState {
|
|||||||
}
|
}
|
||||||
mActualState = state;
|
mActualState = state;
|
||||||
mActualBacklight = brightnessState;
|
mActualBacklight = brightnessState;
|
||||||
|
mActualSdrBacklight = sdrBrightnessState;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply pending change.
|
// Apply pending change.
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Slog.d(TAG, "Updating screen state: id=" + mDisplayId + ", state="
|
Slog.d(TAG, "Updating screen state: id=" + mDisplayId + ", state="
|
||||||
+ Display.stateToString(state) + ", backlight=" + brightnessState);
|
+ Display.stateToString(state) + ", backlight=" + brightnessState
|
||||||
|
+ ", sdrBacklight=" + sdrBrightnessState);
|
||||||
}
|
}
|
||||||
mBlanker.requestDisplayState(mDisplayId, state, brightnessState);
|
mBlanker.requestDisplayState(mDisplayId, state, brightnessState,
|
||||||
|
sdrBrightnessState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,9 +18,11 @@ package com.android.server.display;
|
|||||||
|
|
||||||
import android.hardware.display.BrightnessInfo;
|
import android.hardware.display.BrightnessInfo;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
import android.os.IBinder;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
|
import android.view.SurfaceControlHdrLayerInfoListener;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.server.display.DisplayDeviceConfig.HighBrightnessModeData;
|
import com.android.server.display.DisplayDeviceConfig.HighBrightnessModeData;
|
||||||
@@ -45,17 +47,21 @@ class HighBrightnessModeController {
|
|||||||
|
|
||||||
private final float mBrightnessMin;
|
private final float mBrightnessMin;
|
||||||
private final float mBrightnessMax;
|
private final float mBrightnessMax;
|
||||||
private final HighBrightnessModeData mHbmData;
|
|
||||||
private final Handler mHandler;
|
private final Handler mHandler;
|
||||||
private final Runnable mHbmChangeCallback;
|
private final Runnable mHbmChangeCallback;
|
||||||
private final Runnable mRecalcRunnable;
|
private final Runnable mRecalcRunnable;
|
||||||
private final Clock mClock;
|
private final Clock mClock;
|
||||||
|
|
||||||
|
private SurfaceControlHdrLayerInfoListener mHdrListener;
|
||||||
|
private HighBrightnessModeData mHbmData;
|
||||||
|
private IBinder mRegisteredDisplayToken;
|
||||||
|
|
||||||
private boolean mIsInAllowedAmbientRange = false;
|
private boolean mIsInAllowedAmbientRange = false;
|
||||||
private boolean mIsTimeAvailable = false;
|
private boolean mIsTimeAvailable = false;
|
||||||
private boolean mIsAutoBrightnessEnabled = false;
|
private boolean mIsAutoBrightnessEnabled = false;
|
||||||
private float mAutoBrightness;
|
private float mAutoBrightness;
|
||||||
private int mHbmMode = BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF;
|
private int mHbmMode = BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF;
|
||||||
|
private boolean mIsHdrLayerPresent = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If HBM is currently running, this is the start time for the current HBM session.
|
* If HBM is currently running, this is the start time for the current HBM session.
|
||||||
@@ -69,23 +75,26 @@ class HighBrightnessModeController {
|
|||||||
*/
|
*/
|
||||||
private LinkedList<HbmEvent> mEvents = new LinkedList<>();
|
private LinkedList<HbmEvent> mEvents = new LinkedList<>();
|
||||||
|
|
||||||
HighBrightnessModeController(Handler handler, float brightnessMin, float brightnessMax,
|
HighBrightnessModeController(Handler handler, IBinder displayToken, float brightnessMin,
|
||||||
HighBrightnessModeData hbmData, Runnable hbmChangeCallback) {
|
float brightnessMax, HighBrightnessModeData hbmData, Runnable hbmChangeCallback) {
|
||||||
this(SystemClock::uptimeMillis, handler, brightnessMin, brightnessMax, hbmData,
|
this(SystemClock::uptimeMillis, handler, displayToken, brightnessMin, brightnessMax,
|
||||||
hbmChangeCallback);
|
hbmData, hbmChangeCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
HighBrightnessModeController(Clock clock, Handler handler, float brightnessMin,
|
HighBrightnessModeController(Clock clock, Handler handler, IBinder displayToken,
|
||||||
float brightnessMax, HighBrightnessModeData hbmData, Runnable hbmChangeCallback) {
|
float brightnessMin, float brightnessMax, HighBrightnessModeData hbmData,
|
||||||
|
Runnable hbmChangeCallback) {
|
||||||
mClock = clock;
|
mClock = clock;
|
||||||
mHandler = handler;
|
mHandler = handler;
|
||||||
mBrightnessMin = brightnessMin;
|
mBrightnessMin = brightnessMin;
|
||||||
mBrightnessMax = brightnessMax;
|
mBrightnessMax = brightnessMax;
|
||||||
mHbmData = hbmData;
|
|
||||||
mHbmChangeCallback = hbmChangeCallback;
|
mHbmChangeCallback = hbmChangeCallback;
|
||||||
mAutoBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
|
mAutoBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
|
||||||
mRecalcRunnable = this::recalculateTimeAllowance;
|
mRecalcRunnable = this::recalculateTimeAllowance;
|
||||||
|
mHdrListener = new HdrListener();
|
||||||
|
|
||||||
|
resetHbmData(displayToken, hbmData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setAutoBrightnessEnabled(boolean isEnabled) {
|
void setAutoBrightnessEnabled(boolean isEnabled) {
|
||||||
@@ -117,6 +126,10 @@ class HighBrightnessModeController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float getHdrBrightnessValue() {
|
||||||
|
return mBrightnessMax;
|
||||||
|
}
|
||||||
|
|
||||||
void onAmbientLuxChange(float ambientLux) {
|
void onAmbientLuxChange(float ambientLux) {
|
||||||
if (!deviceSupportsHbm() || !mIsAutoBrightnessEnabled) {
|
if (!deviceSupportsHbm() || !mIsAutoBrightnessEnabled) {
|
||||||
return;
|
return;
|
||||||
@@ -138,11 +151,12 @@ class HighBrightnessModeController {
|
|||||||
|
|
||||||
// If we are starting or ending a high brightness mode session, store the current
|
// If we are starting or ending a high brightness mode session, store the current
|
||||||
// session in mRunningStartTimeMillis, or the old one in mEvents.
|
// session in mRunningStartTimeMillis, or the old one in mEvents.
|
||||||
final boolean wasOldBrightnessHigh = oldAutoBrightness > mHbmData.transitionPoint;
|
final boolean wasHbmDrainingAvailableTime = mRunningStartTimeMillis != -1;
|
||||||
final boolean isNewBrightnessHigh = mAutoBrightness > mHbmData.transitionPoint;
|
final boolean shouldHbmDrainAvailableTime = mAutoBrightness > mHbmData.transitionPoint
|
||||||
if (wasOldBrightnessHigh != isNewBrightnessHigh) {
|
&& !mIsHdrLayerPresent;
|
||||||
|
if (wasHbmDrainingAvailableTime != shouldHbmDrainAvailableTime) {
|
||||||
final long currentTime = mClock.uptimeMillis();
|
final long currentTime = mClock.uptimeMillis();
|
||||||
if (isNewBrightnessHigh) {
|
if (shouldHbmDrainAvailableTime) {
|
||||||
mRunningStartTimeMillis = currentTime;
|
mRunningStartTimeMillis = currentTime;
|
||||||
} else {
|
} else {
|
||||||
mEvents.addFirst(new HbmEvent(mRunningStartTimeMillis, currentTime));
|
mEvents.addFirst(new HbmEvent(mRunningStartTimeMillis, currentTime));
|
||||||
@@ -161,30 +175,49 @@ class HighBrightnessModeController {
|
|||||||
return mHbmMode;
|
return mHbmMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void stop() {
|
||||||
|
registerHdrListener(null /*displayToken*/);
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetHbmData(IBinder displayToken, HighBrightnessModeData hbmData) {
|
||||||
|
mHbmData = hbmData;
|
||||||
|
unregisterHdrListener();
|
||||||
|
if (deviceSupportsHbm()) {
|
||||||
|
registerHdrListener(displayToken);
|
||||||
|
recalculateTimeAllowance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void dump(PrintWriter pw) {
|
void dump(PrintWriter pw) {
|
||||||
pw.println("HighBrightnessModeController:");
|
pw.println("HighBrightnessModeController:");
|
||||||
pw.println(" mBrightnessMin=" + mBrightnessMin);
|
pw.println(" mCurrentMin=" + getCurrentBrightnessMin());
|
||||||
pw.println(" mBrightnessMax=" + mBrightnessMax);
|
pw.println(" mCurrentMax=" + getCurrentBrightnessMax());
|
||||||
|
pw.println(" mHbmMode=" + BrightnessInfo.hbmToString(mHbmMode));
|
||||||
|
pw.println(" remainingTime=" + calculateRemainingTime(mClock.uptimeMillis()));
|
||||||
pw.println(" mHbmData=" + mHbmData);
|
pw.println(" mHbmData=" + mHbmData);
|
||||||
pw.println(" mIsInAllowedAmbientRange=" + mIsInAllowedAmbientRange);
|
pw.println(" mIsInAllowedAmbientRange=" + mIsInAllowedAmbientRange);
|
||||||
pw.println(" mIsTimeAvailable= " + mIsTimeAvailable);
|
pw.println(" mIsTimeAvailable= " + mIsTimeAvailable);
|
||||||
pw.println(" mIsAutoBrightnessEnabled=" + mIsAutoBrightnessEnabled);
|
pw.println(" mIsAutoBrightnessEnabled=" + mIsAutoBrightnessEnabled);
|
||||||
pw.println(" mAutoBrightness=" + mAutoBrightness);
|
pw.println(" mAutoBrightness=" + mAutoBrightness);
|
||||||
|
pw.println(" mIsHdrLayerPresent=" + mIsHdrLayerPresent);
|
||||||
|
pw.println(" mBrightnessMin=" + mBrightnessMin);
|
||||||
|
pw.println(" mBrightnessMax=" + mBrightnessMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isCurrentlyAllowed() {
|
private boolean isCurrentlyAllowed() {
|
||||||
return mIsAutoBrightnessEnabled && mIsTimeAvailable && mIsInAllowedAmbientRange;
|
return mIsHdrLayerPresent
|
||||||
|
|| (mIsAutoBrightnessEnabled && mIsTimeAvailable && mIsInAllowedAmbientRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean deviceSupportsHbm() {
|
private boolean deviceSupportsHbm() {
|
||||||
return mHbmData != null;
|
return mHbmData != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private long calculateRemainingTime(long currentTime) {
|
||||||
* Recalculates the allowable HBM time.
|
if (!deviceSupportsHbm()) {
|
||||||
*/
|
return 0;
|
||||||
private void recalculateTimeAllowance() {
|
}
|
||||||
final long currentTime = mClock.uptimeMillis();
|
|
||||||
long timeAlreadyUsed = 0;
|
long timeAlreadyUsed = 0;
|
||||||
|
|
||||||
// First, lets see how much time we've taken for any currently running
|
// First, lets see how much time we've taken for any currently running
|
||||||
@@ -222,8 +255,15 @@ class HighBrightnessModeController {
|
|||||||
Slog.d(TAG, "Time already used after all sessions: " + timeAlreadyUsed);
|
Slog.d(TAG, "Time already used after all sessions: " + timeAlreadyUsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
// See how much allowable time we have left.
|
return Math.max(0, mHbmData.timeMaxMillis - timeAlreadyUsed);
|
||||||
final long remainingTime = Math.max(0, mHbmData.timeMaxMillis - timeAlreadyUsed);
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recalculates the allowable HBM time.
|
||||||
|
*/
|
||||||
|
private void recalculateTimeAllowance() {
|
||||||
|
final long currentTime = mClock.uptimeMillis();
|
||||||
|
final long remainingTime = calculateRemainingTime(currentTime);
|
||||||
|
|
||||||
// We allow HBM if there is more than the minimum required time available
|
// We allow HBM if there is more than the minimum required time available
|
||||||
// or if brightness is already in the high range, if there is any time left at all.
|
// or if brightness is already in the high range, if there is any time left at all.
|
||||||
@@ -242,6 +282,7 @@ class HighBrightnessModeController {
|
|||||||
// If we are not allowed...timeout when the oldest event moved outside of the timing
|
// If we are not allowed...timeout when the oldest event moved outside of the timing
|
||||||
// window by at least minTime. Basically, we're calculating the soonest time we can
|
// window by at least minTime. Basically, we're calculating the soonest time we can
|
||||||
// get {@code timeMinMillis} back to us.
|
// get {@code timeMinMillis} back to us.
|
||||||
|
final long windowstartTimeMillis = currentTime - mHbmData.timeWindowMillis;
|
||||||
final HbmEvent lastEvent = mEvents.getLast();
|
final HbmEvent lastEvent = mEvents.getLast();
|
||||||
final long startTimePlusMinMillis =
|
final long startTimePlusMinMillis =
|
||||||
Math.max(windowstartTimeMillis, lastEvent.startTimeMillis)
|
Math.max(windowstartTimeMillis, lastEvent.startTimeMillis)
|
||||||
@@ -278,12 +319,36 @@ class HighBrightnessModeController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int calculateHighBrightnessMode() {
|
private int calculateHighBrightnessMode() {
|
||||||
if (deviceSupportsHbm() && isCurrentlyAllowed()) {
|
if (!deviceSupportsHbm()) {
|
||||||
|
return BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF;
|
||||||
|
} else if (mIsHdrLayerPresent) {
|
||||||
|
return BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR;
|
||||||
|
} else if (isCurrentlyAllowed()) {
|
||||||
return BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT;
|
return BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF;
|
return BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void registerHdrListener(IBinder displayToken) {
|
||||||
|
if (mRegisteredDisplayToken == displayToken) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unregisterHdrListener();
|
||||||
|
mRegisteredDisplayToken = displayToken;
|
||||||
|
if (mRegisteredDisplayToken != null) {
|
||||||
|
mHdrListener.register(mRegisteredDisplayToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void unregisterHdrListener() {
|
||||||
|
if (mRegisteredDisplayToken != null) {
|
||||||
|
mHdrListener.unregister(mRegisteredDisplayToken);
|
||||||
|
mIsHdrLayerPresent = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an event in which High Brightness Mode was enabled.
|
* Represents an event in which High Brightness Mode was enabled.
|
||||||
*/
|
*/
|
||||||
@@ -302,4 +367,18 @@ class HighBrightnessModeController {
|
|||||||
+ ((endTimeMillis - startTimeMillis) / 1000) + "]";
|
+ ((endTimeMillis - startTimeMillis) / 1000) + "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class HdrListener extends SurfaceControlHdrLayerInfoListener {
|
||||||
|
@Override
|
||||||
|
public void onHdrInfoChanged(IBinder displayToken, int numberOfHdrLayers,
|
||||||
|
int maxW, int maxH, int flags) {
|
||||||
|
mHandler.post(() -> {
|
||||||
|
mIsHdrLayerPresent = numberOfHdrLayers > 0;
|
||||||
|
// Calling the auto-brightness update so that we can recalculate
|
||||||
|
// auto-brightness with HDR in mind. When HDR layers are present,
|
||||||
|
// we don't limit auto-brightness' HBM time limits.
|
||||||
|
onAutoBrightnessChanged(mAutoBrightness);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,6 +67,8 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
|||||||
|
|
||||||
private static final int NO_DISPLAY_MODE_ID = 0;
|
private static final int NO_DISPLAY_MODE_ID = 0;
|
||||||
|
|
||||||
|
private static final float NITS_INVALID = -1;
|
||||||
|
|
||||||
private final LongSparseArray<LocalDisplayDevice> mDevices = new LongSparseArray<>();
|
private final LongSparseArray<LocalDisplayDevice> mDevices = new LongSparseArray<>();
|
||||||
|
|
||||||
private final Injector mInjector;
|
private final Injector mInjector;
|
||||||
@@ -190,6 +192,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
|||||||
private int mState = Display.STATE_UNKNOWN;
|
private int mState = Display.STATE_UNKNOWN;
|
||||||
// This is only set in the runnable returned from requestDisplayStateLocked.
|
// This is only set in the runnable returned from requestDisplayStateLocked.
|
||||||
private float mBrightnessState = PowerManager.BRIGHTNESS_INVALID_FLOAT;
|
private float mBrightnessState = PowerManager.BRIGHTNESS_INVALID_FLOAT;
|
||||||
|
private float mSdrBrightnessState = PowerManager.BRIGHTNESS_INVALID_FLOAT;
|
||||||
private int mDefaultModeId;
|
private int mDefaultModeId;
|
||||||
private int mDefaultModeGroup;
|
private int mDefaultModeGroup;
|
||||||
private int mActiveModeId;
|
private int mActiveModeId;
|
||||||
@@ -644,13 +647,15 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Runnable requestDisplayStateLocked(final int state, final float brightnessState) {
|
public Runnable requestDisplayStateLocked(final int state, final float brightnessState,
|
||||||
|
final float sdrBrightnessState) {
|
||||||
// Assume that the brightness is off if the display is being turned off.
|
// Assume that the brightness is off if the display is being turned off.
|
||||||
assert state != Display.STATE_OFF || BrightnessSynchronizer.floatEquals(
|
assert state != Display.STATE_OFF || BrightnessSynchronizer.floatEquals(
|
||||||
brightnessState, PowerManager.BRIGHTNESS_OFF_FLOAT);
|
brightnessState, PowerManager.BRIGHTNESS_OFF_FLOAT);
|
||||||
final boolean stateChanged = (mState != state);
|
final boolean stateChanged = (mState != state);
|
||||||
final boolean brightnessChanged = (!BrightnessSynchronizer.floatEquals(
|
final boolean brightnessChanged =
|
||||||
mBrightnessState, brightnessState));
|
!(BrightnessSynchronizer.floatEquals(mBrightnessState, brightnessState)
|
||||||
|
&& BrightnessSynchronizer.floatEquals(mSdrBrightnessState, sdrBrightnessState));
|
||||||
if (stateChanged || brightnessChanged) {
|
if (stateChanged || brightnessChanged) {
|
||||||
final long physicalDisplayId = mPhysicalDisplayId;
|
final long physicalDisplayId = mPhysicalDisplayId;
|
||||||
final IBinder token = getDisplayTokenLocked();
|
final IBinder token = getDisplayTokenLocked();
|
||||||
@@ -702,8 +707,9 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
|||||||
|
|
||||||
// Apply brightness changes given that we are in a non-suspended state.
|
// Apply brightness changes given that we are in a non-suspended state.
|
||||||
if (brightnessChanged || vrModeChange) {
|
if (brightnessChanged || vrModeChange) {
|
||||||
setDisplayBrightness(brightnessState);
|
setDisplayBrightness(brightnessState, sdrBrightnessState);
|
||||||
mBrightnessState = brightnessState;
|
mBrightnessState = brightnessState;
|
||||||
|
mSdrBrightnessState = sdrBrightnessState;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enter the final desired state, possibly suspended.
|
// Enter the final desired state, possibly suspended.
|
||||||
@@ -764,8 +770,8 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setDisplayBrightness(float brightness) {
|
private void setDisplayBrightness(float brightness, float sdrBrightness) {
|
||||||
// Ensure brightnessState is valid, before processing and sending to
|
// Ensure brightnessState is valid before processing and sending to
|
||||||
// surface control
|
// surface control
|
||||||
if (Float.isNaN(brightness)) {
|
if (Float.isNaN(brightness)) {
|
||||||
return;
|
return;
|
||||||
@@ -774,17 +780,31 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
|||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Slog.d(TAG, "setDisplayBrightness("
|
Slog.d(TAG, "setDisplayBrightness("
|
||||||
+ "id=" + physicalDisplayId
|
+ "id=" + physicalDisplayId
|
||||||
+ ", brightness=" + brightness + ")");
|
+ ", brightness=" + brightness
|
||||||
|
+ ", sdrBrightness=" + sdrBrightness + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayBrightness("
|
Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayBrightness("
|
||||||
+ "id=" + physicalDisplayId + ", brightness=" + brightness + ")");
|
+ "id=" + physicalDisplayId + ", brightness=" + brightness
|
||||||
|
+ ", sdrBrightness=" + sdrBrightness + ")");
|
||||||
try {
|
try {
|
||||||
float backlight = brightnessToBacklight(brightness);
|
final float backlight = brightnessToBacklight(brightness);
|
||||||
mBacklightAdapter.setBacklight(backlight);
|
float nits = NITS_INVALID;
|
||||||
|
float sdrBacklight = PowerManager.BRIGHTNESS_INVALID_FLOAT;
|
||||||
|
float sdrNits = NITS_INVALID;
|
||||||
|
if (getDisplayDeviceConfig().hasNitsMapping()
|
||||||
|
&& sdrBrightness != PowerManager.BRIGHTNESS_INVALID_FLOAT) {
|
||||||
|
nits = backlightToNits(backlight);
|
||||||
|
sdrBacklight = brightnessToBacklight(sdrBrightness);
|
||||||
|
sdrNits = backlightToNits(sdrBacklight);
|
||||||
|
}
|
||||||
|
mBacklightAdapter.setBacklight(sdrBacklight, sdrNits, backlight, nits);
|
||||||
Trace.traceCounter(Trace.TRACE_TAG_POWER,
|
Trace.traceCounter(Trace.TRACE_TAG_POWER,
|
||||||
"ScreenBrightness",
|
"ScreenBrightness",
|
||||||
BrightnessSynchronizer.brightnessFloatToInt(brightness));
|
BrightnessSynchronizer.brightnessFloatToInt(brightness));
|
||||||
|
Trace.traceCounter(Trace.TRACE_TAG_POWER,
|
||||||
|
"SdrScreenBrightness",
|
||||||
|
BrightnessSynchronizer.brightnessFloatToInt(sdrBrightness));
|
||||||
} finally {
|
} finally {
|
||||||
Trace.traceEnd(Trace.TRACE_TAG_POWER);
|
Trace.traceEnd(Trace.TRACE_TAG_POWER);
|
||||||
}
|
}
|
||||||
@@ -793,6 +813,10 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
|||||||
private float brightnessToBacklight(float brightness) {
|
private float brightnessToBacklight(float brightness) {
|
||||||
return getDisplayDeviceConfig().getBacklightFromBrightness(brightness);
|
return getDisplayDeviceConfig().getBacklightFromBrightness(brightness);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private float backlightToNits(float backlight) {
|
||||||
|
return getDisplayDeviceConfig().getNitsFromBacklight(backlight);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -1242,6 +1266,13 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
|||||||
public boolean setDisplayBrightness(IBinder displayToken, float brightness) {
|
public boolean setDisplayBrightness(IBinder displayToken, float brightness) {
|
||||||
return SurfaceControl.setDisplayBrightness(displayToken, brightness);
|
return SurfaceControl.setDisplayBrightness(displayToken, brightness);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean setDisplayBrightness(IBinder displayToken, float sdrBacklight,
|
||||||
|
float sdrNits, float displayBacklight, float displayNits) {
|
||||||
|
return SurfaceControl.setDisplayBrightness(displayToken, sdrBacklight, sdrNits,
|
||||||
|
displayBacklight, displayNits);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static class BacklightAdapter {
|
static class BacklightAdapter {
|
||||||
@@ -1273,9 +1304,14 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set backlight within min and max backlight values
|
// Set backlight within min and max backlight values
|
||||||
void setBacklight(float backlight) {
|
void setBacklight(float sdrBacklight, float sdrNits, float backlight, float nits) {
|
||||||
if (mUseSurfaceControlBrightness || mForceSurfaceControl) {
|
if (mUseSurfaceControlBrightness || mForceSurfaceControl) {
|
||||||
|
if (sdrBacklight == PowerManager.BRIGHTNESS_INVALID_FLOAT) {
|
||||||
mSurfaceControlProxy.setDisplayBrightness(mDisplayToken, backlight);
|
mSurfaceControlProxy.setDisplayBrightness(mDisplayToken, backlight);
|
||||||
|
} else {
|
||||||
|
mSurfaceControlProxy.setDisplayBrightness(mDisplayToken, sdrBacklight, sdrNits,
|
||||||
|
backlight, nits);
|
||||||
|
}
|
||||||
} else if (mBacklight != null) {
|
} else if (mBacklight != null) {
|
||||||
mBacklight.setBrightness(backlight);
|
mBacklight.setBrightness(backlight);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import com.android.internal.display.BrightnessSynchronizer;
|
|||||||
* A custom animator that progressively updates a property value at
|
* A custom animator that progressively updates a property value at
|
||||||
* a given variable rate until it reaches a particular target value.
|
* a given variable rate until it reaches a particular target value.
|
||||||
*/
|
*/
|
||||||
final class RampAnimator<T> {
|
class RampAnimator<T> {
|
||||||
private final T mObject;
|
private final T mObject;
|
||||||
private final FloatProperty<T> mProperty;
|
private final FloatProperty<T> mProperty;
|
||||||
private final Choreographer mChoreographer;
|
private final Choreographer mChoreographer;
|
||||||
@@ -174,4 +174,52 @@ final class RampAnimator<T> {
|
|||||||
public interface Listener {
|
public interface Listener {
|
||||||
void onAnimationEnd();
|
void onAnimationEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class DualRampAnimator<T> {
|
||||||
|
private final RampAnimator<T> mFirst;
|
||||||
|
private final RampAnimator<T> mSecond;
|
||||||
|
private final Listener mInternalListener = new Listener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationEnd() {
|
||||||
|
if (mListener != null && !isAnimating()) {
|
||||||
|
mListener.onAnimationEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private Listener mListener;
|
||||||
|
|
||||||
|
DualRampAnimator(T object, FloatProperty<T> firstProperty,
|
||||||
|
FloatProperty<T> secondProperty) {
|
||||||
|
mFirst = new RampAnimator(object, firstProperty);
|
||||||
|
mFirst.setListener(mInternalListener);
|
||||||
|
mSecond = new RampAnimator(object, secondProperty);
|
||||||
|
mSecond.setListener(mInternalListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts animating towards the specified values.
|
||||||
|
*
|
||||||
|
* If this is the first time the property is being set or if the rate is 0,
|
||||||
|
* the value jumps directly to the target.
|
||||||
|
*
|
||||||
|
* @param firstTarget The first target value.
|
||||||
|
* @param secondTarget The second target value.
|
||||||
|
* @param rate The convergence rate in units per second, or 0 to set the value immediately.
|
||||||
|
* @return True if either target differs from the previous target.
|
||||||
|
*/
|
||||||
|
public boolean animateTo(float firstTarget, float secondTarget, float rate) {
|
||||||
|
final boolean firstRetval = mFirst.animateTo(firstTarget, rate);
|
||||||
|
final boolean secondRetval = mSecond.animateTo(secondTarget, rate);
|
||||||
|
return firstRetval && secondRetval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setListener(Listener listener) {
|
||||||
|
mListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAnimating() {
|
||||||
|
return mFirst.isAnimating() && mSecond.isAnimating();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -293,7 +293,8 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Runnable requestDisplayStateLocked(int state, float brightnessState) {
|
public Runnable requestDisplayStateLocked(int state, float brightnessState,
|
||||||
|
float sdrBrightnessState) {
|
||||||
if (state != mDisplayState) {
|
if (state != mDisplayState) {
|
||||||
mDisplayState = state;
|
mDisplayState = state;
|
||||||
if (state == Display.STATE_OFF) {
|
if (state == Display.STATE_OFF) {
|
||||||
|
|||||||
@@ -649,14 +649,14 @@ public class LocalDisplayAdapterTest {
|
|||||||
// Test as default display
|
// Test as default display
|
||||||
BacklightAdapter ba = new BacklightAdapter(displayToken, true /*isDefault*/,
|
BacklightAdapter ba = new BacklightAdapter(displayToken, true /*isDefault*/,
|
||||||
mSurfaceControlProxy);
|
mSurfaceControlProxy);
|
||||||
ba.setBacklight(0.514f);
|
ba.setBacklight(0.514f, 100f, 0.614f, 500f);
|
||||||
verify(mSurfaceControlProxy).setDisplayBrightness(displayToken, 0.514f);
|
verify(mSurfaceControlProxy).setDisplayBrightness(displayToken, 0.514f, 100f, 0.614f, 500f);
|
||||||
|
|
||||||
// Test as not default display
|
// Test as not default display
|
||||||
BacklightAdapter ba2 = new BacklightAdapter(displayToken, false /*isDefault*/,
|
BacklightAdapter ba2 = new BacklightAdapter(displayToken, false /*isDefault*/,
|
||||||
mSurfaceControlProxy);
|
mSurfaceControlProxy);
|
||||||
ba2.setBacklight(0.323f);
|
ba2.setBacklight(0.323f, 101f, 0.723f, 601f);
|
||||||
verify(mSurfaceControlProxy).setDisplayBrightness(displayToken, 0.323f);
|
verify(mSurfaceControlProxy).setDisplayBrightness(displayToken, 0.323f, 101f, 0.723f, 601f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -668,7 +668,7 @@ public class LocalDisplayAdapterTest {
|
|||||||
|
|
||||||
BacklightAdapter ba = new BacklightAdapter(displayToken, true /*isDefault*/,
|
BacklightAdapter ba = new BacklightAdapter(displayToken, true /*isDefault*/,
|
||||||
mSurfaceControlProxy);
|
mSurfaceControlProxy);
|
||||||
ba.setBacklight(0.123f);
|
ba.setBacklight(1f, 1f, 0.123f, 1f);
|
||||||
verify(mMockedBacklight).setBrightness(0.123f);
|
verify(mMockedBacklight).setBrightness(0.123f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -681,7 +681,7 @@ public class LocalDisplayAdapterTest {
|
|||||||
|
|
||||||
BacklightAdapter ba = new BacklightAdapter(displayToken, false /*isDefault*/,
|
BacklightAdapter ba = new BacklightAdapter(displayToken, false /*isDefault*/,
|
||||||
mSurfaceControlProxy);
|
mSurfaceControlProxy);
|
||||||
ba.setBacklight(0.456f);
|
ba.setBacklight(0.456f, 1f, 1f, 1f);
|
||||||
|
|
||||||
// Adapter does not forward any brightness in this case.
|
// Adapter does not forward any brightness in this case.
|
||||||
verify(mMockedBacklight, never()).setBrightness(anyFloat());
|
verify(mMockedBacklight, never()).setBrightness(anyFloat());
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import static android.hardware.display.BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLI
|
|||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import android.os.Binder;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.test.TestLooper;
|
import android.os.test.TestLooper;
|
||||||
@@ -55,6 +56,7 @@ public class HighBrightnessModeControllerTest {
|
|||||||
private OffsettableClock mClock;
|
private OffsettableClock mClock;
|
||||||
private TestLooper mTestLooper;
|
private TestLooper mTestLooper;
|
||||||
private Handler mHandler;
|
private Handler mHandler;
|
||||||
|
private Binder mDisplayToken;
|
||||||
|
|
||||||
private static final HighBrightnessModeData DEFAULT_HBM_DATA =
|
private static final HighBrightnessModeData DEFAULT_HBM_DATA =
|
||||||
new HighBrightnessModeData(MINIMUM_LUX, TRANSITION_POINT, TIME_WINDOW_MILLIS,
|
new HighBrightnessModeData(MINIMUM_LUX, TRANSITION_POINT, TIME_WINDOW_MILLIS,
|
||||||
@@ -64,6 +66,7 @@ public class HighBrightnessModeControllerTest {
|
|||||||
public void setUp() {
|
public void setUp() {
|
||||||
mClock = new OffsettableClock.Stopped();
|
mClock = new OffsettableClock.Stopped();
|
||||||
mTestLooper = new TestLooper(mClock::now);
|
mTestLooper = new TestLooper(mClock::now);
|
||||||
|
mDisplayToken = null;
|
||||||
mHandler = new Handler(mTestLooper.getLooper(), new Handler.Callback() {
|
mHandler = new Handler(mTestLooper.getLooper(), new Handler.Callback() {
|
||||||
@Override
|
@Override
|
||||||
public boolean handleMessage(Message msg) {
|
public boolean handleMessage(Message msg) {
|
||||||
@@ -79,14 +82,14 @@ public class HighBrightnessModeControllerTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testNoHbmData() {
|
public void testNoHbmData() {
|
||||||
final HighBrightnessModeController hbmc = new HighBrightnessModeController(
|
final HighBrightnessModeController hbmc = new HighBrightnessModeController(
|
||||||
mClock::now, mHandler, DEFAULT_MIN, DEFAULT_MAX, null, () -> {});
|
mClock::now, mHandler, mDisplayToken, DEFAULT_MIN, DEFAULT_MAX, null, () -> {});
|
||||||
assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_OFF);
|
assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_OFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNoHbmData_Enabled() {
|
public void testNoHbmData_Enabled() {
|
||||||
final HighBrightnessModeController hbmc = new HighBrightnessModeController(
|
final HighBrightnessModeController hbmc = new HighBrightnessModeController(
|
||||||
mClock::now, mHandler, DEFAULT_MIN, DEFAULT_MAX, null, () -> {});
|
mClock::now, mHandler, mDisplayToken, DEFAULT_MIN, DEFAULT_MAX, null, () -> {});
|
||||||
hbmc.setAutoBrightnessEnabled(true);
|
hbmc.setAutoBrightnessEnabled(true);
|
||||||
hbmc.onAmbientLuxChange(MINIMUM_LUX - 1); // below allowed range
|
hbmc.onAmbientLuxChange(MINIMUM_LUX - 1); // below allowed range
|
||||||
assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_OFF);
|
assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_OFF);
|
||||||
@@ -264,8 +267,8 @@ public class HighBrightnessModeControllerTest {
|
|||||||
|
|
||||||
// Creates instance with standard initialization values.
|
// Creates instance with standard initialization values.
|
||||||
private HighBrightnessModeController createDefaultHbm() {
|
private HighBrightnessModeController createDefaultHbm() {
|
||||||
return new HighBrightnessModeController(mClock::now, mHandler, DEFAULT_MIN, DEFAULT_MAX,
|
return new HighBrightnessModeController(mClock::now, mHandler, mDisplayToken, DEFAULT_MIN,
|
||||||
DEFAULT_HBM_DATA, () -> {});
|
DEFAULT_MAX, DEFAULT_HBM_DATA, () -> {});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void advanceTime(long timeMs) {
|
private void advanceTime(long timeMs) {
|
||||||
|
|||||||
Reference in New Issue
Block a user