diff options
| author | 2022-02-02 00:59:55 +0000 | |
|---|---|---|
| committer | 2022-02-02 00:59:55 +0000 | |
| commit | 1f77cfffc4b711f0c85a566f3e2e213953d15b87 (patch) | |
| tree | 859379f15dc5fd91d327f342434544cee0422ae1 | |
| parent | fde9ae34a11e87c2240c92e583fe1f49ce3162ed (diff) | |
| parent | ecf2faa9988888c1fe3bdfb948b8dc719a160327 (diff) | |
Merge "Reflect BrightnessThrottler effects in Settings, UI and ABC"
3 files changed, 99 insertions, 24 deletions
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java index 1b552577308d..162eb0e188b9 100644 --- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java +++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java @@ -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() { diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index 3494342a66fb..6ae1a5a96a24 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -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()); diff --git a/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java b/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java index 4caa85cee7db..f5a56891b5f5 100644 --- a/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java @@ -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); + } } |