diff options
10 files changed, 479 insertions, 238 deletions
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index f676052bd425..4f4960ad683e 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -5128,13 +5128,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> @@ -5155,14 +5160,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> diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java index c25b25312c89..e5965eff7070 100644 --- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java +++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java @@ -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(); } } } diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index 4880ea96d5b0..59b887171506 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -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; } } diff --git a/services/core/java/com/android/server/display/DisplayPowerController2.java b/services/core/java/com/android/server/display/DisplayPowerController2.java index ad2b471cd7ed..88fc1fb97dc8 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController2.java +++ b/services/core/java/com/android/server/display/DisplayPowerController2.java @@ -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; } } diff --git a/services/core/java/com/android/server/display/feature/DeviceConfigParameterProvider.java b/services/core/java/com/android/server/display/feature/DeviceConfigParameterProvider.java index dfb5f62f15ab..23ffe5948da8 100644 --- a/services/core/java/com/android/server/display/feature/DeviceConfigParameterProvider.java +++ b/services/core/java/com/android/server/display/feature/DeviceConfigParameterProvider.java @@ -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); - } - - /** Return null if no such property or wrong format (not comma separated integers). */ + public float[] getHighAmbientBrightnessThresholds() { + return DeviceConfigParsingUtils.ambientBrightnessThresholdsIntToFloat( + getIntArrayProperty(DisplayManager.DeviceConfig + .KEY_FIXED_REFRESH_RATE_HIGH_AMBIENT_BRIGHTNESS_THRESHOLDS)); + } + + /** + * 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); - } - - /** Return null if no such property or wrong format (not comma separated integers). */ + public float[] getHighDisplayBrightnessThresholds() { + return DeviceConfigParsingUtils.displayBrightnessThresholdsIntToFloat( + getIntArrayProperty(DisplayManager.DeviceConfig + .KEY_FIXED_REFRESH_RATE_HIGH_DISPLAY_BRIGHTNESS_THRESHOLDS)); + } + + /** + * 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); - } - - /** Return null if no such property or wrong format (not comma separated integers). */ + public float[] getLowDisplayBrightnessThresholds() { + return DeviceConfigParsingUtils.displayBrightnessThresholdsIntToFloat( + getIntArrayProperty(DisplayManager.DeviceConfig + .KEY_FIXED_REFRESH_RATE_LOW_DISPLAY_BRIGHTNESS_THRESHOLDS)); + } + + /** + * 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 */ diff --git a/services/core/java/com/android/server/display/mode/DisplayModeDirector.java b/services/core/java/com/android/server/display/mode/DisplayModeDirector.java index 11e35ce09c28..82755b6a2b9c 100644 --- a/services/core/java/com/android/server/display/mode/DisplayModeDirector.java +++ b/services/core/java/com/android/server/display/mode/DisplayModeDirector.java @@ -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(); diff --git a/services/core/java/com/android/server/display/utils/DeviceConfigParsingUtils.java b/services/core/java/com/android/server/display/utils/DeviceConfigParsingUtils.java index a8034c58689d..a7aee3155477 100644 --- a/services/core/java/com/android/server/display/utils/DeviceConfigParsingUtils.java +++ b/services/core/java/com/android/server/display/utils/DeviceConfigParsingUtils.java @@ -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; + } } diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java index 8b04eca69132..da7a6a10895a 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java @@ -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" + + "<nits>300</nits>\n" + + "</displayBrightnessPoint>\n" + + "<displayBrightnessPoint>\n" + + "<lux>-1</lux>\n" + + "<nits>300</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>-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" + + "<nits>100</nits>\n" + + "</displayBrightnessPoint>\n" + + "<displayBrightnessPoint>\n" + + "<lux>-1</lux>\n" + + "<nits>100</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>-1</nits>\n" + "</displayBrightnessPoint>\n" + "</blockingZoneThreshold>\n" + "</higherBlockingZoneConfigs>\n" diff --git a/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java b/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java index 04273d6f4ed6..15f13cdf9242 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java @@ -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( diff --git a/services/tests/displayservicetests/src/com/android/server/display/utils/DeviceConfigParsingUtilsTest.java b/services/tests/displayservicetests/src/com/android/server/display/utils/DeviceConfigParsingUtilsTest.java index 5e28e63cfa49..83858cf73482 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/utils/DeviceConfigParsingUtilsTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/utils/DeviceConfigParsingUtilsTest.java @@ -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); + } } |