Make thresholds tuneable in the ddc
Add screen and ambient thresholds to the ddc. Use these values as a minimum required change, so that brightness can be more stable at lower light levels. Bug: 205683328 Test: adb shell dumpsys display Test: atest AutomaticBrightnessControllerTest Change-Id: I3af6d754899d75ed51964ed7ad140f1572ec41b0
This commit is contained in:
@@ -32,6 +32,7 @@ import android.view.DisplayAddress;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.display.BrightnessSynchronizer;
|
||||
import com.android.server.display.config.BrightnessThresholds;
|
||||
import com.android.server.display.config.Density;
|
||||
import com.android.server.display.config.DisplayConfiguration;
|
||||
import com.android.server.display.config.DisplayQuirks;
|
||||
@@ -42,6 +43,7 @@ import com.android.server.display.config.Point;
|
||||
import com.android.server.display.config.RefreshRateRange;
|
||||
import com.android.server.display.config.SensorDetails;
|
||||
import com.android.server.display.config.ThermalStatus;
|
||||
import com.android.server.display.config.Thresholds;
|
||||
import com.android.server.display.config.XmlParser;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
@@ -130,6 +132,10 @@ public class DisplayDeviceConfig {
|
||||
private float mBrightnessRampSlowIncrease = Float.NaN;
|
||||
private int mAmbientHorizonLong = AMBIENT_LIGHT_LONG_HORIZON_MILLIS;
|
||||
private int mAmbientHorizonShort = AMBIENT_LIGHT_SHORT_HORIZON_MILLIS;
|
||||
private float mScreenBrighteningMinThreshold = 0.0f; // Retain behaviour as though there is
|
||||
private float mScreenDarkeningMinThreshold = 0.0f; // no minimum threshold for change in
|
||||
private float mAmbientLuxBrighteningMinThreshold = 0.0f; // screen brightness or ambient
|
||||
private float mAmbientLuxDarkeningMinThreshold = 0.0f; // brightness.
|
||||
private Spline mBrightnessToBacklightSpline;
|
||||
private Spline mBacklightToBrightnessSpline;
|
||||
private Spline mBacklightToNitsSpline;
|
||||
@@ -364,6 +370,22 @@ public class DisplayDeviceConfig {
|
||||
return mAmbientHorizonShort;
|
||||
}
|
||||
|
||||
public float getScreenBrighteningMinThreshold() {
|
||||
return mScreenBrighteningMinThreshold;
|
||||
}
|
||||
|
||||
public float getScreenDarkeningMinThreshold() {
|
||||
return mScreenDarkeningMinThreshold;
|
||||
}
|
||||
|
||||
public float getAmbientLuxBrighteningMinThreshold() {
|
||||
return mAmbientLuxBrighteningMinThreshold;
|
||||
}
|
||||
|
||||
public float getAmbientLuxDarkeningMinThreshold() {
|
||||
return mAmbientLuxDarkeningMinThreshold;
|
||||
}
|
||||
|
||||
SensorData getAmbientLightSensor() {
|
||||
return mAmbientLightSensor;
|
||||
}
|
||||
@@ -425,6 +447,10 @@ public class DisplayDeviceConfig {
|
||||
+ ", mBrightnessRampSlowIncrease=" + mBrightnessRampSlowIncrease
|
||||
+ ", mAmbientHorizonLong=" + mAmbientHorizonLong
|
||||
+ ", mAmbientHorizonShort=" + mAmbientHorizonShort
|
||||
+ ", mScreenDarkeningMinThreshold=" + mScreenDarkeningMinThreshold
|
||||
+ ", mScreenBrighteningMinThreshold=" + mScreenBrighteningMinThreshold
|
||||
+ ", mAmbientLuxDarkeningMinThreshold=" + mAmbientLuxDarkeningMinThreshold
|
||||
+ ", mAmbientLuxBrighteningMinThreshold=" + mAmbientLuxBrighteningMinThreshold
|
||||
+ ", mAmbientLightSensor=" + mAmbientLightSensor
|
||||
+ ", mProximitySensor=" + mProximitySensor
|
||||
+ ", mRefreshRateLimitations= " + Arrays.toString(mRefreshRateLimitations.toArray())
|
||||
@@ -482,6 +508,7 @@ public class DisplayDeviceConfig {
|
||||
loadAmbientLightSensorFromDdc(config);
|
||||
loadProxSensorFromDdc(config);
|
||||
loadAmbientHorizonFromDdc(config);
|
||||
loadBrightnessChangeThresholds(config);
|
||||
} else {
|
||||
Slog.w(TAG, "DisplayDeviceConfig file is null");
|
||||
}
|
||||
@@ -865,6 +892,45 @@ public class DisplayDeviceConfig {
|
||||
}
|
||||
}
|
||||
|
||||
private void loadBrightnessChangeThresholds(DisplayConfiguration config) {
|
||||
Thresholds displayBrightnessThresholds = config.getDisplayBrightnessChangeThresholds();
|
||||
Thresholds ambientBrightnessThresholds = config.getAmbientBrightnessChangeThresholds();
|
||||
|
||||
if (displayBrightnessThresholds != null) {
|
||||
BrightnessThresholds brighteningScreen =
|
||||
displayBrightnessThresholds.getBrighteningThresholds();
|
||||
BrightnessThresholds darkeningScreen =
|
||||
displayBrightnessThresholds.getDarkeningThresholds();
|
||||
|
||||
final BigDecimal screenBrighteningThreshold = brighteningScreen.getMinimum();
|
||||
final BigDecimal screenDarkeningThreshold = darkeningScreen.getMinimum();
|
||||
|
||||
if (screenBrighteningThreshold != null) {
|
||||
mScreenBrighteningMinThreshold = screenBrighteningThreshold.floatValue();
|
||||
}
|
||||
if (screenDarkeningThreshold != null) {
|
||||
mScreenDarkeningMinThreshold = screenDarkeningThreshold.floatValue();
|
||||
}
|
||||
}
|
||||
|
||||
if (ambientBrightnessThresholds != null) {
|
||||
BrightnessThresholds brighteningAmbientLux =
|
||||
ambientBrightnessThresholds.getBrighteningThresholds();
|
||||
BrightnessThresholds darkeningAmbientLux =
|
||||
ambientBrightnessThresholds.getDarkeningThresholds();
|
||||
|
||||
final BigDecimal ambientBrighteningThreshold = brighteningAmbientLux.getMinimum();
|
||||
final BigDecimal ambientDarkeningThreshold = darkeningAmbientLux.getMinimum();
|
||||
|
||||
if (ambientBrighteningThreshold != null) {
|
||||
mAmbientLuxBrighteningMinThreshold = ambientBrighteningThreshold.floatValue();
|
||||
}
|
||||
if (ambientDarkeningThreshold != null) {
|
||||
mAmbientLuxDarkeningMinThreshold = ambientDarkeningThreshold.floatValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private @PowerManager.ThermalStatus int convertThermalStatus(ThermalStatus value) {
|
||||
if (value == null) {
|
||||
return PowerManager.THERMAL_STATUS_NONE;
|
||||
|
||||
@@ -911,9 +911,14 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
com.android.internal.R.array.config_ambientDarkeningThresholds);
|
||||
int[] ambientThresholdLevels = resources.getIntArray(
|
||||
com.android.internal.R.array.config_ambientThresholdLevels);
|
||||
float ambientDarkeningMinThreshold =
|
||||
mDisplayDeviceConfig.getAmbientLuxDarkeningMinThreshold();
|
||||
float ambientBrighteningMinThreshold =
|
||||
mDisplayDeviceConfig.getAmbientLuxBrighteningMinThreshold();
|
||||
HysteresisLevels ambientBrightnessThresholds = new HysteresisLevels(
|
||||
ambientBrighteningThresholds, ambientDarkeningThresholds,
|
||||
ambientThresholdLevels);
|
||||
ambientThresholdLevels, ambientDarkeningMinThreshold,
|
||||
ambientBrighteningMinThreshold);
|
||||
|
||||
int[] screenBrighteningThresholds = resources.getIntArray(
|
||||
com.android.internal.R.array.config_screenBrighteningThresholds);
|
||||
@@ -921,8 +926,13 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
com.android.internal.R.array.config_screenDarkeningThresholds);
|
||||
int[] screenThresholdLevels = resources.getIntArray(
|
||||
com.android.internal.R.array.config_screenThresholdLevels);
|
||||
float screenDarkeningMinThreshold =
|
||||
mDisplayDeviceConfig.getScreenDarkeningMinThreshold();
|
||||
float screenBrighteningMinThreshold =
|
||||
mDisplayDeviceConfig.getScreenBrighteningMinThreshold();
|
||||
HysteresisLevels screenBrightnessThresholds = new HysteresisLevels(
|
||||
screenBrighteningThresholds, screenDarkeningThresholds, screenThresholdLevels);
|
||||
screenBrighteningThresholds, screenDarkeningThresholds, screenThresholdLevels,
|
||||
screenDarkeningMinThreshold, screenBrighteningMinThreshold);
|
||||
|
||||
long brighteningLightDebounce = resources.getInteger(
|
||||
com.android.internal.R.integer.config_autoBrightnessBrighteningLightDebounce);
|
||||
|
||||
@@ -30,17 +30,13 @@ import java.util.Arrays;
|
||||
public class HysteresisLevels {
|
||||
private static final String TAG = "HysteresisLevels";
|
||||
|
||||
// Default hysteresis constraints for brightening or darkening.
|
||||
// The recent value must have changed by at least this fraction relative to the
|
||||
// current value before a change will be considered.
|
||||
private static final float DEFAULT_BRIGHTENING_HYSTERESIS = 0.10f;
|
||||
private static final float DEFAULT_DARKENING_HYSTERESIS = 0.20f;
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private final float[] mBrighteningThresholds;
|
||||
private final float[] mDarkeningThresholds;
|
||||
private final float[] mThresholdLevels;
|
||||
private final float mMinDarkening;
|
||||
private final float mMinBrightening;
|
||||
|
||||
/**
|
||||
* Creates a {@code HysteresisLevels} object with the given equal-length
|
||||
@@ -48,9 +44,12 @@ public class HysteresisLevels {
|
||||
* @param brighteningThresholds an array of brightening hysteresis constraint constants.
|
||||
* @param darkeningThresholds an array of darkening hysteresis constraint constants.
|
||||
* @param thresholdLevels a monotonically increasing array of threshold levels.
|
||||
* @param minBrighteningThreshold the minimum value for which the brightening value needs to
|
||||
* return.
|
||||
* @param minDarkeningThreshold the minimum value for which the darkening value needs to return.
|
||||
*/
|
||||
HysteresisLevels(int[] brighteningThresholds, int[] darkeningThresholds,
|
||||
int[] thresholdLevels) {
|
||||
int[] thresholdLevels, float minDarkeningThreshold, float minBrighteningThreshold) {
|
||||
if (brighteningThresholds.length != darkeningThresholds.length
|
||||
|| darkeningThresholds.length != thresholdLevels.length + 1) {
|
||||
throw new IllegalArgumentException("Mismatch between hysteresis array lengths.");
|
||||
@@ -58,6 +57,8 @@ public class HysteresisLevels {
|
||||
mBrighteningThresholds = setArrayFormat(brighteningThresholds, 1000.0f);
|
||||
mDarkeningThresholds = setArrayFormat(darkeningThresholds, 1000.0f);
|
||||
mThresholdLevels = setArrayFormat(thresholdLevels, 1.0f);
|
||||
mMinDarkening = minDarkeningThreshold;
|
||||
mMinBrightening = minBrighteningThreshold;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,11 +66,13 @@ public class HysteresisLevels {
|
||||
*/
|
||||
public float getBrighteningThreshold(float value) {
|
||||
final float brightConstant = getReferenceLevel(value, mBrighteningThresholds);
|
||||
final float brightThreshold = value * (1.0f + brightConstant);
|
||||
float brightThreshold = value * (1.0f + brightConstant);
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "bright hysteresis constant=" + brightConstant + ", threshold="
|
||||
+ brightThreshold + ", value=" + value);
|
||||
}
|
||||
|
||||
brightThreshold = Math.max(brightThreshold, value + mMinBrightening);
|
||||
return brightThreshold;
|
||||
}
|
||||
|
||||
@@ -78,12 +81,13 @@ public class HysteresisLevels {
|
||||
*/
|
||||
public float getDarkeningThreshold(float value) {
|
||||
final float darkConstant = getReferenceLevel(value, mDarkeningThresholds);
|
||||
final float darkThreshold = value * (1.0f - darkConstant);
|
||||
float darkThreshold = value * (1.0f - darkConstant);
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "dark hysteresis constant=: " + darkConstant + ", threshold="
|
||||
+ darkThreshold + ", value=" + value);
|
||||
}
|
||||
return darkThreshold;
|
||||
darkThreshold = Math.min(darkThreshold, value - mMinDarkening);
|
||||
return Math.max(darkThreshold, 0.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -38,7 +38,8 @@
|
||||
<xs:annotation name="nonnull"/>
|
||||
<xs:annotation name="final"/>
|
||||
</xs:element>
|
||||
<xs:element type="highBrightnessMode" name="highBrightnessMode" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element type="highBrightnessMode" name="highBrightnessMode" minOccurs="0"
|
||||
maxOccurs="1"/>
|
||||
<xs:element type="displayQuirks" name="quirks" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element type="nonNegativeDecimal" name="screenBrightnessRampFastDecrease">
|
||||
<xs:annotation name="final"/>
|
||||
@@ -67,6 +68,19 @@
|
||||
<xs:element type="xs:nonNegativeInteger" name="ambientLightHorizonShort">
|
||||
<xs:annotation name="final"/>
|
||||
</xs:element>
|
||||
|
||||
<!-- Set of thresholds that dictate the change needed for screen brightness
|
||||
adaptations -->
|
||||
<xs:element type="thresholds" name="displayBrightnessChangeThresholds">
|
||||
<xs:annotation name="nonnull"/>
|
||||
<xs:annotation name="final"/>
|
||||
</xs:element>
|
||||
<!-- Set of thresholds that dictate the change needed for ambient brightness
|
||||
adaptations -->
|
||||
<xs:element type="thresholds" name="ambientBrightnessChangeThresholds">
|
||||
<xs:annotation name="nonnull"/>
|
||||
<xs:annotation name="final"/>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
@@ -81,7 +95,8 @@
|
||||
|
||||
<xs:complexType name="highBrightnessMode">
|
||||
<xs:all>
|
||||
<xs:element name="transitionPoint" type="nonNegativeDecimal" minOccurs="1" maxOccurs="1">
|
||||
<xs:element name="transitionPoint" type="nonNegativeDecimal" minOccurs="1"
|
||||
maxOccurs="1">
|
||||
<xs:annotation name="nonnull"/>
|
||||
<xs:annotation name="final"/>
|
||||
</xs:element>
|
||||
@@ -110,7 +125,8 @@
|
||||
|
||||
<xs:complexType name="hbmTiming">
|
||||
<xs:all>
|
||||
<xs:element name="timeWindowSecs" type="xs:nonNegativeInteger" minOccurs="1" maxOccurs="1">
|
||||
<xs:element name="timeWindowSecs" type="xs:nonNegativeInteger" minOccurs="1"
|
||||
maxOccurs="1">
|
||||
<xs:annotation name="nonnull"/>
|
||||
<xs:annotation name="final"/>
|
||||
</xs:element>
|
||||
@@ -216,5 +232,33 @@
|
||||
<xs:annotation name="final"/>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
<!-- Thresholds for brightness changes. -->
|
||||
<xs:complexType name="thresholds">
|
||||
<xs:sequence>
|
||||
<!-- Brightening thresholds. -->
|
||||
<xs:element name="brighteningThresholds" type="brightnessThresholds" minOccurs="0"
|
||||
maxOccurs="1" >
|
||||
<xs:annotation name="nonnull"/>
|
||||
<xs:annotation name="final"/>
|
||||
</xs:element>
|
||||
<!-- Darkening thresholds. -->
|
||||
<xs:element name="darkeningThresholds" type="brightnessThresholds" minOccurs="0"
|
||||
maxOccurs="1" >
|
||||
<xs:annotation name="nonnull"/>
|
||||
<xs:annotation name="final"/>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
<!-- Brightening and darkening minimum change thresholds. -->
|
||||
<xs:complexType name="brightnessThresholds">
|
||||
<!-- Minimum brightness change needed. -->
|
||||
<xs:element name="minimum" type="nonNegativeDecimal" minOccurs="0" maxOccurs="1" >
|
||||
<xs:annotation name="nonnull"/>
|
||||
<xs:annotation name="final"/>
|
||||
</xs:element>
|
||||
</xs:complexType>
|
||||
|
||||
</xs:schema>
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
// Signature format: 2.0
|
||||
package com.android.server.display.config {
|
||||
|
||||
public class BrightnessThresholds {
|
||||
ctor public BrightnessThresholds();
|
||||
method @NonNull public final java.math.BigDecimal getMinimum();
|
||||
method public final void setMinimum(@NonNull java.math.BigDecimal);
|
||||
}
|
||||
|
||||
public class Density {
|
||||
ctor public Density();
|
||||
method @NonNull public final java.math.BigInteger getDensity();
|
||||
@@ -18,9 +24,11 @@ package com.android.server.display.config {
|
||||
|
||||
public class DisplayConfiguration {
|
||||
ctor public DisplayConfiguration();
|
||||
method @NonNull public final com.android.server.display.config.Thresholds getAmbientBrightnessChangeThresholds();
|
||||
method public final java.math.BigInteger getAmbientLightHorizonLong();
|
||||
method public final java.math.BigInteger getAmbientLightHorizonShort();
|
||||
method @Nullable public final com.android.server.display.config.DensityMap getDensityMap();
|
||||
method @NonNull public final com.android.server.display.config.Thresholds getDisplayBrightnessChangeThresholds();
|
||||
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 getProxSensor();
|
||||
@@ -31,9 +39,11 @@ package com.android.server.display.config {
|
||||
method public final java.math.BigDecimal getScreenBrightnessRampFastIncrease();
|
||||
method public final java.math.BigDecimal getScreenBrightnessRampSlowDecrease();
|
||||
method public final java.math.BigDecimal getScreenBrightnessRampSlowIncrease();
|
||||
method public final void setAmbientBrightnessChangeThresholds(@NonNull com.android.server.display.config.Thresholds);
|
||||
method public final void setAmbientLightHorizonLong(java.math.BigInteger);
|
||||
method public final void setAmbientLightHorizonShort(java.math.BigInteger);
|
||||
method public final void setDensityMap(@Nullable com.android.server.display.config.DensityMap);
|
||||
method public final void setDisplayBrightnessChangeThresholds(@NonNull 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 final void setProxSensor(com.android.server.display.config.SensorDetails);
|
||||
@@ -121,6 +131,14 @@ package com.android.server.display.config {
|
||||
enum_constant public static final com.android.server.display.config.ThermalStatus shutdown;
|
||||
}
|
||||
|
||||
public class Thresholds {
|
||||
ctor public Thresholds();
|
||||
method @NonNull public final com.android.server.display.config.BrightnessThresholds getBrighteningThresholds();
|
||||
method @NonNull public final com.android.server.display.config.BrightnessThresholds getDarkeningThresholds();
|
||||
method public final void setBrighteningThresholds(@NonNull com.android.server.display.config.BrightnessThresholds);
|
||||
method public final void setDarkeningThresholds(@NonNull com.android.server.display.config.BrightnessThresholds);
|
||||
}
|
||||
|
||||
public class XmlParser {
|
||||
ctor public XmlParser();
|
||||
method public static com.android.server.display.config.DisplayConfiguration read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
@@ -391,4 +391,33 @@ public class AutomaticBrightnessControllerTest {
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 0));
|
||||
assertEquals(0.0f, mController.getAmbientLux(), EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHysteresisLevels() {
|
||||
int[] ambientBrighteningThresholds = {100, 200};
|
||||
int[] ambientDarkeningThresholds = {400, 500};
|
||||
int[] ambientThresholdLevels = {500};
|
||||
float ambientDarkeningMinChangeThreshold = 3.0f;
|
||||
float ambientBrighteningMinChangeThreshold = 1.5f;
|
||||
HysteresisLevels hysteresisLevels = new HysteresisLevels(ambientBrighteningThresholds,
|
||||
ambientDarkeningThresholds, ambientThresholdLevels,
|
||||
ambientDarkeningMinChangeThreshold, ambientBrighteningMinChangeThreshold);
|
||||
|
||||
// test low, activate minimum change thresholds.
|
||||
assertEquals(1.5f, hysteresisLevels.getBrighteningThreshold(0.0f), EPSILON);
|
||||
assertEquals(0f, hysteresisLevels.getDarkeningThreshold(0.0f), EPSILON);
|
||||
assertEquals(1f, hysteresisLevels.getDarkeningThreshold(4.0f), EPSILON);
|
||||
|
||||
// test max
|
||||
assertEquals(12000f, hysteresisLevels.getBrighteningThreshold(10000.0f), EPSILON);
|
||||
assertEquals(5000f, hysteresisLevels.getDarkeningThreshold(10000.0f), EPSILON);
|
||||
|
||||
// test just below threshold
|
||||
assertEquals(548.9f, hysteresisLevels.getBrighteningThreshold(499f), EPSILON);
|
||||
assertEquals(299.4f, hysteresisLevels.getDarkeningThreshold(499f), EPSILON);
|
||||
|
||||
// test at (considered above) threshold
|
||||
assertEquals(600f, hysteresisLevels.getBrighteningThreshold(500f), EPSILON);
|
||||
assertEquals(250f, hysteresisLevels.getDarkeningThreshold(500f), EPSILON);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user