[RESTRICT AUTOMERGE] 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
Bug: 209948220
Test: adb shell dumpsys display
Test: atest AutomaticBrightnessControllerTest

Change-Id: I3af6d754899d75ed51964ed7ad140f1572ec41b0
This commit is contained in:
Fiona Campbell
2022-01-18 14:17:28 +00:00
parent 47461bb5ae
commit 8213786954
5 changed files with 155 additions and 15 deletions

View File

@@ -31,6 +31,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.DisplayConfiguration;
import com.android.server.display.config.DisplayQuirks;
import com.android.server.display.config.HbmTiming;
@@ -40,6 +41,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;
@@ -115,6 +117,10 @@ public class DisplayDeviceConfig {
private float mBrightnessRampFastIncrease = Float.NaN;
private float mBrightnessRampSlowDecrease = Float.NaN;
private float mBrightnessRampSlowIncrease = Float.NaN;
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;
@@ -282,6 +288,22 @@ public class DisplayDeviceConfig {
return mBrightnessRampSlowIncrease;
}
public float getScreenBrighteningMinThreshold() {
return mScreenBrighteningMinThreshold;
}
public float getScreenDarkeningMinThreshold() {
return mScreenDarkeningMinThreshold;
}
public float getAmbientLuxBrighteningMinThreshold() {
return mAmbientLuxBrighteningMinThreshold;
}
public float getAmbientLuxDarkeningMinThreshold() {
return mAmbientLuxDarkeningMinThreshold;
}
SensorData getAmbientLightSensor() {
return mAmbientLightSensor;
}
@@ -337,6 +359,10 @@ public class DisplayDeviceConfig {
+ ", mBrightnessRampFastIncrease=" + mBrightnessRampFastIncrease
+ ", mBrightnessRampSlowDecrease=" + mBrightnessRampSlowDecrease
+ ", mBrightnessRampSlowIncrease=" + mBrightnessRampSlowIncrease
+ ", mScreenDarkeningMinThreshold=" + mScreenDarkeningMinThreshold
+ ", mScreenBrighteningMinThreshold=" + mScreenBrighteningMinThreshold
+ ", mAmbientLuxDarkeningMinThreshold=" + mAmbientLuxDarkeningMinThreshold
+ ", mAmbientLuxBrighteningMinThreshold=" + mAmbientLuxBrighteningMinThreshold
+ ", mAmbientLightSensor=" + mAmbientLightSensor
+ ", mProximitySensor=" + mProximitySensor
+ ", mRefreshRateLimitations= " + Arrays.toString(mRefreshRateLimitations.toArray())
@@ -392,6 +418,7 @@ public class DisplayDeviceConfig {
loadBrightnessRamps(config);
loadAmbientLightSensorFromDdc(config);
loadProxSensorFromDdc(config);
loadBrightnessChangeThresholds(config);
} else {
Slog.w(TAG, "DisplayDeviceConfig file is null");
}
@@ -746,6 +773,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;

View File

@@ -880,9 +880,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);
@@ -890,8 +895,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);

View File

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

View File

@@ -34,7 +34,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"/>
@@ -54,6 +55,19 @@
<xs:element type="sensorDetails" name="proxSensor">
<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>
@@ -68,7 +82,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>
@@ -97,7 +112,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>
@@ -181,5 +197,31 @@
</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>

View File

@@ -1,8 +1,16 @@
// 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 DisplayConfiguration {
ctor public DisplayConfiguration();
method @NonNull public final com.android.server.display.config.Thresholds getAmbientBrightnessChangeThresholds();
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();
@@ -13,6 +21,8 @@ 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 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);
@@ -100,6 +110,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;