Loading services/core/java/com/android/server/display/DisplayBrightnessState.java +2 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.display; import android.hardware.display.BrightnessInfo; import android.os.PowerManager; import android.text.TextUtils; import com.android.server.display.brightness.BrightnessEvent; Loading Loading @@ -255,7 +256,7 @@ public final class DisplayBrightnessState { private String mDisplayBrightnessStrategyName; private boolean mShouldUseAutoBrightness; private boolean mIsSlowChange; private float mMaxBrightness; private float mMaxBrightness = PowerManager.BRIGHTNESS_MAX; private float mMinBrightness; private float mCustomAnimationRate = CUSTOM_ANIMATION_RATE_NOT_SET; private boolean mShouldUpdateScreenBrightnessSetting; Loading services/core/java/com/android/server/display/brightness/clamper/BrightnessClamper.java +0 −1 Original line number Diff line number Diff line Loading @@ -73,7 +73,6 @@ abstract class BrightnessClamper<T> { abstract void stop(); protected enum Type { THERMAL, POWER, WEAR_BEDTIME_MODE, } Loading services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java +30 −11 Original line number Diff line number Diff line Loading @@ -72,6 +72,8 @@ public class BrightnessClamperController { private final List<DisplayDeviceDataListener> mDisplayDeviceDataListeners = new ArrayList<>(); private final List<StatefulModifier> mStatefulModifiers = new ArrayList<>(); private final List<UserSwitchListener> mUserSwitchListeners = new ArrayList<>(); private final List<DeviceConfigListener> mDeviceConfigListeners = new ArrayList<>(); private ModifiersAggregatedState mModifiersAggregatedState = new ModifiersAggregatedState(); private final DeviceConfig.OnPropertiesChangedListener mOnPropertiesChangedListener; Loading Loading @@ -144,9 +146,14 @@ public class BrightnessClamperController { if (m instanceof UserSwitchListener l) { mUserSwitchListeners.add(l); } if (m instanceof DeviceConfigListener l) { mDeviceConfigListeners.add(l); } }); mOnPropertiesChangedListener = properties -> mClampers.forEach(BrightnessClamper::onDeviceConfigChanged); mOnPropertiesChangedListener = properties -> { mClampers.forEach(BrightnessClamper::onDeviceConfigChanged); mDeviceConfigListeners.forEach(DeviceConfigListener::onDeviceConfigChanged); }; mLightSensorController.configure(data.getAmbientLightSensor(), data.getDisplayId()); start(); } Loading Loading @@ -209,8 +216,6 @@ public class BrightnessClamperController { private int getBrightnessMaxReason() { if (mClamperType == null) { return BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE; } else if (mClamperType == Type.THERMAL) { return BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL; } else if (mClamperType == Type.POWER) { return BrightnessInfo.BRIGHTNESS_MAX_REASON_POWER_IC; } else if (mClamperType == Type.WEAR_BEDTIME_MODE) { Loading @@ -225,7 +230,7 @@ public class BrightnessClamperController { * Called when the user switches. */ public void onUserSwitch() { mUserSwitchListeners.forEach(listener -> listener.onSwitchUser()); mUserSwitchListeners.forEach(UserSwitchListener::onSwitchUser); } /** Loading Loading @@ -294,11 +299,14 @@ public class BrightnessClamperController { state2.mMaxDesiredHdrRatio) || !BrightnessSynchronizer.floatEquals(state1.mMaxHdrBrightness, state2.mMaxHdrBrightness) || state1.mSdrHdrRatioSpline != state2.mSdrHdrRatioSpline; || state1.mSdrHdrRatioSpline != state2.mSdrHdrRatioSpline || state1.mMaxBrightnessReason != state2.mMaxBrightnessReason || !BrightnessSynchronizer.floatEquals(state1.mMaxBrightness, state2.mMaxBrightness); } private void start() { if (!mClampers.isEmpty()) { if (!mClampers.isEmpty() || !mDeviceConfigListeners.isEmpty()) { mDeviceConfigParameterProvider.addOnPropertiesChangedListener( mExecutor, mOnPropertiesChangedListener); } Loading Loading @@ -333,8 +341,7 @@ public class BrightnessClamperController { ClamperChangeListener clamperChangeListener, DisplayDeviceData data, DisplayManagerFlags flags, Context context, float currentBrightness) { List<BrightnessClamper<? super DisplayDeviceData>> clampers = new ArrayList<>(); clampers.add( new BrightnessThermalClamper(handler, clamperChangeListener, data)); if (flags.isPowerThrottlingClamperEnabled()) { // Check if power-throttling config is present. PowerThrottlingConfigData configData = data.getPowerThrottlingConfigData(); Loading @@ -354,6 +361,8 @@ public class BrightnessClamperController { Handler handler, ClamperChangeListener listener, DisplayDeviceData data) { List<BrightnessStateModifier> modifiers = new ArrayList<>(); modifiers.add(new BrightnessThermalModifier(handler, listener, data)); modifiers.add(new DisplayDimModifier(context)); modifiers.add(new BrightnessLowPowerModeModifier()); if (flags.isEvenDimmerEnabled() && data.mDisplayDeviceConfig.isEvenDimmerAvailable()) { Loading Loading @@ -384,7 +393,7 @@ public class BrightnessClamperController { /** * Config Data for clampers/modifiers */ public static class DisplayDeviceData implements BrightnessThermalClamper.ThermalData, public static class DisplayDeviceData implements BrightnessThermalModifier.ThermalData, BrightnessPowerClamper.PowerData, BrightnessWearBedtimeModeClamper.WearBedtimeModeData { @NonNull Loading Loading @@ -497,14 +506,24 @@ public class BrightnessClamperController { void onSwitchUser(); } /** * Modifier should implement this interface in order to receive device config updates */ interface DeviceConfigListener { void onDeviceConfigChanged(); } /** * StatefulModifiers contribute to AggregatedState, that is used to decide if brightness * adjustement is needed * adjustment is needed */ public static class ModifiersAggregatedState { float mMaxDesiredHdrRatio = HdrBrightnessModifier.DEFAULT_MAX_HDR_SDR_RATIO; float mMaxHdrBrightness = PowerManager.BRIGHTNESS_MAX; @Nullable Spline mSdrHdrRatioSpline = null; @BrightnessInfo.BrightnessMaxReason int mMaxBrightnessReason = BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE; float mMaxBrightness = PowerManager.BRIGHTNESS_MAX; } } services/core/java/com/android/server/display/brightness/clamper/BrightnessThermalClamper.java→services/core/java/com/android/server/display/brightness/clamper/BrightnessThermalModifier.java +87 −37 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ import static com.android.server.display.brightness.clamper.BrightnessClamperCon import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.hardware.display.BrightnessInfo; import android.hardware.display.DisplayManagerInternal; import android.os.Handler; import android.os.IThermalEventListener; import android.os.IThermalService; Loading @@ -33,8 +35,10 @@ import android.provider.DeviceConfigInterface; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import com.android.server.display.DisplayBrightnessState; import com.android.server.display.DisplayDeviceConfig.ThermalBrightnessThrottlingData; import com.android.server.display.DisplayDeviceConfig.ThermalBrightnessThrottlingData.ThrottlingLevel; import com.android.server.display.brightness.BrightnessReason; import com.android.server.display.config.SensorData; import com.android.server.display.feature.DeviceConfigParameterProvider; import com.android.server.display.utils.DeviceConfigParsingUtils; Loading @@ -43,12 +47,15 @@ import com.android.server.display.utils.SensorUtils; import java.io.PrintWriter; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.function.BiFunction; import java.util.function.Function; class BrightnessThermalClamper extends BrightnessClamper<BrightnessThermalClamper.ThermalData> { class BrightnessThermalModifier implements BrightnessStateModifier, BrightnessClamperController.DisplayDeviceDataListener, BrightnessClamperController.StatefulModifier, BrightnessClamperController.DeviceConfigListener { private static final String TAG = "BrightnessThermalClamper"; @NonNull Loading @@ -57,6 +64,11 @@ class BrightnessThermalClamper extends private final DeviceConfigParameterProvider mConfigParameterProvider; // data from DeviceConfig, for all displays, for all dataSets // mapOf(uniqueDisplayId to mapOf(dataSetId to ThermalBrightnessThrottlingData)) @NonNull protected final Handler mHandler; @NonNull protected final BrightnessClamperController.ClamperChangeListener mChangeListener; @NonNull private Map<String, Map<String, ThermalBrightnessThrottlingData>> mThermalThrottlingDataOverride = Map.of(); Loading @@ -73,6 +85,8 @@ class BrightnessThermalClamper extends private String mDataId = null; @Temperature.ThrottlingStatus private int mThrottlingStatus = Temperature.THROTTLING_NONE; private float mBrightnessCap = PowerManager.BRIGHTNESS_MAX; private boolean mApplied = false; private final BiFunction<String, String, ThrottlingLevel> mDataPointMapper = (key, value) -> { try { Loading @@ -88,63 +102,104 @@ class BrightnessThermalClamper extends mDataSetMapper = ThermalBrightnessThrottlingData::create; BrightnessThermalClamper(Handler handler, ClamperChangeListener listener, ThermalData thermalData) { this(new Injector(), handler, listener, thermalData); BrightnessThermalModifier(Handler handler, ClamperChangeListener listener, BrightnessClamperController.DisplayDeviceData data) { this(new Injector(), handler, listener, data); } @VisibleForTesting BrightnessThermalClamper(Injector injector, Handler handler, ClamperChangeListener listener, ThermalData thermalData) { super(handler, listener); BrightnessThermalModifier(Injector injector, @NonNull Handler handler, @NonNull ClamperChangeListener listener, @NonNull BrightnessClamperController.DisplayDeviceData data) { mHandler = handler; mChangeListener = listener; mConfigParameterProvider = injector.getDeviceConfigParameterProvider(); mThermalStatusObserver = new ThermalStatusObserver(injector, handler); mHandler.post(() -> { setDisplayData(thermalData); setDisplayData(data); loadOverrideData(); }); } //region BrightnessStateModifier @Override public void apply(DisplayManagerInternal.DisplayPowerRequest request, DisplayBrightnessState.Builder stateBuilder) { if (stateBuilder.getMaxBrightness() > mBrightnessCap) { stateBuilder.setMaxBrightness(mBrightnessCap); stateBuilder.setBrightness(Math.min(stateBuilder.getBrightness(), mBrightnessCap)); stateBuilder.setBrightnessMaxReason(BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL); stateBuilder.getBrightnessReason().addModifier(BrightnessReason.MODIFIER_THROTTLED); // set fast change only when modifier is activated. // this will allow auto brightness to apply slow change even when modifier is active if (!mApplied) { stateBuilder.setIsSlowChange(false); } mApplied = true; } else { mApplied = false; } } @Override public void stop() { mThermalStatusObserver.stopObserving(); } @Override @NonNull Type getType() { return Type.THERMAL; public void dump(PrintWriter writer) { writer.println("BrightnessThermalClamper:"); writer.println(" mThrottlingStatus: " + mThrottlingStatus); writer.println(" mUniqueDisplayId: " + mUniqueDisplayId); writer.println(" mDataId: " + mDataId); writer.println(" mDataOverride: " + mThermalThrottlingDataOverride); writer.println(" mDataFromDeviceConfig: " + mThermalThrottlingDataFromDeviceConfig); writer.println(" mDataActive: " + mThermalThrottlingDataActive); writer.println(" mBrightnessCap:" + mBrightnessCap); writer.println(" mApplied:" + mApplied); mThermalStatusObserver.dump(writer); } @Override void onDeviceConfigChanged() { mHandler.post(() -> { loadOverrideData(); recalculateActiveData(); }); public boolean shouldListenToLightSensor() { return false; } @Override public void setAmbientLux(float lux) { // noop } //endregion //region DisplayDeviceDataListener @Override void onDisplayChanged(ThermalData data) { public void onDisplayChanged(BrightnessClamperController.DisplayDeviceData data) { mHandler.post(() -> { setDisplayData(data); recalculateActiveData(); }); } //endregion //region StatefulModifier @Override void stop() { mThermalStatusObserver.stopObserving(); public void applyStateChange( BrightnessClamperController.ModifiersAggregatedState aggregatedState) { if (aggregatedState.mMaxBrightness > mBrightnessCap) { aggregatedState.mMaxBrightness = mBrightnessCap; aggregatedState.mMaxBrightnessReason = BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL; } } //endregion //region DeviceConfigListener @Override void dump(PrintWriter writer) { writer.println("BrightnessThermalClamper:"); writer.println(" mThrottlingStatus: " + mThrottlingStatus); writer.println(" mUniqueDisplayId: " + mUniqueDisplayId); writer.println(" mDataId: " + mDataId); writer.println(" mDataOverride: " + mThermalThrottlingDataOverride); writer.println(" mDataFromDeviceConfig: " + mThermalThrottlingDataFromDeviceConfig); writer.println(" mDataActive: " + mThermalThrottlingDataActive); mThermalStatusObserver.dump(writer); super.dump(writer); public void onDeviceConfigChanged() { mHandler.post(() -> { loadOverrideData(); recalculateActiveData(); }); } //endregion private void recalculateActiveData() { if (mUniqueDisplayId == null || mDataId == null) { Loading Loading @@ -176,14 +231,11 @@ class BrightnessThermalClamper extends private void recalculateBrightnessCap() { float brightnessCap = PowerManager.BRIGHTNESS_MAX; boolean isActive = false; if (mThermalThrottlingDataActive != null) { // Throttling levels are sorted by increasing severity for (ThrottlingLevel level : mThermalThrottlingDataActive.throttlingLevels) { if (level.thermalStatus <= mThrottlingStatus) { brightnessCap = level.brightness; isActive = true; } else { // Throttling levels that are greater than the current status are irrelevant break; Loading @@ -191,9 +243,8 @@ class BrightnessThermalClamper extends } } if (brightnessCap != mBrightnessCap || mIsActive != isActive) { if (brightnessCap != mBrightnessCap) { mBrightnessCap = brightnessCap; mIsActive = isActive; mChangeListener.onChanged(); } } Loading @@ -205,7 +256,6 @@ class BrightnessThermalClamper extends } } private final class ThermalStatusObserver extends IThermalEventListener.Stub { private final Injector mInjector; private final Handler mHandler; Loading @@ -228,7 +278,7 @@ class BrightnessThermalClamper extends String curType = mObserverTempSensor.type; mObserverTempSensor = tempSensor; if (curType.equals(tempSensor.type)) { if (Objects.equals(curType, tempSensor.type)) { Slog.d(TAG, "Thermal status observer already started"); return; } Loading services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessClamperControllerTest.java +4 −4 Original line number Diff line number Diff line Loading @@ -226,7 +226,7 @@ public class BrightnessClamperControllerTest { float clampedBrightness = 0.6f; float customAnimationRate = 0.01f; when(mMockClamper.getBrightnessCap()).thenReturn(clampedBrightness); when(mMockClamper.getType()).thenReturn(BrightnessClamper.Type.THERMAL); when(mMockClamper.getType()).thenReturn(BrightnessClamper.Type.POWER); when(mMockClamper.getCustomAnimationRate()).thenReturn(customAnimationRate); when(mMockClamper.isActive()).thenReturn(false); mTestInjector.mCapturedChangeListener.onChanged(); Loading @@ -250,7 +250,7 @@ public class BrightnessClamperControllerTest { float clampedBrightness = 0.6f; float customAnimationRate = 0.01f; when(mMockClamper.getBrightnessCap()).thenReturn(clampedBrightness); when(mMockClamper.getType()).thenReturn(BrightnessClamper.Type.THERMAL); when(mMockClamper.getType()).thenReturn(BrightnessClamper.Type.POWER); when(mMockClamper.getCustomAnimationRate()).thenReturn(customAnimationRate); when(mMockClamper.isActive()).thenReturn(true); mTestInjector.mCapturedChangeListener.onChanged(); Loading @@ -274,7 +274,7 @@ public class BrightnessClamperControllerTest { float clampedBrightness = 0.8f; float customAnimationRate = 0.01f; when(mMockClamper.getBrightnessCap()).thenReturn(clampedBrightness); when(mMockClamper.getType()).thenReturn(BrightnessClamper.Type.THERMAL); when(mMockClamper.getType()).thenReturn(BrightnessClamper.Type.POWER); when(mMockClamper.getCustomAnimationRate()).thenReturn(customAnimationRate); when(mMockClamper.isActive()).thenReturn(true); mTestInjector.mCapturedChangeListener.onChanged(); Loading @@ -298,7 +298,7 @@ public class BrightnessClamperControllerTest { float clampedBrightness = 0.6f; float customAnimationRate = 0.01f; when(mMockClamper.getBrightnessCap()).thenReturn(clampedBrightness); when(mMockClamper.getType()).thenReturn(BrightnessClamper.Type.THERMAL); when(mMockClamper.getType()).thenReturn(BrightnessClamper.Type.POWER); when(mMockClamper.getCustomAnimationRate()).thenReturn(customAnimationRate); when(mMockClamper.isActive()).thenReturn(true); mTestInjector.mCapturedChangeListener.onChanged(); Loading Loading
services/core/java/com/android/server/display/DisplayBrightnessState.java +2 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.display; import android.hardware.display.BrightnessInfo; import android.os.PowerManager; import android.text.TextUtils; import com.android.server.display.brightness.BrightnessEvent; Loading Loading @@ -255,7 +256,7 @@ public final class DisplayBrightnessState { private String mDisplayBrightnessStrategyName; private boolean mShouldUseAutoBrightness; private boolean mIsSlowChange; private float mMaxBrightness; private float mMaxBrightness = PowerManager.BRIGHTNESS_MAX; private float mMinBrightness; private float mCustomAnimationRate = CUSTOM_ANIMATION_RATE_NOT_SET; private boolean mShouldUpdateScreenBrightnessSetting; Loading
services/core/java/com/android/server/display/brightness/clamper/BrightnessClamper.java +0 −1 Original line number Diff line number Diff line Loading @@ -73,7 +73,6 @@ abstract class BrightnessClamper<T> { abstract void stop(); protected enum Type { THERMAL, POWER, WEAR_BEDTIME_MODE, } Loading
services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java +30 −11 Original line number Diff line number Diff line Loading @@ -72,6 +72,8 @@ public class BrightnessClamperController { private final List<DisplayDeviceDataListener> mDisplayDeviceDataListeners = new ArrayList<>(); private final List<StatefulModifier> mStatefulModifiers = new ArrayList<>(); private final List<UserSwitchListener> mUserSwitchListeners = new ArrayList<>(); private final List<DeviceConfigListener> mDeviceConfigListeners = new ArrayList<>(); private ModifiersAggregatedState mModifiersAggregatedState = new ModifiersAggregatedState(); private final DeviceConfig.OnPropertiesChangedListener mOnPropertiesChangedListener; Loading Loading @@ -144,9 +146,14 @@ public class BrightnessClamperController { if (m instanceof UserSwitchListener l) { mUserSwitchListeners.add(l); } if (m instanceof DeviceConfigListener l) { mDeviceConfigListeners.add(l); } }); mOnPropertiesChangedListener = properties -> mClampers.forEach(BrightnessClamper::onDeviceConfigChanged); mOnPropertiesChangedListener = properties -> { mClampers.forEach(BrightnessClamper::onDeviceConfigChanged); mDeviceConfigListeners.forEach(DeviceConfigListener::onDeviceConfigChanged); }; mLightSensorController.configure(data.getAmbientLightSensor(), data.getDisplayId()); start(); } Loading Loading @@ -209,8 +216,6 @@ public class BrightnessClamperController { private int getBrightnessMaxReason() { if (mClamperType == null) { return BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE; } else if (mClamperType == Type.THERMAL) { return BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL; } else if (mClamperType == Type.POWER) { return BrightnessInfo.BRIGHTNESS_MAX_REASON_POWER_IC; } else if (mClamperType == Type.WEAR_BEDTIME_MODE) { Loading @@ -225,7 +230,7 @@ public class BrightnessClamperController { * Called when the user switches. */ public void onUserSwitch() { mUserSwitchListeners.forEach(listener -> listener.onSwitchUser()); mUserSwitchListeners.forEach(UserSwitchListener::onSwitchUser); } /** Loading Loading @@ -294,11 +299,14 @@ public class BrightnessClamperController { state2.mMaxDesiredHdrRatio) || !BrightnessSynchronizer.floatEquals(state1.mMaxHdrBrightness, state2.mMaxHdrBrightness) || state1.mSdrHdrRatioSpline != state2.mSdrHdrRatioSpline; || state1.mSdrHdrRatioSpline != state2.mSdrHdrRatioSpline || state1.mMaxBrightnessReason != state2.mMaxBrightnessReason || !BrightnessSynchronizer.floatEquals(state1.mMaxBrightness, state2.mMaxBrightness); } private void start() { if (!mClampers.isEmpty()) { if (!mClampers.isEmpty() || !mDeviceConfigListeners.isEmpty()) { mDeviceConfigParameterProvider.addOnPropertiesChangedListener( mExecutor, mOnPropertiesChangedListener); } Loading Loading @@ -333,8 +341,7 @@ public class BrightnessClamperController { ClamperChangeListener clamperChangeListener, DisplayDeviceData data, DisplayManagerFlags flags, Context context, float currentBrightness) { List<BrightnessClamper<? super DisplayDeviceData>> clampers = new ArrayList<>(); clampers.add( new BrightnessThermalClamper(handler, clamperChangeListener, data)); if (flags.isPowerThrottlingClamperEnabled()) { // Check if power-throttling config is present. PowerThrottlingConfigData configData = data.getPowerThrottlingConfigData(); Loading @@ -354,6 +361,8 @@ public class BrightnessClamperController { Handler handler, ClamperChangeListener listener, DisplayDeviceData data) { List<BrightnessStateModifier> modifiers = new ArrayList<>(); modifiers.add(new BrightnessThermalModifier(handler, listener, data)); modifiers.add(new DisplayDimModifier(context)); modifiers.add(new BrightnessLowPowerModeModifier()); if (flags.isEvenDimmerEnabled() && data.mDisplayDeviceConfig.isEvenDimmerAvailable()) { Loading Loading @@ -384,7 +393,7 @@ public class BrightnessClamperController { /** * Config Data for clampers/modifiers */ public static class DisplayDeviceData implements BrightnessThermalClamper.ThermalData, public static class DisplayDeviceData implements BrightnessThermalModifier.ThermalData, BrightnessPowerClamper.PowerData, BrightnessWearBedtimeModeClamper.WearBedtimeModeData { @NonNull Loading Loading @@ -497,14 +506,24 @@ public class BrightnessClamperController { void onSwitchUser(); } /** * Modifier should implement this interface in order to receive device config updates */ interface DeviceConfigListener { void onDeviceConfigChanged(); } /** * StatefulModifiers contribute to AggregatedState, that is used to decide if brightness * adjustement is needed * adjustment is needed */ public static class ModifiersAggregatedState { float mMaxDesiredHdrRatio = HdrBrightnessModifier.DEFAULT_MAX_HDR_SDR_RATIO; float mMaxHdrBrightness = PowerManager.BRIGHTNESS_MAX; @Nullable Spline mSdrHdrRatioSpline = null; @BrightnessInfo.BrightnessMaxReason int mMaxBrightnessReason = BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE; float mMaxBrightness = PowerManager.BRIGHTNESS_MAX; } }
services/core/java/com/android/server/display/brightness/clamper/BrightnessThermalClamper.java→services/core/java/com/android/server/display/brightness/clamper/BrightnessThermalModifier.java +87 −37 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ import static com.android.server.display.brightness.clamper.BrightnessClamperCon import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.hardware.display.BrightnessInfo; import android.hardware.display.DisplayManagerInternal; import android.os.Handler; import android.os.IThermalEventListener; import android.os.IThermalService; Loading @@ -33,8 +35,10 @@ import android.provider.DeviceConfigInterface; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import com.android.server.display.DisplayBrightnessState; import com.android.server.display.DisplayDeviceConfig.ThermalBrightnessThrottlingData; import com.android.server.display.DisplayDeviceConfig.ThermalBrightnessThrottlingData.ThrottlingLevel; import com.android.server.display.brightness.BrightnessReason; import com.android.server.display.config.SensorData; import com.android.server.display.feature.DeviceConfigParameterProvider; import com.android.server.display.utils.DeviceConfigParsingUtils; Loading @@ -43,12 +47,15 @@ import com.android.server.display.utils.SensorUtils; import java.io.PrintWriter; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.function.BiFunction; import java.util.function.Function; class BrightnessThermalClamper extends BrightnessClamper<BrightnessThermalClamper.ThermalData> { class BrightnessThermalModifier implements BrightnessStateModifier, BrightnessClamperController.DisplayDeviceDataListener, BrightnessClamperController.StatefulModifier, BrightnessClamperController.DeviceConfigListener { private static final String TAG = "BrightnessThermalClamper"; @NonNull Loading @@ -57,6 +64,11 @@ class BrightnessThermalClamper extends private final DeviceConfigParameterProvider mConfigParameterProvider; // data from DeviceConfig, for all displays, for all dataSets // mapOf(uniqueDisplayId to mapOf(dataSetId to ThermalBrightnessThrottlingData)) @NonNull protected final Handler mHandler; @NonNull protected final BrightnessClamperController.ClamperChangeListener mChangeListener; @NonNull private Map<String, Map<String, ThermalBrightnessThrottlingData>> mThermalThrottlingDataOverride = Map.of(); Loading @@ -73,6 +85,8 @@ class BrightnessThermalClamper extends private String mDataId = null; @Temperature.ThrottlingStatus private int mThrottlingStatus = Temperature.THROTTLING_NONE; private float mBrightnessCap = PowerManager.BRIGHTNESS_MAX; private boolean mApplied = false; private final BiFunction<String, String, ThrottlingLevel> mDataPointMapper = (key, value) -> { try { Loading @@ -88,63 +102,104 @@ class BrightnessThermalClamper extends mDataSetMapper = ThermalBrightnessThrottlingData::create; BrightnessThermalClamper(Handler handler, ClamperChangeListener listener, ThermalData thermalData) { this(new Injector(), handler, listener, thermalData); BrightnessThermalModifier(Handler handler, ClamperChangeListener listener, BrightnessClamperController.DisplayDeviceData data) { this(new Injector(), handler, listener, data); } @VisibleForTesting BrightnessThermalClamper(Injector injector, Handler handler, ClamperChangeListener listener, ThermalData thermalData) { super(handler, listener); BrightnessThermalModifier(Injector injector, @NonNull Handler handler, @NonNull ClamperChangeListener listener, @NonNull BrightnessClamperController.DisplayDeviceData data) { mHandler = handler; mChangeListener = listener; mConfigParameterProvider = injector.getDeviceConfigParameterProvider(); mThermalStatusObserver = new ThermalStatusObserver(injector, handler); mHandler.post(() -> { setDisplayData(thermalData); setDisplayData(data); loadOverrideData(); }); } //region BrightnessStateModifier @Override public void apply(DisplayManagerInternal.DisplayPowerRequest request, DisplayBrightnessState.Builder stateBuilder) { if (stateBuilder.getMaxBrightness() > mBrightnessCap) { stateBuilder.setMaxBrightness(mBrightnessCap); stateBuilder.setBrightness(Math.min(stateBuilder.getBrightness(), mBrightnessCap)); stateBuilder.setBrightnessMaxReason(BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL); stateBuilder.getBrightnessReason().addModifier(BrightnessReason.MODIFIER_THROTTLED); // set fast change only when modifier is activated. // this will allow auto brightness to apply slow change even when modifier is active if (!mApplied) { stateBuilder.setIsSlowChange(false); } mApplied = true; } else { mApplied = false; } } @Override public void stop() { mThermalStatusObserver.stopObserving(); } @Override @NonNull Type getType() { return Type.THERMAL; public void dump(PrintWriter writer) { writer.println("BrightnessThermalClamper:"); writer.println(" mThrottlingStatus: " + mThrottlingStatus); writer.println(" mUniqueDisplayId: " + mUniqueDisplayId); writer.println(" mDataId: " + mDataId); writer.println(" mDataOverride: " + mThermalThrottlingDataOverride); writer.println(" mDataFromDeviceConfig: " + mThermalThrottlingDataFromDeviceConfig); writer.println(" mDataActive: " + mThermalThrottlingDataActive); writer.println(" mBrightnessCap:" + mBrightnessCap); writer.println(" mApplied:" + mApplied); mThermalStatusObserver.dump(writer); } @Override void onDeviceConfigChanged() { mHandler.post(() -> { loadOverrideData(); recalculateActiveData(); }); public boolean shouldListenToLightSensor() { return false; } @Override public void setAmbientLux(float lux) { // noop } //endregion //region DisplayDeviceDataListener @Override void onDisplayChanged(ThermalData data) { public void onDisplayChanged(BrightnessClamperController.DisplayDeviceData data) { mHandler.post(() -> { setDisplayData(data); recalculateActiveData(); }); } //endregion //region StatefulModifier @Override void stop() { mThermalStatusObserver.stopObserving(); public void applyStateChange( BrightnessClamperController.ModifiersAggregatedState aggregatedState) { if (aggregatedState.mMaxBrightness > mBrightnessCap) { aggregatedState.mMaxBrightness = mBrightnessCap; aggregatedState.mMaxBrightnessReason = BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL; } } //endregion //region DeviceConfigListener @Override void dump(PrintWriter writer) { writer.println("BrightnessThermalClamper:"); writer.println(" mThrottlingStatus: " + mThrottlingStatus); writer.println(" mUniqueDisplayId: " + mUniqueDisplayId); writer.println(" mDataId: " + mDataId); writer.println(" mDataOverride: " + mThermalThrottlingDataOverride); writer.println(" mDataFromDeviceConfig: " + mThermalThrottlingDataFromDeviceConfig); writer.println(" mDataActive: " + mThermalThrottlingDataActive); mThermalStatusObserver.dump(writer); super.dump(writer); public void onDeviceConfigChanged() { mHandler.post(() -> { loadOverrideData(); recalculateActiveData(); }); } //endregion private void recalculateActiveData() { if (mUniqueDisplayId == null || mDataId == null) { Loading Loading @@ -176,14 +231,11 @@ class BrightnessThermalClamper extends private void recalculateBrightnessCap() { float brightnessCap = PowerManager.BRIGHTNESS_MAX; boolean isActive = false; if (mThermalThrottlingDataActive != null) { // Throttling levels are sorted by increasing severity for (ThrottlingLevel level : mThermalThrottlingDataActive.throttlingLevels) { if (level.thermalStatus <= mThrottlingStatus) { brightnessCap = level.brightness; isActive = true; } else { // Throttling levels that are greater than the current status are irrelevant break; Loading @@ -191,9 +243,8 @@ class BrightnessThermalClamper extends } } if (brightnessCap != mBrightnessCap || mIsActive != isActive) { if (brightnessCap != mBrightnessCap) { mBrightnessCap = brightnessCap; mIsActive = isActive; mChangeListener.onChanged(); } } Loading @@ -205,7 +256,6 @@ class BrightnessThermalClamper extends } } private final class ThermalStatusObserver extends IThermalEventListener.Stub { private final Injector mInjector; private final Handler mHandler; Loading @@ -228,7 +278,7 @@ class BrightnessThermalClamper extends String curType = mObserverTempSensor.type; mObserverTempSensor = tempSensor; if (curType.equals(tempSensor.type)) { if (Objects.equals(curType, tempSensor.type)) { Slog.d(TAG, "Thermal status observer already started"); return; } Loading
services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessClamperControllerTest.java +4 −4 Original line number Diff line number Diff line Loading @@ -226,7 +226,7 @@ public class BrightnessClamperControllerTest { float clampedBrightness = 0.6f; float customAnimationRate = 0.01f; when(mMockClamper.getBrightnessCap()).thenReturn(clampedBrightness); when(mMockClamper.getType()).thenReturn(BrightnessClamper.Type.THERMAL); when(mMockClamper.getType()).thenReturn(BrightnessClamper.Type.POWER); when(mMockClamper.getCustomAnimationRate()).thenReturn(customAnimationRate); when(mMockClamper.isActive()).thenReturn(false); mTestInjector.mCapturedChangeListener.onChanged(); Loading @@ -250,7 +250,7 @@ public class BrightnessClamperControllerTest { float clampedBrightness = 0.6f; float customAnimationRate = 0.01f; when(mMockClamper.getBrightnessCap()).thenReturn(clampedBrightness); when(mMockClamper.getType()).thenReturn(BrightnessClamper.Type.THERMAL); when(mMockClamper.getType()).thenReturn(BrightnessClamper.Type.POWER); when(mMockClamper.getCustomAnimationRate()).thenReturn(customAnimationRate); when(mMockClamper.isActive()).thenReturn(true); mTestInjector.mCapturedChangeListener.onChanged(); Loading @@ -274,7 +274,7 @@ public class BrightnessClamperControllerTest { float clampedBrightness = 0.8f; float customAnimationRate = 0.01f; when(mMockClamper.getBrightnessCap()).thenReturn(clampedBrightness); when(mMockClamper.getType()).thenReturn(BrightnessClamper.Type.THERMAL); when(mMockClamper.getType()).thenReturn(BrightnessClamper.Type.POWER); when(mMockClamper.getCustomAnimationRate()).thenReturn(customAnimationRate); when(mMockClamper.isActive()).thenReturn(true); mTestInjector.mCapturedChangeListener.onChanged(); Loading @@ -298,7 +298,7 @@ public class BrightnessClamperControllerTest { float clampedBrightness = 0.6f; float customAnimationRate = 0.01f; when(mMockClamper.getBrightnessCap()).thenReturn(clampedBrightness); when(mMockClamper.getType()).thenReturn(BrightnessClamper.Type.THERMAL); when(mMockClamper.getType()).thenReturn(BrightnessClamper.Type.POWER); when(mMockClamper.getCustomAnimationRate()).thenReturn(customAnimationRate); when(mMockClamper.isActive()).thenReturn(true); mTestInjector.mCapturedChangeListener.onChanged(); Loading