NormalBrightnessModeController configuration

Bug: b/277877297
Test: atest DisplayDeviceCongigTest, atest NormalBrightnessControllerTest
Change-Id: I8681d009336d22206db355e6a18a79bc89c39603
Merged-In: I8681d009336d22206db355e6a18a79bc89c39603
This commit is contained in:
Oleg Petsjonkin
2023-05-25 10:30:20 +00:00
committed by Peter Lin
parent ac0d75f2d2
commit 609b475b0b
9 changed files with 520 additions and 38 deletions

View File

@@ -20,6 +20,7 @@ import android.hardware.display.BrightnessInfo;
import android.os.IBinder; import android.os.IBinder;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.function.BooleanSupplier;
class BrightnessRangeController { class BrightnessRangeController {
@@ -43,20 +44,10 @@ class BrightnessRangeController {
} }
void onAmbientLuxChange(float ambientLux) { void onAmbientLuxChange(float ambientLux) {
if (NBM_FEATURE_FLAG) { applyChanges(
boolean nbmTransitionChanged = mNormalBrightnessModeController.onAmbientLuxChange( () -> mNormalBrightnessModeController.onAmbientLuxChange(ambientLux),
ambientLux); () -> mHbmController.onAmbientLuxChange(ambientLux)
int previousHbm = mHbmController.getHighBrightnessMode(); );
mHbmController.onAmbientLuxChange(ambientLux);
int nextHbm = mHbmController.getHighBrightnessMode();
// if hbm changed - callback was triggered in mHbmController.onAmbientLuxChange
// if nbm transition not changed - no need to trigger callback
if (previousHbm == nextHbm && nbmTransitionChanged) {
mModeChangeCallback.run();
}
} else {
mHbmController.onAmbientLuxChange(ambientLux);
}
} }
float getNormalBrightnessMax() { float getNormalBrightnessMax() {
@@ -65,10 +56,16 @@ class BrightnessRangeController {
void loadFromConfig(HighBrightnessModeMetadata hbmMetadata, IBinder token, void loadFromConfig(HighBrightnessModeMetadata hbmMetadata, IBinder token,
DisplayDeviceInfo info, DisplayDeviceConfig displayDeviceConfig) { DisplayDeviceInfo info, DisplayDeviceConfig displayDeviceConfig) {
mHbmController.setHighBrightnessModeMetadata(hbmMetadata); applyChanges(
mHbmController.resetHbmData(info.width, info.height, token, info.uniqueId, () -> mNormalBrightnessModeController.resetNbmData(
displayDeviceConfig.getHighBrightnessModeData(), displayDeviceConfig.getLuxThrottlingData()),
displayDeviceConfig::getHdrBrightnessFromSdr); () -> {
mHbmController.setHighBrightnessModeMetadata(hbmMetadata);
mHbmController.resetHbmData(info.width, info.height, token, info.uniqueId,
displayDeviceConfig.getHighBrightnessModeData(),
displayDeviceConfig::getHdrBrightnessFromSdr);
}
);
} }
void stop() { void stop() {
@@ -76,7 +73,10 @@ class BrightnessRangeController {
} }
void setAutoBrightnessEnabled(int state) { void setAutoBrightnessEnabled(int state) {
mHbmController.setAutoBrightnessEnabled(state); applyChanges(
() -> mNormalBrightnessModeController.setAutoBrightnessState(state),
() -> mHbmController.setAutoBrightnessEnabled(state)
);
} }
void onBrightnessChanged(float brightness, float unthrottledBrightness, void onBrightnessChanged(float brightness, float unthrottledBrightness,
@@ -109,4 +109,18 @@ class BrightnessRangeController {
float getTransitionPoint() { float getTransitionPoint() {
return mHbmController.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

@@ -2141,7 +2141,9 @@ 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(

View File

@@ -1788,7 +1788,9 @@ 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(

View File

@@ -16,36 +16,79 @@
package com.android.server.display; package com.android.server.display;
import android.annotation.NonNull;
import android.os.PowerManager; import android.os.PowerManager;
import com.android.server.display.DisplayDeviceConfig.BrightnessLimitMapType;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
/**
* Limits brightness for normal-brightness mode, based on ambient lux
**/
class NormalBrightnessModeController { class NormalBrightnessModeController {
private Map<Float, Float> mTransitionPoints = new HashMap<>(); @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. // brightness limit in normal brightness mode, based on ambient lux.
private float mVirtualTransitionPoint = PowerManager.BRIGHTNESS_MAX; private float mMaxBrightness = PowerManager.BRIGHTNESS_MAX;
boolean onAmbientLuxChange(float ambientLux) { boolean onAmbientLuxChange(float ambientLux) {
float currentAmbientBoundary = Float.MAX_VALUE; mAmbientLux = ambientLux;
float currentTransitionPoint = PowerManager.BRIGHTNESS_MAX; return recalculateMaxBrightness();
for (Map.Entry<Float, Float> transitionPoint: mTransitionPoints.entrySet()) { }
float ambientBoundary = transitionPoint.getKey();
// find ambient lux upper boundary closest to current ambient lux boolean setAutoBrightnessState(int state) {
if (ambientBoundary > ambientLux && ambientBoundary < currentAmbientBoundary) { boolean isEnabled = state == AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED;
currentTransitionPoint = transitionPoint.getValue(); if (isEnabled != mAutoBrightnessEnabled) {
currentAmbientBoundary = ambientBoundary; mAutoBrightnessEnabled = isEnabled;
} return recalculateMaxBrightness();
}
if (mVirtualTransitionPoint != currentTransitionPoint) {
mVirtualTransitionPoint = currentTransitionPoint;
return true;
} }
return false; return false;
} }
float getCurrentBrightnessMax() { float getCurrentBrightnessMax() {
return mVirtualTransitionPoint; 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

@@ -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);
}
}