From 196943fb51789e7c3a39ae7d56aceba5e1304137 Mon Sep 17 00:00:00 2001 From: Craig Mautner Date: Tue, 15 May 2012 08:10:35 -0700 Subject: [PATCH] Modify auto brightness to return to dim level. Previous auto brightness policy was to only ratchet screen brightness up and never return to dim levels until the device was turned off. This caused the screen to be very bright in dim areas and reduced battery life. This change allows the screen to dim down over the course of a minute to the desired brightness level. Fixes bug 6422464. Change-Id: I5592c06a495650c6496ec2fc9846d7a10fac4b16 --- .../android/server/PowerManagerService.java | 60 +++++++++++++------ 1 file changed, 43 insertions(+), 17 deletions(-) diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java index 2cc270432b875..38e08ae059aa0 100644 --- a/services/java/com/android/server/PowerManagerService.java +++ b/services/java/com/android/server/PowerManagerService.java @@ -178,6 +178,8 @@ public class PowerManagerService extends IPowerManager.Stub static final int ANIM_STEPS = 60; // nominal # of frames at 60Hz // Slower animation for autobrightness changes static final int AUTOBRIGHTNESS_ANIM_STEPS = 2 * ANIM_STEPS; + // Even slower animation for autodimness changes + static final int AUTODIMNESS_ANIM_STEPS = 15 * ANIM_STEPS; // Number of steps when performing a more immediate brightness change. static final int IMMEDIATE_ANIM_STEPS = 4; @@ -1745,7 +1747,6 @@ public class PowerManagerService extends IPowerManager.Stub + Integer.toHexString(mPowerState) + " mSkippedScreenOn=" + mSkippedScreenOn); } - mScreenBrightnessHandler.removeMessages(ScreenBrightnessAnimator.ANIMATE_LIGHTS); mScreenBrightnessAnimator.animateTo(PowerManager.BRIGHTNESS_OFF, SCREEN_BRIGHT_BIT, 0); } } @@ -2159,6 +2160,8 @@ public class PowerManagerService extends IPowerManager.Stub static final int ANIMATE_POWER_OFF = 11; volatile int startValue; volatile int endValue; + volatile int startSensorValue; + volatile int endSensorValue; volatile int currentValue; private int currentMask; private int duration; @@ -2182,7 +2185,7 @@ public class PowerManagerService extends IPowerManager.Stub int value = msg.arg2; long tStart = SystemClock.uptimeMillis(); if ((mask & SCREEN_BRIGHT_BIT) != 0) { - if (mDebugLightAnimation) Log.v(TAG, "Set brightness: " + value); + if (mDebugLightAnimation) Slog.v(TAG, "Set brightness: " + value); mLcdLight.setBrightness(value, brightnessMode); } long elapsed = SystemClock.uptimeMillis() - tStart; @@ -2194,12 +2197,12 @@ public class PowerManagerService extends IPowerManager.Stub } if (elapsed > 100) { - Log.e(TAG, "Excessive delay setting brightness: " + elapsed + Slog.e(TAG, "Excessive delay setting brightness: " + elapsed + "ms, mask=" + mask); } // Throttle brightness updates to frame refresh rate - int delay = elapsed < NOMINAL_FRAME_TIME_MS ? NOMINAL_FRAME_TIME_MS : 0; + int delay = elapsed < NOMINAL_FRAME_TIME_MS ? NOMINAL_FRAME_TIME_MS : 1; synchronized(this) { currentValue = value; } @@ -2227,25 +2230,41 @@ public class PowerManagerService extends IPowerManager.Stub newValue = startValue + delta * elapsed / duration; newValue = Math.max(PowerManager.BRIGHTNESS_OFF, newValue); newValue = Math.min(PowerManager.BRIGHTNESS_ON, newValue); + // Optimization to delay next step until a change will occur. + if (delay > 0 && newValue == currentValue) { + final int timePerStep = duration / Math.abs(delta); + delay = Math.min(duration - elapsed, timePerStep); + newValue += delta < 0 ? -1 : 1; + } + // adjust the peak sensor value until we get to the target sensor value + delta = endSensorValue - startSensorValue; + mHighestLightSensorValue = startSensorValue + delta * elapsed / duration; } else { newValue = endValue; + mHighestLightSensorValue = endSensorValue; mInitialAnimation = false; } if (mDebugLightAnimation) { - Log.v(TAG, "Animating light: " + "start:" + startValue + Slog.v(TAG, "Animating light: " + "start:" + startValue + ", end:" + endValue + ", elapsed:" + elapsed + ", duration:" + duration + ", current:" + currentValue - + ", delay:" + delay); + + ", newValue:" + newValue + + ", delay:" + delay + + ", highestSensor:" + mHighestLightSensorValue); } if (turningOff && !mHeadless && !mAnimateScreenLights) { int mode = mScreenOffReason == OFF_BECAUSE_OF_PROX_SENSOR ? 0 : mAnimationSetting; - if (mDebugLightAnimation) Log.v(TAG, "Doing power-off anim, mode=" + mode); + if (mDebugLightAnimation) { + Slog.v(TAG, "Doing power-off anim, mode=" + mode); + } mScreenBrightnessHandler.obtainMessage(ANIMATE_POWER_OFF, mode, 0) .sendToTarget(); } + mScreenBrightnessHandler.removeMessages( + ScreenBrightnessAnimator.ANIMATE_LIGHTS); Message msg = mScreenBrightnessHandler .obtainMessage(ANIMATE_LIGHTS, mask, newValue); mScreenBrightnessHandler.sendMessageDelayed(msg, delay); @@ -2259,16 +2278,24 @@ public class PowerManagerService extends IPowerManager.Stub } public void animateTo(int target, int mask, int animationDuration) { + animateTo(target, mHighestLightSensorValue, mask, animationDuration); + } + + public void animateTo(int target, int sensorTarget, int mask, int animationDuration) { synchronized(this) { startValue = currentValue; endValue = target; + startSensorValue = mHighestLightSensorValue; + endSensorValue = sensorTarget; currentMask = mask; duration = (int) (mWindowScaleAnimation * animationDuration); startTimeMillis = SystemClock.elapsedRealtime(); mInitialAnimation = currentValue == 0 && target > 0; if (mDebugLightAnimation) { - Log.v(TAG, "animateTo(target=" + target + ", mask=" + mask + Slog.v(TAG, "animateTo(target=" + target + + ", sensor=" + sensorTarget + + ", mask=" + mask + ", duration=" + animationDuration +")" + ", currentValue=" + currentValue + ", startTime=" + startTimeMillis); @@ -2612,9 +2639,11 @@ public class PowerManagerService extends IPowerManager.Stub return; } - // do not allow light sensor value to decrease - if (mHighestLightSensorValue < value) { - mHighestLightSensorValue = value; + final int stepsToTargetLevel; + if (mHighestLightSensorValue <= value) { + stepsToTargetLevel = AUTOBRIGHTNESS_ANIM_STEPS; + } else { + stepsToTargetLevel = AUTODIMNESS_ANIM_STEPS; } if (mLightSensorValue != value) { @@ -2623,9 +2652,7 @@ public class PowerManagerService extends IPowerManager.Stub // 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( - (mIsDocked ? value : mHighestLightSensorValue), - mLcdBacklightValues); + int lcdValue = getAutoBrightnessValue(value, mLcdBacklightValues); int buttonValue = getAutoBrightnessValue(value, mButtonBacklightValues); int keyboardValue; if (mKeyboardVisible) { @@ -2645,9 +2672,8 @@ public class PowerManagerService extends IPowerManager.Stub if (mAutoBrightessEnabled && mScreenBrightnessOverride < 0) { if (!mSkippedScreenOn && !mInitialAnimation) { - int steps = immediate ? IMMEDIATE_ANIM_STEPS : AUTOBRIGHTNESS_ANIM_STEPS; - mScreenBrightnessAnimator.cancelAnimation(); - mScreenBrightnessAnimator.animateTo(lcdValue, + int steps = immediate ? IMMEDIATE_ANIM_STEPS : stepsToTargetLevel; + mScreenBrightnessAnimator.animateTo(lcdValue, value, SCREEN_BRIGHT_BIT, steps * NOMINAL_FRAME_TIME_MS); } }