Merge "Convert refresh rate blocking zone thresholds from nits" into udc-qpr-dev

This commit is contained in:
Piotr Wilczyński
2023-07-26 10:26:11 +00:00
committed by Android (Google) Code Review
10 changed files with 473 additions and 232 deletions

View File

@@ -5125,13 +5125,18 @@
a threshold.
For example, no higher refresh rate if
display brightness <= disp0 && ambient brightness <= amb0
|| display brightness <= disp1 && ambient brightness <= amb1 -->
|| display brightness <= disp1 && ambient brightness <= amb1
Brightness thresholds are paired with lux thresholds - they both have to be met.
A negative brightness or lux value means that only one threshold should be used - e.g. if
the brightness value is negative, only the lux threshold is applied. -->
<!-- Low zone brightness thresholds in the range [0, 255] -->
<integer-array translatable="false" name="config_brightnessThresholdsOfPeakRefreshRate">
<!--
<item>disp0</item>
<item>disp1</item>
-->
</integer-array>
<!-- Low zone lux thresholds -->
<integer-array translatable="false" name="config_ambientThresholdsOfPeakRefreshRate">
<!--
<item>amb0</item>
@@ -5152,14 +5157,18 @@
may have lower display brightness requirements for the flickering is visible.
For example, fixed refresh rate if
display brightness >= disp0 && ambient brightness >= amb0
|| display brightness >= disp1 && ambient brightness >= amb1 -->
|| display brightness >= disp1 && ambient brightness >= amb1
Brightness thresholds are paired with lux thresholds - they both have to be met.
A negative brightness or lux value means that only one threshold should be used - e.g. if
the brightness value is negative, only the lux threshold is applied. -->
<!-- High zone brightness thresholds in the range [0, 255] -->
<integer-array translatable="false" name="config_highDisplayBrightnessThresholdsOfFixedRefreshRate">
<!--
<item>disp0</item>
<item>disp1</item>
-->
</integer-array>
<!-- High zone lux thresholds -->
<integer-array translatable="false" name="config_highAmbientBrightnessThresholdsOfFixedRefreshRate">
<!--
<item>amb0</item>

View File

