summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Fiona Campbell <flc@google.com> 2021-11-10 16:48:04 +0000
committer Fiona Campbell <flc@google.com> 2021-11-24 17:45:26 +0000
commitf0c4a778b098b4128a679b76b3ec2b9bc94f3e53 (patch)
treecf584e12d88ddd80b7e11502f7eeda932d0aaa0e
parent2f9d26218e83806ae877fb1b5ff64fbadb245801 (diff)
Add idle screen brightness mapping to DPC
Add idle screen brightness nits mapping to config.xml. Also add flag to enable idle screen brightness mode. Add idle screen brightness mapping to DPC dumpsys. Bug: 205685949 Test: adb shell dumpsys display | grep -A10 Idle Test: atest BrightnessMappingStrategyTest Change-Id: Ifa18b835c05c28c060c46c77aeaeca457a2b12e3
-rw-r--r--core/res/res/values/config.xml35
-rw-r--r--core/res/res/values/symbols.xml3
-rw-r--r--services/core/java/com/android/server/display/BrightnessMappingStrategy.java57
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController.java42
-rw-r--r--services/tests/servicestests/src/com/android/server/display/BrightnessMappingStrategyTest.java87
5 files changed, 205 insertions, 19 deletions
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index fceb951a7923..bbc9cdeb7a7f 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1464,6 +1464,30 @@
<integer-array name="config_autoBrightnessLevels">
</integer-array>
+ <!-- Array of light sensor lux values to define our levels for auto backlight brightness
+ support whilst in idle mode.
+ The N entries of this array define N + 1 control points as follows:
+ (1-based arrays)
+
+ Point 1: (0, value[1]): lux <= 0
+ Point 2: (level[1], value[2]): 0 < lux <= level[1]
+ Point 3: (level[2], value[3]): level[2] < lux <= level[3]
+ ...
+ Point N+1: (level[N], value[N+1]): level[N] < lux
+
+ The control points must be strictly increasing. Each control point
+ corresponds to an entry in the brightness backlight values arrays.
+ For example, if lux == level[1] (first element of the levels array)
+ then the brightness will be determined by value[2] (second element
+ of the brightness values array).
+
+ Spline interpolation is used to determine the auto-brightness
+ backlight values for lux levels between these control points.
+
+ Must be overridden in platform specific overlays -->
+ <integer-array name="config_autoBrightnessLevelsIdle">
+ </integer-array>
+
<!-- Timeout (in milliseconds) after which we remove the effects any user interactions might've
had on the brightness mapping. This timeout doesn't start until we transition to a
non-interactive display policy so that we don't reset while users are using their devices,
@@ -1487,6 +1511,10 @@
<integer-array name="config_autoBrightnessLcdBacklightValues_doze">
</integer-array>
+ <!-- Enables idle screen brightness mode on this device.
+ If this is true, config_autoBrightnessDisplayValuesNitsIdle must be defined. -->
+ <bool name="config_enableIdleScreenBrightnessMode">false</bool>
+
<!-- Array of desired screen brightness in nits corresponding to the lux values
in the config_autoBrightnessLevels array. As with config_screenBrightnessMinimumNits and
config_screenBrightnessMaximumNits, the display brightness is defined as the measured
@@ -1503,6 +1531,13 @@
<array name="config_autoBrightnessDisplayValuesNits">
</array>
+ <!-- Array of desired screen brightness in nits for idle screen brightness mode.
+ This array should meet the same requirements as config_autoBrightnessDisplayValuesNits.
+ This array also corresponds to the lux values given in config_autoBrightnessLevelsIdle.
+ In order to activate this mode, config_enableIdleScreenBrightnessMode must be true. -->
+ <array name="config_autoBrightnessDisplayValuesNitsIdle">
+ </array>
+
<!-- Array of output values for button backlight corresponding to the luX values
in the config_autoBrightnessLevels array. This array should have size one greater
than the size of the config_autoBrightnessLevels array.
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index f166b733042f..168e0f135260 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1897,6 +1897,7 @@
<java-symbol type="array" name="config_autoBrightnessLcdBacklightValues" />
<java-symbol type="array" name="config_autoBrightnessLcdBacklightValues_doze" />
<java-symbol type="array" name="config_autoBrightnessLevels" />
+ <java-symbol type="array" name="config_autoBrightnessLevelsIdle" />
<java-symbol type="array" name="config_ambientThresholdLevels" />
<java-symbol type="array" name="config_ambientBrighteningThresholds" />
<java-symbol type="array" name="config_ambientDarkeningThresholds" />
@@ -3782,7 +3783,9 @@
<java-symbol type="bool" name="config_fillMainBuiltInDisplayCutout" />
<java-symbol type="drawable" name="ic_logout" />
+ <java-symbol type="bool" name="config_enableIdleScreenBrightnessMode" />
<java-symbol type="array" name="config_autoBrightnessDisplayValuesNits" />
+ <java-symbol type="array" name="config_autoBrightnessDisplayValuesNitsIdle" />
<java-symbol type="array" name="config_screenBrightnessBacklight" />
<java-symbol type="array" name="config_screenBrightnessNits" />
diff --git a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
index 74a21a733fb9..beb4d5b28d5c 100644
--- a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
+++ b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
@@ -60,17 +60,62 @@ public abstract class BrightnessMappingStrategy {
private static final Plog PLOG = Plog.createSystemPlog(TAG);
+ /**
+ * Creates a BrightnessMappingStrategy for active (normal) mode.
+ * @param resources
+ * @param displayDeviceConfig
+ * @return the BrightnessMappingStrategy
+ */
@Nullable
public static BrightnessMappingStrategy create(Resources resources,
DisplayDeviceConfig displayDeviceConfig) {
+ return create(resources, displayDeviceConfig, /* isForIdleMode= */ false);
+ }
+
+ /**
+ * Creates a BrightnessMappingStrategy for idle screen brightness mode.
+ * @param resources
+ * @param displayDeviceConfig
+ * @return the BrightnessMappingStrategy
+ */
+ @Nullable
+ public static BrightnessMappingStrategy createForIdleMode(Resources resources,
+ DisplayDeviceConfig displayDeviceConfig) {
+ return create(resources, displayDeviceConfig, /* isForIdleMode= */ true);
+ }
+
+ /**
+ * Creates a BrightnessMapping strategy for either active or idle screen brightness mode.
+ * We do not create a simple mapping strategy for idle mode.
+ *
+ * @param resources
+ * @param displayDeviceConfig
+ * @param isForIdleMode determines whether the configurations loaded are for idle screen
+ * brightness mode or active screen brightness mode.
+ * @return the BrightnessMappingStrategy
+ */
+ @Nullable
+ private static BrightnessMappingStrategy create(Resources resources,
+ DisplayDeviceConfig displayDeviceConfig, boolean isForIdleMode) {
+
+ // Display independent, mode dependent values
+ float[] brightnessLevelsNits;
+ float[] luxLevels;
+ if (isForIdleMode) {
+ brightnessLevelsNits = getFloatArray(resources.obtainTypedArray(
+ com.android.internal.R.array.config_autoBrightnessDisplayValuesNitsIdle));
+ luxLevels = getLuxLevels(resources.getIntArray(
+ com.android.internal.R.array.config_autoBrightnessLevelsIdle));
+ } else {
+ brightnessLevelsNits = getFloatArray(resources.obtainTypedArray(
+ com.android.internal.R.array.config_autoBrightnessDisplayValuesNits));
+ luxLevels = getLuxLevels(resources.getIntArray(
+ com.android.internal.R.array.config_autoBrightnessLevels));
+ }
- // Display independent values
- float[] luxLevels = getLuxLevels(resources.getIntArray(
- com.android.internal.R.array.config_autoBrightnessLevels));
+ // Display independent, mode independent values
int[] brightnessLevelsBacklight = resources.getIntArray(
com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
- float[] brightnessLevelsNits = getFloatArray(resources.obtainTypedArray(
- com.android.internal.R.array.config_autoBrightnessDisplayValuesNits));
float autoBrightnessAdjustmentMaxGamma = resources.getFraction(
com.android.internal.R.fraction.config_autoBrightnessAdjustmentMaxGamma,
1, 1);
@@ -91,7 +136,7 @@ public abstract class BrightnessMappingStrategy {
builder.setShortTermModelUpperLuxMultiplier(SHORT_TERM_MODEL_THRESHOLD_RATIO);
return new PhysicalMappingStrategy(builder.build(), nitsRange, brightnessRange,
autoBrightnessAdjustmentMaxGamma);
- } else if (isValidMapping(luxLevels, brightnessLevelsBacklight)) {
+ } else if (isValidMapping(luxLevels, brightnessLevelsBacklight) && !isForIdleMode) {
return new SimpleMappingStrategy(luxLevels, brightnessLevelsBacklight,
autoBrightnessAdjustmentMaxGamma, shortTermModelTimeout);
} else {
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 2f3342f20fcb..8f6d20dfcf96 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -54,6 +54,7 @@ import android.util.Slog;
import android.util.TimeUtils;
import android.view.Display;
+import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IBatteryStats;
import com.android.internal.display.BrightnessSynchronizer;
@@ -384,8 +385,17 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
private Sensor mLightSensor;
// The mapper between ambient lux, display backlight values, and display brightness.
+ // This mapper holds the current one that is being used. We will switch between the idle
+ // mapper and active mapper here.
@Nullable
- private BrightnessMappingStrategy mBrightnessMapper;
+ private BrightnessMappingStrategy mCurrentBrightnessMapper;
+
+ // Mapper used for active (normal) screen brightness mode
+ @Nullable
+ private BrightnessMappingStrategy mInteractiveModeBrightnessMapper;
+ // Mapper used for idle screen brightness mode
+ @Nullable
+ private BrightnessMappingStrategy mIdleModeBrightnessMapper;
// The current brightness configuration.
@Nullable
@@ -406,7 +416,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// The temporary screen brightness. Typically set when a user is interacting with the
// brightness slider but hasn't settled on a choice yet. Set to
- // PowerManager.BRIGHNTESS_INVALID_FLOAT when there's no temporary brightness set.
+ // PowerManager.BRIGHTNESS_INVALID_FLOAT when there's no temporary brightness set.
private float mTemporaryScreenBrightness;
// The current screen brightness while in VR mode.
@@ -595,7 +605,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
}
private void handleRbcChanged(boolean strengthChanged, boolean justActivated) {
- if (mBrightnessMapper == null) {
+ if (mCurrentBrightnessMapper == null) {
Log.w(TAG, "No brightness mapping available to recalculate splines");
return;
}
@@ -604,7 +614,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
for (int i = 0; i < mNitsRange.length; i++) {
adjustedNits[i] = mCdsi.getReduceBrightColorsAdjustedBrightnessNits(mNitsRange[i]);
}
- mBrightnessMapper.recalculateSplines(mCdsi.isReduceBrightColorsActivated(), adjustedNits);
+ mCurrentBrightnessMapper.recalculateSplines(mCdsi.isReduceBrightColorsActivated(),
+ adjustedNits);
mPendingRbcOnOrChanged = strengthChanged || justActivated;
@@ -862,9 +873,17 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
return;
}
- mBrightnessMapper = BrightnessMappingStrategy.create(resources, mDisplayDeviceConfig);
+ final boolean isIdleScreenBrightnessEnabled = resources.getBoolean(
+ R.bool.config_enableIdleScreenBrightnessMode);
+ mInteractiveModeBrightnessMapper = BrightnessMappingStrategy.create(resources,
+ mDisplayDeviceConfig);
+ if (isIdleScreenBrightnessEnabled) {
+ mIdleModeBrightnessMapper = BrightnessMappingStrategy.createForIdleMode(resources,
+ mDisplayDeviceConfig);
+ }
+ mCurrentBrightnessMapper = mInteractiveModeBrightnessMapper;
- if (mBrightnessMapper != null) {
+ if (mCurrentBrightnessMapper != null) {
final float dozeScaleFactor = resources.getFraction(
com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor,
1, 1);
@@ -915,7 +934,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mAutomaticBrightnessController.stop();
}
mAutomaticBrightnessController = new AutomaticBrightnessController(this,
- handler.getLooper(), mSensorManager, mLightSensor, mBrightnessMapper,
+ handler.getLooper(), mSensorManager, mLightSensor, mCurrentBrightnessMapper,
lightSensorWarmUpTimeConfig, PowerManager.BRIGHTNESS_MIN,
PowerManager.BRIGHTNESS_MAX, dozeScaleFactor, lightSensorRate,
initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce,
@@ -2138,8 +2157,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
}
private float convertToNits(float brightness) {
- if (mBrightnessMapper != null) {
- return mBrightnessMapper.convertToNits(brightness);
+ if (mCurrentBrightnessMapper != null) {
+ return mCurrentBrightnessMapper.convertToNits(brightness);
} else {
return -1.0f;
}
@@ -2291,6 +2310,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
pw.println(" mReportedToPolicy=" +
reportedToPolicyToString(mReportedScreenStateToPolicy));
+ if (mIdleModeBrightnessMapper != null) {
+ pw.println(" mIdleModeBrightnessMapper= ");
+ mIdleModeBrightnessMapper.dump(pw);
+ }
+
if (mScreenBrightnessRampAnimator != null) {
pw.println(" mScreenBrightnessRampAnimator.isAnimating()=" +
mScreenBrightnessRampAnimator.isAnimating());
diff --git a/services/tests/servicestests/src/com/android/server/display/BrightnessMappingStrategyTest.java b/services/tests/servicestests/src/com/android/server/display/BrightnessMappingStrategyTest.java
index 285806b5dcd7..c6757261ce42 100644
--- a/services/tests/servicestests/src/com/android/server/display/BrightnessMappingStrategyTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/BrightnessMappingStrategyTest.java
@@ -59,6 +59,20 @@ public class BrightnessMappingStrategyTest {
5000
};
+ private static final int[] LUX_LEVELS_IDLE = {
+ 0,
+ 10,
+ 40,
+ 80,
+ 200,
+ 655,
+ 1200,
+ 2500,
+ 4400,
+ 8000,
+ 10000
+ };
+
private static final float[] DISPLAY_LEVELS_NITS = {
13.25f,
54.0f,
@@ -73,6 +87,20 @@ public class BrightnessMappingStrategyTest {
478.5f,
};
+ private static final float[] DISPLAY_LEVELS_NITS_IDLE = {
+ 23.25f,
+ 64.0f,
+ 88.85f,
+ 115.02f,
+ 142.7f,
+ 180.12f,
+ 222.1f,
+ 275.2f,
+ 345.8f,
+ 425.2f,
+ 468.5f,
+ };
+
private static final int[] DISPLAY_LEVELS_BACKLIGHT = {
9,
30,
@@ -88,7 +116,6 @@ public class BrightnessMappingStrategyTest {
};
private static final float[] DISPLAY_RANGE_NITS = { 2.685f, 478.5f };
- private static final float[] DISPLAY_LEVELS_RANGE_NITS = { 13.25f, 478.5f };
private static final float[] BACKLIGHT_RANGE_ZERO_TO_ONE = { 0.0f, 1.0f };
private static final float[] DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT = { 0.03149606299f, 1.0f };
@@ -118,6 +145,8 @@ public class BrightnessMappingStrategyTest {
new float[] { 0.0f, 100.0f, 1000.0f, 2500.0f, 4000.0f, 4900.0f, 5000.0f },
new float[] { 0.0475f, 0.0475f, 0.2225f, 0.5140f, 0.8056f, 0.9805f, 1.0f });
+ private static final float TOLERANCE = 0.0001f;
+
@Test
public void testSimpleStrategyMappingAtControlPoints() {
Resources res = createResources(LUX_LEVELS, DISPLAY_LEVELS_BACKLIGHT);
@@ -357,6 +386,27 @@ public class BrightnessMappingStrategyTest {
assertStrategyAdaptsToUserDataPoints(BrightnessMappingStrategy.create(res, ddc));
}
+ @Test
+ public void testIdleModeConfigLoadsCorrectly() {
+ Resources res = createResourcesIdle(LUX_LEVELS_IDLE, DISPLAY_LEVELS_NITS_IDLE);
+ DisplayDeviceConfig ddc = createDdc(DISPLAY_RANGE_NITS, BACKLIGHT_RANGE_ZERO_TO_ONE);
+
+ // Create an idle mode bms
+ // This will fail if it tries to fetch the wrong configuration.
+ BrightnessMappingStrategy bms = BrightnessMappingStrategy.createForIdleMode(res, ddc);
+ assertNotNull("BrightnessMappingStrategy should not be null", bms);
+
+ // Ensure that the config is the one we set
+ // Ensure that the lux -> brightness -> nits path works. ()
+ for (int i = 0; i < DISPLAY_LEVELS_NITS_IDLE.length; i++) {
+ assertEquals(LUX_LEVELS_IDLE[i], bms.getDefaultConfig().getCurve().first[i], TOLERANCE);
+ assertEquals(DISPLAY_LEVELS_NITS_IDLE[i], bms.getDefaultConfig().getCurve().second[i],
+ TOLERANCE);
+ assertEquals(bms.convertToNits(bms.getBrightness(LUX_LEVELS_IDLE[i])),
+ DISPLAY_LEVELS_NITS_IDLE[i], TOLERANCE);
+ }
+ }
+
private static void assertStrategyAdaptsToUserDataPoints(BrightnessMappingStrategy strategy) {
// Save out all of the initial brightness data for comparison after reset.
float[] initialBrightnessLevels = new float[LUX_LEVELS.length];
@@ -421,14 +471,39 @@ public class BrightnessMappingStrategyTest {
brightnessLevelsNits);
}
+ private Resources createResourcesIdle(int[] luxLevels, float[] brightnessLevelsNits) {
+ return createResources(EMPTY_INT_ARRAY, EMPTY_INT_ARRAY, EMPTY_FLOAT_ARRAY,
+ luxLevels, brightnessLevelsNits);
+ }
+
private Resources createResources(int[] luxLevels, int[] brightnessLevelsBacklight,
float[] brightnessLevelsNits) {
+ return createResources(luxLevels, brightnessLevelsBacklight, brightnessLevelsNits,
+ EMPTY_INT_ARRAY, EMPTY_FLOAT_ARRAY);
+
+ }
+
+ private Resources createResources(int[] luxLevels, int[] brightnessLevelsBacklight,
+ float[] brightnessLevelsNits, int[] luxLevelsIdle, float[] brightnessLevelsNitsIdle) {
+
Resources mockResources = mock(Resources.class);
+
// For historical reasons, the lux levels resource implicitly defines the first point as 0,
// so we need to chop it off of the array the mock resource object returns.
- int[] luxLevelsResource = Arrays.copyOfRange(luxLevels, 1, luxLevels.length);
- when(mockResources.getIntArray(com.android.internal.R.array.config_autoBrightnessLevels))
- .thenReturn(luxLevelsResource);
+ // Don't mock if these values are not set. If we try to use them, we will fail.
+ if (luxLevels.length > 0) {
+ int[] luxLevelsResource = Arrays.copyOfRange(luxLevels, 1, luxLevels.length);
+ when(mockResources.getIntArray(
+ com.android.internal.R.array.config_autoBrightnessLevels))
+ .thenReturn(luxLevelsResource);
+ }
+ if (luxLevelsIdle.length > 0) {
+ int[] luxLevelsIdleResource = Arrays.copyOfRange(luxLevelsIdle, 1,
+ luxLevelsIdle.length);
+ when(mockResources.getIntArray(
+ com.android.internal.R.array.config_autoBrightnessLevelsIdle))
+ .thenReturn(luxLevelsIdleResource);
+ }
when(mockResources.getIntArray(
com.android.internal.R.array.config_autoBrightnessLcdBacklightValues))
@@ -438,6 +513,10 @@ public class BrightnessMappingStrategyTest {
when(mockResources.obtainTypedArray(
com.android.internal.R.array.config_autoBrightnessDisplayValuesNits))
.thenReturn(mockBrightnessLevelNits);
+ TypedArray mockBrightnessLevelNitsIdle = createFloatTypedArray(brightnessLevelsNitsIdle);
+ when(mockResources.obtainTypedArray(
+ com.android.internal.R.array.config_autoBrightnessDisplayValuesNitsIdle))
+ .thenReturn(mockBrightnessLevelNitsIdle);
when(mockResources.getInteger(
com.android.internal.R.integer.config_screenBrightnessSettingMinimum))