summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 a36785f37d3f..86400aa290cf 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1483,6 +1483,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,
@@ -1506,6 +1530,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
@@ -1522,6 +1550,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 faa99027d9ad..96a5098b8f8b 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1902,6 +1902,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" />
@@ -3788,7 +3789,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 5f79f727ca97..7f78cac651dc 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;
@@ -386,8 +387,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
@@ -408,7 +418,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.
@@ -600,7 +610,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;
}
@@ -609,7 +619,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;
@@ -867,9 +878,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);
@@ -920,7 +939,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,
@@ -2143,8 +2162,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;
}
@@ -2296,6 +2315,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))