Merge "Clamp manual brightness on high brightness mode devices." into sc-dev

This commit is contained in:
Santos Cordon
2021-03-15 14:20:42 +00:00
committed by Android (Google) Code Review
4 changed files with 72 additions and 38 deletions

View File

@@ -46,7 +46,6 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.display.BrightnessSynchronizer;
import com.android.internal.os.BackgroundThread;
import com.android.server.EventLogTags;
import com.android.server.display.DisplayDeviceConfig.HighBrightnessModeData;
import java.io.PrintWriter;
@@ -220,12 +219,14 @@ class AutomaticBrightnessController {
float dozeScaleFactor, int lightSensorRate, int initialLightSensorRate,
long brighteningLightDebounceConfig, long darkeningLightDebounceConfig,
boolean resetAmbientLuxAfterWarmUpConfig, HysteresisLevels ambientBrightnessThresholds,
HysteresisLevels screenBrightnessThresholds, LogicalDisplay display, Context context) {
HysteresisLevels screenBrightnessThresholds, LogicalDisplay display, Context context,
HighBrightnessModeController hbmController) {
this(new Injector(), callbacks, looper, sensorManager, lightSensor, mapper,
lightSensorWarmUpTime, brightnessMin, brightnessMax, dozeScaleFactor,
lightSensorRate, initialLightSensorRate, brighteningLightDebounceConfig,
darkeningLightDebounceConfig, resetAmbientLuxAfterWarmUpConfig,
ambientBrightnessThresholds, screenBrightnessThresholds, display, context
ambientBrightnessThresholds, screenBrightnessThresholds, display, context,
hbmController
);
}
@@ -236,7 +237,8 @@ class AutomaticBrightnessController {
float dozeScaleFactor, int lightSensorRate, int initialLightSensorRate,
long brighteningLightDebounceConfig, long darkeningLightDebounceConfig,
boolean resetAmbientLuxAfterWarmUpConfig, HysteresisLevels ambientBrightnessThresholds,
HysteresisLevels screenBrightnessThresholds, LogicalDisplay display, Context context) {
HysteresisLevels screenBrightnessThresholds, LogicalDisplay display, Context context,
HighBrightnessModeController hbmController) {
mInjector = injector;
mContext = context;
mCallbacks = callbacks;
@@ -273,20 +275,7 @@ class AutomaticBrightnessController {
mPendingForegroundAppPackageName = null;
mForegroundAppCategory = ApplicationInfo.CATEGORY_UNDEFINED;
mPendingForegroundAppCategory = ApplicationInfo.CATEGORY_UNDEFINED;
final DisplayDeviceConfig ddConfig =
display.getPrimaryDisplayDeviceLocked().getDisplayDeviceConfig();
HighBrightnessModeData hbmData =
ddConfig != null ? ddConfig.getHighBrightnessModeData() : null;
final Runnable hbmChangeCallback = () -> {
updateAutoBrightness(true /*sendUpdate*/, false /*userInitiatedChange*/);
// TODO: b/175937645 - Callback to DisplayManagerService to indicate a change to the HBM
// allowance has been made so that the brightness limits can be calculated
// appropriately.
};
mHbmController = new HighBrightnessModeController(mHandler, brightnessMin, brightnessMax,
hbmData, hbmChangeCallback);
mHbmController = hbmController;
}
/**
@@ -327,6 +316,7 @@ class AutomaticBrightnessController {
public void configure(boolean enable, @Nullable BrightnessConfiguration configuration,
float brightness, boolean userChangedBrightness, float adjustment,
boolean userChangedAutoBrightnessAdjustment, int displayPolicy) {
mHbmController.setAutoBrightnessEnabled(enable);
// While dozing, the application processor may be suspended which will prevent us from
// receiving new information from the light sensor. On some devices, we may be able to
// switch to a wake-up light sensor instead but for now we will simply disable the sensor

View File

@@ -350,12 +350,15 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
private final ColorDisplayServiceInternal mCdsi;
private final float[] mNitsRange;
private final HighBrightnessModeController mHbmController;
// A record of state for skipping brightness ramps.
private int mSkipRampState = RAMP_STATE_SKIP_NONE;
// The first autobrightness value set when entering RAMP_STATE_SKIP_INITIAL.
private float mInitialAutoBrightness;
// The controller for the automatic brightness level.
private AutomaticBrightnessController mAutomaticBrightnessController;
@@ -433,6 +436,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mBlanker = blanker;
mContext = context;
PowerManager pm = context.getSystemService(PowerManager.class);
final Resources resources = context.getResources();
@@ -476,6 +480,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mSkipScreenOnBrightnessRamp = resources.getBoolean(
com.android.internal.R.bool.config_skipScreenOnBrightnessRamp);
mHbmController = createHbmController();
if (mUseSoftwareAutoBrightnessConfig) {
final float dozeScaleFactor = resources.getFraction(
com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor,
@@ -535,7 +541,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
PowerManager.BRIGHTNESS_MAX, dozeScaleFactor, lightSensorRate,
initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce,
autoBrightnessResetAmbientLuxAfterWarmUp, ambientBrightnessThresholds,
screenBrightnessThresholds, logicalDisplay, context);
screenBrightnessThresholds, logicalDisplay, context, mHbmController);
} else {
mUseSoftwareAutoBrightnessConfig = false;
}
@@ -1081,6 +1087,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mBrightnessTracker.setBrightnessConfiguration(mBrightnessConfiguration);
}
boolean updateScreenBrightnessSetting = false;
// Apply auto-brightness.
boolean slowChange = false;
if (Float.isNaN(brightnessState)) {
@@ -1097,11 +1105,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
if (mAppliedAutoBrightness && !autoBrightnessAdjustmentChanged) {
slowChange = true; // slowly adapt to auto-brightness
}
// Tell the rest of the system about the new brightness. Note that we do this
// before applying the low power or dim transformations so that the slider
// accurately represents the full possible range, even if they range changes what
// it means in absolute terms.
putScreenBrightnessSetting(brightnessState);
updateScreenBrightnessSetting = true;
mAppliedAutoBrightness = true;
mBrightnessReasonTemp.setReason(BrightnessReason.REASON_AUTOMATIC);
} else {
@@ -1119,6 +1123,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mAppliedAutoBrightness = false;
brightnessAdjustmentFlags = 0;
}
// Use default brightness when dozing unless overridden.
if ((Float.isNaN(brightnessState))
&& Display.isDozeState(state)) {
@@ -1129,9 +1134,24 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// Apply manual brightness.
if (Float.isNaN(brightnessState)) {
brightnessState = clampScreenBrightness(mCurrentScreenBrightnessSetting);
if (brightnessState != mCurrentScreenBrightnessSetting) {
// The manually chosen screen brightness is outside of the currently allowed
// range (i.e., high-brightness-mode), make sure we tell the rest of the system
// by updating the setting.
updateScreenBrightnessSetting = true;
}
mBrightnessReasonTemp.setReason(BrightnessReason.REASON_MANUAL);
}
if (updateScreenBrightnessSetting) {
// Tell the rest of the system about the new brightness in case we had to change it
// for things like auto-brightness or high-brightness-mode. Note that we do this
// before applying the low power or dim transformations so that the slider
// accurately represents the full possible range, even if they range changes what
// it means in absolute terms.
putScreenBrightnessSetting(brightnessState);
}
// Apply dimming by at least some minimum amount when user activity
// timeout is about to expire.
if (mPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
@@ -1209,9 +1229,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// animate to. To avoid this, we check the value first.
// If the brightnessState is off (-1.0f) we still want to animate to the minimum
// brightness (0.0f) to accommodate for LED displays, which can appear bright to the
// user even when the display is all black.
float animateValue = brightnessState == PowerManager.BRIGHTNESS_OFF_FLOAT
? PowerManager.BRIGHTNESS_MIN : brightnessState;
// user even when the display is all black. We also clamp here in case some
// transformations to the brightness have pushed it outside of the currently
// allowed range.
float animateValue = clampScreenBrightness(brightnessState);
final float currentBrightness = mPowerState.getScreenBrightness();
if (isValidBrightnessValue(animateValue)
&& !BrightnessSynchronizer.floatEquals(animateValue, currentBrightness)) {
@@ -1354,6 +1375,15 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
msg.sendToTarget();
}
private HighBrightnessModeController createHbmController() {
final DisplayDeviceConfig ddConfig =
mLogicalDisplay.getPrimaryDisplayDeviceLocked().getDisplayDeviceConfig();
final DisplayDeviceConfig.HighBrightnessModeData hbmData =
ddConfig != null ? ddConfig.getHighBrightnessModeData() : null;
return new HighBrightnessModeController(mHandler, PowerManager.BRIGHTNESS_MIN,
PowerManager.BRIGHTNESS_MAX, hbmData, () -> sendUpdatePowerStateLocked());
}
private void blockScreenOn() {
if (mPendingScreenOnUnblocker == null) {
Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0);
@@ -1469,10 +1499,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
private float clampScreenBrightness(float value) {
if (Float.isNaN(value)) {
return PowerManager.BRIGHTNESS_MIN;
value = PowerManager.BRIGHTNESS_MIN;
}
return MathUtils.constrain(
value, PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX);
return MathUtils.constrain(value,
mHbmController.getCurrentBrightnessMin(), mHbmController.getCurrentBrightnessMax());
}
// Checks whether the brightness is within the valid brightness range, not including the off or

View File

@@ -37,7 +37,7 @@ import java.util.LinkedList;
class HighBrightnessModeController {
private static final String TAG = "HighBrightnessModeController";
private static final boolean DEBUG_HBM = false;
private static final boolean DEBUG = false;
private final float mBrightnessMin;
private final float mBrightnessMax;
@@ -48,6 +48,7 @@ class HighBrightnessModeController {
private boolean mIsInAllowedAmbientRange = false;
private boolean mIsTimeAvailable = false;
private boolean mIsAutoBrightnessEnabled = false;
private float mAutoBrightness;
/**
@@ -84,6 +85,17 @@ class HighBrightnessModeController {
};
}
void setAutoBrightnessEnabled(boolean isEnabled) {
if (isEnabled == mIsAutoBrightnessEnabled) {
return;
}
if (DEBUG) {
Slog.d(TAG, "setAutoBrightness( " + isEnabled + " )");
}
mIsAutoBrightnessEnabled = isEnabled;
mIsInAllowedAmbientRange = false; // reset when auto-brightness switches
}
float getCurrentBrightnessMin() {
return mBrightnessMin;
}
@@ -102,7 +114,7 @@ class HighBrightnessModeController {
}
void onAmbientLuxChange(float ambientLux) {
if (!deviceSupportsHbm()) {
if (!deviceSupportsHbm() || !mIsAutoBrightnessEnabled) {
return;
}
@@ -132,7 +144,7 @@ class HighBrightnessModeController {
mEvents.addFirst(new HbmEvent(mRunningStartTimeMillis, currentTime));
mRunningStartTimeMillis = -1;
if (DEBUG_HBM) {
if (DEBUG) {
Slog.d(TAG, "New HBM event: " + mEvents.getFirst());
}
}
@@ -142,7 +154,7 @@ class HighBrightnessModeController {
}
private boolean isCurrentlyAllowed() {
return mIsTimeAvailable && mIsInAllowedAmbientRange;
return mIsAutoBrightnessEnabled && mIsTimeAvailable && mIsInAllowedAmbientRange;
}
private boolean deviceSupportsHbm() {
@@ -167,7 +179,7 @@ class HighBrightnessModeController {
timeAlreadyUsed = currentTime - mRunningStartTimeMillis;
}
if (DEBUG_HBM) {
if (DEBUG) {
Slog.d(TAG, "Time already used after current session: " + timeAlreadyUsed);
}
@@ -187,7 +199,7 @@ class HighBrightnessModeController {
timeAlreadyUsed += event.endTimeMillis - startTimeMillis;
}
if (DEBUG_HBM) {
if (DEBUG) {
Slog.d(TAG, "Time already used after all sessions: " + timeAlreadyUsed);
}
@@ -220,7 +232,7 @@ class HighBrightnessModeController {
nextTimeout = timeWhenMinIsGainedBack;
}
if (DEBUG_HBM) {
if (DEBUG) {
Slog.d(TAG, "HBM recalculated. IsAllowedWithoutRestrictions: "
+ isAllowedWithoutRestrictions
+ ", isOnlyAllowedToStayOn: " + isOnlyAllowedToStayOn

View File

@@ -65,6 +65,7 @@ public class AutomaticBrightnessControllerTest {
@Mock HysteresisLevels mScreenBrightnessThresholds;
@Mock Handler mNoOpHandler;
@Mock DisplayDevice mDisplayDevice;
@Mock HighBrightnessModeController mHbmController;
private static final int LIGHT_SENSOR_WARMUP_TIME = 0;
@Before
@@ -90,7 +91,8 @@ public class AutomaticBrightnessControllerTest {
BRIGHTNESS_MAX_FLOAT, DOZE_SCALE_FACTOR, LIGHT_SENSOR_RATE,
INITIAL_LIGHT_SENSOR_RATE, BRIGHTENING_LIGHT_DEBOUNCE_CONFIG,
DARKENING_LIGHT_DEBOUNCE_CONFIG, RESET_AMBIENT_LUX_AFTER_WARMUP_CONFIG,
mAmbientBrightnessThresholds, mScreenBrightnessThresholds, mLogicalDisplay, mContext
mAmbientBrightnessThresholds, mScreenBrightnessThresholds, mLogicalDisplay,
mContext, mHbmController
);
controller.setLoggingEnabled(true);