summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/display/BrightnessRangeController.java52
-rw-r--r--services/core/java/com/android/server/display/DisplayDeviceConfig.java93
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController.java4
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController2.java4
-rw-r--r--services/core/java/com/android/server/display/NormalBrightnessModeController.java75
-rw-r--r--services/core/xsd/display-device-config/display-device-config.xsd58
-rw-r--r--services/core/xsd/display-device-config/schema/current.txt34
-rw-r--r--services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java122
-rw-r--r--services/tests/servicestests/src/com/android/server/display/NormalBrightnessModeControllerTest.java116
9 files changed, 520 insertions, 38 deletions
diff --git a/services/core/java/com/android/server/display/BrightnessRangeController.java b/services/core/java/com/android/server/display/BrightnessRangeController.java
index 12813c82bfff..47cde1517450 100644
--- a/services/core/java/com/android/server/display/BrightnessRangeController.java
+++ b/services/core/java/com/android/server/display/BrightnessRangeController.java
@@ -20,6 +20,7 @@ import android.hardware.display.BrightnessInfo;
import android.os.IBinder;
import java.io.PrintWriter;
+import java.util.function.BooleanSupplier;
class BrightnessRangeController {
@@ -43,20 +44,10 @@ class BrightnessRangeController {
}
void onAmbientLuxChange(float ambientLux) {
- if (NBM_FEATURE_FLAG) {
- boolean nbmTransitionChanged = mNormalBrightnessModeController.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);
- }
+ applyChanges(
+ () -> mNormalBrightnessModeController.onAmbientLuxChange(ambientLux),
+ () -> mHbmController.onAmbientLuxChange(ambientLux)
+ );
}
float getNormalBrightnessMax() {
@@ -65,10 +56,16 @@ class BrightnessRangeController {
void loadFromConfig(HighBrightnessModeMetadata hbmMetadata, IBinder token,
DisplayDeviceInfo info, DisplayDeviceConfig displayDeviceConfig) {
- mHbmController.setHighBrightnessModeMetadata(hbmMetadata);
- mHbmController.resetHbmData(info.width, info.height, token, info.uniqueId,
- displayDeviceConfig.getHighBrightnessModeData(),
- displayDeviceConfig::getHdrBrightnessFromSdr);
+ applyChanges(
+ () -> mNormalBrightnessModeController.resetNbmData(
+ displayDeviceConfig.getLuxThrottlingData()),
+ () -> {
+ mHbmController.setHighBrightnessModeMetadata(hbmMetadata);
+ mHbmController.resetHbmData(info.width, info.height, token, info.uniqueId,
+ displayDeviceConfig.getHighBrightnessModeData(),
+ displayDeviceConfig::getHdrBrightnessFromSdr);
+ }
+ );
}
void stop() {
@@ -76,7 +73,10 @@ class BrightnessRangeController {
}
void setAutoBrightnessEnabled(int state) {
- mHbmController.setAutoBrightnessEnabled(state);
+ applyChanges(
+ () -> mNormalBrightnessModeController.setAutoBrightnessState(state),
+ () -> mHbmController.setAutoBrightnessEnabled(state)
+ );
}
void onBrightnessChanged(float brightness, float unthrottledBrightness,
@@ -109,4 +109,18 @@ class BrightnessRangeController {
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();
+ }
+ }
}
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index 7a797dd2250c..7ccfb448cf61 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -41,6 +41,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.display.BrightnessSynchronizer;
import com.android.server.display.config.AutoBrightness;
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.BrightnessThrottlingMap;
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.HighBrightnessMode;
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.NonNegativeFloatToFloatPoint;
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.RefreshRateRange;
import com.android.server.display.config.RefreshRateThrottlingMap;
@@ -219,6 +223,22 @@ import javax.xml.datatype.DatatypeConfigurationException;
* <allowInLowPowerMode>false</allowInLowPowerMode>
* </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>
* <quirk>canSetBrightnessViaHwc</quirk>
* </quirks>
@@ -693,6 +713,9 @@ public class DisplayDeviceConfig {
private final Map<String, SparseArray<SurfaceControl.RefreshRateRange>>
mRefreshRateThrottlingMap = new HashMap<>();
+ private final Map<BrightnessLimitMapType, Map<Float, Float>>
+ mLuxThrottlingData = new HashMap<>();
+
@Nullable
private HostUsiVersion mHostUsiVersion;
@@ -1344,6 +1367,11 @@ public class DisplayDeviceConfig {
return hbmData;
}
+ @NonNull
+ public Map<BrightnessLimitMapType, Map<Float, Float>> getLuxThrottlingData() {
+ return mLuxThrottlingData;
+ }
+
public List<RefreshRateLimitation> getRefreshRateLimitations() {
return mRefreshRateLimitations;
}
@@ -1530,6 +1558,7 @@ public class DisplayDeviceConfig {
+ ", mBrightnessDefault=" + mBrightnessDefault
+ ", mQuirks=" + mQuirks
+ ", isHbmEnabled=" + mIsHighBrightnessModeEnabled
+ + ", mLuxThrottlingData=" + mLuxThrottlingData
+ ", mHbmData=" + mHbmData
+ ", mSdrToHdrRatioSpline=" + mSdrToHdrRatioSpline
+ ", mThermalBrightnessThrottlingDataMapByThrottlingId="
@@ -1676,6 +1705,7 @@ public class DisplayDeviceConfig {
loadBrightnessMap(config);
loadThermalThrottlingConfig(config);
loadHighBrightnessModeData(config);
+ loadLuxThrottling(config);
loadQuirks(config);
loadBrightnessRamps(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) {
// Priority 1: Value in the display device config (float)
// 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;
+ }
+ }
}
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 7d8bde9feabf..80114ccd6568 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -2141,7 +2141,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
}
void postBrightnessChangeRunnable() {
- mHandler.post(mOnBrightnessChangeRunnable);
+ if (!mHandler.hasCallbacks(mOnBrightnessChangeRunnable)) {
+ mHandler.post(mOnBrightnessChangeRunnable);
+ }
}
private HighBrightnessModeController createHbmControllerLocked(
diff --git a/services/core/java/com/android/server/display/DisplayPowerController2.java b/services/core/java/com/android/server/display/DisplayPowerController2.java
index 040ceccbc7c9..c8b0a724ffed 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController2.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController2.java
@@ -1788,7 +1788,9 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
}
void postBrightnessChangeRunnable() {
- mHandler.post(mOnBrightnessChangeRunnable);
+ if (!mHandler.hasCallbacks(mOnBrightnessChangeRunnable)) {
+ mHandler.post(mOnBrightnessChangeRunnable);
+ }
}
private HighBrightnessModeController createHbmControllerLocked(
diff --git a/services/core/java/com/android/server/display/NormalBrightnessModeController.java b/services/core/java/com/android/server/display/NormalBrightnessModeController.java
index 91e4a9e407db..dbabc2441224 100644
--- a/services/core/java/com/android/server/display/NormalBrightnessModeController.java
+++ b/services/core/java/com/android/server/display/NormalBrightnessModeController.java
@@ -16,36 +16,79 @@
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 {
- 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.
- private float mVirtualTransitionPoint = PowerManager.BRIGHTNESS_MAX;
+ private float mMaxBrightness = PowerManager.BRIGHTNESS_MAX;
boolean onAmbientLuxChange(float ambientLux) {
- float currentAmbientBoundary = Float.MAX_VALUE;
- float currentTransitionPoint = PowerManager.BRIGHTNESS_MAX;
- for (Map.Entry<Float, Float> transitionPoint: mTransitionPoints.entrySet()) {
- float ambientBoundary = transitionPoint.getKey();
- // find ambient lux upper boundary closest to current ambient lux
- if (ambientBoundary > ambientLux && ambientBoundary < currentAmbientBoundary) {
- currentTransitionPoint = transitionPoint.getValue();
- currentAmbientBoundary = ambientBoundary;
- }
- }
- if (mVirtualTransitionPoint != currentTransitionPoint) {
- mVirtualTransitionPoint = currentTransitionPoint;
- return true;
+ 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 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;
}
}
diff --git a/services/core/xsd/display-device-config/display-device-config.xsd b/services/core/xsd/display-device-config/display-device-config.xsd
index f96ca582c28f..7104a80c668d 100644
--- a/services/core/xsd/display-device-config/display-device-config.xsd
+++ b/services/core/xsd/display-device-config/display-device-config.xsd
@@ -46,6 +46,8 @@
<xs:annotation name="nonnull"/>
<xs:annotation name="final"/>
</xs:element>
+ <xs:element type="luxThrottling" name="luxThrottling" minOccurs="0"
+ maxOccurs="1"/>
<xs:element type="highBrightnessMode" name="highBrightnessMode" minOccurs="0"
maxOccurs="1"/>
<xs:element type="displayQuirks" name="quirks" minOccurs="0" maxOccurs="1"/>
@@ -137,6 +139,39 @@
</xs:sequence>
</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:all>
<xs:element name="transitionPoint" type="nonNegativeDecimal" minOccurs="1"
@@ -575,4 +610,27 @@
<xs:annotation name="final"/>
</xs:element>
</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>
diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt
index ad6434e0c545..507c9dccda59 100644
--- a/services/core/xsd/display-device-config/schema/current.txt
+++ b/services/core/xsd/display-device-config/schema/current.txt
@@ -26,6 +26,14 @@ package com.android.server.display.config {
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 {
ctor public BrightnessThresholds();
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 com.android.server.display.config.HighBrightnessMode getHighBrightnessMode();
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 public final com.android.server.display.config.SensorDetails getProxSensor();
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 void setHighBrightnessMode(com.android.server.display.config.HighBrightnessMode);
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 setProxSensor(com.android.server.display.config.SensorDetails);
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();
}
+ public class LuxThrottling {
+ ctor public LuxThrottling();
+ method @NonNull public final java.util.List<com.android.server.display.config.BrightnessLimitMap> getBrightnessLimitMap();
+ }
+
public class NitsMap {
ctor public NitsMap();
method public String getInterpolation();
@@ -180,6 +195,19 @@ package com.android.server.display.config {
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 {
ctor public Point();
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);
}
+ 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 {
ctor public RefreshRateConfigs();
method public final java.math.BigInteger getDefaultPeakRefreshRate();
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java
index 5837b21b89fd..708421d2a431 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java
@@ -52,6 +52,7 @@ import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -376,6 +377,116 @@ public final class DisplayDeviceConfigTest {
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() {
return "<refreshRateThrottlingMap>\n"
+ " <refreshRateThrottlingPoint>\n"
@@ -405,6 +516,10 @@ public final class DisplayDeviceConfigTest {
}
private String getContent() {
+ return getContent(getValidLuxThrottling());
+ }
+
+ private String getContent(String brightnessCapConfig) {
return "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+ "<displayConfiguration>\n"
+ "<name>Example Display</name>"
@@ -462,6 +577,7 @@ public final class DisplayDeviceConfigTest {
+ "</point>\n"
+ "</sdrHdrRatioMap>\n"
+ "</highBrightnessMode>\n"
+ + brightnessCapConfig
+ "<screenOffBrightnessSensor>\n"
+ "<type>sensor_12345</type>\n"
+ "<name>Sensor 12345</name>\n"
@@ -731,8 +847,12 @@ public final class DisplayDeviceConfigTest {
}
private void setupDisplayDeviceConfigFromDisplayConfigFile() throws IOException {
+ setupDisplayDeviceConfigFromDisplayConfigFile(getContent());
+ }
+
+ private void setupDisplayDeviceConfigFromDisplayConfigFile(String content) throws IOException {
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.initFromFile(tempFile.toFile());
}
diff --git a/services/tests/servicestests/src/com/android/server/display/NormalBrightnessModeControllerTest.java b/services/tests/servicestests/src/com/android/server/display/NormalBrightnessModeControllerTest.java
new file mode 100644
index 000000000000..c379d6b79ee7
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/display/NormalBrightnessModeControllerTest.java
@@ -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);
+ }
+}