Merge "Reflect BrightnessThrottler effects in Settings, UI and ABC"
This commit is contained in:
committed by
Android (Google) Code Review
commit
1f77cfffc4
@@ -201,6 +201,10 @@ class AutomaticBrightnessController {
|
||||
// Controls High Brightness Mode.
|
||||
private HighBrightnessModeController mHbmController;
|
||||
|
||||
// Throttles (caps) maximum allowed brightness
|
||||
private BrightnessThrottler mBrightnessThrottler;
|
||||
private boolean mIsBrightnessThrottled;
|
||||
|
||||
// Context-sensitive brightness configurations require keeping track of the foreground app's
|
||||
// package name and category, which is done by registering a TaskStackListener to call back to
|
||||
// us onTaskStackChanged, and then using the ActivityTaskManager to get the foreground app's
|
||||
@@ -226,7 +230,7 @@ class AutomaticBrightnessController {
|
||||
long brighteningLightDebounceConfig, long darkeningLightDebounceConfig,
|
||||
boolean resetAmbientLuxAfterWarmUpConfig, HysteresisLevels ambientBrightnessThresholds,
|
||||
HysteresisLevels screenBrightnessThresholds, Context context,
|
||||
HighBrightnessModeController hbmController,
|
||||
HighBrightnessModeController hbmController, BrightnessThrottler brightnessThrottler,
|
||||
BrightnessMappingStrategy idleModeBrightnessMapper, int ambientLightHorizonShort,
|
||||
int ambientLightHorizonLong) {
|
||||
this(new Injector(), callbacks, looper, sensorManager, lightSensor,
|
||||
@@ -235,8 +239,8 @@ class AutomaticBrightnessController {
|
||||
lightSensorRate, initialLightSensorRate, brighteningLightDebounceConfig,
|
||||
darkeningLightDebounceConfig, resetAmbientLuxAfterWarmUpConfig,
|
||||
ambientBrightnessThresholds, screenBrightnessThresholds, context,
|
||||
hbmController, idleModeBrightnessMapper, ambientLightHorizonShort,
|
||||
ambientLightHorizonLong
|
||||
hbmController, brightnessThrottler, idleModeBrightnessMapper,
|
||||
ambientLightHorizonShort, ambientLightHorizonLong
|
||||
);
|
||||
}
|
||||
|
||||
@@ -249,7 +253,7 @@ class AutomaticBrightnessController {
|
||||
long brighteningLightDebounceConfig, long darkeningLightDebounceConfig,
|
||||
boolean resetAmbientLuxAfterWarmUpConfig, HysteresisLevels ambientBrightnessThresholds,
|
||||
HysteresisLevels screenBrightnessThresholds, Context context,
|
||||
HighBrightnessModeController hbmController,
|
||||
HighBrightnessModeController hbmController, BrightnessThrottler brightnessThrottler,
|
||||
BrightnessMappingStrategy idleModeBrightnessMapper, int ambientLightHorizonShort,
|
||||
int ambientLightHorizonLong) {
|
||||
mInjector = injector;
|
||||
@@ -291,6 +295,7 @@ class AutomaticBrightnessController {
|
||||
mForegroundAppCategory = ApplicationInfo.CATEGORY_UNDEFINED;
|
||||
mPendingForegroundAppCategory = ApplicationInfo.CATEGORY_UNDEFINED;
|
||||
mHbmController = hbmController;
|
||||
mBrightnessThrottler = brightnessThrottler;
|
||||
mInteractiveModeBrightnessMapper = interactiveModeBrightnessMapper;
|
||||
mIdleModeBrightnessMapper = idleModeBrightnessMapper;
|
||||
// Initialize to active (normal) screen brightness mode
|
||||
@@ -365,6 +370,13 @@ class AutomaticBrightnessController {
|
||||
prepareBrightnessAdjustmentSample();
|
||||
}
|
||||
changed |= setLightSensorEnabled(enable && !dozing);
|
||||
|
||||
if (mIsBrightnessThrottled != mBrightnessThrottler.isThrottled()) {
|
||||
// Maximum brightness has changed, so recalculate display brightness.
|
||||
mIsBrightnessThrottled = mBrightnessThrottler.isThrottled();
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
updateAutoBrightness(false /*sendUpdate*/, userInitiatedChange);
|
||||
}
|
||||
@@ -855,8 +867,11 @@ class AutomaticBrightnessController {
|
||||
|
||||
// Clamps values with float range [0.0-1.0]
|
||||
private float clampScreenBrightness(float value) {
|
||||
return MathUtils.constrain(value,
|
||||
mHbmController.getCurrentBrightnessMin(), mHbmController.getCurrentBrightnessMax());
|
||||
final float minBrightness = Math.min(mHbmController.getCurrentBrightnessMin(),
|
||||
mBrightnessThrottler.getBrightnessCap());
|
||||
final float maxBrightness = Math.min(mHbmController.getCurrentBrightnessMax(),
|
||||
mBrightnessThrottler.getBrightnessCap());
|
||||
return MathUtils.constrain(value, minBrightness, maxBrightness);
|
||||
}
|
||||
|
||||
private void prepareBrightnessAdjustmentSample() {
|
||||
|
||||
@@ -974,7 +974,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
lightSensorRate, initialLightSensorRate, brighteningLightDebounce,
|
||||
darkeningLightDebounce, autoBrightnessResetAmbientLuxAfterWarmUp,
|
||||
ambientBrightnessThresholds, screenBrightnessThresholds, mContext,
|
||||
mHbmController, mIdleModeBrightnessMapper,
|
||||
mHbmController, mBrightnessThrottler, mIdleModeBrightnessMapper,
|
||||
mDisplayDeviceConfig.getAmbientHorizonShort(),
|
||||
mDisplayDeviceConfig.getAmbientHorizonLong());
|
||||
} else {
|
||||
@@ -1347,6 +1347,29 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
mBrightnessReasonTemp.setReason(BrightnessReason.REASON_MANUAL);
|
||||
}
|
||||
|
||||
// Now that a desired brightness has been calculated, apply brightness throttling. The
|
||||
// dimming and low power transformations that follow can only dim brightness further.
|
||||
//
|
||||
// We didn't do this earlier through brightness clamping because we need to know both
|
||||
// unthrottled (unclamped/ideal) and throttled brightness levels for subsequent operations.
|
||||
// Note throttling effectively changes the allowed brightness range, so, similarly to HBM,
|
||||
// we broadcast this change through setting.
|
||||
final float unthrottledBrightnessState = brightnessState;
|
||||
if (mBrightnessThrottler.isThrottled()) {
|
||||
brightnessState = Math.min(brightnessState, mBrightnessThrottler.getBrightnessCap());
|
||||
mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_THROTTLED);
|
||||
if (!mAppliedThrottling) {
|
||||
// Brightness throttling is needed, so do so quickly.
|
||||
// Later, when throttling is removed, we let other mechanisms decide on speed.
|
||||
slowChange = false;
|
||||
updateScreenBrightnessSetting = true;
|
||||
}
|
||||
mAppliedThrottling = true;
|
||||
} else if (mAppliedThrottling) {
|
||||
mAppliedThrottling = false;
|
||||
updateScreenBrightnessSetting = true;
|
||||
}
|
||||
|
||||
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
|
||||
@@ -1393,20 +1416,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
mAppliedLowPower = false;
|
||||
}
|
||||
|
||||
// Apply brightness throttling after applying all other transforms
|
||||
final float unthrottledBrightnessState = brightnessState;
|
||||
if (mBrightnessThrottler.isThrottled()) {
|
||||
brightnessState = Math.min(brightnessState, mBrightnessThrottler.getBrightnessCap());
|
||||
mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_THROTTLED);
|
||||
if (!mAppliedThrottling) {
|
||||
slowChange = false;
|
||||
}
|
||||
mAppliedThrottling = true;
|
||||
} else if (mAppliedThrottling) {
|
||||
slowChange = false;
|
||||
mAppliedThrottling = false;
|
||||
}
|
||||
|
||||
// The current brightness to use has been calculated at this point, and HbmController should
|
||||
// be notified so that it can accurately calculate HDR or HBM levels. We specifically do it
|
||||
// here instead of having HbmController listen to the brightness setting because certain
|
||||
@@ -1656,6 +1665,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
|
||||
private boolean saveBrightnessInfo(float brightness, float adjustedBrightness) {
|
||||
synchronized (mCachedBrightnessInfo) {
|
||||
final float minBrightness = Math.min(mHbmController.getCurrentBrightnessMin(),
|
||||
mBrightnessThrottler.getBrightnessCap());
|
||||
final float maxBrightness = Math.min(mHbmController.getCurrentBrightnessMax(),
|
||||
mBrightnessThrottler.getBrightnessCap());
|
||||
boolean changed = false;
|
||||
|
||||
changed |=
|
||||
@@ -1666,10 +1679,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
adjustedBrightness);
|
||||
changed |=
|
||||
mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.brightnessMin,
|
||||
mHbmController.getCurrentBrightnessMin());
|
||||
minBrightness);
|
||||
changed |=
|
||||
mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.brightnessMax,
|
||||
mHbmController.getCurrentBrightnessMax());
|
||||
maxBrightness);
|
||||
changed |=
|
||||
mCachedBrightnessInfo.checkAndSetInt(mCachedBrightnessInfo.hbmMode,
|
||||
mHbmController.getHighBrightnessMode());
|
||||
|
||||
@@ -81,6 +81,7 @@ public class AutomaticBrightnessControllerTest {
|
||||
@Mock HysteresisLevels mScreenBrightnessThresholds;
|
||||
@Mock Handler mNoOpHandler;
|
||||
@Mock HighBrightnessModeController mHbmController;
|
||||
@Mock BrightnessThrottler mBrightnessThrottler;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@@ -128,12 +129,15 @@ public class AutomaticBrightnessControllerTest {
|
||||
INITIAL_LIGHT_SENSOR_RATE, BRIGHTENING_LIGHT_DEBOUNCE_CONFIG,
|
||||
DARKENING_LIGHT_DEBOUNCE_CONFIG, RESET_AMBIENT_LUX_AFTER_WARMUP_CONFIG,
|
||||
mAmbientBrightnessThresholds, mScreenBrightnessThresholds,
|
||||
mContext, mHbmController, mIdleBrightnessMappingStrategy,
|
||||
mContext, mHbmController, mBrightnessThrottler, mIdleBrightnessMappingStrategy,
|
||||
AMBIENT_LIGHT_HORIZON_SHORT, AMBIENT_LIGHT_HORIZON_LONG
|
||||
);
|
||||
|
||||
when(mHbmController.getCurrentBrightnessMax()).thenReturn(BRIGHTNESS_MAX_FLOAT);
|
||||
when(mHbmController.getCurrentBrightnessMin()).thenReturn(BRIGHTNESS_MIN_FLOAT);
|
||||
// Disable brightness throttling by default. Individual tests can enable it as needed.
|
||||
when(mBrightnessThrottler.getBrightnessCap()).thenReturn(BRIGHTNESS_MAX_FLOAT);
|
||||
when(mBrightnessThrottler.isThrottled()).thenReturn(false);
|
||||
|
||||
// Configure the brightness controller and grab an instance of the sensor listener,
|
||||
// through which we can deliver fake (for test) sensor values.
|
||||
@@ -420,4 +424,47 @@ public class AutomaticBrightnessControllerTest {
|
||||
assertEquals(600f, hysteresisLevels.getBrighteningThreshold(500f), EPSILON);
|
||||
assertEquals(250f, hysteresisLevels.getDarkeningThreshold(500f), EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBrightnessGetsThrottled() throws Exception {
|
||||
Sensor lightSensor = TestUtils.createSensor(Sensor.TYPE_LIGHT, "Light Sensor");
|
||||
mController = setupController(lightSensor);
|
||||
|
||||
ArgumentCaptor<SensorEventListener> listenerCaptor =
|
||||
ArgumentCaptor.forClass(SensorEventListener.class);
|
||||
verify(mSensorManager).registerListener(listenerCaptor.capture(), eq(lightSensor),
|
||||
eq(INITIAL_LIGHT_SENSOR_RATE * 1000), any(Handler.class));
|
||||
SensorEventListener listener = listenerCaptor.getValue();
|
||||
|
||||
// Set up system to return max brightness at 100 lux
|
||||
final float normalizedBrightness = BRIGHTNESS_MAX_FLOAT;
|
||||
final float lux = 100.0f;
|
||||
when(mAmbientBrightnessThresholds.getBrighteningThreshold(lux))
|
||||
.thenReturn(lux);
|
||||
when(mAmbientBrightnessThresholds.getDarkeningThreshold(lux))
|
||||
.thenReturn(lux);
|
||||
when(mBrightnessMappingStrategy.getBrightness(eq(lux), eq(null), anyInt()))
|
||||
.thenReturn(normalizedBrightness);
|
||||
|
||||
// Sensor reads 100 lux. We should get max brightness.
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, (int) lux));
|
||||
assertEquals(BRIGHTNESS_MAX_FLOAT, mController.getAutomaticScreenBrightness(), 0.0f);
|
||||
|
||||
// Apply throttling and notify ABC (simulates DisplayPowerController#updatePowerState())
|
||||
final float throttledBrightness = 0.123f;
|
||||
when(mBrightnessThrottler.getBrightnessCap()).thenReturn(throttledBrightness);
|
||||
when(mBrightnessThrottler.isThrottled()).thenReturn(true);
|
||||
mController.configure(AUTO_BRIGHTNESS_ENABLED, null /* configuration */,
|
||||
BRIGHTNESS_MAX_FLOAT /* brightness */, false /* userChangedBrightness */,
|
||||
0 /* adjustment */, false /* userChanged */, DisplayPowerRequest.POLICY_BRIGHT);
|
||||
assertEquals(throttledBrightness, mController.getAutomaticScreenBrightness(), 0.0f);
|
||||
|
||||
// Remove throttling and notify ABC again
|
||||
when(mBrightnessThrottler.getBrightnessCap()).thenReturn(BRIGHTNESS_MAX_FLOAT);
|
||||
when(mBrightnessThrottler.isThrottled()).thenReturn(false);
|
||||
mController.configure(AUTO_BRIGHTNESS_ENABLED, null /* configuration */,
|
||||
BRIGHTNESS_MAX_FLOAT /* brightness */, false /* userChangedBrightness */,
|
||||
0 /* adjustment */, false /* userChanged */, DisplayPowerRequest.POLICY_BRIGHT);
|
||||
assertEquals(BRIGHTNESS_MAX_FLOAT, mController.getAutomaticScreenBrightness(), 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user