blob: bed269cf6c4f2008b25369f9435c27d346222818 [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
Julius D'souza428aed02016-08-07 19:08:30 -070075 private static final 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
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700105 private static final int REPORTED_TO_POLICY_SCREEN_OFF = 0;
106 private static final int REPORTED_TO_POLICY_SCREEN_TURNING_ON = 1;
107 private static final int REPORTED_TO_POLICY_SCREEN_ON = 2;
108
Jeff Brown96307042012-07-27 15:51:34 -0700109 private final Object mLock = new Object();
110
Michael Lentine0839adb2014-07-29 18:47:56 -0700111 private final Context mContext;
112
Jeff Brown96307042012-07-27 15:51:34 -0700113 // Our handler.
114 private final DisplayControllerHandler mHandler;
115
116 // Asynchronous callbacks into the power manager service.
117 // Only invoked from the handler thread while no locks are held.
Jeff Brown131206b2014-04-08 17:27:14 -0700118 private final DisplayPowerCallbacks mCallbacks;
119
120 // Battery stats.
121 private final IBatteryStats mBatteryStats;
Jeff Brown96307042012-07-27 15:51:34 -0700122
Jeff Brown96307042012-07-27 15:51:34 -0700123 // The sensor manager.
124 private final SensorManager mSensorManager;
125
Jeff Brown3ee549c2014-09-22 20:14:39 -0700126 // The window manager policy.
127 private final WindowManagerPolicy mWindowManagerPolicy;
128
Jeff Brown037c33e2014-04-09 00:31:55 -0700129 // The display blanker.
130 private final DisplayBlanker mBlanker;
131
Jeff Brown96307042012-07-27 15:51:34 -0700132 // The proximity sensor, or null if not available or needed.
133 private Sensor mProximitySensor;
134
Jeff Brown26875502014-01-30 21:47:47 -0800135 // The doze screen brightness.
136 private final int mScreenBrightnessDozeConfig;
137
Jeff Brown96307042012-07-27 15:51:34 -0700138 // The dim screen brightness.
139 private final int mScreenBrightnessDimConfig;
140
Jeff Brown1bfd0f42014-08-22 01:59:06 -0700141 // The minimum screen brightness to use in a very dark room.
142 private final int mScreenBrightnessDarkConfig;
143
Jeff Brownb76eebff2012-10-05 22:26:44 -0700144 // The minimum allowed brightness.
145 private final int mScreenBrightnessRangeMinimum;
146
147 // The maximum allowed brightness.
148 private final int mScreenBrightnessRangeMaximum;
149
Jeff Brown330560f2012-08-21 22:10:57 -0700150 // True if auto-brightness should be used.
Jeff Brown96307042012-07-27 15:51:34 -0700151 private boolean mUseSoftwareAutoBrightnessConfig;
Jeff Brown330560f2012-08-21 22:10:57 -0700152
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700153 // True if should use light sensor to automatically determine doze screen brightness.
154 private final boolean mAllowAutoBrightnessWhileDozingConfig;
155
Jeff Brown252c2062012-10-08 16:21:01 -0700156 // True if we should fade the screen while turning it off, false if we should play
Jeff Brown3ee549c2014-09-22 20:14:39 -0700157 // a stylish color fade animation instead.
Michael Lentine0839adb2014-07-29 18:47:56 -0700158 private boolean mColorFadeFadesConfig;
Jeff Browna52772f2012-10-04 18:38:09 -0700159
Jeff Brown96307042012-07-27 15:51:34 -0700160 // The pending power request.
161 // Initially null until the first call to requestPowerState.
162 // Guarded by mLock.
163 private DisplayPowerRequest mPendingRequestLocked;
164
165 // True if a request has been made to wait for the proximity sensor to go negative.
166 // Guarded by mLock.
167 private boolean mPendingWaitForNegativeProximityLocked;
168
169 // True if the pending power request or wait for negative proximity flag
170 // has been changed since the last update occurred.
171 // Guarded by mLock.
172 private boolean mPendingRequestChangedLocked;
173
174 // Set to true when the important parts of the pending power request have been applied.
175 // The important parts are mainly the screen state. Brightness changes may occur
176 // concurrently.
177 // Guarded by mLock.
178 private boolean mDisplayReadyLocked;
179
180 // Set to true if a power state update is required.
181 // Guarded by mLock.
182 private boolean mPendingUpdatePowerStateLocked;
183
184 /* The following state must only be accessed by the handler thread. */
185
186 // The currently requested power state.
187 // The power controller will progressively update its internal state to match
188 // the requested power state. Initially null until the first update.
189 private DisplayPowerRequest mPowerRequest;
190
191 // The current power state.
192 // Must only be accessed on the handler thread.
193 private DisplayPowerState mPowerState;
194
195 // True if the device should wait for negative proximity sensor before
196 // waking up the screen. This is set to false as soon as a negative
197 // proximity sensor measurement is observed or when the device is forced to
198 // go to sleep by the user. While true, the screen remains off.
199 private boolean mWaitingForNegativeProximity;
200
201 // The actual proximity sensor threshold value.
202 private float mProximityThreshold;
203
204 // Set to true if the proximity sensor listener has been registered
205 // with the sensor manager.
206 private boolean mProximitySensorEnabled;
207
208 // The debounced proximity sensor state.
209 private int mProximity = PROXIMITY_UNKNOWN;
210
211 // The raw non-debounced proximity sensor state.
212 private int mPendingProximity = PROXIMITY_UNKNOWN;
Jeff Brownec083212013-09-11 20:45:25 -0700213 private long mPendingProximityDebounceTime = -1; // -1 if fully debounced
Jeff Brown96307042012-07-27 15:51:34 -0700214
215 // True if the screen was turned off because of the proximity sensor.
216 // When the screen turns on again, we report user activity to the power manager.
217 private boolean mScreenOffBecauseOfProximity;
218
Jeff Brown3ee549c2014-09-22 20:14:39 -0700219 // The currently active screen on unblocker. This field is non-null whenever
220 // we are waiting for a callback to release it and unblock the screen.
221 private ScreenOnUnblocker mPendingScreenOnUnblocker;
222
223 // True if we were in the process of turning off the screen.
224 // This allows us to recover more gracefully from situations where we abort
225 // turning off the screen.
226 private boolean mPendingScreenOff;
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700227
Jeff Brown0a434772014-09-30 14:42:27 -0700228 // True if we have unfinished business and are holding a suspend blocker.
229 private boolean mUnfinishedBusiness;
230
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700231 // The elapsed real time when the screen on was blocked.
232 private long mScreenOnBlockStartRealTime;
233
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700234 // Screen state we reported to policy. Must be one of REPORTED_TO_POLICY_SCREEN_* fields.
235 private int mReportedScreenStateToPolicy;
Jeff Browne1633ad2015-06-22 19:24:24 -0700236
Jeff Brown970d4132014-07-19 11:33:47 -0700237 // Remembers whether certain kinds of brightness adjustments
238 // were recently applied so that we can decide how to transition.
239 private boolean mAppliedAutoBrightness;
240 private boolean mAppliedDimming;
241 private boolean mAppliedLowPower;
Jeff Brown96307042012-07-27 15:51:34 -0700242
Julius D'souzafeadad12016-08-05 14:34:38 -0700243 // Brightness animation ramp rates in brightness units per second
Prashant Malani99e6d432016-03-29 16:32:37 -0700244 private final int mBrightnessRampRateFast;
Julius D'souzafeadad12016-08-05 14:34:38 -0700245 private final int mBrightnessRampRateSlow;
Prashant Malani99e6d432016-03-29 16:32:37 -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 }
liulvpingd01db542016-10-20 19:51:38 +0800287 if (mScreenBrightnessDarkConfig > screenBrightnessSettingMinimum) {
Jeff Brown1bfd0f42014-08-22 01:59:06 -0700288 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
Prashant Malani99e6d432016-03-29 16:32:37 -0700306 mBrightnessRampRateFast = resources.getInteger(
307 com.android.internal.R.integer.config_brightness_ramp_rate_fast);
Julius D'souzafeadad12016-08-05 14:34:38 -0700308 mBrightnessRampRateSlow = resources.getInteger(
309 com.android.internal.R.integer.config_brightness_ramp_rate_slow);
Prashant Malani99e6d432016-03-29 16:32:37 -0700310
Filip Gruszczynskid81ecd12015-02-06 12:38:47 -0800311 int lightSensorRate = resources.getInteger(
312 com.android.internal.R.integer.config_autoBrightnessLightSensorRate);
Julius D'souza5d717092016-10-24 19:26:45 -0700313 int initialLightSensorRate = resources.getInteger(
314 com.android.internal.R.integer.config_autoBrightnessInitialLightSensorRate);
315 if (initialLightSensorRate == -1) {
316 initialLightSensorRate = lightSensorRate;
317 } else if (initialLightSensorRate > lightSensorRate) {
318 Slog.w(TAG, "Expected config_autoBrightnessInitialLightSensorRate ("
319 + initialLightSensorRate + ") to be less than or equal to "
320 + "config_autoBrightnessLightSensorRate (" + lightSensorRate + ").");
321 }
Filip Gruszczynskid81ecd12015-02-06 12:38:47 -0800322 long brighteningLightDebounce = resources.getInteger(
323 com.android.internal.R.integer.config_autoBrightnessBrighteningLightDebounce);
324 long darkeningLightDebounce = resources.getInteger(
325 com.android.internal.R.integer.config_autoBrightnessDarkeningLightDebounce);
326 boolean autoBrightnessResetAmbientLuxAfterWarmUp = resources.getBoolean(
327 com.android.internal.R.bool.config_autoBrightnessResetAmbientLuxAfterWarmUp);
Zoran Jovanovic6fc42f52015-12-10 17:01:16 +0100328 int ambientLightHorizon = resources.getInteger(
329 com.android.internal.R.integer.config_autoBrightnessAmbientLightHorizon);
330 float autoBrightnessAdjustmentMaxGamma = resources.getFraction(
331 com.android.internal.R.fraction.config_autoBrightnessAdjustmentMaxGamma,
332 1, 1);
Filip Gruszczynskid81ecd12015-02-06 12:38:47 -0800333
Julius D'souza428aed02016-08-07 19:08:30 -0700334 int[] brightLevels = resources.getIntArray(
335 com.android.internal.R.array.config_dynamicHysteresisBrightLevels);
336 int[] darkLevels = resources.getIntArray(
337 com.android.internal.R.array.config_dynamicHysteresisDarkLevels);
338 int[] luxLevels = resources.getIntArray(
339 com.android.internal.R.array.config_dynamicHysteresisLuxLevels);
340 HysteresisLevels dynamicHysteresis = new HysteresisLevels(
341 brightLevels, darkLevels, luxLevels);
342
Jeff Brown96307042012-07-27 15:51:34 -0700343 if (mUseSoftwareAutoBrightnessConfig) {
Jeff Brown1a30b552012-08-16 01:31:11 -0700344 int[] lux = resources.getIntArray(
Jeff Brown96307042012-07-27 15:51:34 -0700345 com.android.internal.R.array.config_autoBrightnessLevels);
Jeff Brown1a30b552012-08-16 01:31:11 -0700346 int[] screenBrightness = resources.getIntArray(
Jeff Brown96307042012-07-27 15:51:34 -0700347 com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
Michael Wright639c8be2014-01-17 18:29:12 -0800348 int lightSensorWarmUpTimeConfig = resources.getInteger(
349 com.android.internal.R.integer.config_lightSensorWarmupTime);
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700350 final float dozeScaleFactor = resources.getFraction(
351 com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor,
352 1, 1);
Jeff Brown1a30b552012-08-16 01:31:11 -0700353
Michael Wright639c8be2014-01-17 18:29:12 -0800354 Spline screenAutoBrightnessSpline = createAutoBrightnessSpline(lux, screenBrightness);
355 if (screenAutoBrightnessSpline == null) {
Jeff Brown96307042012-07-27 15:51:34 -0700356 Slog.e(TAG, "Error in config.xml. config_autoBrightnessLcdBacklightValues "
Jeff Brown1a30b552012-08-16 01:31:11 -0700357 + "(size " + screenBrightness.length + ") "
358 + "must be monotic and have exactly one more entry than "
359 + "config_autoBrightnessLevels (size " + lux.length + ") "
360 + "which must be strictly increasing. "
Jeff Brown96307042012-07-27 15:51:34 -0700361 + "Auto-brightness will be disabled.");
362 mUseSoftwareAutoBrightnessConfig = false;
Jeff Brownb76eebff2012-10-05 22:26:44 -0700363 } else {
Jeff Brown1bfd0f42014-08-22 01:59:06 -0700364 int bottom = clampAbsoluteBrightness(screenBrightness[0]);
365 if (mScreenBrightnessDarkConfig > bottom) {
366 Slog.w(TAG, "config_screenBrightnessDark (" + mScreenBrightnessDarkConfig
367 + ") should be less than or equal to the first value of "
368 + "config_autoBrightnessLcdBacklightValues ("
369 + bottom + ").");
370 }
371 if (bottom < screenBrightnessRangeMinimum) {
372 screenBrightnessRangeMinimum = bottom;
Jeff Brownb76eebff2012-10-05 22:26:44 -0700373 }
Jeff Brown131206b2014-04-08 17:27:14 -0700374 mAutomaticBrightnessController = new AutomaticBrightnessController(this,
375 handler.getLooper(), sensorManager, screenAutoBrightnessSpline,
Michael Wright639c8be2014-01-17 18:29:12 -0800376 lightSensorWarmUpTimeConfig, screenBrightnessRangeMinimum,
Filip Gruszczynskid81ecd12015-02-06 12:38:47 -0800377 mScreenBrightnessRangeMaximum, dozeScaleFactor, lightSensorRate,
Julius D'souza5d717092016-10-24 19:26:45 -0700378 initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce,
Julius D'souza428aed02016-08-07 19:08:30 -0700379 autoBrightnessResetAmbientLuxAfterWarmUp, ambientLightHorizon,
380 autoBrightnessAdjustmentMaxGamma, dynamicHysteresis);
Jeff Brown96307042012-07-27 15:51:34 -0700381 }
Jeff Brown96307042012-07-27 15:51:34 -0700382 }
383
Michael Wright639c8be2014-01-17 18:29:12 -0800384 mScreenBrightnessRangeMinimum = screenBrightnessRangeMinimum;
Jeff Brownb76eebff2012-10-05 22:26:44 -0700385
Michael Lentine0839adb2014-07-29 18:47:56 -0700386 mColorFadeFadesConfig = resources.getBoolean(
Jeff Browna52772f2012-10-04 18:38:09 -0700387 com.android.internal.R.bool.config_animateScreenLights);
388
Jeff Brown96307042012-07-27 15:51:34 -0700389 if (!DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) {
390 mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
391 if (mProximitySensor != null) {
392 mProximityThreshold = Math.min(mProximitySensor.getMaximumRange(),
393 TYPICAL_PROXIMITY_THRESHOLD);
394 }
395 }
396
Jeff Brown1a30b552012-08-16 01:31:11 -0700397 }
398
Jeff Brown96307042012-07-27 15:51:34 -0700399 /**
400 * Returns true if the proximity sensor screen-off function is available.
401 */
402 public boolean isProximitySensorAvailable() {
403 return mProximitySensor != null;
404 }
405
406 /**
407 * Requests a new power state.
408 * The controller makes a copy of the provided object and then
409 * begins adjusting the power state to match what was requested.
410 *
411 * @param request The requested power state.
412 * @param waitForNegativeProximity If true, issues a request to wait for
413 * negative proximity before turning the screen back on, assuming the screen
414 * was turned off by the proximity sensor.
415 * @return True if display is ready, false if there are important changes that must
416 * be made asynchronously (such as turning the screen on), in which case the caller
Jeff Brown606e4e82014-09-18 15:22:26 -0700417 * should grab a wake lock, watch for {@link DisplayPowerCallbacks#onStateChanged()}
418 * then try the request again later until the state converges.
Jeff Brown96307042012-07-27 15:51:34 -0700419 */
420 public boolean requestPowerState(DisplayPowerRequest request,
421 boolean waitForNegativeProximity) {
422 if (DEBUG) {
423 Slog.d(TAG, "requestPowerState: "
424 + request + ", waitForNegativeProximity=" + waitForNegativeProximity);
425 }
426
427 synchronized (mLock) {
428 boolean changed = false;
429
430 if (waitForNegativeProximity
431 && !mPendingWaitForNegativeProximityLocked) {
432 mPendingWaitForNegativeProximityLocked = true;
433 changed = true;
434 }
435
436 if (mPendingRequestLocked == null) {
437 mPendingRequestLocked = new DisplayPowerRequest(request);
438 changed = true;
439 } else if (!mPendingRequestLocked.equals(request)) {
440 mPendingRequestLocked.copyFrom(request);
441 changed = true;
442 }
443
444 if (changed) {
445 mDisplayReadyLocked = false;
446 }
447
448 if (changed && !mPendingRequestChangedLocked) {
449 mPendingRequestChangedLocked = true;
450 sendUpdatePowerStateLocked();
451 }
452
453 return mDisplayReadyLocked;
454 }
455 }
456
457 private void sendUpdatePowerState() {
458 synchronized (mLock) {
459 sendUpdatePowerStateLocked();
460 }
461 }
462
463 private void sendUpdatePowerStateLocked() {
464 if (!mPendingUpdatePowerStateLocked) {
465 mPendingUpdatePowerStateLocked = true;
466 Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE);
467 msg.setAsynchronous(true);
468 mHandler.sendMessage(msg);
469 }
470 }
471
472 private void initialize() {
Jeff Brown037c33e2014-04-09 00:31:55 -0700473 // Initialize the power state object for the default display.
474 // In the future, we might manage multiple displays independently.
475 mPowerState = new DisplayPowerState(mBlanker,
Michael Lentine0839adb2014-07-29 18:47:56 -0700476 new ColorFade(Display.DEFAULT_DISPLAY));
Jeff Brown96307042012-07-27 15:51:34 -0700477
Michael Lentine0839adb2014-07-29 18:47:56 -0700478 mColorFadeOnAnimator = ObjectAnimator.ofFloat(
479 mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 0.0f, 1.0f);
480 mColorFadeOnAnimator.setDuration(COLOR_FADE_ON_ANIMATION_DURATION_MILLIS);
481 mColorFadeOnAnimator.addListener(mAnimatorListener);
Jeff Brown96307042012-07-27 15:51:34 -0700482
Michael Lentine0839adb2014-07-29 18:47:56 -0700483 mColorFadeOffAnimator = ObjectAnimator.ofFloat(
484 mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 1.0f, 0.0f);
485 mColorFadeOffAnimator.setDuration(COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS);
486 mColorFadeOffAnimator.addListener(mAnimatorListener);
Jeff Brown96307042012-07-27 15:51:34 -0700487
488 mScreenBrightnessRampAnimator = new RampAnimator<DisplayPowerState>(
489 mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS);
Jeff Brown42558692014-05-20 22:02:46 -0700490 mScreenBrightnessRampAnimator.setListener(mRampAnimatorListener);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800491
Jeff Brown131206b2014-04-08 17:27:14 -0700492 // Initialize screen state for battery stats.
493 try {
Jeff Browne95c3cd2014-05-02 16:59:26 -0700494 mBatteryStats.noteScreenState(mPowerState.getScreenState());
Jeff Brown131206b2014-04-08 17:27:14 -0700495 mBatteryStats.noteScreenBrightness(mPowerState.getScreenBrightness());
496 } catch (RemoteException ex) {
497 // same process
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800498 }
Jeff Brown96307042012-07-27 15:51:34 -0700499 }
500
501 private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() {
502 @Override
503 public void onAnimationStart(Animator animation) {
504 }
505 @Override
506 public void onAnimationEnd(Animator animation) {
507 sendUpdatePowerState();
508 }
509 @Override
510 public void onAnimationRepeat(Animator animation) {
511 }
512 @Override
513 public void onAnimationCancel(Animator animation) {
514 }
515 };
516
Jeff Brown42558692014-05-20 22:02:46 -0700517 private final RampAnimator.Listener mRampAnimatorListener = new RampAnimator.Listener() {
518 @Override
519 public void onAnimationEnd() {
520 sendUpdatePowerState();
521 }
522 };
523
Jeff Brown96307042012-07-27 15:51:34 -0700524 private void updatePowerState() {
525 // Update the power state request.
526 final boolean mustNotify;
527 boolean mustInitialize = false;
Adrian Roos6da87ab2014-05-16 23:09:41 +0200528 boolean autoBrightnessAdjustmentChanged = false;
Jeff Brown330560f2012-08-21 22:10:57 -0700529
Jeff Brown96307042012-07-27 15:51:34 -0700530 synchronized (mLock) {
531 mPendingUpdatePowerStateLocked = false;
532 if (mPendingRequestLocked == null) {
533 return; // wait until first actual power request
534 }
535
536 if (mPowerRequest == null) {
537 mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked);
538 mWaitingForNegativeProximity = mPendingWaitForNegativeProximityLocked;
Jeff Brown6307a152012-08-20 13:24:23 -0700539 mPendingWaitForNegativeProximityLocked = false;
Jeff Brown96307042012-07-27 15:51:34 -0700540 mPendingRequestChangedLocked = false;
541 mustInitialize = true;
542 } else if (mPendingRequestChangedLocked) {
Adrian Roos6da87ab2014-05-16 23:09:41 +0200543 autoBrightnessAdjustmentChanged = (mPowerRequest.screenAutoBrightnessAdjustment
544 != mPendingRequestLocked.screenAutoBrightnessAdjustment);
Jeff Brown96307042012-07-27 15:51:34 -0700545 mPowerRequest.copyFrom(mPendingRequestLocked);
546 mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked;
Jeff Brown6307a152012-08-20 13:24:23 -0700547 mPendingWaitForNegativeProximityLocked = false;
Jeff Brown96307042012-07-27 15:51:34 -0700548 mPendingRequestChangedLocked = false;
549 mDisplayReadyLocked = false;
550 }
551
552 mustNotify = !mDisplayReadyLocked;
553 }
554
555 // Initialize things the first time the power state is changed.
556 if (mustInitialize) {
557 initialize();
558 }
559
Jeff Brown970d4132014-07-19 11:33:47 -0700560 // Compute the basic display state using the policy.
561 // We might override this below based on other factors.
562 int state;
563 int brightness = PowerManager.BRIGHTNESS_DEFAULT;
Jeff Brown2175e9c2014-09-12 16:11:07 -0700564 boolean performScreenOffTransition = false;
Jeff Brown970d4132014-07-19 11:33:47 -0700565 switch (mPowerRequest.policy) {
566 case DisplayPowerRequest.POLICY_OFF:
567 state = Display.STATE_OFF;
Jeff Brown2175e9c2014-09-12 16:11:07 -0700568 performScreenOffTransition = true;
Jeff Brown970d4132014-07-19 11:33:47 -0700569 break;
570 case DisplayPowerRequest.POLICY_DOZE:
571 if (mPowerRequest.dozeScreenState != Display.STATE_UNKNOWN) {
572 state = mPowerRequest.dozeScreenState;
573 } else {
574 state = Display.STATE_DOZE;
575 }
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700576 if (!mAllowAutoBrightnessWhileDozingConfig) {
577 brightness = mPowerRequest.dozeScreenBrightness;
578 }
Jeff Brown970d4132014-07-19 11:33:47 -0700579 break;
Santos Cordon3107d292016-09-20 15:50:35 -0700580 case DisplayPowerRequest.POLICY_VR:
581 state = Display.STATE_VR;
582 break;
Jeff Brown970d4132014-07-19 11:33:47 -0700583 case DisplayPowerRequest.POLICY_DIM:
584 case DisplayPowerRequest.POLICY_BRIGHT:
585 default:
586 state = Display.STATE_ON;
587 break;
588 }
Jeff Brown2175e9c2014-09-12 16:11:07 -0700589 assert(state != Display.STATE_UNKNOWN);
Jeff Brown970d4132014-07-19 11:33:47 -0700590
Jeff Brown6307a152012-08-20 13:24:23 -0700591 // Apply the proximity sensor.
Jeff Brown96307042012-07-27 15:51:34 -0700592 if (mProximitySensor != null) {
Jeff Brown970d4132014-07-19 11:33:47 -0700593 if (mPowerRequest.useProximitySensor && state != Display.STATE_OFF) {
Jeff Brown6307a152012-08-20 13:24:23 -0700594 setProximitySensorEnabled(true);
595 if (!mScreenOffBecauseOfProximity
596 && mProximity == PROXIMITY_POSITIVE) {
597 mScreenOffBecauseOfProximity = true;
Jeff Brownec083212013-09-11 20:45:25 -0700598 sendOnProximityPositiveWithWakelock();
Jeff Brown6307a152012-08-20 13:24:23 -0700599 }
600 } else if (mWaitingForNegativeProximity
601 && mScreenOffBecauseOfProximity
602 && mProximity == PROXIMITY_POSITIVE
Jeff Brown970d4132014-07-19 11:33:47 -0700603 && state != Display.STATE_OFF) {
Jeff Brown6307a152012-08-20 13:24:23 -0700604 setProximitySensorEnabled(true);
605 } else {
606 setProximitySensorEnabled(false);
607 mWaitingForNegativeProximity = false;
608 }
609 if (mScreenOffBecauseOfProximity
610 && mProximity != PROXIMITY_POSITIVE) {
Jeff Brown96307042012-07-27 15:51:34 -0700611 mScreenOffBecauseOfProximity = false;
Jeff Brownec083212013-09-11 20:45:25 -0700612 sendOnProximityNegativeWithWakelock();
Jeff Brown96307042012-07-27 15:51:34 -0700613 }
Jeff Brown6307a152012-08-20 13:24:23 -0700614 } else {
615 mWaitingForNegativeProximity = false;
Jeff Brown96307042012-07-27 15:51:34 -0700616 }
Jeff Brown970d4132014-07-19 11:33:47 -0700617 if (mScreenOffBecauseOfProximity) {
618 state = Display.STATE_OFF;
Jeff Brown96307042012-07-27 15:51:34 -0700619 }
620
Jeff Brownbf4e4142014-10-02 13:08:05 -0700621 // Animate the screen state change unless already animating.
622 // The transition may be deferred, so after this point we will use the
623 // actual state instead of the desired one.
Santos Cordon3107d292016-09-20 15:50:35 -0700624 final int oldState = mPowerState.getScreenState();
Jeff Brownbf4e4142014-10-02 13:08:05 -0700625 animateScreenStateChange(state, performScreenOffTransition);
626 state = mPowerState.getScreenState();
627
Jeff Brown970d4132014-07-19 11:33:47 -0700628 // Use zero brightness when screen is off.
629 if (state == Display.STATE_OFF) {
630 brightness = PowerManager.BRIGHTNESS_OFF;
631 }
632
Jeff Brown970d4132014-07-19 11:33:47 -0700633 // Configure auto-brightness.
634 boolean autoBrightnessEnabled = false;
635 if (mAutomaticBrightnessController != null) {
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700636 final boolean autoBrightnessEnabledInDoze = mAllowAutoBrightnessWhileDozingConfig
637 && (state == Display.STATE_DOZE || state == Display.STATE_DOZE_SUSPEND);
Jeff Brown970d4132014-07-19 11:33:47 -0700638 autoBrightnessEnabled = mPowerRequest.useAutoBrightness
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700639 && (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
640 && brightness < 0;
Jeff Browna576b4d2015-04-23 19:58:06 -0700641 final boolean userInitiatedChange = autoBrightnessAdjustmentChanged
642 && mPowerRequest.brightnessSetByUser;
Jeff Brown970d4132014-07-19 11:33:47 -0700643 mAutomaticBrightnessController.configure(autoBrightnessEnabled,
Jeff Browna576b4d2015-04-23 19:58:06 -0700644 mPowerRequest.screenAutoBrightnessAdjustment, state != Display.STATE_ON,
Justin Klaassen5483cea2017-02-02 09:02:35 -0800645 userInitiatedChange);
Jeff Brown970d4132014-07-19 11:33:47 -0700646 }
647
Jeff Brown7b5be5e2014-11-12 18:45:31 -0800648 // Apply brightness boost.
649 // We do this here after configuring auto-brightness so that we don't
650 // disable the light sensor during this temporary state. That way when
651 // boost ends we will be able to resume normal auto-brightness behavior
652 // without any delay.
653 if (mPowerRequest.boostScreenBrightness
654 && brightness != PowerManager.BRIGHTNESS_OFF) {
655 brightness = PowerManager.BRIGHTNESS_ON;
656 }
657
Jeff Brown970d4132014-07-19 11:33:47 -0700658 // Apply auto-brightness.
659 boolean slowChange = false;
660 if (brightness < 0) {
661 if (autoBrightnessEnabled) {
662 brightness = mAutomaticBrightnessController.getAutomaticScreenBrightness();
663 }
664 if (brightness >= 0) {
665 // Use current auto-brightness value and slowly adjust to changes.
666 brightness = clampScreenBrightness(brightness);
667 if (mAppliedAutoBrightness && !autoBrightnessAdjustmentChanged) {
668 slowChange = true; // slowly adapt to auto-brightness
669 }
670 mAppliedAutoBrightness = true;
Jeff Brown96307042012-07-27 15:51:34 -0700671 } else {
Jeff Brown970d4132014-07-19 11:33:47 -0700672 mAppliedAutoBrightness = false;
Jeff Brown96307042012-07-27 15:51:34 -0700673 }
674 } else {
Jeff Brown970d4132014-07-19 11:33:47 -0700675 mAppliedAutoBrightness = false;
676 }
677
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700678 // Use default brightness when dozing unless overridden.
679 if (brightness < 0 && (state == Display.STATE_DOZE
680 || state == Display.STATE_DOZE_SUSPEND)) {
681 brightness = mScreenBrightnessDozeConfig;
682 }
683
Jeff Brown970d4132014-07-19 11:33:47 -0700684 // Apply manual brightness.
685 // Use the current brightness setting from the request, which is expected
686 // provide a nominal default value for the case where auto-brightness
687 // is not ready yet.
688 if (brightness < 0) {
689 brightness = clampScreenBrightness(mPowerRequest.screenBrightness);
690 }
691
692 // Apply dimming by at least some minimum amount when user activity
693 // timeout is about to expire.
694 if (mPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
Jeff Brown5c8ea082014-07-24 19:30:31 -0700695 if (brightness > mScreenBrightnessRangeMinimum) {
696 brightness = Math.max(Math.min(brightness - SCREEN_DIM_MINIMUM_REDUCTION,
697 mScreenBrightnessDimConfig), mScreenBrightnessRangeMinimum);
698 }
Jeff Brown970d4132014-07-19 11:33:47 -0700699 if (!mAppliedDimming) {
700 slowChange = false;
701 }
702 mAppliedDimming = true;
mochangmingf0cb46c2015-12-29 13:55:24 +0800703 } else if (mAppliedDimming) {
704 slowChange = false;
705 mAppliedDimming = false;
Jeff Brown970d4132014-07-19 11:33:47 -0700706 }
707
708 // If low power mode is enabled, cut the brightness level by half
709 // as long as it is above the minimum threshold.
710 if (mPowerRequest.lowPowerMode) {
711 if (brightness > mScreenBrightnessRangeMinimum) {
712 brightness = Math.max(brightness / 2, mScreenBrightnessRangeMinimum);
713 }
714 if (!mAppliedLowPower) {
715 slowChange = false;
716 }
717 mAppliedLowPower = true;
mochangmingf0cb46c2015-12-29 13:55:24 +0800718 } else if (mAppliedLowPower) {
719 slowChange = false;
720 mAppliedLowPower = false;
Jeff Brown970d4132014-07-19 11:33:47 -0700721 }
722
Jeff Brown0a434772014-09-30 14:42:27 -0700723 // Animate the screen brightness when the screen is on or dozing.
Santos Cordon3107d292016-09-20 15:50:35 -0700724 // Skip the animation when the screen is off or suspended or transition to/from VR.
Prashant Malani33538242014-11-13 14:04:00 -0800725 if (!mPendingScreenOff) {
Santos Cordon3107d292016-09-20 15:50:35 -0700726 boolean wasOrWillBeInVr = (state == Display.STATE_VR || oldState == Display.STATE_VR);
727 if ((state == Display.STATE_ON || state == Display.STATE_DOZE) && !wasOrWillBeInVr) {
Prashant Malani33538242014-11-13 14:04:00 -0800728 animateScreenBrightness(brightness,
Julius D'souzafeadad12016-08-05 14:34:38 -0700729 slowChange ? mBrightnessRampRateSlow : mBrightnessRampRateFast);
Prashant Malani33538242014-11-13 14:04:00 -0800730 } else {
731 animateScreenBrightness(brightness, 0);
732 }
Jeff Brown0a434772014-09-30 14:42:27 -0700733 }
734
735 // Determine whether the display is ready for use in the newly requested state.
736 // Note that we do not wait for the brightness ramp animation to complete before
737 // reporting the display is ready because we only need to ensure the screen is in the
738 // right power state even as it continues to converge on the desired brightness.
739 final boolean ready = mPendingScreenOnUnblocker == null
Michael Lentine0839adb2014-07-29 18:47:56 -0700740 && !mColorFadeOnAnimator.isStarted()
741 && !mColorFadeOffAnimator.isStarted()
Jeff Brown0a434772014-09-30 14:42:27 -0700742 && mPowerState.waitUntilClean(mCleanListener);
743 final boolean finished = ready
744 && !mScreenBrightnessRampAnimator.isAnimating();
745
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700746 // Notify policy about screen turned on.
747 if (ready && state != Display.STATE_OFF
748 && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_ON) {
749 mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_ON;
750 mWindowManagerPolicy.screenTurnedOn();
751 }
752
Jeff Brown0a434772014-09-30 14:42:27 -0700753 // Grab a wake lock if we have unfinished business.
754 if (!finished && !mUnfinishedBusiness) {
755 if (DEBUG) {
756 Slog.d(TAG, "Unfinished business...");
757 }
758 mCallbacks.acquireSuspendBlocker();
759 mUnfinishedBusiness = true;
760 }
761
762 // Notify the power manager when ready.
763 if (ready && mustNotify) {
764 // Send state change.
Jeff Brown96307042012-07-27 15:51:34 -0700765 synchronized (mLock) {
766 if (!mPendingRequestChangedLocked) {
767 mDisplayReadyLocked = true;
Jeff Brownc38c9be2012-10-04 13:16:19 -0700768
769 if (DEBUG) {
770 Slog.d(TAG, "Display ready!");
771 }
Jeff Brown96307042012-07-27 15:51:34 -0700772 }
773 }
Jeff Brownec083212013-09-11 20:45:25 -0700774 sendOnStateChangedWithWakelock();
Jeff Brown96307042012-07-27 15:51:34 -0700775 }
Jeff Brown0a434772014-09-30 14:42:27 -0700776
777 // Release the wake lock when we have no unfinished business.
778 if (finished && mUnfinishedBusiness) {
779 if (DEBUG) {
780 Slog.d(TAG, "Finished business...");
781 }
782 mUnfinishedBusiness = false;
783 mCallbacks.releaseSuspendBlocker();
784 }
Jeff Brown96307042012-07-27 15:51:34 -0700785 }
786
Michael Wright639c8be2014-01-17 18:29:12 -0800787 @Override
788 public void updateBrightness() {
789 sendUpdatePowerState();
790 }
791
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700792 private void blockScreenOn() {
Jeff Brown3ee549c2014-09-22 20:14:39 -0700793 if (mPendingScreenOnUnblocker == null) {
Jeff Brown3edf5272014-08-14 19:25:14 -0700794 Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0);
Jeff Brown3ee549c2014-09-22 20:14:39 -0700795 mPendingScreenOnUnblocker = new ScreenOnUnblocker();
Jeff Brown037c33e2014-04-09 00:31:55 -0700796 mScreenOnBlockStartRealTime = SystemClock.elapsedRealtime();
Jeff Brown3edf5272014-08-14 19:25:14 -0700797 Slog.i(TAG, "Blocking screen on until initial contents have been drawn.");
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700798 }
799 }
800
801 private void unblockScreenOn() {
Jeff Brown3ee549c2014-09-22 20:14:39 -0700802 if (mPendingScreenOnUnblocker != null) {
803 mPendingScreenOnUnblocker = null;
Jeff Brown2d8a3902014-03-11 23:02:35 -0700804 long delay = SystemClock.elapsedRealtime() - mScreenOnBlockStartRealTime;
Jeff Brown3edf5272014-08-14 19:25:14 -0700805 Slog.i(TAG, "Unblocked screen on after " + delay + " ms");
806 Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0);
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700807 }
808 }
809
Jeff Brown3ee549c2014-09-22 20:14:39 -0700810 private boolean setScreenState(int state) {
Jeff Brown037c33e2014-04-09 00:31:55 -0700811 if (mPowerState.getScreenState() != state) {
Jeff Brown3ee549c2014-09-22 20:14:39 -0700812 final boolean wasOn = (mPowerState.getScreenState() != Display.STATE_OFF);
Jeff Brown037c33e2014-04-09 00:31:55 -0700813 mPowerState.setScreenState(state);
Jeff Brown3ee549c2014-09-22 20:14:39 -0700814
815 // Tell battery stats about the transition.
Jeff Brown131206b2014-04-08 17:27:14 -0700816 try {
Jeff Browne95c3cd2014-05-02 16:59:26 -0700817 mBatteryStats.noteScreenState(state);
Jeff Brown131206b2014-04-08 17:27:14 -0700818 } catch (RemoteException ex) {
819 // same process
Jeff Brown96307042012-07-27 15:51:34 -0700820 }
821 }
Jeff Browne1633ad2015-06-22 19:24:24 -0700822
823 // Tell the window manager policy when the screen is turned off or on unless it's due
824 // to the proximity sensor. We temporarily block turning the screen on until the
825 // window manager is ready by leaving a black surface covering the screen.
826 // This surface is essentially the final state of the color fade animation and
827 // it is only removed once the window manager tells us that the activity has
828 // finished drawing underneath.
829 final boolean isOff = (state == Display.STATE_OFF);
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700830 if (isOff && mReportedScreenStateToPolicy != REPORTED_TO_POLICY_SCREEN_OFF
831 && !mScreenOffBecauseOfProximity) {
832 mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_OFF;
Jeff Browne1633ad2015-06-22 19:24:24 -0700833 unblockScreenOn();
834 mWindowManagerPolicy.screenTurnedOff();
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700835 } else if (!isOff && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF) {
836 mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_TURNING_ON;
Jeff Browne1633ad2015-06-22 19:24:24 -0700837 if (mPowerState.getColorFadeLevel() == 0.0f) {
838 blockScreenOn();
839 } else {
840 unblockScreenOn();
841 }
842 mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker);
843 }
844
845 // Return true if the screen isn't blocked.
Jeff Brown3ee549c2014-09-22 20:14:39 -0700846 return mPendingScreenOnUnblocker == null;
Jeff Brown96307042012-07-27 15:51:34 -0700847 }
848
Jeff Brown330560f2012-08-21 22:10:57 -0700849 private int clampScreenBrightness(int value) {
Michael Wright639c8be2014-01-17 18:29:12 -0800850 return MathUtils.constrain(
851 value, mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum);
Jeff Brown330560f2012-08-21 22:10:57 -0700852 }
853
Jeff Brown96307042012-07-27 15:51:34 -0700854 private void animateScreenBrightness(int target, int rate) {
Jeff Brown0a434772014-09-30 14:42:27 -0700855 if (DEBUG) {
856 Slog.d(TAG, "Animating brightness: target=" + target +", rate=" + rate);
857 }
Jeff Brown96307042012-07-27 15:51:34 -0700858 if (mScreenBrightnessRampAnimator.animateTo(target, rate)) {
Jeff Brown131206b2014-04-08 17:27:14 -0700859 try {
860 mBatteryStats.noteScreenBrightness(target);
861 } catch (RemoteException ex) {
862 // same process
863 }
Jeff Brown96307042012-07-27 15:51:34 -0700864 }
865 }
866
Jeff Brown606e4e82014-09-18 15:22:26 -0700867 private void animateScreenStateChange(int target, boolean performScreenOffTransition) {
868 // If there is already an animation in progress, don't interfere with it.
869 if (mColorFadeOnAnimator.isStarted()
870 || mColorFadeOffAnimator.isStarted()) {
Chong Zhangb131c702016-02-16 16:31:48 -0800871 if (target != Display.STATE_ON) {
872 return;
873 }
874 // If display state changed to on, proceed and stop the color fade and turn screen on.
875 mPendingScreenOff = false;
Jeff Brown606e4e82014-09-18 15:22:26 -0700876 }
877
Jeff Brown3ee549c2014-09-22 20:14:39 -0700878 // If we were in the process of turning off the screen but didn't quite
879 // finish. Then finish up now to prevent a jarring transition back
880 // to screen on if we skipped blocking screen on as usual.
881 if (mPendingScreenOff && target != Display.STATE_OFF) {
882 setScreenState(Display.STATE_OFF);
883 mPendingScreenOff = false;
Michael Lentined73854d2015-09-25 10:55:26 -0700884 mPowerState.dismissColorFadeResources();
Jeff Brown606e4e82014-09-18 15:22:26 -0700885 }
886
887 if (target == Display.STATE_ON) {
888 // Want screen on. The contents of the screen may not yet
Jeff Brown3ee549c2014-09-22 20:14:39 -0700889 // be visible if the color fade has not been dismissed because
Jeff Brown606e4e82014-09-18 15:22:26 -0700890 // its last frame of animation is solid black.
Jeff Brown3ee549c2014-09-22 20:14:39 -0700891 if (!setScreenState(Display.STATE_ON)) {
892 return; // screen on blocked
893 }
Jeff Brown606e4e82014-09-18 15:22:26 -0700894 if (USE_COLOR_FADE_ON_ANIMATION && mPowerRequest.isBrightOrDim()) {
895 // Perform screen on animation.
896 if (mPowerState.getColorFadeLevel() == 1.0f) {
897 mPowerState.dismissColorFade();
898 } else if (mPowerState.prepareColorFade(mContext,
899 mColorFadeFadesConfig ?
900 ColorFade.MODE_FADE :
901 ColorFade.MODE_WARM_UP)) {
902 mColorFadeOnAnimator.start();
903 } else {
904 mColorFadeOnAnimator.end();
905 }
906 } else {
907 // Skip screen on animation.
908 mPowerState.setColorFadeLevel(1.0f);
909 mPowerState.dismissColorFade();
910 }
Santos Cordon3107d292016-09-20 15:50:35 -0700911 } else if (target == Display.STATE_VR) {
912 // Wait for brightness animation to complete beforehand when entering VR
913 // from screen on to prevent a perceptible jump because brightness may operate
914 // differently when the display is configured for dozing.
915 if (mScreenBrightnessRampAnimator.isAnimating()
916 && mPowerState.getScreenState() == Display.STATE_ON) {
917 return;
918 }
919
920 // Set screen state.
921 if (!setScreenState(Display.STATE_VR)) {
922 return; // screen on blocked
923 }
924
925 // Dismiss the black surface without fanfare.
926 mPowerState.setColorFadeLevel(1.0f);
927 mPowerState.dismissColorFade();
Jeff Brown606e4e82014-09-18 15:22:26 -0700928 } else if (target == Display.STATE_DOZE) {
929 // Want screen dozing.
930 // Wait for brightness animation to complete beforehand when entering doze
931 // from screen on to prevent a perceptible jump because brightness may operate
932 // differently when the display is configured for dozing.
933 if (mScreenBrightnessRampAnimator.isAnimating()
934 && mPowerState.getScreenState() == Display.STATE_ON) {
935 return;
936 }
937
Jeff Brown3ee549c2014-09-22 20:14:39 -0700938 // Set screen state.
939 if (!setScreenState(Display.STATE_DOZE)) {
940 return; // screen on blocked
941 }
942
943 // Dismiss the black surface without fanfare.
Jeff Brown606e4e82014-09-18 15:22:26 -0700944 mPowerState.setColorFadeLevel(1.0f);
945 mPowerState.dismissColorFade();
946 } else if (target == Display.STATE_DOZE_SUSPEND) {
947 // Want screen dozing and suspended.
948 // Wait for brightness animation to complete beforehand unless already
949 // suspended because we may not be able to change it after suspension.
950 if (mScreenBrightnessRampAnimator.isAnimating()
951 && mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) {
952 return;
953 }
954
Jeff Brown3ee549c2014-09-22 20:14:39 -0700955 // If not already suspending, temporarily set the state to doze until the
956 // screen on is unblocked, then suspend.
957 if (mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) {
958 if (!setScreenState(Display.STATE_DOZE)) {
959 return; // screen on blocked
960 }
961 setScreenState(Display.STATE_DOZE_SUSPEND); // already on so can't block
962 }
963
964 // Dismiss the black surface without fanfare.
Jeff Brown606e4e82014-09-18 15:22:26 -0700965 mPowerState.setColorFadeLevel(1.0f);
966 mPowerState.dismissColorFade();
967 } else {
968 // Want screen off.
Jeff Brown3ee549c2014-09-22 20:14:39 -0700969 mPendingScreenOff = true;
Jeff Brown606e4e82014-09-18 15:22:26 -0700970 if (mPowerState.getColorFadeLevel() == 0.0f) {
971 // Turn the screen off.
972 // A black surface is already hiding the contents of the screen.
973 setScreenState(Display.STATE_OFF);
Jeff Brown3ee549c2014-09-22 20:14:39 -0700974 mPendingScreenOff = false;
Michael Lentined73854d2015-09-25 10:55:26 -0700975 mPowerState.dismissColorFadeResources();
Jeff Brown606e4e82014-09-18 15:22:26 -0700976 } else if (performScreenOffTransition
977 && mPowerState.prepareColorFade(mContext,
978 mColorFadeFadesConfig ?
979 ColorFade.MODE_FADE : ColorFade.MODE_COOL_DOWN)
980 && mPowerState.getScreenState() != Display.STATE_OFF) {
981 // Perform the screen off animation.
982 mColorFadeOffAnimator.start();
983 } else {
984 // Skip the screen off animation and add a black surface to hide the
985 // contents of the screen.
986 mColorFadeOffAnimator.end();
987 }
988 }
989 }
990
Jeff Brown96307042012-07-27 15:51:34 -0700991 private final Runnable mCleanListener = new Runnable() {
992 @Override
993 public void run() {
994 sendUpdatePowerState();
995 }
996 };
997
998 private void setProximitySensorEnabled(boolean enable) {
999 if (enable) {
1000 if (!mProximitySensorEnabled) {
Jeff Brownec083212013-09-11 20:45:25 -07001001 // Register the listener.
1002 // Proximity sensor state already cleared initially.
Jeff Brown96307042012-07-27 15:51:34 -07001003 mProximitySensorEnabled = true;
Jeff Brown96307042012-07-27 15:51:34 -07001004 mSensorManager.registerListener(mProximitySensorListener, mProximitySensor,
1005 SensorManager.SENSOR_DELAY_NORMAL, mHandler);
1006 }
1007 } else {
1008 if (mProximitySensorEnabled) {
Jeff Brownec083212013-09-11 20:45:25 -07001009 // Unregister the listener.
1010 // Clear the proximity sensor state for next time.
Jeff Brown96307042012-07-27 15:51:34 -07001011 mProximitySensorEnabled = false;
1012 mProximity = PROXIMITY_UNKNOWN;
Jeff Brownec083212013-09-11 20:45:25 -07001013 mPendingProximity = PROXIMITY_UNKNOWN;
Jeff Brown96307042012-07-27 15:51:34 -07001014 mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
1015 mSensorManager.unregisterListener(mProximitySensorListener);
Jeff Brownec083212013-09-11 20:45:25 -07001016 clearPendingProximityDebounceTime(); // release wake lock (must be last)
Jeff Brown96307042012-07-27 15:51:34 -07001017 }
1018 }
1019 }
1020
1021 private void handleProximitySensorEvent(long time, boolean positive) {
Jeff Brownec083212013-09-11 20:45:25 -07001022 if (mProximitySensorEnabled) {
1023 if (mPendingProximity == PROXIMITY_NEGATIVE && !positive) {
1024 return; // no change
1025 }
1026 if (mPendingProximity == PROXIMITY_POSITIVE && positive) {
1027 return; // no change
1028 }
Jeff Brown96307042012-07-27 15:51:34 -07001029
Jeff Brownec083212013-09-11 20:45:25 -07001030 // Only accept a proximity sensor reading if it remains
1031 // stable for the entire debounce delay. We hold a wake lock while
1032 // debouncing the sensor.
1033 mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
1034 if (positive) {
1035 mPendingProximity = PROXIMITY_POSITIVE;
1036 setPendingProximityDebounceTime(
1037 time + PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY); // acquire wake lock
1038 } else {
1039 mPendingProximity = PROXIMITY_NEGATIVE;
1040 setPendingProximityDebounceTime(
1041 time + PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY); // acquire wake lock
1042 }
1043
1044 // Debounce the new sensor reading.
1045 debounceProximitySensor();
Jeff Brown93cbbb22012-10-04 13:18:36 -07001046 }
Jeff Brown96307042012-07-27 15:51:34 -07001047 }
1048
1049 private void debounceProximitySensor() {
Jeff Brownec083212013-09-11 20:45:25 -07001050 if (mProximitySensorEnabled
1051 && mPendingProximity != PROXIMITY_UNKNOWN
1052 && mPendingProximityDebounceTime >= 0) {
Jeff Brown96307042012-07-27 15:51:34 -07001053 final long now = SystemClock.uptimeMillis();
1054 if (mPendingProximityDebounceTime <= now) {
Jeff Brownec083212013-09-11 20:45:25 -07001055 // Sensor reading accepted. Apply the change then release the wake lock.
Jeff Brown96307042012-07-27 15:51:34 -07001056 mProximity = mPendingProximity;
Jeff Brownec083212013-09-11 20:45:25 -07001057 updatePowerState();
1058 clearPendingProximityDebounceTime(); // release wake lock (must be last)
Jeff Brown96307042012-07-27 15:51:34 -07001059 } else {
Jeff Brownec083212013-09-11 20:45:25 -07001060 // Need to wait a little longer.
1061 // Debounce again later. We continue holding a wake lock while waiting.
Jeff Brown96307042012-07-27 15:51:34 -07001062 Message msg = mHandler.obtainMessage(MSG_PROXIMITY_SENSOR_DEBOUNCED);
1063 msg.setAsynchronous(true);
1064 mHandler.sendMessageAtTime(msg, mPendingProximityDebounceTime);
1065 }
1066 }
1067 }
1068
Jeff Brownec083212013-09-11 20:45:25 -07001069 private void clearPendingProximityDebounceTime() {
1070 if (mPendingProximityDebounceTime >= 0) {
1071 mPendingProximityDebounceTime = -1;
Jeff Brown131206b2014-04-08 17:27:14 -07001072 mCallbacks.releaseSuspendBlocker(); // release wake lock
Jeff Brownec083212013-09-11 20:45:25 -07001073 }
1074 }
1075
1076 private void setPendingProximityDebounceTime(long debounceTime) {
1077 if (mPendingProximityDebounceTime < 0) {
Jeff Brown131206b2014-04-08 17:27:14 -07001078 mCallbacks.acquireSuspendBlocker(); // acquire wake lock
Jeff Brownec083212013-09-11 20:45:25 -07001079 }
1080 mPendingProximityDebounceTime = debounceTime;
1081 }
1082
Jeff Brownec083212013-09-11 20:45:25 -07001083 private void sendOnStateChangedWithWakelock() {
Jeff Brown131206b2014-04-08 17:27:14 -07001084 mCallbacks.acquireSuspendBlocker();
1085 mHandler.post(mOnStateChangedRunnable);
Jeff Brown96307042012-07-27 15:51:34 -07001086 }
1087
1088 private final Runnable mOnStateChangedRunnable = new Runnable() {
1089 @Override
1090 public void run() {
1091 mCallbacks.onStateChanged();
Jeff Brown131206b2014-04-08 17:27:14 -07001092 mCallbacks.releaseSuspendBlocker();
Jeff Brown96307042012-07-27 15:51:34 -07001093 }
1094 };
1095
Jeff Brownec083212013-09-11 20:45:25 -07001096 private void sendOnProximityPositiveWithWakelock() {
Jeff Brown131206b2014-04-08 17:27:14 -07001097 mCallbacks.acquireSuspendBlocker();
1098 mHandler.post(mOnProximityPositiveRunnable);
Jeff Brown93cbbb22012-10-04 13:18:36 -07001099 }
1100
1101 private final Runnable mOnProximityPositiveRunnable = new Runnable() {
1102 @Override
1103 public void run() {
1104 mCallbacks.onProximityPositive();
Jeff Brown131206b2014-04-08 17:27:14 -07001105 mCallbacks.releaseSuspendBlocker();
Jeff Brown93cbbb22012-10-04 13:18:36 -07001106 }
1107 };
1108
Jeff Brownec083212013-09-11 20:45:25 -07001109 private void sendOnProximityNegativeWithWakelock() {
Jeff Brown131206b2014-04-08 17:27:14 -07001110 mCallbacks.acquireSuspendBlocker();
1111 mHandler.post(mOnProximityNegativeRunnable);
Jeff Brown96307042012-07-27 15:51:34 -07001112 }
1113
1114 private final Runnable mOnProximityNegativeRunnable = new Runnable() {
1115 @Override
1116 public void run() {
1117 mCallbacks.onProximityNegative();
Jeff Brown131206b2014-04-08 17:27:14 -07001118 mCallbacks.releaseSuspendBlocker();
Jeff Brown96307042012-07-27 15:51:34 -07001119 }
1120 };
1121
Jeff Brownbd6e1502012-08-28 03:27:37 -07001122 public void dump(final PrintWriter pw) {
Jeff Brown96307042012-07-27 15:51:34 -07001123 synchronized (mLock) {
1124 pw.println();
Jeff Brown131206b2014-04-08 17:27:14 -07001125 pw.println("Display Power Controller Locked State:");
Jeff Brown96307042012-07-27 15:51:34 -07001126 pw.println(" mDisplayReadyLocked=" + mDisplayReadyLocked);
1127 pw.println(" mPendingRequestLocked=" + mPendingRequestLocked);
1128 pw.println(" mPendingRequestChangedLocked=" + mPendingRequestChangedLocked);
1129 pw.println(" mPendingWaitForNegativeProximityLocked="
1130 + mPendingWaitForNegativeProximityLocked);
1131 pw.println(" mPendingUpdatePowerStateLocked=" + mPendingUpdatePowerStateLocked);
1132 }
1133
1134 pw.println();
Jeff Brown131206b2014-04-08 17:27:14 -07001135 pw.println("Display Power Controller Configuration:");
Jeff Brown26875502014-01-30 21:47:47 -08001136 pw.println(" mScreenBrightnessDozeConfig=" + mScreenBrightnessDozeConfig);
Jeff Brown96307042012-07-27 15:51:34 -07001137 pw.println(" mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig);
Jeff Brown1bfd0f42014-08-22 01:59:06 -07001138 pw.println(" mScreenBrightnessDarkConfig=" + mScreenBrightnessDarkConfig);
Jeff Brownb76eebff2012-10-05 22:26:44 -07001139 pw.println(" mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum);
1140 pw.println(" mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum);
Jeff Brown2175e9c2014-09-12 16:11:07 -07001141 pw.println(" mUseSoftwareAutoBrightnessConfig=" + mUseSoftwareAutoBrightnessConfig);
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -07001142 pw.println(" mAllowAutoBrightnessWhileDozingConfig=" +
1143 mAllowAutoBrightnessWhileDozingConfig);
Jeff Brown2175e9c2014-09-12 16:11:07 -07001144 pw.println(" mColorFadeFadesConfig=" + mColorFadeFadesConfig);
Jeff Brown96307042012-07-27 15:51:34 -07001145
Jeff Brownbd6e1502012-08-28 03:27:37 -07001146 mHandler.runWithScissors(new Runnable() {
1147 @Override
1148 public void run() {
1149 dumpLocal(pw);
Jeff Brown96307042012-07-27 15:51:34 -07001150 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001151 }, 1000);
Jeff Brown96307042012-07-27 15:51:34 -07001152 }
1153
1154 private void dumpLocal(PrintWriter pw) {
1155 pw.println();
Jeff Brown131206b2014-04-08 17:27:14 -07001156 pw.println("Display Power Controller Thread State:");
Jeff Brown96307042012-07-27 15:51:34 -07001157 pw.println(" mPowerRequest=" + mPowerRequest);
1158 pw.println(" mWaitingForNegativeProximity=" + mWaitingForNegativeProximity);
1159
1160 pw.println(" mProximitySensor=" + mProximitySensor);
1161 pw.println(" mProximitySensorEnabled=" + mProximitySensorEnabled);
1162 pw.println(" mProximityThreshold=" + mProximityThreshold);
1163 pw.println(" mProximity=" + proximityToString(mProximity));
1164 pw.println(" mPendingProximity=" + proximityToString(mPendingProximity));
1165 pw.println(" mPendingProximityDebounceTime="
1166 + TimeUtils.formatUptime(mPendingProximityDebounceTime));
1167 pw.println(" mScreenOffBecauseOfProximity=" + mScreenOffBecauseOfProximity);
Jeff Brown970d4132014-07-19 11:33:47 -07001168 pw.println(" mAppliedAutoBrightness=" + mAppliedAutoBrightness);
1169 pw.println(" mAppliedDimming=" + mAppliedDimming);
1170 pw.println(" mAppliedLowPower=" + mAppliedLowPower);
Jeff Brown3ee549c2014-09-22 20:14:39 -07001171 pw.println(" mPendingScreenOnUnblocker=" + mPendingScreenOnUnblocker);
1172 pw.println(" mPendingScreenOff=" + mPendingScreenOff);
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001173 pw.println(" mReportedToPolicy=" + reportedToPolicyToString(mReportedScreenStateToPolicy));
Jeff Brown96307042012-07-27 15:51:34 -07001174
Jeff Brown42558692014-05-20 22:02:46 -07001175 pw.println(" mScreenBrightnessRampAnimator.isAnimating()=" +
1176 mScreenBrightnessRampAnimator.isAnimating());
1177
Michael Lentine0839adb2014-07-29 18:47:56 -07001178 if (mColorFadeOnAnimator != null) {
1179 pw.println(" mColorFadeOnAnimator.isStarted()=" +
1180 mColorFadeOnAnimator.isStarted());
Jeff Brown96307042012-07-27 15:51:34 -07001181 }
Michael Lentine0839adb2014-07-29 18:47:56 -07001182 if (mColorFadeOffAnimator != null) {
1183 pw.println(" mColorFadeOffAnimator.isStarted()=" +
1184 mColorFadeOffAnimator.isStarted());
Jeff Brown96307042012-07-27 15:51:34 -07001185 }
1186
1187 if (mPowerState != null) {
1188 mPowerState.dump(pw);
1189 }
Michael Wright639c8be2014-01-17 18:29:12 -08001190
1191 if (mAutomaticBrightnessController != null) {
1192 mAutomaticBrightnessController.dump(pw);
1193 }
1194
Jeff Brown96307042012-07-27 15:51:34 -07001195 }
1196
1197 private static String proximityToString(int state) {
1198 switch (state) {
1199 case PROXIMITY_UNKNOWN:
1200 return "Unknown";
1201 case PROXIMITY_NEGATIVE:
1202 return "Negative";
1203 case PROXIMITY_POSITIVE:
1204 return "Positive";
1205 default:
1206 return Integer.toString(state);
1207 }
1208 }
1209
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001210 private static String reportedToPolicyToString(int state) {
1211 switch (state) {
1212 case REPORTED_TO_POLICY_SCREEN_OFF:
1213 return "REPORTED_TO_POLICY_SCREEN_OFF";
1214 case REPORTED_TO_POLICY_SCREEN_TURNING_ON:
1215 return "REPORTED_TO_POLICY_SCREEN_TURNING_ON";
1216 case REPORTED_TO_POLICY_SCREEN_ON:
1217 return "REPORTED_TO_POLICY_SCREEN_ON";
1218 default:
1219 return Integer.toString(state);
1220 }
1221 }
1222
Michael Wright639c8be2014-01-17 18:29:12 -08001223 private static Spline createAutoBrightnessSpline(int[] lux, int[] brightness) {
Erik Wolsheimerad82aca2016-06-28 14:51:07 -07001224 if (lux == null || lux.length == 0 || brightness == null || brightness.length == 0) {
1225 Slog.e(TAG, "Could not create auto-brightness spline.");
1226 return null;
1227 }
Michael Wright639c8be2014-01-17 18:29:12 -08001228 try {
1229 final int n = brightness.length;
1230 float[] x = new float[n];
1231 float[] y = new float[n];
1232 y[0] = normalizeAbsoluteBrightness(brightness[0]);
1233 for (int i = 1; i < n; i++) {
1234 x[i] = lux[i - 1];
1235 y[i] = normalizeAbsoluteBrightness(brightness[i]);
1236 }
1237
Michael Wright3e9a1342014-08-28 17:42:16 -07001238 Spline spline = Spline.createSpline(x, y);
Michael Wright639c8be2014-01-17 18:29:12 -08001239 if (DEBUG) {
1240 Slog.d(TAG, "Auto-brightness spline: " + spline);
1241 for (float v = 1f; v < lux[lux.length - 1] * 1.25f; v *= 1.25f) {
1242 Slog.d(TAG, String.format(" %7.1f: %7.1f", v, spline.interpolate(v)));
1243 }
1244 }
1245 return spline;
1246 } catch (IllegalArgumentException ex) {
1247 Slog.e(TAG, "Could not create auto-brightness spline.", ex);
1248 return null;
Jeff Brown96307042012-07-27 15:51:34 -07001249 }
Michael Wright639c8be2014-01-17 18:29:12 -08001250 }
1251
1252 private static float normalizeAbsoluteBrightness(int value) {
1253 return (float)clampAbsoluteBrightness(value) / PowerManager.BRIGHTNESS_ON;
1254 }
1255
1256 private static int clampAbsoluteBrightness(int value) {
1257 return MathUtils.constrain(value, PowerManager.BRIGHTNESS_OFF, PowerManager.BRIGHTNESS_ON);
Jeff Brown96307042012-07-27 15:51:34 -07001258 }
1259
Jeff Brown96307042012-07-27 15:51:34 -07001260 private final class DisplayControllerHandler extends Handler {
1261 public DisplayControllerHandler(Looper looper) {
Jeff Browna2910d02012-08-25 12:29:46 -07001262 super(looper, null, true /*async*/);
Jeff Brown96307042012-07-27 15:51:34 -07001263 }
1264
1265 @Override
1266 public void handleMessage(Message msg) {
1267 switch (msg.what) {
1268 case MSG_UPDATE_POWER_STATE:
1269 updatePowerState();
1270 break;
1271
1272 case MSG_PROXIMITY_SENSOR_DEBOUNCED:
1273 debounceProximitySensor();
1274 break;
Jeff Brown3ee549c2014-09-22 20:14:39 -07001275
1276 case MSG_SCREEN_ON_UNBLOCKED:
1277 if (mPendingScreenOnUnblocker == msg.obj) {
1278 unblockScreenOn();
1279 updatePowerState();
1280 }
1281 break;
Jeff Brown96307042012-07-27 15:51:34 -07001282 }
1283 }
1284 }
1285
1286 private final SensorEventListener mProximitySensorListener = new SensorEventListener() {
1287 @Override
1288 public void onSensorChanged(SensorEvent event) {
1289 if (mProximitySensorEnabled) {
1290 final long time = SystemClock.uptimeMillis();
1291 final float distance = event.values[0];
1292 boolean positive = distance >= 0.0f && distance < mProximityThreshold;
1293 handleProximitySensorEvent(time, positive);
1294 }
1295 }
1296
1297 @Override
1298 public void onAccuracyChanged(Sensor sensor, int accuracy) {
1299 // Not used.
1300 }
1301 };
Jeff Brown3ee549c2014-09-22 20:14:39 -07001302
1303 private final class ScreenOnUnblocker implements WindowManagerPolicy.ScreenOnListener {
1304 @Override
1305 public void onScreenOn() {
1306 Message msg = mHandler.obtainMessage(MSG_SCREEN_ON_UNBLOCKED, this);
1307 msg.setAsynchronous(true);
1308 mHandler.sendMessage(msg);
1309 }
1310 }
Jeff Brown96307042012-07-27 15:51:34 -07001311}