@@ -125,28 +125,34 @@ final class DisplayPowerController {
125125 // Trigger proximity if distance is less than 5 cm.
126126 private static final float TYPICAL_PROXIMITY_THRESHOLD = 5.0f ;
127127
128- // Light sensor event rate in microseconds.
129- private static final int LIGHT_SENSOR_RATE = 500 * 1000 ;
128+ // Light sensor event rate in milliseconds.
129+ private static final int LIGHT_SENSOR_RATE_MILLIS = 1000 ;
130+
131+ // A rate for generating synthetic light sensor events in the case where the light
132+ // sensor hasn't reported any new data in a while and we need it to update the
133+ // debounce filter. We only synthesize light sensor measurements when needed.
134+ private static final int SYNTHETIC_LIGHT_SENSOR_RATE_MILLIS =
135+ LIGHT_SENSOR_RATE_MILLIS * 2 ;
130136
131137 // Brightness animation ramp rate in brightness units per second.
132138 private static final int BRIGHTNESS_RAMP_RATE_FAST = 200 ;
133- private static final int BRIGHTNESS_RAMP_RATE_SLOW = 30 ;
139+ private static final int BRIGHTNESS_RAMP_RATE_SLOW = 40 ;
134140
135141 // IIR filter time constants in milliseconds for computing two moving averages of
136142 // the light samples. One is a long-term average and the other is a short-term average.
137143 // We can use these filters to assess trends in ambient brightness.
138144 // The short term average gives us a filtered but relatively low latency measurement.
139145 // The long term average informs us about the overall trend.
140146 private static final long SHORT_TERM_AVERAGE_LIGHT_TIME_CONSTANT = 1000 ;
141- private static final long LONG_TERM_AVERAGE_LIGHT_TIME_CONSTANT = 8000 ;
147+ private static final long LONG_TERM_AVERAGE_LIGHT_TIME_CONSTANT = 5000 ;
142148
143149 // Stability requirements in milliseconds for accepting a new brightness
144150 // level. This is used for debouncing the light sensor. Different constants
145151 // are used to debounce the light sensor when adapting to brighter or darker environments.
146152 // This parameter controls how quickly brightness changes occur in response to
147- // an observed change in light level following a previous change in the opposite direction .
148- private static final long BRIGHTENING_LIGHT_DEBOUNCE = 5000 ;
149- private static final long DARKENING_LIGHT_DEBOUNCE = 15000 ;
153+ // an observed change in light level that exceeds the hysteresis threshold .
154+ private static final long BRIGHTENING_LIGHT_DEBOUNCE = 4000 ;
155+ private static final long DARKENING_LIGHT_DEBOUNCE = 8000 ;
150156
151157 // Hysteresis constraints for brightening or darkening.
152158 // The recent lux must have changed by at least this fraction relative to the
@@ -290,10 +296,6 @@ final class DisplayPowerController {
290296 // True if mAmbientLux holds a valid value.
291297 private boolean mAmbientLuxValid ;
292298
293- // The time when the ambient lux was last brightened or darkened.
294- private long mLastAmbientBrightenTime ;
295- private long mLastAmbientDarkenTime ;
296-
297299 // The most recent light sample.
298300 private float mLastObservedLux ;
299301
@@ -307,6 +309,15 @@ final class DisplayPowerController {
307309 private float mRecentShortTermAverageLux ;
308310 private float mRecentLongTermAverageLux ;
309311
312+ // The direction in which the average lux is moving relative to the current ambient lux.
313+ // 0 if not changing or within hysteresis threshold.
314+ // 1 if brightening beyond hysteresis threshold.
315+ // -1 if darkening beyond hysteresis threshold.
316+ private int mDebounceLuxDirection ;
317+
318+ // The time when the average lux last changed direction.
319+ private long mDebounceLuxTime ;
320+
310321 // The screen brightness level that has been chosen by the auto-brightness
311322 // algorithm. The actual brightness should ramp towards this value.
312323 // We preserve this value even when we stop using the light sensor so
@@ -547,6 +558,7 @@ private void updatePowerState() {
547558 final boolean mustNotify ;
548559 boolean mustInitialize = false ;
549560 boolean updateAutoBrightness = mTwilightChanged ;
561+ boolean wasDim = false ;
550562 mTwilightChanged = false ;
551563
552564 synchronized (mLock ) {
@@ -566,6 +578,7 @@ private void updatePowerState() {
566578 != mPendingRequestLocked .screenAutoBrightnessAdjustment ) {
567579 updateAutoBrightness = true ;
568580 }
581+ wasDim = (mPowerRequest .screenState == DisplayPowerRequest .SCREEN_STATE_DIM );
569582 mPowerRequest .copyFrom (mPendingRequestLocked );
570583 mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked ;
571584 mPendingWaitForNegativeProximityLocked = false ;
@@ -635,9 +648,12 @@ private void updatePowerState() {
635648 mUsingScreenAutoBrightness = false ;
636649 }
637650 if (mPowerRequest .screenState == DisplayPowerRequest .SCREEN_STATE_DIM ) {
638- // Screen is dimmed. Sets an upper bound on everything else .
651+ // Dim slowly by at least some minimum amount .
639652 target = Math .min (target - SCREEN_DIM_MINIMUM_REDUCTION ,
640653 mScreenBrightnessDimConfig );
654+ slow = true ;
655+ } else if (wasDim ) {
656+ // Brighten quickly.
641657 slow = false ;
642658 }
643659 animateScreenBrightness (clampScreenBrightness (target ),
@@ -852,7 +868,7 @@ private void setLightSensorEnabled(boolean enable, boolean updateAutoBrightness)
852868 mLightSensorEnabled = true ;
853869 mLightSensorEnableTime = SystemClock .uptimeMillis ();
854870 mSensorManager .registerListener (mLightSensorListener , mLightSensor ,
855- LIGHT_SENSOR_RATE , mHandler );
871+ LIGHT_SENSOR_RATE_MILLIS * 1000 , mHandler );
856872 }
857873 } else {
858874 if (mLightSensorEnabled ) {
@@ -869,6 +885,13 @@ private void setLightSensorEnabled(boolean enable, boolean updateAutoBrightness)
869885 }
870886
871887 private void handleLightSensorEvent (long time , float lux ) {
888+ mHandler .removeMessages (MSG_LIGHT_SENSOR_DEBOUNCED );
889+
890+ applyLightSensorMeasurement (time , lux );
891+ updateAmbientLux (time );
892+ }
893+
894+ private void applyLightSensorMeasurement (long time , float lux ) {
872895 // Update our filters.
873896 mRecentLightSamples += 1 ;
874897 if (mRecentLightSamples == 1 ) {
@@ -885,45 +908,53 @@ private void handleLightSensorEvent(long time, float lux) {
885908 // Remember this sample value.
886909 mLastObservedLux = lux ;
887910 mLastObservedLuxTime = time ;
888-
889- // Update the ambient lux level.
890- mHandler .removeMessages (MSG_LIGHT_SENSOR_DEBOUNCED );
891- updateAmbientLux (time );
892911 }
893912
894913 private void updateAmbientLux (long time ) {
895914 // If the light sensor was just turned on then immediately update our initial
896915 // estimate of the current ambient light level.
897916 if (!mAmbientLuxValid
898917 || (time - mLightSensorEnableTime ) < mLightSensorWarmUpTimeConfig ) {
918+ mAmbientLux = mRecentShortTermAverageLux ;
919+ mAmbientLuxValid = true ;
920+ mDebounceLuxDirection = 0 ;
921+ mDebounceLuxTime = time ;
899922 if (DEBUG ) {
900- Slog .d (TAG , "updateAmbientLux: Initializing, "
901- + "mAmbientLux=" + (mAmbientLuxValid ? mAmbientLux : -1 )
923+ Slog .d (TAG , "updateAmbientLux: Initializing: "
902924 + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux
903- + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux );
925+ + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux
926+ + ", mAmbientLux=" + mAmbientLux );
904927 }
905- mAmbientLux = mRecentShortTermAverageLux ;
906- mAmbientLuxValid = true ;
907- mLastAmbientBrightenTime = time ;
908- mLastAmbientDarkenTime = time ;
909928 updateAutoBrightness (true );
910929 return ;
911930 }
912931
913932 // Determine whether the ambient environment appears to be brightening.
914- float minAmbientLux = mAmbientLux * (1.0f + BRIGHTENING_LIGHT_HYSTERESIS );
915- if (mRecentShortTermAverageLux > minAmbientLux
916- && mRecentLongTermAverageLux > minAmbientLux ) {
917- long debounceTime = mLastAmbientDarkenTime + BRIGHTENING_LIGHT_DEBOUNCE ;
933+ float brighteningLuxThreshold = mAmbientLux * (1.0f + BRIGHTENING_LIGHT_HYSTERESIS );
934+ if (mRecentShortTermAverageLux > brighteningLuxThreshold
935+ && mRecentLongTermAverageLux > brighteningLuxThreshold ) {
936+ if (mDebounceLuxDirection <= 0 ) {
937+ mDebounceLuxDirection = 1 ;
938+ mDebounceLuxTime = time ;
939+ if (DEBUG ) {
940+ Slog .d (TAG , "updateAmbientLux: Possibly brightened, waiting for "
941+ + BRIGHTENING_LIGHT_DEBOUNCE + " ms: "
942+ + "brighteningLuxThreshold=" + brighteningLuxThreshold
943+ + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux
944+ + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux
945+ + ", mAmbientLux=" + mAmbientLux );
946+ }
947+ }
948+ long debounceTime = mDebounceLuxTime + BRIGHTENING_LIGHT_DEBOUNCE ;
918949 if (time >= debounceTime ) {
950+ mAmbientLux = mRecentShortTermAverageLux ;
919951 if (DEBUG ) {
920952 Slog .d (TAG , "updateAmbientLux: Brightened: "
921- + "mAmbientLux =" + mAmbientLux
953+ + "brighteningLuxThreshold =" + brighteningLuxThreshold
922954 + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux
923- + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux );
955+ + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux
956+ + ", mAmbientLux=" + mAmbientLux );
924957 }
925- mLastAmbientBrightenTime = time ;
926- mAmbientLux = mRecentShortTermAverageLux ;
927958 updateAutoBrightness (true );
928959 } else {
929960 mHandler .sendEmptyMessageAtTime (MSG_LIGHT_SENSOR_DEBOUNCED , debounceTime );
@@ -932,28 +963,78 @@ private void updateAmbientLux(long time) {
932963 }
933964
934965 // Determine whether the ambient environment appears to be darkening.
935- float maxAmbientLux = mAmbientLux * (1.0f - DARKENING_LIGHT_HYSTERESIS );
936- if (mRecentShortTermAverageLux < maxAmbientLux
937- && mRecentLongTermAverageLux < maxAmbientLux ) {
938- long debounceTime = mLastAmbientBrightenTime + DARKENING_LIGHT_DEBOUNCE ;
966+ float darkeningLuxThreshold = mAmbientLux * (1.0f - DARKENING_LIGHT_HYSTERESIS );
967+ if (mRecentShortTermAverageLux < darkeningLuxThreshold
968+ && mRecentLongTermAverageLux < darkeningLuxThreshold ) {
969+ if (mDebounceLuxDirection >= 0 ) {
970+ mDebounceLuxDirection = -1 ;
971+ mDebounceLuxTime = time ;
972+ if (DEBUG ) {
973+ Slog .d (TAG , "updateAmbientLux: Possibly darkened, waiting for "
974+ + DARKENING_LIGHT_DEBOUNCE + " ms: "
975+ + "darkeningLuxThreshold=" + darkeningLuxThreshold
976+ + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux
977+ + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux
978+ + ", mAmbientLux=" + mAmbientLux );
979+ }
980+ }
981+ long debounceTime = mDebounceLuxTime + DARKENING_LIGHT_DEBOUNCE ;
939982 if (time >= debounceTime ) {
983+ // Be conservative about reducing the brightness, only reduce it a little bit
984+ // at a time to avoid having to bump it up again soon.
985+ mAmbientLux = Math .max (mRecentShortTermAverageLux , mRecentLongTermAverageLux );
940986 if (DEBUG ) {
941987 Slog .d (TAG , "updateAmbientLux: Darkened: "
942- + "mAmbientLux =" + mAmbientLux
988+ + "darkeningLuxThreshold =" + darkeningLuxThreshold
943989 + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux
944- + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux );
990+ + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux
991+ + ", mAmbientLux=" + mAmbientLux );
945992 }
946- mLastAmbientDarkenTime = time ;
947- mAmbientLux = mRecentShortTermAverageLux ;
948993 updateAutoBrightness (true );
949994 } else {
950995 mHandler .sendEmptyMessageAtTime (MSG_LIGHT_SENSOR_DEBOUNCED , debounceTime );
951996 }
997+ return ;
998+ }
999+
1000+ // No change or change is within the hysteresis thresholds.
1001+ if (mDebounceLuxDirection != 0 ) {
1002+ mDebounceLuxDirection = 0 ;
1003+ mDebounceLuxTime = time ;
1004+ if (DEBUG ) {
1005+ Slog .d (TAG , "updateAmbientLux: Canceled debounce: "
1006+ + "brighteningLuxThreshold=" + brighteningLuxThreshold
1007+ + ", darkeningLuxThreshold=" + darkeningLuxThreshold
1008+ + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux
1009+ + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux
1010+ + ", mAmbientLux=" + mAmbientLux );
1011+ }
1012+ }
1013+
1014+ // If the light level does not change, then the sensor may not report
1015+ // a new value. This can cause problems for the auto-brightness algorithm
1016+ // because the filters might not be updated. To work around it, we want to
1017+ // make sure to update the filters whenever the observed light level could
1018+ // possibly exceed one of the hysteresis thresholds.
1019+ if (mLastObservedLux > brighteningLuxThreshold
1020+ || mLastObservedLux < darkeningLuxThreshold ) {
1021+ mHandler .sendEmptyMessageAtTime (MSG_LIGHT_SENSOR_DEBOUNCED ,
1022+ time + SYNTHETIC_LIGHT_SENSOR_RATE_MILLIS );
9521023 }
9531024 }
9541025
9551026 private void debounceLightSensor () {
956- updateAmbientLux (SystemClock .uptimeMillis ());
1027+ if (mLightSensorEnabled ) {
1028+ long time = SystemClock .uptimeMillis ();
1029+ if (time >= mLastObservedLuxTime + SYNTHETIC_LIGHT_SENSOR_RATE_MILLIS ) {
1030+ if (DEBUG ) {
1031+ Slog .d (TAG , "debounceLightSensor: Synthesizing light sensor measurement "
1032+ + "after " + (time - mLastObservedLuxTime ) + " ms." );
1033+ }
1034+ applyLightSensorMeasurement (time , mLastObservedLux );
1035+ }
1036+ updateAmbientLux (time );
1037+ }
9571038 }
9581039
9591040 private void updateAutoBrightness (boolean sendUpdate ) {
@@ -1124,16 +1205,14 @@ private void dumpLocal(PrintWriter pw) {
11241205 + TimeUtils .formatUptime (mLightSensorEnableTime ));
11251206 pw .println (" mAmbientLux=" + mAmbientLux );
11261207 pw .println (" mAmbientLuxValid=" + mAmbientLuxValid );
1127- pw .println (" mLastAmbientBrightenTime="
1128- + TimeUtils .formatUptime (mLastAmbientBrightenTime ));
1129- pw .println (" mLastAmbientDimTime="
1130- + TimeUtils .formatUptime (mLastAmbientDarkenTime ));
11311208 pw .println (" mLastObservedLux=" + mLastObservedLux );
11321209 pw .println (" mLastObservedLuxTime="
11331210 + TimeUtils .formatUptime (mLastObservedLuxTime ));
11341211 pw .println (" mRecentLightSamples=" + mRecentLightSamples );
11351212 pw .println (" mRecentShortTermAverageLux=" + mRecentShortTermAverageLux );
11361213 pw .println (" mRecentLongTermAverageLux=" + mRecentLongTermAverageLux );
1214+ pw .println (" mDebounceLuxDirection=" + mDebounceLuxDirection );
1215+ pw .println (" mDebounceLuxTime=" + TimeUtils .formatUptime (mDebounceLuxTime ));
11371216 pw .println (" mScreenAutoBrightness=" + mScreenAutoBrightness );
11381217 pw .println (" mUsingScreenAutoBrightness=" + mUsingScreenAutoBrightness );
11391218 pw .println (" mLastScreenAutoBrightnessGamma=" + mLastScreenAutoBrightnessGamma );
0 commit comments