Loading services/core/java/com/android/server/display/BrightnessRangeController.java +20 −3 Original line number Diff line number Diff line Loading @@ -17,9 +17,11 @@ package com.android.server.display; import android.hardware.display.BrightnessInfo; import android.os.Handler; import android.os.IBinder; import android.provider.DeviceConfigInterface; import com.android.server.display.brightness.clamper.HdrClamper; import com.android.server.display.feature.DeviceConfigParameterProvider; import java.io.PrintWriter; Loading @@ -31,23 +33,30 @@ class BrightnessRangeController { private final NormalBrightnessModeController mNormalBrightnessModeController = new NormalBrightnessModeController(); private final HdrClamper mHdrClamper; private final Runnable mModeChangeCallback; private final boolean mUseNbmController; private final boolean mUseHdrClamper; BrightnessRangeController(HighBrightnessModeController hbmController, Runnable modeChangeCallback, DisplayDeviceConfig displayDeviceConfig) { Runnable modeChangeCallback, DisplayDeviceConfig displayDeviceConfig, Handler handler) { this(hbmController, modeChangeCallback, displayDeviceConfig, new HdrClamper(modeChangeCallback::run, new Handler(handler.getLooper())), new DeviceConfigParameterProvider(DeviceConfigInterface.REAL)); } BrightnessRangeController(HighBrightnessModeController hbmController, Runnable modeChangeCallback, DisplayDeviceConfig displayDeviceConfig, DeviceConfigParameterProvider configParameterProvider) { HdrClamper hdrClamper, DeviceConfigParameterProvider configParameterProvider) { mHbmController = hbmController; mModeChangeCallback = modeChangeCallback; mUseNbmController = configParameterProvider.isNormalBrightnessControllerFeatureEnabled(); mUseHdrClamper = false; mNormalBrightnessModeController.resetNbmData(displayDeviceConfig.getLuxThrottlingData()); mHdrClamper = hdrClamper; } void dump(PrintWriter pw) { Loading @@ -63,6 +72,9 @@ class BrightnessRangeController { () -> mNormalBrightnessModeController.onAmbientLuxChange(ambientLux), () -> mHbmController.onAmbientLuxChange(ambientLux) ); if (mUseHdrClamper) { mHdrClamper.onAmbientLuxChange(ambientLux); } } float getNormalBrightnessMax() { Loading Loading @@ -118,7 +130,8 @@ class BrightnessRangeController { } float getHdrBrightnessValue() { return mHbmController.getHdrBrightnessValue(); float hdrBrightness = mHbmController.getHdrBrightnessValue(); return Math.min(hdrBrightness, mHdrClamper.getMaxBrightness()); } float getTransitionPoint() { Loading @@ -138,4 +151,8 @@ class BrightnessRangeController { hbmChangesFunc.run(); } } public float getHdrTransitionRate() { return mHdrClamper.getTransitionRate(); } } services/core/java/com/android/server/display/DisplayPowerController.java +1 −1 Original line number Diff line number Diff line Loading @@ -677,7 +677,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call HighBrightnessModeController hbmController = createHbmControllerLocked(modeChangeCallback); mBrightnessRangeController = new BrightnessRangeController(hbmController, modeChangeCallback, mDisplayDeviceConfig); modeChangeCallback, mDisplayDeviceConfig, mHandler); mBrightnessThrottler = createBrightnessThrottlerLocked(); Loading services/core/java/com/android/server/display/DisplayPowerController2.java +16 −2 Original line number Diff line number Diff line Loading @@ -539,8 +539,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal modeChangeCallback); mBrightnessThrottler = createBrightnessThrottlerLocked(); mBrightnessRangeController = new BrightnessRangeController(hbmController, modeChangeCallback, mDisplayDeviceConfig); mBrightnessRangeController = mInjector.getBrightnessRangeController(hbmController, modeChangeCallback, mDisplayDeviceConfig, mHandler); mDisplayBrightnessController = new DisplayBrightnessController(context, null, Loading Loading @@ -1497,6 +1497,9 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal // allowed range. float animateValue = clampScreenBrightness(brightnessState); // custom transition duration float customTransitionRate = -1f; // 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. Loading @@ -1511,6 +1514,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal // We want to scale HDR brightness level with the SDR level, we also need to restore // SDR brightness immediately when entering dim or low power mode. animateValue = mBrightnessRangeController.getHdrBrightnessValue(); customTransitionRate = mBrightnessRangeController.getHdrTransitionRate(); } final float currentBrightness = mPowerState.getScreenBrightness(); Loading @@ -1523,6 +1527,9 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal || !isDisplayContentVisible || brightnessIsTemporary) { animateScreenBrightness(animateValue, sdrAnimateValue, SCREEN_ANIMATION_RATE_MINIMUM); } else if (customTransitionRate > 0) { animateScreenBrightness(animateValue, sdrAnimateValue, customTransitionRate); } else { boolean isIncreasing = animateValue > currentBrightness; final float rampSpeed; Loading Loading @@ -2968,6 +2975,13 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal hbmChangeCallback, hbmMetadata, context); } BrightnessRangeController getBrightnessRangeController( HighBrightnessModeController hbmController, Runnable modeChangeCallback, DisplayDeviceConfig displayDeviceConfig, Handler handler) { return new BrightnessRangeController(hbmController, modeChangeCallback, displayDeviceConfig, handler); } DisplayWhiteBalanceController getDisplayWhiteBalanceController(Handler handler, SensorManager sensorManager, Resources resources) { return DisplayWhiteBalanceFactory.create(handler, Loading services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java 0 → 100644 +132 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.display.brightness.clamper; import android.os.Handler; import android.os.PowerManager; import com.android.internal.annotations.VisibleForTesting; import java.util.HashMap; import java.util.Map; public class HdrClamper { private final Configuration mConfiguration = new Configuration(); private final BrightnessClamperController.ClamperChangeListener mClamperChangeListener; private final Handler mHandler; private final Runnable mDebouncer; private float mMaxBrightness = PowerManager.BRIGHTNESS_MAX; // brightness change speed, in units per seconds, private float mTransitionRate = -1f; private float mDesiredMaxBrightness = PowerManager.BRIGHTNESS_MAX; private float mDesiredTransitionDuration = -1; // in seconds public HdrClamper(BrightnessClamperController.ClamperChangeListener clamperChangeListener, Handler handler) { mClamperChangeListener = clamperChangeListener; mHandler = handler; mDebouncer = () -> { mTransitionRate = Math.abs((mMaxBrightness - mDesiredMaxBrightness) / mDesiredTransitionDuration); mMaxBrightness = mDesiredMaxBrightness; mClamperChangeListener.onChanged(); }; } // Called in same looper: mHandler.getLooper() public float getMaxBrightness() { return mMaxBrightness; } // Called in same looper: mHandler.getLooper() public float getTransitionRate() { return mTransitionRate; } /** * Updates brightness cap in response to ambient lux change. * Called by ABC in same looper: mHandler.getLooper() */ public void onAmbientLuxChange(float ambientLux) { float expectedMaxBrightness = findBrightnessLimit(ambientLux); if (mMaxBrightness == expectedMaxBrightness) { mDesiredMaxBrightness = mMaxBrightness; mDesiredTransitionDuration = -1; mTransitionRate = -1f; mHandler.removeCallbacks(mDebouncer); } else if (mDesiredMaxBrightness != expectedMaxBrightness) { mDesiredMaxBrightness = expectedMaxBrightness; long debounceTime; if (mDesiredMaxBrightness > mMaxBrightness) { debounceTime = mConfiguration.mIncreaseConfig.mDebounceTimeMillis; mDesiredTransitionDuration = (float) mConfiguration.mIncreaseConfig.mTransitionTimeMillis / 1000; } else { debounceTime = mConfiguration.mDecreaseConfig.mDebounceTimeMillis; mDesiredTransitionDuration = (float) mConfiguration.mDecreaseConfig.mTransitionTimeMillis / 1000; } mHandler.removeCallbacks(mDebouncer); mHandler.postDelayed(mDebouncer, debounceTime); } } @VisibleForTesting Configuration getConfiguration() { return mConfiguration; } private float findBrightnessLimit(float ambientLux) { float foundAmbientBoundary = Float.MAX_VALUE; float foundMaxBrightness = PowerManager.BRIGHTNESS_MAX; for (Map.Entry<Float, Float> brightnessPoint : mConfiguration.mMaxBrightnessLimits.entrySet()) { float ambientBoundary = brightnessPoint.getKey(); // find ambient lux upper boundary closest to current ambient lux if (ambientBoundary > ambientLux && ambientBoundary < foundAmbientBoundary) { foundMaxBrightness = brightnessPoint.getValue(); foundAmbientBoundary = ambientBoundary; } } return foundMaxBrightness; } @VisibleForTesting static class Configuration { final Map<Float, Float> mMaxBrightnessLimits = new HashMap<>(); final TransitionConfiguration mIncreaseConfig = new TransitionConfiguration(); final TransitionConfiguration mDecreaseConfig = new TransitionConfiguration(); } @VisibleForTesting static class TransitionConfiguration { long mDebounceTimeMillis; long mTransitionTimeMillis; } } services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java +50 −3 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import android.content.res.Resources; import android.hardware.Sensor; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.hardware.display.BrightnessInfo; import android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks; import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest; import android.os.Handler; Loading @@ -67,7 +68,9 @@ import com.android.server.LocalServices; import com.android.server.am.BatteryStatsService; import com.android.server.display.RampAnimator.DualRampAnimator; import com.android.server.display.brightness.BrightnessEvent; import com.android.server.display.brightness.clamper.HdrClamper; import com.android.server.display.color.ColorDisplayService; import com.android.server.display.feature.DeviceConfigParameterProvider; import com.android.server.display.layout.Layout; import com.android.server.display.whitebalance.DisplayWhiteBalanceController; import com.android.server.policy.WindowManagerPolicy; Loading Loading @@ -1175,6 +1178,26 @@ public final class DisplayPowerController2Test { verify(mHolder.displayPowerState, times(1)).stop(); } @Test public void testRampRateForHdrContent() { float clampedBrightness = 0.6f; float transitionRate = 35.5f; DisplayPowerRequest dpr = new DisplayPowerRequest(); when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f); when(mHolder.hbmController.getHighBrightnessMode()).thenReturn( BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR); when(mHolder.hbmController.getHdrBrightnessValue()).thenReturn(PowerManager.BRIGHTNESS_MAX); when(mHolder.hdrClamper.getMaxBrightness()).thenReturn(clampedBrightness); when(mHolder.hdrClamper.getTransitionRate()).thenReturn(transitionRate); mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); advanceTime(1); // Run updatePowerState verify(mHolder.animator, atLeastOnce()).animateTo(eq(clampedBrightness), anyFloat(), eq(transitionRate)); } /** * Creates a mock and registers it to {@link LocalServices}. */ Loading Loading @@ -1270,12 +1293,16 @@ public final class DisplayPowerController2Test { final ScreenOffBrightnessSensorController screenOffBrightnessSensorController = mock(ScreenOffBrightnessSensorController.class); final HighBrightnessModeController hbmController = mock(HighBrightnessModeController.class); final HdrClamper hdrClamper = mock(HdrClamper.class); final DeviceConfigParameterProvider deviceConfigParameterProvider = mock(DeviceConfigParameterProvider.class); when(hbmController.getCurrentBrightnessMax()).thenReturn(PowerManager.BRIGHTNESS_MAX); TestInjector injector = spy(new TestInjector(displayPowerState, animator, automaticBrightnessController, wakelockController, brightnessMappingStrategy, hysteresisLevels, screenOffBrightnessSensorController, hbmController)); hysteresisLevels, screenOffBrightnessSensorController, hbmController, hdrClamper, deviceConfigParameterProvider)); final LogicalDisplay display = mock(LogicalDisplay.class); final DisplayDevice device = mock(DisplayDevice.class); Loading @@ -1293,7 +1320,7 @@ public final class DisplayPowerController2Test { return new DisplayPowerControllerHolder(dpc, display, displayPowerState, brightnessSetting, animator, automaticBrightnessController, wakelockController, screenOffBrightnessSensorController, hbmController, hbmMetadata, screenOffBrightnessSensorController, hbmController, hdrClamper, hbmMetadata, brightnessMappingStrategy, injector); } Loading @@ -1311,6 +1338,8 @@ public final class DisplayPowerController2Test { public final WakelockController wakelockController; public final ScreenOffBrightnessSensorController screenOffBrightnessSensorController; public final HighBrightnessModeController hbmController; public final HdrClamper hdrClamper; public final HighBrightnessModeMetadata hbmMetadata; public final BrightnessMappingStrategy brightnessMappingStrategy; public final DisplayPowerController2.Injector injector; Loading @@ -1322,6 +1351,7 @@ public final class DisplayPowerController2Test { WakelockController wakelockController, ScreenOffBrightnessSensorController screenOffBrightnessSensorController, HighBrightnessModeController hbmController, HdrClamper hdrClamper, HighBrightnessModeMetadata hbmMetadata, BrightnessMappingStrategy brightnessMappingStrategy, DisplayPowerController2.Injector injector) { Loading @@ -1334,6 +1364,7 @@ public final class DisplayPowerController2Test { this.wakelockController = wakelockController; this.screenOffBrightnessSensorController = screenOffBrightnessSensorController; this.hbmController = hbmController; this.hdrClamper = hdrClamper; this.hbmMetadata = hbmMetadata; this.brightnessMappingStrategy = brightnessMappingStrategy; this.injector = injector; Loading @@ -1350,13 +1381,19 @@ public final class DisplayPowerController2Test { private final ScreenOffBrightnessSensorController mScreenOffBrightnessSensorController; private final HighBrightnessModeController mHighBrightnessModeController; private final HdrClamper mHdrClamper; private final DeviceConfigParameterProvider mDeviceConfigParameterProvider; TestInjector(DisplayPowerState dps, DualRampAnimator<DisplayPowerState> animator, AutomaticBrightnessController automaticBrightnessController, WakelockController wakelockController, BrightnessMappingStrategy brightnessMappingStrategy, HysteresisLevels hysteresisLevels, ScreenOffBrightnessSensorController screenOffBrightnessSensorController, HighBrightnessModeController highBrightnessModeController) { HighBrightnessModeController highBrightnessModeController, HdrClamper hdrClamper, DeviceConfigParameterProvider deviceConfigParameterProvider) { mDisplayPowerState = dps; mAnimator = animator; mAutomaticBrightnessController = automaticBrightnessController; Loading @@ -1365,6 +1402,8 @@ public final class DisplayPowerController2Test { mHysteresisLevels = hysteresisLevels; mScreenOffBrightnessSensorController = screenOffBrightnessSensorController; mHighBrightnessModeController = highBrightnessModeController; mHdrClamper = hdrClamper; mDeviceConfigParameterProvider = deviceConfigParameterProvider; } @Override Loading Loading @@ -1470,6 +1509,14 @@ public final class DisplayPowerController2Test { return mHighBrightnessModeController; } @Override BrightnessRangeController getBrightnessRangeController( HighBrightnessModeController hbmController, Runnable modeChangeCallback, DisplayDeviceConfig displayDeviceConfig, Handler handler) { return new BrightnessRangeController(hbmController, modeChangeCallback, displayDeviceConfig, mHdrClamper, mDeviceConfigParameterProvider); } @Override DisplayWhiteBalanceController getDisplayWhiteBalanceController(Handler handler, SensorManager sensorManager, Resources resources) { Loading Loading
services/core/java/com/android/server/display/BrightnessRangeController.java +20 −3 Original line number Diff line number Diff line Loading @@ -17,9 +17,11 @@ package com.android.server.display; import android.hardware.display.BrightnessInfo; import android.os.Handler; import android.os.IBinder; import android.provider.DeviceConfigInterface; import com.android.server.display.brightness.clamper.HdrClamper; import com.android.server.display.feature.DeviceConfigParameterProvider; import java.io.PrintWriter; Loading @@ -31,23 +33,30 @@ class BrightnessRangeController { private final NormalBrightnessModeController mNormalBrightnessModeController = new NormalBrightnessModeController(); private final HdrClamper mHdrClamper; private final Runnable mModeChangeCallback; private final boolean mUseNbmController; private final boolean mUseHdrClamper; BrightnessRangeController(HighBrightnessModeController hbmController, Runnable modeChangeCallback, DisplayDeviceConfig displayDeviceConfig) { Runnable modeChangeCallback, DisplayDeviceConfig displayDeviceConfig, Handler handler) { this(hbmController, modeChangeCallback, displayDeviceConfig, new HdrClamper(modeChangeCallback::run, new Handler(handler.getLooper())), new DeviceConfigParameterProvider(DeviceConfigInterface.REAL)); } BrightnessRangeController(HighBrightnessModeController hbmController, Runnable modeChangeCallback, DisplayDeviceConfig displayDeviceConfig, DeviceConfigParameterProvider configParameterProvider) { HdrClamper hdrClamper, DeviceConfigParameterProvider configParameterProvider) { mHbmController = hbmController; mModeChangeCallback = modeChangeCallback; mUseNbmController = configParameterProvider.isNormalBrightnessControllerFeatureEnabled(); mUseHdrClamper = false; mNormalBrightnessModeController.resetNbmData(displayDeviceConfig.getLuxThrottlingData()); mHdrClamper = hdrClamper; } void dump(PrintWriter pw) { Loading @@ -63,6 +72,9 @@ class BrightnessRangeController { () -> mNormalBrightnessModeController.onAmbientLuxChange(ambientLux), () -> mHbmController.onAmbientLuxChange(ambientLux) ); if (mUseHdrClamper) { mHdrClamper.onAmbientLuxChange(ambientLux); } } float getNormalBrightnessMax() { Loading Loading @@ -118,7 +130,8 @@ class BrightnessRangeController { } float getHdrBrightnessValue() { return mHbmController.getHdrBrightnessValue(); float hdrBrightness = mHbmController.getHdrBrightnessValue(); return Math.min(hdrBrightness, mHdrClamper.getMaxBrightness()); } float getTransitionPoint() { Loading @@ -138,4 +151,8 @@ class BrightnessRangeController { hbmChangesFunc.run(); } } public float getHdrTransitionRate() { return mHdrClamper.getTransitionRate(); } }
services/core/java/com/android/server/display/DisplayPowerController.java +1 −1 Original line number Diff line number Diff line Loading @@ -677,7 +677,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call HighBrightnessModeController hbmController = createHbmControllerLocked(modeChangeCallback); mBrightnessRangeController = new BrightnessRangeController(hbmController, modeChangeCallback, mDisplayDeviceConfig); modeChangeCallback, mDisplayDeviceConfig, mHandler); mBrightnessThrottler = createBrightnessThrottlerLocked(); Loading
services/core/java/com/android/server/display/DisplayPowerController2.java +16 −2 Original line number Diff line number Diff line Loading @@ -539,8 +539,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal modeChangeCallback); mBrightnessThrottler = createBrightnessThrottlerLocked(); mBrightnessRangeController = new BrightnessRangeController(hbmController, modeChangeCallback, mDisplayDeviceConfig); mBrightnessRangeController = mInjector.getBrightnessRangeController(hbmController, modeChangeCallback, mDisplayDeviceConfig, mHandler); mDisplayBrightnessController = new DisplayBrightnessController(context, null, Loading Loading @@ -1497,6 +1497,9 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal // allowed range. float animateValue = clampScreenBrightness(brightnessState); // custom transition duration float customTransitionRate = -1f; // 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. Loading @@ -1511,6 +1514,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal // We want to scale HDR brightness level with the SDR level, we also need to restore // SDR brightness immediately when entering dim or low power mode. animateValue = mBrightnessRangeController.getHdrBrightnessValue(); customTransitionRate = mBrightnessRangeController.getHdrTransitionRate(); } final float currentBrightness = mPowerState.getScreenBrightness(); Loading @@ -1523,6 +1527,9 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal || !isDisplayContentVisible || brightnessIsTemporary) { animateScreenBrightness(animateValue, sdrAnimateValue, SCREEN_ANIMATION_RATE_MINIMUM); } else if (customTransitionRate > 0) { animateScreenBrightness(animateValue, sdrAnimateValue, customTransitionRate); } else { boolean isIncreasing = animateValue > currentBrightness; final float rampSpeed; Loading Loading @@ -2968,6 +2975,13 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal hbmChangeCallback, hbmMetadata, context); } BrightnessRangeController getBrightnessRangeController( HighBrightnessModeController hbmController, Runnable modeChangeCallback, DisplayDeviceConfig displayDeviceConfig, Handler handler) { return new BrightnessRangeController(hbmController, modeChangeCallback, displayDeviceConfig, handler); } DisplayWhiteBalanceController getDisplayWhiteBalanceController(Handler handler, SensorManager sensorManager, Resources resources) { return DisplayWhiteBalanceFactory.create(handler, Loading
services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java 0 → 100644 +132 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.display.brightness.clamper; import android.os.Handler; import android.os.PowerManager; import com.android.internal.annotations.VisibleForTesting; import java.util.HashMap; import java.util.Map; public class HdrClamper { private final Configuration mConfiguration = new Configuration(); private final BrightnessClamperController.ClamperChangeListener mClamperChangeListener; private final Handler mHandler; private final Runnable mDebouncer; private float mMaxBrightness = PowerManager.BRIGHTNESS_MAX; // brightness change speed, in units per seconds, private float mTransitionRate = -1f; private float mDesiredMaxBrightness = PowerManager.BRIGHTNESS_MAX; private float mDesiredTransitionDuration = -1; // in seconds public HdrClamper(BrightnessClamperController.ClamperChangeListener clamperChangeListener, Handler handler) { mClamperChangeListener = clamperChangeListener; mHandler = handler; mDebouncer = () -> { mTransitionRate = Math.abs((mMaxBrightness - mDesiredMaxBrightness) / mDesiredTransitionDuration); mMaxBrightness = mDesiredMaxBrightness; mClamperChangeListener.onChanged(); }; } // Called in same looper: mHandler.getLooper() public float getMaxBrightness() { return mMaxBrightness; } // Called in same looper: mHandler.getLooper() public float getTransitionRate() { return mTransitionRate; } /** * Updates brightness cap in response to ambient lux change. * Called by ABC in same looper: mHandler.getLooper() */ public void onAmbientLuxChange(float ambientLux) { float expectedMaxBrightness = findBrightnessLimit(ambientLux); if (mMaxBrightness == expectedMaxBrightness) { mDesiredMaxBrightness = mMaxBrightness; mDesiredTransitionDuration = -1; mTransitionRate = -1f; mHandler.removeCallbacks(mDebouncer); } else if (mDesiredMaxBrightness != expectedMaxBrightness) { mDesiredMaxBrightness = expectedMaxBrightness; long debounceTime; if (mDesiredMaxBrightness > mMaxBrightness) { debounceTime = mConfiguration.mIncreaseConfig.mDebounceTimeMillis; mDesiredTransitionDuration = (float) mConfiguration.mIncreaseConfig.mTransitionTimeMillis / 1000; } else { debounceTime = mConfiguration.mDecreaseConfig.mDebounceTimeMillis; mDesiredTransitionDuration = (float) mConfiguration.mDecreaseConfig.mTransitionTimeMillis / 1000; } mHandler.removeCallbacks(mDebouncer); mHandler.postDelayed(mDebouncer, debounceTime); } } @VisibleForTesting Configuration getConfiguration() { return mConfiguration; } private float findBrightnessLimit(float ambientLux) { float foundAmbientBoundary = Float.MAX_VALUE; float foundMaxBrightness = PowerManager.BRIGHTNESS_MAX; for (Map.Entry<Float, Float> brightnessPoint : mConfiguration.mMaxBrightnessLimits.entrySet()) { float ambientBoundary = brightnessPoint.getKey(); // find ambient lux upper boundary closest to current ambient lux if (ambientBoundary > ambientLux && ambientBoundary < foundAmbientBoundary) { foundMaxBrightness = brightnessPoint.getValue(); foundAmbientBoundary = ambientBoundary; } } return foundMaxBrightness; } @VisibleForTesting static class Configuration { final Map<Float, Float> mMaxBrightnessLimits = new HashMap<>(); final TransitionConfiguration mIncreaseConfig = new TransitionConfiguration(); final TransitionConfiguration mDecreaseConfig = new TransitionConfiguration(); } @VisibleForTesting static class TransitionConfiguration { long mDebounceTimeMillis; long mTransitionTimeMillis; } }
services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java +50 −3 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import android.content.res.Resources; import android.hardware.Sensor; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.hardware.display.BrightnessInfo; import android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks; import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest; import android.os.Handler; Loading @@ -67,7 +68,9 @@ import com.android.server.LocalServices; import com.android.server.am.BatteryStatsService; import com.android.server.display.RampAnimator.DualRampAnimator; import com.android.server.display.brightness.BrightnessEvent; import com.android.server.display.brightness.clamper.HdrClamper; import com.android.server.display.color.ColorDisplayService; import com.android.server.display.feature.DeviceConfigParameterProvider; import com.android.server.display.layout.Layout; import com.android.server.display.whitebalance.DisplayWhiteBalanceController; import com.android.server.policy.WindowManagerPolicy; Loading Loading @@ -1175,6 +1178,26 @@ public final class DisplayPowerController2Test { verify(mHolder.displayPowerState, times(1)).stop(); } @Test public void testRampRateForHdrContent() { float clampedBrightness = 0.6f; float transitionRate = 35.5f; DisplayPowerRequest dpr = new DisplayPowerRequest(); when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f); when(mHolder.hbmController.getHighBrightnessMode()).thenReturn( BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR); when(mHolder.hbmController.getHdrBrightnessValue()).thenReturn(PowerManager.BRIGHTNESS_MAX); when(mHolder.hdrClamper.getMaxBrightness()).thenReturn(clampedBrightness); when(mHolder.hdrClamper.getTransitionRate()).thenReturn(transitionRate); mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); advanceTime(1); // Run updatePowerState verify(mHolder.animator, atLeastOnce()).animateTo(eq(clampedBrightness), anyFloat(), eq(transitionRate)); } /** * Creates a mock and registers it to {@link LocalServices}. */ Loading Loading @@ -1270,12 +1293,16 @@ public final class DisplayPowerController2Test { final ScreenOffBrightnessSensorController screenOffBrightnessSensorController = mock(ScreenOffBrightnessSensorController.class); final HighBrightnessModeController hbmController = mock(HighBrightnessModeController.class); final HdrClamper hdrClamper = mock(HdrClamper.class); final DeviceConfigParameterProvider deviceConfigParameterProvider = mock(DeviceConfigParameterProvider.class); when(hbmController.getCurrentBrightnessMax()).thenReturn(PowerManager.BRIGHTNESS_MAX); TestInjector injector = spy(new TestInjector(displayPowerState, animator, automaticBrightnessController, wakelockController, brightnessMappingStrategy, hysteresisLevels, screenOffBrightnessSensorController, hbmController)); hysteresisLevels, screenOffBrightnessSensorController, hbmController, hdrClamper, deviceConfigParameterProvider)); final LogicalDisplay display = mock(LogicalDisplay.class); final DisplayDevice device = mock(DisplayDevice.class); Loading @@ -1293,7 +1320,7 @@ public final class DisplayPowerController2Test { return new DisplayPowerControllerHolder(dpc, display, displayPowerState, brightnessSetting, animator, automaticBrightnessController, wakelockController, screenOffBrightnessSensorController, hbmController, hbmMetadata, screenOffBrightnessSensorController, hbmController, hdrClamper, hbmMetadata, brightnessMappingStrategy, injector); } Loading @@ -1311,6 +1338,8 @@ public final class DisplayPowerController2Test { public final WakelockController wakelockController; public final ScreenOffBrightnessSensorController screenOffBrightnessSensorController; public final HighBrightnessModeController hbmController; public final HdrClamper hdrClamper; public final HighBrightnessModeMetadata hbmMetadata; public final BrightnessMappingStrategy brightnessMappingStrategy; public final DisplayPowerController2.Injector injector; Loading @@ -1322,6 +1351,7 @@ public final class DisplayPowerController2Test { WakelockController wakelockController, ScreenOffBrightnessSensorController screenOffBrightnessSensorController, HighBrightnessModeController hbmController, HdrClamper hdrClamper, HighBrightnessModeMetadata hbmMetadata, BrightnessMappingStrategy brightnessMappingStrategy, DisplayPowerController2.Injector injector) { Loading @@ -1334,6 +1364,7 @@ public final class DisplayPowerController2Test { this.wakelockController = wakelockController; this.screenOffBrightnessSensorController = screenOffBrightnessSensorController; this.hbmController = hbmController; this.hdrClamper = hdrClamper; this.hbmMetadata = hbmMetadata; this.brightnessMappingStrategy = brightnessMappingStrategy; this.injector = injector; Loading @@ -1350,13 +1381,19 @@ public final class DisplayPowerController2Test { private final ScreenOffBrightnessSensorController mScreenOffBrightnessSensorController; private final HighBrightnessModeController mHighBrightnessModeController; private final HdrClamper mHdrClamper; private final DeviceConfigParameterProvider mDeviceConfigParameterProvider; TestInjector(DisplayPowerState dps, DualRampAnimator<DisplayPowerState> animator, AutomaticBrightnessController automaticBrightnessController, WakelockController wakelockController, BrightnessMappingStrategy brightnessMappingStrategy, HysteresisLevels hysteresisLevels, ScreenOffBrightnessSensorController screenOffBrightnessSensorController, HighBrightnessModeController highBrightnessModeController) { HighBrightnessModeController highBrightnessModeController, HdrClamper hdrClamper, DeviceConfigParameterProvider deviceConfigParameterProvider) { mDisplayPowerState = dps; mAnimator = animator; mAutomaticBrightnessController = automaticBrightnessController; Loading @@ -1365,6 +1402,8 @@ public final class DisplayPowerController2Test { mHysteresisLevels = hysteresisLevels; mScreenOffBrightnessSensorController = screenOffBrightnessSensorController; mHighBrightnessModeController = highBrightnessModeController; mHdrClamper = hdrClamper; mDeviceConfigParameterProvider = deviceConfigParameterProvider; } @Override Loading Loading @@ -1470,6 +1509,14 @@ public final class DisplayPowerController2Test { return mHighBrightnessModeController; } @Override BrightnessRangeController getBrightnessRangeController( HighBrightnessModeController hbmController, Runnable modeChangeCallback, DisplayDeviceConfig displayDeviceConfig, Handler handler) { return new BrightnessRangeController(hbmController, modeChangeCallback, displayDeviceConfig, mHdrClamper, mDeviceConfigParameterProvider); } @Override DisplayWhiteBalanceController getDisplayWhiteBalanceController(Handler handler, SensorManager sensorManager, Resources resources) { Loading