@@ -16,6 +16,9 @@
package com.android.server.display;
import static com.android.server.display.utils.DeviceConfigParsingUtils.ambientBrightnessThresholdsIntToFloat;
import static com.android.server.display.utils.DeviceConfigParsingUtils.displayBrightnessThresholdsIntToFloat;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
@@ -475,7 +478,7 @@ public class DisplayDeviceConfig {
private static final int DEFAULT_REFRESH_RATE_IN_HBM = 0;
private static final int DEFAULT_LOW_REFRESH_RATE = 60;
private static final int DEFAULT_HIGH_REFRESH_RATE = 0;
private static final int[] DEFAULT_BRIGHTNESS_THRESHOLDS = new int[]{};
private static final float[] DEFAULT_BRIGHTNESS_THRESHOLDS = new float[]{};
private static final float[] DEFAULT_AMBIENT_THRESHOLD_LEVELS = new float[]{0f};
private static final float[] DEFAULT_AMBIENT_BRIGHTENING_THRESHOLDS = new float[]{100f};
@@ -691,9 +694,14 @@ public class DisplayDeviceConfig {
* prevent flicker, we only support higher refresh rates if the display brightness is above a
* threshold. For example, no higher refresh rate if display brightness <= disp0 && ambient
* brightness <= amb0 || display brightness <= disp1 && ambient brightness <= amb1
*
* Brightness thresholds are paired with lux thresholds - they both have to be met.
*
* A negative brightness or lux value means that only one threshold should be used - e.g. if
* the brightness value is negative, only the lux threshold is applied.
*/
private int[] mLowDisplayBrightnessThresholds = DEFAULT_BRIGHTNESS_THRESHOLDS;
private int[] mLowAmbientBrightnessThresholds = DEFAULT_BRIGHTNESS_THRESHOLDS;
private float[] mLowDisplayBrightnessThresholds = DEFAULT_BRIGHTNESS_THRESHOLDS;
private float[] mLowAmbientBrightnessThresholds = DEFAULT_BRIGHTNESS_THRESHOLDS;
/**
* The display uses different gamma curves for different refresh rates. It's hard for panel
@@ -705,9 +713,14 @@ public class DisplayDeviceConfig {
* have lower display brightness requirements for the flickering is visible. For example, fixed
* refresh rate if display brightness >= disp0 && ambient brightness >= amb0 || display
* brightness >= disp1 && ambient brightness >= amb1
*
* Brightness thresholds are paired with lux thresholds - they both have to be met.
*
* A negative brightness or lux value means that only one threshold should be used - e.g. if
* the brightness value is negative, only the lux threshold is applied.
*/
private int[] mHighDisplayBrightnessThresholds = DEFAULT_BRIGHTNESS_THRESHOLDS;
private int[] mHighAmbientBrightnessThresholds = DEFAULT_BRIGHTNESS_THRESHOLDS;
private float[] mHighDisplayBrightnessThresholds = DEFAULT_BRIGHTNESS_THRESHOLDS;
private float[] mHighAmbientBrightnessThresholds = DEFAULT_BRIGHTNESS_THRESHOLDS;
private final HashMap<String, ThermalBrightnessThrottlingData>
mThermalBrightnessThrottlingDataMapByThrottlingId = new HashMap<>();
@@ -1493,36 +1506,44 @@ public class DisplayDeviceConfig {
/**
* @return An array of lower display brightness thresholds. This, in combination with lower
* ambient brightness thresholds help define buckets in which the refresh rate switching is not
* allowed
* allowed.
*
* A negative threshold value means that only the lux threshold is applied.
*/
public int[] getLowDisplayBrightnessThresholds() {
public float[] getLowDisplayBrightnessThresholds() {
return mLowDisplayBrightnessThresholds;
}
/**
* @return An array of lower ambient brightness thresholds. This, in combination with lower
* display brightness thresholds help define buckets in which the refresh rate switching is not
* allowed
* allowed.
*
* A negative threshold value means that only the display brightness threshold is applied.
*/
public int[] getLowAmbientBrightnessThresholds() {
public float[] getLowAmbientBrightnessThresholds() {
return mLowAmbientBrightnessThresholds;
}
/**
* @return An array of high display brightness thresholds. This, in combination with high
* ambient brightness thresholds help define buckets in which the refresh rate switching is not
* allowed
* allowed.
*
* A negative threshold value means that only the lux threshold is applied.
*/
public int[] getHighDisplayBrightnessThresholds() {
public float[] getHighDisplayBrightnessThresholds() {
return mHighDisplayBrightnessThresholds;
}
/**
* @return An array of high ambient brightness thresholds. This, in combination with high
* display brightness thresholds help define buckets in which the refresh rate switching is not
* allowed
* allowed.
*
* A negative threshold value means that only the display brightness threshold is applied.
*/
public int[] getHighAmbientBrightnessThresholds() {
public float[] getHighAmbientBrightnessThresholds() {
return mHighAmbientBrightnessThresholds;
}
@@ -2144,34 +2165,46 @@ public class DisplayDeviceConfig {
*/
private void loadLowerBrightnessThresholds(BlockingZoneConfig lowerBlockingZoneConfig) {
if (lowerBlockingZoneConfig == null) {
mLowDisplayBrightnessThresholds = mContext.getResources().getIntArray(
int[] lowDisplayBrightnessThresholdsInt = mContext.getResources().getIntArray(
R.array.config_brightnessThresholdsOfPeakRefreshRate);
mLowAmbientBrightnessThresholds = mContext.getResources().getIntArray(
int[] lowAmbientBrightnessThresholdsInt = mContext.getResources().getIntArray(
R.array.config_ambientThresholdsOfPeakRefreshRate);
if (mLowDisplayBrightnessThresholds == null || mLowAmbientBrightnessThresholds == null
|| mLowDisplayBrightnessThresholds.length
!= mLowAmbientBrightnessThresholds.length) {
if (lowDisplayBrightnessThresholdsInt == null
|| lowAmbientBrightnessThresholdsInt == null
|| lowDisplayBrightnessThresholdsInt.length
!= lowAmbientBrightnessThresholdsInt.length) {
throw new RuntimeException("display low brightness threshold array and ambient "
+ "brightness threshold array have different length: "
+ "mLowDisplayBrightnessThresholds="
+ Arrays.toString(mLowDisplayBrightnessThresholds)
+ ", mLowAmbientBrightnessThresholds="
+ Arrays.toString(mLowAmbientBrightnessThresholds));
+ "lowDisplayBrightnessThresholdsInt="
+ Arrays.toString(lowDisplayBrightnessThresholdsInt)
+ ", lowAmbientBrightnessThresholdsInt="
+ Arrays.toString(lowAmbientBrightnessThresholdsInt));
}
mLowDisplayBrightnessThresholds =
displayBrightnessThresholdsIntToFloat(lowDisplayBrightnessThresholdsInt);
mLowAmbientBrightnessThresholds =
ambientBrightnessThresholdsIntToFloat(lowAmbientBrightnessThresholdsInt);
} else {
List<DisplayBrightnessPoint> lowerThresholdDisplayBrightnessPoints =
lowerBlockingZoneConfig.getBlockingZoneThreshold().getDisplayBrightnessPoint();
int size = lowerThresholdDisplayBrightnessPoints.size();
mLowDisplayBrightnessThresholds = new int[size];
mLowAmbientBrightnessThresholds = new int[size];
mLowDisplayBrightnessThresholds = new float[size];
mLowAmbientBrightnessThresholds = new float[size];
for (int i = 0; i < size; i++) {
// We are explicitly casting this value to an integer to be able to reuse the
// existing DisplayBrightnessPoint type. It is fine to do this because the round off
// will have the negligible and unnoticeable impact on the loaded thresholds.
mLowDisplayBrightnessThresholds[i] = (int) lowerThresholdDisplayBrightnessPoints
.get(i).getNits().floatValue();
float thresholdNits = lowerThresholdDisplayBrightnessPoints
.get(i).getNits().floatValue();
if (thresholdNits < 0) {
// A negative value means that there's no threshold
mLowDisplayBrightnessThresholds[i] = thresholdNits;
} else {
float thresholdBacklight = mNitsToBacklightSpline.interpolate(thresholdNits);
mLowDisplayBrightnessThresholds[i] =
mBacklightToBrightnessSpline.interpolate(thresholdBacklight);
}
mLowAmbientBrightnessThresholds[i] = lowerThresholdDisplayBrightnessPoints
.get(i).getLux().intValue();
.get(i).getLux().floatValue();
}
}
}
@@ -2183,34 +2216,46 @@ public class DisplayDeviceConfig {
*/
private void loadHigherBrightnessThresholds(BlockingZoneConfig blockingZoneConfig) {
if (blockingZoneConfig == null) {
mHighDisplayBrightnessThresholds = mContext.getResources().getIntArray(
int[] highDisplayBrightnessThresholdsInt = mContext.getResources().getIntArray(
R.array.config_highDisplayBrightnessThresholdsOfFixedRefreshRate);
mHighAmbientBrightnessThresholds = mContext.getResources().getIntArray(
int[] highAmbientBrightnessThresholdsInt = mContext.getResources().getIntArray(
R.array.config_highAmbientBrightnessThresholdsOfFixedRefreshRate);
if (mHighAmbientBrightnessThresholds == null || mHighDisplayBrightnessThresholds == null
|| mHighAmbientBrightnessThresholds.length
!= mHighDisplayBrightnessThresholds.length) {
if (highDisplayBrightnessThresholdsInt == null
|| highAmbientBrightnessThresholdsInt == null
|| highDisplayBrightnessThresholdsInt.length
!= highAmbientBrightnessThresholdsInt.length) {
throw new RuntimeException("display high brightness threshold array and ambient "
+ "brightness threshold array have different length: "
+ "mHighDisplayBrightnessThresholds="
+ Arrays.toString(mHighDisplayBrightnessThresholds)
+ ", mHighAmbientBrightnessThresholds="
+ Arrays.toString(mHighAmbientBrightnessThresholds));
+ "highDisplayBrightnessThresholdsInt="
+ Arrays.toString(highDisplayBrightnessThresholdsInt)
+ ", highAmbientBrightnessThresholdsInt="
+ Arrays.toString(highAmbientBrightnessThresholdsInt));
}
mHighDisplayBrightnessThresholds =
displayBrightnessThresholdsIntToFloat(highDisplayBrightnessThresholdsInt);
mHighAmbientBrightnessThresholds =
ambientBrightnessThresholdsIntToFloat(highAmbientBrightnessThresholdsInt);
} else {
List<DisplayBrightnessPoint> higherThresholdDisplayBrightnessPoints =
blockingZoneConfig.getBlockingZoneThreshold().getDisplayBrightnessPoint();
int size = higherThresholdDisplayBrightnessPoints.size();
mHighDisplayBrightnessThresholds = new int[size];
mHighAmbientBrightnessThresholds = new int[size];
mHighDisplayBrightnessThresholds = new float[size];
mHighAmbientBrightnessThresholds = new float[size];
for (int i = 0; i < size; i++) {
// We are explicitly casting this value to an integer to be able to reuse the
// existing DisplayBrightnessPoint type. It is fine to do this because the round off
// will have the negligible and unnoticeable impact on the loaded thresholds.
mHighDisplayBrightnessThresholds[i] = (int) higherThresholdDisplayBrightnessPoints
.get(i).getNits().floatValue();
float thresholdNits = higherThresholdDisplayBrightnessPoints
.get(i).getNits().floatValue();
if (thresholdNits < 0) {
// A negative value means that there's no threshold
mHighDisplayBrightnessThresholds[i] = thresholdNits;
} else {
float thresholdBacklight = mNitsToBacklightSpline.interpolate(thresholdNits);
mHighDisplayBrightnessThresholds[i] =
mBacklightToBrightnessSpline.interpolate(thresholdBacklight);
}
mHighAmbientBrightnessThresholds[i] = higherThresholdDisplayBrightnessPoints
.get(i).getLux().intValue();
.get(i).getLux().floatValue();
}
}
}

View File

@@ -1262,7 +1262,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
float userBrightness = BrightnessMappingStrategy.NO_USER_BRIGHTNESS;
if (userNits >= 0) {
userBrightness = mInteractiveModeBrightnessMapper.convertToFloatScale(userNits);
if (userBrightness == PowerManager.BRIGHTNESS_INVALID_FLOAT) {
if (Float.isNaN(userBrightness)) {
userBrightness = BrightnessMappingStrategy.NO_USER_BRIGHTNESS;
}
}

View File

@@ -1083,7 +1083,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
float userBrightness = BrightnessMappingStrategy.NO_USER_BRIGHTNESS;
if (userNits >= 0) {
userBrightness = mInteractiveModeBrightnessMapper.convertToFloatScale(userNits);
if (userBrightness == PowerManager.BRIGHTNESS_INVALID_FLOAT) {
if (Float.isNaN(userBrightness)) {
userBrightness = BrightnessMappingStrategy.NO_USER_BRIGHTNESS;
}
}

View File

@@ -23,6 +23,8 @@ import android.provider.DeviceConfig;
import android.provider.DeviceConfigInterface;
import android.util.Slog;
import com.android.server.display.utils.DeviceConfigParsingUtils;
import java.util.concurrent.Executor;
/**
@@ -102,32 +104,64 @@ public class DeviceConfigParameterProvider {
DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_LOW_ZONE, -1);
}
/** Return null if no such property or wrong format (not comma separated integers). */
/**
* Get the high ambient brightness thresholds for the configured refresh rate zone. The values
* are paired with brightness thresholds.
*
* A negative value means that only the display brightness threshold should be used.
*
* Return null if no such property or wrong format (not comma separated integers).
*/
@Nullable
public int[] getHighAmbientBrightnessThresholds() {
return getIntArrayProperty(DisplayManager.DeviceConfig
.KEY_FIXED_REFRESH_RATE_HIGH_AMBIENT_BRIGHTNESS_THRESHOLDS);
public float[] getHighAmbientBrightnessThresholds() {
return DeviceConfigParsingUtils.ambientBrightnessThresholdsIntToFloat(
getIntArrayProperty(DisplayManager.DeviceConfig
.KEY_FIXED_REFRESH_RATE_HIGH_AMBIENT_BRIGHTNESS_THRESHOLDS));
}
/** Return null if no such property or wrong format (not comma separated integers). */
/**
* Get the high display brightness thresholds for the configured refresh rate zone. The values
* are paired with lux thresholds.
*
* A negative value means that only the ambient threshold should be used.
*
* Return null if no such property or wrong format (not comma separated integers).
*/
@Nullable
public int[] getHighDisplayBrightnessThresholds() {
return getIntArrayProperty(DisplayManager.DeviceConfig
.KEY_FIXED_REFRESH_RATE_HIGH_DISPLAY_BRIGHTNESS_THRESHOLDS);
public float[] getHighDisplayBrightnessThresholds() {
return DeviceConfigParsingUtils.displayBrightnessThresholdsIntToFloat(
getIntArrayProperty(DisplayManager.DeviceConfig
.KEY_FIXED_REFRESH_RATE_HIGH_DISPLAY_BRIGHTNESS_THRESHOLDS));
}
/** Return null if no such property or wrong format (not comma separated integers). */
/**
* Get the low display brightness thresholds for the configured refresh rate zone. The values
* are paired with lux thresholds.
*
* A negative value means that only the ambient threshold should be used.
*
* Return null if no such property or wrong format (not comma separated integers).
*/
@Nullable
public int[] getLowDisplayBrightnessThresholds() {
return getIntArrayProperty(DisplayManager.DeviceConfig
.KEY_FIXED_REFRESH_RATE_LOW_DISPLAY_BRIGHTNESS_THRESHOLDS);
public float[] getLowDisplayBrightnessThresholds() {
return DeviceConfigParsingUtils.displayBrightnessThresholdsIntToFloat(
getIntArrayProperty(DisplayManager.DeviceConfig
.KEY_FIXED_REFRESH_RATE_LOW_DISPLAY_BRIGHTNESS_THRESHOLDS));
}
/** Return null if no such property or wrong format (not comma separated integers). */
/**
* Get the low ambient brightness thresholds for the configured refresh rate zone. The values
* are paired with brightness thresholds.
*
* A negative value means that only the display brightness threshold should be used.
*
* Return null if no such property or wrong format (not comma separated integers).
*/
@Nullable
public int[] getLowAmbientBrightnessThresholds() {
return getIntArrayProperty(DisplayManager.DeviceConfig
.KEY_FIXED_REFRESH_RATE_LOW_AMBIENT_BRIGHTNESS_THRESHOLDS);
public float[] getLowAmbientBrightnessThresholds() {
return DeviceConfigParsingUtils.ambientBrightnessThresholdsIntToFloat(
getIntArrayProperty(DisplayManager.DeviceConfig
.KEY_FIXED_REFRESH_RATE_LOW_AMBIENT_BRIGHTNESS_THRESHOLDS));
}
/** add property change listener to DeviceConfig */

View File

@@ -18,7 +18,7 @@ package com.android.server.display.mode;
import static android.hardware.display.DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED;
import static android.hardware.display.DisplayManagerInternal.REFRESH_RATE_LIMIT_HIGH_BRIGHTNESS_MODE;
import static android.os.PowerManager.BRIGHTNESS_INVALID;
import static android.os.PowerManager.BRIGHTNESS_INVALID_FLOAT;
import android.annotation.IntegerRes;
import android.annotation.NonNull;
@@ -42,6 +42,7 @@ import android.os.IThermalEventListener;
import android.os.IThermalService;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
@@ -72,6 +73,7 @@ import com.android.server.display.DisplayDeviceConfig;
import com.android.server.display.feature.DeviceConfigParameterProvider;
import com.android.server.display.utils.AmbientFilter;
import com.android.server.display.utils.AmbientFilterFactory;
import com.android.server.display.utils.DeviceConfigParsingUtils;
import com.android.server.display.utils.SensorUtils;
import com.android.server.sensors.SensorManagerInternal;
import com.android.server.sensors.SensorManagerInternal.ProximityActiveListener;
@@ -86,6 +88,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.function.Function;
import java.util.function.IntSupplier;
/**
@@ -895,7 +898,7 @@ public class DisplayModeDirector {
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_LOW_BRIGHTNESS_THRESHOLDS_CHANGED: {
Pair<int[], int[]> thresholds = (Pair<int[], int[]>) msg.obj;
Pair<float[], float[]> thresholds = (Pair<float[], float[]>) msg.obj;
mBrightnessObserver.onDeviceConfigLowBrightnessThresholdsChanged(
thresholds.first, thresholds.second);
break;
@@ -909,7 +912,7 @@ public class DisplayModeDirector {
}
case MSG_HIGH_BRIGHTNESS_THRESHOLDS_CHANGED: {
Pair<int[], int[]> thresholds = (Pair<int[], int[]>) msg.obj;
Pair<float[], float[]> thresholds = (Pair<float[], float[]>) msg.obj;
mBrightnessObserver.onDeviceConfigHighBrightnessThresholdsChanged(
thresholds.first, thresholds.second);
@@ -1487,10 +1490,32 @@ public class DisplayModeDirector {
@VisibleForTesting
public class BrightnessObserver implements DisplayManager.DisplayListener {
private static final int LIGHT_SENSOR_RATE_MS = 250;
private int[] mLowDisplayBrightnessThresholds;
private int[] mLowAmbientBrightnessThresholds;
private int[] mHighDisplayBrightnessThresholds;
private int[] mHighAmbientBrightnessThresholds;
/**
* Brightness thresholds for the low zone. Paired with lux thresholds.
*
* A negative value means that only the lux threshold should be applied.
*/
private float[] mLowDisplayBrightnessThresholds;
/**
* Lux thresholds for the low zone. Paired with brightness thresholds.
*
* A negative value means that only the display brightness threshold should be applied.
*/
private float[] mLowAmbientBrightnessThresholds;
/**
* Brightness thresholds for the high zone. Paired with lux thresholds.
*
* A negative value means that only the lux threshold should be applied.
*/
private float[] mHighDisplayBrightnessThresholds;
/**
* Lux thresholds for the high zone. Paired with brightness thresholds.
*
* A negative value means that only the display brightness threshold should be applied.
*/
private float[] mHighAmbientBrightnessThresholds;
// valid threshold if any item from the array >= 0
private boolean mShouldObserveDisplayLowChange;
private boolean mShouldObserveAmbientLowChange;
@@ -1508,7 +1533,8 @@ public class DisplayModeDirector {
// Take it as low brightness before valid sensor data comes
private float mAmbientLux = -1.0f;
private AmbientFilter mAmbientFilter;
private int mBrightness = -1;
private float mBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
private final Context mContext;
private final Injector mInjector;
@@ -1546,22 +1572,22 @@ public class DisplayModeDirector {
}
@VisibleForTesting
int[] getLowDisplayBrightnessThreshold() {
float[] getLowDisplayBrightnessThresholds() {
return mLowDisplayBrightnessThresholds;
}
@VisibleForTesting
int[] getLowAmbientBrightnessThreshold() {
float[] getLowAmbientBrightnessThresholds() {
return mLowAmbientBrightnessThresholds;
}
@VisibleForTesting
int[] getHighDisplayBrightnessThreshold() {
float[] getHighDisplayBrightnessThresholds() {
return mHighDisplayBrightnessThresholds;
}
@VisibleForTesting
int[] getHighAmbientBrightnessThreshold() {
float[] getHighAmbientBrightnessThresholds() {
return mHighAmbientBrightnessThresholds;
}
@@ -1589,12 +1615,14 @@ public class DisplayModeDirector {
() -> mConfigParameterProvider.getLowDisplayBrightnessThresholds(),
() -> displayDeviceConfig.getLowDisplayBrightnessThresholds(),
R.array.config_brightnessThresholdsOfPeakRefreshRate,
displayDeviceConfig, attemptReadFromFeatureParams);
displayDeviceConfig, attemptReadFromFeatureParams,
DeviceConfigParsingUtils::displayBrightnessThresholdsIntToFloat);
mLowAmbientBrightnessThresholds = loadBrightnessThresholds(
() -> mConfigParameterProvider.getLowAmbientBrightnessThresholds(),
() -> displayDeviceConfig.getLowAmbientBrightnessThresholds(),
R.array.config_ambientThresholdsOfPeakRefreshRate,
displayDeviceConfig, attemptReadFromFeatureParams);
displayDeviceConfig, attemptReadFromFeatureParams,
DeviceConfigParsingUtils::ambientBrightnessThresholdsIntToFloat);
if (mLowDisplayBrightnessThresholds.length != mLowAmbientBrightnessThresholds.length) {
throw new RuntimeException("display low brightness threshold array and ambient "
+ "brightness threshold array have different length: "
@@ -1649,12 +1677,14 @@ public class DisplayModeDirector {
() -> mConfigParameterProvider.getHighDisplayBrightnessThresholds(),
() -> displayDeviceConfig.getHighDisplayBrightnessThresholds(),
R.array.config_highDisplayBrightnessThresholdsOfFixedRefreshRate,
displayDeviceConfig, attemptReadFromFeatureParams);
displayDeviceConfig, attemptReadFromFeatureParams,
DeviceConfigParsingUtils::displayBrightnessThresholdsIntToFloat);
mHighAmbientBrightnessThresholds = loadBrightnessThresholds(
() -> mConfigParameterProvider.getHighAmbientBrightnessThresholds(),
() -> displayDeviceConfig.getHighAmbientBrightnessThresholds(),
R.array.config_highAmbientBrightnessThresholdsOfFixedRefreshRate,
displayDeviceConfig, attemptReadFromFeatureParams);
displayDeviceConfig, attemptReadFromFeatureParams,
DeviceConfigParsingUtils::ambientBrightnessThresholdsIntToFloat);
if (mHighDisplayBrightnessThresholds.length
!= mHighAmbientBrightnessThresholds.length) {
throw new RuntimeException("display high brightness threshold array and ambient "
@@ -1666,27 +1696,27 @@ public class DisplayModeDirector {
}
}
private int[] loadBrightnessThresholds(
Callable<int[]> loadFromDeviceConfigDisplaySettingsCallable,
Callable<int[]> loadFromDisplayDeviceConfigCallable,
private float[] loadBrightnessThresholds(
Callable<float[]> loadFromDeviceConfigDisplaySettingsCallable,
Callable<float[]> loadFromDisplayDeviceConfigCallable,
int brightnessThresholdOfFixedRefreshRateKey,
DisplayDeviceConfig displayDeviceConfig, boolean attemptReadFromFeatureParams) {
int[] brightnessThresholds = null;
DisplayDeviceConfig displayDeviceConfig, boolean attemptReadFromFeatureParams,
Function<int[], float[]> conversion) {
float[] brightnessThresholds = null;
if (attemptReadFromFeatureParams) {
try {
brightnessThresholds =
loadFromDeviceConfigDisplaySettingsCallable.call();
brightnessThresholds = loadFromDeviceConfigDisplaySettingsCallable.call();
} catch (Exception exception) {
// Do nothing
}
}
if (brightnessThresholds == null) {
try {
brightnessThresholds =
(displayDeviceConfig == null) ? mContext.getResources().getIntArray(
brightnessThresholdOfFixedRefreshRateKey)
: loadFromDisplayDeviceConfigCallable.call();
brightnessThresholds = displayDeviceConfig == null ? conversion.apply(
mContext.getResources().getIntArray(
brightnessThresholdOfFixedRefreshRateKey)) :
loadFromDisplayDeviceConfigCallable.call();
} catch (Exception e) {
Slog.e(TAG, "Unexpectedly failed to load display brightness threshold");
e.printStackTrace();
@@ -1695,32 +1725,15 @@ public class DisplayModeDirector {
return brightnessThresholds;
}
/**
* @return the display brightness thresholds for the low brightness zones
*/
@VisibleForTesting
int[] getLowDisplayBrightnessThresholds() {
return mLowDisplayBrightnessThresholds;
}
/**
* @return the ambient brightness thresholds for the low brightness zones
*/
@VisibleForTesting
int[] getLowAmbientBrightnessThresholds() {
return mLowAmbientBrightnessThresholds;
}
private void observe(SensorManager sensorManager) {
mSensorManager = sensorManager;
mBrightness = getBrightness(Display.DEFAULT_DISPLAY);
// DeviceConfig is accessible after system ready.
int[] lowDisplayBrightnessThresholds =
float[] lowDisplayBrightnessThresholds =
mConfigParameterProvider.getLowDisplayBrightnessThresholds();
int[] lowAmbientBrightnessThresholds =
float[] lowAmbientBrightnessThresholds =
mConfigParameterProvider.getLowAmbientBrightnessThresholds();
if (lowDisplayBrightnessThresholds != null && lowAmbientBrightnessThresholds != null
&& lowDisplayBrightnessThresholds.length
== lowAmbientBrightnessThresholds.length) {
@@ -1728,11 +1741,10 @@ public class DisplayModeDirector {
mLowAmbientBrightnessThresholds = lowAmbientBrightnessThresholds;
}
int[] highDisplayBrightnessThresholds =
float[] highDisplayBrightnessThresholds =
mConfigParameterProvider.getHighDisplayBrightnessThresholds();
int[] highAmbientBrightnessThresholds =
float[] highAmbientBrightnessThresholds =
mConfigParameterProvider.getHighAmbientBrightnessThresholds();
if (highDisplayBrightnessThresholds != null && highAmbientBrightnessThresholds != null
&& highDisplayBrightnessThresholds.length
== highAmbientBrightnessThresholds.length) {
@@ -1787,8 +1799,8 @@ public class DisplayModeDirector {
}
}
private void onDeviceConfigLowBrightnessThresholdsChanged(int[] displayThresholds,
int[] ambientThresholds) {
private void onDeviceConfigLowBrightnessThresholdsChanged(float[] displayThresholds,
float[] ambientThresholds) {
if (displayThresholds != null && ambientThresholds != null
&& displayThresholds.length == ambientThresholds.length) {
mLowDisplayBrightnessThresholds = displayThresholds;
@@ -1802,12 +1814,14 @@ public class DisplayModeDirector {
() -> mConfigParameterProvider.getLowDisplayBrightnessThresholds(),
() -> displayDeviceConfig.getLowDisplayBrightnessThresholds(),
R.array.config_brightnessThresholdsOfPeakRefreshRate,
displayDeviceConfig, /* attemptReadFromFeatureParams= */ false);
displayDeviceConfig, /* attemptReadFromFeatureParams= */ false,
DeviceConfigParsingUtils::displayBrightnessThresholdsIntToFloat);
mLowAmbientBrightnessThresholds = loadBrightnessThresholds(
() -> mConfigParameterProvider.getLowAmbientBrightnessThresholds(),
() -> displayDeviceConfig.getLowAmbientBrightnessThresholds(),
R.array.config_ambientThresholdsOfPeakRefreshRate,
displayDeviceConfig, /* attemptReadFromFeatureParams= */ false);
displayDeviceConfig, /* attemptReadFromFeatureParams= */ false,
DeviceConfigParsingUtils::ambientBrightnessThresholdsIntToFloat);
}
restartObserver();
}
@@ -1831,8 +1845,8 @@ public class DisplayModeDirector {
}
}
private void onDeviceConfigHighBrightnessThresholdsChanged(int[] displayThresholds,
int[] ambientThresholds) {
private void onDeviceConfigHighBrightnessThresholdsChanged(float[] displayThresholds,
float[] ambientThresholds) {
if (displayThresholds != null && ambientThresholds != null
&& displayThresholds.length == ambientThresholds.length) {
mHighDisplayBrightnessThresholds = displayThresholds;
@@ -1846,12 +1860,14 @@ public class DisplayModeDirector {
() -> mConfigParameterProvider.getLowDisplayBrightnessThresholds(),
() -> displayDeviceConfig.getHighDisplayBrightnessThresholds(),
R.array.config_highDisplayBrightnessThresholdsOfFixedRefreshRate,
displayDeviceConfig, /* attemptReadFromFeatureParams= */ false);
displayDeviceConfig, /* attemptReadFromFeatureParams= */ false,
DeviceConfigParsingUtils::displayBrightnessThresholdsIntToFloat);
mHighAmbientBrightnessThresholds = loadBrightnessThresholds(
() -> mConfigParameterProvider.getHighAmbientBrightnessThresholds(),
() -> displayDeviceConfig.getHighAmbientBrightnessThresholds(),
R.array.config_highAmbientBrightnessThresholdsOfFixedRefreshRate,
displayDeviceConfig, /* attemptReadFromFeatureParams= */ false);
displayDeviceConfig, /* attemptReadFromFeatureParams= */ false,
DeviceConfigParsingUtils::ambientBrightnessThresholdsIntToFloat);
}
restartObserver();
}
@@ -1886,11 +1902,11 @@ public class DisplayModeDirector {
pw.println(" mShouldObserveAmbientLowChange: " + mShouldObserveAmbientLowChange);
pw.println(" mRefreshRateInLowZone: " + mRefreshRateInLowZone);
for (int d : mLowDisplayBrightnessThresholds) {
for (float d : mLowDisplayBrightnessThresholds) {
pw.println(" mDisplayLowBrightnessThreshold: " + d);
}
for (int d : mLowAmbientBrightnessThresholds) {
for (float d : mLowAmbientBrightnessThresholds) {
pw.println(" mAmbientLowBrightnessThreshold: " + d);
}
@@ -1898,11 +1914,11 @@ public class DisplayModeDirector {
pw.println(" mShouldObserveAmbientHighChange: " + mShouldObserveAmbientHighChange);
pw.println(" mRefreshRateInHighZone: " + mRefreshRateInHighZone);
for (int d : mHighDisplayBrightnessThresholds) {
for (float d : mHighDisplayBrightnessThresholds) {
pw.println(" mDisplayHighBrightnessThresholds: " + d);
}
for (int d : mHighAmbientBrightnessThresholds) {
for (float d : mHighAmbientBrightnessThresholds) {
pw.println(" mAmbientHighBrightnessThresholds: " + d);
}
@@ -1931,9 +1947,9 @@ public class DisplayModeDirector {
// We don't support multiple display blocking zones yet, so only handle
// brightness changes for the default display for now.
int brightness = getBrightness(displayId);
float brightness = getBrightness(displayId);
synchronized (mLock) {
if (brightness != mBrightness) {
if (!BrightnessSynchronizer.floatEquals(brightness, mBrightness)) {
mBrightness = brightness;
onBrightnessChangedLocked();
}
@@ -2012,8 +2028,8 @@ public class DisplayModeDirector {
* Checks to see if at least one value is positive, in which case it is necessary to listen
* to value changes.
*/
private boolean hasValidThreshold(int[] a) {
for (int d: a) {
private boolean hasValidThreshold(float[] a) {
for (float d: a) {
if (d >= 0) {
return true;
}
@@ -2022,10 +2038,18 @@ public class DisplayModeDirector {
return false;
}
private boolean isInsideLowZone(int brightness, float lux) {
/**
* Check if we're in the low zone where higher refresh rates aren't allowed to prevent
* flickering.
* @param brightness The brightness value or a negative value meaning that only the lux
* threshold should be applied
* @param lux The lux value. If negative, only the brightness threshold is applied
* @return True if we're in the low zone
*/
private boolean isInsideLowZone(float brightness, float lux) {
for (int i = 0; i < mLowDisplayBrightnessThresholds.length; i++) {
int disp = mLowDisplayBrightnessThresholds[i];
int ambi = mLowAmbientBrightnessThresholds[i];
float disp = mLowDisplayBrightnessThresholds[i];
float ambi = mLowAmbientBrightnessThresholds[i];
if (disp >= 0 && ambi >= 0) {
if (brightness <= disp && lux <= ambi) {
@@ -2045,10 +2069,18 @@ public class DisplayModeDirector {
return false;
}
private boolean isInsideHighZone(int brightness, float lux) {
/**
* Check if we're in the high zone where higher refresh rates aren't allowed to prevent
* flickering.
* @param brightness The brightness value or a negative value meaning that only the lux
* threshold should be applied
* @param lux The lux value. If negative, only the brightness threshold is applied
* @return True if we're in the high zone
*/
private boolean isInsideHighZone(float brightness, float lux) {
for (int i = 0; i < mHighDisplayBrightnessThresholds.length; i++) {
int disp = mHighDisplayBrightnessThresholds[i];
int ambi = mHighAmbientBrightnessThresholds[i];
float disp = mHighDisplayBrightnessThresholds[i];
float ambi = mHighAmbientBrightnessThresholds[i];
if (disp >= 0 && ambi >= 0) {
if (brightness >= disp && lux >= ambi) {
@@ -2075,7 +2107,7 @@ public class DisplayModeDirector {
Vote refreshRateVote = null;
Vote refreshRateSwitchingVote = null;
if (mBrightness < 0) {
if (Float.isNaN(mBrightness)) {
// Either the setting isn't available or we shouldn't be observing yet anyways.
// Either way, just bail out since there's nothing we can do here.
return;
@@ -2191,13 +2223,18 @@ public class DisplayModeDirector {
return mDefaultDisplayState == Display.STATE_ON;
}
private int getBrightness(int displayId) {
/**
* Get the brightness value for a display
* @param displayId The ID of the display
* @return The brightness value
*/
private float getBrightness(int displayId) {
final BrightnessInfo info = mInjector.getBrightnessInfo(displayId);
if (info != null) {
return BrightnessSynchronizer.brightnessFloatToInt(info.adjustedBrightness);
return info.adjustedBrightness;
}
return BRIGHTNESS_INVALID;
return BRIGHTNESS_INVALID_FLOAT;
}
private final class LightSensorEventListener implements SensorEventListener {
@@ -2285,7 +2322,7 @@ public class DisplayModeDirector {
}
}
private boolean isDifferentZone(float lux1, float lux2, int[] luxThresholds) {
private boolean isDifferentZone(float lux1, float lux2, float[] luxThresholds) {
for (final float boundary : luxThresholds) {
// Test each boundary. See if the current value and the new value are at
// different sides.
@@ -2719,9 +2756,9 @@ public class DisplayModeDirector {
mHandler.obtainMessage(MSG_DEFAULT_PEAK_REFRESH_RATE_CHANGED,
defaultPeakRefreshRate == -1 ? null : defaultPeakRefreshRate).sendToTarget();
int[] lowDisplayBrightnessThresholds =
float[] lowDisplayBrightnessThresholds =
mConfigParameterProvider.getLowDisplayBrightnessThresholds();
int[] lowAmbientBrightnessThresholds =
float[] lowAmbientBrightnessThresholds =
mConfigParameterProvider.getLowAmbientBrightnessThresholds();
final int refreshRateInLowZone = mConfigParameterProvider.getRefreshRateInLowZone();
@@ -2732,9 +2769,9 @@ public class DisplayModeDirector {
mHandler.obtainMessage(MSG_REFRESH_RATE_IN_LOW_ZONE_CHANGED, refreshRateInLowZone,
0).sendToTarget();
int[] highDisplayBrightnessThresholds =
float[] highDisplayBrightnessThresholds =
mConfigParameterProvider.getHighDisplayBrightnessThresholds();
int[] highAmbientBrightnessThresholds =
float[] highAmbientBrightnessThresholds =
mConfigParameterProvider.getHighAmbientBrightnessThresholds();
final int refreshRateInHighZone = mConfigParameterProvider.getRefreshRateInHighZone();

View File

@@ -21,6 +21,7 @@ import android.annotation.Nullable;
import android.os.PowerManager;
import android.util.Slog;
import com.android.internal.display.BrightnessSynchronizer;
import com.android.server.display.DisplayDeviceConfig;
import java.util.ArrayList;
@@ -149,4 +150,43 @@ public class DeviceConfigParsingUtils {
}
return value;
}
/**
* Convert display brightness thresholds to a float array.
* @param thresholdsInt The int array of the thresholds in the range [0, 255]
* @return The float array of the thresholds
*/
public static float[] displayBrightnessThresholdsIntToFloat(int[] thresholdsInt) {
if (thresholdsInt == null) {
return null;
}
float[] thresholds = new float[thresholdsInt.length];
for (int i = 0; i < thresholds.length; i++) {
if (thresholdsInt[i] < 0) {
// A negative value means that there's no threshold
thresholds[i] = thresholdsInt[i];
} else {
thresholds[i] = BrightnessSynchronizer.brightnessIntToFloat(thresholdsInt[i]);
}
}
return thresholds;
}
/**
* Convert ambient brightness thresholds to a float array.
* @param thresholdsInt The int array of the thresholds
* @return The float array of the thresholds
*/
public static float[] ambientBrightnessThresholdsIntToFloat(int[] thresholdsInt) {
if (thresholdsInt == null) {
return null;
}
float[] thresholds = new float[thresholdsInt.length];
for (int i = 0; i < thresholds.length; i++) {
thresholds[i] = thresholdsInt[i];
}
return thresholds;
}
}

View File

@@ -17,6 +17,9 @@
package com.android.server.display;
import static com.android.server.display.utils.DeviceConfigParsingUtils.ambientBrightnessThresholdsIntToFloat;
import static com.android.server.display.utils.DeviceConfigParsingUtils.displayBrightnessThresholdsIntToFloat;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -31,6 +34,7 @@ import android.content.res.Resources;
import android.content.res.TypedArray;
import android.os.Temperature;
import android.util.SparseArray;
import android.util.Spline;
import android.view.SurfaceControl;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -63,10 +67,15 @@ public final class DisplayDeviceConfigTest {
private static final int DEFAULT_LOW_BLOCKING_ZONE_REFRESH_RATE = 95;
private static final int DEFAULT_REFRESH_RATE_IN_HBM_HDR = 90;
private static final int DEFAULT_REFRESH_RATE_IN_HBM_SUNLIGHT = 100;
private static final int[] LOW_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE = new int[]{10, 30};
private static final int[] LOW_AMBIENT_THRESHOLD_OF_PEAK_REFRESH_RATE = new int[]{1, 21};
private static final int[] HIGH_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE = new int[]{160};
private static final int[] HIGH_AMBIENT_THRESHOLD_OF_PEAK_REFRESH_RATE = new int[]{30000};
private static final int[] LOW_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE =
new int[]{10, 30, -1};
private static final int[] LOW_AMBIENT_THRESHOLD_OF_PEAK_REFRESH_RATE = new int[]{-1, 1, 21};
private static final int[] HIGH_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE = new int[]{160, -1};
private static final int[] HIGH_AMBIENT_THRESHOLD_OF_PEAK_REFRESH_RATE = new int[]{-1, 30000};
private static final float[] NITS = {2, 500, 800};
private static final float[] BRIGHTNESS = {0, 0.62f, 1};
private static final Spline NITS_TO_BRIGHTNESS_SPLINE =
Spline.createSpline(NITS, BRIGHTNESS);
private DisplayDeviceConfig mDisplayDeviceConfig;
private static final float ZERO_DELTA = 0.0f;
@@ -98,12 +107,9 @@ public final class DisplayDeviceConfigTest {
assertEquals(mDisplayDeviceConfig.getBrightnessRampSlowIncrease(), 0.04f, ZERO_DELTA);
assertEquals(mDisplayDeviceConfig.getBrightnessRampSlowDecrease(), 0.03f, ZERO_DELTA);
assertEquals(mDisplayDeviceConfig.getBrightnessDefault(), 0.5f, ZERO_DELTA);
assertArrayEquals(mDisplayDeviceConfig.getBrightness(), new float[]{0.0f, 0.62f, 1.0f},
ZERO_DELTA);
assertArrayEquals(mDisplayDeviceConfig.getNits(), new float[]{2.0f, 500.0f, 800.0f},
ZERO_DELTA);
assertArrayEquals(mDisplayDeviceConfig.getBacklight(), new float[]{0.0f, 0.62f, 1.0f},
ZERO_DELTA);
assertArrayEquals(mDisplayDeviceConfig.getBrightness(), BRIGHTNESS, ZERO_DELTA);
assertArrayEquals(mDisplayDeviceConfig.getNits(), NITS, ZERO_DELTA);
assertArrayEquals(mDisplayDeviceConfig.getBacklight(), BRIGHTNESS, ZERO_DELTA);
assertEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLightDebounce(), 2000);
assertEquals(mDisplayDeviceConfig.getAutoBrightnessDarkeningLightDebounce(), 1000);
assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(), new
@@ -171,14 +177,6 @@ public final class DisplayDeviceConfigTest {
assertEquals(90, mDisplayDeviceConfig.getRefreshRange("test2").max, SMALL_DELTA);
assertEquals(82, mDisplayDeviceConfig.getDefaultRefreshRateInHbmHdr());
assertEquals(83, mDisplayDeviceConfig.getDefaultRefreshRateInHbmSunlight());
assertArrayEquals(new int[]{45, 55},
mDisplayDeviceConfig.getLowDisplayBrightnessThresholds());
assertArrayEquals(new int[]{50, 60},
mDisplayDeviceConfig.getLowAmbientBrightnessThresholds());
assertArrayEquals(new int[]{65, 75},
mDisplayDeviceConfig.getHighDisplayBrightnessThresholds());
assertArrayEquals(new int[]{70, 80},
mDisplayDeviceConfig.getHighAmbientBrightnessThresholds());
assertEquals("sensor_12345",
mDisplayDeviceConfig.getScreenOffBrightnessSensor().type);
@@ -343,14 +341,6 @@ public final class DisplayDeviceConfigTest {
DEFAULT_REFRESH_RATE_IN_HBM_SUNLIGHT);
assertEquals(mDisplayDeviceConfig.getDefaultRefreshRateInHbmHdr(),
DEFAULT_REFRESH_RATE_IN_HBM_HDR);
assertArrayEquals(mDisplayDeviceConfig.getLowDisplayBrightnessThresholds(),
LOW_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE);
assertArrayEquals(mDisplayDeviceConfig.getLowAmbientBrightnessThresholds(),
LOW_AMBIENT_THRESHOLD_OF_PEAK_REFRESH_RATE);
assertArrayEquals(mDisplayDeviceConfig.getHighDisplayBrightnessThresholds(),
HIGH_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE);
assertArrayEquals(mDisplayDeviceConfig.getHighAmbientBrightnessThresholds(),
HIGH_AMBIENT_THRESHOLD_OF_PEAK_REFRESH_RATE);
// Todo: Add asserts for ThermalBrightnessThrottlingData, DensityMapping,
// HighBrightnessModeData AmbientLightSensor, RefreshRateLimitations and ProximitySensor.
@@ -412,6 +402,42 @@ public final class DisplayDeviceConfigTest {
assertEquals(0.3f, adaptiveOnBrightnessPoints.get(1000f), SMALL_DELTA);
}
@Test
public void testBlockingZoneThresholdsFromDisplayConfig() throws IOException {
setupDisplayDeviceConfigFromDisplayConfigFile();
assertArrayEquals(new float[]{ NITS_TO_BRIGHTNESS_SPLINE.interpolate(50),
NITS_TO_BRIGHTNESS_SPLINE.interpolate(300),
NITS_TO_BRIGHTNESS_SPLINE.interpolate(300), -1},
mDisplayDeviceConfig.getLowDisplayBrightnessThresholds(), SMALL_DELTA);
assertArrayEquals(new float[]{50, 60, -1, 60},
mDisplayDeviceConfig.getLowAmbientBrightnessThresholds(), ZERO_DELTA);
assertArrayEquals(new float[]{ NITS_TO_BRIGHTNESS_SPLINE.interpolate(80),
NITS_TO_BRIGHTNESS_SPLINE.interpolate(100),
NITS_TO_BRIGHTNESS_SPLINE.interpolate(100), -1},
mDisplayDeviceConfig.getHighDisplayBrightnessThresholds(), SMALL_DELTA);
assertArrayEquals(new float[]{70, 80, -1, 80},
mDisplayDeviceConfig.getHighAmbientBrightnessThresholds(), ZERO_DELTA);
}
@Test
public void testBlockingZoneThresholdsFromConfigResource() {
setupDisplayDeviceConfigFromConfigResourceFile();
assertArrayEquals(displayBrightnessThresholdsIntToFloat(
LOW_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE),
mDisplayDeviceConfig.getLowDisplayBrightnessThresholds(), SMALL_DELTA);
assertArrayEquals(ambientBrightnessThresholdsIntToFloat(
LOW_AMBIENT_THRESHOLD_OF_PEAK_REFRESH_RATE),
mDisplayDeviceConfig.getLowAmbientBrightnessThresholds(), ZERO_DELTA);
assertArrayEquals(displayBrightnessThresholdsIntToFloat(
HIGH_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE),
mDisplayDeviceConfig.getHighDisplayBrightnessThresholds(), SMALL_DELTA);
assertArrayEquals(ambientBrightnessThresholdsIntToFloat(
HIGH_AMBIENT_THRESHOLD_OF_PEAK_REFRESH_RATE),
mDisplayDeviceConfig.getHighAmbientBrightnessThresholds(), ZERO_DELTA);
}
private String getValidLuxThrottling() {
return "<luxThrottling>\n"
+ " <brightnessLimitMap>\n"
@@ -525,16 +551,16 @@ public final class DisplayDeviceConfigTest {
+ "<name>Example Display</name>"
+ "<screenBrightnessMap>\n"
+ "<point>\n"
+ "<value>0.0</value>\n"
+ "<nits>2.0</nits>\n"
+ "<value>" + BRIGHTNESS[0] + "</value>\n"
+ "<nits>" + NITS[0] + "</nits>\n"
+ "</point>\n"
+ "<point>\n"
+ "<value>0.62</value>\n"
+ "<nits>500.0</nits>\n"
+ "<value>" + BRIGHTNESS[1] + "</value>\n"
+ "<nits>" + NITS[1] + "</nits>\n"
+ "</point>\n"
+ "<point>\n"
+ "<value>1.0</value>\n"
+ "<nits>800.0</nits>\n"
+ "<value>" + BRIGHTNESS[2] + "</value>\n"
+ "<nits>" + NITS[2] + "</nits>\n"
+ "</point>\n"
+ "</screenBrightnessMap>\n"
+ "<autoBrightness>\n"
@@ -799,13 +825,19 @@ public final class DisplayDeviceConfigTest {
+ "<blockingZoneThreshold>\n"
+ "<displayBrightnessPoint>\n"
+ "<lux>50</lux>\n"
// This number will be rounded to integer when read by the system
+ "<nits>45.3</nits>\n"
+ "<nits>50</nits>\n"
+ "</displayBrightnessPoint>\n"
+ "<displayBrightnessPoint>\n"
+ "<lux>60</lux>\n"
// This number will be rounded to integer when read by the system
+ "<nits>55.2</nits>\n"
+ "<nits>300</nits>\n"
+ "</displayBrightnessPoint>\n"
+ "<displayBrightnessPoint>\n"
+ "<lux>-1</lux>\n"
+ "<nits>300</nits>\n"
+ "</displayBrightnessPoint>\n"
+ "<displayBrightnessPoint>\n"
+ "<lux>60</lux>\n"
+ "<nits>-1</nits>\n"
+ "</displayBrightnessPoint>\n"
+ "</blockingZoneThreshold>\n"
+ "</lowerBlockingZoneConfigs>\n"
@@ -814,13 +846,19 @@ public final class DisplayDeviceConfigTest {
+ "<blockingZoneThreshold>\n"
+ "<displayBrightnessPoint>\n"
+ "<lux>70</lux>\n"
// This number will be rounded to integer when read by the system
+ "<nits>65.6</nits>\n"
+ "<nits>80</nits>\n"
+ "</displayBrightnessPoint>\n"
+ "<displayBrightnessPoint>\n"
+ "<lux>80</lux>\n"
// This number will be rounded to integer when read by the system
+ "<nits>75</nits>\n"
+ "<nits>100</nits>\n"
+ "</displayBrightnessPoint>\n"
+ "<displayBrightnessPoint>\n"
+ "<lux>-1</lux>\n"
+ "<nits>100</nits>\n"
+ "</displayBrightnessPoint>\n"
+ "<displayBrightnessPoint>\n"
+ "<lux>80</lux>\n"
+ "<nits>-1</nits>\n"
+ "</displayBrightnessPoint>\n"
+ "</blockingZoneThreshold>\n"
+ "</higherBlockingZoneConfigs>\n"

View File

@@ -897,10 +897,12 @@ public class DisplayModeDirectorTest {
config.setLowAmbientBrightnessThresholds(initialAmbientThresholds);
director.start(sensorManager);
float[] expectedDisplayThresholds = { BrightnessSynchronizer.brightnessIntToFloat(10) };
float[] expectedAmbientThresholds = { 20 };
assertThat(director.getBrightnessObserver().getLowDisplayBrightnessThresholds())
.isEqualTo(initialDisplayThresholds);
.isEqualTo(expectedDisplayThresholds);
assertThat(director.getBrightnessObserver().getLowAmbientBrightnessThresholds())
.isEqualTo(initialAmbientThresholds);
.isEqualTo(expectedAmbientThresholds);
final int[] updatedDisplayThresholds = { 9, 14 };
final int[] updatedAmbientThresholds = { -1, 19 };
@@ -908,10 +910,14 @@ public class DisplayModeDirectorTest {
config.setLowAmbientBrightnessThresholds(updatedAmbientThresholds);
// Need to wait for the property change to propagate to the main thread.
waitForIdleSync();
expectedDisplayThresholds = new float[]{ BrightnessSynchronizer.brightnessIntToFloat(9),
BrightnessSynchronizer.brightnessIntToFloat(14) };
expectedAmbientThresholds = new float[]{ -1, 19 };
assertThat(director.getBrightnessObserver().getLowDisplayBrightnessThresholds())
.isEqualTo(updatedDisplayThresholds);
.isEqualTo(expectedDisplayThresholds);
assertThat(director.getBrightnessObserver().getLowAmbientBrightnessThresholds())
.isEqualTo(updatedAmbientThresholds);
.isEqualTo(expectedAmbientThresholds);
}
@Test
@@ -2370,14 +2376,14 @@ public class DisplayModeDirectorTest {
assertEquals(director.getBrightnessObserver().getRefreshRateInLowZone(), 85);
assertEquals(director.getHbmObserver().getRefreshRateInHbmHdr(), 95);
assertEquals(director.getHbmObserver().getRefreshRateInHbmSunlight(), 100);
assertArrayEquals(director.getBrightnessObserver().getHighDisplayBrightnessThreshold(),
new int[]{250});
assertArrayEquals(director.getBrightnessObserver().getHighAmbientBrightnessThreshold(),
new int[]{7000});
assertArrayEquals(director.getBrightnessObserver().getLowDisplayBrightnessThreshold(),
new int[]{5});
assertArrayEquals(director.getBrightnessObserver().getLowAmbientBrightnessThreshold(),
new int[]{10});
assertArrayEquals(director.getBrightnessObserver().getHighDisplayBrightnessThresholds(),
new float[]{ BrightnessSynchronizer.brightnessIntToFloat(250) }, /* delta= */ 0);
assertArrayEquals(director.getBrightnessObserver().getHighAmbientBrightnessThresholds(),
new float[]{7000}, /* delta= */ 0);
assertArrayEquals(director.getBrightnessObserver().getLowDisplayBrightnessThresholds(),
new float[]{ BrightnessSynchronizer.brightnessIntToFloat(5) }, /* delta= */ 0);
assertArrayEquals(director.getBrightnessObserver().getLowAmbientBrightnessThresholds(),
new float[]{10}, /* delta= */ 0);
// Notify that the default display is updated, such that DisplayDeviceConfig has new values
@@ -2386,10 +2392,14 @@ public class DisplayModeDirectorTest {
when(displayDeviceConfig.getDefaultHighBlockingZoneRefreshRate()).thenReturn(55);
when(displayDeviceConfig.getDefaultRefreshRate()).thenReturn(60);
when(displayDeviceConfig.getDefaultPeakRefreshRate()).thenReturn(65);
when(displayDeviceConfig.getLowDisplayBrightnessThresholds()).thenReturn(new int[]{25});
when(displayDeviceConfig.getLowAmbientBrightnessThresholds()).thenReturn(new int[]{30});
when(displayDeviceConfig.getHighDisplayBrightnessThresholds()).thenReturn(new int[]{210});
when(displayDeviceConfig.getHighAmbientBrightnessThresholds()).thenReturn(new int[]{2100});
when(displayDeviceConfig.getLowDisplayBrightnessThresholds())
.thenReturn(new float[]{0.025f});
when(displayDeviceConfig.getLowAmbientBrightnessThresholds())
.thenReturn(new float[]{30});
when(displayDeviceConfig.getHighDisplayBrightnessThresholds())
.thenReturn(new float[]{0.21f});
when(displayDeviceConfig.getHighAmbientBrightnessThresholds())
.thenReturn(new float[]{2100});
when(displayDeviceConfig.getDefaultRefreshRateInHbmHdr()).thenReturn(65);
when(displayDeviceConfig.getDefaultRefreshRateInHbmSunlight()).thenReturn(75);
director.defaultDisplayDeviceUpdated(displayDeviceConfig);
@@ -2400,14 +2410,14 @@ public class DisplayModeDirectorTest {
0.0);
assertEquals(director.getBrightnessObserver().getRefreshRateInHighZone(), 55);
assertEquals(director.getBrightnessObserver().getRefreshRateInLowZone(), 50);
assertArrayEquals(director.getBrightnessObserver().getHighDisplayBrightnessThreshold(),
new int[]{210});
assertArrayEquals(director.getBrightnessObserver().getHighAmbientBrightnessThreshold(),
new int[]{2100});
assertArrayEquals(director.getBrightnessObserver().getLowDisplayBrightnessThreshold(),
new int[]{25});
assertArrayEquals(director.getBrightnessObserver().getLowAmbientBrightnessThreshold(),
new int[]{30});
assertArrayEquals(director.getBrightnessObserver().getHighDisplayBrightnessThresholds(),
new float[]{0.21f}, /* delta= */ 0);
assertArrayEquals(director.getBrightnessObserver().getHighAmbientBrightnessThresholds(),
new float[]{2100}, /* delta= */ 0);
assertArrayEquals(director.getBrightnessObserver().getLowDisplayBrightnessThresholds(),
new float[]{0.025f}, /* delta= */ 0);
assertArrayEquals(director.getBrightnessObserver().getLowAmbientBrightnessThresholds(),
new float[]{30}, /* delta= */ 0);
assertEquals(director.getHbmObserver().getRefreshRateInHbmHdr(), 65);
assertEquals(director.getHbmObserver().getRefreshRateInHbmSunlight(), 75);
@@ -2431,14 +2441,14 @@ public class DisplayModeDirectorTest {
0.0);
assertEquals(director.getBrightnessObserver().getRefreshRateInHighZone(), 65);
assertEquals(director.getBrightnessObserver().getRefreshRateInLowZone(), 70);
assertArrayEquals(director.getBrightnessObserver().getHighDisplayBrightnessThreshold(),
new int[]{255});
assertArrayEquals(director.getBrightnessObserver().getHighAmbientBrightnessThreshold(),
new int[]{8000});
assertArrayEquals(director.getBrightnessObserver().getLowDisplayBrightnessThreshold(),
new int[]{10});
assertArrayEquals(director.getBrightnessObserver().getLowAmbientBrightnessThreshold(),
new int[]{20});
assertArrayEquals(director.getBrightnessObserver().getHighDisplayBrightnessThresholds(),
new float[]{ BrightnessSynchronizer.brightnessIntToFloat(255) }, /* delta= */ 0);
assertArrayEquals(director.getBrightnessObserver().getHighAmbientBrightnessThresholds(),
new float[]{8000}, /* delta= */ 0);
assertArrayEquals(director.getBrightnessObserver().getLowDisplayBrightnessThresholds(),
new float[]{ BrightnessSynchronizer.brightnessIntToFloat(10) }, /* delta= */ 0);
assertArrayEquals(director.getBrightnessObserver().getLowAmbientBrightnessThresholds(),
new float[]{20}, /* delta= */ 0);
assertEquals(director.getHbmObserver().getRefreshRateInHbmHdr(), 70);
assertEquals(director.getHbmObserver().getRefreshRateInHbmSunlight(), 80);
@@ -2460,14 +2470,14 @@ public class DisplayModeDirectorTest {
0.0);
assertEquals(director.getBrightnessObserver().getRefreshRateInHighZone(), 55);
assertEquals(director.getBrightnessObserver().getRefreshRateInLowZone(), 50);
assertArrayEquals(director.getBrightnessObserver().getHighDisplayBrightnessThreshold(),
new int[]{210});
assertArrayEquals(director.getBrightnessObserver().getHighAmbientBrightnessThreshold(),
new int[]{2100});
assertArrayEquals(director.getBrightnessObserver().getLowDisplayBrightnessThreshold(),
new int[]{25});
assertArrayEquals(director.getBrightnessObserver().getLowAmbientBrightnessThreshold(),
new int[]{30});
assertArrayEquals(director.getBrightnessObserver().getHighDisplayBrightnessThresholds(),
new float[]{0.21f}, /* delta= */ 0);
assertArrayEquals(director.getBrightnessObserver().getHighAmbientBrightnessThresholds(),
new float[]{2100}, /* delta= */ 0);
assertArrayEquals(director.getBrightnessObserver().getLowDisplayBrightnessThresholds(),
new float[]{0.025f}, /* delta= */ 0);
assertArrayEquals(director.getBrightnessObserver().getLowAmbientBrightnessThresholds(),
new float[]{30}, /* delta= */ 0);
assertEquals(director.getHbmObserver().getRefreshRateInHbmHdr(), 65);
assertEquals(director.getHbmObserver().getRefreshRateInHbmSunlight(), 75);
}
@@ -2503,10 +2513,10 @@ public class DisplayModeDirectorTest {
DisplayDeviceConfig ddcMock = mock(DisplayDeviceConfig.class);
when(ddcMock.getDefaultLowBlockingZoneRefreshRate()).thenReturn(50);
when(ddcMock.getDefaultHighBlockingZoneRefreshRate()).thenReturn(55);
when(ddcMock.getLowDisplayBrightnessThresholds()).thenReturn(new int[]{25});
when(ddcMock.getLowAmbientBrightnessThresholds()).thenReturn(new int[]{30});
when(ddcMock.getHighDisplayBrightnessThresholds()).thenReturn(new int[]{210});
when(ddcMock.getHighAmbientBrightnessThresholds()).thenReturn(new int[]{2100});
when(ddcMock.getLowDisplayBrightnessThresholds()).thenReturn(new float[]{0.025f});
when(ddcMock.getLowAmbientBrightnessThresholds()).thenReturn(new float[]{30});
when(ddcMock.getHighDisplayBrightnessThresholds()).thenReturn(new float[]{0.21f});
when(ddcMock.getHighAmbientBrightnessThresholds()).thenReturn(new float[]{2100});
Resources resMock = mock(Resources.class);
when(resMock.getInteger(

View File

@@ -16,7 +16,9 @@
package com.android.server.display.utils;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
import android.os.PowerManager;
@@ -25,6 +27,7 @@ import android.util.Pair;
import androidx.test.filters.SmallTest;
import com.android.internal.annotations.Keep;
import com.android.internal.display.BrightnessSynchronizer;
import com.android.server.display.DisplayDeviceConfig;
import org.junit.Test;
@@ -158,4 +161,29 @@ public class DeviceConfigParsingUtilsTest {
assertEquals("Brightness value out of bounds: 1.65", result.getMessage());
}
@Test
public void testDisplayBrightnessThresholdsIntToFloat_Null() {
assertNull(DeviceConfigParsingUtils.displayBrightnessThresholdsIntToFloat(null));
}
@Test
public void testDisplayBrightnessThresholdsIntToFloat() {
assertArrayEquals(new float[]{ BrightnessSynchronizer.brightnessIntToFloat(155), -1,
BrightnessSynchronizer.brightnessIntToFloat(170) },
DeviceConfigParsingUtils.displayBrightnessThresholdsIntToFloat(
new int[]{ 155, -1, 170 }), FLOAT_TOLERANCE);
}
@Test
public void testAmbientBrightnessThresholdsIntToFloat_Null() {
assertNull(DeviceConfigParsingUtils.ambientBrightnessThresholdsIntToFloat(null));
}
@Test
public void testAmbientBrightnessThresholdsIntToFloat() {
assertArrayEquals(new float[]{ 1700, 20000, -1 },
DeviceConfigParsingUtils.ambientBrightnessThresholdsIntToFloat(
new int[]{ 1700, 20000, -1 }), FLOAT_TOLERANCE);
}
}