Skip to content

Commit

Permalink
Fix race condition in backlight adjustment.
Browse files Browse the repository at this point in the history
When configuring the automatic backlight levels, there's a race
condition in setting the lux and brightness settings as the settings
provider doesn't allow storing multiple settings atomically. When
deleting rows, there's quite a high chance of DisplayPowerController
picking up a state where the lux values already have the lower number of
rows, but the brightness values do not, effectively leading to an
ArrayIndexOutOfBoundsException.

Fix that by
- waiting a second of cool-down time until applying the settings and
- adding a sanity check for the very unlikely case that the delay
  between writing both values is > 1 second

Change-Id: I44e41530fc5334aaefc4ab7d3a90542f78fabe0c
JIRA:CYAN-755
Signed-off-by: DHO <DHO@dho.im>

Conflicts:

	services/java/com/android/server/power/DisplayPowerController.java
  • Loading branch information
maniac103 authored and davros- committed Apr 18, 2013
1 parent 2b76e22 commit 9c36af6
Showing 1 changed file with 22 additions and 4 deletions.
26 changes: 22 additions & 4 deletions services/java/com/android/server/power/DisplayPowerController.java
Expand Up @@ -112,6 +112,7 @@ final class DisplayPowerController {
private static final int MSG_UPDATE_POWER_STATE = 1;
private static final int MSG_PROXIMITY_SENSOR_DEBOUNCED = 2;
private static final int MSG_LIGHT_SENSOR_DEBOUNCED = 3;
private static final int MSG_UPDATE_BACKLIGHT_SETTINGS = 4;

private static final int PROXIMITY_UNKNOWN = -1;
private static final int PROXIMITY_NEGATIVE = 0;
Expand Down Expand Up @@ -371,10 +372,17 @@ public DisplayPowerController(Looper looper, Context context, Notifier notifier,
mUseSoftwareAutoBrightnessConfig = resources.getBoolean(
com.android.internal.R.bool.config_automatic_brightness_available);
if (mUseSoftwareAutoBrightnessConfig) {
int[] lux = resources.getIntArray(
com.android.internal.R.array.config_autoBrightnessLevels);
int[] screenBrightness = resources.getIntArray(
com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
final ContentResolver cr = mContext.getContentResolver();
final ContentObserver observer = new ContentObserver(mHandler) {
@Override
public void onChange(boolean selfChange, Uri uri) {
// As both LUX and BACKLIGHT might be changed at the same time, there's
// a potential race condition. As the settings provider API doesn't give
// us transactions to avoid them, wait a little until things settle down
mHandler.removeMessages(MSG_UPDATE_BACKLIGHT_SETTINGS);
mHandler.sendEmptyMessageDelayed(MSG_UPDATE_BACKLIGHT_SETTINGS, 1000);
}
};

mScreenAutoBrightnessSpline = createAutoBrightnessSpline(lux, screenBrightness);
if (mScreenAutoBrightnessSpline == null) {
Expand Down Expand Up @@ -420,6 +428,10 @@ public DisplayPowerController(Looper looper, Context context, Notifier notifier,
}

private static Spline createAutoBrightnessSpline(int[] lux, int[] brightness) {
if (lux.length < 2 || lux.length != (brightness.length - 1)) {
return null;
}

try {
final int n = brightness.length;
float[] x = new float[n];
Expand Down Expand Up @@ -1281,6 +1293,12 @@ public void handleMessage(Message msg) {
case MSG_LIGHT_SENSOR_DEBOUNCED:
debounceLightSensor();
break;

case MSG_UPDATE_BACKLIGHT_SETTINGS:
mAutoBrightnessSettingsChanged = true;
updateAutomaticBrightnessSettings();
updatePowerState();
break;
}
}
}
Expand Down

0 comments on commit 9c36af6

Please sign in to comment.