Loading services/core/java/com/android/server/display/BrightnessRangeController.java +6 −50 Original line number Diff line number Diff line Loading @@ -17,13 +17,9 @@ package com.android.server.display; import android.annotation.Nullable; import android.os.Handler; import android.os.IBinder; import com.android.internal.annotations.VisibleForTesting; import com.android.server.display.brightness.clamper.HdrClamper; import com.android.server.display.config.HighBrightnessModeData; import com.android.server.display.feature.DisplayManagerFlags; import java.io.PrintWriter; import java.util.function.BooleanSupplier; Loading @@ -33,48 +29,31 @@ class BrightnessRangeController { private final HighBrightnessModeController mHbmController; private final NormalBrightnessModeController mNormalBrightnessModeController; private final HdrClamper mHdrClamper; private final Runnable mModeChangeCallback; private final boolean mUseHdrClamper; BrightnessRangeController(HighBrightnessModeController hbmController, Runnable modeChangeCallback, DisplayDeviceConfig displayDeviceConfig, Handler handler, DisplayManagerFlags flags, IBinder displayToken, DisplayDeviceInfo info) { Runnable modeChangeCallback, DisplayDeviceConfig displayDeviceConfig) { this(hbmController, modeChangeCallback, displayDeviceConfig, new NormalBrightnessModeController(), new HdrClamper(modeChangeCallback::run, new Handler(handler.getLooper())), flags, displayToken, info); new NormalBrightnessModeController()); } @VisibleForTesting BrightnessRangeController(HighBrightnessModeController hbmController, Runnable modeChangeCallback, DisplayDeviceConfig displayDeviceConfig, NormalBrightnessModeController normalBrightnessModeController, HdrClamper hdrClamper, DisplayManagerFlags flags, IBinder displayToken, DisplayDeviceInfo info) { NormalBrightnessModeController normalBrightnessModeController) { mHbmController = hbmController; mModeChangeCallback = modeChangeCallback; mHdrClamper = hdrClamper; mNormalBrightnessModeController = normalBrightnessModeController; mUseHdrClamper = !flags.useNewHdrBrightnessModifier(); mNormalBrightnessModeController.resetNbmData( displayDeviceConfig.getLuxThrottlingData()); if (flags.useNewHdrBrightnessModifier()) { // HDR boost is handled by HdrBrightnessModifier and should be disabled in HbmController mHbmController.disableHdrBoost(); } updateHdrClamper(info, displayToken, displayDeviceConfig); } void dump(PrintWriter pw) { pw.println("BrightnessRangeController:"); pw.println(" mUseHdrClamper=" + mUseHdrClamper); mHbmController.dump(pw); mNormalBrightnessModeController.dump(pw); mHdrClamper.dump(pw); } void onAmbientLuxChange(float ambientLux) { Loading @@ -82,9 +61,6 @@ class BrightnessRangeController { () -> mNormalBrightnessModeController.onAmbientLuxChange(ambientLux), () -> mHbmController.onAmbientLuxChange(ambientLux) ); if (mUseHdrClamper) { mHdrClamper.onAmbientLuxChange(ambientLux); } } float getNormalBrightnessMax() { Loading @@ -103,12 +79,10 @@ class BrightnessRangeController { displayDeviceConfig::getHdrBrightnessFromSdr); } ); updateHdrClamper(info, token, displayDeviceConfig); } void stop() { mHbmController.stop(); mHdrClamper.stop(); } void setAutoBrightnessEnabled(int state) { Loading @@ -116,7 +90,6 @@ class BrightnessRangeController { () -> mNormalBrightnessModeController.setAutoBrightnessState(state), () -> mHbmController.setAutoBrightnessEnabled(state) ); mHdrClamper.setAutoBrightnessState(state); } void onBrightnessChanged(float brightness, float unthrottledBrightness, Loading Loading @@ -147,26 +120,13 @@ class BrightnessRangeController { } float getHdrBrightnessValue() { float hdrBrightness = mHbmController.getHdrBrightnessValue(); return mUseHdrClamper ? mHdrClamper.clamp(hdrBrightness) : hdrBrightness; return mHbmController.getHdrBrightnessValue(); } float getTransitionPoint() { return mHbmController.getTransitionPoint(); } private void updateHdrClamper(DisplayDeviceInfo info, IBinder token, DisplayDeviceConfig displayDeviceConfig) { if (mUseHdrClamper) { HighBrightnessModeData hbmData = displayDeviceConfig.getHighBrightnessModeData(); float minimumHdrPercentOfScreen = hbmData == null ? -1f : hbmData.minimumHdrPercentOfScreen; mHdrClamper.resetHdrConfig(displayDeviceConfig.getHdrBrightnessData(), info.width, info.height, minimumHdrPercentOfScreen, token); } } private void applyChanges(BooleanSupplier nbmChangesFunc, Runnable hbmChangesFunc) { boolean nbmTransitionChanged = nbmChangesFunc.getAsBoolean(); hbmChangesFunc.run(); Loading @@ -176,8 +136,4 @@ class BrightnessRangeController { mModeChangeCallback.run(); } } public float getHdrTransitionRate() { return mUseHdrClamper ? mHdrClamper.getTransitionRate() : -1; } } services/core/java/com/android/server/display/DisplayPowerController.java +3 −7 Original line number Diff line number Diff line Loading @@ -594,8 +594,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call modeChangeCallback); mBrightnessRangeController = mInjector.getBrightnessRangeController(hbmController, modeChangeCallback, mDisplayDeviceConfig, mHandler, flags, displayToken, displayDeviceInfo); modeChangeCallback, mDisplayDeviceConfig); mDisplayBrightnessController = new DisplayBrightnessController(context, mDisplayId, Loading Loading @@ -1689,8 +1688,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // SDR brightness immediately when entering dim or low power mode. animateValue = mBrightnessRangeController.getHdrBrightnessValue(); hdrBrightness = animateValue; customAnimationRate = Math.max(customAnimationRate, mBrightnessRangeController.getHdrTransitionRate()); mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_HDR); } Loading Loading @@ -3369,10 +3366,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call BrightnessRangeController getBrightnessRangeController( HighBrightnessModeController hbmController, Runnable modeChangeCallback, DisplayDeviceConfig displayDeviceConfig, Handler handler, DisplayManagerFlags flags, IBinder displayToken, DisplayDeviceInfo info) { DisplayDeviceConfig displayDeviceConfig) { return new BrightnessRangeController(hbmController, modeChangeCallback, displayDeviceConfig, handler, flags, displayToken, info); modeChangeCallback, displayDeviceConfig); } BrightnessClamperController getBrightnessClamperController(Handler handler, Loading services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java +2 −4 Original line number Diff line number Diff line Loading @@ -325,10 +325,8 @@ public class BrightnessClamperController { modifiers.add(new BrightnessLowLuxModifier(handler, listener, context, data.mDisplayDeviceConfig)); } if (flags.useNewHdrBrightnessModifier()) { modifiers.add(new HdrBrightnessModifier( handler, context, flags, pluginManager, listener, data)); } return modifiers; } Loading services/core/java/com/android/server/display/brightness/clamper/HdrClamper.javadeleted 100644 → 0 +0 −281 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.annotation.Nullable; import android.annotation.SuppressLint; import android.os.Handler; import android.os.IBinder; import android.os.PowerManager; import android.view.SurfaceControlHdrLayerInfoListener; import com.android.internal.annotations.VisibleForTesting; import com.android.server.display.AutomaticBrightnessController; import com.android.server.display.config.HdrBrightnessData; import java.io.PrintWriter; import java.util.Map; public class HdrClamper { private final BrightnessClamperController.ClamperChangeListener mClamperChangeListener; private final Handler mHandler; private final Runnable mDebouncer; private final HdrLayerInfoListener mHdrListener; @Nullable private HdrBrightnessData mHdrBrightnessData = null; @Nullable private IBinder mRegisteredDisplayToken = null; private float mAmbientLux = Float.MAX_VALUE; private boolean mHdrVisible = false; private float mMaxBrightness = PowerManager.BRIGHTNESS_MAX; private float mDesiredMaxBrightness = PowerManager.BRIGHTNESS_MAX; // brightness change speed, in units per seconds, private float mTransitionRate = -1f; private float mDesiredTransitionRate = -1f; private boolean mAutoBrightnessEnabled = false; /** * Indicates that maxBrightness is changed, and we should use slow transition */ private boolean mUseSlowTransition = false; public HdrClamper(BrightnessClamperController.ClamperChangeListener clamperChangeListener, Handler handler) { this(clamperChangeListener, handler, new Injector()); } @VisibleForTesting public HdrClamper(BrightnessClamperController.ClamperChangeListener clamperChangeListener, Handler handler, Injector injector) { mClamperChangeListener = clamperChangeListener; mHandler = handler; mDebouncer = () -> { mTransitionRate = mDesiredTransitionRate; mMaxBrightness = mDesiredMaxBrightness; mUseSlowTransition = true; mClamperChangeListener.onChanged(); }; mHdrListener = injector.getHdrListener((visible) -> { mHdrVisible = visible; recalculateBrightnessCap(mHdrBrightnessData, mAmbientLux, mHdrVisible); }, handler); } /** * Applies clamping * Called in same looper: mHandler.getLooper() */ public float clamp(float brightness) { return Math.min(brightness, mMaxBrightness); } @VisibleForTesting public float getMaxBrightness() { return mMaxBrightness; } // Called in same looper: mHandler.getLooper() public float getTransitionRate() { float expectedTransitionRate = mUseSlowTransition ? mTransitionRate : -1; mUseSlowTransition = false; return expectedTransitionRate; } /** * Updates brightness cap in response to ambient lux change. * Called by ABC in same looper: mHandler.getLooper() */ public void onAmbientLuxChange(float ambientLux) { mAmbientLux = ambientLux; recalculateBrightnessCap(mHdrBrightnessData, ambientLux, mHdrVisible); } /** * Updates brightness cap config. * Called in same looper: mHandler.getLooper() */ @SuppressLint("AndroidFrameworkRequiresPermission") public void resetHdrConfig(HdrBrightnessData data, int width, int height, float minimumHdrPercentOfScreen, IBinder displayToken) { mHdrBrightnessData = data; mHdrListener.mHdrMinPixels = (float) (width * height) * minimumHdrPercentOfScreen; if (displayToken != mRegisteredDisplayToken) { // token changed, resubscribe if (mRegisteredDisplayToken != null) { // previous token not null, unsubscribe mHdrListener.unregister(mRegisteredDisplayToken); mHdrVisible = false; mRegisteredDisplayToken = null; } // new token not null and hdr min % of the screen is set, subscribe. // e.g. for virtual display, HBM data will be missing and HdrListener // should not be registered if (displayToken != null && mHdrListener.mHdrMinPixels >= 0 && hasBrightnessLimits()) { mHdrListener.register(displayToken); mRegisteredDisplayToken = displayToken; } } recalculateBrightnessCap(data, mAmbientLux, mHdrVisible); } /** * Sets state of auto brightness to temporary disabling this Clamper if auto brightness is off. * The issue is tracked here: b/322445088 */ public void setAutoBrightnessState(int state) { boolean isEnabled = state == AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED; if (isEnabled != mAutoBrightnessEnabled) { mAutoBrightnessEnabled = isEnabled; recalculateBrightnessCap(mHdrBrightnessData, mAmbientLux, mHdrVisible); } } /** Clean up all resources */ @SuppressLint("AndroidFrameworkRequiresPermission") public void stop() { if (mRegisteredDisplayToken != null) { mHdrListener.unregister(mRegisteredDisplayToken); } } /** * Dumps the state of HdrClamper. */ public void dump(PrintWriter pw) { pw.println("HdrClamper:"); pw.println(" mMaxBrightness=" + mMaxBrightness); pw.println(" mDesiredMaxBrightness=" + mDesiredMaxBrightness); pw.println(" mTransitionRate=" + mTransitionRate); pw.println(" mDesiredTransitionRate=" + mDesiredTransitionRate); pw.println(" mHdrVisible=" + mHdrVisible); pw.println(" mHdrListener.mHdrMinPixels=" + mHdrListener.mHdrMinPixels); pw.println(" mHdrBrightnessData=" + (mHdrBrightnessData == null ? "null" : mHdrBrightnessData.toString())); pw.println(" mHdrListener registered=" + (mRegisteredDisplayToken != null)); pw.println(" mAmbientLux=" + mAmbientLux); pw.println(" mAutoBrightnessEnabled=" + mAutoBrightnessEnabled); } private boolean hasBrightnessLimits() { return mHdrBrightnessData != null && !mHdrBrightnessData.maxBrightnessLimits.isEmpty(); } private void reset() { if (mMaxBrightness == PowerManager.BRIGHTNESS_MAX && mDesiredMaxBrightness == PowerManager.BRIGHTNESS_MAX && mTransitionRate == -1f && mDesiredTransitionRate == -1f) { // already done reset, do nothing return; } mHandler.removeCallbacks(mDebouncer); mMaxBrightness = PowerManager.BRIGHTNESS_MAX; mDesiredMaxBrightness = PowerManager.BRIGHTNESS_MAX; mDesiredTransitionRate = -1f; mTransitionRate = -1f; mUseSlowTransition = false; mClamperChangeListener.onChanged(); } private void recalculateBrightnessCap(HdrBrightnessData data, float ambientLux, boolean hdrVisible) { // AutoBrightnessController sends ambientLux values *only* when auto brightness enabled. // Temporary disabling this Clamper if auto brightness is off, to avoid capping // brightness based on stale ambient lux. The issue is tracked here: b/322445088 if (data == null || !hdrVisible || !mAutoBrightnessEnabled) { reset(); return; } float expectedMaxBrightness = findBrightnessLimit(data, ambientLux); if (mMaxBrightness == expectedMaxBrightness) { mDesiredMaxBrightness = mMaxBrightness; mDesiredTransitionRate = -1f; mTransitionRate = -1f; mHandler.removeCallbacks(mDebouncer); } else if (mDesiredMaxBrightness != expectedMaxBrightness) { mDesiredMaxBrightness = expectedMaxBrightness; long debounceTime; if (mDesiredMaxBrightness > mMaxBrightness) { debounceTime = mHdrBrightnessData.brightnessIncreaseDebounceMillis; mDesiredTransitionRate = mHdrBrightnessData.screenBrightnessRampIncrease; } else { debounceTime = mHdrBrightnessData.brightnessDecreaseDebounceMillis; mDesiredTransitionRate = mHdrBrightnessData.screenBrightnessRampDecrease; } mHandler.removeCallbacks(mDebouncer); mHandler.postDelayed(mDebouncer, debounceTime); } // do nothing if expectedMaxBrightness == mDesiredMaxBrightness // && expectedMaxBrightness != mMaxBrightness } private float findBrightnessLimit(HdrBrightnessData data, float ambientLux) { float foundAmbientBoundary = Float.MAX_VALUE; float foundMaxBrightness = PowerManager.BRIGHTNESS_MAX; for (Map.Entry<Float, Float> brightnessPoint : data.maxBrightnessLimits.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; } @FunctionalInterface interface HdrListener { void onHdrVisible(boolean visible); } static class HdrLayerInfoListener extends SurfaceControlHdrLayerInfoListener { private final HdrListener mHdrListener; private final Handler mHandler; private float mHdrMinPixels = Float.MAX_VALUE; HdrLayerInfoListener(HdrListener hdrListener, Handler handler) { mHdrListener = hdrListener; mHandler = handler; } @Override public void onHdrInfoChanged(IBinder displayToken, int numberOfHdrLayers, int maxW, int maxH, int flags, float maxDesiredHdrSdrRatio) { mHandler.post(() -> mHdrListener.onHdrVisible( numberOfHdrLayers > 0 && (float) (maxW * maxH) >= mHdrMinPixels)); } } static class Injector { HdrLayerInfoListener getHdrListener(HdrListener hdrListener, Handler handler) { return new HdrLayerInfoListener(hdrListener, handler); } } } services/core/java/com/android/server/display/feature/DisplayManagerFlags.java +0 −12 Original line number Diff line number Diff line Loading @@ -177,10 +177,6 @@ public class DisplayManagerFlags { Flags.FLAG_OFFLOAD_SESSION_CANCEL_BLOCK_SCREEN_ON, Flags::offloadSessionCancelBlockScreenOn); private final FlagState mNewHdrBrightnessModifier = new FlagState( Flags.FLAG_NEW_HDR_BRIGHTNESS_MODIFIER, Flags::newHdrBrightnessModifier); private final FlagState mVirtualDisplayLimit = new FlagState( Flags.FLAG_VIRTUAL_DISPLAY_LIMIT, Loading Loading @@ -482,13 +478,6 @@ public class DisplayManagerFlags { return mSynthetic60hzModes.isEnabled(); } /** * @return Whether to use new HDR brightness modifier or not */ public boolean useNewHdrBrightnessModifier() { return mNewHdrBrightnessModifier.isEnabled(); } public boolean isVirtualDisplayLimitEnabled() { return mVirtualDisplayLimit.isEnabled(); } Loading Loading @@ -688,7 +677,6 @@ public class DisplayManagerFlags { pw.println(" " + mIgnoreAppPreferredRefreshRate); pw.println(" " + mSynthetic60hzModes); pw.println(" " + mOffloadSessionCancelBlockScreenOn); pw.println(" " + mNewHdrBrightnessModifier); pw.println(" " + mVirtualDisplayLimit); pw.println(" " + mNormalBrightnessForDozeParameter); pw.println(" " + mEnableBatteryStatsForAllDisplays); Loading Loading
services/core/java/com/android/server/display/BrightnessRangeController.java +6 −50 Original line number Diff line number Diff line Loading @@ -17,13 +17,9 @@ package com.android.server.display; import android.annotation.Nullable; import android.os.Handler; import android.os.IBinder; import com.android.internal.annotations.VisibleForTesting; import com.android.server.display.brightness.clamper.HdrClamper; import com.android.server.display.config.HighBrightnessModeData; import com.android.server.display.feature.DisplayManagerFlags; import java.io.PrintWriter; import java.util.function.BooleanSupplier; Loading @@ -33,48 +29,31 @@ class BrightnessRangeController { private final HighBrightnessModeController mHbmController; private final NormalBrightnessModeController mNormalBrightnessModeController; private final HdrClamper mHdrClamper; private final Runnable mModeChangeCallback; private final boolean mUseHdrClamper; BrightnessRangeController(HighBrightnessModeController hbmController, Runnable modeChangeCallback, DisplayDeviceConfig displayDeviceConfig, Handler handler, DisplayManagerFlags flags, IBinder displayToken, DisplayDeviceInfo info) { Runnable modeChangeCallback, DisplayDeviceConfig displayDeviceConfig) { this(hbmController, modeChangeCallback, displayDeviceConfig, new NormalBrightnessModeController(), new HdrClamper(modeChangeCallback::run, new Handler(handler.getLooper())), flags, displayToken, info); new NormalBrightnessModeController()); } @VisibleForTesting BrightnessRangeController(HighBrightnessModeController hbmController, Runnable modeChangeCallback, DisplayDeviceConfig displayDeviceConfig, NormalBrightnessModeController normalBrightnessModeController, HdrClamper hdrClamper, DisplayManagerFlags flags, IBinder displayToken, DisplayDeviceInfo info) { NormalBrightnessModeController normalBrightnessModeController) { mHbmController = hbmController; mModeChangeCallback = modeChangeCallback; mHdrClamper = hdrClamper; mNormalBrightnessModeController = normalBrightnessModeController; mUseHdrClamper = !flags.useNewHdrBrightnessModifier(); mNormalBrightnessModeController.resetNbmData( displayDeviceConfig.getLuxThrottlingData()); if (flags.useNewHdrBrightnessModifier()) { // HDR boost is handled by HdrBrightnessModifier and should be disabled in HbmController mHbmController.disableHdrBoost(); } updateHdrClamper(info, displayToken, displayDeviceConfig); } void dump(PrintWriter pw) { pw.println("BrightnessRangeController:"); pw.println(" mUseHdrClamper=" + mUseHdrClamper); mHbmController.dump(pw); mNormalBrightnessModeController.dump(pw); mHdrClamper.dump(pw); } void onAmbientLuxChange(float ambientLux) { Loading @@ -82,9 +61,6 @@ class BrightnessRangeController { () -> mNormalBrightnessModeController.onAmbientLuxChange(ambientLux), () -> mHbmController.onAmbientLuxChange(ambientLux) ); if (mUseHdrClamper) { mHdrClamper.onAmbientLuxChange(ambientLux); } } float getNormalBrightnessMax() { Loading @@ -103,12 +79,10 @@ class BrightnessRangeController { displayDeviceConfig::getHdrBrightnessFromSdr); } ); updateHdrClamper(info, token, displayDeviceConfig); } void stop() { mHbmController.stop(); mHdrClamper.stop(); } void setAutoBrightnessEnabled(int state) { Loading @@ -116,7 +90,6 @@ class BrightnessRangeController { () -> mNormalBrightnessModeController.setAutoBrightnessState(state), () -> mHbmController.setAutoBrightnessEnabled(state) ); mHdrClamper.setAutoBrightnessState(state); } void onBrightnessChanged(float brightness, float unthrottledBrightness, Loading Loading @@ -147,26 +120,13 @@ class BrightnessRangeController { } float getHdrBrightnessValue() { float hdrBrightness = mHbmController.getHdrBrightnessValue(); return mUseHdrClamper ? mHdrClamper.clamp(hdrBrightness) : hdrBrightness; return mHbmController.getHdrBrightnessValue(); } float getTransitionPoint() { return mHbmController.getTransitionPoint(); } private void updateHdrClamper(DisplayDeviceInfo info, IBinder token, DisplayDeviceConfig displayDeviceConfig) { if (mUseHdrClamper) { HighBrightnessModeData hbmData = displayDeviceConfig.getHighBrightnessModeData(); float minimumHdrPercentOfScreen = hbmData == null ? -1f : hbmData.minimumHdrPercentOfScreen; mHdrClamper.resetHdrConfig(displayDeviceConfig.getHdrBrightnessData(), info.width, info.height, minimumHdrPercentOfScreen, token); } } private void applyChanges(BooleanSupplier nbmChangesFunc, Runnable hbmChangesFunc) { boolean nbmTransitionChanged = nbmChangesFunc.getAsBoolean(); hbmChangesFunc.run(); Loading @@ -176,8 +136,4 @@ class BrightnessRangeController { mModeChangeCallback.run(); } } public float getHdrTransitionRate() { return mUseHdrClamper ? mHdrClamper.getTransitionRate() : -1; } }
services/core/java/com/android/server/display/DisplayPowerController.java +3 −7 Original line number Diff line number Diff line Loading @@ -594,8 +594,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call modeChangeCallback); mBrightnessRangeController = mInjector.getBrightnessRangeController(hbmController, modeChangeCallback, mDisplayDeviceConfig, mHandler, flags, displayToken, displayDeviceInfo); modeChangeCallback, mDisplayDeviceConfig); mDisplayBrightnessController = new DisplayBrightnessController(context, mDisplayId, Loading Loading @@ -1689,8 +1688,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // SDR brightness immediately when entering dim or low power mode. animateValue = mBrightnessRangeController.getHdrBrightnessValue(); hdrBrightness = animateValue; customAnimationRate = Math.max(customAnimationRate, mBrightnessRangeController.getHdrTransitionRate()); mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_HDR); } Loading Loading @@ -3369,10 +3366,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call BrightnessRangeController getBrightnessRangeController( HighBrightnessModeController hbmController, Runnable modeChangeCallback, DisplayDeviceConfig displayDeviceConfig, Handler handler, DisplayManagerFlags flags, IBinder displayToken, DisplayDeviceInfo info) { DisplayDeviceConfig displayDeviceConfig) { return new BrightnessRangeController(hbmController, modeChangeCallback, displayDeviceConfig, handler, flags, displayToken, info); modeChangeCallback, displayDeviceConfig); } BrightnessClamperController getBrightnessClamperController(Handler handler, Loading
services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java +2 −4 Original line number Diff line number Diff line Loading @@ -325,10 +325,8 @@ public class BrightnessClamperController { modifiers.add(new BrightnessLowLuxModifier(handler, listener, context, data.mDisplayDeviceConfig)); } if (flags.useNewHdrBrightnessModifier()) { modifiers.add(new HdrBrightnessModifier( handler, context, flags, pluginManager, listener, data)); } return modifiers; } Loading
services/core/java/com/android/server/display/brightness/clamper/HdrClamper.javadeleted 100644 → 0 +0 −281 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.annotation.Nullable; import android.annotation.SuppressLint; import android.os.Handler; import android.os.IBinder; import android.os.PowerManager; import android.view.SurfaceControlHdrLayerInfoListener; import com.android.internal.annotations.VisibleForTesting; import com.android.server.display.AutomaticBrightnessController; import com.android.server.display.config.HdrBrightnessData; import java.io.PrintWriter; import java.util.Map; public class HdrClamper { private final BrightnessClamperController.ClamperChangeListener mClamperChangeListener; private final Handler mHandler; private final Runnable mDebouncer; private final HdrLayerInfoListener mHdrListener; @Nullable private HdrBrightnessData mHdrBrightnessData = null; @Nullable private IBinder mRegisteredDisplayToken = null; private float mAmbientLux = Float.MAX_VALUE; private boolean mHdrVisible = false; private float mMaxBrightness = PowerManager.BRIGHTNESS_MAX; private float mDesiredMaxBrightness = PowerManager.BRIGHTNESS_MAX; // brightness change speed, in units per seconds, private float mTransitionRate = -1f; private float mDesiredTransitionRate = -1f; private boolean mAutoBrightnessEnabled = false; /** * Indicates that maxBrightness is changed, and we should use slow transition */ private boolean mUseSlowTransition = false; public HdrClamper(BrightnessClamperController.ClamperChangeListener clamperChangeListener, Handler handler) { this(clamperChangeListener, handler, new Injector()); } @VisibleForTesting public HdrClamper(BrightnessClamperController.ClamperChangeListener clamperChangeListener, Handler handler, Injector injector) { mClamperChangeListener = clamperChangeListener; mHandler = handler; mDebouncer = () -> { mTransitionRate = mDesiredTransitionRate; mMaxBrightness = mDesiredMaxBrightness; mUseSlowTransition = true; mClamperChangeListener.onChanged(); }; mHdrListener = injector.getHdrListener((visible) -> { mHdrVisible = visible; recalculateBrightnessCap(mHdrBrightnessData, mAmbientLux, mHdrVisible); }, handler); } /** * Applies clamping * Called in same looper: mHandler.getLooper() */ public float clamp(float brightness) { return Math.min(brightness, mMaxBrightness); } @VisibleForTesting public float getMaxBrightness() { return mMaxBrightness; } // Called in same looper: mHandler.getLooper() public float getTransitionRate() { float expectedTransitionRate = mUseSlowTransition ? mTransitionRate : -1; mUseSlowTransition = false; return expectedTransitionRate; } /** * Updates brightness cap in response to ambient lux change. * Called by ABC in same looper: mHandler.getLooper() */ public void onAmbientLuxChange(float ambientLux) { mAmbientLux = ambientLux; recalculateBrightnessCap(mHdrBrightnessData, ambientLux, mHdrVisible); } /** * Updates brightness cap config. * Called in same looper: mHandler.getLooper() */ @SuppressLint("AndroidFrameworkRequiresPermission") public void resetHdrConfig(HdrBrightnessData data, int width, int height, float minimumHdrPercentOfScreen, IBinder displayToken) { mHdrBrightnessData = data; mHdrListener.mHdrMinPixels = (float) (width * height) * minimumHdrPercentOfScreen; if (displayToken != mRegisteredDisplayToken) { // token changed, resubscribe if (mRegisteredDisplayToken != null) { // previous token not null, unsubscribe mHdrListener.unregister(mRegisteredDisplayToken); mHdrVisible = false; mRegisteredDisplayToken = null; } // new token not null and hdr min % of the screen is set, subscribe. // e.g. for virtual display, HBM data will be missing and HdrListener // should not be registered if (displayToken != null && mHdrListener.mHdrMinPixels >= 0 && hasBrightnessLimits()) { mHdrListener.register(displayToken); mRegisteredDisplayToken = displayToken; } } recalculateBrightnessCap(data, mAmbientLux, mHdrVisible); } /** * Sets state of auto brightness to temporary disabling this Clamper if auto brightness is off. * The issue is tracked here: b/322445088 */ public void setAutoBrightnessState(int state) { boolean isEnabled = state == AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED; if (isEnabled != mAutoBrightnessEnabled) { mAutoBrightnessEnabled = isEnabled; recalculateBrightnessCap(mHdrBrightnessData, mAmbientLux, mHdrVisible); } } /** Clean up all resources */ @SuppressLint("AndroidFrameworkRequiresPermission") public void stop() { if (mRegisteredDisplayToken != null) { mHdrListener.unregister(mRegisteredDisplayToken); } } /** * Dumps the state of HdrClamper. */ public void dump(PrintWriter pw) { pw.println("HdrClamper:"); pw.println(" mMaxBrightness=" + mMaxBrightness); pw.println(" mDesiredMaxBrightness=" + mDesiredMaxBrightness); pw.println(" mTransitionRate=" + mTransitionRate); pw.println(" mDesiredTransitionRate=" + mDesiredTransitionRate); pw.println(" mHdrVisible=" + mHdrVisible); pw.println(" mHdrListener.mHdrMinPixels=" + mHdrListener.mHdrMinPixels); pw.println(" mHdrBrightnessData=" + (mHdrBrightnessData == null ? "null" : mHdrBrightnessData.toString())); pw.println(" mHdrListener registered=" + (mRegisteredDisplayToken != null)); pw.println(" mAmbientLux=" + mAmbientLux); pw.println(" mAutoBrightnessEnabled=" + mAutoBrightnessEnabled); } private boolean hasBrightnessLimits() { return mHdrBrightnessData != null && !mHdrBrightnessData.maxBrightnessLimits.isEmpty(); } private void reset() { if (mMaxBrightness == PowerManager.BRIGHTNESS_MAX && mDesiredMaxBrightness == PowerManager.BRIGHTNESS_MAX && mTransitionRate == -1f && mDesiredTransitionRate == -1f) { // already done reset, do nothing return; } mHandler.removeCallbacks(mDebouncer); mMaxBrightness = PowerManager.BRIGHTNESS_MAX; mDesiredMaxBrightness = PowerManager.BRIGHTNESS_MAX; mDesiredTransitionRate = -1f; mTransitionRate = -1f; mUseSlowTransition = false; mClamperChangeListener.onChanged(); } private void recalculateBrightnessCap(HdrBrightnessData data, float ambientLux, boolean hdrVisible) { // AutoBrightnessController sends ambientLux values *only* when auto brightness enabled. // Temporary disabling this Clamper if auto brightness is off, to avoid capping // brightness based on stale ambient lux. The issue is tracked here: b/322445088 if (data == null || !hdrVisible || !mAutoBrightnessEnabled) { reset(); return; } float expectedMaxBrightness = findBrightnessLimit(data, ambientLux); if (mMaxBrightness == expectedMaxBrightness) { mDesiredMaxBrightness = mMaxBrightness; mDesiredTransitionRate = -1f; mTransitionRate = -1f; mHandler.removeCallbacks(mDebouncer); } else if (mDesiredMaxBrightness != expectedMaxBrightness) { mDesiredMaxBrightness = expectedMaxBrightness; long debounceTime; if (mDesiredMaxBrightness > mMaxBrightness) { debounceTime = mHdrBrightnessData.brightnessIncreaseDebounceMillis; mDesiredTransitionRate = mHdrBrightnessData.screenBrightnessRampIncrease; } else { debounceTime = mHdrBrightnessData.brightnessDecreaseDebounceMillis; mDesiredTransitionRate = mHdrBrightnessData.screenBrightnessRampDecrease; } mHandler.removeCallbacks(mDebouncer); mHandler.postDelayed(mDebouncer, debounceTime); } // do nothing if expectedMaxBrightness == mDesiredMaxBrightness // && expectedMaxBrightness != mMaxBrightness } private float findBrightnessLimit(HdrBrightnessData data, float ambientLux) { float foundAmbientBoundary = Float.MAX_VALUE; float foundMaxBrightness = PowerManager.BRIGHTNESS_MAX; for (Map.Entry<Float, Float> brightnessPoint : data.maxBrightnessLimits.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; } @FunctionalInterface interface HdrListener { void onHdrVisible(boolean visible); } static class HdrLayerInfoListener extends SurfaceControlHdrLayerInfoListener { private final HdrListener mHdrListener; private final Handler mHandler; private float mHdrMinPixels = Float.MAX_VALUE; HdrLayerInfoListener(HdrListener hdrListener, Handler handler) { mHdrListener = hdrListener; mHandler = handler; } @Override public void onHdrInfoChanged(IBinder displayToken, int numberOfHdrLayers, int maxW, int maxH, int flags, float maxDesiredHdrSdrRatio) { mHandler.post(() -> mHdrListener.onHdrVisible( numberOfHdrLayers > 0 && (float) (maxW * maxH) >= mHdrMinPixels)); } } static class Injector { HdrLayerInfoListener getHdrListener(HdrListener hdrListener, Handler handler) { return new HdrLayerInfoListener(hdrListener, handler); } } }
services/core/java/com/android/server/display/feature/DisplayManagerFlags.java +0 −12 Original line number Diff line number Diff line Loading @@ -177,10 +177,6 @@ public class DisplayManagerFlags { Flags.FLAG_OFFLOAD_SESSION_CANCEL_BLOCK_SCREEN_ON, Flags::offloadSessionCancelBlockScreenOn); private final FlagState mNewHdrBrightnessModifier = new FlagState( Flags.FLAG_NEW_HDR_BRIGHTNESS_MODIFIER, Flags::newHdrBrightnessModifier); private final FlagState mVirtualDisplayLimit = new FlagState( Flags.FLAG_VIRTUAL_DISPLAY_LIMIT, Loading Loading @@ -482,13 +478,6 @@ public class DisplayManagerFlags { return mSynthetic60hzModes.isEnabled(); } /** * @return Whether to use new HDR brightness modifier or not */ public boolean useNewHdrBrightnessModifier() { return mNewHdrBrightnessModifier.isEnabled(); } public boolean isVirtualDisplayLimitEnabled() { return mVirtualDisplayLimit.isEnabled(); } Loading Loading @@ -688,7 +677,6 @@ public class DisplayManagerFlags { pw.println(" " + mIgnoreAppPreferredRefreshRate); pw.println(" " + mSynthetic60hzModes); pw.println(" " + mOffloadSessionCancelBlockScreenOn); pw.println(" " + mNewHdrBrightnessModifier); pw.println(" " + mVirtualDisplayLimit); pw.println(" " + mNormalBrightnessForDozeParameter); pw.println(" " + mEnableBatteryStatsForAllDisplays); Loading