Track brightness changes in nits rather than backlight values.
For the moment, the only one that actually knows the true brightness
value is the DisplayPowerController, so have that tell the
BrightnessTracker directly when brightness changes.
Bug: 69405990
Test: atest com.android.server.display.BrightnessTrackerTest
atest com.android.server.display.BrightnessMappingStrategyTest
Change-Id: Ibf4e501ce2f7b071360bfac501dbbafb3ba55fa5
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 2629b12..5105f4e 100644
--- a/services/tests/servicestests/src/com/android/server/display/BrightnessMappingStrategyTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/BrightnessMappingStrategyTest.java
@@ -20,7 +20,13 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyFloat;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
import android.os.PowerManager;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
@@ -35,18 +41,18 @@
@RunWith(AndroidJUnit4.class)
public class BrightnessMappingStrategyTest {
- private static final float[] LUX_LEVELS = {
- 0f,
- 5f,
- 20f,
- 40f,
- 100f,
- 325f,
- 600f,
- 1250f,
- 2200f,
- 4000f,
- 5000f
+ private static final int[] LUX_LEVELS = {
+ 0,
+ 5,
+ 20,
+ 40,
+ 100,
+ 325,
+ 600,
+ 1250,
+ 2200,
+ 4000,
+ 5000
};
private static final float[] DISPLAY_LEVELS_NITS = {
@@ -80,11 +86,13 @@
private static final float[] DISPLAY_RANGE_NITS = { 2.685f, 478.5f };
private static final int[] BACKLIGHT_RANGE = { 1, 255 };
+ private static final float[] EMPTY_FLOAT_ARRAY = new float[0];
+ private static final int[] EMPTY_INT_ARRAY = new int[0];
+
@Test
public void testSimpleStrategyMappingAtControlPoints() {
- BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(
- LUX_LEVELS, DISPLAY_LEVELS_BACKLIGHT,
- null /*brightnessLevelsNits*/, null /*nitsRange*/, null /*backlightRange*/);
+ Resources res = createResources(LUX_LEVELS, DISPLAY_LEVELS_BACKLIGHT);
+ BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(res);
assertNotNull("BrightnessMappingStrategy should not be null", simple);
for (int i = 0; i < LUX_LEVELS.length; i++) {
final float expectedLevel =
@@ -96,9 +104,8 @@
@Test
public void testSimpleStrategyMappingBetweenControlPoints() {
- BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(
- LUX_LEVELS, DISPLAY_LEVELS_BACKLIGHT,
- null /*brightnessLevelsNits*/, null /*nitsRange*/, null /*backlightRange*/);
+ Resources res = createResources(LUX_LEVELS, DISPLAY_LEVELS_BACKLIGHT);
+ BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(res);
assertNotNull("BrightnessMappingStrategy should not be null", simple);
for (int i = 1; i < LUX_LEVELS.length; i++) {
final float lux = (LUX_LEVELS[i - 1] + LUX_LEVELS[i]) / 2;
@@ -111,9 +118,9 @@
@Test
public void testPhysicalStrategyMappingAtControlPoints() {
- BrightnessMappingStrategy physical = BrightnessMappingStrategy.create(
- LUX_LEVELS, null /*brightnessLevelsBacklight*/,
- DISPLAY_LEVELS_NITS, DISPLAY_RANGE_NITS, BACKLIGHT_RANGE);
+ Resources res = createResources(LUX_LEVELS, DISPLAY_LEVELS_NITS,
+ DISPLAY_RANGE_NITS, BACKLIGHT_RANGE);
+ BrightnessMappingStrategy physical = BrightnessMappingStrategy.create(res);
assertNotNull("BrightnessMappingStrategy should not be null", physical);
for (int i = 0; i < LUX_LEVELS.length; i++) {
final float expectedLevel = DISPLAY_LEVELS_NITS[i] / DISPLAY_RANGE_NITS[1];
@@ -124,9 +131,9 @@
@Test
public void testPhysicalStrategyMappingBetweenControlPoints() {
- BrightnessMappingStrategy physical = BrightnessMappingStrategy.create(
- LUX_LEVELS, null /*brightnessLevelsBacklight*/,
- DISPLAY_LEVELS_NITS, DISPLAY_RANGE_NITS, BACKLIGHT_RANGE);
+ Resources res = createResources(LUX_LEVELS, DISPLAY_LEVELS_NITS,
+ DISPLAY_RANGE_NITS, BACKLIGHT_RANGE);
+ BrightnessMappingStrategy physical = BrightnessMappingStrategy.create(res);
assertNotNull("BrightnessMappingStrategy should not be null", physical);
Spline backlightToBrightness =
Spline.createSpline(toFloatArray(BACKLIGHT_RANGE), DISPLAY_RANGE_NITS);
@@ -141,82 +148,79 @@
@Test
public void testDefaultStrategyIsPhysical() {
- BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(
- LUX_LEVELS, DISPLAY_LEVELS_BACKLIGHT,
+ Resources res = createResources(LUX_LEVELS, DISPLAY_LEVELS_BACKLIGHT,
DISPLAY_LEVELS_NITS, DISPLAY_RANGE_NITS, BACKLIGHT_RANGE);
+ BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res);
assertTrue(strategy instanceof BrightnessMappingStrategy.PhysicalMappingStrategy);
}
@Test
public void testNonStrictlyIncreasingLuxLevelsFails() {
- final float[] lux = Arrays.copyOf(LUX_LEVELS, LUX_LEVELS.length);
+ final int[] lux = Arrays.copyOf(LUX_LEVELS, LUX_LEVELS.length);
final int idx = lux.length / 2;
- float tmp = lux[idx];
+ int tmp = lux[idx];
lux[idx] = lux[idx+1];
lux[idx+1] = tmp;
- BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(
- lux, null /*brightnessLevelsBacklight*/,
- DISPLAY_LEVELS_NITS, DISPLAY_RANGE_NITS, BACKLIGHT_RANGE);
+ Resources res = createResources(lux, DISPLAY_LEVELS_NITS,
+ DISPLAY_RANGE_NITS, BACKLIGHT_RANGE);
+ BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res);
assertNull(strategy);
// And make sure we get the same result even if it's monotone but not increasing.
lux[idx] = lux[idx+1];
- strategy = BrightnessMappingStrategy.create(
- lux, null /*brightnessLevelsBacklight*/,
- DISPLAY_LEVELS_NITS, DISPLAY_RANGE_NITS, BACKLIGHT_RANGE);
+ res = createResources(lux, DISPLAY_LEVELS_NITS, DISPLAY_RANGE_NITS, BACKLIGHT_RANGE);
+ strategy = BrightnessMappingStrategy.create(res);
assertNull(strategy);
}
@Test
public void testDifferentNumberOfControlPointValuesFails() {
//Extra lux level
- final float[] lux = Arrays.copyOf(LUX_LEVELS, LUX_LEVELS.length+1);
+ final int[] lux = Arrays.copyOf(LUX_LEVELS, LUX_LEVELS.length+1);
// Make sure it's strictly increasing so that the only failure is the differing array
// lengths
lux[lux.length - 1] = lux[lux.length - 2] + 1;
- BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(
- lux, null /*brightnessLevelsBacklight*/,
- DISPLAY_LEVELS_NITS, DISPLAY_RANGE_NITS, BACKLIGHT_RANGE);
+ Resources res = createResources(lux, DISPLAY_LEVELS_NITS,
+ DISPLAY_RANGE_NITS, BACKLIGHT_RANGE);
+ BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res);
assertNull(strategy);
- strategy = BrightnessMappingStrategy.create(
- lux, DISPLAY_LEVELS_BACKLIGHT,
- null /*brightnessLevelsNits*/, null /*nitsRange*/, null /*backlightRange*/);
+ res = createResources(lux, DISPLAY_LEVELS_BACKLIGHT);
+ strategy = BrightnessMappingStrategy.create(res);
assertNull(strategy);
// Extra backlight level
final int[] backlight = Arrays.copyOf(
DISPLAY_LEVELS_BACKLIGHT, DISPLAY_LEVELS_BACKLIGHT.length+1);
backlight[backlight.length - 1] = backlight[backlight.length - 2] + 1;
- strategy = BrightnessMappingStrategy.create(
- LUX_LEVELS, backlight,
- null /*brightnessLevelsNits*/, null /*nitsRange*/, null /*backlightRange*/);
+ res = createResources(LUX_LEVELS, backlight);
+ strategy = BrightnessMappingStrategy.create(res);
assertNull(strategy);
// Extra nits level
final float[] nits = Arrays.copyOf(DISPLAY_RANGE_NITS, DISPLAY_LEVELS_NITS.length+1);
nits[nits.length - 1] = nits[nits.length - 2] + 1;
- strategy = BrightnessMappingStrategy.create(
- LUX_LEVELS, null /*brightnessLevelsBacklight*/,
- nits, DISPLAY_RANGE_NITS, BACKLIGHT_RANGE);
+ res = createResources(LUX_LEVELS, nits, DISPLAY_RANGE_NITS, BACKLIGHT_RANGE);
+ strategy = BrightnessMappingStrategy.create(res);
assertNull(strategy);
}
@Test
public void testPhysicalStrategyRequiresNitsMapping() {
- BrightnessMappingStrategy physical = BrightnessMappingStrategy.create(
- LUX_LEVELS, null /*brightnessLevelsBacklight*/,
- DISPLAY_LEVELS_NITS, null, BACKLIGHT_RANGE);
+ Resources res = createResources(LUX_LEVELS, EMPTY_INT_ARRAY /*brightnessLevelsBacklight*/,
+ DISPLAY_LEVELS_NITS, EMPTY_FLOAT_ARRAY /*nitsRange*/, BACKLIGHT_RANGE);
+ BrightnessMappingStrategy physical = BrightnessMappingStrategy.create(res);
assertNull(physical);
- physical = BrightnessMappingStrategy.create(
- LUX_LEVELS, null /*brightnessLevelsBacklight*/,
- DISPLAY_LEVELS_NITS, DISPLAY_RANGE_NITS, null);
+ res = createResources(LUX_LEVELS, EMPTY_INT_ARRAY /*brightnessLevelsBacklight*/,
+ DISPLAY_LEVELS_NITS, DISPLAY_RANGE_NITS, EMPTY_INT_ARRAY /*backlightRange*/);
+ physical = BrightnessMappingStrategy.create(res);
assertNull(physical);
- physical = BrightnessMappingStrategy.create(
- LUX_LEVELS, null /*brightnessLevelsBacklight*/,
- DISPLAY_LEVELS_NITS, null, null);
+ res = createResources(LUX_LEVELS, EMPTY_INT_ARRAY /*brightnessLevelsBacklight*/,
+ DISPLAY_LEVELS_NITS, EMPTY_FLOAT_ARRAY /*nitsRange*/,
+ EMPTY_INT_ARRAY /*backlightRange*/);
+ physical = BrightnessMappingStrategy.create(res);
assertNull(physical);
}
@@ -227,4 +231,73 @@
}
return newVals;
}
+
+ private Resources createResources(int[] luxLevels, int[] brightnessLevelsBacklight) {
+ return createResources(luxLevels, brightnessLevelsBacklight,
+ EMPTY_FLOAT_ARRAY /*brightnessLevelsNits*/, EMPTY_FLOAT_ARRAY /*nitsRange*/,
+ EMPTY_INT_ARRAY /*backlightRange*/);
+ }
+
+ private Resources createResources(int[] luxLevels, float[] brightnessLevelsNits,
+ float[] nitsRange, int[] backlightRange) {
+ return createResources(luxLevels, EMPTY_INT_ARRAY /*brightnessLevelsBacklight*/,
+ brightnessLevelsNits, nitsRange, backlightRange);
+ }
+
+ private Resources createResources(int[] luxLevels, int[] brightnessLevelsBacklight,
+ float[] brightnessLevelsNits, float[] nitsRange, int[] backlightRange) {
+ 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);
+
+ when(mockResources.getIntArray(
+ com.android.internal.R.array.config_autoBrightnessLcdBacklightValues))
+ .thenReturn(brightnessLevelsBacklight);
+
+ TypedArray mockBrightnessLevelNits = createFloatTypedArray(brightnessLevelsNits);
+ when(mockResources.obtainTypedArray(
+ com.android.internal.R.array.config_autoBrightnessDisplayValuesNits))
+ .thenReturn(mockBrightnessLevelNits);
+
+ TypedArray mockNitsRange = createFloatTypedArray(nitsRange);
+ when(mockResources.obtainTypedArray(
+ com.android.internal.R.array.config_screenBrightnessNits))
+ .thenReturn(mockNitsRange);
+
+ when(mockResources.getIntArray(
+ com.android.internal.R.array.config_screenBrightnessBacklight))
+ .thenReturn(backlightRange);
+
+ when(mockResources.getInteger(
+ com.android.internal.R.integer.config_screenBrightnessSettingMinimum))
+ .thenReturn(1);
+ when(mockResources.getInteger(
+ com.android.internal.R.integer.config_screenBrightnessSettingMaximum))
+ .thenReturn(255);
+ return mockResources;
+ }
+
+ private TypedArray createFloatTypedArray(float[] vals) {
+ TypedArray mockArray = mock(TypedArray.class);
+ when(mockArray.length()).thenAnswer(invocation -> {
+ return vals.length;
+ });
+ when(mockArray.getFloat(anyInt(), anyFloat())).thenAnswer(invocation -> {
+ final float def = (float) invocation.getArguments()[1];
+ if (vals == null) {
+ return def;
+ }
+ int idx = (int) invocation.getArguments()[0];
+ if (idx >= 0 && idx < vals.length) {
+ return vals[idx];
+ } else {
+ return def;
+ }
+ });
+ return mockArray;
+ }
+
}