Merge changes from topic "NormalBrightnessModeController" into udc-d1-dev

* changes:
  NormalBrightnessModeController configuration
  NormalBrightnessModeController structure
This commit is contained in:
Treehugger Robot
2023-06-28 10:35:12 +00:00
committed by Android (Google) Code Review
13 changed files with 764 additions and 121 deletions

View File

@@ -223,11 +223,11 @@ public class AutomaticBrightnessController {
private final ShortTermModel mShortTermModel; private final ShortTermModel mShortTermModel;
private final ShortTermModel mPausedShortTermModel; private final ShortTermModel mPausedShortTermModel;
// Controls High Brightness Mode. // Controls Brightness range (including High Brightness Mode).
private HighBrightnessModeController mHbmController; private final BrightnessRangeController mBrightnessRangeController;
// Throttles (caps) maximum allowed brightness // Throttles (caps) maximum allowed brightness
private BrightnessThrottler mBrightnessThrottler; private final BrightnessThrottler mBrightnessThrottler;
private boolean mIsBrightnessThrottled; private boolean mIsBrightnessThrottled;
// Context-sensitive brightness configurations require keeping track of the foreground app's // Context-sensitive brightness configurations require keeping track of the foreground app's
@@ -257,7 +257,8 @@ public class AutomaticBrightnessController {
HysteresisLevels screenBrightnessThresholds, HysteresisLevels screenBrightnessThresholds,
HysteresisLevels ambientBrightnessThresholdsIdle, HysteresisLevels ambientBrightnessThresholdsIdle,
HysteresisLevels screenBrightnessThresholdsIdle, Context context, HysteresisLevels screenBrightnessThresholdsIdle, Context context,
HighBrightnessModeController hbmController, BrightnessThrottler brightnessThrottler, BrightnessRangeController brightnessModeController,
BrightnessThrottler brightnessThrottler,
BrightnessMappingStrategy idleModeBrightnessMapper, int ambientLightHorizonShort, BrightnessMappingStrategy idleModeBrightnessMapper, int ambientLightHorizonShort,
int ambientLightHorizonLong, float userLux, float userBrightness) { int ambientLightHorizonLong, float userLux, float userBrightness) {
this(new Injector(), callbacks, looper, sensorManager, lightSensor, this(new Injector(), callbacks, looper, sensorManager, lightSensor,
@@ -267,7 +268,7 @@ public class AutomaticBrightnessController {
darkeningLightDebounceConfig, resetAmbientLuxAfterWarmUpConfig, darkeningLightDebounceConfig, resetAmbientLuxAfterWarmUpConfig,
ambientBrightnessThresholds, screenBrightnessThresholds, ambientBrightnessThresholds, screenBrightnessThresholds,
ambientBrightnessThresholdsIdle, screenBrightnessThresholdsIdle, context, ambientBrightnessThresholdsIdle, screenBrightnessThresholdsIdle, context,
hbmController, brightnessThrottler, idleModeBrightnessMapper, brightnessModeController, brightnessThrottler, idleModeBrightnessMapper,
ambientLightHorizonShort, ambientLightHorizonLong, userLux, userBrightness ambientLightHorizonShort, ambientLightHorizonLong, userLux, userBrightness
); );
} }
@@ -283,7 +284,8 @@ public class AutomaticBrightnessController {
HysteresisLevels screenBrightnessThresholds, HysteresisLevels screenBrightnessThresholds,
HysteresisLevels ambientBrightnessThresholdsIdle, HysteresisLevels ambientBrightnessThresholdsIdle,
HysteresisLevels screenBrightnessThresholdsIdle, Context context, HysteresisLevels screenBrightnessThresholdsIdle, Context context,
HighBrightnessModeController hbmController, BrightnessThrottler brightnessThrottler, BrightnessRangeController brightnessModeController,
BrightnessThrottler brightnessThrottler,
BrightnessMappingStrategy idleModeBrightnessMapper, int ambientLightHorizonShort, BrightnessMappingStrategy idleModeBrightnessMapper, int ambientLightHorizonShort,
int ambientLightHorizonLong, float userLux, float userBrightness) { int ambientLightHorizonLong, float userLux, float userBrightness) {
mInjector = injector; mInjector = injector;
@@ -326,7 +328,7 @@ public class AutomaticBrightnessController {
mPendingForegroundAppPackageName = null; mPendingForegroundAppPackageName = null;
mForegroundAppCategory = ApplicationInfo.CATEGORY_UNDEFINED; mForegroundAppCategory = ApplicationInfo.CATEGORY_UNDEFINED;
mPendingForegroundAppCategory = ApplicationInfo.CATEGORY_UNDEFINED; mPendingForegroundAppCategory = ApplicationInfo.CATEGORY_UNDEFINED;
mHbmController = hbmController; mBrightnessRangeController = brightnessModeController;
mBrightnessThrottler = brightnessThrottler; mBrightnessThrottler = brightnessThrottler;
mInteractiveModeBrightnessMapper = interactiveModeBrightnessMapper; mInteractiveModeBrightnessMapper = interactiveModeBrightnessMapper;
mIdleModeBrightnessMapper = idleModeBrightnessMapper; mIdleModeBrightnessMapper = idleModeBrightnessMapper;
@@ -607,10 +609,11 @@ public class AutomaticBrightnessController {
pw.println(); pw.println();
pw.println(" mInteractiveMapper="); pw.println(" mInteractiveMapper=");
mInteractiveModeBrightnessMapper.dump(pw, mHbmController.getNormalBrightnessMax()); mInteractiveModeBrightnessMapper.dump(pw,
mBrightnessRangeController.getNormalBrightnessMax());
if (mIdleModeBrightnessMapper != null) { if (mIdleModeBrightnessMapper != null) {
pw.println(" mIdleMapper="); pw.println(" mIdleMapper=");
mIdleModeBrightnessMapper.dump(pw, mHbmController.getNormalBrightnessMax()); mIdleModeBrightnessMapper.dump(pw, mBrightnessRangeController.getNormalBrightnessMax());
} }
pw.println(); pw.println();
@@ -736,7 +739,7 @@ public class AutomaticBrightnessController {
mAmbientDarkeningThreshold = mAmbientDarkeningThreshold =
mAmbientBrightnessThresholds.getDarkeningThreshold(lux); mAmbientBrightnessThresholds.getDarkeningThreshold(lux);
} }
mHbmController.onAmbientLuxChange(mAmbientLux); mBrightnessRangeController.onAmbientLuxChange(mAmbientLux);
// If the short term model was invalidated and the change is drastic enough, reset it. // If the short term model was invalidated and the change is drastic enough, reset it.
@@ -976,9 +979,9 @@ public class AutomaticBrightnessController {
// Clamps values with float range [0.0-1.0] // Clamps values with float range [0.0-1.0]
private float clampScreenBrightness(float value) { private float clampScreenBrightness(float value) {
final float minBrightness = Math.min(mHbmController.getCurrentBrightnessMin(), final float minBrightness = Math.min(mBrightnessRangeController.getCurrentBrightnessMin(),
mBrightnessThrottler.getBrightnessCap()); mBrightnessThrottler.getBrightnessCap());
final float maxBrightness = Math.min(mHbmController.getCurrentBrightnessMax(), final float maxBrightness = Math.min(mBrightnessRangeController.getCurrentBrightnessMax(),
mBrightnessThrottler.getBrightnessCap()); mBrightnessThrottler.getBrightnessCap());
return MathUtils.constrain(value, minBrightness, maxBrightness); return MathUtils.constrain(value, minBrightness, maxBrightness);
} }

View File

@@ -0,0 +1,126 @@
/*
* 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;
import android.hardware.display.BrightnessInfo;
import android.os.IBinder;
import java.io.PrintWriter;
import java.util.function.BooleanSupplier;
class BrightnessRangeController {
private static final boolean NBM_FEATURE_FLAG = false;
private final HighBrightnessModeController mHbmController;
private final NormalBrightnessModeController mNormalBrightnessModeController =
new NormalBrightnessModeController();
private final Runnable mModeChangeCallback;
BrightnessRangeController(HighBrightnessModeController hbmController,
Runnable modeChangeCallback) {
mHbmController = hbmController;
mModeChangeCallback = modeChangeCallback;
}
void dump(PrintWriter pw) {
mHbmController.dump(pw);
}
void onAmbientLuxChange(float ambientLux) {
applyChanges(
() -> mNormalBrightnessModeController.onAmbientLuxChange(ambientLux),
() -> mHbmController.onAmbientLuxChange(ambientLux)
);
}
float getNormalBrightnessMax() {
return mHbmController.getNormalBrightnessMax();
}
void loadFromConfig(HighBrightnessModeMetadata hbmMetadata, IBinder token,
DisplayDeviceInfo info, DisplayDeviceConfig displayDeviceConfig) {
applyChanges(
() -> mNormalBrightnessModeController.resetNbmData(
displayDeviceConfig.getLuxThrottlingData()),
() -> {
mHbmController.setHighBrightnessModeMetadata(hbmMetadata);
mHbmController.resetHbmData(info.width, info.height, token, info.uniqueId,
displayDeviceConfig.getHighBrightnessModeData(),
displayDeviceConfig::getHdrBrightnessFromSdr);
}
);
}
void stop() {
mHbmController.stop();
}
void setAutoBrightnessEnabled(int state) {
applyChanges(
() -> mNormalBrightnessModeController.setAutoBrightnessState(state),
() -> mHbmController.setAutoBrightnessEnabled(state)
);
}
void onBrightnessChanged(float brightness, float unthrottledBrightness,
@BrightnessInfo.BrightnessMaxReason int throttlingReason) {
mHbmController.onBrightnessChanged(brightness, unthrottledBrightness, throttlingReason);
}
float getCurrentBrightnessMin() {
return mHbmController.getCurrentBrightnessMin();
}
float getCurrentBrightnessMax() {
if (NBM_FEATURE_FLAG && mHbmController.getHighBrightnessMode()
== BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF) {
return Math.min(mHbmController.getCurrentBrightnessMax(),
mNormalBrightnessModeController.getCurrentBrightnessMax());
}
return mHbmController.getCurrentBrightnessMax();
}
int getHighBrightnessMode() {
return mHbmController.getHighBrightnessMode();
}
float getHdrBrightnessValue() {
return mHbmController.getHdrBrightnessValue();
}
float getTransitionPoint() {
return mHbmController.getTransitionPoint();
}
private void applyChanges(BooleanSupplier nbmChangesFunc, Runnable hbmChangesFunc) {
if (NBM_FEATURE_FLAG) {
boolean nbmTransitionChanged = nbmChangesFunc.getAsBoolean();
hbmChangesFunc.run();
// if nbm transition changed - trigger callback
// HighBrightnessModeController handles sending changes itself
if (nbmTransitionChanged) {
mModeChangeCallback.run();
}
} else {
hbmChangesFunc.run();
}
}
}

View File

@@ -41,6 +41,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.display.BrightnessSynchronizer; import com.android.internal.display.BrightnessSynchronizer;
import com.android.server.display.config.AutoBrightness; import com.android.server.display.config.AutoBrightness;
import com.android.server.display.config.BlockingZoneConfig; import com.android.server.display.config.BlockingZoneConfig;
import com.android.server.display.config.BrightnessLimitMap;
import com.android.server.display.config.BrightnessThresholds; import com.android.server.display.config.BrightnessThresholds;
import com.android.server.display.config.BrightnessThrottlingMap; import com.android.server.display.config.BrightnessThrottlingMap;
import com.android.server.display.config.BrightnessThrottlingPoint; import com.android.server.display.config.BrightnessThrottlingPoint;
@@ -51,8 +52,11 @@ import com.android.server.display.config.DisplayQuirks;
import com.android.server.display.config.HbmTiming; import com.android.server.display.config.HbmTiming;
import com.android.server.display.config.HighBrightnessMode; import com.android.server.display.config.HighBrightnessMode;
import com.android.server.display.config.IntegerArray; import com.android.server.display.config.IntegerArray;
import com.android.server.display.config.LuxThrottling;
import com.android.server.display.config.NitsMap; import com.android.server.display.config.NitsMap;
import com.android.server.display.config.NonNegativeFloatToFloatPoint;
import com.android.server.display.config.Point; import com.android.server.display.config.Point;
import com.android.server.display.config.PredefinedBrightnessLimitNames;
import com.android.server.display.config.RefreshRateConfigs; import com.android.server.display.config.RefreshRateConfigs;
import com.android.server.display.config.RefreshRateRange; import com.android.server.display.config.RefreshRateRange;
import com.android.server.display.config.RefreshRateThrottlingMap; import com.android.server.display.config.RefreshRateThrottlingMap;
@@ -219,6 +223,22 @@ import javax.xml.datatype.DatatypeConfigurationException;
* <allowInLowPowerMode>false</allowInLowPowerMode> * <allowInLowPowerMode>false</allowInLowPowerMode>
* </highBrightnessMode> * </highBrightnessMode>
* *
* <luxThrottling>
* <brightnessLimitMap>
* <type>default</type>
* <map>
* <point>
* <first>5000</first>
* <second>0.3</second>
* </point>
* <point>
* <first>5000</first>
* <second>0.3</second>
* </point>
* </map>
* </brightnessPeakMap>
* </luxThrottling>
*
* <quirks> * <quirks>
* <quirk>canSetBrightnessViaHwc</quirk> * <quirk>canSetBrightnessViaHwc</quirk>
* </quirks> * </quirks>
@@ -693,6 +713,9 @@ public class DisplayDeviceConfig {
private final Map<String, SparseArray<SurfaceControl.RefreshRateRange>> private final Map<String, SparseArray<SurfaceControl.RefreshRateRange>>
mRefreshRateThrottlingMap = new HashMap<>(); mRefreshRateThrottlingMap = new HashMap<>();
private final Map<BrightnessLimitMapType, Map<Float, Float>>
mLuxThrottlingData = new HashMap<>();
@Nullable @Nullable
private HostUsiVersion mHostUsiVersion; private HostUsiVersion mHostUsiVersion;
@@ -1344,6 +1367,11 @@ public class DisplayDeviceConfig {
return hbmData; return hbmData;
} }
@NonNull
public Map<BrightnessLimitMapType, Map<Float, Float>> getLuxThrottlingData() {
return mLuxThrottlingData;
}
public List<RefreshRateLimitation> getRefreshRateLimitations() { public List<RefreshRateLimitation> getRefreshRateLimitations() {
return mRefreshRateLimitations; return mRefreshRateLimitations;
} }
@@ -1530,6 +1558,7 @@ public class DisplayDeviceConfig {
+ ", mBrightnessDefault=" + mBrightnessDefault + ", mBrightnessDefault=" + mBrightnessDefault
+ ", mQuirks=" + mQuirks + ", mQuirks=" + mQuirks
+ ", isHbmEnabled=" + mIsHighBrightnessModeEnabled + ", isHbmEnabled=" + mIsHighBrightnessModeEnabled
+ ", mLuxThrottlingData=" + mLuxThrottlingData
+ ", mHbmData=" + mHbmData + ", mHbmData=" + mHbmData
+ ", mSdrToHdrRatioSpline=" + mSdrToHdrRatioSpline + ", mSdrToHdrRatioSpline=" + mSdrToHdrRatioSpline
+ ", mThermalBrightnessThrottlingDataMapByThrottlingId=" + ", mThermalBrightnessThrottlingDataMapByThrottlingId="
@@ -1676,6 +1705,7 @@ public class DisplayDeviceConfig {
loadBrightnessMap(config); loadBrightnessMap(config);
loadThermalThrottlingConfig(config); loadThermalThrottlingConfig(config);
loadHighBrightnessModeData(config); loadHighBrightnessModeData(config);
loadLuxThrottling(config);
loadQuirks(config); loadQuirks(config);
loadBrightnessRamps(config); loadBrightnessRamps(config);
loadAmbientLightSensorFromDdc(config); loadAmbientLightSensorFromDdc(config);
@@ -2428,6 +2458,54 @@ public class DisplayDeviceConfig {
} }
} }
private void loadLuxThrottling(DisplayConfiguration config) {
LuxThrottling cfg = config.getLuxThrottling();
if (cfg != null) {
HighBrightnessMode hbm = config.getHighBrightnessMode();
float hbmTransitionPoint = hbm != null ? hbm.getTransitionPoint_all().floatValue()
: PowerManager.BRIGHTNESS_MAX;
List<BrightnessLimitMap> limitMaps = cfg.getBrightnessLimitMap();
for (BrightnessLimitMap map : limitMaps) {
PredefinedBrightnessLimitNames type = map.getType();
BrightnessLimitMapType mappedType = BrightnessLimitMapType.convert(type);
if (mappedType == null) {
Slog.wtf(TAG, "Invalid NBM config: unsupported map type=" + type);
continue;
}
if (mLuxThrottlingData.containsKey(mappedType)) {
Slog.wtf(TAG, "Invalid NBM config: duplicate map type=" + mappedType);
continue;
}
Map<Float, Float> luxToTransitionPointMap = new HashMap<>();
List<NonNegativeFloatToFloatPoint> points = map.getMap().getPoint();
for (NonNegativeFloatToFloatPoint point : points) {
float lux = point.getFirst().floatValue();
float maxBrightness = point.getSecond().floatValue();
if (maxBrightness > hbmTransitionPoint) {
Slog.wtf(TAG,
"Invalid NBM config: maxBrightness is greater than hbm"
+ ".transitionPoint. type="
+ type + "; lux=" + lux + "; maxBrightness="
+ maxBrightness);
continue;
}
if (luxToTransitionPointMap.containsKey(lux)) {
Slog.wtf(TAG,
"Invalid NBM config: duplicate lux key. type=" + type + "; lux="
+ lux);
continue;
}
luxToTransitionPointMap.put(lux,
mBacklightToBrightnessSpline.interpolate(maxBrightness));
}
if (!luxToTransitionPointMap.isEmpty()) {
mLuxThrottlingData.put(mappedType, luxToTransitionPointMap);
}
}
}
}
private void loadBrightnessRamps(DisplayConfiguration config) { private void loadBrightnessRamps(DisplayConfiguration config) {
// Priority 1: Value in the display device config (float) // Priority 1: Value in the display device config (float)
// Priority 2: Value in the config.xml (int) // Priority 2: Value in the config.xml (int)
@@ -3155,4 +3233,19 @@ public class DisplayDeviceConfig {
} }
} }
} }
public enum BrightnessLimitMapType {
DEFAULT, ADAPTIVE;
@Nullable
private static BrightnessLimitMapType convert(PredefinedBrightnessLimitNames type) {
switch (type) {
case _default:
return DEFAULT;
case adaptive:
return ADAPTIVE;
}
return null;
}
}
} }

View File

@@ -445,7 +445,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
private final ColorDisplayServiceInternal mCdsi; private final ColorDisplayServiceInternal mCdsi;
private float[] mNitsRange; private float[] mNitsRange;
private final HighBrightnessModeController mHbmController; private final BrightnessRangeController mBrightnessRangeController;
private final HighBrightnessModeMetadata mHighBrightnessModeMetadata; private final HighBrightnessModeMetadata mHighBrightnessModeMetadata;
private final BrightnessThrottler mBrightnessThrottler; private final BrightnessThrottler mBrightnessThrottler;
@@ -654,8 +654,19 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
loadBrightnessRampRates(); loadBrightnessRampRates();
mSkipScreenOnBrightnessRamp = resources.getBoolean( mSkipScreenOnBrightnessRamp = resources.getBoolean(
com.android.internal.R.bool.config_skipScreenOnBrightnessRamp); com.android.internal.R.bool.config_skipScreenOnBrightnessRamp);
Runnable modeChangeCallback = () -> {
sendUpdatePowerState();
postBrightnessChangeRunnable();
// TODO(b/192258832): Switch the HBMChangeCallback to a listener pattern.
if (mAutomaticBrightnessController != null) {
mAutomaticBrightnessController.update();
}
};
mHbmController = createHbmControllerLocked(); HighBrightnessModeController hbmController = createHbmControllerLocked(modeChangeCallback);
mBrightnessRangeController = new BrightnessRangeController(hbmController,
modeChangeCallback);
mBrightnessThrottler = createBrightnessThrottlerLocked(); mBrightnessThrottler = createBrightnessThrottlerLocked();
@@ -802,7 +813,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
@Override @Override
public void setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux) { public void setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux) {
mHbmController.onAmbientLuxChange(ambientLux); mBrightnessRangeController.onAmbientLuxChange(ambientLux);
if (nits < 0) { if (nits < 0) {
mBrightnessToFollow = leadDisplayBrightness; mBrightnessToFollow = leadDisplayBrightness;
} else { } else {
@@ -1039,17 +1050,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mBrightnessRampIncreaseMaxTimeMillis, mBrightnessRampIncreaseMaxTimeMillis,
mBrightnessRampDecreaseMaxTimeMillis); mBrightnessRampDecreaseMaxTimeMillis);
} }
mHbmController.setHighBrightnessModeMetadata(hbmMetadata); mBrightnessRangeController.loadFromConfig(hbmMetadata, token, info, mDisplayDeviceConfig);
mHbmController.resetHbmData(info.width, info.height, token, info.uniqueId,
mDisplayDeviceConfig.getHighBrightnessModeData(),
new HighBrightnessModeController.HdrBrightnessDeviceConfig() {
@Override
public float getHdrBrightnessFromSdr(
float sdrBrightness, float maxDesiredHdrSdrRatio) {
return mDisplayDeviceConfig.getHdrBrightnessFromSdr(
sdrBrightness, maxDesiredHdrSdrRatio);
}
});
mBrightnessThrottler.loadThermalBrightnessThrottlingDataFromDisplayDeviceConfig( mBrightnessThrottler.loadThermalBrightnessThrottlingDataFromDisplayDeviceConfig(
mDisplayDeviceConfig.getThermalBrightnessThrottlingDataMapByThrottlingId(), mDisplayDeviceConfig.getThermalBrightnessThrottlingDataMapByThrottlingId(),
mThermalBrightnessThrottlingDataId, mUniqueDisplayId); mThermalBrightnessThrottlingDataId, mUniqueDisplayId);
@@ -1264,7 +1265,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
darkeningLightDebounce, autoBrightnessResetAmbientLuxAfterWarmUp, darkeningLightDebounce, autoBrightnessResetAmbientLuxAfterWarmUp,
ambientBrightnessThresholds, screenBrightnessThresholds, ambientBrightnessThresholds, screenBrightnessThresholds,
ambientBrightnessThresholdsIdle, screenBrightnessThresholdsIdle, mContext, ambientBrightnessThresholdsIdle, screenBrightnessThresholdsIdle, mContext,
mHbmController, mBrightnessThrottler, mIdleModeBrightnessMapper, mBrightnessRangeController, mBrightnessThrottler, mIdleModeBrightnessMapper,
mDisplayDeviceConfig.getAmbientHorizonShort(), mDisplayDeviceConfig.getAmbientHorizonShort(),
mDisplayDeviceConfig.getAmbientHorizonLong(), userLux, userBrightness); mDisplayDeviceConfig.getAmbientHorizonLong(), userLux, userBrightness);
@@ -1364,7 +1365,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
/** Clean up all resources that are accessed via the {@link #mHandler} thread. */ /** Clean up all resources that are accessed via the {@link #mHandler} thread. */
private void cleanupHandlerThreadAfterStop() { private void cleanupHandlerThreadAfterStop() {
setProximitySensorEnabled(false); setProximitySensorEnabled(false);
mHbmController.stop(); mBrightnessRangeController.stop();
mBrightnessThrottler.stop(); mBrightnessThrottler.stop();
mHandler.removeCallbacksAndMessages(null); mHandler.removeCallbacksAndMessages(null);
@@ -1647,7 +1648,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mShouldResetShortTermModel); mShouldResetShortTermModel);
mShouldResetShortTermModel = false; mShouldResetShortTermModel = false;
} }
mHbmController.setAutoBrightnessEnabled(mUseAutoBrightness mBrightnessRangeController.setAutoBrightnessEnabled(mUseAutoBrightness
? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED ? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED
: AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED); : AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED);
@@ -1820,7 +1821,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// here instead of having HbmController listen to the brightness setting because certain // here instead of having HbmController listen to the brightness setting because certain
// brightness sources (such as an app override) are not saved to the setting, but should be // brightness sources (such as an app override) are not saved to the setting, but should be
// reflected in HBM calculations. // reflected in HBM calculations.
mHbmController.onBrightnessChanged(brightnessState, unthrottledBrightnessState, mBrightnessRangeController.onBrightnessChanged(brightnessState, unthrottledBrightnessState,
mBrightnessThrottler.getBrightnessMaxReason()); mBrightnessThrottler.getBrightnessMaxReason());
// Animate the screen brightness when the screen is on or dozing. // Animate the screen brightness when the screen is on or dozing.
@@ -1874,13 +1875,14 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
float sdrAnimateValue = animateValue; float sdrAnimateValue = animateValue;
// TODO(b/216365040): The decision to prevent HBM for HDR in low power mode should be // TODO(b/216365040): The decision to prevent HBM for HDR in low power mode should be
// done in HighBrightnessModeController. // done in HighBrightnessModeController.
if (mHbmController.getHighBrightnessMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR if (mBrightnessRangeController.getHighBrightnessMode()
== BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR
&& (mBrightnessReasonTemp.getModifier() & BrightnessReason.MODIFIER_DIMMED) == 0 && (mBrightnessReasonTemp.getModifier() & BrightnessReason.MODIFIER_DIMMED) == 0
&& (mBrightnessReasonTemp.getModifier() & BrightnessReason.MODIFIER_LOW_POWER) && (mBrightnessReasonTemp.getModifier() & BrightnessReason.MODIFIER_LOW_POWER)
== 0) { == 0) {
// We want to scale HDR brightness level with the SDR level, we also need to restore // 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. // SDR brightness immediately when entering dim or low power mode.
animateValue = mHbmController.getHdrBrightnessValue(); animateValue = mBrightnessRangeController.getHdrBrightnessValue();
} }
final float currentBrightness = mPowerState.getScreenBrightness(); final float currentBrightness = mPowerState.getScreenBrightness();
@@ -1942,8 +1944,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mTempBrightnessEvent.setBrightness(brightnessState); mTempBrightnessEvent.setBrightness(brightnessState);
mTempBrightnessEvent.setPhysicalDisplayId(mUniqueDisplayId); mTempBrightnessEvent.setPhysicalDisplayId(mUniqueDisplayId);
mTempBrightnessEvent.setReason(mBrightnessReason); mTempBrightnessEvent.setReason(mBrightnessReason);
mTempBrightnessEvent.setHbmMax(mHbmController.getCurrentBrightnessMax()); mTempBrightnessEvent.setHbmMax(mBrightnessRangeController.getCurrentBrightnessMax());
mTempBrightnessEvent.setHbmMode(mHbmController.getHighBrightnessMode()); mTempBrightnessEvent.setHbmMode(mBrightnessRangeController.getHighBrightnessMode());
mTempBrightnessEvent.setFlags(mTempBrightnessEvent.getFlags() mTempBrightnessEvent.setFlags(mTempBrightnessEvent.getFlags()
| (mIsRbcActive ? BrightnessEvent.FLAG_RBC : 0) | (mIsRbcActive ? BrightnessEvent.FLAG_RBC : 0)
| (mPowerRequest.lowPowerMode ? BrightnessEvent.FLAG_LOW_POWER_MODE : 0)); | (mPowerRequest.lowPowerMode ? BrightnessEvent.FLAG_LOW_POWER_MODE : 0));
@@ -2104,9 +2106,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
private boolean saveBrightnessInfo(float brightness, float adjustedBrightness) { private boolean saveBrightnessInfo(float brightness, float adjustedBrightness) {
synchronized (mCachedBrightnessInfo) { synchronized (mCachedBrightnessInfo) {
final float minBrightness = Math.min(mHbmController.getCurrentBrightnessMin(), final float minBrightness = Math.min(
mBrightnessRangeController.getCurrentBrightnessMin(),
mBrightnessThrottler.getBrightnessCap()); mBrightnessThrottler.getBrightnessCap());
final float maxBrightness = Math.min(mHbmController.getCurrentBrightnessMax(), final float maxBrightness = Math.min(
mBrightnessRangeController.getCurrentBrightnessMax(),
mBrightnessThrottler.getBrightnessCap()); mBrightnessThrottler.getBrightnessCap());
boolean changed = false; boolean changed = false;
@@ -2124,10 +2128,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
maxBrightness); maxBrightness);
changed |= changed |=
mCachedBrightnessInfo.checkAndSetInt(mCachedBrightnessInfo.hbmMode, mCachedBrightnessInfo.checkAndSetInt(mCachedBrightnessInfo.hbmMode,
mHbmController.getHighBrightnessMode()); mBrightnessRangeController.getHighBrightnessMode());
changed |= changed |=
mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.hbmTransitionPoint, mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.hbmTransitionPoint,
mHbmController.getTransitionPoint()); mBrightnessRangeController.getTransitionPoint());
changed |= changed |=
mCachedBrightnessInfo.checkAndSetInt(mCachedBrightnessInfo.brightnessMaxReason, mCachedBrightnessInfo.checkAndSetInt(mCachedBrightnessInfo.brightnessMaxReason,
mBrightnessThrottler.getBrightnessMaxReason()); mBrightnessThrottler.getBrightnessMaxReason());
@@ -2137,10 +2141,13 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
} }
void postBrightnessChangeRunnable() { void postBrightnessChangeRunnable() {
mHandler.post(mOnBrightnessChangeRunnable); if (!mHandler.hasCallbacks(mOnBrightnessChangeRunnable)) {
mHandler.post(mOnBrightnessChangeRunnable);
}
} }
private HighBrightnessModeController createHbmControllerLocked() { private HighBrightnessModeController createHbmControllerLocked(
Runnable modeChangeCallback) {
final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked(); final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
final DisplayDeviceConfig ddConfig = device.getDisplayDeviceConfig(); final DisplayDeviceConfig ddConfig = device.getDisplayDeviceConfig();
final IBinder displayToken = final IBinder displayToken =
@@ -2159,15 +2166,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
return mDisplayDeviceConfig.getHdrBrightnessFromSdr( return mDisplayDeviceConfig.getHdrBrightnessFromSdr(
sdrBrightness, maxDesiredHdrSdrRatio); sdrBrightness, maxDesiredHdrSdrRatio);
} }
}, }, modeChangeCallback, mHighBrightnessModeMetadata, mContext);
() -> {
sendUpdatePowerState();
postBrightnessChangeRunnable();
// TODO(b/192258832): Switch the HBMChangeCallback to a listener pattern.
if (mAutomaticBrightnessController != null) {
mAutomaticBrightnessController.update();
}
}, mHighBrightnessModeMetadata, mContext);
} }
private BrightnessThrottler createBrightnessThrottlerLocked() { private BrightnessThrottler createBrightnessThrottlerLocked() {
@@ -2328,8 +2327,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
if (Float.isNaN(value)) { if (Float.isNaN(value)) {
value = PowerManager.BRIGHTNESS_MIN; value = PowerManager.BRIGHTNESS_MIN;
} }
return MathUtils.constrain(value, return MathUtils.constrain(value, mBrightnessRangeController.getCurrentBrightnessMin(),
mHbmController.getCurrentBrightnessMin(), mHbmController.getCurrentBrightnessMax()); mBrightnessRangeController.getCurrentBrightnessMax());
} }
// Checks whether the brightness is within the valid brightness range, not including off. // Checks whether the brightness is within the valid brightness range, not including off.
@@ -3003,8 +3002,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mScreenOffBrightnessSensorController.dump(pw); mScreenOffBrightnessSensorController.dump(pw);
} }
if (mHbmController != null) { if (mBrightnessRangeController != null) {
mHbmController.dump(pw); mBrightnessRangeController.dump(pw);
} }
if (mBrightnessThrottler != null) { if (mBrightnessThrottler != null) {
@@ -3471,7 +3470,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
HysteresisLevels screenBrightnessThresholds, HysteresisLevels screenBrightnessThresholds,
HysteresisLevels ambientBrightnessThresholdsIdle, HysteresisLevels ambientBrightnessThresholdsIdle,
HysteresisLevels screenBrightnessThresholdsIdle, Context context, HysteresisLevels screenBrightnessThresholdsIdle, Context context,
HighBrightnessModeController hbmController, BrightnessThrottler brightnessThrottler, BrightnessRangeController brightnessRangeController,
BrightnessThrottler brightnessThrottler,
BrightnessMappingStrategy idleModeBrightnessMapper, int ambientLightHorizonShort, BrightnessMappingStrategy idleModeBrightnessMapper, int ambientLightHorizonShort,
int ambientLightHorizonLong, float userLux, float userBrightness) { int ambientLightHorizonLong, float userLux, float userBrightness) {
return new AutomaticBrightnessController(callbacks, looper, sensorManager, lightSensor, return new AutomaticBrightnessController(callbacks, looper, sensorManager, lightSensor,
@@ -3480,9 +3480,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
brighteningLightDebounceConfig, darkeningLightDebounceConfig, brighteningLightDebounceConfig, darkeningLightDebounceConfig,
resetAmbientLuxAfterWarmUpConfig, ambientBrightnessThresholds, resetAmbientLuxAfterWarmUpConfig, ambientBrightnessThresholds,
screenBrightnessThresholds, ambientBrightnessThresholdsIdle, screenBrightnessThresholds, ambientBrightnessThresholdsIdle,
screenBrightnessThresholdsIdle, context, hbmController, brightnessThrottler, screenBrightnessThresholdsIdle, context, brightnessRangeController,
idleModeBrightnessMapper, ambientLightHorizonShort, ambientLightHorizonLong, brightnessThrottler, idleModeBrightnessMapper, ambientLightHorizonShort,
userLux, userBrightness); ambientLightHorizonLong, userLux, userBrightness);
} }
BrightnessMappingStrategy getInteractiveModeBrightnessMapper(Resources resources, BrightnessMappingStrategy getInteractiveModeBrightnessMapper(Resources resources,

View File

@@ -376,8 +376,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
private final ColorDisplayServiceInternal mCdsi; private final ColorDisplayServiceInternal mCdsi;
private float[] mNitsRange; private float[] mNitsRange;
private final HighBrightnessModeController mHbmController; private final BrightnessRangeController mBrightnessRangeController;
private final HighBrightnessModeMetadata mHighBrightnessModeMetadata;
private final BrightnessThrottler mBrightnessThrottler; private final BrightnessThrottler mBrightnessThrottler;
@@ -489,7 +488,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
mDisplayPowerProximityStateController = mInjector.getDisplayPowerProximityStateController( mDisplayPowerProximityStateController = mInjector.getDisplayPowerProximityStateController(
mWakelockController, mDisplayDeviceConfig, mHandler.getLooper(), mWakelockController, mDisplayDeviceConfig, mHandler.getLooper(),
() -> updatePowerState(), mDisplayId, mSensorManager); () -> updatePowerState(), mDisplayId, mSensorManager);
mHighBrightnessModeMetadata = hbmMetadata;
mDisplayStateController = new DisplayStateController(mDisplayPowerProximityStateController); mDisplayStateController = new DisplayStateController(mDisplayPowerProximityStateController);
mAutomaticBrightnessStrategy = new AutomaticBrightnessStrategy(context, mDisplayId); mAutomaticBrightnessStrategy = new AutomaticBrightnessStrategy(context, mDisplayId);
mTag = "DisplayPowerController2[" + mDisplayId + "]"; mTag = "DisplayPowerController2[" + mDisplayId + "]";
@@ -532,9 +530,22 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
mSkipScreenOnBrightnessRamp = resources.getBoolean( mSkipScreenOnBrightnessRamp = resources.getBoolean(
R.bool.config_skipScreenOnBrightnessRamp); R.bool.config_skipScreenOnBrightnessRamp);
mHbmController = createHbmControllerLocked(); Runnable modeChangeCallback = () -> {
sendUpdatePowerState();
postBrightnessChangeRunnable();
// TODO(b/192258832): Switch the HBMChangeCallback to a listener pattern.
if (mAutomaticBrightnessController != null) {
mAutomaticBrightnessController.update();
}
};
HighBrightnessModeController hbmController = createHbmControllerLocked(hbmMetadata,
modeChangeCallback);
mBrightnessThrottler = createBrightnessThrottlerLocked(); mBrightnessThrottler = createBrightnessThrottlerLocked();
mBrightnessRangeController = new BrightnessRangeController(hbmController,
modeChangeCallback);
mDisplayBrightnessController = mDisplayBrightnessController =
new DisplayBrightnessController(context, null, new DisplayBrightnessController(context, null,
mDisplayId, mLogicalDisplay.getDisplayInfoLocked().brightnessDefault, mDisplayId, mLogicalDisplay.getDisplayInfoLocked().brightnessDefault,
@@ -848,17 +859,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
mBrightnessRampIncreaseMaxTimeMillis, mBrightnessRampIncreaseMaxTimeMillis,
mBrightnessRampDecreaseMaxTimeMillis); mBrightnessRampDecreaseMaxTimeMillis);
} }
mHbmController.setHighBrightnessModeMetadata(hbmMetadata);
mHbmController.resetHbmData(info.width, info.height, token, info.uniqueId, mBrightnessRangeController.loadFromConfig(hbmMetadata, token, info, mDisplayDeviceConfig);
mDisplayDeviceConfig.getHighBrightnessModeData(),
new HighBrightnessModeController.HdrBrightnessDeviceConfig() {
@Override
public float getHdrBrightnessFromSdr(
float sdrBrightness, float maxDesiredHdrSdrRatio) {
return mDisplayDeviceConfig.getHdrBrightnessFromSdr(
sdrBrightness, maxDesiredHdrSdrRatio);
}
});
mBrightnessThrottler.loadThermalBrightnessThrottlingDataFromDisplayDeviceConfig( mBrightnessThrottler.loadThermalBrightnessThrottlingDataFromDisplayDeviceConfig(
mDisplayDeviceConfig.getThermalBrightnessThrottlingDataMapByThrottlingId(), mDisplayDeviceConfig.getThermalBrightnessThrottlingDataMapByThrottlingId(),
mThermalBrightnessThrottlingDataId, mUniqueDisplayId); mThermalBrightnessThrottlingDataId, mUniqueDisplayId);
@@ -1076,7 +1078,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
darkeningLightDebounce, autoBrightnessResetAmbientLuxAfterWarmUp, darkeningLightDebounce, autoBrightnessResetAmbientLuxAfterWarmUp,
ambientBrightnessThresholds, screenBrightnessThresholds, ambientBrightnessThresholds, screenBrightnessThresholds,
ambientBrightnessThresholdsIdle, screenBrightnessThresholdsIdle, mContext, ambientBrightnessThresholdsIdle, screenBrightnessThresholdsIdle, mContext,
mHbmController, mBrightnessThrottler, mIdleModeBrightnessMapper, mBrightnessRangeController, mBrightnessThrottler, mIdleModeBrightnessMapper,
mDisplayDeviceConfig.getAmbientHorizonShort(), mDisplayDeviceConfig.getAmbientHorizonShort(),
mDisplayDeviceConfig.getAmbientHorizonLong(), userLux, userBrightness); mDisplayDeviceConfig.getAmbientHorizonLong(), userLux, userBrightness);
mDisplayBrightnessController.setAutomaticBrightnessController( mDisplayBrightnessController.setAutomaticBrightnessController(
@@ -1180,7 +1182,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
/** Clean up all resources that are accessed via the {@link #mHandler} thread. */ /** Clean up all resources that are accessed via the {@link #mHandler} thread. */
private void cleanupHandlerThreadAfterStop() { private void cleanupHandlerThreadAfterStop() {
mDisplayPowerProximityStateController.cleanup(); mDisplayPowerProximityStateController.cleanup();
mHbmController.stop(); mBrightnessRangeController.stop();
mBrightnessThrottler.stop(); mBrightnessThrottler.stop();
mHandler.removeCallbacksAndMessages(null); mHandler.removeCallbacksAndMessages(null);
@@ -1295,7 +1297,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
&& (mAutomaticBrightnessStrategy.getAutoBrightnessAdjustmentChanged() && (mAutomaticBrightnessStrategy.getAutoBrightnessAdjustmentChanged()
|| userSetBrightnessChanged); || userSetBrightnessChanged);
mHbmController.setAutoBrightnessEnabled(mAutomaticBrightnessStrategy mBrightnessRangeController.setAutoBrightnessEnabled(mAutomaticBrightnessStrategy
.shouldUseAutoBrightness() .shouldUseAutoBrightness()
? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED ? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED
: AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED); : AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED);
@@ -1452,7 +1454,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
// here instead of having HbmController listen to the brightness setting because certain // here instead of having HbmController listen to the brightness setting because certain
// brightness sources (such as an app override) are not saved to the setting, but should be // brightness sources (such as an app override) are not saved to the setting, but should be
// reflected in HBM calculations. // reflected in HBM calculations.
mHbmController.onBrightnessChanged(brightnessState, unthrottledBrightnessState, mBrightnessRangeController.onBrightnessChanged(brightnessState, unthrottledBrightnessState,
mBrightnessThrottler.getBrightnessMaxReason()); mBrightnessThrottler.getBrightnessMaxReason());
// Animate the screen brightness when the screen is on or dozing. // Animate the screen brightness when the screen is on or dozing.
@@ -1509,13 +1511,14 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
float sdrAnimateValue = animateValue; float sdrAnimateValue = animateValue;
// TODO(b/216365040): The decision to prevent HBM for HDR in low power mode should be // TODO(b/216365040): The decision to prevent HBM for HDR in low power mode should be
// done in HighBrightnessModeController. // done in HighBrightnessModeController.
if (mHbmController.getHighBrightnessMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR if (mBrightnessRangeController.getHighBrightnessMode()
== BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR
&& (mBrightnessReasonTemp.getModifier() & BrightnessReason.MODIFIER_DIMMED) == 0 && (mBrightnessReasonTemp.getModifier() & BrightnessReason.MODIFIER_DIMMED) == 0
&& (mBrightnessReasonTemp.getModifier() & BrightnessReason.MODIFIER_LOW_POWER) && (mBrightnessReasonTemp.getModifier() & BrightnessReason.MODIFIER_LOW_POWER)
== 0) { == 0) {
// We want to scale HDR brightness level with the SDR level, we also need to restore // 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. // SDR brightness immediately when entering dim or low power mode.
animateValue = mHbmController.getHdrBrightnessValue(); animateValue = mBrightnessRangeController.getHdrBrightnessValue();
} }
final float currentBrightness = mPowerState.getScreenBrightness(); final float currentBrightness = mPowerState.getScreenBrightness();
@@ -1579,8 +1582,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
mTempBrightnessEvent.setBrightness(brightnessState); mTempBrightnessEvent.setBrightness(brightnessState);
mTempBrightnessEvent.setPhysicalDisplayId(mUniqueDisplayId); mTempBrightnessEvent.setPhysicalDisplayId(mUniqueDisplayId);
mTempBrightnessEvent.setReason(mBrightnessReason); mTempBrightnessEvent.setReason(mBrightnessReason);
mTempBrightnessEvent.setHbmMax(mHbmController.getCurrentBrightnessMax()); mTempBrightnessEvent.setHbmMax(mBrightnessRangeController.getCurrentBrightnessMax());
mTempBrightnessEvent.setHbmMode(mHbmController.getHighBrightnessMode()); mTempBrightnessEvent.setHbmMode(mBrightnessRangeController.getHighBrightnessMode());
mTempBrightnessEvent.setFlags(mTempBrightnessEvent.getFlags() mTempBrightnessEvent.setFlags(mTempBrightnessEvent.getFlags()
| (mIsRbcActive ? BrightnessEvent.FLAG_RBC : 0) | (mIsRbcActive ? BrightnessEvent.FLAG_RBC : 0)
| (mPowerRequest.lowPowerMode ? BrightnessEvent.FLAG_LOW_POWER_MODE : 0)); | (mPowerRequest.lowPowerMode ? BrightnessEvent.FLAG_LOW_POWER_MODE : 0));
@@ -1750,9 +1753,11 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
private boolean saveBrightnessInfo(float brightness, float adjustedBrightness) { private boolean saveBrightnessInfo(float brightness, float adjustedBrightness) {
synchronized (mCachedBrightnessInfo) { synchronized (mCachedBrightnessInfo) {
final float minBrightness = Math.min(mHbmController.getCurrentBrightnessMin(), final float minBrightness = Math.min(
mBrightnessRangeController.getCurrentBrightnessMin(),
mBrightnessThrottler.getBrightnessCap()); mBrightnessThrottler.getBrightnessCap());
final float maxBrightness = Math.min(mHbmController.getCurrentBrightnessMax(), final float maxBrightness = Math.min(
mBrightnessRangeController.getCurrentBrightnessMax(),
mBrightnessThrottler.getBrightnessCap()); mBrightnessThrottler.getBrightnessCap());
boolean changed = false; boolean changed = false;
@@ -1770,10 +1775,10 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
maxBrightness); maxBrightness);
changed |= changed |=
mCachedBrightnessInfo.checkAndSetInt(mCachedBrightnessInfo.hbmMode, mCachedBrightnessInfo.checkAndSetInt(mCachedBrightnessInfo.hbmMode,
mHbmController.getHighBrightnessMode()); mBrightnessRangeController.getHighBrightnessMode());
changed |= changed |=
mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.hbmTransitionPoint, mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.hbmTransitionPoint,
mHbmController.getTransitionPoint()); mBrightnessRangeController.getTransitionPoint());
changed |= changed |=
mCachedBrightnessInfo.checkAndSetInt(mCachedBrightnessInfo.brightnessMaxReason, mCachedBrightnessInfo.checkAndSetInt(mCachedBrightnessInfo.brightnessMaxReason,
mBrightnessThrottler.getBrightnessMaxReason()); mBrightnessThrottler.getBrightnessMaxReason());
@@ -1783,10 +1788,13 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
} }
void postBrightnessChangeRunnable() { void postBrightnessChangeRunnable() {
mHandler.post(mOnBrightnessChangeRunnable); if (!mHandler.hasCallbacks(mOnBrightnessChangeRunnable)) {
mHandler.post(mOnBrightnessChangeRunnable);
}
} }
private HighBrightnessModeController createHbmControllerLocked() { private HighBrightnessModeController createHbmControllerLocked(
HighBrightnessModeMetadata hbmMetadata, Runnable modeChangeCallback) {
final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked(); final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
final DisplayDeviceConfig ddConfig = device.getDisplayDeviceConfig(); final DisplayDeviceConfig ddConfig = device.getDisplayDeviceConfig();
final IBinder displayToken = final IBinder displayToken =
@@ -1798,22 +1806,9 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
return new HighBrightnessModeController(mHandler, info.width, info.height, displayToken, return new HighBrightnessModeController(mHandler, info.width, info.height, displayToken,
displayUniqueId, PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX, hbmData, displayUniqueId, PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX, hbmData,
new HighBrightnessModeController.HdrBrightnessDeviceConfig() { (sdrBrightness, maxDesiredHdrSdrRatio) ->
@Override mDisplayDeviceConfig.getHdrBrightnessFromSdr(sdrBrightness,
public float getHdrBrightnessFromSdr( maxDesiredHdrSdrRatio), modeChangeCallback, hbmMetadata, mContext);
float sdrBrightness, float maxDesiredHdrSdrRatio) {
return mDisplayDeviceConfig.getHdrBrightnessFromSdr(
sdrBrightness, maxDesiredHdrSdrRatio);
}
},
() -> {
sendUpdatePowerState();
postBrightnessChangeRunnable();
// TODO(b/192258832): Switch the HBMChangeCallback to a listener pattern.
if (mAutomaticBrightnessController != null) {
mAutomaticBrightnessController.update();
}
}, mHighBrightnessModeMetadata, mContext);
} }
private BrightnessThrottler createBrightnessThrottlerLocked() { private BrightnessThrottler createBrightnessThrottlerLocked() {
@@ -1960,8 +1955,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
if (Float.isNaN(value)) { if (Float.isNaN(value)) {
value = PowerManager.BRIGHTNESS_MIN; value = PowerManager.BRIGHTNESS_MIN;
} }
return MathUtils.constrain(value, return MathUtils.constrain(value, mBrightnessRangeController.getCurrentBrightnessMin(),
mHbmController.getCurrentBrightnessMin(), mHbmController.getCurrentBrightnessMax()); mBrightnessRangeController.getCurrentBrightnessMax());
} }
private void animateScreenBrightness(float target, float sdrTarget, float rate) { private void animateScreenBrightness(float target, float sdrTarget, float rate) {
@@ -2195,7 +2190,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
@Override @Override
public void setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux) { public void setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux) {
mHbmController.onAmbientLuxChange(ambientLux); mBrightnessRangeController.onAmbientLuxChange(ambientLux);
if (nits < 0) { if (nits < 0) {
mDisplayBrightnessController.setBrightnessToFollow(leadDisplayBrightness); mDisplayBrightnessController.setBrightnessToFollow(leadDisplayBrightness);
} else { } else {
@@ -2374,8 +2369,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
dumpRbcEvents(pw); dumpRbcEvents(pw);
if (mHbmController != null) { if (mBrightnessRangeController != null) {
mHbmController.dump(pw); mBrightnessRangeController.dump(pw);
} }
if (mBrightnessThrottler != null) { if (mBrightnessThrottler != null) {
@@ -2840,7 +2835,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
HysteresisLevels screenBrightnessThresholds, HysteresisLevels screenBrightnessThresholds,
HysteresisLevels ambientBrightnessThresholdsIdle, HysteresisLevels ambientBrightnessThresholdsIdle,
HysteresisLevels screenBrightnessThresholdsIdle, Context context, HysteresisLevels screenBrightnessThresholdsIdle, Context context,
HighBrightnessModeController hbmController, BrightnessThrottler brightnessThrottler, BrightnessRangeController brightnessModeController,
BrightnessThrottler brightnessThrottler,
BrightnessMappingStrategy idleModeBrightnessMapper, int ambientLightHorizonShort, BrightnessMappingStrategy idleModeBrightnessMapper, int ambientLightHorizonShort,
int ambientLightHorizonLong, float userLux, float userBrightness) { int ambientLightHorizonLong, float userLux, float userBrightness) {
return new AutomaticBrightnessController(callbacks, looper, sensorManager, lightSensor, return new AutomaticBrightnessController(callbacks, looper, sensorManager, lightSensor,
@@ -2849,9 +2845,9 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
brighteningLightDebounceConfig, darkeningLightDebounceConfig, brighteningLightDebounceConfig, darkeningLightDebounceConfig,
resetAmbientLuxAfterWarmUpConfig, ambientBrightnessThresholds, resetAmbientLuxAfterWarmUpConfig, ambientBrightnessThresholds,
screenBrightnessThresholds, ambientBrightnessThresholdsIdle, screenBrightnessThresholds, ambientBrightnessThresholdsIdle,
screenBrightnessThresholdsIdle, context, hbmController, brightnessThrottler, screenBrightnessThresholdsIdle, context, brightnessModeController,
idleModeBrightnessMapper, ambientLightHorizonShort, ambientLightHorizonLong, brightnessThrottler, idleModeBrightnessMapper, ambientLightHorizonShort,
userLux, userBrightness); ambientLightHorizonLong, userLux, userBrightness);
} }
BrightnessMappingStrategy getInteractiveModeBrightnessMapper(Resources resources, BrightnessMappingStrategy getInteractiveModeBrightnessMapper(Resources resources,

View File

@@ -0,0 +1,94 @@
/*
* 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;
import android.annotation.NonNull;
import android.os.PowerManager;
import com.android.server.display.DisplayDeviceConfig.BrightnessLimitMapType;
import java.util.HashMap;
import java.util.Map;
/**
* Limits brightness for normal-brightness mode, based on ambient lux
**/
class NormalBrightnessModeController {
@NonNull
private Map<BrightnessLimitMapType, Map<Float, Float>> mMaxBrightnessLimits = new HashMap<>();
private float mAmbientLux = Float.MAX_VALUE;
private boolean mAutoBrightnessEnabled = false;
// brightness limit in normal brightness mode, based on ambient lux.
private float mMaxBrightness = PowerManager.BRIGHTNESS_MAX;
boolean onAmbientLuxChange(float ambientLux) {
mAmbientLux = ambientLux;
return recalculateMaxBrightness();
}
boolean setAutoBrightnessState(int state) {
boolean isEnabled = state == AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED;
if (isEnabled != mAutoBrightnessEnabled) {
mAutoBrightnessEnabled = isEnabled;
return recalculateMaxBrightness();
}
return false;
}
float getCurrentBrightnessMax() {
return mMaxBrightness;
}
boolean resetNbmData(
@NonNull Map<BrightnessLimitMapType, Map<Float, Float>> maxBrightnessLimits) {
mMaxBrightnessLimits = maxBrightnessLimits;
return recalculateMaxBrightness();
}
private boolean recalculateMaxBrightness() {
float foundAmbientBoundary = Float.MAX_VALUE;
float foundMaxBrightness = PowerManager.BRIGHTNESS_MAX;
Map<Float, Float> maxBrightnessPoints = null;
if (mAutoBrightnessEnabled) {
maxBrightnessPoints = mMaxBrightnessLimits.get(BrightnessLimitMapType.ADAPTIVE);
}
if (maxBrightnessPoints == null) {
maxBrightnessPoints = mMaxBrightnessLimits.get(BrightnessLimitMapType.DEFAULT);
}
if (maxBrightnessPoints != null) {
for (Map.Entry<Float, Float> brightnessPoint : maxBrightnessPoints.entrySet()) {
float ambientBoundary = brightnessPoint.getKey();
// find ambient lux upper boundary closest to current ambient lux
if (ambientBoundary > mAmbientLux && ambientBoundary < foundAmbientBoundary) {
foundMaxBrightness = brightnessPoint.getValue();
foundAmbientBoundary = ambientBoundary;
}
}
}
if (mMaxBrightness != foundMaxBrightness) {
mMaxBrightness = foundMaxBrightness;
return true;
}
return false;
}
}

View File

@@ -46,6 +46,8 @@
<xs:annotation name="nonnull"/> <xs:annotation name="nonnull"/>
<xs:annotation name="final"/> <xs:annotation name="final"/>
</xs:element> </xs:element>
<xs:element type="luxThrottling" name="luxThrottling" minOccurs="0"
maxOccurs="1"/>
<xs:element type="highBrightnessMode" name="highBrightnessMode" minOccurs="0" <xs:element type="highBrightnessMode" name="highBrightnessMode" minOccurs="0"
maxOccurs="1"/> maxOccurs="1"/>
<xs:element type="displayQuirks" name="quirks" minOccurs="0" maxOccurs="1"/> <xs:element type="displayQuirks" name="quirks" minOccurs="0" maxOccurs="1"/>
@@ -137,6 +139,39 @@
</xs:sequence> </xs:sequence>
</xs:complexType> </xs:complexType>
<xs:complexType name="luxThrottling">
<xs:sequence>
<xs:element name="brightnessLimitMap" type="brightnessLimitMap"
maxOccurs="unbounded">
<xs:annotation name="nonnull"/>
<xs:annotation name="final"/>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="brightnessLimitMap">
<xs:sequence>
<xs:element name="type" type="PredefinedBrightnessLimitNames">
<xs:annotation name="nonnull"/>
<xs:annotation name="final"/>
</xs:element>
<!-- lux level from light sensor to screen brightness recommended max value map.
Screen brightness recommended max value is to highBrightnessMode.transitionPoint and must be below that -->
<xs:element name="map" type="nonNegativeFloatToFloatMap">
<xs:annotation name="nonnull"/>
<xs:annotation name="final"/>
</xs:element>
</xs:sequence>
</xs:complexType>
<!-- Predefined type names as defined by DisplayDeviceConfig.BrightnessLimitMapType -->
<xs:simpleType name="PredefinedBrightnessLimitNames">
<xs:restriction base="xs:string">
<xs:enumeration value="default"/>
<xs:enumeration value="adaptive"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="highBrightnessMode"> <xs:complexType name="highBrightnessMode">
<xs:all> <xs:all>
<xs:element name="transitionPoint" type="nonNegativeDecimal" minOccurs="1" <xs:element name="transitionPoint" type="nonNegativeDecimal" minOccurs="1"
@@ -575,4 +610,27 @@
<xs:annotation name="final"/> <xs:annotation name="final"/>
</xs:element> </xs:element>
</xs:complexType> </xs:complexType>
<!-- generic types -->
<xs:complexType name="nonNegativeFloatToFloatPoint">
<xs:sequence>
<xs:element name="first" type="nonNegativeDecimal">
<xs:annotation name="nonnull"/>
<xs:annotation name="final"/>
</xs:element>
<xs:element name="second" type="nonNegativeDecimal">
<xs:annotation name="nonnull"/>
<xs:annotation name="final"/>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="nonNegativeFloatToFloatMap">
<xs:sequence>
<xs:element name="point" type="nonNegativeFloatToFloatPoint" maxOccurs="unbounded">
<xs:annotation name="nonnull"/>
<xs:annotation name="final"/>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema> </xs:schema>

View File

@@ -26,6 +26,14 @@ package com.android.server.display.config {
method public final java.util.List<com.android.server.display.config.DisplayBrightnessPoint> getDisplayBrightnessPoint(); method public final java.util.List<com.android.server.display.config.DisplayBrightnessPoint> getDisplayBrightnessPoint();
} }
public class BrightnessLimitMap {
ctor public BrightnessLimitMap();
method @NonNull public final com.android.server.display.config.NonNegativeFloatToFloatMap getMap();
method @NonNull public final com.android.server.display.config.PredefinedBrightnessLimitNames getType();
method public final void setMap(@NonNull com.android.server.display.config.NonNegativeFloatToFloatMap);
method public final void setType(@NonNull com.android.server.display.config.PredefinedBrightnessLimitNames);
}
public class BrightnessThresholds { public class BrightnessThresholds {
ctor public BrightnessThresholds(); ctor public BrightnessThresholds();
method public final com.android.server.display.config.ThresholdPoints getBrightnessThresholdPoints(); method public final com.android.server.display.config.ThresholdPoints getBrightnessThresholdPoints();
@@ -89,6 +97,7 @@ package com.android.server.display.config {
method public final com.android.server.display.config.Thresholds getDisplayBrightnessChangeThresholdsIdle(); method public final com.android.server.display.config.Thresholds getDisplayBrightnessChangeThresholdsIdle();
method public com.android.server.display.config.HighBrightnessMode getHighBrightnessMode(); method public com.android.server.display.config.HighBrightnessMode getHighBrightnessMode();
method public final com.android.server.display.config.SensorDetails getLightSensor(); method public final com.android.server.display.config.SensorDetails getLightSensor();
method public com.android.server.display.config.LuxThrottling getLuxThrottling();
method @Nullable public final String getName(); method @Nullable public final String getName();
method public final com.android.server.display.config.SensorDetails getProxSensor(); method public final com.android.server.display.config.SensorDetails getProxSensor();
method public com.android.server.display.config.DisplayQuirks getQuirks(); method public com.android.server.display.config.DisplayQuirks getQuirks();
@@ -115,6 +124,7 @@ package com.android.server.display.config {
method public final void setDisplayBrightnessChangeThresholdsIdle(com.android.server.display.config.Thresholds); method public final void setDisplayBrightnessChangeThresholdsIdle(com.android.server.display.config.Thresholds);
method public void setHighBrightnessMode(com.android.server.display.config.HighBrightnessMode); method public void setHighBrightnessMode(com.android.server.display.config.HighBrightnessMode);
method public final void setLightSensor(com.android.server.display.config.SensorDetails); method public final void setLightSensor(com.android.server.display.config.SensorDetails);
method public void setLuxThrottling(com.android.server.display.config.LuxThrottling);
method public final void setName(@Nullable String); method public final void setName(@Nullable String);
method public final void setProxSensor(com.android.server.display.config.SensorDetails); method public final void setProxSensor(com.android.server.display.config.SensorDetails);
method public void setQuirks(com.android.server.display.config.DisplayQuirks); method public void setQuirks(com.android.server.display.config.DisplayQuirks);
@@ -173,6 +183,11 @@ package com.android.server.display.config {
method public java.util.List<java.math.BigInteger> getItem(); method public java.util.List<java.math.BigInteger> getItem();
} }
public class LuxThrottling {
ctor public LuxThrottling();
method @NonNull public final java.util.List<com.android.server.display.config.BrightnessLimitMap> getBrightnessLimitMap();
}
public class NitsMap { public class NitsMap {
ctor public NitsMap(); ctor public NitsMap();
method public String getInterpolation(); method public String getInterpolation();
@@ -180,6 +195,19 @@ package com.android.server.display.config {
method public void setInterpolation(String); method public void setInterpolation(String);
} }
public class NonNegativeFloatToFloatMap {
ctor public NonNegativeFloatToFloatMap();
method @NonNull public final java.util.List<com.android.server.display.config.NonNegativeFloatToFloatPoint> getPoint();
}
public class NonNegativeFloatToFloatPoint {
ctor public NonNegativeFloatToFloatPoint();
method @NonNull public final java.math.BigDecimal getFirst();
method @NonNull public final java.math.BigDecimal getSecond();
method public final void setFirst(@NonNull java.math.BigDecimal);
method public final void setSecond(@NonNull java.math.BigDecimal);
}
public class Point { public class Point {
ctor public Point(); ctor public Point();
method @NonNull public final java.math.BigDecimal getNits(); method @NonNull public final java.math.BigDecimal getNits();
@@ -188,6 +216,12 @@ package com.android.server.display.config {
method public final void setValue(@NonNull java.math.BigDecimal); method public final void setValue(@NonNull java.math.BigDecimal);
} }
public enum PredefinedBrightnessLimitNames {
method public String getRawName();
enum_constant public static final com.android.server.display.config.PredefinedBrightnessLimitNames _default;
enum_constant public static final com.android.server.display.config.PredefinedBrightnessLimitNames adaptive;
}
public class RefreshRateConfigs { public class RefreshRateConfigs {
ctor public RefreshRateConfigs(); ctor public RefreshRateConfigs();
method public final java.math.BigInteger getDefaultPeakRefreshRate(); method public final java.math.BigInteger getDefaultPeakRefreshRate();

View File

@@ -815,7 +815,7 @@ public final class DisplayPowerController2Test {
any(HysteresisLevels.class), any(HysteresisLevels.class),
any(HysteresisLevels.class), any(HysteresisLevels.class),
eq(mContext), eq(mContext),
any(HighBrightnessModeController.class), any(BrightnessRangeController.class),
any(BrightnessThrottler.class), any(BrightnessThrottler.class),
isNull(), isNull(),
anyInt(), anyInt(),
@@ -1064,7 +1064,7 @@ public final class DisplayPowerController2Test {
HysteresisLevels screenBrightnessThresholds, HysteresisLevels screenBrightnessThresholds,
HysteresisLevels ambientBrightnessThresholdsIdle, HysteresisLevels ambientBrightnessThresholdsIdle,
HysteresisLevels screenBrightnessThresholdsIdle, Context context, HysteresisLevels screenBrightnessThresholdsIdle, Context context,
HighBrightnessModeController hbmController, BrightnessRangeController brightnessRangeController,
BrightnessThrottler brightnessThrottler, BrightnessThrottler brightnessThrottler,
BrightnessMappingStrategy idleModeBrightnessMapper, BrightnessMappingStrategy idleModeBrightnessMapper,
int ambientLightHorizonShort, int ambientLightHorizonLong, float userLux, int ambientLightHorizonShort, int ambientLightHorizonLong, float userLux,

View File

@@ -819,7 +819,7 @@ public final class DisplayPowerControllerTest {
any(HysteresisLevels.class), any(HysteresisLevels.class),
any(HysteresisLevels.class), any(HysteresisLevels.class),
eq(mContext), eq(mContext),
any(HighBrightnessModeController.class), any(BrightnessRangeController.class),
any(BrightnessThrottler.class), any(BrightnessThrottler.class),
isNull(), isNull(),
anyInt(), anyInt(),
@@ -1038,7 +1038,7 @@ public final class DisplayPowerControllerTest {
HysteresisLevels screenBrightnessThresholds, HysteresisLevels screenBrightnessThresholds,
HysteresisLevels ambientBrightnessThresholdsIdle, HysteresisLevels ambientBrightnessThresholdsIdle,
HysteresisLevels screenBrightnessThresholdsIdle, Context context, HysteresisLevels screenBrightnessThresholdsIdle, Context context,
HighBrightnessModeController hbmController, BrightnessRangeController brightnessRangeController,
BrightnessThrottler brightnessThrottler, BrightnessThrottler brightnessThrottler,
BrightnessMappingStrategy idleModeBrightnessMapper, BrightnessMappingStrategy idleModeBrightnessMapper,
int ambientLightHorizonShort, int ambientLightHorizonLong, float userLux, int ambientLightHorizonShort, int ambientLightHorizonLong, float userLux,

View File

@@ -85,7 +85,7 @@ public class AutomaticBrightnessControllerTest {
@Mock HysteresisLevels mAmbientBrightnessThresholdsIdle; @Mock HysteresisLevels mAmbientBrightnessThresholdsIdle;
@Mock HysteresisLevels mScreenBrightnessThresholdsIdle; @Mock HysteresisLevels mScreenBrightnessThresholdsIdle;
@Mock Handler mNoOpHandler; @Mock Handler mNoOpHandler;
@Mock HighBrightnessModeController mHbmController; @Mock BrightnessRangeController mBrightnessRangeController;
@Mock BrightnessThrottler mBrightnessThrottler; @Mock BrightnessThrottler mBrightnessThrottler;
@Before @Before
@@ -134,12 +134,15 @@ public class AutomaticBrightnessControllerTest {
DARKENING_LIGHT_DEBOUNCE_CONFIG, RESET_AMBIENT_LUX_AFTER_WARMUP_CONFIG, DARKENING_LIGHT_DEBOUNCE_CONFIG, RESET_AMBIENT_LUX_AFTER_WARMUP_CONFIG,
mAmbientBrightnessThresholds, mScreenBrightnessThresholds, mAmbientBrightnessThresholds, mScreenBrightnessThresholds,
mAmbientBrightnessThresholdsIdle, mScreenBrightnessThresholdsIdle, mAmbientBrightnessThresholdsIdle, mScreenBrightnessThresholdsIdle,
mContext, mHbmController, mBrightnessThrottler, mIdleBrightnessMappingStrategy, mContext, mBrightnessRangeController, mBrightnessThrottler,
AMBIENT_LIGHT_HORIZON_SHORT, AMBIENT_LIGHT_HORIZON_LONG, userLux, userBrightness mIdleBrightnessMappingStrategy, AMBIENT_LIGHT_HORIZON_SHORT,
AMBIENT_LIGHT_HORIZON_LONG, userLux, userBrightness
); );
when(mHbmController.getCurrentBrightnessMax()).thenReturn(BRIGHTNESS_MAX_FLOAT); when(mBrightnessRangeController.getCurrentBrightnessMax()).thenReturn(
when(mHbmController.getCurrentBrightnessMin()).thenReturn(BRIGHTNESS_MIN_FLOAT); BRIGHTNESS_MAX_FLOAT);
when(mBrightnessRangeController.getCurrentBrightnessMin()).thenReturn(
BRIGHTNESS_MIN_FLOAT);
// Disable brightness throttling by default. Individual tests can enable it as needed. // Disable brightness throttling by default. Individual tests can enable it as needed.
when(mBrightnessThrottler.getBrightnessCap()).thenReturn(BRIGHTNESS_MAX_FLOAT); when(mBrightnessThrottler.getBrightnessCap()).thenReturn(BRIGHTNESS_MAX_FLOAT);
when(mBrightnessThrottler.isThrottled()).thenReturn(false); when(mBrightnessThrottler.isThrottled()).thenReturn(false);

View File

@@ -52,6 +52,7 @@ import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
@SmallTest @SmallTest
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
@@ -376,6 +377,116 @@ public final class DisplayDeviceConfigTest {
assertEquals(90, testMap.get(Temperature.THROTTLING_EMERGENCY).max, SMALL_DELTA); assertEquals(90, testMap.get(Temperature.THROTTLING_EMERGENCY).max, SMALL_DELTA);
} }
@Test
public void testValidLuxThrottling() throws Exception {
setupDisplayDeviceConfigFromDisplayConfigFile();
Map<DisplayDeviceConfig.BrightnessLimitMapType, Map<Float, Float>> luxThrottlingData =
mDisplayDeviceConfig.getLuxThrottlingData();
assertEquals(2, luxThrottlingData.size());
Map<Float, Float> adaptiveOnBrightnessPoints = luxThrottlingData.get(
DisplayDeviceConfig.BrightnessLimitMapType.ADAPTIVE);
assertEquals(2, adaptiveOnBrightnessPoints.size());
assertEquals(0.3f, adaptiveOnBrightnessPoints.get(1000f), SMALL_DELTA);
assertEquals(0.5f, adaptiveOnBrightnessPoints.get(5000f), SMALL_DELTA);
Map<Float, Float> adaptiveOffBrightnessPoints = luxThrottlingData.get(
DisplayDeviceConfig.BrightnessLimitMapType.DEFAULT);
assertEquals(2, adaptiveOffBrightnessPoints.size());
assertEquals(0.35f, adaptiveOffBrightnessPoints.get(1500f), SMALL_DELTA);
assertEquals(0.55f, adaptiveOffBrightnessPoints.get(5500f), SMALL_DELTA);
}
@Test
public void testInvalidLuxThrottling() throws Exception {
setupDisplayDeviceConfigFromDisplayConfigFile(getContent(getInvalidLuxThrottling()));
Map<DisplayDeviceConfig.BrightnessLimitMapType, Map<Float, Float>> luxThrottlingData =
mDisplayDeviceConfig.getLuxThrottlingData();
assertEquals(1, luxThrottlingData.size());
Map<Float, Float> adaptiveOnBrightnessPoints = luxThrottlingData.get(
DisplayDeviceConfig.BrightnessLimitMapType.ADAPTIVE);
assertEquals(1, adaptiveOnBrightnessPoints.size());
assertEquals(0.3f, adaptiveOnBrightnessPoints.get(1000f), SMALL_DELTA);
}
private String getValidLuxThrottling() {
return "<luxThrottling>\n"
+ " <brightnessLimitMap>\n"
+ " <type>adaptive</type>\n"
+ " <map>\n"
+ " <point>"
+ " <first>1000</first>\n"
+ " <second>0.3</second>\n"
+ " </point>"
+ " <point>"
+ " <first>5000</first>\n"
+ " <second>0.5</second>\n"
+ " </point>"
+ " </map>\n"
+ " </brightnessLimitMap>\n"
+ " <brightnessLimitMap>\n"
+ " <type>default</type>\n"
+ " <map>\n"
+ " <point>"
+ " <first>1500</first>\n"
+ " <second>0.35</second>\n"
+ " </point>"
+ " <point>"
+ " <first>5500</first>\n"
+ " <second>0.55</second>\n"
+ " </point>"
+ " </map>\n"
+ " </brightnessLimitMap>\n"
+ "</luxThrottling>";
}
private String getInvalidLuxThrottling() {
return "<luxThrottling>\n"
+ " <brightnessLimitMap>\n"
+ " <type>adaptive</type>\n"
+ " <map>\n"
+ " <point>"
+ " <first>1000</first>\n"
+ " <second>0.3</second>\n"
+ " </point>"
+ " <point>" // second > hbm.transitionPoint, skipped
+ " <first>1500</first>\n"
+ " <second>0.9</second>\n"
+ " </point>"
+ " <point>" // same lux value, skipped
+ " <first>1000</first>\n"
+ " <second>0.5</second>\n"
+ " </point>"
+ " </map>\n"
+ " </brightnessLimitMap>\n"
+ " <brightnessLimitMap>\n" // Same type, skipped
+ " <type>adaptive</type>\n"
+ " <map>\n"
+ " <point>"
+ " <first>2000</first>\n"
+ " <second>0.35</second>\n"
+ " </point>"
+ " <point>"
+ " <first>6000</first>\n"
+ " <second>0.55</second>\n"
+ " </point>"
+ " </map>\n"
+ " </brightnessLimitMap>\n"
+ " <brightnessLimitMap>\n" // Invalid points only, skipped
+ " <type>default</type>\n"
+ " <map>\n"
+ " <point>"
+ " <first>2500</first>\n"
+ " <second>0.99</second>\n"
+ " </point>"
+ " </map>\n"
+ " </brightnessLimitMap>\n"
+ "</luxThrottling>";
}
private String getRefreshThermalThrottlingMaps() { private String getRefreshThermalThrottlingMaps() {
return "<refreshRateThrottlingMap>\n" return "<refreshRateThrottlingMap>\n"
+ " <refreshRateThrottlingPoint>\n" + " <refreshRateThrottlingPoint>\n"
@@ -405,6 +516,10 @@ public final class DisplayDeviceConfigTest {
} }
private String getContent() { private String getContent() {
return getContent(getValidLuxThrottling());
}
private String getContent(String brightnessCapConfig) {
return "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" return "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+ "<displayConfiguration>\n" + "<displayConfiguration>\n"
+ "<name>Example Display</name>" + "<name>Example Display</name>"
@@ -462,6 +577,7 @@ public final class DisplayDeviceConfigTest {
+ "</point>\n" + "</point>\n"
+ "</sdrHdrRatioMap>\n" + "</sdrHdrRatioMap>\n"
+ "</highBrightnessMode>\n" + "</highBrightnessMode>\n"
+ brightnessCapConfig
+ "<screenOffBrightnessSensor>\n" + "<screenOffBrightnessSensor>\n"
+ "<type>sensor_12345</type>\n" + "<type>sensor_12345</type>\n"
+ "<name>Sensor 12345</name>\n" + "<name>Sensor 12345</name>\n"
@@ -731,8 +847,12 @@ public final class DisplayDeviceConfigTest {
} }
private void setupDisplayDeviceConfigFromDisplayConfigFile() throws IOException { private void setupDisplayDeviceConfigFromDisplayConfigFile() throws IOException {
setupDisplayDeviceConfigFromDisplayConfigFile(getContent());
}
private void setupDisplayDeviceConfigFromDisplayConfigFile(String content) throws IOException {
Path tempFile = Files.createTempFile("display_config", ".tmp"); Path tempFile = Files.createTempFile("display_config", ".tmp");
Files.write(tempFile, getContent().getBytes(StandardCharsets.UTF_8)); Files.write(tempFile, content.getBytes(StandardCharsets.UTF_8));
mDisplayDeviceConfig = new DisplayDeviceConfig(mContext); mDisplayDeviceConfig = new DisplayDeviceConfig(mContext);
mDisplayDeviceConfig.initFromFile(tempFile.toFile()); mDisplayDeviceConfig.initFromFile(tempFile.toFile());
} }

View File

@@ -0,0 +1,116 @@
/*
* 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;
import static org.junit.Assert.assertEquals;
import android.os.PowerManager;
import androidx.test.filters.SmallTest;
import com.android.internal.annotations.Keep;
import com.android.server.display.DisplayDeviceConfig.BrightnessLimitMapType;
import com.google.common.collect.ImmutableMap;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.HashMap;
import java.util.Map;
import junitparams.JUnitParamsRunner;
import junitparams.Parameters;
@SmallTest
@RunWith(JUnitParamsRunner.class)
public class NormalBrightnessModeControllerTest {
private static final float FLOAT_TOLERANCE = 0.001f;
private final NormalBrightnessModeController mController = new NormalBrightnessModeController();
@Keep
private static Object[][] brightnessData() {
return new Object[][]{
// no brightness config
{0, AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED, new HashMap<>(),
PowerManager.BRIGHTNESS_MAX},
{0, AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED, new HashMap<>(),
PowerManager.BRIGHTNESS_MAX},
{100, AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED, new HashMap<>(),
PowerManager.BRIGHTNESS_MAX},
// Auto brightness - on, config only for default
{100, AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED, ImmutableMap.of(
BrightnessLimitMapType.DEFAULT,
ImmutableMap.of(99f, 0.1f, 101f, 0.2f)
), 0.2f},
// Auto brightness - off, config only for default
{100, AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED, ImmutableMap.of(
BrightnessLimitMapType.DEFAULT,
ImmutableMap.of(99f, 0.1f, 101f, 0.2f)
), 0.2f},
// Auto brightness - off, config only for adaptive
{100, AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED, ImmutableMap.of(
BrightnessLimitMapType.ADAPTIVE,
ImmutableMap.of(99f, 0.1f, 101f, 0.2f)
), PowerManager.BRIGHTNESS_MAX},
// Auto brightness - on, config only for adaptive
{100, AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED, ImmutableMap.of(
BrightnessLimitMapType.ADAPTIVE,
ImmutableMap.of(99f, 0.1f, 101f, 0.2f)
), 0.2f},
// Auto brightness - on, config for both
{100, AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED, ImmutableMap.of(
BrightnessLimitMapType.DEFAULT,
ImmutableMap.of(99f, 0.1f, 101f, 0.2f),
BrightnessLimitMapType.ADAPTIVE,
ImmutableMap.of(99f, 0.3f, 101f, 0.4f)
), 0.4f},
// Auto brightness - off, config for both
{100, AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED, ImmutableMap.of(
BrightnessLimitMapType.DEFAULT,
ImmutableMap.of(99f, 0.1f, 101f, 0.2f),
BrightnessLimitMapType.ADAPTIVE,
ImmutableMap.of(99f, 0.3f, 101f, 0.4f)
), 0.2f},
// Auto brightness - on, config for both, ambient high
{1000, AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED, ImmutableMap.of(
BrightnessLimitMapType.DEFAULT,
ImmutableMap.of(1000f, 0.1f, 2000f, 0.2f),
BrightnessLimitMapType.ADAPTIVE,
ImmutableMap.of(99f, 0.3f, 101f, 0.4f)
), PowerManager.BRIGHTNESS_MAX},
};
}
@Test
@Parameters(method = "brightnessData")
public void testReturnsCorrectMaxBrightness(float ambientLux, int autoBrightnessState,
Map<BrightnessLimitMapType, Map<Float, Float>> maxBrightnessConfig,
float expectedBrightness) {
setupController(ambientLux, autoBrightnessState, maxBrightnessConfig);
assertEquals(expectedBrightness, mController.getCurrentBrightnessMax(), FLOAT_TOLERANCE);
}
private void setupController(float ambientLux, int autoBrightnessState,
Map<BrightnessLimitMapType, Map<Float, Float>> maxBrightnessConfig) {
mController.onAmbientLuxChange(ambientLux);
mController.setAutoBrightnessState(autoBrightnessState);
mController.resetNbmData(maxBrightnessConfig);
}
}