Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Backlight settings, preliminary, but works

based on CM9 code

Change-Id: Iddcbee98f6588bba428c4059e786d946d7ce2298
  • Loading branch information...
commit a790e784e173e513db20423a9a4609c2ee195139 1 parent d40edab
@tpruvot tpruvot authored Whitehawkx committed
View
7 core/java/android/os/IPowerManager.aidl
@@ -46,4 +46,11 @@ interface IPowerManager
void setBacklightBrightness(int brightness);
void setAttentionLight(boolean on, int color);
void setAutoBrightnessAdjustment(float adj);
+
+ // custom backlight things
+ int getLightSensorValue();
+ int getRawLightSensorValue();
+ int getLightSensorScreenBrightness();
+ int getLightSensorButtonBrightness();
+ int getLightSensorKeyboardBrightness();
}
View
130 core/java/android/provider/Settings.java
@@ -1469,6 +1469,136 @@ public static void setShowGTalkServiceStatus(ContentResolver cr, boolean flag) {
public static final int SCREEN_BRIGHTNESS_MODE_AUTOMATIC = 1;
/**
+ * Indicates that custom light sensor settings has changed. The value is
+ * random and changes reloads light settings.
+ *
+ * @hide
+ */
+ public static final String LIGHTS_CHANGED = "lights_changed";
+
+ /**
+ * Whether custom light sensor levels & values are enabled. The value is
+ * boolean (1 or 0).
+ *
+ * @hide
+ */
+ public static final String LIGHT_SENSOR_CUSTOM = "light_sensor_custom";
+
+ /**
+ * Screen dim value to use if LIGHT_SENSOR_CUSTOM is set. The value is int.
+ * Default is android.os.BRIGHTNESS_DIM.
+ *
+ * @hide
+ */
+ public static final String LIGHT_SCREEN_DIM = "light_screen_dim";
+
+ /**
+ * Custom light sensor levels. The value is a comma separated int array
+ * with length N.
+ * Example: "100,300,3000".
+ *
+ * @hide
+ */
+ public static final String LIGHT_SENSOR_LEVELS = "light_sensor_levels";
+
+ /**
+ * Custom light sensor lcd values. The value is a comma separated int array
+ * with length N+1.
+ * Example: "10,50,100,255".
+ *
+ * @hide
+ */
+ public static final String LIGHT_SENSOR_LCD_VALUES = "light_sensor_lcd_values";
+
+ /**
+ * Custom light sensor lcd values. The value is a comma separated int array
+ * with length N+1.
+ * Example: "10,50,100,255".
+ *
+ * @hide
+ */
+ public static final String LIGHT_SENSOR_BUTTON_VALUES = "light_sensor_button_values";
+
+ /**
+ * Custom light sensor lcd values. The value is a comma separated int array
+ * with length N+1.
+ * Example: "10,50,100,255".
+ *
+ * @hide
+ */
+ public static final String LIGHT_SENSOR_KEYBOARD_VALUES = "light_sensor_keyboard_values";
+
+ /**
+ * Whether light sensor is allowed to decrease when calculating automatic
+ * backlight. The value is boolean (1 or 0).
+ *
+ * @hide
+ */
+ public static final String LIGHT_DECREASE = "light_decrease";
+
+ /**
+ * Light sensor hysteresis for decreasing backlight. The value is
+ * int (0-99) representing % (0-0.99 as float). Example:
+ *
+ * Levels Output
+ * 0 - 100 50
+ * 100 - 200 100
+ * 200 - Inf 255
+ *
+ * Current sensor value is 150 which gives light value 100. Hysteresis is 50.
+ * Current level lower bound is 100 and previous lower bound is 0.
+ * Sensor value must drop below 100-(100-0)*(50/100)=50 for output to become 50
+ * (corresponding to the 0 - 100 level).
+ * @hide
+ */
+ public static final String LIGHT_HYSTERESIS = "light_hysteresis";
+
+ /**
+ * Whether light sensor used when calculating automatic backlight should
+ * be filtered through an moving average filter.
+ * The value is boolean (1 or 0).
+ *
+ * @hide
+ */
+ public static final String LIGHT_FILTER = "light_filter";
+
+ /**
+ * Window length of filter used when calculating automatic backlight.
+ * One minute means that the average sensor value last minute is used.
+ * The value is integer (milliseconds)
+ *
+ * @hide
+ */
+ public static final String LIGHT_FILTER_WINDOW = "light_filter_window";
+
+ /**
+ * Reset threshold of filter used when calculating automatic backlight.
+ * Sudden large jumps in sensor value resets the filter. This is used
+ * to make the filter respond quickly to large enough changes in input
+ * while still filtering small changes. Example:
+ *
+ * Current filter value (average) is 100 and sensor value is changing to
+ * 10, 150, 100, 30, 50. The filter is continously taking the average of
+ * the samples. Now the user goes outside and the value jumps over 1000.
+ * The difference between current average and new sample is larger than
+ * the reset threshold and filter is reset. It begins calculating a new
+ * average on samples around 1000 (say, 800, 1200, 1000, 1100 etc.)
+ *
+ * The value is integer (lux)
+ *
+ * @hide
+ */
+ public static final String LIGHT_FILTER_RESET = "light_filter_reset";
+
+ /**
+ * Sample interval of filter used when calculating automatic backlight.
+ * The value is integer (milliseconds)
+ *
+ * @hide
+ */
+ public static final String LIGHT_FILTER_INTERVAL = "light_filter_interval";
+
+ /**
* Control whether the process CPU usage meter should be shown.
*/
public static final String SHOW_PROCESSES = "show_processes";
View
477 services/java/com/android/server/PowerManagerService.java
@@ -55,6 +55,7 @@
import android.os.WorkSource;
import android.os.SystemProperties;
import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
import android.util.EventLog;
import android.util.Log;
import android.util.Slog;
@@ -85,6 +86,7 @@
private static final int NOMINAL_FRAME_TIME_MS = 1000/60;
private static final String TAG = "PowerManagerService";
+ private static final String TAGF = "LightFilter";
static final String PARTIAL_NAME = "PowerManagerService";
// Wake lock that ensures that the CPU is running. The screen might not be on.
@@ -307,6 +309,36 @@
private static final int ANIM_SETTING_ON = 0x01;
private static final int ANIM_SETTING_OFF = 0x10;
+ // Custom light housekeeping
+ private long mLightSettingsTag = -1;
+
+ // Light sensor levels / values
+ private boolean mLightDecrease;
+ private float mLightHysteresis;
+ private boolean mCustomLightEnabled;
+ private int[] mCustomLightLevels;
+ private int[] mCustomLcdValues;
+ private int[] mCustomButtonValues;
+ private int[] mCustomKeyboardValues;
+ private int mLastLcdValue;
+ private int mLastButtonValue;
+ private int mLastKeyboardValue;
+ private int mScreenDim = PowerManager.BRIGHTNESS_DIM;
+ private boolean mAlwaysOnAndDimmed;
+
+ // Light sensor filter, times in milliseconds
+ private boolean mLightFilterEnabled;
+ private boolean mLightFilterRunning;
+ private int mLightFilterSample = -1;
+ private int[] mLightFilterSamples;
+ private int mLightFilterIndex;
+ private int mLightFilterSampleCounter;
+ private int mLightFilterSum;
+ private int mLightFilterEqualCounter;
+ private int mLightFilterWindow;
+ private int mLightFilterInterval;
+ private int mLightFilterReset;
+
// Used when logging number and duration of touch-down cycles
private long mTotalTouchDownTime;
private long mLastTouchDown;
@@ -521,6 +553,7 @@ public void update(Observable o, Object arg) {
mScreenBrightnessSetting = getInt(SCREEN_BRIGHTNESS, DEFAULT_SCREEN_BRIGHTNESS);
mLightSensorAdjustSetting = 0; //getFloat(SCREEN_AUTO_BRIGHTNESS_ADJ, 0);
+ updateLightSettings();
// SCREEN_BRIGHTNESS_MODE, default to manual
setScreenBrightnessMode(getInt(SCREEN_BRIGHTNESS_MODE,
@@ -681,7 +714,7 @@ void initInThread() {
+ Settings.System.NAME + "=?)",
new String[]{STAY_ON_WHILE_PLUGGED_IN, SCREEN_OFF_TIMEOUT, DIM_SCREEN, SCREEN_BRIGHTNESS,
SCREEN_BRIGHTNESS_MODE, /*SCREEN_AUTO_BRIGHTNESS_ADJ,*/
- WINDOW_ANIMATION_SCALE, TRANSITION_ANIMATION_SCALE},
+ WINDOW_ANIMATION_SCALE, TRANSITION_ANIMATION_SCALE, Settings.System.LIGHTS_CHANGED},
null);
mSettings = new ContentQueryMap(settingsCursor, Settings.System.NAME, true, mHandler);
SettingsObserver settingsObserver = new SettingsObserver();
@@ -1798,6 +1831,13 @@ private int setScreenStateLocked(boolean on) {
// make sure button and key backlights are off too
mButtonLight.turnOff();
mKeyboardLight.turnOff();
+ // clear current value so we will update based on the new conditions
+ // when the sensor is reenabled.
+ mLightSensorValue = -1;
+ // reset our highest light sensor value when the screen turns off
+ mHighestLightSensorValue = -1;
+ lightFilterStop();
+ resetLastLightValues();
}
}
}
@@ -1948,6 +1988,9 @@ private void setPowerState(int newState, boolean noChangeLights, int reason)
mHandler.removeCallbacks(mAutoBrightnessTask);
mLightSensorPendingDecrease = false;
mLightSensorPendingIncrease = false;
+
+ lightFilterStop();
+
mScreenOffTime = SystemClock.elapsedRealtime();
long identity = Binder.clearCallingIdentity();
try {
@@ -1986,7 +2029,7 @@ private void updateNativePowerStateLocked() {
private int screenOffFinishedAnimatingLocked(int reason) {
// I don't think we need to check the current state here because all of these
- // Power.setScreenState and sendNotificationLocked can both handle being
+ // PowerManager.setScreenState and sendNotificationLocked can both handle being
// called multiple times in the same state. -joeo
EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, reason, mTotalTouchDownTime,
mTouchCycles);
@@ -2088,7 +2131,7 @@ private void updateLightsLocked(int newState, int forceState) {
nominalCurrentValue = preferredBrightness;
break;
case SCREEN_ON_BIT:
- nominalCurrentValue = mScreenBrightnessDim;
+ nominalCurrentValue = mScreenDim;
break;
case 0:
nominalCurrentValue = PowerManager.BRIGHTNESS_OFF;
@@ -2107,7 +2150,7 @@ private void updateLightsLocked(int newState, int forceState) {
// the scale is because the brightness ramp isn't linear and this biases
// it so the later parts take longer.
final float scale = 1.5f;
- float ratio = (((float)mScreenBrightnessDim)/preferredBrightness);
+ float ratio = (((float)mScreenDim)/preferredBrightness);
if (ratio > 1.0f) ratio = 1.0f;
if ((newState & SCREEN_ON_BIT) == 0) {
if ((oldState & SCREEN_BRIGHT_BIT) != 0) {
@@ -2134,8 +2177,9 @@ private void updateLightsLocked(int newState, int forceState) {
// still have a sense of when it is inactive, we
// will then count going dim as turning off.
mScreenOffTime = SystemClock.elapsedRealtime();
+ mAlwaysOnAndDimmed = true;
}
- brightness = mScreenBrightnessDim;
+ brightness = mScreenDim;
}
}
if (mWaitingForFirstLightSensor && (newState & SCREEN_ON_BIT) != 0) {
@@ -2240,14 +2284,29 @@ public void handleMessage(Message msg) {
// light situations.
mButtonLight.setBrightness(mLightSensorButtonBrightness >= 0 && value > 0 ?
mLightSensorButtonBrightness : value);
-
-
}
+
if ((mask & KEYBOARD_BRIGHT_BIT) != 0) {
mKeyboardLight.setBrightness(mLightSensorKeyboardBrightness >= 0 && value > 0 ?
mLightSensorKeyboardBrightness : value);
}
+ if ((mask & SCREEN_BRIGHT_BIT) != 0) {
+ if (DEBUG_SCREEN_ON) {
+ RuntimeException e = new RuntimeException("here");
+ e.fillInStackTrace();
+ Slog.i(TAG, "Set LCD brightness: " + value, e);
+ }
+ mLcdLight.setBrightness(value, brightnessMode);
+ mLastLcdValue = value;
+ }
+ if ((mask & BUTTON_BRIGHT_BIT) != 0) {
+ mButtonLight.setBrightness(value);
+ }
+ if ((mask & KEYBOARD_BRIGHT_BIT) != 0) {
+ mKeyboardLight.setBrightness(value);
+ }
+
if (elapsed > 100) {
Slog.e(TAG, "Excessive delay setting brightness: " + elapsed
+ "ms, mask=" + mask);
@@ -2420,15 +2479,20 @@ private void setLightBrightness(int mask, int value) {
}
private int getPreferredBrightness() {
- if (mScreenBrightnessOverride >= 0) {
- return mScreenBrightnessOverride;
- } else if (mLightSensorScreenBrightness >= 0 && mUseSoftwareAutoBrightness
- && mAutoBrightessEnabled) {
- return mLightSensorScreenBrightness;
+ try {
+ if (mScreenBrightnessOverride >= 0) {
+ return mScreenBrightnessOverride;
+ } else if (mLightSensorScreenBrightness >= 0 && mUseSoftwareAutoBrightness
+ && mAutoBrightessEnabled) {
+ return mLightSensorScreenBrightness;
+ }
+ final int brightness = Settings.System.getInt(mContext.getContentResolver(),
+ SCREEN_BRIGHTNESS);
+ // Don't let applications turn the screen all the way off
+ return Math.max(brightness, mScreenDim);
+ } catch (SettingNotFoundException snfe) {
+ return PowerManager.BRIGHTNESS_ON;
}
- final int brightness = mScreenBrightnessSetting;
- // Don't let applications turn the screen all the way off
- return Math.max(brightness, mScreenBrightnessDim);
}
private int applyButtonState(int state) {
@@ -2616,6 +2680,7 @@ private void userActivity(long time, long timeoutOverride, boolean noChangeLight
setPowerState(mUserState | mWakeLockState, noChangeLights,
WindowManagerPolicy.OFF_BECAUSE_OF_USER);
setTimeoutLocked(time, timeoutOverride, SCREEN_BRIGHT);
+ mAlwaysOnAndDimmed = false;
}
}
}
@@ -2625,11 +2690,41 @@ private void userActivity(long time, long timeoutOverride, boolean noChangeLight
}
}
- private int getAutoBrightnessValue(int sensorValue, int[] values) {
+ private int getAutoBrightnessValue(int current, int last, int[] levels, int[] values) {
try {
+ // If have a last value and sensor value is decreasing
+ // we should include hysteresis in calculations
+ if (last >= 0 && current < last) {
+ int i;
+ for (i = 0; i < levels.length; i++) {
+ if (last < levels[i]) {
+ break;
+ }
+ }
+ // First sensor level begins at 0 and doesn't have hysteresis
+ if (i > 0) {
+ final int length = levels[i - 1] - (i == 1 ? 0 : levels[i - 2]);
+ final int lower = levels[i - 1] - Math.round(mLightHysteresis * length);
+ if (mDebugLightSensor) {
+ Slog.d(TAG, "level=" + i + " current=" + current + " last=" + last
+ + " length=" + length + " lower=" + lower);
+ }
+ if (current < levels[i - 1] && current >= lower) {
+ // Current sensor value has decreased to the level below but is
+ // still too large due to the hysteresis.
+ // Ignore current to reduce flicker (use last)
+ if (mDebugLightSensor) {
+ Slog.d(TAG, "using last instead of current: " + current
+ + "->" + last);
+ }
+ current = last;
+ }
+ }
+ }
+
int i;
- for (i = 0; i < mAutoBrightnessLevels.length; i++) {
- if (sensorValue < mAutoBrightnessLevels[i]) {
+ for (i = 0; i < levels.length; i++) {
+ if (current < levels[i]) {
break;
}
}
@@ -2704,18 +2799,123 @@ public void run() {
/** used to prevent lightsensor changes while turning on. */
private boolean mInitialAnimation = true;
+ private Runnable mLightFilterTask = new Runnable() {
+ public void run() {
+ synchronized (mLocks) {
+ boolean again = false;
+ if (mLightFilterSample > 0 && !isScreenTurningOffLocked()) {
+ int discarded = mLightFilterSamples[mLightFilterIndex];
+ mLightFilterSamples[mLightFilterIndex] = mLightFilterSample;
+ mLightFilterIndex = (mLightFilterIndex + 1) %
+ mLightFilterSamples.length;
+ mLightFilterSampleCounter = Math.min(mLightFilterSampleCounter + 1,
+ mLightFilterSamples.length);
+ if (mLightFilterSampleCounter < mLightFilterSamples.length) {
+ discarded = 0; // Don't subtract if window isn't full
+ }
+ // Add new value...
+ mLightFilterSum += mLightFilterSample;
+ // ... and subtract discarded value
+ mLightFilterSum -= discarded;
+ // Count can't be zero here
+ int average = Math.round(
+ (float)mLightFilterSum / mLightFilterSampleCounter);
+ if (average != (int)mLightSensorValue) {
+ lightSensorChangedLocked(average, true);
+ }
+ if ((int)mLightSensorValue != mLightFilterSample) {
+ mLightFilterEqualCounter = 0;
+ again = true;
+ if (mDebugLightSensor) {
+ Slog.d(TAGF, "Tick: " + (int)mLightSensorValue + "::" +
+ mLightFilterSample + " sum:" + mLightFilterSum +
+ " samples:" + mLightFilterSampleCounter);
+ }
+ } else {
+ mLightFilterEqualCounter++;
+ again = mLightFilterEqualCounter < mLightFilterSamples.length;
+ if (mDebugLightSensor) {
+ Slog.d(TAGF, "Done: " + (int)mLightSensorValue + " " +
+ mLightFilterEqualCounter + "/" + mLightFilterSamples.length +
+ " sum:" + mLightFilterSum + " samples:" + mLightFilterSampleCounter);
+ }
+ }
+ }
+ if (again) {
+ mHandler.postDelayed(mLightFilterTask, mLightFilterInterval);
+ } else {
+ lightFilterStop();
+ }
+ }
+ }
+ };
+
+ private void lightFilterStop() {
+ if (mDebugLightSensor) {
+ Slog.d(TAGF, "stop");
+ }
+ mLightFilterRunning = false;
+ mHandler.removeCallbacks(mLightFilterTask);
+ mLightFilterSample = -1;
+ }
+
+ private void lightFilterReset(int initial) {
+ mLightFilterEqualCounter = 0;
+ mLightFilterIndex = 0;
+ mLightFilterSamples = new int[(mLightFilterWindow / mLightFilterInterval)];
+ mLightFilterSampleCounter = initial == -1 ? 0 : mLightFilterSamples.length;
+ mLightFilterSum = initial == -1 ? 0 : initial * mLightFilterSamples.length;
+ java.util.Arrays.fill(mLightFilterSamples, initial);
+ if (mDebugLightSensor) {
+ Slog.d(TAGF, "reset: " + initial);
+ }
+ }
+
+ private void resetLastLightValues() {
+ mLastLcdValue = -1;
+ mLastButtonValue = -1;
+ mLastKeyboardValue = -1;
+ }
+
+ public int getLightSensorValue() {
+ return (int) mLightSensorValue;
+ }
+
+ public int getRawLightSensorValue() {
+ if (mLightFilterEnabled && mLightFilterSample != -1) {
+ return mLightFilterSample;
+ } else {
+ return getLightSensorValue();
+ }
+ }
+
+ public int getLightSensorScreenBrightness() {
+ return mLightSensorScreenBrightness;
+ }
+
+ public int getLightSensorButtonBrightness() {
+ return mLightSensorButtonBrightness;
+ }
+
+ public int getLightSensorKeyboardBrightness() {
+ return mLightSensorKeyboardBrightness;
+ }
+
private void dockStateChanged(int state) {
synchronized (mLocks) {
mIsDocked = (state != Intent.EXTRA_DOCK_STATE_UNDOCKED);
if (mIsDocked) {
// allow brightness to decrease when docked
mHighestLightSensorValue = -1;
+ resetLastLightValues();
}
if ((mPowerState & SCREEN_ON_BIT) != 0) {
// force lights recalculation
int value = (int)mLightSensorValue;
mLightSensorValue = -1;
+ resetLastLightValues();
lightSensorChangedLocked(value, false);
+ lightFilterReset((int)mLightSensorValue);
}
}
}
@@ -2733,17 +2933,38 @@ private void lightSensorChangedLocked(int value, boolean immediate) {
return;
}
+ // do not allow light sensor value to decrease unless
+ // user has actively permitted it
+ if (mLightDecrease) {
+ mHighestLightSensorValue = value;
+ }
+
+ // do not allow light sensor value to decrease
+ if (mHighestLightSensorValue < value) {
+ mHighestLightSensorValue = value;
+ }
+
if (mLightSensorValue != value) {
mLightSensorValue = value;
if ((mPowerState & BATTERY_LOW_BIT) == 0) {
// use maximum light sensor value seen since screen went on for LCD to avoid flicker
// we only do this if we are undocked, since lighting should be stable when
// stationary in a dock.
- int lcdValue = getAutoBrightnessValue(value, mLcdBacklightValues);
- int buttonValue = getAutoBrightnessValue(value, mButtonBacklightValues);
+ int lcdValue = getAutoBrightnessValue(
+ (mIsDocked ? value : mHighestLightSensorValue),
+ mLastLcdValue,
+ (mCustomLightEnabled ? mCustomLightLevels : mAutoBrightnessLevels),
+ (mCustomLightEnabled ? mCustomLcdValues : mLcdBacklightValues));
+
+ int buttonValue = getAutoBrightnessValue(value, mLastButtonValue,
+ (mCustomLightEnabled ? mCustomLightLevels : mAutoBrightnessLevels),
+ (mCustomLightEnabled ? mCustomButtonValues : mButtonBacklightValues));
+
int keyboardValue;
if (mKeyboardVisible) {
- keyboardValue = getAutoBrightnessValue(value, mKeyboardBacklightValues);
+ keyboardValue = getAutoBrightnessValue(value, mLastKeyboardValue,
+ (mCustomLightEnabled ? mCustomLightLevels : mAutoBrightnessLevels),
+ (mCustomLightEnabled ? mCustomKeyboardValues : mKeyboardBacklightValues));
} else {
keyboardValue = 0;
}
@@ -2774,6 +2995,7 @@ private void lightSensorChangedLocked(int value, boolean immediate) {
mScreenBrightnessAnimator.animateTo(lcdValue, value,
SCREEN_BRIGHT_BIT, steps * NOMINAL_FRAME_TIME_MS);
}
+ mLastLcdValue = value;
}
if (mButtonBrightnessOverride < 0 && mAutoBrightnessButtonKeyboard) {
mButtonLight.setBrightness(buttonValue);
@@ -2933,6 +3155,7 @@ public void setKeyboardVisibility(boolean visible) {
int value = (int)mLightSensorValue;
mLightSensorValue = -1;
lightSensorChangedLocked(value, false);
+ lightFilterReset((int)mLightSensorValue);
}
}
userActivity(SystemClock.uptimeMillis(), false, BUTTON_EVENT, true);
@@ -2960,14 +3183,151 @@ public void enableUserActivity(boolean enabled) {
}
private void setScreenBrightnessMode(int mode) {
- synchronized (mLocks) {
- boolean enabled = (mode == SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
- if (mUseSoftwareAutoBrightness && mAutoBrightessEnabled != enabled) {
- mAutoBrightessEnabled = enabled;
- // This will get us a new value
- enableLightSensorLocked(mAutoBrightessEnabled && isScreenOn());
+ boolean enabled = (mode == SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
+ if (mUseSoftwareAutoBrightness && mAutoBrightessEnabled != enabled) {
+ mAutoBrightessEnabled = enabled;
+ if (isScreenOn()) {
+ // force recompute of backlight values
+ if (mLightSensorValue >= 0) {
+ int value = (int)mLightSensorValue;
+ mLightSensorValue = -1;
+ resetLastLightValues();
+ lightSensorChangedLocked(value, true);
+ }
+ lightFilterReset((int)mLightSensorValue);
+ if (!enabled) {
+ lightFilterStop();
+ }
+ }
+ }
+ }
+
+ private void updateLightSettings() {
+ ContentResolver cr = mContext.getContentResolver();
+ boolean filterWasEnabled = mLightFilterEnabled;
+
+ long tag = Settings.System.getLong(cr,
+ Settings.System.LIGHTS_CHANGED, 0);
+ if (tag == mLightSettingsTag) {
+ return;
+ }
+ mLightSettingsTag = tag;
+ mCustomLightEnabled = Settings.System.getInt(cr,
+ Settings.System.LIGHT_SENSOR_CUSTOM, 0) != 0;
+ mLightDecrease = Settings.System.getInt(cr,
+ Settings.System.LIGHT_DECREASE, 0) != 0;
+ mLightHysteresis = Settings.System.getInt(cr,
+ Settings.System.LIGHT_HYSTERESIS, 50) / 100f;
+ mLightFilterEnabled = Settings.System.getInt(cr,
+ Settings.System.LIGHT_FILTER, 0) != 0;
+ mLightFilterWindow = Settings.System.getInt(cr,
+ Settings.System.LIGHT_FILTER_WINDOW, 30000);
+ mLightFilterInterval = Settings.System.getInt(cr,
+ Settings.System.LIGHT_FILTER_INTERVAL, 1000);
+ mLightFilterReset = Settings.System.getInt(cr,
+ Settings.System.LIGHT_FILTER_RESET, -1);
+ if (mCustomLightEnabled) {
+ mScreenDim = Settings.System.getInt(cr,
+ Settings.System.LIGHT_SCREEN_DIM, PowerManager.BRIGHTNESS_DIM);
+ } else {
+ mScreenDim = PowerManager.BRIGHTNESS_DIM;
+ }
+
+ if (mLightFilterEnabled) {
+ if (!filterWasEnabled) {
+ lightFilterReset(-1);
}
+ } else {
+ lightFilterStop();
}
+
+ if (mDebugLightSensor) {
+ Slog.d(TAG, "custom: " + mCustomLightEnabled);
+ Slog.d(TAG, "decrease: " + mLightDecrease);
+ Slog.d(TAG, "hysteresis: " + mLightHysteresis);
+ Slog.d(TAG, "filter: " + mLightFilterEnabled);
+ Slog.d(TAG, "window: " + mLightFilterWindow);
+ Slog.d(TAG, "interval: " + mLightFilterInterval);
+ Slog.d(TAG, "reset: " + mLightFilterReset);
+ Slog.d(TAG, "dim: " + mScreenDim);
+ }
+
+ if (mCustomLightEnabled) {
+ // Load custom values
+ try {
+ mCustomLightLevels = parseIntArray(Settings.System.getString(
+ cr, Settings.System.LIGHT_SENSOR_LEVELS));
+ if (mDebugLightSensor) {
+ Slog.d(TAG, "levels: " +
+ java.util.Arrays.toString(mCustomLightLevels));
+ }
+
+ mCustomLcdValues = parseIntArray(Settings.System.getString(
+ cr, Settings.System.LIGHT_SENSOR_LCD_VALUES));
+ if (mDebugLightSensor) {
+ Slog.d(TAG, "lcd values: " +
+ java.util.Arrays.toString(mCustomLcdValues));
+ }
+
+ mCustomButtonValues = parseIntArray(Settings.System.getString(
+ cr, Settings.System.LIGHT_SENSOR_BUTTON_VALUES));
+ if (mDebugLightSensor) {
+ Slog.d(TAG, "button values: " +
+ java.util.Arrays.toString(mCustomButtonValues));
+ }
+
+ mCustomKeyboardValues = parseIntArray(Settings.System.getString(
+ cr, Settings.System.LIGHT_SENSOR_KEYBOARD_VALUES));
+ if (mDebugLightSensor) {
+ Slog.d(TAG, "keyboard values: " +
+ java.util.Arrays.toString(mCustomKeyboardValues));
+ }
+
+ if (mDebugLightSensor) {
+ Slog.d(TAG, "default levels: " +
+ java.util.Arrays.toString(mAutoBrightnessLevels));
+ Slog.d(TAG, "default lcd values: " +
+ java.util.Arrays.toString(mLcdBacklightValues));
+ Slog.d(TAG, "default button values: " +
+ java.util.Arrays.toString(mButtonBacklightValues));
+ Slog.d(TAG, "default keyboard values: " +
+ java.util.Arrays.toString(mKeyboardBacklightValues));
+ }
+
+ // Sanity check
+ int N = mCustomLightLevels.length;
+ if (N < 1 || mCustomLcdValues.length != (N + 1)
+ || mCustomButtonValues.length != (N + 1)
+ || mCustomKeyboardValues.length != (N + 1)) {
+ throw new Exception("sanity check failed");
+ }
+ // force recompute of backlight values
+ if (mLightSensorValue >= 0) {
+ int value = (int)mLightSensorValue;
+ mLightSensorValue = -1;
+ resetLastLightValues();
+ lightSensorChangedLocked(value, true);
+ }
+ } catch (Exception e) {
+ // Use defaults since we can't trust custom values
+ mCustomLightEnabled = false;
+ Slog.e(TAG, "loading custom settings failed", e);
+ }
+ }
+ }
+
+ private int[] parseIntArray(String intArray) {
+ int[] result;
+ if (intArray == null || intArray.length() == 0) {
+ result = new int[0];
+ } else {
+ String[] split = intArray.split(",");
+ result = new int[split.length];
+ for (int i = 0; i < split.length; i++) {
+ result[i] = Integer.parseInt(split[i]);
+ }
+ }
+ return result;
}
/** Sets the screen off timeouts:
@@ -3179,7 +3539,7 @@ public void setBacklightBrightness(int brightness) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
// Don't let applications turn the screen all the way off
synchronized (mLocks) {
- brightness = Math.max(brightness, mScreenBrightnessDim);
+ brightness = Math.max(brightness, mScreenDim);
mLcdLight.setBrightness(brightness);
mKeyboardLight.setBrightness(mKeyboardVisible ? brightness : 0);
mButtonLight.setBrightness(brightness);
@@ -3333,6 +3693,7 @@ private void enableLightSensorLocked(boolean enable) {
mSensorManager.registerListener(mLightListener, mLightSensor,
LIGHT_SENSOR_RATE);
} else {
+ lightFilterStop();
mSensorManager.unregisterListener(mLightListener);
mHandler.removeCallbacks(mAutoBrightnessTask);
mLightSensorPendingDecrease = false;
@@ -3435,6 +3796,66 @@ public void onSensorChanged(SensorEvent event) {
}
mWaitingForFirstLightSensor = false;
}
+
+ int value = (int)event.values[0];
+ long milliseconds = SystemClock.elapsedRealtime();
+ if (mDebugLightSensor) {
+ Slog.d(TAG, "onSensorChanged: light value: " + value);
+ }
+ mHandler.removeCallbacks(mAutoBrightnessTask);
+ mLightFilterSample = value;
+ if (mAutoBrightessEnabled && mLightFilterEnabled) {
+ if (mLightFilterRunning && mLightSensorValue != -1) {
+ // Large changes -> quick response
+ int diff = value - (int)mLightSensorValue;
+ if (mLightFilterReset != -1 && diff > mLightFilterReset && // Only increasing
+ mLightSensorValue < 1500) { // Only "indoors"
+ if (mDebugLightSensor) {
+ Slog.d(TAGF, "reset cause: " + value +
+ " " + mLightSensorValue + " " + diff);
+ }
+ // Push filter faster towards sensor value
+ lightFilterReset((int)(mLightSensorValue + diff / 2f));
+ }
+ if (mDebugLightSensor) {
+ Slog.d(TAGF, "sample: " + value);
+ }
+ } else {
+ if (mLightSensorValue == -1 ||
+ milliseconds < mLastScreenOnTime + mLightSensorWarmupTime) {
+ // process the value immediately if screen has just turned on
+ lightFilterReset(-1);
+ lightSensorChangedLocked(value, true);
+ }
+ if (!mLightFilterRunning) {
+ if (mDebugLightSensor) {
+ Slog.d(TAGF, "start: " + value);
+ }
+ mLightFilterRunning = true;
+ mHandler.postDelayed(mLightFilterTask, LIGHT_SENSOR_DELAY);
+ }
+ }
+ return;
+ }
+
+ if (mLightSensorValue != value) {
+ if (mLightSensorValue == -1 ||
+ milliseconds < mLastScreenOnTime + mLightSensorWarmupTime) {
+ // process the value immediately if screen has just turned on
+ lightSensorChangedLocked(value, true);
+ } else {
+ // delay processing to debounce the sensor
+ mHandler.removeCallbacks(mAutoBrightnessTask);
+ mLightSensorPendingDecrease = (value < mLightSensorValue);
+ mLightSensorPendingIncrease = (value > mLightSensorValue);
+ if (mLightSensorPendingDecrease || mLightSensorPendingIncrease) {
+ mLightSensorPendingValue = value;
+ mHandler.postDelayed(mAutoBrightnessTask, LIGHT_SENSOR_DELAY);
+ }
+ }
+ } else {
+ mLightSensorPendingValue = value;
+ }
}
}
View
32 tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
@@ -129,4 +129,36 @@ public void userActivity(long arg0, boolean arg1) throws RemoteException {
public void userActivityWithForce(long arg0, boolean arg1, boolean arg2) throws RemoteException {
// pass for now.
}
+
+ // custom backlight things
+
+ @Override
+ public int getLightSensorValue() throws RemoteException {
+ // pass for now.
+ return 0;
+ }
+
+ @Override
+ public int getRawLightSensorValue() throws RemoteException {
+ // pass for now.
+ return 0;
+ }
+
+ @Override
+ public int getLightSensorScreenBrightness() throws RemoteException {
+ // pass for now.
+ return 0;
+ }
+
+ @Override
+ public int getLightSensorButtonBrightness() throws RemoteException {
+ // pass for now.
+ return 0;
+ }
+
+ @Override
+ public int getLightSensorKeyboardBrightness() throws RemoteException {
+ // pass for now.
+ return 0;
+ }
}
Please sign in to comment.
Something went wrong with that request. Please try again.