summaryrefslogtreecommitdiff
path: root/services/java/com/android/server/power/DisplayPowerController.java
diff options
context:
space:
mode:
authorJeff Brown <jeffbrown@google.com>2012-08-16 01:31:11 -0700
committerJeff Brown <jeffbrown@google.com>2012-08-16 01:45:10 -0700
commit1a30b55036c2279d72ba69cb1107ec5f6f40d5e9 (patch)
tree32fd9c82689d3d41703da8eb01880fcbe2aa6f34 /services/java/com/android/server/power/DisplayPowerController.java
parent270e3381e7053c3b15aa8f508c9df9d98032cd62 (diff)
Use spline interpolation for auto-brightness.
Strictly speaking, this is a change in behavior for all products. Instead of using discrete zones, they will all now use spline interpolation. We could make this behavior configurable but there seems to be little point to it. The range of brightness values used will be more or less the same as before, it's just that what used to be the brightness value for all levels within a particular zone now becomes the brightness value for the highest level in that zone and lower values are used for lower levels within the zone. Change-Id: I39804ee630ba55f018e1e53c0576b28e7bd27931
Diffstat (limited to 'services/java/com/android/server/power/DisplayPowerController.java')
-rw-r--r--services/java/com/android/server/power/DisplayPowerController.java82
1 files changed, 46 insertions, 36 deletions
diff --git a/services/java/com/android/server/power/DisplayPowerController.java b/services/java/com/android/server/power/DisplayPowerController.java
index 54e2b574a59c..b0c79fa13d95 100644
--- a/services/java/com/android/server/power/DisplayPowerController.java
+++ b/services/java/com/android/server/power/DisplayPowerController.java
@@ -33,11 +33,11 @@ import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
import android.util.Slog;
+import android.util.Spline;
import android.util.TimeUtils;
import java.io.PrintWriter;
import java.io.StringWriter;
-import java.util.Arrays;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
@@ -98,9 +98,9 @@ final class DisplayPowerController {
// average of light samples. Different constants are used
// to calculate the average light level when adapting to brighter or
// dimmer environments.
- // This parameter only controls the averaging of light samples.
- private static final long BRIGHTENING_LIGHT_TIME_CONSTANT = 1500;
- private static final long DIMMING_LIGHT_TIME_CONSTANT = 3000;
+ // This parameter only controls the filtering of light samples.
+ private static final long BRIGHTENING_LIGHT_TIME_CONSTANT = 500;
+ private static final long DIMMING_LIGHT_TIME_CONSTANT = 2000;
// Stability requirements in milliseconds for accepting a new brightness
// level. This is used for debouncing the light sensor. Different constants
@@ -144,8 +144,7 @@ final class DisplayPowerController {
// Auto-brightness.
private boolean mUseSoftwareAutoBrightnessConfig;
- private int[] mAutoBrightnessLevelsConfig;
- private int[] mAutoBrightnessLcdBacklightValuesConfig;
+ private Spline mScreenAutoBrightnessSpline;
// Amount of time to delay auto-brightness after screen on while waiting for
// the light sensor to warm-up in milliseconds.
@@ -289,17 +288,18 @@ final class DisplayPowerController {
mUseSoftwareAutoBrightnessConfig = resources.getBoolean(
com.android.internal.R.bool.config_automatic_brightness_available);
if (mUseSoftwareAutoBrightnessConfig) {
- mAutoBrightnessLevelsConfig = resources.getIntArray(
+ int[] lux = resources.getIntArray(
com.android.internal.R.array.config_autoBrightnessLevels);
- mAutoBrightnessLcdBacklightValuesConfig = resources.getIntArray(
+ int[] screenBrightness = resources.getIntArray(
com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
- if (mAutoBrightnessLcdBacklightValuesConfig.length
- != mAutoBrightnessLevelsConfig.length + 1) {
+
+ mScreenAutoBrightnessSpline = createAutoBrightnessSpline(lux, screenBrightness);
+ if (mScreenAutoBrightnessSpline == null) {
Slog.e(TAG, "Error in config.xml. config_autoBrightnessLcdBacklightValues "
- + "(size " + mAutoBrightnessLcdBacklightValuesConfig.length + ") "
- + "should have exactly one more entry than "
- + "config_autoBrightnessLevels (size "
- + mAutoBrightnessLevelsConfig.length + "). "
+ + "(size " + screenBrightness.length + ") "
+ + "must be monotic and have exactly one more entry than "
+ + "config_autoBrightnessLevels (size " + lux.length + ") "
+ + "which must be strictly increasing. "
+ "Auto-brightness will be disabled.");
mUseSoftwareAutoBrightnessConfig = false;
}
@@ -322,6 +322,31 @@ final class DisplayPowerController {
}
}
+ private static Spline createAutoBrightnessSpline(int[] lux, int[] brightness) {
+ try {
+ final int n = brightness.length;
+ float[] x = new float[n];
+ float[] y = new float[n];
+ y[0] = brightness[0];
+ for (int i = 1; i < n; i++) {
+ x[i] = lux[i - 1];
+ y[i] = brightness[i];
+ }
+
+ Spline spline = Spline.createMonotoneCubicSpline(x, y);
+ if (false) {
+ Slog.d(TAG, "Auto-brightness spline: " + spline);
+ for (float v = 1f; v < lux[lux.length - 1] * 1.25f; v *= 1.25f) {
+ Slog.d(TAG, String.format(" %7.1f: %7.1f", v, spline.interpolate(v)));
+ }
+ }
+ return spline;
+ } catch (IllegalArgumentException ex) {
+ Slog.e(TAG, "Could not create auto-brightness spline.", ex);
+ return null;
+ }
+ }
+
/**
* Returns true if the proximity sensor screen-off function is available.
*/
@@ -768,13 +793,13 @@ final class DisplayPowerController {
return;
}
- final int newScreenAutoBrightness = mapLuxToBrightness(mLightMeasurement,
- mAutoBrightnessLevelsConfig,
- mAutoBrightnessLcdBacklightValuesConfig);
+ final int newScreenAutoBrightness = interpolateBrightness(
+ mScreenAutoBrightnessSpline, mLightMeasurement);
if (mScreenAutoBrightness != newScreenAutoBrightness) {
if (DEBUG) {
Slog.d(TAG, "updateAutoBrightness: mScreenAutoBrightness="
- + mScreenAutoBrightness);
+ + mScreenAutoBrightness + "newScreenAutoBrightness="
+ + newScreenAutoBrightness);
}
mScreenAutoBrightness = newScreenAutoBrightness;
@@ -784,20 +809,8 @@ final class DisplayPowerController {
}
}
- /**
- * Maps a light sensor measurement in lux to a brightness value given
- * a table of lux breakpoint values and a table of brightnesses that
- * is one element larger.
- */
- private static int mapLuxToBrightness(float lux,
- int[] fromLux, int[] toBrightness) {
- // TODO implement interpolation and possibly range expansion
- int level = 0;
- final int count = fromLux.length;
- while (level < count && lux >= fromLux[level]) {
- level += 1;
- }
- return toBrightness[level];
+ private static int interpolateBrightness(Spline spline, float lux) {
+ return Math.min(255, Math.max(0, (int)Math.round(spline.interpolate(lux))));
}
private void sendOnStateChanged() {
@@ -839,10 +852,7 @@ final class DisplayPowerController {
pw.println(" mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig);
pw.println(" mUseSoftwareAutoBrightnessConfig="
+ mUseSoftwareAutoBrightnessConfig);
- pw.println(" mAutoBrightnessLevelsConfig="
- + Arrays.toString(mAutoBrightnessLevelsConfig));
- pw.println(" mAutoBrightnessLcdBacklightValuesConfig="
- + Arrays.toString(mAutoBrightnessLcdBacklightValuesConfig));
+ pw.println(" mScreenAutoBrightnessSpline=" + mScreenAutoBrightnessSpline);
pw.println(" mLightSensorWarmUpTimeConfig=" + mLightSensorWarmUpTimeConfig);
if (Looper.myLooper() == mHandler.getLooper()) {