Merge "Add HDR-HBM support into framework." into sc-dev

This commit is contained in:
Santos Cordon
2021-04-30 14:40:35 +00:00
committed by Android (Google) Code Review
14 changed files with 461 additions and 103 deletions

View File

@@ -33,7 +33,8 @@ public final class BrightnessInfo implements Parcelable {
@IntDef(prefix = {"HIGH_BRIGHTNESS_MODE_"}, value = {
HIGH_BRIGHTNESS_MODE_OFF,
HIGH_BRIGHTNESS_MODE_SUNLIGHT
HIGH_BRIGHTNESS_MODE_SUNLIGHT,
HIGH_BRIGHTNESS_MODE_HDR
})
@Retention(RetentionPolicy.SOURCE)
public @interface HighBrightnessMode {}
@@ -50,6 +51,12 @@ public final class BrightnessInfo implements Parcelable {
*/
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 */
public final float brightness;
@@ -73,6 +80,21 @@ public final class BrightnessInfo implements Parcelable {
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
public int describeContents() {
return 0;

View File

@@ -738,13 +738,19 @@ class AutomaticBrightnessController {
float value = mBrightnessMapper.getBrightness(mAmbientLux, mForegroundAppPackageName,
mForegroundAppCategory);
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,
// in which case we ignore the new screen brightness if it doesn't differ enough from the
// previous one.
if (!Float.isNaN(mScreenAutoBrightness)
&& !isManuallySet
&& newScreenAutoBrightness > mScreenDarkeningThreshold
&& newScreenAutoBrightness < mScreenBrighteningThreshold) {
&& newScreenAutoBrightness < mScreenBrighteningThreshold
&& currentBrightnessWithinAllowedRange) {
if (mLoggingEnabled) {
Slog.d(TAG, "ignoring newScreenAutoBrightness: "
+ mScreenDarkeningThreshold + " < " + newScreenAutoBrightness

View File

@@ -20,5 +20,8 @@ package com.android.server.display;
* Interface used to update the actual display state.
*/
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);
}

View File

@@ -156,10 +156,12 @@ abstract class DisplayDevice {
*
* @param state The new display state.
* @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
* 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;
}

View File

@@ -104,6 +104,7 @@ public class DisplayDeviceConfig {
private float mBrightnessRampSlowIncrease = Float.NaN;
private Spline mBrightnessToBacklightSpline;
private Spline mBacklightToBrightnessSpline;
private Spline mBacklightToNitsSpline;
private List<String> mQuirks;
private boolean mIsHighBrightnessModeEnabled = false;
private HighBrightnessModeData mHbmData;
@@ -218,6 +219,20 @@ public class DisplayDeviceConfig {
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
* brightness range of 0.0-1.0.
@@ -257,6 +272,13 @@ public class DisplayDeviceConfig {
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.
* @return {@code true} if the specified quirk is present in this configuration,
@@ -584,6 +606,7 @@ public class DisplayDeviceConfig {
}
mBrightnessToBacklightSpline = Spline.createSpline(mBrightness, mBacklight);
mBacklightToBrightnessSpline = Spline.createSpline(mBacklight, mBrightness);
mBacklightToNitsSpline = Spline.createSpline(mBacklight, mNits);
}
private void loadQuirks(DisplayConfiguration config) {

View File

@@ -257,7 +257,8 @@ public final class DisplayManagerService extends SystemService {
private final DisplayBlanker mDisplayBlanker = new DisplayBlanker() {
// Synchronized to avoid race conditions when updating multiple display states.
@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 allOff = true;
final boolean stateChanged;
@@ -288,7 +289,7 @@ public final class DisplayManagerService extends SystemService {
// The order of operations is important for legacy reasons.
if (state == Display.STATE_OFF) {
requestDisplayStateInternal(displayId, state, brightness);
requestDisplayStateInternal(displayId, state, brightness, sdrBrightness);
}
if (stateChanged) {
@@ -296,7 +297,7 @@ public final class DisplayManagerService extends SystemService {
}
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.
@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
// to the surface flinger state.
@@ -667,11 +668,8 @@ public final class DisplayManagerService extends SystemService {
}
}
private void requestDisplayStateInternal(int displayId, int state, float brightnessState) {
if (state == Display.STATE_UNKNOWN) {
state = Display.STATE_ON;
}
if (state == Display.STATE_OFF) {
private float clampBrightness(int displayState, float brightnessState) {
if (displayState == Display.STATE_OFF) {
brightnessState = PowerManager.BRIGHTNESS_OFF_FLOAT;
} else if (brightnessState != PowerManager.BRIGHTNESS_OFF_FLOAT
&& brightnessState < PowerManager.BRIGHTNESS_MIN) {
@@ -679,6 +677,17 @@ public final class DisplayManagerService extends SystemService {
} else if (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.
// Note that we do not need to schedule traversals here although it
@@ -688,20 +697,26 @@ public final class DisplayManagerService extends SystemService {
synchronized (mSyncRoot) {
final int index = mDisplayStates.indexOfKey(displayId);
final BrightnessPair brightnessPair =
index < 0 ? null : mDisplayBrightnesses.valueAt(index);
if (index < 0 || (mDisplayStates.valueAt(index) == state
&& BrightnessSynchronizer.floatEquals(mDisplayBrightnesses.valueAt(index),
brightnessState))) {
&& BrightnessSynchronizer.floatEquals(
brightnessPair.brightness, brightnessState)
&& BrightnessSynchronizer.floatEquals(
brightnessPair.sdrBrightness, sdrBrightnessState))) {
return; // Display no longer exists or no change.
}
traceMessage = "requestDisplayStateInternal("
+ displayId + ", "
+ Display.stateToString(state)
+ ", brightness=" + brightnessState + ")";
+ ", brightness=" + brightnessState
+ ", sdrBrightness=" + sdrBrightnessState + ")";
Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, traceMessage, displayId);
mDisplayStates.setValueAt(index, state);
mDisplayBrightnesses.setValueAt(index, brightnessState);
brightnessPair.brightness = brightnessState;
brightnessPair.sdrBrightness = sdrBrightnessState;
runnable = updateDisplayStateLocked(mLogicalDisplayMapper.getDisplayLocked(displayId)
.getPrimaryDisplayDeviceLocked());
}
@@ -1235,7 +1250,9 @@ public final class DisplayManagerService extends SystemService {
addDisplayPowerControllerLocked(display);
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();
@@ -1265,11 +1282,6 @@ public final class DisplayManagerService extends SystemService {
// this point.
sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
scheduleTraversalLocked(false);
DisplayPowerController dpc = mDisplayPowerControllers.get(displayId);
if (dpc != null) {
dpc.onDisplayChanged();
}
}
private void handleLogicalDisplayFrameRateOverridesChangedLocked(
@@ -1301,6 +1313,11 @@ public final class DisplayManagerService extends SystemService {
if (work != null) {
mHandler.post(work);
}
final int displayId = display.getDisplayIdLocked();
DisplayPowerController dpc = mDisplayPowerControllers.get(displayId);
if (dpc != null) {
dpc.onDisplayChanged();
}
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.
if (state != Display.STATE_UNKNOWN) {
final float brightness = mDisplayBrightnesses.get(displayId);
return device.requestDisplayStateLocked(state, brightness);
final BrightnessPair brightnessPair = mDisplayBrightnesses.get(displayId);
return device.requestDisplayStateLocked(state, brightnessPair.brightness,
brightnessPair.sdrBrightness);
}
}
return null;
@@ -1935,10 +1953,11 @@ public final class DisplayManagerService extends SystemService {
for (int i = 0; i < displayStateCount; i++) {
final int displayId = mDisplayStates.keyAt(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 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, " ");
@@ -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.
* TODO(b/184781936): merge with PowerManagerService.Clock
@@ -3288,5 +3317,4 @@ public final class DisplayManagerService extends SystemService {
*/
long uptimeMillis();
}
}

View File

@@ -38,6 +38,7 @@ import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
import android.metrics.LogMaker;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
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.server.LocalServices;
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.ReduceBrightColorsListener;
import com.android.server.display.whitebalance.DisplayWhiteBalanceController;
@@ -223,6 +225,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
@GuardedBy("mCachedBrightnessInfo")
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
// a stylish color fade animation instead.
private boolean mColorFadeFadesConfig;
@@ -424,7 +428,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// Animators.
private ObjectAnimator mColorFadeOnAnimator;
private ObjectAnimator mColorFadeOffAnimator;
private RampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator;
private DualRampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator;
private BrightnessSetting.BrightnessSettingListener mBrightnessSettingListener;
// 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) {
mLogicalDisplay = logicalDisplay;
mDisplayId = mLogicalDisplay.getDisplayIdLocked();
mDisplayDevice = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
mHandler = new DisplayControllerHandler(handler.getLooper());
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
* of each display need to be properly reflected in AutomaticBrightnessController.
*/
@GuardedBy("DisplayManagerService.mSyncRoot")
public void onDisplayChanged() {
// TODO: b/175821789 - Support high brightness on multiple (folding) displays
mUniqueDisplayId = mLogicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId();
mDisplayDeviceConfig = mLogicalDisplay.getPrimaryDisplayDeviceLocked()
.getDisplayDeviceConfig();
loadAmbientLightSensor();
final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
if (device == null) {
Slog.wtf(TAG, "Display Device is null in DisplayPowerController for display: "
+ 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();
mHbmController.resetHbmData(token, config.getHighBrightnessModeData());
});
}
/**
@@ -855,8 +877,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mColorFadeOffAnimator.addListener(mAnimatorListener);
}
mScreenBrightnessRampAnimator = new RampAnimator<>(
mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS_FLOAT);
mScreenBrightnessRampAnimator = new DualRampAnimator<>(mPowerState,
DisplayPowerState.SCREEN_BRIGHTNESS_FLOAT,
DisplayPowerState.SCREEN_SDR_BRIGHTNESS_FLOAT);
mScreenBrightnessRampAnimator.setListener(mRampAnimatorListener);
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. */
private void cleanupHandlerThreadAfterStop() {
setProximitySensorEnabled(false);
mHbmController.stop();
mHandler.removeCallbacksAndMessages(null);
if (mUnfinishedBusiness) {
mCallbacks.releaseSuspendBlocker();
@@ -1205,9 +1229,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// timeout is about to expire.
if (mPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
if (brightnessState > PowerManager.BRIGHTNESS_MIN) {
brightnessState = Math.max(Math.min(brightnessState
- SCREEN_DIM_MINIMUM_REDUCTION_FLOAT,
mScreenBrightnessDimConfig), PowerManager.BRIGHTNESS_MIN);
brightnessState = Math.max(
Math.min(brightnessState - SCREEN_DIM_MINIMUM_REDUCTION_FLOAT,
mScreenBrightnessDimConfig),
PowerManager.BRIGHTNESS_MIN);
mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_DIMMED);
}
if (!mAppliedDimming) {
@@ -1282,12 +1307,27 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// transformations to the brightness have pushed it outside of the currently
// allowed range.
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 currentSdrBrightness = mPowerState.getSdrScreenBrightness();
if (isValidBrightnessValue(animateValue)
&& !BrightnessSynchronizer.floatEquals(animateValue, currentBrightness)) {
&& (!BrightnessSynchronizer.floatEquals(animateValue, currentBrightness)
|| !BrightnessSynchronizer.floatEquals(
sdrAnimateValue, currentSdrBrightness))) {
if (initialRampSkip || hasBrightnessBuckets
|| wasOrWillBeInVr || !isDisplayContentVisible || brightnessIsTemporary) {
animateScreenBrightness(animateValue, SCREEN_ANIMATION_RATE_MINIMUM);
animateScreenBrightness(animateValue, sdrAnimateValue,
SCREEN_ANIMATION_RATE_MINIMUM);
} else {
boolean isIncreasing = animateValue > currentBrightness;
final float rampSpeed;
@@ -1300,7 +1340,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
} else {
rampSpeed = mBrightnessRampRateFastDecrease;
}
animateScreenBrightness(animateValue, rampSpeed);
animateScreenBrightness(animateValue, sdrAnimateValue, rampSpeed);
}
}
@@ -1446,9 +1486,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
private HighBrightnessModeController createHbmController() {
final DisplayDeviceConfig ddConfig =
mLogicalDisplay.getPrimaryDisplayDeviceLocked().getDisplayDeviceConfig();
final IBinder displayToken =
mLogicalDisplay.getPrimaryDisplayDeviceLocked().getDisplayTokenLocked();
final DisplayDeviceConfig.HighBrightnessModeData hbmData =
ddConfig != null ? ddConfig.getHighBrightnessModeData() : null;
return new HighBrightnessModeController(mHandler, PowerManager.BRIGHTNESS_MIN,
return new HighBrightnessModeController(mHandler, displayToken, PowerManager.BRIGHTNESS_MIN,
PowerManager.BRIGHTNESS_MAX, hbmData,
() -> {
sendUpdatePowerStateLocked();
@@ -1596,11 +1638,12 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
&& brightnessState <= PowerManager.BRIGHTNESS_MAX;
}
private void animateScreenBrightness(float target, float rate) {
private void animateScreenBrightness(float target, float sdrTarget, float rate) {
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);
// TODO(b/153319140) remove when we can get this from the above trace invocation
SystemProperties.set("debug.tracing.screen_brightness", String.valueOf(target));
@@ -2295,6 +2338,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
return;
}
handleSettingsChange(false /*userSwitch*/);
break;
}
}
}
@@ -2392,7 +2436,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
static final int MODIFIER_DIMMED = 0x1;
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_*
// 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) {
sb.append(" dim");
}
if ((modifier & MODIFIER_HDR) != 0) {
sb.append(" hdr");
}
int strlen = sb.length();
if (sb.charAt(strlen - 1) == '[') {
sb.setLength(strlen - 2);

View File

@@ -62,6 +62,7 @@ final class DisplayPowerState {
private int mScreenState;
private float mScreenBrightness;
private float mSdrScreenBrightness;
private boolean mScreenReady;
private boolean mScreenUpdatePending;
@@ -92,6 +93,7 @@ final class DisplayPowerState {
mScreenState = displayState;
mScreenBrightness = (displayState != Display.STATE_OFF) ? PowerManager.BRIGHTNESS_MAX
: PowerManager.BRIGHTNESS_OFF_FLOAT;
mSdrScreenBrightness = mScreenBrightness;
scheduleScreenUpdate();
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.
*/
@@ -148,13 +163,39 @@ final class DisplayPowerState {
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.
*
* @param brightness The brightness, ranges from 0.0f (minimum / off) to 1.0f (brightest).
*/
public void setScreenBrightness(float brightness) {
if (mScreenBrightness != brightness) {
if (!BrightnessSynchronizer.floatEquals(mScreenBrightness, brightness)) {
if (DEBUG) {
Slog.d(TAG, "setScreenBrightness: brightness=" + brightness);
}
@@ -286,6 +327,7 @@ final class DisplayPowerState {
pw.println(" mStopped=" + mStopped);
pw.println(" mScreenState=" + Display.stateToString(mScreenState));
pw.println(" mScreenBrightness=" + mScreenBrightness);
pw.println(" mSdrScreenBrightness=" + mSdrScreenBrightness);
pw.println(" mScreenReady=" + mScreenReady);
pw.println(" mScreenUpdatePending=" + mScreenUpdatePending);
pw.println(" mColorFadePrepared=" + mColorFadePrepared);
@@ -332,7 +374,10 @@ final class DisplayPowerState {
float brightnessState = mScreenState != Display.STATE_OFF
&& 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) {
Slog.d(TAG, "Screen ready");
}
@@ -373,8 +418,10 @@ final class DisplayPowerState {
private int mPendingState = INITIAL_SCREEN_STATE;
private float mPendingBacklight = INITIAL_BACKLIGHT_FLOAT;
private float mPendingSdrBacklight = INITIAL_BACKLIGHT_FLOAT;
private int mActualState = INITIAL_SCREEN_STATE;
private float mActualBacklight = INITIAL_BACKLIGHT_FLOAT;
private float mActualSdrBacklight = INITIAL_BACKLIGHT_FLOAT;
private boolean mStateChangeInProgress;
private boolean mBacklightChangeInProgress;
@@ -382,11 +429,13 @@ final class DisplayPowerState {
super("PhotonicModulator");
}
public boolean setState(int state, float brightnessState) {
public boolean setState(int state, float brightnessState, float sdrBrightnessState) {
synchronized (mLock) {
boolean stateChanged = state != mPendingState;
boolean backlightChanged = !BrightnessSynchronizer.floatEquals(
brightnessState, mPendingBacklight);
boolean backlightChanged =
!BrightnessSynchronizer.floatEquals(brightnessState, mPendingBacklight)
|| !BrightnessSynchronizer.floatEquals(
sdrBrightnessState, mPendingSdrBacklight);
if (stateChanged || backlightChanged) {
if (DEBUG) {
Slog.d(TAG, "Requesting new screen state: state="
@@ -395,6 +444,7 @@ final class DisplayPowerState {
mPendingState = state;
mPendingBacklight = brightnessState;
mPendingSdrBacklight = sdrBrightnessState;
boolean changeInProgress = mStateChangeInProgress || mBacklightChangeInProgress;
mStateChangeInProgress = stateChanged || mStateChangeInProgress;
mBacklightChangeInProgress = backlightChanged || mBacklightChangeInProgress;
@@ -413,8 +463,10 @@ final class DisplayPowerState {
pw.println("Photonic Modulator State:");
pw.println(" mPendingState=" + Display.stateToString(mPendingState));
pw.println(" mPendingBacklight=" + mPendingBacklight);
pw.println(" mPendingSdrBacklight=" + mPendingSdrBacklight);
pw.println(" mActualState=" + Display.stateToString(mActualState));
pw.println(" mActualBacklight=" + mActualBacklight);
pw.println(" mActualSdrBacklight=" + mActualSdrBacklight);
pw.println(" mStateChangeInProgress=" + mStateChangeInProgress);
pw.println(" mBacklightChangeInProgress=" + mBacklightChangeInProgress);
}
@@ -427,13 +479,17 @@ final class DisplayPowerState {
final int state;
final boolean stateChanged;
final float brightnessState;
final float sdrBrightnessState;
final boolean backlightChanged;
synchronized (mLock) {
state = mPendingState;
stateChanged = (state != mActualState);
brightnessState = mPendingBacklight;
backlightChanged = !BrightnessSynchronizer.floatEquals(
brightnessState, mActualBacklight);
sdrBrightnessState = mPendingSdrBacklight;
backlightChanged =
!BrightnessSynchronizer.floatEquals(brightnessState, mActualBacklight)
|| !BrightnessSynchronizer.floatEquals(
sdrBrightnessState, mActualSdrBacklight);
if (!stateChanged) {
// State changed applied, notify outer class.
postScreenUpdateThreadSafe();
@@ -454,14 +510,17 @@ final class DisplayPowerState {
}
mActualState = state;
mActualBacklight = brightnessState;
mActualSdrBacklight = sdrBrightnessState;
}
// Apply pending change.
if (DEBUG) {
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);
}
}
}

View File

@@ -18,9 +18,11 @@ package com.android.server.display;
import android.hardware.display.BrightnessInfo;
import android.os.Handler;
import android.os.IBinder;
import android.os.PowerManager;
import android.os.SystemClock;
import android.util.Slog;
import android.view.SurfaceControlHdrLayerInfoListener;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.display.DisplayDeviceConfig.HighBrightnessModeData;
@@ -45,17 +47,21 @@ class HighBrightnessModeController {
private final float mBrightnessMin;
private final float mBrightnessMax;
private final HighBrightnessModeData mHbmData;
private final Handler mHandler;
private final Runnable mHbmChangeCallback;
private final Runnable mRecalcRunnable;
private final Clock mClock;
private SurfaceControlHdrLayerInfoListener mHdrListener;
private HighBrightnessModeData mHbmData;
private IBinder mRegisteredDisplayToken;
private boolean mIsInAllowedAmbientRange = false;
private boolean mIsTimeAvailable = false;
private boolean mIsAutoBrightnessEnabled = false;
private float mAutoBrightness;
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.
@@ -69,23 +75,26 @@ class HighBrightnessModeController {
*/
private LinkedList<HbmEvent> mEvents = new LinkedList<>();
HighBrightnessModeController(Handler handler, float brightnessMin, float brightnessMax,
HighBrightnessModeData hbmData, Runnable hbmChangeCallback) {
this(SystemClock::uptimeMillis, handler, brightnessMin, brightnessMax, hbmData,
hbmChangeCallback);
HighBrightnessModeController(Handler handler, IBinder displayToken, float brightnessMin,
float brightnessMax, HighBrightnessModeData hbmData, Runnable hbmChangeCallback) {
this(SystemClock::uptimeMillis, handler, displayToken, brightnessMin, brightnessMax,
hbmData, hbmChangeCallback);
}
@VisibleForTesting
HighBrightnessModeController(Clock clock, Handler handler, float brightnessMin,
float brightnessMax, HighBrightnessModeData hbmData, Runnable hbmChangeCallback) {
HighBrightnessModeController(Clock clock, Handler handler, IBinder displayToken,
float brightnessMin, float brightnessMax, HighBrightnessModeData hbmData,
Runnable hbmChangeCallback) {
mClock = clock;
mHandler = handler;
mBrightnessMin = brightnessMin;
mBrightnessMax = brightnessMax;
mHbmData = hbmData;
mHbmChangeCallback = hbmChangeCallback;
mAutoBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
mRecalcRunnable = this::recalculateTimeAllowance;
mHdrListener = new HdrListener();
resetHbmData(displayToken, hbmData);
}
void setAutoBrightnessEnabled(boolean isEnabled) {
@@ -117,6 +126,10 @@ class HighBrightnessModeController {
}
}
float getHdrBrightnessValue() {
return mBrightnessMax;
}
void onAmbientLuxChange(float ambientLux) {
if (!deviceSupportsHbm() || !mIsAutoBrightnessEnabled) {
return;
@@ -138,11 +151,12 @@ class HighBrightnessModeController {
// If we are starting or ending a high brightness mode session, store the current
// session in mRunningStartTimeMillis, or the old one in mEvents.
final boolean wasOldBrightnessHigh = oldAutoBrightness > mHbmData.transitionPoint;
final boolean isNewBrightnessHigh = mAutoBrightness > mHbmData.transitionPoint;
if (wasOldBrightnessHigh != isNewBrightnessHigh) {
final boolean wasHbmDrainingAvailableTime = mRunningStartTimeMillis != -1;
final boolean shouldHbmDrainAvailableTime = mAutoBrightness > mHbmData.transitionPoint
&& !mIsHdrLayerPresent;
if (wasHbmDrainingAvailableTime != shouldHbmDrainAvailableTime) {
final long currentTime = mClock.uptimeMillis();
if (isNewBrightnessHigh) {
if (shouldHbmDrainAvailableTime) {
mRunningStartTimeMillis = currentTime;
} else {
mEvents.addFirst(new HbmEvent(mRunningStartTimeMillis, currentTime));
@@ -161,30 +175,49 @@ class HighBrightnessModeController {
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) {
pw.println("HighBrightnessModeController:");
pw.println(" mBrightnessMin=" + mBrightnessMin);
pw.println(" mBrightnessMax=" + mBrightnessMax);
pw.println(" mCurrentMin=" + getCurrentBrightnessMin());
pw.println(" mCurrentMax=" + getCurrentBrightnessMax());
pw.println(" mHbmMode=" + BrightnessInfo.hbmToString(mHbmMode));
pw.println(" remainingTime=" + calculateRemainingTime(mClock.uptimeMillis()));
pw.println(" mHbmData=" + mHbmData);
pw.println(" mIsInAllowedAmbientRange=" + mIsInAllowedAmbientRange);
pw.println(" mIsTimeAvailable= " + mIsTimeAvailable);
pw.println(" mIsAutoBrightnessEnabled=" + mIsAutoBrightnessEnabled);
pw.println(" mAutoBrightness=" + mAutoBrightness);
pw.println(" mIsHdrLayerPresent=" + mIsHdrLayerPresent);
pw.println(" mBrightnessMin=" + mBrightnessMin);
pw.println(" mBrightnessMax=" + mBrightnessMax);
}
private boolean isCurrentlyAllowed() {
return mIsAutoBrightnessEnabled && mIsTimeAvailable && mIsInAllowedAmbientRange;
return mIsHdrLayerPresent
|| (mIsAutoBrightnessEnabled && mIsTimeAvailable && mIsInAllowedAmbientRange);
}
private boolean deviceSupportsHbm() {
return mHbmData != null;
}
/**
* Recalculates the allowable HBM time.
*/
private void recalculateTimeAllowance() {
final long currentTime = mClock.uptimeMillis();
private long calculateRemainingTime(long currentTime) {
if (!deviceSupportsHbm()) {
return 0;
}
long timeAlreadyUsed = 0;
// 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);
}
// See how much allowable time we have left.
final long remainingTime = Math.max(0, mHbmData.timeMaxMillis - timeAlreadyUsed);
return 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
// 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
// window by at least minTime. Basically, we're calculating the soonest time we can
// get {@code timeMinMillis} back to us.
final long windowstartTimeMillis = currentTime - mHbmData.timeWindowMillis;
final HbmEvent lastEvent = mEvents.getLast();
final long startTimePlusMinMillis =
Math.max(windowstartTimeMillis, lastEvent.startTimeMillis)
@@ -278,12 +319,36 @@ class HighBrightnessModeController {
}
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_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.
*/
@@ -302,4 +367,18 @@ class HighBrightnessModeController {
+ ((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);
});
}
}
}

View File

@@ -67,6 +67,8 @@ final class LocalDisplayAdapter extends DisplayAdapter {
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 Injector mInjector;
@@ -190,6 +192,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
private int mState = Display.STATE_UNKNOWN;
// This is only set in the runnable returned from requestDisplayStateLocked.
private float mBrightnessState = PowerManager.BRIGHTNESS_INVALID_FLOAT;
private float mSdrBrightnessState = PowerManager.BRIGHTNESS_INVALID_FLOAT;
private int mDefaultModeId;
private int mDefaultModeGroup;
private int mActiveModeId;
@@ -644,13 +647,15 @@ final class LocalDisplayAdapter extends DisplayAdapter {
}
@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.
assert state != Display.STATE_OFF || BrightnessSynchronizer.floatEquals(
brightnessState, PowerManager.BRIGHTNESS_OFF_FLOAT);
final boolean stateChanged = (mState != state);
final boolean brightnessChanged = (!BrightnessSynchronizer.floatEquals(
mBrightnessState, brightnessState));
final boolean brightnessChanged =
!(BrightnessSynchronizer.floatEquals(mBrightnessState, brightnessState)
&& BrightnessSynchronizer.floatEquals(mSdrBrightnessState, sdrBrightnessState));
if (stateChanged || brightnessChanged) {
final long physicalDisplayId = mPhysicalDisplayId;
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.
if (brightnessChanged || vrModeChange) {
setDisplayBrightness(brightnessState);
setDisplayBrightness(brightnessState, sdrBrightnessState);
mBrightnessState = brightnessState;
mSdrBrightnessState = sdrBrightnessState;
}
// Enter the final desired state, possibly suspended.
@@ -764,8 +770,8 @@ final class LocalDisplayAdapter extends DisplayAdapter {
}
}
private void setDisplayBrightness(float brightness) {
// Ensure brightnessState is valid, before processing and sending to
private void setDisplayBrightness(float brightness, float sdrBrightness) {
// Ensure brightnessState is valid before processing and sending to
// surface control
if (Float.isNaN(brightness)) {
return;
@@ -774,17 +780,31 @@ final class LocalDisplayAdapter extends DisplayAdapter {
if (DEBUG) {
Slog.d(TAG, "setDisplayBrightness("
+ "id=" + physicalDisplayId
+ ", brightness=" + brightness + ")");
+ ", brightness=" + brightness
+ ", sdrBrightness=" + sdrBrightness + ")");
}
Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayBrightness("
+ "id=" + physicalDisplayId + ", brightness=" + brightness + ")");
+ "id=" + physicalDisplayId + ", brightness=" + brightness
+ ", sdrBrightness=" + sdrBrightness + ")");
try {
float backlight = brightnessToBacklight(brightness);
mBacklightAdapter.setBacklight(backlight);
final float backlight = brightnessToBacklight(brightness);
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,
"ScreenBrightness",
BrightnessSynchronizer.brightnessFloatToInt(brightness));
Trace.traceCounter(Trace.TRACE_TAG_POWER,
"SdrScreenBrightness",
BrightnessSynchronizer.brightnessFloatToInt(sdrBrightness));
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
@@ -793,6 +813,10 @@ final class LocalDisplayAdapter extends DisplayAdapter {
private float brightnessToBacklight(float brightness) {
return getDisplayDeviceConfig().getBacklightFromBrightness(brightness);
}
private float backlightToNits(float backlight) {
return getDisplayDeviceConfig().getNitsFromBacklight(backlight);
}
};
}
return null;
@@ -1242,6 +1266,13 @@ final class LocalDisplayAdapter extends DisplayAdapter {
public boolean setDisplayBrightness(IBinder displayToken, float 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 {
@@ -1273,9 +1304,14 @@ final class LocalDisplayAdapter extends DisplayAdapter {
}
// 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) {
mSurfaceControlProxy.setDisplayBrightness(mDisplayToken, backlight);
if (sdrBacklight == PowerManager.BRIGHTNESS_INVALID_FLOAT) {
mSurfaceControlProxy.setDisplayBrightness(mDisplayToken, backlight);
} else {
mSurfaceControlProxy.setDisplayBrightness(mDisplayToken, sdrBacklight, sdrNits,
backlight, nits);
}
} else if (mBacklight != null) {
mBacklight.setBrightness(backlight);
}

View File

@@ -26,7 +26,7 @@ import com.android.internal.display.BrightnessSynchronizer;
* A custom animator that progressively updates a property value at
* a given variable rate until it reaches a particular target value.
*/
final class RampAnimator<T> {
class RampAnimator<T> {
private final T mObject;
private final FloatProperty<T> mProperty;
private final Choreographer mChoreographer;
@@ -174,4 +174,52 @@ final class RampAnimator<T> {
public interface Listener {
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();
}
}
}

View File

@@ -293,7 +293,8 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
}
@Override
public Runnable requestDisplayStateLocked(int state, float brightnessState) {
public Runnable requestDisplayStateLocked(int state, float brightnessState,
float sdrBrightnessState) {
if (state != mDisplayState) {
mDisplayState = state;
if (state == Display.STATE_OFF) {

View File

@@ -649,14 +649,14 @@ public class LocalDisplayAdapterTest {
// Test as default display
BacklightAdapter ba = new BacklightAdapter(displayToken, true /*isDefault*/,
mSurfaceControlProxy);
ba.setBacklight(0.514f);
verify(mSurfaceControlProxy).setDisplayBrightness(displayToken, 0.514f);
ba.setBacklight(0.514f, 100f, 0.614f, 500f);
verify(mSurfaceControlProxy).setDisplayBrightness(displayToken, 0.514f, 100f, 0.614f, 500f);
// Test as not default display
BacklightAdapter ba2 = new BacklightAdapter(displayToken, false /*isDefault*/,
mSurfaceControlProxy);
ba2.setBacklight(0.323f);
verify(mSurfaceControlProxy).setDisplayBrightness(displayToken, 0.323f);
ba2.setBacklight(0.323f, 101f, 0.723f, 601f);
verify(mSurfaceControlProxy).setDisplayBrightness(displayToken, 0.323f, 101f, 0.723f, 601f);
}
@Test
@@ -668,7 +668,7 @@ public class LocalDisplayAdapterTest {
BacklightAdapter ba = new BacklightAdapter(displayToken, true /*isDefault*/,
mSurfaceControlProxy);
ba.setBacklight(0.123f);
ba.setBacklight(1f, 1f, 0.123f, 1f);
verify(mMockedBacklight).setBrightness(0.123f);
}
@@ -681,7 +681,7 @@ public class LocalDisplayAdapterTest {
BacklightAdapter ba = new BacklightAdapter(displayToken, false /*isDefault*/,
mSurfaceControlProxy);
ba.setBacklight(0.456f);
ba.setBacklight(0.456f, 1f, 1f, 1f);
// Adapter does not forward any brightness in this case.
verify(mMockedBacklight, never()).setBrightness(anyFloat());

View File

@@ -21,6 +21,7 @@ import static android.hardware.display.BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLI
import static org.junit.Assert.assertEquals;
import android.os.Binder;
import android.os.Handler;
import android.os.Message;
import android.os.test.TestLooper;
@@ -55,6 +56,7 @@ public class HighBrightnessModeControllerTest {
private OffsettableClock mClock;
private TestLooper mTestLooper;
private Handler mHandler;
private Binder mDisplayToken;
private static final HighBrightnessModeData DEFAULT_HBM_DATA =
new HighBrightnessModeData(MINIMUM_LUX, TRANSITION_POINT, TIME_WINDOW_MILLIS,
@@ -64,6 +66,7 @@ public class HighBrightnessModeControllerTest {
public void setUp() {
mClock = new OffsettableClock.Stopped();
mTestLooper = new TestLooper(mClock::now);
mDisplayToken = null;
mHandler = new Handler(mTestLooper.getLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
@@ -79,14 +82,14 @@ public class HighBrightnessModeControllerTest {
@Test
public void testNoHbmData() {
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);
}
@Test
public void testNoHbmData_Enabled() {
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.onAmbientLuxChange(MINIMUM_LUX - 1); // below allowed range
assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_OFF);
@@ -264,8 +267,8 @@ public class HighBrightnessModeControllerTest {
// Creates instance with standard initialization values.
private HighBrightnessModeController createDefaultHbm() {
return new HighBrightnessModeController(mClock::now, mHandler, DEFAULT_MIN, DEFAULT_MAX,
DEFAULT_HBM_DATA, () -> {});
return new HighBrightnessModeController(mClock::now, mHandler, mDisplayToken, DEFAULT_MIN,
DEFAULT_MAX, DEFAULT_HBM_DATA, () -> {});
}
private void advanceTime(long timeMs) {