blob: 1ed7070d2586aa089bc2687f544c52e4b2f23854 [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 Brown131206b2014-04-08 17:27:14 -070017package com.android.server.display;
Jeff Brown96307042012-07-27 15:51:34 -070018
Jeff Brown131206b2014-04-08 17:27:14 -070019import com.android.internal.app.IBatteryStats;
20import com.android.server.LocalServices;
21import com.android.server.am.BatteryStatsService;
Jeff Brown96307042012-07-27 15:51:34 -070022
23import android.animation.Animator;
24import android.animation.ObjectAnimator;
25import android.content.Context;
26import android.content.res.Resources;
27import android.hardware.Sensor;
28import android.hardware.SensorEvent;
29import android.hardware.SensorEventListener;
30import android.hardware.SensorManager;
Jeff Brown131206b2014-04-08 17:27:14 -070031import android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks;
32import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
Jeff Brown96307042012-07-27 15:51:34 -070033import android.os.Handler;
34import android.os.Looper;
35import android.os.Message;
Jeff Brown330560f2012-08-21 22:10:57 -070036import android.os.PowerManager;
Jeff Brown131206b2014-04-08 17:27:14 -070037import android.os.RemoteException;
Jeff Brown96307042012-07-27 15:51:34 -070038import android.os.SystemClock;
Jeff Brown3edf5272014-08-14 19:25:14 -070039import android.os.Trace;
Michael Wright41a5cdf2013-11-13 16:18:32 -080040import android.util.MathUtils;
Jeff Brown96307042012-07-27 15:51:34 -070041import android.util.Slog;
Jeff Brown1a30b552012-08-16 01:31:11 -070042import android.util.Spline;
Jeff Brown96307042012-07-27 15:51:34 -070043import android.util.TimeUtils;
Jeff Brown037c33e2014-04-09 00:31:55 -070044import android.view.Display;
Jeff Brown3ee549c2014-09-22 20:14:39 -070045import android.view.WindowManagerPolicy;
Jeff Brown96307042012-07-27 15:51:34 -070046
47import java.io.PrintWriter;
Jeff Brown96307042012-07-27 15:51:34 -070048
49/**
50 * Controls the power state of the display.
51 *
52 * Handles the proximity sensor, light sensor, and animations between states
53 * including the screen off animation.
54 *
55 * This component acts independently of the rest of the power manager service.
56 * In particular, it does not share any state and it only communicates
57 * via asynchronous callbacks to inform the power manager that something has
58 * changed.
59 *
60 * Everything this class does internally is serialized on its handler although
61 * it may be accessed by other threads from the outside.
62 *
63 * Note that the power manager service guarantees that it will hold a suspend
64 * blocker as long as the display is not ready. So most of the work done here
65 * does not need to worry about holding a suspend blocker unless it happens
66 * independently of the display ready signal.
Michael Lentine0839adb2014-07-29 18:47:56 -070067 *
Jeff Brown3ee549c2014-09-22 20:14:39 -070068 * For debugging, you can make the color fade and brightness animations run
Jeff Brown96307042012-07-27 15:51:34 -070069 * slower by changing the "animator duration scale" option in Development Settings.
70 */
Michael Wright639c8be2014-01-17 18:29:12 -080071final class DisplayPowerController implements AutomaticBrightnessController.Callbacks {
Jeff Brown96307042012-07-27 15:51:34 -070072 private static final String TAG = "DisplayPowerController";
Jeff Browna576b4d2015-04-23 19:58:06 -070073 private static final String SCREEN_ON_BLOCKED_TRACE_NAME = "Screen on blocked";
Jeff Brown96307042012-07-27 15:51:34 -070074
Michael Wright639c8be2014-01-17 18:29:12 -080075 private static boolean DEBUG = false;
Jeff Brown96307042012-07-27 15:51:34 -070076 private static final boolean DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT = false;
Jeff Brown96307042012-07-27 15:51:34 -070077
Jeff Brown3ee549c2014-09-22 20:14:39 -070078 // If true, uses the color fade on animation.
Jeff Brown13c589b2012-08-16 16:20:54 -070079 // We might want to turn this off if we cannot get a guarantee that the screen
80 // actually turns on and starts showing new content after the call to set the
Jeff Brown5356c7dc2012-08-20 20:17:36 -070081 // screen state returns. Playing the animation can also be somewhat slow.
Michael Lentine0839adb2014-07-29 18:47:56 -070082 private static final boolean USE_COLOR_FADE_ON_ANIMATION = false;
Jeff Brown13c589b2012-08-16 16:20:54 -070083
Jeff Brownb76eebff2012-10-05 22:26:44 -070084 // The minimum reduction in brightness when dimmed.
85 private static final int SCREEN_DIM_MINIMUM_REDUCTION = 10;
86
Michael Lentine0839adb2014-07-29 18:47:56 -070087 private static final int COLOR_FADE_ON_ANIMATION_DURATION_MILLIS = 250;
Michael Lentine0c9a62d2014-08-20 09:19:07 -070088 private static final int COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS = 400;
Jeff Brown96307042012-07-27 15:51:34 -070089
90 private static final int MSG_UPDATE_POWER_STATE = 1;
91 private static final int MSG_PROXIMITY_SENSOR_DEBOUNCED = 2;
Jeff Brown3ee549c2014-09-22 20:14:39 -070092 private static final int MSG_SCREEN_ON_UNBLOCKED = 3;
Jeff Brown96307042012-07-27 15:51:34 -070093
94 private static final int PROXIMITY_UNKNOWN = -1;
95 private static final int PROXIMITY_NEGATIVE = 0;
96 private static final int PROXIMITY_POSITIVE = 1;
97
Jeff Brown93cbbb22012-10-04 13:18:36 -070098 // Proximity sensor debounce delay in milliseconds for positive or negative transitions.
99 private static final int PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY = 0;
Jeff Brownec083212013-09-11 20:45:25 -0700100 private static final int PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY = 250;
Jeff Brown96307042012-07-27 15:51:34 -0700101
102 // Trigger proximity if distance is less than 5 cm.
103 private static final float TYPICAL_PROXIMITY_THRESHOLD = 5.0f;
104
Jeff Brown96307042012-07-27 15:51:34 -0700105 // Brightness animation ramp rate in brightness units per second.
106 private static final int BRIGHTNESS_RAMP_RATE_FAST = 200;
Jeff Browne941b1e2012-10-22 16:50:25 -0700107 private static final int BRIGHTNESS_RAMP_RATE_SLOW = 40;
Jeff Brown96307042012-07-27 15:51:34 -0700108
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700109 private static final int REPORTED_TO_POLICY_SCREEN_OFF = 0;
110 private static final int REPORTED_TO_POLICY_SCREEN_TURNING_ON = 1;
111 private static final int REPORTED_TO_POLICY_SCREEN_ON = 2;
112
Jeff Brown96307042012-07-27 15:51:34 -0700113 private final Object mLock = new Object();
114
Michael Lentine0839adb2014-07-29 18:47:56 -0700115 private final Context mContext;
116
Jeff Brown96307042012-07-27 15:51:34 -0700117 // Our handler.
118 private final DisplayControllerHandler mHandler;
119
120 // Asynchronous callbacks into the power manager service.
121 // Only invoked from the handler thread while no locks are held.
Jeff Brown131206b2014-04-08 17:27:14 -0700122 private final DisplayPowerCallbacks mCallbacks;
123
124 // Battery stats.
125 private final IBatteryStats mBatteryStats;
Jeff Brown96307042012-07-27 15:51:34 -0700126
Jeff Brown96307042012-07-27 15:51:34 -0700127 // The sensor manager.
128 private final SensorManager mSensorManager;
129
Jeff Brown3ee549c2014-09-22 20:14:39 -0700130 // The window manager policy.
131 private final WindowManagerPolicy mWindowManagerPolicy;
132
Jeff Brown037c33e2014-04-09 00:31:55 -0700133 // The display blanker.
134 private final DisplayBlanker mBlanker;
135
Jeff Brown96307042012-07-27 15:51:34 -0700136 // The proximity sensor, or null if not available or needed.
137 private Sensor mProximitySensor;
138
Jeff Brown26875502014-01-30 21:47:47 -0800139 // The doze screen brightness.
140 private final int mScreenBrightnessDozeConfig;
141
Jeff Brown96307042012-07-27 15:51:34 -0700142 // The dim screen brightness.
143 private final int mScreenBrightnessDimConfig;
144
Jeff Brown1bfd0f42014-08-22 01:59:06 -0700145 // The minimum screen brightness to use in a very dark room.
146 private final int mScreenBrightnessDarkConfig;
147
Jeff Brownb76eebff2012-10-05 22:26:44 -0700148 // The minimum allowed brightness.
149 private final int mScreenBrightnessRangeMinimum;
150
151 // The maximum allowed brightness.
152 private final int mScreenBrightnessRangeMaximum;
153
Jeff Brown330560f2012-08-21 22:10:57 -0700154 // True if auto-brightness should be used.
Jeff Brown96307042012-07-27 15:51:34 -0700155 private boolean mUseSoftwareAutoBrightnessConfig;
Jeff Brown330560f2012-08-21 22:10:57 -0700156
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700157 // True if should use light sensor to automatically determine doze screen brightness.
158 private final boolean mAllowAutoBrightnessWhileDozingConfig;
159
Jeff Brown252c2062012-10-08 16:21:01 -0700160 // True if we should fade the screen while turning it off, false if we should play
Jeff Brown3ee549c2014-09-22 20:14:39 -0700161 // a stylish color fade animation instead.
Michael Lentine0839adb2014-07-29 18:47:56 -0700162 private boolean mColorFadeFadesConfig;
Jeff Browna52772f2012-10-04 18:38:09 -0700163
Jeff Brown96307042012-07-27 15:51:34 -0700164 // The pending power request.
165 // Initially null until the first call to requestPowerState.
166 // Guarded by mLock.
167 private DisplayPowerRequest mPendingRequestLocked;
168
169 // True if a request has been made to wait for the proximity sensor to go negative.
170 // Guarded by mLock.
171 private boolean mPendingWaitForNegativeProximityLocked;
172
173 // True if the pending power request or wait for negative proximity flag
174 // has been changed since the last update occurred.
175 // Guarded by mLock.
176 private boolean mPendingRequestChangedLocked;
177
178 // Set to true when the important parts of the pending power request have been applied.
179 // The important parts are mainly the screen state. Brightness changes may occur
180 // concurrently.
181 // Guarded by mLock.
182 private boolean mDisplayReadyLocked;
183
184 // Set to true if a power state update is required.
185 // Guarded by mLock.
186 private boolean mPendingUpdatePowerStateLocked;
187
188 /* The following state must only be accessed by the handler thread. */
189
190 // The currently requested power state.
191 // The power controller will progressively update its internal state to match
192 // the requested power state. Initially null until the first update.
193 private DisplayPowerRequest mPowerRequest;
194
195 // The current power state.
196 // Must only be accessed on the handler thread.
197 private DisplayPowerState mPowerState;
198
199 // True if the device should wait for negative proximity sensor before
200 // waking up the screen. This is set to false as soon as a negative
201 // proximity sensor measurement is observed or when the device is forced to
202 // go to sleep by the user. While true, the screen remains off.
203 private boolean mWaitingForNegativeProximity;
204
205 // The actual proximity sensor threshold value.
206 private float mProximityThreshold;
207
208 // Set to true if the proximity sensor listener has been registered
209 // with the sensor manager.
210 private boolean mProximitySensorEnabled;
211
212 // The debounced proximity sensor state.
213 private int mProximity = PROXIMITY_UNKNOWN;
214
215 // The raw non-debounced proximity sensor state.
216 private int mPendingProximity = PROXIMITY_UNKNOWN;
Jeff Brownec083212013-09-11 20:45:25 -0700217 private long mPendingProximityDebounceTime = -1; // -1 if fully debounced
Jeff Brown96307042012-07-27 15:51:34 -0700218
219 // True if the screen was turned off because of the proximity sensor.
220 // When the screen turns on again, we report user activity to the power manager.
221 private boolean mScreenOffBecauseOfProximity;
222
Jeff Brown3ee549c2014-09-22 20:14:39 -0700223 // The currently active screen on unblocker. This field is non-null whenever
224 // we are waiting for a callback to release it and unblock the screen.
225 private ScreenOnUnblocker mPendingScreenOnUnblocker;
226
227 // True if we were in the process of turning off the screen.
228 // This allows us to recover more gracefully from situations where we abort
229 // turning off the screen.
230 private boolean mPendingScreenOff;
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700231
Jeff Brown0a434772014-09-30 14:42:27 -0700232 // True if we have unfinished business and are holding a suspend blocker.
233 private boolean mUnfinishedBusiness;
234
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700235 // The elapsed real time when the screen on was blocked.
236 private long mScreenOnBlockStartRealTime;
237
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700238 // Screen state we reported to policy. Must be one of REPORTED_TO_POLICY_SCREEN_* fields.
239 private int mReportedScreenStateToPolicy;
Jeff Browne1633ad2015-06-22 19:24:24 -0700240
Jeff Brown970d4132014-07-19 11:33:47 -0700241 // Remembers whether certain kinds of brightness adjustments
242 // were recently applied so that we can decide how to transition.
243 private boolean mAppliedAutoBrightness;
244 private boolean mAppliedDimming;
245 private boolean mAppliedLowPower;
Jeff Brown96307042012-07-27 15:51:34 -0700246
Michael Wright639c8be2014-01-17 18:29:12 -0800247 // The controller for the automatic brightness level.
248 private AutomaticBrightnessController mAutomaticBrightnessController;
249
Jeff Brown96307042012-07-27 15:51:34 -0700250 // Animators.
Michael Lentine0839adb2014-07-29 18:47:56 -0700251 private ObjectAnimator mColorFadeOnAnimator;
252 private ObjectAnimator mColorFadeOffAnimator;
Jeff Brown96307042012-07-27 15:51:34 -0700253 private RampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator;
254
255 /**
256 * Creates the display power controller.
257 */
Jeff Brown131206b2014-04-08 17:27:14 -0700258 public DisplayPowerController(Context context,
Jeff Brown037c33e2014-04-09 00:31:55 -0700259 DisplayPowerCallbacks callbacks, Handler handler,
260 SensorManager sensorManager, DisplayBlanker blanker) {
Jeff Brown131206b2014-04-08 17:27:14 -0700261 mHandler = new DisplayControllerHandler(handler.getLooper());
Jeff Brown96307042012-07-27 15:51:34 -0700262 mCallbacks = callbacks;
Jeff Brown96307042012-07-27 15:51:34 -0700263
Jeff Brown131206b2014-04-08 17:27:14 -0700264 mBatteryStats = BatteryStatsService.getService();
Jeff Brown3b971592013-01-09 18:46:37 -0800265 mSensorManager = sensorManager;
Jeff Brown3ee549c2014-09-22 20:14:39 -0700266 mWindowManagerPolicy = LocalServices.getService(WindowManagerPolicy.class);
Jeff Brown037c33e2014-04-09 00:31:55 -0700267 mBlanker = blanker;
Michael Lentine0839adb2014-07-29 18:47:56 -0700268 mContext = context;
Jeff Brown96307042012-07-27 15:51:34 -0700269
270 final Resources resources = context.getResources();
Jeff Brown1bfd0f42014-08-22 01:59:06 -0700271 final int screenBrightnessSettingMinimum = clampAbsoluteBrightness(resources.getInteger(
272 com.android.internal.R.integer.config_screenBrightnessSettingMinimum));
Jeff Brownb76eebff2012-10-05 22:26:44 -0700273
Jeff Brown26875502014-01-30 21:47:47 -0800274 mScreenBrightnessDozeConfig = clampAbsoluteBrightness(resources.getInteger(
275 com.android.internal.R.integer.config_screenBrightnessDoze));
276
Jeff Brownb76eebff2012-10-05 22:26:44 -0700277 mScreenBrightnessDimConfig = clampAbsoluteBrightness(resources.getInteger(
278 com.android.internal.R.integer.config_screenBrightnessDim));
279
Jeff Brown1bfd0f42014-08-22 01:59:06 -0700280 mScreenBrightnessDarkConfig = clampAbsoluteBrightness(resources.getInteger(
281 com.android.internal.R.integer.config_screenBrightnessDark));
282 if (mScreenBrightnessDarkConfig > mScreenBrightnessDimConfig) {
283 Slog.w(TAG, "Expected config_screenBrightnessDark ("
284 + mScreenBrightnessDarkConfig + ") to be less than or equal to "
285 + "config_screenBrightnessDim (" + mScreenBrightnessDimConfig + ").");
286 }
287 if (mScreenBrightnessDarkConfig > mScreenBrightnessDimConfig) {
288 Slog.w(TAG, "Expected config_screenBrightnessDark ("
289 + mScreenBrightnessDarkConfig + ") to be less than or equal to "
290 + "config_screenBrightnessSettingMinimum ("
291 + screenBrightnessSettingMinimum + ").");
292 }
293
294 int screenBrightnessRangeMinimum = Math.min(Math.min(
295 screenBrightnessSettingMinimum, mScreenBrightnessDimConfig),
296 mScreenBrightnessDarkConfig);
Michael Wright639c8be2014-01-17 18:29:12 -0800297
298 mScreenBrightnessRangeMaximum = PowerManager.BRIGHTNESS_ON;
Jeff Brownb76eebff2012-10-05 22:26:44 -0700299
Jeff Brown96307042012-07-27 15:51:34 -0700300 mUseSoftwareAutoBrightnessConfig = resources.getBoolean(
301 com.android.internal.R.bool.config_automatic_brightness_available);
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700302
303 mAllowAutoBrightnessWhileDozingConfig = resources.getBoolean(
304 com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing);
305
Filip Gruszczynskid81ecd12015-02-06 12:38:47 -0800306 int lightSensorRate = resources.getInteger(
307 com.android.internal.R.integer.config_autoBrightnessLightSensorRate);
308 long brighteningLightDebounce = resources.getInteger(
309 com.android.internal.R.integer.config_autoBrightnessBrighteningLightDebounce);
310 long darkeningLightDebounce = resources.getInteger(
311 com.android.internal.R.integer.config_autoBrightnessDarkeningLightDebounce);
312 boolean autoBrightnessResetAmbientLuxAfterWarmUp = resources.getBoolean(
313 com.android.internal.R.bool.config_autoBrightnessResetAmbientLuxAfterWarmUp);
Zoran Jovanovic6fc42f52015-12-10 17:01:16 +0100314 int ambientLightHorizon = resources.getInteger(
315 com.android.internal.R.integer.config_autoBrightnessAmbientLightHorizon);
316 float autoBrightnessAdjustmentMaxGamma = resources.getFraction(
317 com.android.internal.R.fraction.config_autoBrightnessAdjustmentMaxGamma,
318 1, 1);
Filip Gruszczynskid81ecd12015-02-06 12:38:47 -0800319
Jeff Brown96307042012-07-27 15:51:34 -0700320 if (mUseSoftwareAutoBrightnessConfig) {
Jeff Brown1a30b552012-08-16 01:31:11 -0700321 int[] lux = resources.getIntArray(
Jeff Brown96307042012-07-27 15:51:34 -0700322 com.android.internal.R.array.config_autoBrightnessLevels);
Jeff Brown1a30b552012-08-16 01:31:11 -0700323 int[] screenBrightness = resources.getIntArray(
Jeff Brown96307042012-07-27 15:51:34 -0700324 com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
Michael Wright639c8be2014-01-17 18:29:12 -0800325 int lightSensorWarmUpTimeConfig = resources.getInteger(
326 com.android.internal.R.integer.config_lightSensorWarmupTime);
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700327 final float dozeScaleFactor = resources.getFraction(
328 com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor,
329 1, 1);
Jeff Brown1a30b552012-08-16 01:31:11 -0700330
Michael Wright639c8be2014-01-17 18:29:12 -0800331 Spline screenAutoBrightnessSpline = createAutoBrightnessSpline(lux, screenBrightness);
332 if (screenAutoBrightnessSpline == null) {
Jeff Brown96307042012-07-27 15:51:34 -0700333 Slog.e(TAG, "Error in config.xml. config_autoBrightnessLcdBacklightValues "
Jeff Brown1a30b552012-08-16 01:31:11 -0700334 + "(size " + screenBrightness.length + ") "
335 + "must be monotic and have exactly one more entry than "
336 + "config_autoBrightnessLevels (size " + lux.length + ") "
337 + "which must be strictly increasing. "
Jeff Brown96307042012-07-27 15:51:34 -0700338 + "Auto-brightness will be disabled.");
339 mUseSoftwareAutoBrightnessConfig = false;
Jeff Brownb76eebff2012-10-05 22:26:44 -0700340 } else {
Jeff Brown1bfd0f42014-08-22 01:59:06 -0700341 int bottom = clampAbsoluteBrightness(screenBrightness[0]);
342 if (mScreenBrightnessDarkConfig > bottom) {
343 Slog.w(TAG, "config_screenBrightnessDark (" + mScreenBrightnessDarkConfig
344 + ") should be less than or equal to the first value of "
345 + "config_autoBrightnessLcdBacklightValues ("
346 + bottom + ").");
347 }
348 if (bottom < screenBrightnessRangeMinimum) {
349 screenBrightnessRangeMinimum = bottom;
Jeff Brownb76eebff2012-10-05 22:26:44 -0700350 }
Jeff Brown131206b2014-04-08 17:27:14 -0700351 mAutomaticBrightnessController = new AutomaticBrightnessController(this,
352 handler.getLooper(), sensorManager, screenAutoBrightnessSpline,
Michael Wright639c8be2014-01-17 18:29:12 -0800353 lightSensorWarmUpTimeConfig, screenBrightnessRangeMinimum,
Filip Gruszczynskid81ecd12015-02-06 12:38:47 -0800354 mScreenBrightnessRangeMaximum, dozeScaleFactor, lightSensorRate,
355 brighteningLightDebounce, darkeningLightDebounce,
Zoran Jovanovic6fc42f52015-12-10 17:01:16 +0100356 autoBrightnessResetAmbientLuxAfterWarmUp,
357 ambientLightHorizon, autoBrightnessAdjustmentMaxGamma);
Jeff Brown96307042012-07-27 15:51:34 -0700358 }
Jeff Brown96307042012-07-27 15:51:34 -0700359 }
360
Michael Wright639c8be2014-01-17 18:29:12 -0800361 mScreenBrightnessRangeMinimum = screenBrightnessRangeMinimum;
Jeff Brownb76eebff2012-10-05 22:26:44 -0700362
Michael Lentine0839adb2014-07-29 18:47:56 -0700363 mColorFadeFadesConfig = resources.getBoolean(
Jeff Browna52772f2012-10-04 18:38:09 -0700364 com.android.internal.R.bool.config_animateScreenLights);
365
Jeff Brown96307042012-07-27 15:51:34 -0700366 if (!DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) {
367 mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
368 if (mProximitySensor != null) {
369 mProximityThreshold = Math.min(mProximitySensor.getMaximumRange(),
370 TYPICAL_PROXIMITY_THRESHOLD);
371 }
372 }
373
Jeff Brown1a30b552012-08-16 01:31:11 -0700374 }
375
Jeff Brown96307042012-07-27 15:51:34 -0700376 /**
377 * Returns true if the proximity sensor screen-off function is available.
378 */
379 public boolean isProximitySensorAvailable() {
380 return mProximitySensor != null;
381 }
382
383 /**
384 * Requests a new power state.
385 * The controller makes a copy of the provided object and then
386 * begins adjusting the power state to match what was requested.
387 *
388 * @param request The requested power state.
389 * @param waitForNegativeProximity If true, issues a request to wait for
390 * negative proximity before turning the screen back on, assuming the screen
391 * was turned off by the proximity sensor.
392 * @return True if display is ready, false if there are important changes that must
393 * be made asynchronously (such as turning the screen on), in which case the caller
Jeff Brown606e4e82014-09-18 15:22:26 -0700394 * should grab a wake lock, watch for {@link DisplayPowerCallbacks#onStateChanged()}
395 * then try the request again later until the state converges.
Jeff Brown96307042012-07-27 15:51:34 -0700396 */
397 public boolean requestPowerState(DisplayPowerRequest request,
398 boolean waitForNegativeProximity) {
399 if (DEBUG) {
400 Slog.d(TAG, "requestPowerState: "
401 + request + ", waitForNegativeProximity=" + waitForNegativeProximity);
402 }
403
404 synchronized (mLock) {
405 boolean changed = false;
406
407 if (waitForNegativeProximity
408 && !mPendingWaitForNegativeProximityLocked) {
409 mPendingWaitForNegativeProximityLocked = true;
410 changed = true;
411 }
412
413 if (mPendingRequestLocked == null) {
414 mPendingRequestLocked = new DisplayPowerRequest(request);
415 changed = true;
416 } else if (!mPendingRequestLocked.equals(request)) {
417 mPendingRequestLocked.copyFrom(request);
418 changed = true;
419 }
420
421 if (changed) {
422 mDisplayReadyLocked = false;
423 }
424
425 if (changed && !mPendingRequestChangedLocked) {
426 mPendingRequestChangedLocked = true;
427 sendUpdatePowerStateLocked();
428 }
429
430 return mDisplayReadyLocked;
431 }
432 }
433
434 private void sendUpdatePowerState() {
435 synchronized (mLock) {
436 sendUpdatePowerStateLocked();
437 }
438 }
439
440 private void sendUpdatePowerStateLocked() {
441 if (!mPendingUpdatePowerStateLocked) {
442 mPendingUpdatePowerStateLocked = true;
443 Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE);
444 msg.setAsynchronous(true);
445 mHandler.sendMessage(msg);
446 }
447 }
448
449 private void initialize() {
Jeff Brown037c33e2014-04-09 00:31:55 -0700450 // Initialize the power state object for the default display.
451 // In the future, we might manage multiple displays independently.
452 mPowerState = new DisplayPowerState(mBlanker,
Michael Lentine0839adb2014-07-29 18:47:56 -0700453 new ColorFade(Display.DEFAULT_DISPLAY));
Jeff Brown96307042012-07-27 15:51:34 -0700454
Michael Lentine0839adb2014-07-29 18:47:56 -0700455 mColorFadeOnAnimator = ObjectAnimator.ofFloat(
456 mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 0.0f, 1.0f);
457 mColorFadeOnAnimator.setDuration(COLOR_FADE_ON_ANIMATION_DURATION_MILLIS);
458 mColorFadeOnAnimator.addListener(mAnimatorListener);
Jeff Brown96307042012-07-27 15:51:34 -0700459
Michael Lentine0839adb2014-07-29 18:47:56 -0700460 mColorFadeOffAnimator = ObjectAnimator.ofFloat(
461 mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 1.0f, 0.0f);
462 mColorFadeOffAnimator.setDuration(COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS);
463 mColorFadeOffAnimator.addListener(mAnimatorListener);
Jeff Brown96307042012-07-27 15:51:34 -0700464
465 mScreenBrightnessRampAnimator = new RampAnimator<DisplayPowerState>(
466 mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS);
Jeff Brown42558692014-05-20 22:02:46 -0700467 mScreenBrightnessRampAnimator.setListener(mRampAnimatorListener);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800468
Jeff Brown131206b2014-04-08 17:27:14 -0700469 // Initialize screen state for battery stats.
470 try {
Jeff Browne95c3cd2014-05-02 16:59:26 -0700471 mBatteryStats.noteScreenState(mPowerState.getScreenState());
Jeff Brown131206b2014-04-08 17:27:14 -0700472 mBatteryStats.noteScreenBrightness(mPowerState.getScreenBrightness());
473 } catch (RemoteException ex) {
474 // same process
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800475 }
Jeff Brown96307042012-07-27 15:51:34 -0700476 }
477
478 private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() {
479 @Override
480 public void onAnimationStart(Animator animation) {
481 }
482 @Override
483 public void onAnimationEnd(Animator animation) {
484 sendUpdatePowerState();
485 }
486 @Override
487 public void onAnimationRepeat(Animator animation) {
488 }
489 @Override
490 public void onAnimationCancel(Animator animation) {
491 }
492 };
493
Jeff Brown42558692014-05-20 22:02:46 -0700494 private final RampAnimator.Listener mRampAnimatorListener = new RampAnimator.Listener() {
495 @Override
496 public void onAnimationEnd() {
497 sendUpdatePowerState();
498 }
499 };
500
Jeff Brown96307042012-07-27 15:51:34 -0700501 private void updatePowerState() {
502 // Update the power state request.
503 final boolean mustNotify;
504 boolean mustInitialize = false;
Adrian Roos6da87ab2014-05-16 23:09:41 +0200505 boolean autoBrightnessAdjustmentChanged = false;
Jeff Brown330560f2012-08-21 22:10:57 -0700506
Jeff Brown96307042012-07-27 15:51:34 -0700507 synchronized (mLock) {
508 mPendingUpdatePowerStateLocked = false;
509 if (mPendingRequestLocked == null) {
510 return; // wait until first actual power request
511 }
512
513 if (mPowerRequest == null) {
514 mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked);
515 mWaitingForNegativeProximity = mPendingWaitForNegativeProximityLocked;
Jeff Brown6307a152012-08-20 13:24:23 -0700516 mPendingWaitForNegativeProximityLocked = false;
Jeff Brown96307042012-07-27 15:51:34 -0700517 mPendingRequestChangedLocked = false;
518 mustInitialize = true;
519 } else if (mPendingRequestChangedLocked) {
Adrian Roos6da87ab2014-05-16 23:09:41 +0200520 autoBrightnessAdjustmentChanged = (mPowerRequest.screenAutoBrightnessAdjustment
521 != mPendingRequestLocked.screenAutoBrightnessAdjustment);
Jeff Brown96307042012-07-27 15:51:34 -0700522 mPowerRequest.copyFrom(mPendingRequestLocked);
523 mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked;
Jeff Brown6307a152012-08-20 13:24:23 -0700524 mPendingWaitForNegativeProximityLocked = false;
Jeff Brown96307042012-07-27 15:51:34 -0700525 mPendingRequestChangedLocked = false;
526 mDisplayReadyLocked = false;
527 }
528
529 mustNotify = !mDisplayReadyLocked;
530 }
531
532 // Initialize things the first time the power state is changed.
533 if (mustInitialize) {
534 initialize();
535 }
536
Jeff Brown970d4132014-07-19 11:33:47 -0700537 // Compute the basic display state using the policy.
538 // We might override this below based on other factors.
539 int state;
540 int brightness = PowerManager.BRIGHTNESS_DEFAULT;
Jeff Brown2175e9c2014-09-12 16:11:07 -0700541 boolean performScreenOffTransition = false;
Jeff Brown970d4132014-07-19 11:33:47 -0700542 switch (mPowerRequest.policy) {
543 case DisplayPowerRequest.POLICY_OFF:
544 state = Display.STATE_OFF;
Jeff Brown2175e9c2014-09-12 16:11:07 -0700545 performScreenOffTransition = true;
Jeff Brown970d4132014-07-19 11:33:47 -0700546 break;
547 case DisplayPowerRequest.POLICY_DOZE:
548 if (mPowerRequest.dozeScreenState != Display.STATE_UNKNOWN) {
549 state = mPowerRequest.dozeScreenState;
550 } else {
551 state = Display.STATE_DOZE;
552 }
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700553 if (!mAllowAutoBrightnessWhileDozingConfig) {
554 brightness = mPowerRequest.dozeScreenBrightness;
555 }
Jeff Brown970d4132014-07-19 11:33:47 -0700556 break;
557 case DisplayPowerRequest.POLICY_DIM:
558 case DisplayPowerRequest.POLICY_BRIGHT:
559 default:
560 state = Display.STATE_ON;
561 break;
562 }
Jeff Brown2175e9c2014-09-12 16:11:07 -0700563 assert(state != Display.STATE_UNKNOWN);
Jeff Brown970d4132014-07-19 11:33:47 -0700564
Jeff Brown6307a152012-08-20 13:24:23 -0700565 // Apply the proximity sensor.
Jeff Brown96307042012-07-27 15:51:34 -0700566 if (mProximitySensor != null) {
Jeff Brown970d4132014-07-19 11:33:47 -0700567 if (mPowerRequest.useProximitySensor && state != Display.STATE_OFF) {
Jeff Brown6307a152012-08-20 13:24:23 -0700568 setProximitySensorEnabled(true);
569 if (!mScreenOffBecauseOfProximity
570 && mProximity == PROXIMITY_POSITIVE) {
571 mScreenOffBecauseOfProximity = true;
Jeff Brownec083212013-09-11 20:45:25 -0700572 sendOnProximityPositiveWithWakelock();
Jeff Brown6307a152012-08-20 13:24:23 -0700573 }
574 } else if (mWaitingForNegativeProximity
575 && mScreenOffBecauseOfProximity
576 && mProximity == PROXIMITY_POSITIVE
Jeff Brown970d4132014-07-19 11:33:47 -0700577 && state != Display.STATE_OFF) {
Jeff Brown6307a152012-08-20 13:24:23 -0700578 setProximitySensorEnabled(true);
579 } else {
580 setProximitySensorEnabled(false);
581 mWaitingForNegativeProximity = false;
582 }
583 if (mScreenOffBecauseOfProximity
584 && mProximity != PROXIMITY_POSITIVE) {
Jeff Brown96307042012-07-27 15:51:34 -0700585 mScreenOffBecauseOfProximity = false;
Jeff Brownec083212013-09-11 20:45:25 -0700586 sendOnProximityNegativeWithWakelock();
Jeff Brown96307042012-07-27 15:51:34 -0700587 }
Jeff Brown6307a152012-08-20 13:24:23 -0700588 } else {
589 mWaitingForNegativeProximity = false;
Jeff Brown96307042012-07-27 15:51:34 -0700590 }
Jeff Brown970d4132014-07-19 11:33:47 -0700591 if (mScreenOffBecauseOfProximity) {
592 state = Display.STATE_OFF;
Jeff Brown96307042012-07-27 15:51:34 -0700593 }
594
Jeff Brownbf4e4142014-10-02 13:08:05 -0700595 // Animate the screen state change unless already animating.
596 // The transition may be deferred, so after this point we will use the
597 // actual state instead of the desired one.
598 animateScreenStateChange(state, performScreenOffTransition);
599 state = mPowerState.getScreenState();
600
Jeff Brown970d4132014-07-19 11:33:47 -0700601 // Use zero brightness when screen is off.
602 if (state == Display.STATE_OFF) {
603 brightness = PowerManager.BRIGHTNESS_OFF;
604 }
605
Jeff Brown970d4132014-07-19 11:33:47 -0700606 // Configure auto-brightness.
607 boolean autoBrightnessEnabled = false;
608 if (mAutomaticBrightnessController != null) {
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700609 final boolean autoBrightnessEnabledInDoze = mAllowAutoBrightnessWhileDozingConfig
610 && (state == Display.STATE_DOZE || state == Display.STATE_DOZE_SUSPEND);
Jeff Brown970d4132014-07-19 11:33:47 -0700611 autoBrightnessEnabled = mPowerRequest.useAutoBrightness
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700612 && (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
613 && brightness < 0;
Jeff Browna576b4d2015-04-23 19:58:06 -0700614 final boolean userInitiatedChange = autoBrightnessAdjustmentChanged
615 && mPowerRequest.brightnessSetByUser;
Jeff Brown970d4132014-07-19 11:33:47 -0700616 mAutomaticBrightnessController.configure(autoBrightnessEnabled,
Jeff Browna576b4d2015-04-23 19:58:06 -0700617 mPowerRequest.screenAutoBrightnessAdjustment, state != Display.STATE_ON,
Jason Monk5dbd4aa2016-02-07 13:13:39 -0500618 userInitiatedChange, mPowerRequest.useTwilight);
Jeff Brown970d4132014-07-19 11:33:47 -0700619 }
620
Jeff Brown7b5be5e2014-11-12 18:45:31 -0800621 // Apply brightness boost.
622 // We do this here after configuring auto-brightness so that we don't
623 // disable the light sensor during this temporary state. That way when
624 // boost ends we will be able to resume normal auto-brightness behavior
625 // without any delay.
626 if (mPowerRequest.boostScreenBrightness
627 && brightness != PowerManager.BRIGHTNESS_OFF) {
628 brightness = PowerManager.BRIGHTNESS_ON;
629 }
630
Jeff Brown970d4132014-07-19 11:33:47 -0700631 // Apply auto-brightness.
632 boolean slowChange = false;
633 if (brightness < 0) {
634 if (autoBrightnessEnabled) {
635 brightness = mAutomaticBrightnessController.getAutomaticScreenBrightness();
636 }
637 if (brightness >= 0) {
638 // Use current auto-brightness value and slowly adjust to changes.
639 brightness = clampScreenBrightness(brightness);
640 if (mAppliedAutoBrightness && !autoBrightnessAdjustmentChanged) {
641 slowChange = true; // slowly adapt to auto-brightness
642 }
643 mAppliedAutoBrightness = true;
Jeff Brown96307042012-07-27 15:51:34 -0700644 } else {
Jeff Brown970d4132014-07-19 11:33:47 -0700645 mAppliedAutoBrightness = false;
Jeff Brown96307042012-07-27 15:51:34 -0700646 }
647 } else {
Jeff Brown970d4132014-07-19 11:33:47 -0700648 mAppliedAutoBrightness = false;
649 }
650
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700651 // Use default brightness when dozing unless overridden.
652 if (brightness < 0 && (state == Display.STATE_DOZE
653 || state == Display.STATE_DOZE_SUSPEND)) {
654 brightness = mScreenBrightnessDozeConfig;
655 }
656
Jeff Brown970d4132014-07-19 11:33:47 -0700657 // Apply manual brightness.
658 // Use the current brightness setting from the request, which is expected
659 // provide a nominal default value for the case where auto-brightness
660 // is not ready yet.
661 if (brightness < 0) {
662 brightness = clampScreenBrightness(mPowerRequest.screenBrightness);
663 }
664
665 // Apply dimming by at least some minimum amount when user activity
666 // timeout is about to expire.
667 if (mPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
Jeff Brown5c8ea082014-07-24 19:30:31 -0700668 if (brightness > mScreenBrightnessRangeMinimum) {
669 brightness = Math.max(Math.min(brightness - SCREEN_DIM_MINIMUM_REDUCTION,
670 mScreenBrightnessDimConfig), mScreenBrightnessRangeMinimum);
671 }
Jeff Brown970d4132014-07-19 11:33:47 -0700672 if (!mAppliedDimming) {
673 slowChange = false;
674 }
675 mAppliedDimming = true;
mochangmingf0cb46c2015-12-29 13:55:24 +0800676 } else if (mAppliedDimming) {
677 slowChange = false;
678 mAppliedDimming = false;
Jeff Brown970d4132014-07-19 11:33:47 -0700679 }
680
681 // If low power mode is enabled, cut the brightness level by half
682 // as long as it is above the minimum threshold.
683 if (mPowerRequest.lowPowerMode) {
684 if (brightness > mScreenBrightnessRangeMinimum) {
685 brightness = Math.max(brightness / 2, mScreenBrightnessRangeMinimum);
686 }
687 if (!mAppliedLowPower) {
688 slowChange = false;
689 }
690 mAppliedLowPower = true;
mochangmingf0cb46c2015-12-29 13:55:24 +0800691 } else if (mAppliedLowPower) {
692 slowChange = false;
693 mAppliedLowPower = false;
Jeff Brown970d4132014-07-19 11:33:47 -0700694 }
695
Jeff Brown0a434772014-09-30 14:42:27 -0700696 // Animate the screen brightness when the screen is on or dozing.
697 // Skip the animation when the screen is off or suspended.
Prashant Malani33538242014-11-13 14:04:00 -0800698 if (!mPendingScreenOff) {
699 if (state == Display.STATE_ON || state == Display.STATE_DOZE) {
700 animateScreenBrightness(brightness,
701 slowChange ? BRIGHTNESS_RAMP_RATE_SLOW : BRIGHTNESS_RAMP_RATE_FAST);
702 } else {
703 animateScreenBrightness(brightness, 0);
704 }
Jeff Brown0a434772014-09-30 14:42:27 -0700705 }
706
707 // Determine whether the display is ready for use in the newly requested state.
708 // Note that we do not wait for the brightness ramp animation to complete before
709 // reporting the display is ready because we only need to ensure the screen is in the
710 // right power state even as it continues to converge on the desired brightness.
711 final boolean ready = mPendingScreenOnUnblocker == null
Michael Lentine0839adb2014-07-29 18:47:56 -0700712 && !mColorFadeOnAnimator.isStarted()
713 && !mColorFadeOffAnimator.isStarted()
Jeff Brown0a434772014-09-30 14:42:27 -0700714 && mPowerState.waitUntilClean(mCleanListener);
715 final boolean finished = ready
716 && !mScreenBrightnessRampAnimator.isAnimating();
717
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700718 // Notify policy about screen turned on.
719 if (ready && state != Display.STATE_OFF
720 && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_ON) {
721 mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_ON;
722 mWindowManagerPolicy.screenTurnedOn();
723 }
724
Jeff Brown0a434772014-09-30 14:42:27 -0700725 // Grab a wake lock if we have unfinished business.
726 if (!finished && !mUnfinishedBusiness) {
727 if (DEBUG) {
728 Slog.d(TAG, "Unfinished business...");
729 }
730 mCallbacks.acquireSuspendBlocker();
731 mUnfinishedBusiness = true;
732 }
733
734 // Notify the power manager when ready.
735 if (ready && mustNotify) {
736 // Send state change.
Jeff Brown96307042012-07-27 15:51:34 -0700737 synchronized (mLock) {
738 if (!mPendingRequestChangedLocked) {
739 mDisplayReadyLocked = true;
Jeff Brownc38c9be2012-10-04 13:16:19 -0700740
741 if (DEBUG) {
742 Slog.d(TAG, "Display ready!");
743 }
Jeff Brown96307042012-07-27 15:51:34 -0700744 }
745 }
Jeff Brownec083212013-09-11 20:45:25 -0700746 sendOnStateChangedWithWakelock();
Jeff Brown96307042012-07-27 15:51:34 -0700747 }
Jeff Brown0a434772014-09-30 14:42:27 -0700748
749 // Release the wake lock when we have no unfinished business.
750 if (finished && mUnfinishedBusiness) {
751 if (DEBUG) {
752 Slog.d(TAG, "Finished business...");
753 }
754 mUnfinishedBusiness = false;
755 mCallbacks.releaseSuspendBlocker();
756 }
Jeff Brown96307042012-07-27 15:51:34 -0700757 }
758
Michael Wright639c8be2014-01-17 18:29:12 -0800759 @Override
760 public void updateBrightness() {
761 sendUpdatePowerState();
762 }
763
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700764 private void blockScreenOn() {
Jeff Brown3ee549c2014-09-22 20:14:39 -0700765 if (mPendingScreenOnUnblocker == null) {
Jeff Brown3edf5272014-08-14 19:25:14 -0700766 Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0);
Jeff Brown3ee549c2014-09-22 20:14:39 -0700767 mPendingScreenOnUnblocker = new ScreenOnUnblocker();
Jeff Brown037c33e2014-04-09 00:31:55 -0700768 mScreenOnBlockStartRealTime = SystemClock.elapsedRealtime();
Jeff Brown3edf5272014-08-14 19:25:14 -0700769 Slog.i(TAG, "Blocking screen on until initial contents have been drawn.");
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700770 }
771 }
772
773 private void unblockScreenOn() {
Jeff Brown3ee549c2014-09-22 20:14:39 -0700774 if (mPendingScreenOnUnblocker != null) {
775 mPendingScreenOnUnblocker = null;
Jeff Brown2d8a3902014-03-11 23:02:35 -0700776 long delay = SystemClock.elapsedRealtime() - mScreenOnBlockStartRealTime;
Jeff Brown3edf5272014-08-14 19:25:14 -0700777 Slog.i(TAG, "Unblocked screen on after " + delay + " ms");
778 Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0);
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700779 }
780 }
781
Jeff Brown3ee549c2014-09-22 20:14:39 -0700782 private boolean setScreenState(int state) {
Jeff Brown037c33e2014-04-09 00:31:55 -0700783 if (mPowerState.getScreenState() != state) {
Jeff Brown3ee549c2014-09-22 20:14:39 -0700784 final boolean wasOn = (mPowerState.getScreenState() != Display.STATE_OFF);
Jeff Brown037c33e2014-04-09 00:31:55 -0700785 mPowerState.setScreenState(state);
Jeff Brown3ee549c2014-09-22 20:14:39 -0700786
787 // Tell battery stats about the transition.
Jeff Brown131206b2014-04-08 17:27:14 -0700788 try {
Jeff Browne95c3cd2014-05-02 16:59:26 -0700789 mBatteryStats.noteScreenState(state);
Jeff Brown131206b2014-04-08 17:27:14 -0700790 } catch (RemoteException ex) {
791 // same process
Jeff Brown96307042012-07-27 15:51:34 -0700792 }
793 }
Jeff Browne1633ad2015-06-22 19:24:24 -0700794
795 // Tell the window manager policy when the screen is turned off or on unless it's due
796 // to the proximity sensor. We temporarily block turning the screen on until the
797 // window manager is ready by leaving a black surface covering the screen.
798 // This surface is essentially the final state of the color fade animation and
799 // it is only removed once the window manager tells us that the activity has
800 // finished drawing underneath.
801 final boolean isOff = (state == Display.STATE_OFF);
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700802 if (isOff && mReportedScreenStateToPolicy != REPORTED_TO_POLICY_SCREEN_OFF
803 && !mScreenOffBecauseOfProximity) {
804 mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_OFF;
Jeff Browne1633ad2015-06-22 19:24:24 -0700805 unblockScreenOn();
806 mWindowManagerPolicy.screenTurnedOff();
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700807 } else if (!isOff && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF) {
808 mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_TURNING_ON;
Jeff Browne1633ad2015-06-22 19:24:24 -0700809 if (mPowerState.getColorFadeLevel() == 0.0f) {
810 blockScreenOn();
811 } else {
812 unblockScreenOn();
813 }
814 mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker);
815 }
816
817 // Return true if the screen isn't blocked.
Jeff Brown3ee549c2014-09-22 20:14:39 -0700818 return mPendingScreenOnUnblocker == null;
Jeff Brown96307042012-07-27 15:51:34 -0700819 }
820
Jeff Brown330560f2012-08-21 22:10:57 -0700821 private int clampScreenBrightness(int value) {
Michael Wright639c8be2014-01-17 18:29:12 -0800822 return MathUtils.constrain(
823 value, mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum);
Jeff Brown330560f2012-08-21 22:10:57 -0700824 }
825
Jeff Brown96307042012-07-27 15:51:34 -0700826 private void animateScreenBrightness(int target, int rate) {
Jeff Brown0a434772014-09-30 14:42:27 -0700827 if (DEBUG) {
828 Slog.d(TAG, "Animating brightness: target=" + target +", rate=" + rate);
829 }
Jeff Brown96307042012-07-27 15:51:34 -0700830 if (mScreenBrightnessRampAnimator.animateTo(target, rate)) {
Jeff Brown131206b2014-04-08 17:27:14 -0700831 try {
832 mBatteryStats.noteScreenBrightness(target);
833 } catch (RemoteException ex) {
834 // same process
835 }
Jeff Brown96307042012-07-27 15:51:34 -0700836 }
837 }
838
Jeff Brown606e4e82014-09-18 15:22:26 -0700839 private void animateScreenStateChange(int target, boolean performScreenOffTransition) {
840 // If there is already an animation in progress, don't interfere with it.
841 if (mColorFadeOnAnimator.isStarted()
842 || mColorFadeOffAnimator.isStarted()) {
Chong Zhangb131c702016-02-16 16:31:48 -0800843 if (target != Display.STATE_ON) {
844 return;
845 }
846 // If display state changed to on, proceed and stop the color fade and turn screen on.
847 mPendingScreenOff = false;
Jeff Brown606e4e82014-09-18 15:22:26 -0700848 }
849
Jeff Brown3ee549c2014-09-22 20:14:39 -0700850 // If we were in the process of turning off the screen but didn't quite
851 // finish. Then finish up now to prevent a jarring transition back
852 // to screen on if we skipped blocking screen on as usual.
853 if (mPendingScreenOff && target != Display.STATE_OFF) {
854 setScreenState(Display.STATE_OFF);
855 mPendingScreenOff = false;
Michael Lentined73854d2015-09-25 10:55:26 -0700856 mPowerState.dismissColorFadeResources();
Jeff Brown606e4e82014-09-18 15:22:26 -0700857 }
858
859 if (target == Display.STATE_ON) {
860 // Want screen on. The contents of the screen may not yet
Jeff Brown3ee549c2014-09-22 20:14:39 -0700861 // be visible if the color fade has not been dismissed because
Jeff Brown606e4e82014-09-18 15:22:26 -0700862 // its last frame of animation is solid black.
Jeff Brown3ee549c2014-09-22 20:14:39 -0700863 if (!setScreenState(Display.STATE_ON)) {
864 return; // screen on blocked
865 }
Jeff Brown606e4e82014-09-18 15:22:26 -0700866 if (USE_COLOR_FADE_ON_ANIMATION && mPowerRequest.isBrightOrDim()) {
867 // Perform screen on animation.
868 if (mPowerState.getColorFadeLevel() == 1.0f) {
869 mPowerState.dismissColorFade();
870 } else if (mPowerState.prepareColorFade(mContext,
871 mColorFadeFadesConfig ?
872 ColorFade.MODE_FADE :
873 ColorFade.MODE_WARM_UP)) {
874 mColorFadeOnAnimator.start();
875 } else {
876 mColorFadeOnAnimator.end();
877 }
878 } else {
879 // Skip screen on animation.
880 mPowerState.setColorFadeLevel(1.0f);
881 mPowerState.dismissColorFade();
882 }
883 } else if (target == Display.STATE_DOZE) {
884 // Want screen dozing.
885 // Wait for brightness animation to complete beforehand when entering doze
886 // from screen on to prevent a perceptible jump because brightness may operate
887 // differently when the display is configured for dozing.
888 if (mScreenBrightnessRampAnimator.isAnimating()
889 && mPowerState.getScreenState() == Display.STATE_ON) {
890 return;
891 }
892
Jeff Brown3ee549c2014-09-22 20:14:39 -0700893 // Set screen state.
894 if (!setScreenState(Display.STATE_DOZE)) {
895 return; // screen on blocked
896 }
897
898 // Dismiss the black surface without fanfare.
Jeff Brown606e4e82014-09-18 15:22:26 -0700899 mPowerState.setColorFadeLevel(1.0f);
900 mPowerState.dismissColorFade();
901 } else if (target == Display.STATE_DOZE_SUSPEND) {
902 // Want screen dozing and suspended.
903 // Wait for brightness animation to complete beforehand unless already
904 // suspended because we may not be able to change it after suspension.
905 if (mScreenBrightnessRampAnimator.isAnimating()
906 && mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) {
907 return;
908 }
909
Jeff Brown3ee549c2014-09-22 20:14:39 -0700910 // If not already suspending, temporarily set the state to doze until the
911 // screen on is unblocked, then suspend.
912 if (mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) {
913 if (!setScreenState(Display.STATE_DOZE)) {
914 return; // screen on blocked
915 }
916 setScreenState(Display.STATE_DOZE_SUSPEND); // already on so can't block
917 }
918
919 // Dismiss the black surface without fanfare.
Jeff Brown606e4e82014-09-18 15:22:26 -0700920 mPowerState.setColorFadeLevel(1.0f);
921 mPowerState.dismissColorFade();
922 } else {
923 // Want screen off.
Jeff Brown3ee549c2014-09-22 20:14:39 -0700924 mPendingScreenOff = true;
Jeff Brown606e4e82014-09-18 15:22:26 -0700925 if (mPowerState.getColorFadeLevel() == 0.0f) {
926 // Turn the screen off.
927 // A black surface is already hiding the contents of the screen.
928 setScreenState(Display.STATE_OFF);
Jeff Brown3ee549c2014-09-22 20:14:39 -0700929 mPendingScreenOff = false;
Michael Lentined73854d2015-09-25 10:55:26 -0700930 mPowerState.dismissColorFadeResources();
Jeff Brown606e4e82014-09-18 15:22:26 -0700931 } else if (performScreenOffTransition
932 && mPowerState.prepareColorFade(mContext,
933 mColorFadeFadesConfig ?
934 ColorFade.MODE_FADE : ColorFade.MODE_COOL_DOWN)
935 && mPowerState.getScreenState() != Display.STATE_OFF) {
936 // Perform the screen off animation.
937 mColorFadeOffAnimator.start();
938 } else {
939 // Skip the screen off animation and add a black surface to hide the
940 // contents of the screen.
941 mColorFadeOffAnimator.end();
942 }
943 }
944 }
945
Jeff Brown96307042012-07-27 15:51:34 -0700946 private final Runnable mCleanListener = new Runnable() {
947 @Override
948 public void run() {
949 sendUpdatePowerState();
950 }
951 };
952
953 private void setProximitySensorEnabled(boolean enable) {
954 if (enable) {
955 if (!mProximitySensorEnabled) {
Jeff Brownec083212013-09-11 20:45:25 -0700956 // Register the listener.
957 // Proximity sensor state already cleared initially.
Jeff Brown96307042012-07-27 15:51:34 -0700958 mProximitySensorEnabled = true;
Jeff Brown96307042012-07-27 15:51:34 -0700959 mSensorManager.registerListener(mProximitySensorListener, mProximitySensor,
960 SensorManager.SENSOR_DELAY_NORMAL, mHandler);
961 }
962 } else {
963 if (mProximitySensorEnabled) {
Jeff Brownec083212013-09-11 20:45:25 -0700964 // Unregister the listener.
965 // Clear the proximity sensor state for next time.
Jeff Brown96307042012-07-27 15:51:34 -0700966 mProximitySensorEnabled = false;
967 mProximity = PROXIMITY_UNKNOWN;
Jeff Brownec083212013-09-11 20:45:25 -0700968 mPendingProximity = PROXIMITY_UNKNOWN;
Jeff Brown96307042012-07-27 15:51:34 -0700969 mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
970 mSensorManager.unregisterListener(mProximitySensorListener);
Jeff Brownec083212013-09-11 20:45:25 -0700971 clearPendingProximityDebounceTime(); // release wake lock (must be last)
Jeff Brown96307042012-07-27 15:51:34 -0700972 }
973 }
974 }
975
976 private void handleProximitySensorEvent(long time, boolean positive) {
Jeff Brownec083212013-09-11 20:45:25 -0700977 if (mProximitySensorEnabled) {
978 if (mPendingProximity == PROXIMITY_NEGATIVE && !positive) {
979 return; // no change
980 }
981 if (mPendingProximity == PROXIMITY_POSITIVE && positive) {
982 return; // no change
983 }
Jeff Brown96307042012-07-27 15:51:34 -0700984
Jeff Brownec083212013-09-11 20:45:25 -0700985 // Only accept a proximity sensor reading if it remains
986 // stable for the entire debounce delay. We hold a wake lock while
987 // debouncing the sensor.
988 mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
989 if (positive) {
990 mPendingProximity = PROXIMITY_POSITIVE;
991 setPendingProximityDebounceTime(
992 time + PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY); // acquire wake lock
993 } else {
994 mPendingProximity = PROXIMITY_NEGATIVE;
995 setPendingProximityDebounceTime(
996 time + PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY); // acquire wake lock
997 }
998
999 // Debounce the new sensor reading.
1000 debounceProximitySensor();
Jeff Brown93cbbb22012-10-04 13:18:36 -07001001 }
Jeff Brown96307042012-07-27 15:51:34 -07001002 }
1003
1004 private void debounceProximitySensor() {
Jeff Brownec083212013-09-11 20:45:25 -07001005 if (mProximitySensorEnabled
1006 && mPendingProximity != PROXIMITY_UNKNOWN
1007 && mPendingProximityDebounceTime >= 0) {
Jeff Brown96307042012-07-27 15:51:34 -07001008 final long now = SystemClock.uptimeMillis();
1009 if (mPendingProximityDebounceTime <= now) {
Jeff Brownec083212013-09-11 20:45:25 -07001010 // Sensor reading accepted. Apply the change then release the wake lock.
Jeff Brown96307042012-07-27 15:51:34 -07001011 mProximity = mPendingProximity;
Jeff Brownec083212013-09-11 20:45:25 -07001012 updatePowerState();
1013 clearPendingProximityDebounceTime(); // release wake lock (must be last)
Jeff Brown96307042012-07-27 15:51:34 -07001014 } else {
Jeff Brownec083212013-09-11 20:45:25 -07001015 // Need to wait a little longer.
1016 // Debounce again later. We continue holding a wake lock while waiting.
Jeff Brown96307042012-07-27 15:51:34 -07001017 Message msg = mHandler.obtainMessage(MSG_PROXIMITY_SENSOR_DEBOUNCED);
1018 msg.setAsynchronous(true);
1019 mHandler.sendMessageAtTime(msg, mPendingProximityDebounceTime);
1020 }
1021 }
1022 }
1023
Jeff Brownec083212013-09-11 20:45:25 -07001024 private void clearPendingProximityDebounceTime() {
1025 if (mPendingProximityDebounceTime >= 0) {
1026 mPendingProximityDebounceTime = -1;
Jeff Brown131206b2014-04-08 17:27:14 -07001027 mCallbacks.releaseSuspendBlocker(); // release wake lock
Jeff Brownec083212013-09-11 20:45:25 -07001028 }
1029 }
1030
1031 private void setPendingProximityDebounceTime(long debounceTime) {
1032 if (mPendingProximityDebounceTime < 0) {
Jeff Brown131206b2014-04-08 17:27:14 -07001033 mCallbacks.acquireSuspendBlocker(); // acquire wake lock
Jeff Brownec083212013-09-11 20:45:25 -07001034 }
1035 mPendingProximityDebounceTime = debounceTime;
1036 }
1037
Jeff Brownec083212013-09-11 20:45:25 -07001038 private void sendOnStateChangedWithWakelock() {
Jeff Brown131206b2014-04-08 17:27:14 -07001039 mCallbacks.acquireSuspendBlocker();
1040 mHandler.post(mOnStateChangedRunnable);
Jeff Brown96307042012-07-27 15:51:34 -07001041 }
1042
1043 private final Runnable mOnStateChangedRunnable = new Runnable() {
1044 @Override
1045 public void run() {
1046 mCallbacks.onStateChanged();
Jeff Brown131206b2014-04-08 17:27:14 -07001047 mCallbacks.releaseSuspendBlocker();
Jeff Brown96307042012-07-27 15:51:34 -07001048 }
1049 };
1050
Jeff Brownec083212013-09-11 20:45:25 -07001051 private void sendOnProximityPositiveWithWakelock() {
Jeff Brown131206b2014-04-08 17:27:14 -07001052 mCallbacks.acquireSuspendBlocker();
1053 mHandler.post(mOnProximityPositiveRunnable);
Jeff Brown93cbbb22012-10-04 13:18:36 -07001054 }
1055
1056 private final Runnable mOnProximityPositiveRunnable = new Runnable() {
1057 @Override
1058 public void run() {
1059 mCallbacks.onProximityPositive();
Jeff Brown131206b2014-04-08 17:27:14 -07001060 mCallbacks.releaseSuspendBlocker();
Jeff Brown93cbbb22012-10-04 13:18:36 -07001061 }
1062 };
1063
Jeff Brownec083212013-09-11 20:45:25 -07001064 private void sendOnProximityNegativeWithWakelock() {
Jeff Brown131206b2014-04-08 17:27:14 -07001065 mCallbacks.acquireSuspendBlocker();
1066 mHandler.post(mOnProximityNegativeRunnable);
Jeff Brown96307042012-07-27 15:51:34 -07001067 }
1068
1069 private final Runnable mOnProximityNegativeRunnable = new Runnable() {
1070 @Override
1071 public void run() {
1072 mCallbacks.onProximityNegative();
Jeff Brown131206b2014-04-08 17:27:14 -07001073 mCallbacks.releaseSuspendBlocker();
Jeff Brown96307042012-07-27 15:51:34 -07001074 }
1075 };
1076
Jeff Brownbd6e1502012-08-28 03:27:37 -07001077 public void dump(final PrintWriter pw) {
Jeff Brown96307042012-07-27 15:51:34 -07001078 synchronized (mLock) {
1079 pw.println();
Jeff Brown131206b2014-04-08 17:27:14 -07001080 pw.println("Display Power Controller Locked State:");
Jeff Brown96307042012-07-27 15:51:34 -07001081 pw.println(" mDisplayReadyLocked=" + mDisplayReadyLocked);
1082 pw.println(" mPendingRequestLocked=" + mPendingRequestLocked);
1083 pw.println(" mPendingRequestChangedLocked=" + mPendingRequestChangedLocked);
1084 pw.println(" mPendingWaitForNegativeProximityLocked="
1085 + mPendingWaitForNegativeProximityLocked);
1086 pw.println(" mPendingUpdatePowerStateLocked=" + mPendingUpdatePowerStateLocked);
1087 }
1088
1089 pw.println();
Jeff Brown131206b2014-04-08 17:27:14 -07001090 pw.println("Display Power Controller Configuration:");
Jeff Brown26875502014-01-30 21:47:47 -08001091 pw.println(" mScreenBrightnessDozeConfig=" + mScreenBrightnessDozeConfig);
Jeff Brown96307042012-07-27 15:51:34 -07001092 pw.println(" mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig);
Jeff Brown1bfd0f42014-08-22 01:59:06 -07001093 pw.println(" mScreenBrightnessDarkConfig=" + mScreenBrightnessDarkConfig);
Jeff Brownb76eebff2012-10-05 22:26:44 -07001094 pw.println(" mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum);
1095 pw.println(" mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum);
Jeff Brown2175e9c2014-09-12 16:11:07 -07001096 pw.println(" mUseSoftwareAutoBrightnessConfig=" + mUseSoftwareAutoBrightnessConfig);
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -07001097 pw.println(" mAllowAutoBrightnessWhileDozingConfig=" +
1098 mAllowAutoBrightnessWhileDozingConfig);
Jeff Brown2175e9c2014-09-12 16:11:07 -07001099 pw.println(" mColorFadeFadesConfig=" + mColorFadeFadesConfig);
Jeff Brown96307042012-07-27 15:51:34 -07001100
Jeff Brownbd6e1502012-08-28 03:27:37 -07001101 mHandler.runWithScissors(new Runnable() {
1102 @Override
1103 public void run() {
1104 dumpLocal(pw);
Jeff Brown96307042012-07-27 15:51:34 -07001105 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001106 }, 1000);
Jeff Brown96307042012-07-27 15:51:34 -07001107 }
1108
1109 private void dumpLocal(PrintWriter pw) {
1110 pw.println();
Jeff Brown131206b2014-04-08 17:27:14 -07001111 pw.println("Display Power Controller Thread State:");
Jeff Brown96307042012-07-27 15:51:34 -07001112 pw.println(" mPowerRequest=" + mPowerRequest);
1113 pw.println(" mWaitingForNegativeProximity=" + mWaitingForNegativeProximity);
1114
1115 pw.println(" mProximitySensor=" + mProximitySensor);
1116 pw.println(" mProximitySensorEnabled=" + mProximitySensorEnabled);
1117 pw.println(" mProximityThreshold=" + mProximityThreshold);
1118 pw.println(" mProximity=" + proximityToString(mProximity));
1119 pw.println(" mPendingProximity=" + proximityToString(mPendingProximity));
1120 pw.println(" mPendingProximityDebounceTime="
1121 + TimeUtils.formatUptime(mPendingProximityDebounceTime));
1122 pw.println(" mScreenOffBecauseOfProximity=" + mScreenOffBecauseOfProximity);
Jeff Brown970d4132014-07-19 11:33:47 -07001123 pw.println(" mAppliedAutoBrightness=" + mAppliedAutoBrightness);
1124 pw.println(" mAppliedDimming=" + mAppliedDimming);
1125 pw.println(" mAppliedLowPower=" + mAppliedLowPower);
Jeff Brown3ee549c2014-09-22 20:14:39 -07001126 pw.println(" mPendingScreenOnUnblocker=" + mPendingScreenOnUnblocker);
1127 pw.println(" mPendingScreenOff=" + mPendingScreenOff);
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001128 pw.println(" mReportedToPolicy=" + reportedToPolicyToString(mReportedScreenStateToPolicy));
Jeff Brown96307042012-07-27 15:51:34 -07001129
Jeff Brown42558692014-05-20 22:02:46 -07001130 pw.println(" mScreenBrightnessRampAnimator.isAnimating()=" +
1131 mScreenBrightnessRampAnimator.isAnimating());
1132
Michael Lentine0839adb2014-07-29 18:47:56 -07001133 if (mColorFadeOnAnimator != null) {
1134 pw.println(" mColorFadeOnAnimator.isStarted()=" +
1135 mColorFadeOnAnimator.isStarted());
Jeff Brown96307042012-07-27 15:51:34 -07001136 }
Michael Lentine0839adb2014-07-29 18:47:56 -07001137 if (mColorFadeOffAnimator != null) {
1138 pw.println(" mColorFadeOffAnimator.isStarted()=" +
1139 mColorFadeOffAnimator.isStarted());
Jeff Brown96307042012-07-27 15:51:34 -07001140 }
1141
1142 if (mPowerState != null) {
1143 mPowerState.dump(pw);
1144 }
Michael Wright639c8be2014-01-17 18:29:12 -08001145
1146 if (mAutomaticBrightnessController != null) {
1147 mAutomaticBrightnessController.dump(pw);
1148 }
1149
Jeff Brown96307042012-07-27 15:51:34 -07001150 }
1151
1152 private static String proximityToString(int state) {
1153 switch (state) {
1154 case PROXIMITY_UNKNOWN:
1155 return "Unknown";
1156 case PROXIMITY_NEGATIVE:
1157 return "Negative";
1158 case PROXIMITY_POSITIVE:
1159 return "Positive";
1160 default:
1161 return Integer.toString(state);
1162 }
1163 }
1164
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001165 private static String reportedToPolicyToString(int state) {
1166 switch (state) {
1167 case REPORTED_TO_POLICY_SCREEN_OFF:
1168 return "REPORTED_TO_POLICY_SCREEN_OFF";
1169 case REPORTED_TO_POLICY_SCREEN_TURNING_ON:
1170 return "REPORTED_TO_POLICY_SCREEN_TURNING_ON";
1171 case REPORTED_TO_POLICY_SCREEN_ON:
1172 return "REPORTED_TO_POLICY_SCREEN_ON";
1173 default:
1174 return Integer.toString(state);
1175 }
1176 }
1177
Michael Wright639c8be2014-01-17 18:29:12 -08001178 private static Spline createAutoBrightnessSpline(int[] lux, int[] brightness) {
1179 try {
1180 final int n = brightness.length;
1181 float[] x = new float[n];
1182 float[] y = new float[n];
1183 y[0] = normalizeAbsoluteBrightness(brightness[0]);
1184 for (int i = 1; i < n; i++) {
1185 x[i] = lux[i - 1];
1186 y[i] = normalizeAbsoluteBrightness(brightness[i]);
1187 }
1188
Michael Wright3e9a1342014-08-28 17:42:16 -07001189 Spline spline = Spline.createSpline(x, y);
Michael Wright639c8be2014-01-17 18:29:12 -08001190 if (DEBUG) {
1191 Slog.d(TAG, "Auto-brightness spline: " + spline);
1192 for (float v = 1f; v < lux[lux.length - 1] * 1.25f; v *= 1.25f) {
1193 Slog.d(TAG, String.format(" %7.1f: %7.1f", v, spline.interpolate(v)));
1194 }
1195 }
1196 return spline;
1197 } catch (IllegalArgumentException ex) {
1198 Slog.e(TAG, "Could not create auto-brightness spline.", ex);
1199 return null;
Jeff Brown96307042012-07-27 15:51:34 -07001200 }
Michael Wright639c8be2014-01-17 18:29:12 -08001201 }
1202
1203 private static float normalizeAbsoluteBrightness(int value) {
1204 return (float)clampAbsoluteBrightness(value) / PowerManager.BRIGHTNESS_ON;
1205 }
1206
1207 private static int clampAbsoluteBrightness(int value) {
1208 return MathUtils.constrain(value, PowerManager.BRIGHTNESS_OFF, PowerManager.BRIGHTNESS_ON);
Jeff Brown96307042012-07-27 15:51:34 -07001209 }
1210
Jeff Brown96307042012-07-27 15:51:34 -07001211 private final class DisplayControllerHandler extends Handler {
1212 public DisplayControllerHandler(Looper looper) {
Jeff Browna2910d02012-08-25 12:29:46 -07001213 super(looper, null, true /*async*/);
Jeff Brown96307042012-07-27 15:51:34 -07001214 }
1215
1216 @Override
1217 public void handleMessage(Message msg) {
1218 switch (msg.what) {
1219 case MSG_UPDATE_POWER_STATE:
1220 updatePowerState();
1221 break;
1222
1223 case MSG_PROXIMITY_SENSOR_DEBOUNCED:
1224 debounceProximitySensor();
1225 break;
Jeff Brown3ee549c2014-09-22 20:14:39 -07001226
1227 case MSG_SCREEN_ON_UNBLOCKED:
1228 if (mPendingScreenOnUnblocker == msg.obj) {
1229 unblockScreenOn();
1230 updatePowerState();
1231 }
1232 break;
Jeff Brown96307042012-07-27 15:51:34 -07001233 }
1234 }
1235 }
1236
1237 private final SensorEventListener mProximitySensorListener = new SensorEventListener() {
1238 @Override
1239 public void onSensorChanged(SensorEvent event) {
1240 if (mProximitySensorEnabled) {
1241 final long time = SystemClock.uptimeMillis();
1242 final float distance = event.values[0];
1243 boolean positive = distance >= 0.0f && distance < mProximityThreshold;
1244 handleProximitySensorEvent(time, positive);
1245 }
1246 }
1247
1248 @Override
1249 public void onAccuracyChanged(Sensor sensor, int accuracy) {
1250 // Not used.
1251 }
1252 };
Jeff Brown3ee549c2014-09-22 20:14:39 -07001253
1254 private final class ScreenOnUnblocker implements WindowManagerPolicy.ScreenOnListener {
1255 @Override
1256 public void onScreenOn() {
1257 Message msg = mHandler.obtainMessage(MSG_SCREEN_ON_UNBLOCKED, this);
1258 msg.setAsynchronous(true);
1259 mHandler.sendMessage(msg);
1260 }
1261 }
Jeff Brown96307042012-07-27 15:51:34 -07001262}