blob: dcf7da2cfdf9c59a22bbd5ad69106d1d232193a5 [file] [log] [blame]
Jeff Brown96307042012-07-27 15:51:34 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jeff Brownad9ef192014-04-08 17:26:30 -070017package com.android.server.display;
Jeff Brown96307042012-07-27 15:51:34 -070018
Jeff Brownad9ef192014-04-08 17:26:30 -070019import com.android.internal.app.IBatteryStats;
20import com.android.server.LocalServices;
21import com.android.server.am.BatteryStatsService;
Adam Lesinski182f73f2013-12-05 16:48:06 -080022import com.android.server.lights.LightsManager;
23import com.android.server.twilight.TwilightListener;
24import com.android.server.twilight.TwilightManager;
Adam Lesinski182f73f2013-12-05 16:48:06 -080025import com.android.server.twilight.TwilightState;
Jeff Brown96307042012-07-27 15:51:34 -070026
27import android.animation.Animator;
28import android.animation.ObjectAnimator;
29import android.content.Context;
30import android.content.res.Resources;
31import android.hardware.Sensor;
32import android.hardware.SensorEvent;
33import android.hardware.SensorEventListener;
34import android.hardware.SensorManager;
Jeff Brownad9ef192014-04-08 17:26:30 -070035import android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks;
36import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
Jeff Brown96307042012-07-27 15:51:34 -070037import android.os.Handler;
38import android.os.Looper;
39import android.os.Message;
Jeff Brown330560f2012-08-21 22:10:57 -070040import android.os.PowerManager;
Jeff Brownad9ef192014-04-08 17:26:30 -070041import android.os.RemoteException;
Jeff Brown96307042012-07-27 15:51:34 -070042import android.os.SystemClock;
Jeff Brown330560f2012-08-21 22:10:57 -070043import android.text.format.DateUtils;
44import android.util.FloatMath;
Jeff Brown96307042012-07-27 15:51:34 -070045import android.util.Slog;
Jeff Brown1a30b552012-08-16 01:31:11 -070046import android.util.Spline;
Jeff Brown96307042012-07-27 15:51:34 -070047import android.util.TimeUtils;
48
49import java.io.PrintWriter;
Jeff Brown96307042012-07-27 15:51:34 -070050
51/**
52 * Controls the power state of the display.
53 *
54 * Handles the proximity sensor, light sensor, and animations between states
55 * including the screen off animation.
56 *
57 * This component acts independently of the rest of the power manager service.
58 * In particular, it does not share any state and it only communicates
59 * via asynchronous callbacks to inform the power manager that something has
60 * changed.
61 *
62 * Everything this class does internally is serialized on its handler although
63 * it may be accessed by other threads from the outside.
64 *
65 * Note that the power manager service guarantees that it will hold a suspend
66 * blocker as long as the display is not ready. So most of the work done here
67 * does not need to worry about holding a suspend blocker unless it happens
68 * independently of the display ready signal.
69 *
70 * For debugging, you can make the electron beam and brightness animations run
71 * slower by changing the "animator duration scale" option in Development Settings.
72 */
73final class DisplayPowerController {
74 private static final String TAG = "DisplayPowerController";
75
76 private static boolean DEBUG = false;
77 private static final boolean DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT = false;
78 private static final boolean DEBUG_PRETEND_LIGHT_SENSOR_ABSENT = false;
79
Jeff Brown13c589b2012-08-16 16:20:54 -070080 // If true, uses the electron beam on animation.
81 // We might want to turn this off if we cannot get a guarantee that the screen
82 // actually turns on and starts showing new content after the call to set the
Jeff Brown5356c7dc2012-08-20 20:17:36 -070083 // screen state returns. Playing the animation can also be somewhat slow.
84 private static final boolean USE_ELECTRON_BEAM_ON_ANIMATION = false;
Jeff Brown13c589b2012-08-16 16:20:54 -070085
Jeff Brown330560f2012-08-21 22:10:57 -070086 // If true, enables the use of the screen auto-brightness adjustment setting.
Jeff Brown631938f2012-09-08 15:11:11 -070087 private static final boolean USE_SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT =
88 PowerManager.useScreenAutoBrightnessAdjustmentFeature();
Jeff Brown330560f2012-08-21 22:10:57 -070089
90 // The maximum range of gamma adjustment possible using the screen
91 // auto-brightness adjustment setting.
92 private static final float SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT_MAX_GAMMA = 3.0f;
93
Jeff Brownb76eebff2012-10-05 22:26:44 -070094 // The minimum reduction in brightness when dimmed.
95 private static final int SCREEN_DIM_MINIMUM_REDUCTION = 10;
96
Jeff Brownaa202a62012-08-21 22:14:26 -070097 // If true, enables the use of the current time as an auto-brightness adjustment.
98 // The basic idea here is to expand the dynamic range of auto-brightness
99 // when it is especially dark outside. The light sensor tends to perform
100 // poorly at low light levels so we compensate for it by making an
101 // assumption about the environment.
Jeff Browndb212842012-10-01 14:33:09 -0700102 private static final boolean USE_TWILIGHT_ADJUSTMENT =
103 PowerManager.useTwilightAdjustmentFeature();
Jeff Brownaa202a62012-08-21 22:14:26 -0700104
105 // Specifies the maximum magnitude of the time of day adjustment.
106 private static final float TWILIGHT_ADJUSTMENT_MAX_GAMMA = 1.5f;
107
108 // The amount of time after or before sunrise over which to start adjusting
109 // the gamma. We want the change to happen gradually so that it is below the
110 // threshold of perceptibility and so that the adjustment has maximum effect
111 // well after dusk.
112 private static final long TWILIGHT_ADJUSTMENT_TIME = DateUtils.HOUR_IN_MILLIS * 2;
113
Jeff Brown00a8f4f2012-08-21 23:11:46 -0700114 private static final int ELECTRON_BEAM_ON_ANIMATION_DURATION_MILLIS = 250;
Jeff Brown3c584f22012-10-10 14:36:00 -0700115 private static final int ELECTRON_BEAM_OFF_ANIMATION_DURATION_MILLIS = 400;
Jeff Brown96307042012-07-27 15:51:34 -0700116
117 private static final int MSG_UPDATE_POWER_STATE = 1;
118 private static final int MSG_PROXIMITY_SENSOR_DEBOUNCED = 2;
119 private static final int MSG_LIGHT_SENSOR_DEBOUNCED = 3;
120
121 private static final int PROXIMITY_UNKNOWN = -1;
122 private static final int PROXIMITY_NEGATIVE = 0;
123 private static final int PROXIMITY_POSITIVE = 1;
124
Jeff Brown93cbbb22012-10-04 13:18:36 -0700125 // Proximity sensor debounce delay in milliseconds for positive or negative transitions.
126 private static final int PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY = 0;
Jeff Brownec083212013-09-11 20:45:25 -0700127 private static final int PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY = 250;
Jeff Brown96307042012-07-27 15:51:34 -0700128
129 // Trigger proximity if distance is less than 5 cm.
130 private static final float TYPICAL_PROXIMITY_THRESHOLD = 5.0f;
131
Jeff Browne941b1e2012-10-22 16:50:25 -0700132 // Light sensor event rate in milliseconds.
133 private static final int LIGHT_SENSOR_RATE_MILLIS = 1000;
134
135 // A rate for generating synthetic light sensor events in the case where the light
136 // sensor hasn't reported any new data in a while and we need it to update the
137 // debounce filter. We only synthesize light sensor measurements when needed.
138 private static final int SYNTHETIC_LIGHT_SENSOR_RATE_MILLIS =
139 LIGHT_SENSOR_RATE_MILLIS * 2;
Jeff Brown96307042012-07-27 15:51:34 -0700140
141 // Brightness animation ramp rate in brightness units per second.
142 private static final int BRIGHTNESS_RAMP_RATE_FAST = 200;
Jeff Browne941b1e2012-10-22 16:50:25 -0700143 private static final int BRIGHTNESS_RAMP_RATE_SLOW = 40;
Jeff Brown96307042012-07-27 15:51:34 -0700144
Jeff Brown4f0e9692012-10-18 16:14:16 -0700145 // IIR filter time constants in milliseconds for computing two moving averages of
146 // the light samples. One is a long-term average and the other is a short-term average.
147 // We can use these filters to assess trends in ambient brightness.
148 // The short term average gives us a filtered but relatively low latency measurement.
149 // The long term average informs us about the overall trend.
150 private static final long SHORT_TERM_AVERAGE_LIGHT_TIME_CONSTANT = 1000;
Jeff Browne941b1e2012-10-22 16:50:25 -0700151 private static final long LONG_TERM_AVERAGE_LIGHT_TIME_CONSTANT = 5000;
Jeff Brown06565b62012-08-15 21:10:32 -0700152
153 // Stability requirements in milliseconds for accepting a new brightness
154 // level. This is used for debouncing the light sensor. Different constants
Jeff Brown4f0e9692012-10-18 16:14:16 -0700155 // are used to debounce the light sensor when adapting to brighter or darker environments.
Jeff Brown06565b62012-08-15 21:10:32 -0700156 // This parameter controls how quickly brightness changes occur in response to
Jeff Browne941b1e2012-10-22 16:50:25 -0700157 // an observed change in light level that exceeds the hysteresis threshold.
158 private static final long BRIGHTENING_LIGHT_DEBOUNCE = 4000;
159 private static final long DARKENING_LIGHT_DEBOUNCE = 8000;
Jeff Brown4f0e9692012-10-18 16:14:16 -0700160
161 // Hysteresis constraints for brightening or darkening.
162 // The recent lux must have changed by at least this fraction relative to the
163 // current ambient lux before a change will be considered.
164 private static final float BRIGHTENING_LIGHT_HYSTERESIS = 0.10f;
165 private static final float DARKENING_LIGHT_HYSTERESIS = 0.20f;
Jeff Brown96307042012-07-27 15:51:34 -0700166
167 private final Object mLock = new Object();
168
Jeff Brown96307042012-07-27 15:51:34 -0700169 // Our handler.
170 private final DisplayControllerHandler mHandler;
171
172 // Asynchronous callbacks into the power manager service.
173 // Only invoked from the handler thread while no locks are held.
Jeff Brownad9ef192014-04-08 17:26:30 -0700174 private final DisplayPowerCallbacks mCallbacks;
175
176 // Battery stats.
177 private final IBatteryStats mBatteryStats;
Jeff Brown96307042012-07-27 15:51:34 -0700178
179 // The lights service.
Adam Lesinski182f73f2013-12-05 16:48:06 -0800180 private final LightsManager mLights;
Jeff Brown96307042012-07-27 15:51:34 -0700181
Jeff Brownaa202a62012-08-21 22:14:26 -0700182 // The twilight service.
Adam Lesinski182f73f2013-12-05 16:48:06 -0800183 private final TwilightManager mTwilight;
Jeff Brownaa202a62012-08-21 22:14:26 -0700184
Jeff Brown96307042012-07-27 15:51:34 -0700185 // The sensor manager.
186 private final SensorManager mSensorManager;
187
188 // The proximity sensor, or null if not available or needed.
189 private Sensor mProximitySensor;
190
191 // The light sensor, or null if not available or needed.
192 private Sensor mLightSensor;
193
Jeff Brown26875502014-01-30 21:47:47 -0800194 // The doze screen brightness.
195 private final int mScreenBrightnessDozeConfig;
196
Jeff Brown96307042012-07-27 15:51:34 -0700197 // The dim screen brightness.
198 private final int mScreenBrightnessDimConfig;
199
Jeff Brownb76eebff2012-10-05 22:26:44 -0700200 // The minimum allowed brightness.
201 private final int mScreenBrightnessRangeMinimum;
202
203 // The maximum allowed brightness.
204 private final int mScreenBrightnessRangeMaximum;
205
Jeff Brown330560f2012-08-21 22:10:57 -0700206 // True if auto-brightness should be used.
Jeff Brown96307042012-07-27 15:51:34 -0700207 private boolean mUseSoftwareAutoBrightnessConfig;
Jeff Brown330560f2012-08-21 22:10:57 -0700208
209 // The auto-brightness spline adjustment.
210 // The brightness values have been scaled to a range of 0..1.
Jeff Brown1a30b552012-08-16 01:31:11 -0700211 private Spline mScreenAutoBrightnessSpline;
Jeff Brown96307042012-07-27 15:51:34 -0700212
213 // Amount of time to delay auto-brightness after screen on while waiting for
214 // the light sensor to warm-up in milliseconds.
215 // May be 0 if no warm-up is required.
216 private int mLightSensorWarmUpTimeConfig;
217
Jeff Brown252c2062012-10-08 16:21:01 -0700218 // True if we should fade the screen while turning it off, false if we should play
219 // a stylish electron beam animation instead.
220 private boolean mElectronBeamFadesConfig;
Jeff Browna52772f2012-10-04 18:38:09 -0700221
Jeff Brown96307042012-07-27 15:51:34 -0700222 // The pending power request.
223 // Initially null until the first call to requestPowerState.
224 // Guarded by mLock.
225 private DisplayPowerRequest mPendingRequestLocked;
226
227 // True if a request has been made to wait for the proximity sensor to go negative.
228 // Guarded by mLock.
229 private boolean mPendingWaitForNegativeProximityLocked;
230
231 // True if the pending power request or wait for negative proximity flag
232 // has been changed since the last update occurred.
233 // Guarded by mLock.
234 private boolean mPendingRequestChangedLocked;
235
236 // Set to true when the important parts of the pending power request have been applied.
237 // The important parts are mainly the screen state. Brightness changes may occur
238 // concurrently.
239 // Guarded by mLock.
240 private boolean mDisplayReadyLocked;
241
242 // Set to true if a power state update is required.
243 // Guarded by mLock.
244 private boolean mPendingUpdatePowerStateLocked;
245
246 /* The following state must only be accessed by the handler thread. */
247
248 // The currently requested power state.
249 // The power controller will progressively update its internal state to match
250 // the requested power state. Initially null until the first update.
251 private DisplayPowerRequest mPowerRequest;
252
253 // The current power state.
254 // Must only be accessed on the handler thread.
255 private DisplayPowerState mPowerState;
256
257 // True if the device should wait for negative proximity sensor before
258 // waking up the screen. This is set to false as soon as a negative
259 // proximity sensor measurement is observed or when the device is forced to
260 // go to sleep by the user. While true, the screen remains off.
261 private boolean mWaitingForNegativeProximity;
262
263 // The actual proximity sensor threshold value.
264 private float mProximityThreshold;
265
266 // Set to true if the proximity sensor listener has been registered
267 // with the sensor manager.
268 private boolean mProximitySensorEnabled;
269
270 // The debounced proximity sensor state.
271 private int mProximity = PROXIMITY_UNKNOWN;
272
273 // The raw non-debounced proximity sensor state.
274 private int mPendingProximity = PROXIMITY_UNKNOWN;
Jeff Brownec083212013-09-11 20:45:25 -0700275 private long mPendingProximityDebounceTime = -1; // -1 if fully debounced
Jeff Brown96307042012-07-27 15:51:34 -0700276
277 // True if the screen was turned off because of the proximity sensor.
278 // When the screen turns on again, we report user activity to the power manager.
279 private boolean mScreenOffBecauseOfProximity;
280
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700281 // True if the screen on is being blocked.
282 private boolean mScreenOnWasBlocked;
283
284 // The elapsed real time when the screen on was blocked.
285 private long mScreenOnBlockStartRealTime;
286
Jeff Brown96307042012-07-27 15:51:34 -0700287 // Set to true if the light sensor is enabled.
288 private boolean mLightSensorEnabled;
289
290 // The time when the light sensor was enabled.
291 private long mLightSensorEnableTime;
292
Jeff Brown4f0e9692012-10-18 16:14:16 -0700293 // The currently accepted nominal ambient light level.
294 private float mAmbientLux;
Jeff Brown96307042012-07-27 15:51:34 -0700295
Jeff Brown4f0e9692012-10-18 16:14:16 -0700296 // True if mAmbientLux holds a valid value.
297 private boolean mAmbientLuxValid;
Jeff Brown96307042012-07-27 15:51:34 -0700298
Michael Wright65031a22013-11-04 19:07:49 -0800299 // The ambient light level threshold at which to brighten or darken the screen.
300 private float mBrighteningLuxThreshold;
301 private float mDarkeningLuxThreshold;
302
Jeff Brown96307042012-07-27 15:51:34 -0700303 // The most recent light sample.
Jeff Brown4f0e9692012-10-18 16:14:16 -0700304 private float mLastObservedLux;
Jeff Brown96307042012-07-27 15:51:34 -0700305
306 // The time of the most light recent sample.
Jeff Brown4f0e9692012-10-18 16:14:16 -0700307 private long mLastObservedLuxTime;
Jeff Brown96307042012-07-27 15:51:34 -0700308
Jeff Brown4f0e9692012-10-18 16:14:16 -0700309 // The number of light samples collected since the light sensor was enabled.
310 private int mRecentLightSamples;
Jeff Brown06565b62012-08-15 21:10:32 -0700311
Jeff Brown4f0e9692012-10-18 16:14:16 -0700312 // The long-term and short-term filtered light measurements.
313 private float mRecentShortTermAverageLux;
314 private float mRecentLongTermAverageLux;
Jeff Brown96307042012-07-27 15:51:34 -0700315
Jeff Browne941b1e2012-10-22 16:50:25 -0700316 // The direction in which the average lux is moving relative to the current ambient lux.
317 // 0 if not changing or within hysteresis threshold.
318 // 1 if brightening beyond hysteresis threshold.
319 // -1 if darkening beyond hysteresis threshold.
320 private int mDebounceLuxDirection;
321
322 // The time when the average lux last changed direction.
323 private long mDebounceLuxTime;
324
Jeff Brown96307042012-07-27 15:51:34 -0700325 // The screen brightness level that has been chosen by the auto-brightness
326 // algorithm. The actual brightness should ramp towards this value.
327 // We preserve this value even when we stop using the light sensor so
328 // that we can quickly revert to the previous auto-brightness level
329 // while the light sensor warms up.
330 // Use -1 if there is no current auto-brightness value available.
331 private int mScreenAutoBrightness = -1;
332
Jeff Brown330560f2012-08-21 22:10:57 -0700333 // The last screen auto-brightness gamma. (For printing in dump() only.)
334 private float mLastScreenAutoBrightnessGamma = 1.0f;
335
Jeff Brown96307042012-07-27 15:51:34 -0700336 // True if the screen auto-brightness value is actually being used to
337 // set the display brightness.
338 private boolean mUsingScreenAutoBrightness;
339
340 // Animators.
341 private ObjectAnimator mElectronBeamOnAnimator;
342 private ObjectAnimator mElectronBeamOffAnimator;
343 private RampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator;
344
Jeff Brownaa202a62012-08-21 22:14:26 -0700345 // Twilight changed. We might recalculate auto-brightness values.
346 private boolean mTwilightChanged;
347
Jeff Brown96307042012-07-27 15:51:34 -0700348 /**
349 * Creates the display power controller.
350 */
Jeff Brownad9ef192014-04-08 17:26:30 -0700351 public DisplayPowerController(Context context,
352 DisplayPowerCallbacks callbacks, Handler handler, SensorManager sensorManager) {
353 mHandler = new DisplayControllerHandler(handler.getLooper());
Jeff Brown96307042012-07-27 15:51:34 -0700354 mCallbacks = callbacks;
Jeff Brown96307042012-07-27 15:51:34 -0700355
Jeff Brownad9ef192014-04-08 17:26:30 -0700356 mBatteryStats = BatteryStatsService.getService();
357 mLights = LocalServices.getService(LightsManager.class);
358 mTwilight = LocalServices.getService(TwilightManager.class);
Jeff Brown3b971592013-01-09 18:46:37 -0800359 mSensorManager = sensorManager;
Jeff Brown96307042012-07-27 15:51:34 -0700360
361 final Resources resources = context.getResources();
Jeff Brownb76eebff2012-10-05 22:26:44 -0700362
Jeff Brown26875502014-01-30 21:47:47 -0800363 mScreenBrightnessDozeConfig = clampAbsoluteBrightness(resources.getInteger(
364 com.android.internal.R.integer.config_screenBrightnessDoze));
365
Jeff Brownb76eebff2012-10-05 22:26:44 -0700366 mScreenBrightnessDimConfig = clampAbsoluteBrightness(resources.getInteger(
367 com.android.internal.R.integer.config_screenBrightnessDim));
368
369 int screenBrightnessMinimum = Math.min(resources.getInteger(
370 com.android.internal.R.integer.config_screenBrightnessSettingMinimum),
371 mScreenBrightnessDimConfig);
372
Jeff Brown96307042012-07-27 15:51:34 -0700373 mUseSoftwareAutoBrightnessConfig = resources.getBoolean(
374 com.android.internal.R.bool.config_automatic_brightness_available);
375 if (mUseSoftwareAutoBrightnessConfig) {
Jeff Brown1a30b552012-08-16 01:31:11 -0700376 int[] lux = resources.getIntArray(
Jeff Brown96307042012-07-27 15:51:34 -0700377 com.android.internal.R.array.config_autoBrightnessLevels);
Jeff Brown1a30b552012-08-16 01:31:11 -0700378 int[] screenBrightness = resources.getIntArray(
Jeff Brown96307042012-07-27 15:51:34 -0700379 com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
Jeff Brown1a30b552012-08-16 01:31:11 -0700380
381 mScreenAutoBrightnessSpline = createAutoBrightnessSpline(lux, screenBrightness);
382 if (mScreenAutoBrightnessSpline == null) {
Jeff Brown96307042012-07-27 15:51:34 -0700383 Slog.e(TAG, "Error in config.xml. config_autoBrightnessLcdBacklightValues "
Jeff Brown1a30b552012-08-16 01:31:11 -0700384 + "(size " + screenBrightness.length + ") "
385 + "must be monotic and have exactly one more entry than "
386 + "config_autoBrightnessLevels (size " + lux.length + ") "
387 + "which must be strictly increasing. "
Jeff Brown96307042012-07-27 15:51:34 -0700388 + "Auto-brightness will be disabled.");
389 mUseSoftwareAutoBrightnessConfig = false;
Jeff Brownb76eebff2012-10-05 22:26:44 -0700390 } else {
391 if (screenBrightness[0] < screenBrightnessMinimum) {
392 screenBrightnessMinimum = screenBrightness[0];
393 }
Jeff Brown96307042012-07-27 15:51:34 -0700394 }
395
396 mLightSensorWarmUpTimeConfig = resources.getInteger(
397 com.android.internal.R.integer.config_lightSensorWarmupTime);
398 }
399
Jeff Brownb76eebff2012-10-05 22:26:44 -0700400 mScreenBrightnessRangeMinimum = clampAbsoluteBrightness(screenBrightnessMinimum);
401 mScreenBrightnessRangeMaximum = PowerManager.BRIGHTNESS_ON;
402
Jeff Brown252c2062012-10-08 16:21:01 -0700403 mElectronBeamFadesConfig = resources.getBoolean(
Jeff Browna52772f2012-10-04 18:38:09 -0700404 com.android.internal.R.bool.config_animateScreenLights);
405
Jeff Brown96307042012-07-27 15:51:34 -0700406 if (!DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) {
407 mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
408 if (mProximitySensor != null) {
409 mProximityThreshold = Math.min(mProximitySensor.getMaximumRange(),
410 TYPICAL_PROXIMITY_THRESHOLD);
411 }
412 }
413
414 if (mUseSoftwareAutoBrightnessConfig
415 && !DEBUG_PRETEND_LIGHT_SENSOR_ABSENT) {
416 mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
417 }
Jeff Brownaa202a62012-08-21 22:14:26 -0700418
419 if (mUseSoftwareAutoBrightnessConfig && USE_TWILIGHT_ADJUSTMENT) {
420 mTwilight.registerListener(mTwilightListener, mHandler);
421 }
Jeff Brown96307042012-07-27 15:51:34 -0700422 }
423
Jeff Brown1a30b552012-08-16 01:31:11 -0700424 private static Spline createAutoBrightnessSpline(int[] lux, int[] brightness) {
425 try {
426 final int n = brightness.length;
427 float[] x = new float[n];
428 float[] y = new float[n];
Jeff Brownb76eebff2012-10-05 22:26:44 -0700429 y[0] = normalizeAbsoluteBrightness(brightness[0]);
Jeff Brown1a30b552012-08-16 01:31:11 -0700430 for (int i = 1; i < n; i++) {
431 x[i] = lux[i - 1];
Jeff Brownb76eebff2012-10-05 22:26:44 -0700432 y[i] = normalizeAbsoluteBrightness(brightness[i]);
Jeff Brown1a30b552012-08-16 01:31:11 -0700433 }
434
435 Spline spline = Spline.createMonotoneCubicSpline(x, y);
Jeff Brownb76eebff2012-10-05 22:26:44 -0700436 if (DEBUG) {
Jeff Brown1a30b552012-08-16 01:31:11 -0700437 Slog.d(TAG, "Auto-brightness spline: " + spline);
438 for (float v = 1f; v < lux[lux.length - 1] * 1.25f; v *= 1.25f) {
439 Slog.d(TAG, String.format(" %7.1f: %7.1f", v, spline.interpolate(v)));
440 }
441 }
442 return spline;
443 } catch (IllegalArgumentException ex) {
444 Slog.e(TAG, "Could not create auto-brightness spline.", ex);
445 return null;
446 }
447 }
448
Jeff Brown96307042012-07-27 15:51:34 -0700449 /**
450 * Returns true if the proximity sensor screen-off function is available.
451 */
452 public boolean isProximitySensorAvailable() {
453 return mProximitySensor != null;
454 }
455
456 /**
457 * Requests a new power state.
458 * The controller makes a copy of the provided object and then
459 * begins adjusting the power state to match what was requested.
460 *
461 * @param request The requested power state.
462 * @param waitForNegativeProximity If true, issues a request to wait for
463 * negative proximity before turning the screen back on, assuming the screen
464 * was turned off by the proximity sensor.
465 * @return True if display is ready, false if there are important changes that must
466 * be made asynchronously (such as turning the screen on), in which case the caller
467 * should grab a wake lock, watch for {@link Callbacks#onStateChanged()} then try
468 * the request again later until the state converges.
469 */
470 public boolean requestPowerState(DisplayPowerRequest request,
471 boolean waitForNegativeProximity) {
472 if (DEBUG) {
473 Slog.d(TAG, "requestPowerState: "
474 + request + ", waitForNegativeProximity=" + waitForNegativeProximity);
475 }
476
477 synchronized (mLock) {
478 boolean changed = false;
479
480 if (waitForNegativeProximity
481 && !mPendingWaitForNegativeProximityLocked) {
482 mPendingWaitForNegativeProximityLocked = true;
483 changed = true;
484 }
485
486 if (mPendingRequestLocked == null) {
487 mPendingRequestLocked = new DisplayPowerRequest(request);
488 changed = true;
489 } else if (!mPendingRequestLocked.equals(request)) {
490 mPendingRequestLocked.copyFrom(request);
491 changed = true;
492 }
493
494 if (changed) {
495 mDisplayReadyLocked = false;
496 }
497
498 if (changed && !mPendingRequestChangedLocked) {
499 mPendingRequestChangedLocked = true;
500 sendUpdatePowerStateLocked();
501 }
502
503 return mDisplayReadyLocked;
504 }
505 }
506
507 private void sendUpdatePowerState() {
508 synchronized (mLock) {
509 sendUpdatePowerStateLocked();
510 }
511 }
512
513 private void sendUpdatePowerStateLocked() {
514 if (!mPendingUpdatePowerStateLocked) {
515 mPendingUpdatePowerStateLocked = true;
516 Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE);
517 msg.setAsynchronous(true);
518 mHandler.sendMessage(msg);
519 }
520 }
521
522 private void initialize() {
Jeff Brownad9ef192014-04-08 17:26:30 -0700523 mPowerState = new DisplayPowerState(new ElectronBeam(), mCallbacks,
Adam Lesinski182f73f2013-12-05 16:48:06 -0800524 mLights.getLight(LightsManager.LIGHT_ID_BACKLIGHT));
Jeff Brown96307042012-07-27 15:51:34 -0700525
526 mElectronBeamOnAnimator = ObjectAnimator.ofFloat(
527 mPowerState, DisplayPowerState.ELECTRON_BEAM_LEVEL, 0.0f, 1.0f);
528 mElectronBeamOnAnimator.setDuration(ELECTRON_BEAM_ON_ANIMATION_DURATION_MILLIS);
529 mElectronBeamOnAnimator.addListener(mAnimatorListener);
530
531 mElectronBeamOffAnimator = ObjectAnimator.ofFloat(
532 mPowerState, DisplayPowerState.ELECTRON_BEAM_LEVEL, 1.0f, 0.0f);
533 mElectronBeamOffAnimator.setDuration(ELECTRON_BEAM_OFF_ANIMATION_DURATION_MILLIS);
534 mElectronBeamOffAnimator.addListener(mAnimatorListener);
535
536 mScreenBrightnessRampAnimator = new RampAnimator<DisplayPowerState>(
537 mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS);
538 }
539
540 private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() {
541 @Override
542 public void onAnimationStart(Animator animation) {
543 }
544 @Override
545 public void onAnimationEnd(Animator animation) {
546 sendUpdatePowerState();
547 }
548 @Override
549 public void onAnimationRepeat(Animator animation) {
550 }
551 @Override
552 public void onAnimationCancel(Animator animation) {
553 }
554 };
555
556 private void updatePowerState() {
557 // Update the power state request.
558 final boolean mustNotify;
559 boolean mustInitialize = false;
Jeff Brownaa202a62012-08-21 22:14:26 -0700560 boolean updateAutoBrightness = mTwilightChanged;
Jeff Brown26875502014-01-30 21:47:47 -0800561 boolean wasDimOrDoze = false;
Jeff Brownaa202a62012-08-21 22:14:26 -0700562 mTwilightChanged = false;
Jeff Brown330560f2012-08-21 22:10:57 -0700563
Jeff Brown96307042012-07-27 15:51:34 -0700564 synchronized (mLock) {
565 mPendingUpdatePowerStateLocked = false;
566 if (mPendingRequestLocked == null) {
567 return; // wait until first actual power request
568 }
569
570 if (mPowerRequest == null) {
571 mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked);
572 mWaitingForNegativeProximity = mPendingWaitForNegativeProximityLocked;
Jeff Brown6307a152012-08-20 13:24:23 -0700573 mPendingWaitForNegativeProximityLocked = false;
Jeff Brown96307042012-07-27 15:51:34 -0700574 mPendingRequestChangedLocked = false;
575 mustInitialize = true;
576 } else if (mPendingRequestChangedLocked) {
Jeff Brown330560f2012-08-21 22:10:57 -0700577 if (mPowerRequest.screenAutoBrightnessAdjustment
578 != mPendingRequestLocked.screenAutoBrightnessAdjustment) {
579 updateAutoBrightness = true;
580 }
Jeff Brown26875502014-01-30 21:47:47 -0800581 wasDimOrDoze = (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DIM
582 || mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DOZE);
Jeff Brown96307042012-07-27 15:51:34 -0700583 mPowerRequest.copyFrom(mPendingRequestLocked);
584 mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked;
Jeff Brown6307a152012-08-20 13:24:23 -0700585 mPendingWaitForNegativeProximityLocked = false;
Jeff Brown96307042012-07-27 15:51:34 -0700586 mPendingRequestChangedLocked = false;
587 mDisplayReadyLocked = false;
588 }
589
590 mustNotify = !mDisplayReadyLocked;
591 }
592
593 // Initialize things the first time the power state is changed.
594 if (mustInitialize) {
595 initialize();
596 }
597
Jeff Brown6307a152012-08-20 13:24:23 -0700598 // Apply the proximity sensor.
Jeff Brown96307042012-07-27 15:51:34 -0700599 if (mProximitySensor != null) {
Jeff Brown6307a152012-08-20 13:24:23 -0700600 if (mPowerRequest.useProximitySensor
601 && mPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF) {
602 setProximitySensorEnabled(true);
603 if (!mScreenOffBecauseOfProximity
604 && mProximity == PROXIMITY_POSITIVE) {
605 mScreenOffBecauseOfProximity = true;
Jeff Brownec083212013-09-11 20:45:25 -0700606 sendOnProximityPositiveWithWakelock();
Jeff Brown6307a152012-08-20 13:24:23 -0700607 }
608 } else if (mWaitingForNegativeProximity
609 && mScreenOffBecauseOfProximity
610 && mProximity == PROXIMITY_POSITIVE
611 && mPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF) {
612 setProximitySensorEnabled(true);
613 } else {
614 setProximitySensorEnabled(false);
615 mWaitingForNegativeProximity = false;
616 }
617 if (mScreenOffBecauseOfProximity
618 && mProximity != PROXIMITY_POSITIVE) {
Jeff Brown96307042012-07-27 15:51:34 -0700619 mScreenOffBecauseOfProximity = false;
Jeff Brownec083212013-09-11 20:45:25 -0700620 sendOnProximityNegativeWithWakelock();
Jeff Brown96307042012-07-27 15:51:34 -0700621 }
Jeff Brown6307a152012-08-20 13:24:23 -0700622 } else {
623 mWaitingForNegativeProximity = false;
Jeff Brown96307042012-07-27 15:51:34 -0700624 }
625
626 // Turn on the light sensor if needed.
627 if (mLightSensor != null) {
Jeff Brown26875502014-01-30 21:47:47 -0800628 setLightSensorEnabled(mPowerRequest.wantLightSensorEnabled(),
629 updateAutoBrightness);
Jeff Brown96307042012-07-27 15:51:34 -0700630 }
631
632 // Set the screen brightness.
Jeff Brown26875502014-01-30 21:47:47 -0800633 if (mPowerRequest.wantScreenOnAny()) {
Jeff Brownb76eebff2012-10-05 22:26:44 -0700634 int target;
635 boolean slow;
Jeff Brown96307042012-07-27 15:51:34 -0700636 if (mScreenAutoBrightness >= 0 && mLightSensorEnabled) {
637 // Use current auto-brightness value.
Jeff Brownb76eebff2012-10-05 22:26:44 -0700638 target = mScreenAutoBrightness;
639 slow = mUsingScreenAutoBrightness;
Jeff Brown96307042012-07-27 15:51:34 -0700640 mUsingScreenAutoBrightness = true;
641 } else {
642 // Light sensor is disabled or not ready yet.
643 // Use the current brightness setting from the request, which is expected
644 // provide a nominal default value for the case where auto-brightness
645 // is not ready yet.
Jeff Brownb76eebff2012-10-05 22:26:44 -0700646 target = mPowerRequest.screenBrightness;
647 slow = false;
Jeff Brown96307042012-07-27 15:51:34 -0700648 mUsingScreenAutoBrightness = false;
649 }
Jeff Brown26875502014-01-30 21:47:47 -0800650 if (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DOZE) {
651 // Dim quickly to the doze state.
652 target = mScreenBrightnessDozeConfig;
653 slow = false;
654 } else if (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DIM) {
Jeff Brown5244c932012-10-24 14:46:26 -0700655 // Dim quickly by at least some minimum amount.
Jeff Brownb76eebff2012-10-05 22:26:44 -0700656 target = Math.min(target - SCREEN_DIM_MINIMUM_REDUCTION,
657 mScreenBrightnessDimConfig);
Jeff Brown5244c932012-10-24 14:46:26 -0700658 slow = false;
Jeff Brown26875502014-01-30 21:47:47 -0800659 } else if (wasDimOrDoze) {
Jeff Browne941b1e2012-10-22 16:50:25 -0700660 // Brighten quickly.
Jeff Brownb76eebff2012-10-05 22:26:44 -0700661 slow = false;
662 }
663 animateScreenBrightness(clampScreenBrightness(target),
664 slow ? BRIGHTNESS_RAMP_RATE_SLOW : BRIGHTNESS_RAMP_RATE_FAST);
Jeff Brown96307042012-07-27 15:51:34 -0700665 } else {
666 // Screen is off. Don't bother changing the brightness.
667 mUsingScreenAutoBrightness = false;
668 }
669
Jeff Brown2d8a3902014-03-11 23:02:35 -0700670 // Animate the screen on or off unless blocked.
671 if (mScreenOffBecauseOfProximity) {
672 // Screen off due to proximity.
673 setScreenOn(false);
674 unblockScreenOn();
675 } else if (mPowerRequest.wantScreenOnAny()) {
676 // Want screen on.
677 // Wait for previous off animation to complete beforehand.
678 // It is relatively short but if we cancel it and switch to the
679 // on animation immediately then the results are pretty ugly.
680 if (!mElectronBeamOffAnimator.isStarted()) {
681 // Turn the screen on. The contents of the screen may not yet
682 // be visible if the electron beam has not been dismissed because
683 // its last frame of animation is solid black.
684 setScreenOn(true);
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700685
Jeff Brown2d8a3902014-03-11 23:02:35 -0700686 if (mPowerRequest.blockScreenOn
687 && mPowerState.getElectronBeamLevel() == 0.0f) {
688 blockScreenOn();
689 } else {
690 unblockScreenOn();
691 if (USE_ELECTRON_BEAM_ON_ANIMATION) {
692 if (!mElectronBeamOnAnimator.isStarted()) {
693 if (mPowerState.getElectronBeamLevel() == 1.0f) {
694 mPowerState.dismissElectronBeam();
695 } else if (mPowerState.prepareElectronBeam(
696 mElectronBeamFadesConfig ?
697 ElectronBeam.MODE_FADE :
698 ElectronBeam.MODE_WARM_UP)) {
699 mElectronBeamOnAnimator.start();
700 } else {
701 mElectronBeamOnAnimator.end();
Jeff Brownc38c9be2012-10-04 13:16:19 -0700702 }
Jeff Brownc38c9be2012-10-04 13:16:19 -0700703 }
Jeff Brown2d8a3902014-03-11 23:02:35 -0700704 } else {
705 mPowerState.setElectronBeamLevel(1.0f);
706 mPowerState.dismissElectronBeam();
Jeff Brownc38c9be2012-10-04 13:16:19 -0700707 }
Jeff Brown96307042012-07-27 15:51:34 -0700708 }
Jeff Brown2d8a3902014-03-11 23:02:35 -0700709 }
710 } else {
711 // Want screen off.
712 // Wait for previous on animation to complete beforehand.
713 unblockScreenOn();
714 if (!mElectronBeamOnAnimator.isStarted()) {
715 if (!mElectronBeamOffAnimator.isStarted()) {
716 if (mPowerState.getElectronBeamLevel() == 0.0f) {
717 setScreenOn(false);
718 } else if (mPowerState.prepareElectronBeam(
719 mElectronBeamFadesConfig ?
720 ElectronBeam.MODE_FADE :
721 ElectronBeam.MODE_COOL_DOWN)
722 && mPowerState.isScreenOn()) {
723 mElectronBeamOffAnimator.start();
724 } else {
725 mElectronBeamOffAnimator.end();
Jeff Brown96307042012-07-27 15:51:34 -0700726 }
727 }
728 }
729 }
730
731 // Report whether the display is ready for use.
732 // We mostly care about the screen state here, ignoring brightness changes
733 // which will be handled asynchronously.
734 if (mustNotify
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700735 && !mScreenOnWasBlocked
Jeff Brown96307042012-07-27 15:51:34 -0700736 && !mElectronBeamOnAnimator.isStarted()
737 && !mElectronBeamOffAnimator.isStarted()
738 && mPowerState.waitUntilClean(mCleanListener)) {
739 synchronized (mLock) {
740 if (!mPendingRequestChangedLocked) {
741 mDisplayReadyLocked = true;
Jeff Brownc38c9be2012-10-04 13:16:19 -0700742
743 if (DEBUG) {
744 Slog.d(TAG, "Display ready!");
745 }
Jeff Brown96307042012-07-27 15:51:34 -0700746 }
747 }
Jeff Brownec083212013-09-11 20:45:25 -0700748 sendOnStateChangedWithWakelock();
Jeff Brown96307042012-07-27 15:51:34 -0700749 }
750 }
751
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700752 private void blockScreenOn() {
753 if (!mScreenOnWasBlocked) {
754 mScreenOnWasBlocked = true;
755 if (DEBUG) {
756 Slog.d(TAG, "Blocked screen on.");
757 mScreenOnBlockStartRealTime = SystemClock.elapsedRealtime();
758 }
759 }
760 }
761
762 private void unblockScreenOn() {
763 if (mScreenOnWasBlocked) {
764 mScreenOnWasBlocked = false;
Jeff Brown2d8a3902014-03-11 23:02:35 -0700765 long delay = SystemClock.elapsedRealtime() - mScreenOnBlockStartRealTime;
766 if (delay > 1000 || DEBUG) {
767 Slog.d(TAG, "Unblocked screen on after " + delay + " ms");
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700768 }
769 }
770 }
771
Jeff Brown96307042012-07-27 15:51:34 -0700772 private void setScreenOn(boolean on) {
Jeff Brown2d8a3902014-03-11 23:02:35 -0700773 if (mPowerState.isScreenOn() != on) {
Jeff Brown96307042012-07-27 15:51:34 -0700774 mPowerState.setScreenOn(on);
Jeff Brownad9ef192014-04-08 17:26:30 -0700775 try {
776 if (on) {
777 mBatteryStats.noteScreenOn();
778 } else {
779 mBatteryStats.noteScreenOff();
780 }
781 } catch (RemoteException ex) {
782 // same process
Jeff Brown96307042012-07-27 15:51:34 -0700783 }
784 }
785 }
786
Jeff Brown330560f2012-08-21 22:10:57 -0700787 private int clampScreenBrightness(int value) {
Jeff Brownb76eebff2012-10-05 22:26:44 -0700788 return clamp(value, mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum);
789 }
790
791 private static int clampAbsoluteBrightness(int value) {
792 return clamp(value, PowerManager.BRIGHTNESS_OFF, PowerManager.BRIGHTNESS_ON);
793 }
794
795 private static int clamp(int value, int min, int max) {
796 if (value <= min) {
797 return min;
798 }
799 if (value >= max) {
800 return max;
801 }
802 return value;
803 }
804
805 private static float normalizeAbsoluteBrightness(int value) {
806 return (float)clampAbsoluteBrightness(value) / PowerManager.BRIGHTNESS_ON;
Jeff Brown330560f2012-08-21 22:10:57 -0700807 }
808
Jeff Brown96307042012-07-27 15:51:34 -0700809 private void animateScreenBrightness(int target, int rate) {
810 if (mScreenBrightnessRampAnimator.animateTo(target, rate)) {
Jeff Brownad9ef192014-04-08 17:26:30 -0700811 try {
812 mBatteryStats.noteScreenBrightness(target);
813 } catch (RemoteException ex) {
814 // same process
815 }
Jeff Brown96307042012-07-27 15:51:34 -0700816 }
817 }
818
819 private final Runnable mCleanListener = new Runnable() {
820 @Override
821 public void run() {
822 sendUpdatePowerState();
823 }
824 };
825
826 private void setProximitySensorEnabled(boolean enable) {
827 if (enable) {
828 if (!mProximitySensorEnabled) {
Jeff Brownec083212013-09-11 20:45:25 -0700829 // Register the listener.
830 // Proximity sensor state already cleared initially.
Jeff Brown96307042012-07-27 15:51:34 -0700831 mProximitySensorEnabled = true;
Jeff Brown96307042012-07-27 15:51:34 -0700832 mSensorManager.registerListener(mProximitySensorListener, mProximitySensor,
833 SensorManager.SENSOR_DELAY_NORMAL, mHandler);
834 }
835 } else {
836 if (mProximitySensorEnabled) {
Jeff Brownec083212013-09-11 20:45:25 -0700837 // Unregister the listener.
838 // Clear the proximity sensor state for next time.
Jeff Brown96307042012-07-27 15:51:34 -0700839 mProximitySensorEnabled = false;
840 mProximity = PROXIMITY_UNKNOWN;
Jeff Brownec083212013-09-11 20:45:25 -0700841 mPendingProximity = PROXIMITY_UNKNOWN;
Jeff Brown96307042012-07-27 15:51:34 -0700842 mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
843 mSensorManager.unregisterListener(mProximitySensorListener);
Jeff Brownec083212013-09-11 20:45:25 -0700844 clearPendingProximityDebounceTime(); // release wake lock (must be last)
Jeff Brown96307042012-07-27 15:51:34 -0700845 }
846 }
847 }
848
849 private void handleProximitySensorEvent(long time, boolean positive) {
Jeff Brownec083212013-09-11 20:45:25 -0700850 if (mProximitySensorEnabled) {
851 if (mPendingProximity == PROXIMITY_NEGATIVE && !positive) {
852 return; // no change
853 }
854 if (mPendingProximity == PROXIMITY_POSITIVE && positive) {
855 return; // no change
856 }
Jeff Brown96307042012-07-27 15:51:34 -0700857
Jeff Brownec083212013-09-11 20:45:25 -0700858 // Only accept a proximity sensor reading if it remains
859 // stable for the entire debounce delay. We hold a wake lock while
860 // debouncing the sensor.
861 mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
862 if (positive) {
863 mPendingProximity = PROXIMITY_POSITIVE;
864 setPendingProximityDebounceTime(
865 time + PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY); // acquire wake lock
866 } else {
867 mPendingProximity = PROXIMITY_NEGATIVE;
868 setPendingProximityDebounceTime(
869 time + PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY); // acquire wake lock
870 }
871
872 // Debounce the new sensor reading.
873 debounceProximitySensor();
Jeff Brown93cbbb22012-10-04 13:18:36 -0700874 }
Jeff Brown96307042012-07-27 15:51:34 -0700875 }
876
877 private void debounceProximitySensor() {
Jeff Brownec083212013-09-11 20:45:25 -0700878 if (mProximitySensorEnabled
879 && mPendingProximity != PROXIMITY_UNKNOWN
880 && mPendingProximityDebounceTime >= 0) {
Jeff Brown96307042012-07-27 15:51:34 -0700881 final long now = SystemClock.uptimeMillis();
882 if (mPendingProximityDebounceTime <= now) {
Jeff Brownec083212013-09-11 20:45:25 -0700883 // Sensor reading accepted. Apply the change then release the wake lock.
Jeff Brown96307042012-07-27 15:51:34 -0700884 mProximity = mPendingProximity;
Jeff Brownec083212013-09-11 20:45:25 -0700885 updatePowerState();
886 clearPendingProximityDebounceTime(); // release wake lock (must be last)
Jeff Brown96307042012-07-27 15:51:34 -0700887 } else {
Jeff Brownec083212013-09-11 20:45:25 -0700888 // Need to wait a little longer.
889 // Debounce again later. We continue holding a wake lock while waiting.
Jeff Brown96307042012-07-27 15:51:34 -0700890 Message msg = mHandler.obtainMessage(MSG_PROXIMITY_SENSOR_DEBOUNCED);
891 msg.setAsynchronous(true);
892 mHandler.sendMessageAtTime(msg, mPendingProximityDebounceTime);
893 }
894 }
895 }
896
Jeff Brownec083212013-09-11 20:45:25 -0700897 private void clearPendingProximityDebounceTime() {
898 if (mPendingProximityDebounceTime >= 0) {
899 mPendingProximityDebounceTime = -1;
Jeff Brownad9ef192014-04-08 17:26:30 -0700900 mCallbacks.releaseSuspendBlocker(); // release wake lock
Jeff Brownec083212013-09-11 20:45:25 -0700901 }
902 }
903
904 private void setPendingProximityDebounceTime(long debounceTime) {
905 if (mPendingProximityDebounceTime < 0) {
Jeff Brownad9ef192014-04-08 17:26:30 -0700906 mCallbacks.acquireSuspendBlocker(); // acquire wake lock
Jeff Brownec083212013-09-11 20:45:25 -0700907 }
908 mPendingProximityDebounceTime = debounceTime;
909 }
910
Jeff Brown330560f2012-08-21 22:10:57 -0700911 private void setLightSensorEnabled(boolean enable, boolean updateAutoBrightness) {
Jeff Brown96307042012-07-27 15:51:34 -0700912 if (enable) {
913 if (!mLightSensorEnabled) {
Jeff Brown330560f2012-08-21 22:10:57 -0700914 updateAutoBrightness = true;
Jeff Brown96307042012-07-27 15:51:34 -0700915 mLightSensorEnabled = true;
916 mLightSensorEnableTime = SystemClock.uptimeMillis();
917 mSensorManager.registerListener(mLightSensorListener, mLightSensor,
Jeff Browne941b1e2012-10-22 16:50:25 -0700918 LIGHT_SENSOR_RATE_MILLIS * 1000, mHandler);
Jeff Brown96307042012-07-27 15:51:34 -0700919 }
920 } else {
921 if (mLightSensorEnabled) {
922 mLightSensorEnabled = false;
Jeff Brown4f0e9692012-10-18 16:14:16 -0700923 mAmbientLuxValid = false;
924 mRecentLightSamples = 0;
Jeff Brown96307042012-07-27 15:51:34 -0700925 mHandler.removeMessages(MSG_LIGHT_SENSOR_DEBOUNCED);
926 mSensorManager.unregisterListener(mLightSensorListener);
927 }
928 }
Jeff Brown330560f2012-08-21 22:10:57 -0700929 if (updateAutoBrightness) {
930 updateAutoBrightness(false);
931 }
Jeff Brown96307042012-07-27 15:51:34 -0700932 }
933
934 private void handleLightSensorEvent(long time, float lux) {
Jeff Browne941b1e2012-10-22 16:50:25 -0700935 mHandler.removeMessages(MSG_LIGHT_SENSOR_DEBOUNCED);
936
937 applyLightSensorMeasurement(time, lux);
938 updateAmbientLux(time);
939 }
940
941 private void applyLightSensorMeasurement(long time, float lux) {
Jeff Brown4f0e9692012-10-18 16:14:16 -0700942 // Update our filters.
Jeff Brown96307042012-07-27 15:51:34 -0700943 mRecentLightSamples += 1;
Jeff Brown4f0e9692012-10-18 16:14:16 -0700944 if (mRecentLightSamples == 1) {
945 mRecentShortTermAverageLux = lux;
946 mRecentLongTermAverageLux = lux;
947 } else {
948 final long timeDelta = time - mLastObservedLuxTime;
949 mRecentShortTermAverageLux += (lux - mRecentShortTermAverageLux)
950 * timeDelta / (SHORT_TERM_AVERAGE_LIGHT_TIME_CONSTANT + timeDelta);
951 mRecentLongTermAverageLux += (lux - mRecentLongTermAverageLux)
952 * timeDelta / (LONG_TERM_AVERAGE_LIGHT_TIME_CONSTANT + timeDelta);
953 }
954
955 // Remember this sample value.
956 mLastObservedLux = lux;
957 mLastObservedLuxTime = time;
Jeff Brown96307042012-07-27 15:51:34 -0700958 }
959
Michael Wright65031a22013-11-04 19:07:49 -0800960 private void setAmbientLux(float lux) {
961 mAmbientLux = lux;
962 mBrighteningLuxThreshold = mAmbientLux * (1.0f + BRIGHTENING_LIGHT_HYSTERESIS);
963 mDarkeningLuxThreshold = mAmbientLux * (1.0f - DARKENING_LIGHT_HYSTERESIS);
964 }
965
Jeff Brown4f0e9692012-10-18 16:14:16 -0700966 private void updateAmbientLux(long time) {
967 // If the light sensor was just turned on then immediately update our initial
968 // estimate of the current ambient light level.
Michael Wright65031a22013-11-04 19:07:49 -0800969 if (!mAmbientLuxValid) {
970 final long timeWhenSensorWarmedUp =
971 mLightSensorWarmUpTimeConfig + mLightSensorEnableTime;
972 if (time < timeWhenSensorWarmedUp) {
973 mHandler.sendEmptyMessageAtTime(MSG_LIGHT_SENSOR_DEBOUNCED,
974 timeWhenSensorWarmedUp);
975 return;
976 }
977 setAmbientLux(mRecentShortTermAverageLux);
Jeff Brown4f0e9692012-10-18 16:14:16 -0700978 mAmbientLuxValid = true;
Jeff Browne941b1e2012-10-22 16:50:25 -0700979 mDebounceLuxDirection = 0;
980 mDebounceLuxTime = time;
981 if (DEBUG) {
982 Slog.d(TAG, "updateAmbientLux: Initializing: "
983 + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux
984 + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux
985 + ", mAmbientLux=" + mAmbientLux);
986 }
Jeff Brown4f0e9692012-10-18 16:14:16 -0700987 updateAutoBrightness(true);
Michael Wright65031a22013-11-04 19:07:49 -0800988 } else if (mRecentShortTermAverageLux > mBrighteningLuxThreshold
989 && mRecentLongTermAverageLux > mBrighteningLuxThreshold) {
990 // The ambient environment appears to be brightening.
Jeff Browne941b1e2012-10-22 16:50:25 -0700991 if (mDebounceLuxDirection <= 0) {
992 mDebounceLuxDirection = 1;
993 mDebounceLuxTime = time;
994 if (DEBUG) {
995 Slog.d(TAG, "updateAmbientLux: Possibly brightened, waiting for "
996 + BRIGHTENING_LIGHT_DEBOUNCE + " ms: "
Michael Wright65031a22013-11-04 19:07:49 -0800997 + "mBrighteningLuxThreshold=" + mBrighteningLuxThreshold
Jeff Browne941b1e2012-10-22 16:50:25 -0700998 + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux
999 + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux
1000 + ", mAmbientLux=" + mAmbientLux);
1001 }
1002 }
1003 long debounceTime = mDebounceLuxTime + BRIGHTENING_LIGHT_DEBOUNCE;
Michael Wright65031a22013-11-04 19:07:49 -08001004 if (time < debounceTime) {
Jeff Brown4f0e9692012-10-18 16:14:16 -07001005 mHandler.sendEmptyMessageAtTime(MSG_LIGHT_SENSOR_DEBOUNCED, debounceTime);
Michael Wright65031a22013-11-04 19:07:49 -08001006 return;
Jeff Brown4f0e9692012-10-18 16:14:16 -07001007 }
Michael Wright65031a22013-11-04 19:07:49 -08001008 setAmbientLux(mRecentShortTermAverageLux);
1009 if (DEBUG) {
1010 Slog.d(TAG, "updateAmbientLux: Brightened: "
1011 + "mBrighteningLuxThreshold=" + mBrighteningLuxThreshold
1012 + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux
1013 + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux
1014 + ", mAmbientLux=" + mAmbientLux);
1015 }
1016 updateAutoBrightness(true);
1017 } else if (mRecentShortTermAverageLux < mDarkeningLuxThreshold
1018 && mRecentLongTermAverageLux < mDarkeningLuxThreshold) {
1019 // The ambient environment appears to be darkening.
Jeff Browne941b1e2012-10-22 16:50:25 -07001020 if (mDebounceLuxDirection >= 0) {
1021 mDebounceLuxDirection = -1;
1022 mDebounceLuxTime = time;
1023 if (DEBUG) {
1024 Slog.d(TAG, "updateAmbientLux: Possibly darkened, waiting for "
1025 + DARKENING_LIGHT_DEBOUNCE + " ms: "
Michael Wright65031a22013-11-04 19:07:49 -08001026 + "mDarkeningLuxThreshold=" + mDarkeningLuxThreshold
Jeff Browne941b1e2012-10-22 16:50:25 -07001027 + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux
1028 + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux
1029 + ", mAmbientLux=" + mAmbientLux);
1030 }
1031 }
1032 long debounceTime = mDebounceLuxTime + DARKENING_LIGHT_DEBOUNCE;
Michael Wright65031a22013-11-04 19:07:49 -08001033 if (time < debounceTime) {
Jeff Brown4f0e9692012-10-18 16:14:16 -07001034 mHandler.sendEmptyMessageAtTime(MSG_LIGHT_SENSOR_DEBOUNCED, debounceTime);
Michael Wright65031a22013-11-04 19:07:49 -08001035 return;
Jeff Brown96307042012-07-27 15:51:34 -07001036 }
Michael Wright65031a22013-11-04 19:07:49 -08001037 // Be conservative about reducing the brightness, only reduce it a little bit
1038 // at a time to avoid having to bump it up again soon.
1039 setAmbientLux(Math.max(mRecentShortTermAverageLux, mRecentLongTermAverageLux));
1040 if (DEBUG) {
1041 Slog.d(TAG, "updateAmbientLux: Darkened: "
1042 + "mDarkeningLuxThreshold=" + mDarkeningLuxThreshold
1043 + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux
1044 + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux
1045 + ", mAmbientLux=" + mAmbientLux);
1046 }
1047 updateAutoBrightness(true);
1048 } else if (mDebounceLuxDirection != 0) {
1049 // No change or change is within the hysteresis thresholds.
Jeff Browne941b1e2012-10-22 16:50:25 -07001050 mDebounceLuxDirection = 0;
1051 mDebounceLuxTime = time;
1052 if (DEBUG) {
1053 Slog.d(TAG, "updateAmbientLux: Canceled debounce: "
Michael Wright65031a22013-11-04 19:07:49 -08001054 + "mBrighteningLuxThreshold=" + mBrighteningLuxThreshold
1055 + ", mDarkeningLuxThreshold=" + mDarkeningLuxThreshold
Jeff Browne941b1e2012-10-22 16:50:25 -07001056 + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux
1057 + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux
1058 + ", mAmbientLux=" + mAmbientLux);
1059 }
1060 }
1061
Michael Wright65031a22013-11-04 19:07:49 -08001062 // Now that we've done all of that, we haven't yet posted a debounce
1063 // message. So consider the case where current lux is beyond the
1064 // threshold. It's possible that the light sensor may not report values
1065 // if the light level does not change, so we need to occasionally
1066 // synthesize sensor readings in order to make sure the brightness is
1067 // adjusted accordingly. Note these thresholds may have changed since
1068 // we entered the function because we called setAmbientLux and
1069 // updateAutoBrightness along the way.
1070 if (mLastObservedLux > mBrighteningLuxThreshold
1071 || mLastObservedLux < mDarkeningLuxThreshold) {
Jeff Browne941b1e2012-10-22 16:50:25 -07001072 mHandler.sendEmptyMessageAtTime(MSG_LIGHT_SENSOR_DEBOUNCED,
1073 time + SYNTHETIC_LIGHT_SENSOR_RATE_MILLIS);
Jeff Brown96307042012-07-27 15:51:34 -07001074 }
1075 }
1076
Jeff Brown4f0e9692012-10-18 16:14:16 -07001077 private void debounceLightSensor() {
Jeff Browne941b1e2012-10-22 16:50:25 -07001078 if (mLightSensorEnabled) {
1079 long time = SystemClock.uptimeMillis();
1080 if (time >= mLastObservedLuxTime + SYNTHETIC_LIGHT_SENSOR_RATE_MILLIS) {
1081 if (DEBUG) {
1082 Slog.d(TAG, "debounceLightSensor: Synthesizing light sensor measurement "
1083 + "after " + (time - mLastObservedLuxTime) + " ms.");
1084 }
1085 applyLightSensorMeasurement(time, mLastObservedLux);
1086 }
1087 updateAmbientLux(time);
1088 }
Jeff Brown4f0e9692012-10-18 16:14:16 -07001089 }
1090
Jeff Brown96307042012-07-27 15:51:34 -07001091 private void updateAutoBrightness(boolean sendUpdate) {
Jeff Brown4f0e9692012-10-18 16:14:16 -07001092 if (!mAmbientLuxValid) {
Jeff Brown96307042012-07-27 15:51:34 -07001093 return;
1094 }
1095
Jeff Brown4f0e9692012-10-18 16:14:16 -07001096 float value = mScreenAutoBrightnessSpline.interpolate(mAmbientLux);
Jeff Brown330560f2012-08-21 22:10:57 -07001097 float gamma = 1.0f;
1098
1099 if (USE_SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT
1100 && mPowerRequest.screenAutoBrightnessAdjustment != 0.0f) {
1101 final float adjGamma = FloatMath.pow(SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT_MAX_GAMMA,
1102 Math.min(1.0f, Math.max(-1.0f,
1103 -mPowerRequest.screenAutoBrightnessAdjustment)));
1104 gamma *= adjGamma;
1105 if (DEBUG) {
1106 Slog.d(TAG, "updateAutoBrightness: adjGamma=" + adjGamma);
1107 }
1108 }
1109
Jeff Brownaa202a62012-08-21 22:14:26 -07001110 if (USE_TWILIGHT_ADJUSTMENT) {
1111 TwilightState state = mTwilight.getCurrentState();
1112 if (state != null && state.isNight()) {
1113 final long now = System.currentTimeMillis();
1114 final float earlyGamma =
1115 getTwilightGamma(now, state.getYesterdaySunset(), state.getTodaySunrise());
1116 final float lateGamma =
1117 getTwilightGamma(now, state.getTodaySunset(), state.getTomorrowSunrise());
1118 gamma *= earlyGamma * lateGamma;
1119 if (DEBUG) {
1120 Slog.d(TAG, "updateAutoBrightness: earlyGamma=" + earlyGamma
1121 + ", lateGamma=" + lateGamma);
1122 }
1123 }
1124 }
1125
Jeff Brown330560f2012-08-21 22:10:57 -07001126 if (gamma != 1.0f) {
1127 final float in = value;
1128 value = FloatMath.pow(value, gamma);
1129 if (DEBUG) {
1130 Slog.d(TAG, "updateAutoBrightness: gamma=" + gamma
1131 + ", in=" + in + ", out=" + value);
1132 }
1133 }
1134
1135 int newScreenAutoBrightness = clampScreenBrightness(
Jeff Brown4f0e9692012-10-18 16:14:16 -07001136 Math.round(value * PowerManager.BRIGHTNESS_ON));
Jeff Brown96307042012-07-27 15:51:34 -07001137 if (mScreenAutoBrightness != newScreenAutoBrightness) {
1138 if (DEBUG) {
1139 Slog.d(TAG, "updateAutoBrightness: mScreenAutoBrightness="
Jeff Brown330560f2012-08-21 22:10:57 -07001140 + mScreenAutoBrightness + ", newScreenAutoBrightness="
Jeff Brown1a30b552012-08-16 01:31:11 -07001141 + newScreenAutoBrightness);
Jeff Brown96307042012-07-27 15:51:34 -07001142 }
1143
1144 mScreenAutoBrightness = newScreenAutoBrightness;
Jeff Brown330560f2012-08-21 22:10:57 -07001145 mLastScreenAutoBrightnessGamma = gamma;
Jeff Brown96307042012-07-27 15:51:34 -07001146 if (sendUpdate) {
1147 sendUpdatePowerState();
1148 }
1149 }
1150 }
1151
Jeff Brownaa202a62012-08-21 22:14:26 -07001152 private static float getTwilightGamma(long now, long lastSunset, long nextSunrise) {
1153 if (lastSunset < 0 || nextSunrise < 0
1154 || now < lastSunset || now > nextSunrise) {
1155 return 1.0f;
1156 }
1157
1158 if (now < lastSunset + TWILIGHT_ADJUSTMENT_TIME) {
1159 return lerp(1.0f, TWILIGHT_ADJUSTMENT_MAX_GAMMA,
1160 (float)(now - lastSunset) / TWILIGHT_ADJUSTMENT_TIME);
1161 }
1162
1163 if (now > nextSunrise - TWILIGHT_ADJUSTMENT_TIME) {
1164 return lerp(1.0f, TWILIGHT_ADJUSTMENT_MAX_GAMMA,
1165 (float)(nextSunrise - now) / TWILIGHT_ADJUSTMENT_TIME);
1166 }
1167
1168 return TWILIGHT_ADJUSTMENT_MAX_GAMMA;
1169 }
1170
1171 private static float lerp(float x, float y, float alpha) {
1172 return x + (y - x) * alpha;
1173 }
1174
Jeff Brownec083212013-09-11 20:45:25 -07001175 private void sendOnStateChangedWithWakelock() {
Jeff Brownad9ef192014-04-08 17:26:30 -07001176 mCallbacks.acquireSuspendBlocker();
1177 mHandler.post(mOnStateChangedRunnable);
Jeff Brown96307042012-07-27 15:51:34 -07001178 }
1179
1180 private final Runnable mOnStateChangedRunnable = new Runnable() {
1181 @Override
1182 public void run() {
1183 mCallbacks.onStateChanged();
Jeff Brownad9ef192014-04-08 17:26:30 -07001184 mCallbacks.releaseSuspendBlocker();
Jeff Brown96307042012-07-27 15:51:34 -07001185 }
1186 };
1187
Jeff Brownec083212013-09-11 20:45:25 -07001188 private void sendOnProximityPositiveWithWakelock() {
Jeff Brownad9ef192014-04-08 17:26:30 -07001189 mCallbacks.acquireSuspendBlocker();
1190 mHandler.post(mOnProximityPositiveRunnable);
Jeff Brown93cbbb22012-10-04 13:18:36 -07001191 }
1192
1193 private final Runnable mOnProximityPositiveRunnable = new Runnable() {
1194 @Override
1195 public void run() {
1196 mCallbacks.onProximityPositive();
Jeff Brownad9ef192014-04-08 17:26:30 -07001197 mCallbacks.releaseSuspendBlocker();
Jeff Brown93cbbb22012-10-04 13:18:36 -07001198 }
1199 };
1200
Jeff Brownec083212013-09-11 20:45:25 -07001201 private void sendOnProximityNegativeWithWakelock() {
Jeff Brownad9ef192014-04-08 17:26:30 -07001202 mCallbacks.acquireSuspendBlocker();
1203 mHandler.post(mOnProximityNegativeRunnable);
Jeff Brown96307042012-07-27 15:51:34 -07001204 }
1205
1206 private final Runnable mOnProximityNegativeRunnable = new Runnable() {
1207 @Override
1208 public void run() {
1209 mCallbacks.onProximityNegative();
Jeff Brownad9ef192014-04-08 17:26:30 -07001210 mCallbacks.releaseSuspendBlocker();
Jeff Brown96307042012-07-27 15:51:34 -07001211 }
1212 };
1213
Jeff Brownbd6e1502012-08-28 03:27:37 -07001214 public void dump(final PrintWriter pw) {
Jeff Brown96307042012-07-27 15:51:34 -07001215 synchronized (mLock) {
1216 pw.println();
Jeff Brownad9ef192014-04-08 17:26:30 -07001217 pw.println("Display Power Controller Locked State:");
Jeff Brown96307042012-07-27 15:51:34 -07001218 pw.println(" mDisplayReadyLocked=" + mDisplayReadyLocked);
1219 pw.println(" mPendingRequestLocked=" + mPendingRequestLocked);
1220 pw.println(" mPendingRequestChangedLocked=" + mPendingRequestChangedLocked);
1221 pw.println(" mPendingWaitForNegativeProximityLocked="
1222 + mPendingWaitForNegativeProximityLocked);
1223 pw.println(" mPendingUpdatePowerStateLocked=" + mPendingUpdatePowerStateLocked);
1224 }
1225
1226 pw.println();
Jeff Brownad9ef192014-04-08 17:26:30 -07001227 pw.println("Display Power Controller Configuration:");
Jeff Brown26875502014-01-30 21:47:47 -08001228 pw.println(" mScreenBrightnessDozeConfig=" + mScreenBrightnessDozeConfig);
Jeff Brown96307042012-07-27 15:51:34 -07001229 pw.println(" mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig);
Jeff Brownb76eebff2012-10-05 22:26:44 -07001230 pw.println(" mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum);
1231 pw.println(" mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum);
Jeff Brown96307042012-07-27 15:51:34 -07001232 pw.println(" mUseSoftwareAutoBrightnessConfig="
1233 + mUseSoftwareAutoBrightnessConfig);
Jeff Brown1a30b552012-08-16 01:31:11 -07001234 pw.println(" mScreenAutoBrightnessSpline=" + mScreenAutoBrightnessSpline);
Jeff Brown96307042012-07-27 15:51:34 -07001235 pw.println(" mLightSensorWarmUpTimeConfig=" + mLightSensorWarmUpTimeConfig);
1236
Jeff Brownbd6e1502012-08-28 03:27:37 -07001237 mHandler.runWithScissors(new Runnable() {
1238 @Override
1239 public void run() {
1240 dumpLocal(pw);
Jeff Brown96307042012-07-27 15:51:34 -07001241 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001242 }, 1000);
Jeff Brown96307042012-07-27 15:51:34 -07001243 }
1244
1245 private void dumpLocal(PrintWriter pw) {
1246 pw.println();
Jeff Brownad9ef192014-04-08 17:26:30 -07001247 pw.println("Display Power Controller Thread State:");
Jeff Brown96307042012-07-27 15:51:34 -07001248 pw.println(" mPowerRequest=" + mPowerRequest);
1249 pw.println(" mWaitingForNegativeProximity=" + mWaitingForNegativeProximity);
1250
1251 pw.println(" mProximitySensor=" + mProximitySensor);
1252 pw.println(" mProximitySensorEnabled=" + mProximitySensorEnabled);
1253 pw.println(" mProximityThreshold=" + mProximityThreshold);
1254 pw.println(" mProximity=" + proximityToString(mProximity));
1255 pw.println(" mPendingProximity=" + proximityToString(mPendingProximity));
1256 pw.println(" mPendingProximityDebounceTime="
1257 + TimeUtils.formatUptime(mPendingProximityDebounceTime));
1258 pw.println(" mScreenOffBecauseOfProximity=" + mScreenOffBecauseOfProximity);
1259
1260 pw.println(" mLightSensor=" + mLightSensor);
1261 pw.println(" mLightSensorEnabled=" + mLightSensorEnabled);
1262 pw.println(" mLightSensorEnableTime="
1263 + TimeUtils.formatUptime(mLightSensorEnableTime));
Jeff Brown4f0e9692012-10-18 16:14:16 -07001264 pw.println(" mAmbientLux=" + mAmbientLux);
1265 pw.println(" mAmbientLuxValid=" + mAmbientLuxValid);
Jeff Brown4f0e9692012-10-18 16:14:16 -07001266 pw.println(" mLastObservedLux=" + mLastObservedLux);
1267 pw.println(" mLastObservedLuxTime="
1268 + TimeUtils.formatUptime(mLastObservedLuxTime));
Jeff Brown96307042012-07-27 15:51:34 -07001269 pw.println(" mRecentLightSamples=" + mRecentLightSamples);
Jeff Brown4f0e9692012-10-18 16:14:16 -07001270 pw.println(" mRecentShortTermAverageLux=" + mRecentShortTermAverageLux);
1271 pw.println(" mRecentLongTermAverageLux=" + mRecentLongTermAverageLux);
Jeff Browne941b1e2012-10-22 16:50:25 -07001272 pw.println(" mDebounceLuxDirection=" + mDebounceLuxDirection);
1273 pw.println(" mDebounceLuxTime=" + TimeUtils.formatUptime(mDebounceLuxTime));
Jeff Brown96307042012-07-27 15:51:34 -07001274 pw.println(" mScreenAutoBrightness=" + mScreenAutoBrightness);
1275 pw.println(" mUsingScreenAutoBrightness=" + mUsingScreenAutoBrightness);
Jeff Brown330560f2012-08-21 22:10:57 -07001276 pw.println(" mLastScreenAutoBrightnessGamma=" + mLastScreenAutoBrightnessGamma);
Jeff Brownaa202a62012-08-21 22:14:26 -07001277 pw.println(" mTwilight.getCurrentState()=" + mTwilight.getCurrentState());
Jeff Brown96307042012-07-27 15:51:34 -07001278
1279 if (mElectronBeamOnAnimator != null) {
1280 pw.println(" mElectronBeamOnAnimator.isStarted()=" +
1281 mElectronBeamOnAnimator.isStarted());
1282 }
1283 if (mElectronBeamOffAnimator != null) {
1284 pw.println(" mElectronBeamOffAnimator.isStarted()=" +
1285 mElectronBeamOffAnimator.isStarted());
1286 }
1287
1288 if (mPowerState != null) {
1289 mPowerState.dump(pw);
1290 }
1291 }
1292
1293 private static String proximityToString(int state) {
1294 switch (state) {
1295 case PROXIMITY_UNKNOWN:
1296 return "Unknown";
1297 case PROXIMITY_NEGATIVE:
1298 return "Negative";
1299 case PROXIMITY_POSITIVE:
1300 return "Positive";
1301 default:
1302 return Integer.toString(state);
1303 }
1304 }
1305
Jeff Brown96307042012-07-27 15:51:34 -07001306 private final class DisplayControllerHandler extends Handler {
1307 public DisplayControllerHandler(Looper looper) {
Jeff Browna2910d02012-08-25 12:29:46 -07001308 super(looper, null, true /*async*/);
Jeff Brown96307042012-07-27 15:51:34 -07001309 }
1310
1311 @Override
1312 public void handleMessage(Message msg) {
1313 switch (msg.what) {
1314 case MSG_UPDATE_POWER_STATE:
1315 updatePowerState();
1316 break;
1317
1318 case MSG_PROXIMITY_SENSOR_DEBOUNCED:
1319 debounceProximitySensor();
1320 break;
1321
1322 case MSG_LIGHT_SENSOR_DEBOUNCED:
1323 debounceLightSensor();
1324 break;
1325 }
1326 }
1327 }
1328
1329 private final SensorEventListener mProximitySensorListener = new SensorEventListener() {
1330 @Override
1331 public void onSensorChanged(SensorEvent event) {
1332 if (mProximitySensorEnabled) {
1333 final long time = SystemClock.uptimeMillis();
1334 final float distance = event.values[0];
1335 boolean positive = distance >= 0.0f && distance < mProximityThreshold;
1336 handleProximitySensorEvent(time, positive);
1337 }
1338 }
1339
1340 @Override
1341 public void onAccuracyChanged(Sensor sensor, int accuracy) {
1342 // Not used.
1343 }
1344 };
1345
1346 private final SensorEventListener mLightSensorListener = new SensorEventListener() {
1347 @Override
1348 public void onSensorChanged(SensorEvent event) {
1349 if (mLightSensorEnabled) {
1350 final long time = SystemClock.uptimeMillis();
1351 final float lux = event.values[0];
1352 handleLightSensorEvent(time, lux);
1353 }
1354 }
1355
1356 @Override
1357 public void onAccuracyChanged(Sensor sensor, int accuracy) {
1358 // Not used.
1359 }
1360 };
Jeff Brownaa202a62012-08-21 22:14:26 -07001361
Adam Lesinski182f73f2013-12-05 16:48:06 -08001362 private final TwilightListener mTwilightListener = new TwilightListener() {
Jeff Brownaa202a62012-08-21 22:14:26 -07001363 @Override
1364 public void onTwilightStateChanged() {
1365 mTwilightChanged = true;
1366 updatePowerState();
1367 }
1368 };
Jeff Brown96307042012-07-27 15:51:34 -07001369}