From 54a69e7a3b3268bbe50bd12ede542ab42ac4d8fe Mon Sep 17 00:00:00 2001 From: Rupesh Bansal Date: Tue, 18 Oct 2022 11:18:08 +0000 Subject: [PATCH] Making the config_screenThresholdLevels a float array to fix the issue where it was always greater than all possible brightness values config_screenThresholdLevels is an integer array, which is internally compared with brightness in [0.0f,1.0f] to get the right index on which the brightening and darkening thresholds are to be applied. This means no matter what we have in the array, it will always be the first index that will win, and we will always apply the first brightening and darkening thresholds. To keep the settings backward compatible, we still accept the integer array for this threshold, and divide those thresholds with the scale range(255). Bug: 245746705 Bug: 243097291 Test: Manual Test: adb shell dumpsys display | grep HysteresisLevels -A 5 Merged-In: I177d7a1aa48bdfb3385780f0eee7af689755efb4 Change-Id: If5d326e5a32cb436e1d2983dd9185549be76f2e8 --- core/res/res/values/config.xml | 5 ++ .../display/DisplayPowerController.java | 4 +- .../server/display/HysteresisLevels.java | 58 ++++++++++++++++++- 3 files changed, 62 insertions(+), 5 deletions(-) diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 6f83ab169b5fe..689620c13918c 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -1649,6 +1649,11 @@ darkening hysteresis constraint value is the n-th element of config_screenDarkeningThresholds. + Historically, it has been assumed that this will be an integer array with values in the + range of [0, 255]. However, it is now assumed to be a float array with values in the + range of [0, 1]. To accommodate both the possibilities, we internally check the scale on + which the thresholds are defined, and calibrate it accordingly. + The (zero-based) index is calculated as follows: (MAX is the largest index of the array) condition calculated index value < level[0] 0 diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index 070acd0b61835..1514750aff66a 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -975,8 +975,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call com.android.internal.R.array.config_screenBrighteningThresholds); int[] screenDarkeningThresholds = resources.getIntArray( com.android.internal.R.array.config_screenDarkeningThresholds); - int[] screenThresholdLevels = resources.getIntArray( - com.android.internal.R.array.config_screenThresholdLevels); + float[] screenThresholdLevels = BrightnessMappingStrategy.getFloatArray(resources + .obtainTypedArray(com.android.internal.R.array.config_screenThresholdLevels)); float screenDarkeningMinThreshold = mDisplayDeviceConfig.getScreenDarkeningMinThreshold(); float screenBrighteningMinThreshold = diff --git a/services/core/java/com/android/server/display/HysteresisLevels.java b/services/core/java/com/android/server/display/HysteresisLevels.java index 7a932ce6d7cf4..232495ed36409 100644 --- a/services/core/java/com/android/server/display/HysteresisLevels.java +++ b/services/core/java/com/android/server/display/HysteresisLevels.java @@ -39,8 +39,7 @@ public class HysteresisLevels { private final float mMinBrightening; /** - * Creates a {@code HysteresisLevels} object with the given equal-length - * integer arrays. + * Creates a {@code HysteresisLevels} object for ambient brightness. * @param brighteningThresholds an array of brightening hysteresis constraint constants. * @param darkeningThresholds an array of darkening hysteresis constraint constants. * @param thresholdLevels a monotonically increasing array of threshold levels. @@ -61,6 +60,28 @@ public class HysteresisLevels { mMinBrightening = minBrighteningThreshold; } + /** + * Creates a {@code HysteresisLevels} object for screen brightness. + * @param brighteningThresholds an array of brightening hysteresis constraint constants. + * @param darkeningThresholds an array of darkening hysteresis constraint constants. + * @param thresholdLevels a monotonically increasing array of threshold levels. + * @param minBrighteningThreshold the minimum value for which the brightening value needs to + * return. + * @param minDarkeningThreshold the minimum value for which the darkening value needs to return. + */ + HysteresisLevels(int[] brighteningThresholds, int[] darkeningThresholds, + float[] thresholdLevels, float minDarkeningThreshold, float minBrighteningThreshold) { + if (brighteningThresholds.length != darkeningThresholds.length + || darkeningThresholds.length != thresholdLevels.length + 1) { + throw new IllegalArgumentException("Mismatch between hysteresis array lengths."); + } + mBrighteningThresholds = setArrayFormat(brighteningThresholds, 1000.0f); + mDarkeningThresholds = setArrayFormat(darkeningThresholds, 1000.0f); + mThresholdLevels = constraintInRangeIfNeeded(thresholdLevels); + mMinDarkening = minDarkeningThreshold; + mMinBrightening = minBrighteningThreshold; + } + /** * Return the brightening hysteresis threshold for the given value level. */ @@ -107,11 +128,42 @@ public class HysteresisLevels { private float[] setArrayFormat(int[] configArray, float divideFactor) { float[] levelArray = new float[configArray.length]; for (int index = 0; levelArray.length > index; ++index) { - levelArray[index] = (float)configArray[index] / divideFactor; + levelArray[index] = (float) configArray[index] / divideFactor; } return levelArray; } + /** + * This check is due to historical reasons, where screen thresholdLevels used to be + * integer values in the range of [0-255], but then was changed to be float values from [0,1]. + * To accommodate both the possibilities, we first check if all the thresholdLevels are in [0, + * 1], and if not, we divide all the levels with 255 to bring them down to the same scale. + */ + private float[] constraintInRangeIfNeeded(float[] thresholdLevels) { + if (isAllInRange(thresholdLevels, /* minValueInclusive = */ 0.0f, /* maxValueInclusive = */ + 1.0f)) { + return thresholdLevels; + } + + Slog.w(TAG, "Detected screen thresholdLevels on a deprecated brightness scale"); + float[] thresholdLevelsScaled = new float[thresholdLevels.length]; + for (int index = 0; thresholdLevels.length > index; ++index) { + thresholdLevelsScaled[index] = thresholdLevels[index] / 255.0f; + } + return thresholdLevelsScaled; + } + + private boolean isAllInRange(float[] configArray, float minValueInclusive, + float maxValueInclusive) { + int configArraySize = configArray.length; + for (int index = 0; configArraySize > index; ++index) { + if (configArray[index] < minValueInclusive || configArray[index] > maxValueInclusive) { + return false; + } + } + return true; + } + void dump(PrintWriter pw) { pw.println("HysteresisLevels"); pw.println(" mBrighteningThresholds=" + Arrays.toString(mBrighteningThresholds));