blob: 22df07b3e3f0db288c3c4cbde0a2134bece9210c [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'souza043a5712016-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
Julius D'souzabbfdf7a2016-11-03 18:43:15 -0700156 // True if collecting light sensor samples in doze mode.
157 private boolean mUseActiveDozeLightSensorConfig;
Julius D'souzaa2b07dc2016-10-21 19:16:47 -0700158
Jeff Brown252c2062012-10-08 16:21:01 -0700159 // True if we should fade the screen while turning it off, false if we should play
Jeff Brown3ee549c2014-09-22 20:14:39 -0700160 // a stylish color fade animation instead.
Michael Lentine0839adb2014-07-29 18:47:56 -0700161 private boolean mColorFadeFadesConfig;
Jeff Browna52772f2012-10-04 18:38:09 -0700162
Jeff Brown96307042012-07-27 15:51:34 -0700163 // The pending power request.
164 // Initially null until the first call to requestPowerState.
165 // Guarded by mLock.
166 private DisplayPowerRequest mPendingRequestLocked;
167
168 // True if a request has been made to wait for the proximity sensor to go negative.
169 // Guarded by mLock.
170 private boolean mPendingWaitForNegativeProximityLocked;
171
172 // True if the pending power request or wait for negative proximity flag
173 // has been changed since the last update occurred.
174 // Guarded by mLock.
175 private boolean mPendingRequestChangedLocked;
176
177 // Set to true when the important parts of the pending power request have been applied.
178 // The important parts are mainly the screen state. Brightness changes may occur
179 // concurrently.
180 // Guarded by mLock.
181 private boolean mDisplayReadyLocked;
182
183 // Set to true if a power state update is required.
184 // Guarded by mLock.
185 private boolean mPendingUpdatePowerStateLocked;
186
187 /* The following state must only be accessed by the handler thread. */
188
189 // The currently requested power state.
190 // The power controller will progressively update its internal state to match
191 // the requested power state. Initially null until the first update.
192 private DisplayPowerRequest mPowerRequest;
193
194 // The current power state.
195 // Must only be accessed on the handler thread.
196 private DisplayPowerState mPowerState;
197
198 // True if the device should wait for negative proximity sensor before
199 // waking up the screen. This is set to false as soon as a negative
200 // proximity sensor measurement is observed or when the device is forced to
201 // go to sleep by the user. While true, the screen remains off.
202 private boolean mWaitingForNegativeProximity;
203
204 // The actual proximity sensor threshold value.
205 private float mProximityThreshold;
206
207 // Set to true if the proximity sensor listener has been registered
208 // with the sensor manager.
209 private boolean mProximitySensorEnabled;
210
211 // The debounced proximity sensor state.
212 private int mProximity = PROXIMITY_UNKNOWN;
213
214 // The raw non-debounced proximity sensor state.
215 private int mPendingProximity = PROXIMITY_UNKNOWN;
Jeff Brownec083212013-09-11 20:45:25 -0700216 private long mPendingProximityDebounceTime = -1; // -1 if fully debounced
Jeff Brown96307042012-07-27 15:51:34 -0700217
218 // True if the screen was turned off because of the proximity sensor.
219 // When the screen turns on again, we report user activity to the power manager.
220 private boolean mScreenOffBecauseOfProximity;
221
Jeff Brown3ee549c2014-09-22 20:14:39 -0700222 // The currently active screen on unblocker. This field is non-null whenever
223 // we are waiting for a callback to release it and unblock the screen.
224 private ScreenOnUnblocker mPendingScreenOnUnblocker;
225
226 // True if we were in the process of turning off the screen.
227 // This allows us to recover more gracefully from situations where we abort
228 // turning off the screen.
229 private boolean mPendingScreenOff;
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700230
Jeff Brown0a434772014-09-30 14:42:27 -0700231 // True if we have unfinished business and are holding a suspend blocker.
232 private boolean mUnfinishedBusiness;
233
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700234 // The elapsed real time when the screen on was blocked.
235 private long mScreenOnBlockStartRealTime;
236
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700237 // Screen state we reported to policy. Must be one of REPORTED_TO_POLICY_SCREEN_* fields.
238 private int mReportedScreenStateToPolicy;
Jeff Browne1633ad2015-06-22 19:24:24 -0700239
Jeff Brown970d4132014-07-19 11:33:47 -0700240 // Remembers whether certain kinds of brightness adjustments
241 // were recently applied so that we can decide how to transition.
242 private boolean mAppliedAutoBrightness;
243 private boolean mAppliedDimming;
244 private boolean mAppliedLowPower;
Jeff Brown96307042012-07-27 15:51:34 -0700245
Julius D'souza621dc1c2016-08-05 14:34:38 -0700246 // Brightness animation ramp rates in brightness units per second
Prashant Malani99e6d432016-03-29 16:32:37 -0700247 private final int mBrightnessRampRateFast;
Julius D'souza621dc1c2016-08-05 14:34:38 -0700248 private final int mBrightnessRampRateSlow;
Prashant Malani99e6d432016-03-29 16:32:37 -0700249
Michael Wright639c8be2014-01-17 18:29:12 -0800250 // The controller for the automatic brightness level.
251 private AutomaticBrightnessController mAutomaticBrightnessController;
252
Jeff Brown96307042012-07-27 15:51:34 -0700253 // Animators.
Michael Lentine0839adb2014-07-29 18:47:56 -0700254 private ObjectAnimator mColorFadeOnAnimator;
255 private ObjectAnimator mColorFadeOffAnimator;
Jeff Brown96307042012-07-27 15:51:34 -0700256 private RampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator;
257
258 /**
259 * Creates the display power controller.
260 */
Jeff Brown131206b2014-04-08 17:27:14 -0700261 public DisplayPowerController(Context context,
Jeff Brown037c33e2014-04-09 00:31:55 -0700262 DisplayPowerCallbacks callbacks, Handler handler,
263 SensorManager sensorManager, DisplayBlanker blanker) {
Jeff Brown131206b2014-04-08 17:27:14 -0700264 mHandler = new DisplayControllerHandler(handler.getLooper());
Jeff Brown96307042012-07-27 15:51:34 -0700265 mCallbacks = callbacks;
Jeff Brown96307042012-07-27 15:51:34 -0700266
Jeff Brown131206b2014-04-08 17:27:14 -0700267 mBatteryStats = BatteryStatsService.getService();
Jeff Brown3b971592013-01-09 18:46:37 -0800268 mSensorManager = sensorManager;
Jeff Brown3ee549c2014-09-22 20:14:39 -0700269 mWindowManagerPolicy = LocalServices.getService(WindowManagerPolicy.class);
Jeff Brown037c33e2014-04-09 00:31:55 -0700270 mBlanker = blanker;
Michael Lentine0839adb2014-07-29 18:47:56 -0700271 mContext = context;
Jeff Brown96307042012-07-27 15:51:34 -0700272
273 final Resources resources = context.getResources();
Jeff Brown1bfd0f42014-08-22 01:59:06 -0700274 final int screenBrightnessSettingMinimum = clampAbsoluteBrightness(resources.getInteger(
275 com.android.internal.R.integer.config_screenBrightnessSettingMinimum));
Jeff Brownb76eebff2012-10-05 22:26:44 -0700276
Jeff Brown26875502014-01-30 21:47:47 -0800277 mScreenBrightnessDozeConfig = clampAbsoluteBrightness(resources.getInteger(
278 com.android.internal.R.integer.config_screenBrightnessDoze));
279
Jeff Brownb76eebff2012-10-05 22:26:44 -0700280 mScreenBrightnessDimConfig = clampAbsoluteBrightness(resources.getInteger(
281 com.android.internal.R.integer.config_screenBrightnessDim));
282
Jeff Brown1bfd0f42014-08-22 01:59:06 -0700283 mScreenBrightnessDarkConfig = clampAbsoluteBrightness(resources.getInteger(
284 com.android.internal.R.integer.config_screenBrightnessDark));
285 if (mScreenBrightnessDarkConfig > mScreenBrightnessDimConfig) {
286 Slog.w(TAG, "Expected config_screenBrightnessDark ("
287 + mScreenBrightnessDarkConfig + ") to be less than or equal to "
288 + "config_screenBrightnessDim (" + mScreenBrightnessDimConfig + ").");
289 }
290 if (mScreenBrightnessDarkConfig > mScreenBrightnessDimConfig) {
291 Slog.w(TAG, "Expected config_screenBrightnessDark ("
292 + mScreenBrightnessDarkConfig + ") to be less than or equal to "
293 + "config_screenBrightnessSettingMinimum ("
294 + screenBrightnessSettingMinimum + ").");
295 }
296
297 int screenBrightnessRangeMinimum = Math.min(Math.min(
298 screenBrightnessSettingMinimum, mScreenBrightnessDimConfig),
299 mScreenBrightnessDarkConfig);
Michael Wright639c8be2014-01-17 18:29:12 -0800300
301 mScreenBrightnessRangeMaximum = PowerManager.BRIGHTNESS_ON;
Jeff Brownb76eebff2012-10-05 22:26:44 -0700302
Jeff Brown96307042012-07-27 15:51:34 -0700303 mUseSoftwareAutoBrightnessConfig = resources.getBoolean(
304 com.android.internal.R.bool.config_automatic_brightness_available);
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700305
306 mAllowAutoBrightnessWhileDozingConfig = resources.getBoolean(
307 com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing);
308
Prashant Malani99e6d432016-03-29 16:32:37 -0700309 mBrightnessRampRateFast = resources.getInteger(
310 com.android.internal.R.integer.config_brightness_ramp_rate_fast);
Julius D'souza621dc1c2016-08-05 14:34:38 -0700311 mBrightnessRampRateSlow = resources.getInteger(
312 com.android.internal.R.integer.config_brightness_ramp_rate_slow);
Prashant Malani99e6d432016-03-29 16:32:37 -0700313
Filip Gruszczynskid81ecd12015-02-06 12:38:47 -0800314 int lightSensorRate = resources.getInteger(
315 com.android.internal.R.integer.config_autoBrightnessLightSensorRate);
Julius D'souza82b9aff2016-10-24 19:26:45 -0700316 int initialLightSensorRate = resources.getInteger(
317 com.android.internal.R.integer.config_autoBrightnessInitialLightSensorRate);
Julius D'souza5c7ae142016-11-07 10:55:20 -0800318 if (initialLightSensorRate == -1) {
319 initialLightSensorRate = lightSensorRate;
320 } else if (initialLightSensorRate > lightSensorRate) {
321 Slog.w(TAG, "Expected config_autoBrightnessInitialLightSensorRate ("
322 + initialLightSensorRate + ") to be less than or equal to "
323 + "config_autoBrightnessLightSensorRate (" + lightSensorRate + ").");
324 }
Filip Gruszczynskid81ecd12015-02-06 12:38:47 -0800325 long brighteningLightDebounce = resources.getInteger(
326 com.android.internal.R.integer.config_autoBrightnessBrighteningLightDebounce);
327 long darkeningLightDebounce = resources.getInteger(
328 com.android.internal.R.integer.config_autoBrightnessDarkeningLightDebounce);
329 boolean autoBrightnessResetAmbientLuxAfterWarmUp = resources.getBoolean(
330 com.android.internal.R.bool.config_autoBrightnessResetAmbientLuxAfterWarmUp);
Zoran Jovanovic6fc42f52015-12-10 17:01:16 +0100331 int ambientLightHorizon = resources.getInteger(
332 com.android.internal.R.integer.config_autoBrightnessAmbientLightHorizon);
333 float autoBrightnessAdjustmentMaxGamma = resources.getFraction(
334 com.android.internal.R.fraction.config_autoBrightnessAdjustmentMaxGamma,
335 1, 1);
Filip Gruszczynskid81ecd12015-02-06 12:38:47 -0800336
Jeff Brown96307042012-07-27 15:51:34 -0700337 if (mUseSoftwareAutoBrightnessConfig) {
Jeff Brown1a30b552012-08-16 01:31:11 -0700338 int[] lux = resources.getIntArray(
Jeff Brown96307042012-07-27 15:51:34 -0700339 com.android.internal.R.array.config_autoBrightnessLevels);
Jeff Brown1a30b552012-08-16 01:31:11 -0700340 int[] screenBrightness = resources.getIntArray(
Jeff Brown96307042012-07-27 15:51:34 -0700341 com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
Michael Wright639c8be2014-01-17 18:29:12 -0800342 int lightSensorWarmUpTimeConfig = resources.getInteger(
343 com.android.internal.R.integer.config_lightSensorWarmupTime);
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700344 final float dozeScaleFactor = resources.getFraction(
345 com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor,
346 1, 1);
Jeff Brown1a30b552012-08-16 01:31:11 -0700347
Julius D'souzac4e1e492016-10-04 11:05:56 -0700348 // hysteresis configs
349 int[] brightHysteresisLevels = resources.getIntArray(
350 com.android.internal.R.array.config_dynamicHysteresisBrightLevels);
351 int[] darkHysteresisLevels = resources.getIntArray(
352 com.android.internal.R.array.config_dynamicHysteresisDarkLevels);
353 int[] luxHysteresisLevels = resources.getIntArray(
354 com.android.internal.R.array.config_dynamicHysteresisLuxLevels);
355 // doze brightness configs
356 int[] dozeSensorLuxLevels = resources.getIntArray(
357 com.android.internal.R.array.config_dozeSensorLuxLevels);
358 int[] dozeBrightnessBacklightValues = resources.getIntArray(
359 com.android.internal.R.array.config_dozeBrightnessBacklightValues);
Julius D'souzabbfdf7a2016-11-03 18:43:15 -0700360 boolean useNewSensorSamplesForDoze = resources.getBoolean(
Julius D'souzac4e1e492016-10-04 11:05:56 -0700361 com.android.internal.R.bool.config_useNewSensorSamplesForDoze);
Julius D'souzabbfdf7a2016-11-03 18:43:15 -0700362 mUseActiveDozeLightSensorConfig = resources.getBoolean(
363 com.android.internal.R.bool.config_allowAutoBrightnessActiveDozeLightSensor);
Julius D'souzac4e1e492016-10-04 11:05:56 -0700364 LuxLevels luxLevels = new LuxLevels(brightHysteresisLevels, darkHysteresisLevels,
Julius D'souzabbfdf7a2016-11-03 18:43:15 -0700365 luxHysteresisLevels, dozeSensorLuxLevels, dozeBrightnessBacklightValues);
Julius D'souzac4e1e492016-10-04 11:05:56 -0700366
Michael Wright639c8be2014-01-17 18:29:12 -0800367 Spline screenAutoBrightnessSpline = createAutoBrightnessSpline(lux, screenBrightness);
368 if (screenAutoBrightnessSpline == null) {
Jeff Brown96307042012-07-27 15:51:34 -0700369 Slog.e(TAG, "Error in config.xml. config_autoBrightnessLcdBacklightValues "
Jeff Brown1a30b552012-08-16 01:31:11 -0700370 + "(size " + screenBrightness.length + ") "
371 + "must be monotic and have exactly one more entry than "
372 + "config_autoBrightnessLevels (size " + lux.length + ") "
373 + "which must be strictly increasing. "
Jeff Brown96307042012-07-27 15:51:34 -0700374 + "Auto-brightness will be disabled.");
375 mUseSoftwareAutoBrightnessConfig = false;
Jeff Brownb76eebff2012-10-05 22:26:44 -0700376 } else {
Jeff Brown1bfd0f42014-08-22 01:59:06 -0700377 int bottom = clampAbsoluteBrightness(screenBrightness[0]);
378 if (mScreenBrightnessDarkConfig > bottom) {
379 Slog.w(TAG, "config_screenBrightnessDark (" + mScreenBrightnessDarkConfig
380 + ") should be less than or equal to the first value of "
381 + "config_autoBrightnessLcdBacklightValues ("
382 + bottom + ").");
383 }
384 if (bottom < screenBrightnessRangeMinimum) {
385 screenBrightnessRangeMinimum = bottom;
Jeff Brownb76eebff2012-10-05 22:26:44 -0700386 }
Jeff Brown131206b2014-04-08 17:27:14 -0700387 mAutomaticBrightnessController = new AutomaticBrightnessController(this,
388 handler.getLooper(), sensorManager, screenAutoBrightnessSpline,
Michael Wright639c8be2014-01-17 18:29:12 -0800389 lightSensorWarmUpTimeConfig, screenBrightnessRangeMinimum,
Filip Gruszczynskid81ecd12015-02-06 12:38:47 -0800390 mScreenBrightnessRangeMaximum, dozeScaleFactor, lightSensorRate,
Julius D'souza82b9aff2016-10-24 19:26:45 -0700391 initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce,
Julius D'souza043a5712016-08-07 19:08:30 -0700392 autoBrightnessResetAmbientLuxAfterWarmUp, ambientLightHorizon,
Julius D'souzabbfdf7a2016-11-03 18:43:15 -0700393 autoBrightnessAdjustmentMaxGamma, mUseActiveDozeLightSensorConfig,
394 useNewSensorSamplesForDoze, luxLevels);
Jeff Brown96307042012-07-27 15:51:34 -0700395 }
Jeff Brown96307042012-07-27 15:51:34 -0700396 }
397
Michael Wright639c8be2014-01-17 18:29:12 -0800398 mScreenBrightnessRangeMinimum = screenBrightnessRangeMinimum;
Jeff Brownb76eebff2012-10-05 22:26:44 -0700399
Michael Lentine0839adb2014-07-29 18:47:56 -0700400 mColorFadeFadesConfig = resources.getBoolean(
Jeff Browna52772f2012-10-04 18:38:09 -0700401 com.android.internal.R.bool.config_animateScreenLights);
402
Jeff Brown96307042012-07-27 15:51:34 -0700403 if (!DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) {
404 mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
405 if (mProximitySensor != null) {
406 mProximityThreshold = Math.min(mProximitySensor.getMaximumRange(),
407 TYPICAL_PROXIMITY_THRESHOLD);
408 }
409 }
410
Jeff Brown1a30b552012-08-16 01:31:11 -0700411 }
412
Jeff Brown96307042012-07-27 15:51:34 -0700413 /**
414 * Returns true if the proximity sensor screen-off function is available.
415 */
416 public boolean isProximitySensorAvailable() {
417 return mProximitySensor != null;
418 }
419
420 /**
421 * Requests a new power state.
422 * The controller makes a copy of the provided object and then
423 * begins adjusting the power state to match what was requested.
424 *
425 * @param request The requested power state.
426 * @param waitForNegativeProximity If true, issues a request to wait for
427 * negative proximity before turning the screen back on, assuming the screen
428 * was turned off by the proximity sensor.
429 * @return True if display is ready, false if there are important changes that must
430 * be made asynchronously (such as turning the screen on), in which case the caller
Jeff Brown606e4e82014-09-18 15:22:26 -0700431 * should grab a wake lock, watch for {@link DisplayPowerCallbacks#onStateChanged()}
432 * then try the request again later until the state converges.
Jeff Brown96307042012-07-27 15:51:34 -0700433 */
434 public boolean requestPowerState(DisplayPowerRequest request,
435 boolean waitForNegativeProximity) {
436 if (DEBUG) {
437 Slog.d(TAG, "requestPowerState: "
438 + request + ", waitForNegativeProximity=" + waitForNegativeProximity);
439 }
440
441 synchronized (mLock) {
442 boolean changed = false;
443
444 if (waitForNegativeProximity
445 && !mPendingWaitForNegativeProximityLocked) {
446 mPendingWaitForNegativeProximityLocked = true;
447 changed = true;
448 }
449
450 if (mPendingRequestLocked == null) {
451 mPendingRequestLocked = new DisplayPowerRequest(request);
452 changed = true;
453 } else if (!mPendingRequestLocked.equals(request)) {
454 mPendingRequestLocked.copyFrom(request);
455 changed = true;
456 }
457
458 if (changed) {
459 mDisplayReadyLocked = false;
460 }
461
462 if (changed && !mPendingRequestChangedLocked) {
463 mPendingRequestChangedLocked = true;
464 sendUpdatePowerStateLocked();
465 }
466
467 return mDisplayReadyLocked;
468 }
469 }
470
471 private void sendUpdatePowerState() {
472 synchronized (mLock) {
473 sendUpdatePowerStateLocked();
474 }
475 }
476
477 private void sendUpdatePowerStateLocked() {
478 if (!mPendingUpdatePowerStateLocked) {
479 mPendingUpdatePowerStateLocked = true;
480 Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE);
481 msg.setAsynchronous(true);
482 mHandler.sendMessage(msg);
483 }
484 }
485
486 private void initialize() {
Jeff Brown037c33e2014-04-09 00:31:55 -0700487 // Initialize the power state object for the default display.
488 // In the future, we might manage multiple displays independently.
489 mPowerState = new DisplayPowerState(mBlanker,
Michael Lentine0839adb2014-07-29 18:47:56 -0700490 new ColorFade(Display.DEFAULT_DISPLAY));
Jeff Brown96307042012-07-27 15:51:34 -0700491
Michael Lentine0839adb2014-07-29 18:47:56 -0700492 mColorFadeOnAnimator = ObjectAnimator.ofFloat(
493 mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 0.0f, 1.0f);
494 mColorFadeOnAnimator.setDuration(COLOR_FADE_ON_ANIMATION_DURATION_MILLIS);
495 mColorFadeOnAnimator.addListener(mAnimatorListener);
Jeff Brown96307042012-07-27 15:51:34 -0700496
Michael Lentine0839adb2014-07-29 18:47:56 -0700497 mColorFadeOffAnimator = ObjectAnimator.ofFloat(
498 mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 1.0f, 0.0f);
499 mColorFadeOffAnimator.setDuration(COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS);
500 mColorFadeOffAnimator.addListener(mAnimatorListener);
Jeff Brown96307042012-07-27 15:51:34 -0700501
502 mScreenBrightnessRampAnimator = new RampAnimator<DisplayPowerState>(
503 mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS);
Jeff Brown42558692014-05-20 22:02:46 -0700504 mScreenBrightnessRampAnimator.setListener(mRampAnimatorListener);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800505
Jeff Brown131206b2014-04-08 17:27:14 -0700506 // Initialize screen state for battery stats.
507 try {
Jeff Browne95c3cd2014-05-02 16:59:26 -0700508 mBatteryStats.noteScreenState(mPowerState.getScreenState());
Jeff Brown131206b2014-04-08 17:27:14 -0700509 mBatteryStats.noteScreenBrightness(mPowerState.getScreenBrightness());
510 } catch (RemoteException ex) {
511 // same process
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800512 }
Jeff Brown96307042012-07-27 15:51:34 -0700513 }
514
515 private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() {
516 @Override
517 public void onAnimationStart(Animator animation) {
518 }
519 @Override
520 public void onAnimationEnd(Animator animation) {
521 sendUpdatePowerState();
522 }
523 @Override
524 public void onAnimationRepeat(Animator animation) {
525 }
526 @Override
527 public void onAnimationCancel(Animator animation) {
528 }
529 };
530
Jeff Brown42558692014-05-20 22:02:46 -0700531 private final RampAnimator.Listener mRampAnimatorListener = new RampAnimator.Listener() {
532 @Override
533 public void onAnimationEnd() {
534 sendUpdatePowerState();
535 }
536 };
537
Jeff Brown96307042012-07-27 15:51:34 -0700538 private void updatePowerState() {
539 // Update the power state request.
540 final boolean mustNotify;
541 boolean mustInitialize = false;
Adrian Roos6da87ab2014-05-16 23:09:41 +0200542 boolean autoBrightnessAdjustmentChanged = false;
Jeff Brown330560f2012-08-21 22:10:57 -0700543
Jeff Brown96307042012-07-27 15:51:34 -0700544 synchronized (mLock) {
545 mPendingUpdatePowerStateLocked = false;
546 if (mPendingRequestLocked == null) {
547 return; // wait until first actual power request
548 }
549
550 if (mPowerRequest == null) {
551 mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked);
552 mWaitingForNegativeProximity = mPendingWaitForNegativeProximityLocked;
Jeff Brown6307a152012-08-20 13:24:23 -0700553 mPendingWaitForNegativeProximityLocked = false;
Jeff Brown96307042012-07-27 15:51:34 -0700554 mPendingRequestChangedLocked = false;
555 mustInitialize = true;
556 } else if (mPendingRequestChangedLocked) {
Adrian Roos6da87ab2014-05-16 23:09:41 +0200557 autoBrightnessAdjustmentChanged = (mPowerRequest.screenAutoBrightnessAdjustment
558 != mPendingRequestLocked.screenAutoBrightnessAdjustment);
Jeff Brown96307042012-07-27 15:51:34 -0700559 mPowerRequest.copyFrom(mPendingRequestLocked);
560 mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked;
Jeff Brown6307a152012-08-20 13:24:23 -0700561 mPendingWaitForNegativeProximityLocked = false;
Jeff Brown96307042012-07-27 15:51:34 -0700562 mPendingRequestChangedLocked = false;
563 mDisplayReadyLocked = false;
564 }
565
566 mustNotify = !mDisplayReadyLocked;
567 }
568
569 // Initialize things the first time the power state is changed.
570 if (mustInitialize) {
571 initialize();
572 }
573
Jeff Brown970d4132014-07-19 11:33:47 -0700574 // Compute the basic display state using the policy.
575 // We might override this below based on other factors.
576 int state;
577 int brightness = PowerManager.BRIGHTNESS_DEFAULT;
Jeff Brown2175e9c2014-09-12 16:11:07 -0700578 boolean performScreenOffTransition = false;
Jeff Brown970d4132014-07-19 11:33:47 -0700579 switch (mPowerRequest.policy) {
580 case DisplayPowerRequest.POLICY_OFF:
581 state = Display.STATE_OFF;
Jeff Brown2175e9c2014-09-12 16:11:07 -0700582 performScreenOffTransition = true;
Jeff Brown970d4132014-07-19 11:33:47 -0700583 break;
584 case DisplayPowerRequest.POLICY_DOZE:
585 if (mPowerRequest.dozeScreenState != Display.STATE_UNKNOWN) {
586 state = mPowerRequest.dozeScreenState;
587 } else {
588 state = Display.STATE_DOZE;
589 }
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700590 if (!mAllowAutoBrightnessWhileDozingConfig) {
591 brightness = mPowerRequest.dozeScreenBrightness;
592 }
Jeff Brown970d4132014-07-19 11:33:47 -0700593 break;
Santos Cordond6a56602016-09-20 15:50:35 -0700594 case DisplayPowerRequest.POLICY_VR:
595 state = Display.STATE_VR;
596 break;
Jeff Brown970d4132014-07-19 11:33:47 -0700597 case DisplayPowerRequest.POLICY_DIM:
598 case DisplayPowerRequest.POLICY_BRIGHT:
599 default:
600 state = Display.STATE_ON;
601 break;
602 }
Jeff Brown2175e9c2014-09-12 16:11:07 -0700603 assert(state != Display.STATE_UNKNOWN);
Jeff Brown970d4132014-07-19 11:33:47 -0700604
Jeff Brown6307a152012-08-20 13:24:23 -0700605 // Apply the proximity sensor.
Jeff Brown96307042012-07-27 15:51:34 -0700606 if (mProximitySensor != null) {
Jeff Brown970d4132014-07-19 11:33:47 -0700607 if (mPowerRequest.useProximitySensor && state != Display.STATE_OFF) {
Jeff Brown6307a152012-08-20 13:24:23 -0700608 setProximitySensorEnabled(true);
609 if (!mScreenOffBecauseOfProximity
610 && mProximity == PROXIMITY_POSITIVE) {
611 mScreenOffBecauseOfProximity = true;
Jeff Brownec083212013-09-11 20:45:25 -0700612 sendOnProximityPositiveWithWakelock();
Jeff Brown6307a152012-08-20 13:24:23 -0700613 }
614 } else if (mWaitingForNegativeProximity
615 && mScreenOffBecauseOfProximity
616 && mProximity == PROXIMITY_POSITIVE
Jeff Brown970d4132014-07-19 11:33:47 -0700617 && state != Display.STATE_OFF) {
Jeff Brown6307a152012-08-20 13:24:23 -0700618 setProximitySensorEnabled(true);
619 } else {
620 setProximitySensorEnabled(false);
621 mWaitingForNegativeProximity = false;
622 }
623 if (mScreenOffBecauseOfProximity
624 && mProximity != PROXIMITY_POSITIVE) {
Jeff Brown96307042012-07-27 15:51:34 -0700625 mScreenOffBecauseOfProximity = false;
Jeff Brownec083212013-09-11 20:45:25 -0700626 sendOnProximityNegativeWithWakelock();
Jeff Brown96307042012-07-27 15:51:34 -0700627 }
Jeff Brown6307a152012-08-20 13:24:23 -0700628 } else {
629 mWaitingForNegativeProximity = false;
Jeff Brown96307042012-07-27 15:51:34 -0700630 }
Jeff Brown970d4132014-07-19 11:33:47 -0700631 if (mScreenOffBecauseOfProximity) {
632 state = Display.STATE_OFF;
Jeff Brown96307042012-07-27 15:51:34 -0700633 }
634
Jeff Brownbf4e4142014-10-02 13:08:05 -0700635 // Animate the screen state change unless already animating.
636 // The transition may be deferred, so after this point we will use the
637 // actual state instead of the desired one.
Santos Cordond6a56602016-09-20 15:50:35 -0700638 final int oldState = mPowerState.getScreenState();
Jeff Brownbf4e4142014-10-02 13:08:05 -0700639 animateScreenStateChange(state, performScreenOffTransition);
640 state = mPowerState.getScreenState();
641
Jeff Brown970d4132014-07-19 11:33:47 -0700642 // Use zero brightness when screen is off.
643 if (state == Display.STATE_OFF) {
644 brightness = PowerManager.BRIGHTNESS_OFF;
645 }
646
Jeff Brown970d4132014-07-19 11:33:47 -0700647 // Configure auto-brightness.
648 boolean autoBrightnessEnabled = false;
649 if (mAutomaticBrightnessController != null) {
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700650 final boolean autoBrightnessEnabledInDoze = mAllowAutoBrightnessWhileDozingConfig
651 && (state == Display.STATE_DOZE || state == Display.STATE_DOZE_SUSPEND);
Julius D'souzabbfdf7a2016-11-03 18:43:15 -0700652 autoBrightnessEnabled = (mPowerRequest.useAutoBrightness
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700653 && (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
Julius D'souzabbfdf7a2016-11-03 18:43:15 -0700654 || mUseActiveDozeLightSensorConfig && autoBrightnessEnabledInDoze)
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700655 && brightness < 0;
Jeff Browna576b4d2015-04-23 19:58:06 -0700656 final boolean userInitiatedChange = autoBrightnessAdjustmentChanged
657 && mPowerRequest.brightnessSetByUser;
Jeff Brown970d4132014-07-19 11:33:47 -0700658 mAutomaticBrightnessController.configure(autoBrightnessEnabled,
Jeff Browna576b4d2015-04-23 19:58:06 -0700659 mPowerRequest.screenAutoBrightnessAdjustment, state != Display.STATE_ON,
Jason Monk5dbd4aa2016-02-07 13:13:39 -0500660 userInitiatedChange, mPowerRequest.useTwilight);
Jeff Brown970d4132014-07-19 11:33:47 -0700661 }
662
Jeff Brown7b5be5e2014-11-12 18:45:31 -0800663 // Apply brightness boost.
664 // We do this here after configuring auto-brightness so that we don't
665 // disable the light sensor during this temporary state. That way when
666 // boost ends we will be able to resume normal auto-brightness behavior
667 // without any delay.
668 if (mPowerRequest.boostScreenBrightness
669 && brightness != PowerManager.BRIGHTNESS_OFF) {
670 brightness = PowerManager.BRIGHTNESS_ON;
671 }
672
Jeff Brown970d4132014-07-19 11:33:47 -0700673 // Apply auto-brightness.
674 boolean slowChange = false;
675 if (brightness < 0) {
676 if (autoBrightnessEnabled) {
677 brightness = mAutomaticBrightnessController.getAutomaticScreenBrightness();
678 }
679 if (brightness >= 0) {
680 // Use current auto-brightness value and slowly adjust to changes.
681 brightness = clampScreenBrightness(brightness);
682 if (mAppliedAutoBrightness && !autoBrightnessAdjustmentChanged) {
683 slowChange = true; // slowly adapt to auto-brightness
684 }
685 mAppliedAutoBrightness = true;
Jeff Brown96307042012-07-27 15:51:34 -0700686 } else {
Jeff Brown970d4132014-07-19 11:33:47 -0700687 mAppliedAutoBrightness = false;
Jeff Brown96307042012-07-27 15:51:34 -0700688 }
689 } else {
Jeff Brown970d4132014-07-19 11:33:47 -0700690 mAppliedAutoBrightness = false;
691 }
692
Julius D'souzaa2b07dc2016-10-21 19:16:47 -0700693 // Use default brightness when dozing unless overridden or if collecting sensor samples.
694 if (state == Display.STATE_DOZE || state == Display.STATE_DOZE_SUSPEND) {
695 if (brightness < 0) {
696 brightness = mScreenBrightnessDozeConfig;
Julius D'souzabbfdf7a2016-11-03 18:43:15 -0700697 } else if (mUseActiveDozeLightSensorConfig) {
Julius D'souzaa2b07dc2016-10-21 19:16:47 -0700698 brightness = Math.min(brightness, mScreenBrightnessDozeConfig);
Julius D'souzabbfdf7a2016-11-03 18:43:15 -0700699 if (DEBUG) {
700 Slog.d(TAG, "updatePowerState: ALS-based doze brightness: " + brightness);
701 }
Julius D'souzaa2b07dc2016-10-21 19:16:47 -0700702 }
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700703 }
704
Jeff Brown970d4132014-07-19 11:33:47 -0700705 // Apply manual brightness.
706 // Use the current brightness setting from the request, which is expected
707 // provide a nominal default value for the case where auto-brightness
708 // is not ready yet.
709 if (brightness < 0) {
710 brightness = clampScreenBrightness(mPowerRequest.screenBrightness);
711 }
712
713 // Apply dimming by at least some minimum amount when user activity
Julius D'souza4fff94f2016-10-22 02:21:01 +0000714 // timeout is about to expire.
715 if (mPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
Jeff Brown5c8ea082014-07-24 19:30:31 -0700716 if (brightness > mScreenBrightnessRangeMinimum) {
717 brightness = Math.max(Math.min(brightness - SCREEN_DIM_MINIMUM_REDUCTION,
718 mScreenBrightnessDimConfig), mScreenBrightnessRangeMinimum);
719 }
Jeff Brown970d4132014-07-19 11:33:47 -0700720 if (!mAppliedDimming) {
721 slowChange = false;
722 }
723 mAppliedDimming = true;
mochangmingf0cb46c2015-12-29 13:55:24 +0800724 } else if (mAppliedDimming) {
725 slowChange = false;
726 mAppliedDimming = false;
Jeff Brown970d4132014-07-19 11:33:47 -0700727 }
728
729 // If low power mode is enabled, cut the brightness level by half
730 // as long as it is above the minimum threshold.
731 if (mPowerRequest.lowPowerMode) {
732 if (brightness > mScreenBrightnessRangeMinimum) {
733 brightness = Math.max(brightness / 2, mScreenBrightnessRangeMinimum);
734 }
735 if (!mAppliedLowPower) {
736 slowChange = false;
737 }
738 mAppliedLowPower = true;
mochangmingf0cb46c2015-12-29 13:55:24 +0800739 } else if (mAppliedLowPower) {
740 slowChange = false;
741 mAppliedLowPower = false;
Jeff Brown970d4132014-07-19 11:33:47 -0700742 }
743
Jeff Brown0a434772014-09-30 14:42:27 -0700744 // Animate the screen brightness when the screen is on or dozing.
Santos Cordond6a56602016-09-20 15:50:35 -0700745 // Skip the animation when the screen is off or suspended or transition to/from VR.
Prashant Malani33538242014-11-13 14:04:00 -0800746 if (!mPendingScreenOff) {
Santos Cordond6a56602016-09-20 15:50:35 -0700747 boolean wasOrWillBeInVr = (state == Display.STATE_VR || oldState == Display.STATE_VR);
748 if ((state == Display.STATE_ON || state == Display.STATE_DOZE) && !wasOrWillBeInVr) {
Prashant Malani33538242014-11-13 14:04:00 -0800749 animateScreenBrightness(brightness,
Julius D'souza621dc1c2016-08-05 14:34:38 -0700750 slowChange ? mBrightnessRampRateSlow : mBrightnessRampRateFast);
Prashant Malani33538242014-11-13 14:04:00 -0800751 } else {
752 animateScreenBrightness(brightness, 0);
753 }
Jeff Brown0a434772014-09-30 14:42:27 -0700754 }
755
756 // Determine whether the display is ready for use in the newly requested state.
757 // Note that we do not wait for the brightness ramp animation to complete before
758 // reporting the display is ready because we only need to ensure the screen is in the
759 // right power state even as it continues to converge on the desired brightness.
760 final boolean ready = mPendingScreenOnUnblocker == null
Michael Lentine0839adb2014-07-29 18:47:56 -0700761 && !mColorFadeOnAnimator.isStarted()
762 && !mColorFadeOffAnimator.isStarted()
Jeff Brown0a434772014-09-30 14:42:27 -0700763 && mPowerState.waitUntilClean(mCleanListener);
764 final boolean finished = ready
765 && !mScreenBrightnessRampAnimator.isAnimating();
766
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700767 // Notify policy about screen turned on.
768 if (ready && state != Display.STATE_OFF
769 && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_ON) {
770 mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_ON;
771 mWindowManagerPolicy.screenTurnedOn();
772 }
773
Jeff Brown0a434772014-09-30 14:42:27 -0700774 // Grab a wake lock if we have unfinished business.
775 if (!finished && !mUnfinishedBusiness) {
776 if (DEBUG) {
777 Slog.d(TAG, "Unfinished business...");
778 }
779 mCallbacks.acquireSuspendBlocker();
780 mUnfinishedBusiness = true;
781 }
782
783 // Notify the power manager when ready.
784 if (ready && mustNotify) {
785 // Send state change.
Jeff Brown96307042012-07-27 15:51:34 -0700786 synchronized (mLock) {
787 if (!mPendingRequestChangedLocked) {
788 mDisplayReadyLocked = true;
Jeff Brownc38c9be2012-10-04 13:16:19 -0700789
790 if (DEBUG) {
791 Slog.d(TAG, "Display ready!");
792 }
Jeff Brown96307042012-07-27 15:51:34 -0700793 }
794 }
Jeff Brownec083212013-09-11 20:45:25 -0700795 sendOnStateChangedWithWakelock();
Jeff Brown96307042012-07-27 15:51:34 -0700796 }
Jeff Brown0a434772014-09-30 14:42:27 -0700797
798 // Release the wake lock when we have no unfinished business.
799 if (finished && mUnfinishedBusiness) {
800 if (DEBUG) {
801 Slog.d(TAG, "Finished business...");
802 }
803 mUnfinishedBusiness = false;
804 mCallbacks.releaseSuspendBlocker();
805 }
Jeff Brown96307042012-07-27 15:51:34 -0700806 }
807
Michael Wright639c8be2014-01-17 18:29:12 -0800808 @Override
809 public void updateBrightness() {
810 sendUpdatePowerState();
811 }
812
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700813 private void blockScreenOn() {
Jeff Brown3ee549c2014-09-22 20:14:39 -0700814 if (mPendingScreenOnUnblocker == null) {
Jeff Brown3edf5272014-08-14 19:25:14 -0700815 Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0);
Jeff Brown3ee549c2014-09-22 20:14:39 -0700816 mPendingScreenOnUnblocker = new ScreenOnUnblocker();
Jeff Brown037c33e2014-04-09 00:31:55 -0700817 mScreenOnBlockStartRealTime = SystemClock.elapsedRealtime();
Jeff Brown3edf5272014-08-14 19:25:14 -0700818 Slog.i(TAG, "Blocking screen on until initial contents have been drawn.");
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700819 }
820 }
821
822 private void unblockScreenOn() {
Jeff Brown3ee549c2014-09-22 20:14:39 -0700823 if (mPendingScreenOnUnblocker != null) {
824 mPendingScreenOnUnblocker = null;
Jeff Brown2d8a3902014-03-11 23:02:35 -0700825 long delay = SystemClock.elapsedRealtime() - mScreenOnBlockStartRealTime;
Jeff Brown3edf5272014-08-14 19:25:14 -0700826 Slog.i(TAG, "Unblocked screen on after " + delay + " ms");
827 Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0);
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700828 }
829 }
830
Jeff Brown3ee549c2014-09-22 20:14:39 -0700831 private boolean setScreenState(int state) {
Jeff Brown037c33e2014-04-09 00:31:55 -0700832 if (mPowerState.getScreenState() != state) {
Jeff Brown3ee549c2014-09-22 20:14:39 -0700833 final boolean wasOn = (mPowerState.getScreenState() != Display.STATE_OFF);
Jeff Brown037c33e2014-04-09 00:31:55 -0700834 mPowerState.setScreenState(state);
Jeff Brown3ee549c2014-09-22 20:14:39 -0700835
836 // Tell battery stats about the transition.
Jeff Brown131206b2014-04-08 17:27:14 -0700837 try {
Jeff Browne95c3cd2014-05-02 16:59:26 -0700838 mBatteryStats.noteScreenState(state);
Jeff Brown131206b2014-04-08 17:27:14 -0700839 } catch (RemoteException ex) {
840 // same process
Jeff Brown96307042012-07-27 15:51:34 -0700841 }
842 }
Jeff Browne1633ad2015-06-22 19:24:24 -0700843
844 // Tell the window manager policy when the screen is turned off or on unless it's due
845 // to the proximity sensor. We temporarily block turning the screen on until the
846 // window manager is ready by leaving a black surface covering the screen.
847 // This surface is essentially the final state of the color fade animation and
848 // it is only removed once the window manager tells us that the activity has
849 // finished drawing underneath.
850 final boolean isOff = (state == Display.STATE_OFF);
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700851 if (isOff && mReportedScreenStateToPolicy != REPORTED_TO_POLICY_SCREEN_OFF
852 && !mScreenOffBecauseOfProximity) {
853 mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_OFF;
Jeff Browne1633ad2015-06-22 19:24:24 -0700854 unblockScreenOn();
855 mWindowManagerPolicy.screenTurnedOff();
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700856 } else if (!isOff && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF) {
857 mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_TURNING_ON;
Jeff Browne1633ad2015-06-22 19:24:24 -0700858 if (mPowerState.getColorFadeLevel() == 0.0f) {
859 blockScreenOn();
860 } else {
861 unblockScreenOn();
862 }
863 mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker);
864 }
865
866 // Return true if the screen isn't blocked.
Jeff Brown3ee549c2014-09-22 20:14:39 -0700867 return mPendingScreenOnUnblocker == null;
Jeff Brown96307042012-07-27 15:51:34 -0700868 }
869
Jeff Brown330560f2012-08-21 22:10:57 -0700870 private int clampScreenBrightness(int value) {
Michael Wright639c8be2014-01-17 18:29:12 -0800871 return MathUtils.constrain(
872 value, mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum);
Jeff Brown330560f2012-08-21 22:10:57 -0700873 }
874
Jeff Brown96307042012-07-27 15:51:34 -0700875 private void animateScreenBrightness(int target, int rate) {
Jeff Brown0a434772014-09-30 14:42:27 -0700876 if (DEBUG) {
877 Slog.d(TAG, "Animating brightness: target=" + target +", rate=" + rate);
878 }
Jeff Brown96307042012-07-27 15:51:34 -0700879 if (mScreenBrightnessRampAnimator.animateTo(target, rate)) {
Jeff Brown131206b2014-04-08 17:27:14 -0700880 try {
881 mBatteryStats.noteScreenBrightness(target);
882 } catch (RemoteException ex) {
883 // same process
884 }
Jeff Brown96307042012-07-27 15:51:34 -0700885 }
886 }
887
Jeff Brown606e4e82014-09-18 15:22:26 -0700888 private void animateScreenStateChange(int target, boolean performScreenOffTransition) {
889 // If there is already an animation in progress, don't interfere with it.
890 if (mColorFadeOnAnimator.isStarted()
891 || mColorFadeOffAnimator.isStarted()) {
Chong Zhangb131c702016-02-16 16:31:48 -0800892 if (target != Display.STATE_ON) {
893 return;
894 }
895 // If display state changed to on, proceed and stop the color fade and turn screen on.
896 mPendingScreenOff = false;
Jeff Brown606e4e82014-09-18 15:22:26 -0700897 }
898
Jeff Brown3ee549c2014-09-22 20:14:39 -0700899 // If we were in the process of turning off the screen but didn't quite
900 // finish. Then finish up now to prevent a jarring transition back
901 // to screen on if we skipped blocking screen on as usual.
902 if (mPendingScreenOff && target != Display.STATE_OFF) {
903 setScreenState(Display.STATE_OFF);
904 mPendingScreenOff = false;
Michael Lentined73854d2015-09-25 10:55:26 -0700905 mPowerState.dismissColorFadeResources();
Jeff Brown606e4e82014-09-18 15:22:26 -0700906 }
907
908 if (target == Display.STATE_ON) {
909 // Want screen on. The contents of the screen may not yet
Jeff Brown3ee549c2014-09-22 20:14:39 -0700910 // be visible if the color fade has not been dismissed because
Jeff Brown606e4e82014-09-18 15:22:26 -0700911 // its last frame of animation is solid black.
Jeff Brown3ee549c2014-09-22 20:14:39 -0700912 if (!setScreenState(Display.STATE_ON)) {
913 return; // screen on blocked
914 }
Jeff Brown606e4e82014-09-18 15:22:26 -0700915 if (USE_COLOR_FADE_ON_ANIMATION && mPowerRequest.isBrightOrDim()) {
916 // Perform screen on animation.
917 if (mPowerState.getColorFadeLevel() == 1.0f) {
918 mPowerState.dismissColorFade();
919 } else if (mPowerState.prepareColorFade(mContext,
920 mColorFadeFadesConfig ?
921 ColorFade.MODE_FADE :
922 ColorFade.MODE_WARM_UP)) {
923 mColorFadeOnAnimator.start();
924 } else {
925 mColorFadeOnAnimator.end();
926 }
927 } else {
928 // Skip screen on animation.
929 mPowerState.setColorFadeLevel(1.0f);
930 mPowerState.dismissColorFade();
931 }
Santos Cordond6a56602016-09-20 15:50:35 -0700932 } else if (target == Display.STATE_VR) {
933 // Wait for brightness animation to complete beforehand when entering VR
934 // from screen on to prevent a perceptible jump because brightness may operate
935 // differently when the display is configured for dozing.
936 if (mScreenBrightnessRampAnimator.isAnimating()
937 && mPowerState.getScreenState() == Display.STATE_ON) {
938 return;
939 }
940
941 // Set screen state.
942 if (!setScreenState(Display.STATE_VR)) {
943 return; // screen on blocked
944 }
945
946 // Dismiss the black surface without fanfare.
947 mPowerState.setColorFadeLevel(1.0f);
948 mPowerState.dismissColorFade();
Jeff Brown606e4e82014-09-18 15:22:26 -0700949 } else if (target == Display.STATE_DOZE) {
950 // Want screen dozing.
951 // Wait for brightness animation to complete beforehand when entering doze
952 // from screen on to prevent a perceptible jump because brightness may operate
953 // differently when the display is configured for dozing.
954 if (mScreenBrightnessRampAnimator.isAnimating()
955 && mPowerState.getScreenState() == Display.STATE_ON) {
956 return;
957 }
958
Jeff Brown3ee549c2014-09-22 20:14:39 -0700959 // Set screen state.
960 if (!setScreenState(Display.STATE_DOZE)) {
961 return; // screen on blocked
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 if (target == Display.STATE_DOZE_SUSPEND) {
968 // Want screen dozing and suspended.
969 // Wait for brightness animation to complete beforehand unless already
970 // suspended because we may not be able to change it after suspension.
971 if (mScreenBrightnessRampAnimator.isAnimating()
972 && mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) {
973 return;
974 }
975
Jeff Brown3ee549c2014-09-22 20:14:39 -0700976 // If not already suspending, temporarily set the state to doze until the
977 // screen on is unblocked, then suspend.
978 if (mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) {
979 if (!setScreenState(Display.STATE_DOZE)) {
980 return; // screen on blocked
981 }
982 setScreenState(Display.STATE_DOZE_SUSPEND); // already on so can't block
983 }
984
985 // Dismiss the black surface without fanfare.
Jeff Brown606e4e82014-09-18 15:22:26 -0700986 mPowerState.setColorFadeLevel(1.0f);
987 mPowerState.dismissColorFade();
988 } else {
989 // Want screen off.
Jeff Brown3ee549c2014-09-22 20:14:39 -0700990 mPendingScreenOff = true;
Jeff Brown606e4e82014-09-18 15:22:26 -0700991 if (mPowerState.getColorFadeLevel() == 0.0f) {
992 // Turn the screen off.
993 // A black surface is already hiding the contents of the screen.
994 setScreenState(Display.STATE_OFF);
Jeff Brown3ee549c2014-09-22 20:14:39 -0700995 mPendingScreenOff = false;
Michael Lentined73854d2015-09-25 10:55:26 -0700996 mPowerState.dismissColorFadeResources();
Jeff Brown606e4e82014-09-18 15:22:26 -0700997 } else if (performScreenOffTransition
998 && mPowerState.prepareColorFade(mContext,
999 mColorFadeFadesConfig ?
1000 ColorFade.MODE_FADE : ColorFade.MODE_COOL_DOWN)
1001 && mPowerState.getScreenState() != Display.STATE_OFF) {
1002 // Perform the screen off animation.
1003 mColorFadeOffAnimator.start();
1004 } else {
1005 // Skip the screen off animation and add a black surface to hide the
1006 // contents of the screen.
1007 mColorFadeOffAnimator.end();
1008 }
1009 }
1010 }
1011
Jeff Brown96307042012-07-27 15:51:34 -07001012 private final Runnable mCleanListener = new Runnable() {
1013 @Override
1014 public void run() {
1015 sendUpdatePowerState();
1016 }
1017 };
1018
1019 private void setProximitySensorEnabled(boolean enable) {
1020 if (enable) {
1021 if (!mProximitySensorEnabled) {
Jeff Brownec083212013-09-11 20:45:25 -07001022 // Register the listener.
1023 // Proximity sensor state already cleared initially.
Jeff Brown96307042012-07-27 15:51:34 -07001024 mProximitySensorEnabled = true;
Jeff Brown96307042012-07-27 15:51:34 -07001025 mSensorManager.registerListener(mProximitySensorListener, mProximitySensor,
1026 SensorManager.SENSOR_DELAY_NORMAL, mHandler);
1027 }
1028 } else {
1029 if (mProximitySensorEnabled) {
Jeff Brownec083212013-09-11 20:45:25 -07001030 // Unregister the listener.
1031 // Clear the proximity sensor state for next time.
Jeff Brown96307042012-07-27 15:51:34 -07001032 mProximitySensorEnabled = false;
1033 mProximity = PROXIMITY_UNKNOWN;
Jeff Brownec083212013-09-11 20:45:25 -07001034 mPendingProximity = PROXIMITY_UNKNOWN;
Jeff Brown96307042012-07-27 15:51:34 -07001035 mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
1036 mSensorManager.unregisterListener(mProximitySensorListener);
Jeff Brownec083212013-09-11 20:45:25 -07001037 clearPendingProximityDebounceTime(); // release wake lock (must be last)
Jeff Brown96307042012-07-27 15:51:34 -07001038 }
1039 }
1040 }
1041
1042 private void handleProximitySensorEvent(long time, boolean positive) {
Jeff Brownec083212013-09-11 20:45:25 -07001043 if (mProximitySensorEnabled) {
1044 if (mPendingProximity == PROXIMITY_NEGATIVE && !positive) {
1045 return; // no change
1046 }
1047 if (mPendingProximity == PROXIMITY_POSITIVE && positive) {
1048 return; // no change
1049 }
Jeff Brown96307042012-07-27 15:51:34 -07001050
Jeff Brownec083212013-09-11 20:45:25 -07001051 // Only accept a proximity sensor reading if it remains
1052 // stable for the entire debounce delay. We hold a wake lock while
1053 // debouncing the sensor.
1054 mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
1055 if (positive) {
1056 mPendingProximity = PROXIMITY_POSITIVE;
1057 setPendingProximityDebounceTime(
1058 time + PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY); // acquire wake lock
1059 } else {
1060 mPendingProximity = PROXIMITY_NEGATIVE;
1061 setPendingProximityDebounceTime(
1062 time + PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY); // acquire wake lock
1063 }
1064
1065 // Debounce the new sensor reading.
1066 debounceProximitySensor();
Jeff Brown93cbbb22012-10-04 13:18:36 -07001067 }
Jeff Brown96307042012-07-27 15:51:34 -07001068 }
1069
1070 private void debounceProximitySensor() {
Jeff Brownec083212013-09-11 20:45:25 -07001071 if (mProximitySensorEnabled
1072 && mPendingProximity != PROXIMITY_UNKNOWN
1073 && mPendingProximityDebounceTime >= 0) {
Jeff Brown96307042012-07-27 15:51:34 -07001074 final long now = SystemClock.uptimeMillis();
1075 if (mPendingProximityDebounceTime <= now) {
Jeff Brownec083212013-09-11 20:45:25 -07001076 // Sensor reading accepted. Apply the change then release the wake lock.
Jeff Brown96307042012-07-27 15:51:34 -07001077 mProximity = mPendingProximity;
Jeff Brownec083212013-09-11 20:45:25 -07001078 updatePowerState();
1079 clearPendingProximityDebounceTime(); // release wake lock (must be last)
Jeff Brown96307042012-07-27 15:51:34 -07001080 } else {
Jeff Brownec083212013-09-11 20:45:25 -07001081 // Need to wait a little longer.
1082 // Debounce again later. We continue holding a wake lock while waiting.
Jeff Brown96307042012-07-27 15:51:34 -07001083 Message msg = mHandler.obtainMessage(MSG_PROXIMITY_SENSOR_DEBOUNCED);
1084 msg.setAsynchronous(true);
1085 mHandler.sendMessageAtTime(msg, mPendingProximityDebounceTime);
1086 }
1087 }
1088 }
1089
Jeff Brownec083212013-09-11 20:45:25 -07001090 private void clearPendingProximityDebounceTime() {
1091 if (mPendingProximityDebounceTime >= 0) {
1092 mPendingProximityDebounceTime = -1;
Jeff Brown131206b2014-04-08 17:27:14 -07001093 mCallbacks.releaseSuspendBlocker(); // release wake lock
Jeff Brownec083212013-09-11 20:45:25 -07001094 }
1095 }
1096
1097 private void setPendingProximityDebounceTime(long debounceTime) {
1098 if (mPendingProximityDebounceTime < 0) {
Jeff Brown131206b2014-04-08 17:27:14 -07001099 mCallbacks.acquireSuspendBlocker(); // acquire wake lock
Jeff Brownec083212013-09-11 20:45:25 -07001100 }
1101 mPendingProximityDebounceTime = debounceTime;
1102 }
1103
Jeff Brownec083212013-09-11 20:45:25 -07001104 private void sendOnStateChangedWithWakelock() {
Jeff Brown131206b2014-04-08 17:27:14 -07001105 mCallbacks.acquireSuspendBlocker();
1106 mHandler.post(mOnStateChangedRunnable);
Jeff Brown96307042012-07-27 15:51:34 -07001107 }
1108
1109 private final Runnable mOnStateChangedRunnable = new Runnable() {
1110 @Override
1111 public void run() {
1112 mCallbacks.onStateChanged();
Jeff Brown131206b2014-04-08 17:27:14 -07001113 mCallbacks.releaseSuspendBlocker();
Jeff Brown96307042012-07-27 15:51:34 -07001114 }
1115 };
1116
Jeff Brownec083212013-09-11 20:45:25 -07001117 private void sendOnProximityPositiveWithWakelock() {
Jeff Brown131206b2014-04-08 17:27:14 -07001118 mCallbacks.acquireSuspendBlocker();
1119 mHandler.post(mOnProximityPositiveRunnable);
Jeff Brown93cbbb22012-10-04 13:18:36 -07001120 }
1121
1122 private final Runnable mOnProximityPositiveRunnable = new Runnable() {
1123 @Override
1124 public void run() {
1125 mCallbacks.onProximityPositive();
Jeff Brown131206b2014-04-08 17:27:14 -07001126 mCallbacks.releaseSuspendBlocker();
Jeff Brown93cbbb22012-10-04 13:18:36 -07001127 }
1128 };
1129
Jeff Brownec083212013-09-11 20:45:25 -07001130 private void sendOnProximityNegativeWithWakelock() {
Jeff Brown131206b2014-04-08 17:27:14 -07001131 mCallbacks.acquireSuspendBlocker();
1132 mHandler.post(mOnProximityNegativeRunnable);
Jeff Brown96307042012-07-27 15:51:34 -07001133 }
1134
1135 private final Runnable mOnProximityNegativeRunnable = new Runnable() {
1136 @Override
1137 public void run() {
1138 mCallbacks.onProximityNegative();
Jeff Brown131206b2014-04-08 17:27:14 -07001139 mCallbacks.releaseSuspendBlocker();
Jeff Brown96307042012-07-27 15:51:34 -07001140 }
1141 };
1142
Jeff Brownbd6e1502012-08-28 03:27:37 -07001143 public void dump(final PrintWriter pw) {
Jeff Brown96307042012-07-27 15:51:34 -07001144 synchronized (mLock) {
1145 pw.println();
Jeff Brown131206b2014-04-08 17:27:14 -07001146 pw.println("Display Power Controller Locked State:");
Jeff Brown96307042012-07-27 15:51:34 -07001147 pw.println(" mDisplayReadyLocked=" + mDisplayReadyLocked);
1148 pw.println(" mPendingRequestLocked=" + mPendingRequestLocked);
1149 pw.println(" mPendingRequestChangedLocked=" + mPendingRequestChangedLocked);
1150 pw.println(" mPendingWaitForNegativeProximityLocked="
1151 + mPendingWaitForNegativeProximityLocked);
1152 pw.println(" mPendingUpdatePowerStateLocked=" + mPendingUpdatePowerStateLocked);
1153 }
1154
1155 pw.println();
Jeff Brown131206b2014-04-08 17:27:14 -07001156 pw.println("Display Power Controller Configuration:");
Jeff Brown26875502014-01-30 21:47:47 -08001157 pw.println(" mScreenBrightnessDozeConfig=" + mScreenBrightnessDozeConfig);
Jeff Brown96307042012-07-27 15:51:34 -07001158 pw.println(" mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig);
Jeff Brown1bfd0f42014-08-22 01:59:06 -07001159 pw.println(" mScreenBrightnessDarkConfig=" + mScreenBrightnessDarkConfig);
Jeff Brownb76eebff2012-10-05 22:26:44 -07001160 pw.println(" mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum);
1161 pw.println(" mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum);
Jeff Brown2175e9c2014-09-12 16:11:07 -07001162 pw.println(" mUseSoftwareAutoBrightnessConfig=" + mUseSoftwareAutoBrightnessConfig);
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -07001163 pw.println(" mAllowAutoBrightnessWhileDozingConfig=" +
1164 mAllowAutoBrightnessWhileDozingConfig);
Jeff Brown2175e9c2014-09-12 16:11:07 -07001165 pw.println(" mColorFadeFadesConfig=" + mColorFadeFadesConfig);
Jeff Brown96307042012-07-27 15:51:34 -07001166
Jeff Brownbd6e1502012-08-28 03:27:37 -07001167 mHandler.runWithScissors(new Runnable() {
1168 @Override
1169 public void run() {
1170 dumpLocal(pw);
Jeff Brown96307042012-07-27 15:51:34 -07001171 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001172 }, 1000);
Jeff Brown96307042012-07-27 15:51:34 -07001173 }
1174
1175 private void dumpLocal(PrintWriter pw) {
1176 pw.println();
Jeff Brown131206b2014-04-08 17:27:14 -07001177 pw.println("Display Power Controller Thread State:");
Jeff Brown96307042012-07-27 15:51:34 -07001178 pw.println(" mPowerRequest=" + mPowerRequest);
1179 pw.println(" mWaitingForNegativeProximity=" + mWaitingForNegativeProximity);
1180
1181 pw.println(" mProximitySensor=" + mProximitySensor);
1182 pw.println(" mProximitySensorEnabled=" + mProximitySensorEnabled);
1183 pw.println(" mProximityThreshold=" + mProximityThreshold);
1184 pw.println(" mProximity=" + proximityToString(mProximity));
1185 pw.println(" mPendingProximity=" + proximityToString(mPendingProximity));
1186 pw.println(" mPendingProximityDebounceTime="
1187 + TimeUtils.formatUptime(mPendingProximityDebounceTime));
1188 pw.println(" mScreenOffBecauseOfProximity=" + mScreenOffBecauseOfProximity);
Jeff Brown970d4132014-07-19 11:33:47 -07001189 pw.println(" mAppliedAutoBrightness=" + mAppliedAutoBrightness);
1190 pw.println(" mAppliedDimming=" + mAppliedDimming);
1191 pw.println(" mAppliedLowPower=" + mAppliedLowPower);
Jeff Brown3ee549c2014-09-22 20:14:39 -07001192 pw.println(" mPendingScreenOnUnblocker=" + mPendingScreenOnUnblocker);
1193 pw.println(" mPendingScreenOff=" + mPendingScreenOff);
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001194 pw.println(" mReportedToPolicy=" + reportedToPolicyToString(mReportedScreenStateToPolicy));
Jeff Brown96307042012-07-27 15:51:34 -07001195
Jeff Brown42558692014-05-20 22:02:46 -07001196 pw.println(" mScreenBrightnessRampAnimator.isAnimating()=" +
1197 mScreenBrightnessRampAnimator.isAnimating());
1198
Michael Lentine0839adb2014-07-29 18:47:56 -07001199 if (mColorFadeOnAnimator != null) {
1200 pw.println(" mColorFadeOnAnimator.isStarted()=" +
1201 mColorFadeOnAnimator.isStarted());
Jeff Brown96307042012-07-27 15:51:34 -07001202 }
Michael Lentine0839adb2014-07-29 18:47:56 -07001203 if (mColorFadeOffAnimator != null) {
1204 pw.println(" mColorFadeOffAnimator.isStarted()=" +
1205 mColorFadeOffAnimator.isStarted());
Jeff Brown96307042012-07-27 15:51:34 -07001206 }
1207
1208 if (mPowerState != null) {
1209 mPowerState.dump(pw);
1210 }
Michael Wright639c8be2014-01-17 18:29:12 -08001211
1212 if (mAutomaticBrightnessController != null) {
1213 mAutomaticBrightnessController.dump(pw);
1214 }
1215
Jeff Brown96307042012-07-27 15:51:34 -07001216 }
1217
1218 private static String proximityToString(int state) {
1219 switch (state) {
1220 case PROXIMITY_UNKNOWN:
1221 return "Unknown";
1222 case PROXIMITY_NEGATIVE:
1223 return "Negative";
1224 case PROXIMITY_POSITIVE:
1225 return "Positive";
1226 default:
1227 return Integer.toString(state);
1228 }
1229 }
1230
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001231 private static String reportedToPolicyToString(int state) {
1232 switch (state) {
1233 case REPORTED_TO_POLICY_SCREEN_OFF:
1234 return "REPORTED_TO_POLICY_SCREEN_OFF";
1235 case REPORTED_TO_POLICY_SCREEN_TURNING_ON:
1236 return "REPORTED_TO_POLICY_SCREEN_TURNING_ON";
1237 case REPORTED_TO_POLICY_SCREEN_ON:
1238 return "REPORTED_TO_POLICY_SCREEN_ON";
1239 default:
1240 return Integer.toString(state);
1241 }
1242 }
1243
Michael Wright639c8be2014-01-17 18:29:12 -08001244 private static Spline createAutoBrightnessSpline(int[] lux, int[] brightness) {
Erik Wolsheimerad82aca2016-06-28 14:51:07 -07001245 if (lux == null || lux.length == 0 || brightness == null || brightness.length == 0) {
1246 Slog.e(TAG, "Could not create auto-brightness spline.");
1247 return null;
1248 }
Michael Wright639c8be2014-01-17 18:29:12 -08001249 try {
1250 final int n = brightness.length;
1251 float[] x = new float[n];
1252 float[] y = new float[n];
1253 y[0] = normalizeAbsoluteBrightness(brightness[0]);
1254 for (int i = 1; i < n; i++) {
1255 x[i] = lux[i - 1];
1256 y[i] = normalizeAbsoluteBrightness(brightness[i]);
1257 }
1258
Michael Wright3e9a1342014-08-28 17:42:16 -07001259 Spline spline = Spline.createSpline(x, y);
Michael Wright639c8be2014-01-17 18:29:12 -08001260 if (DEBUG) {
1261 Slog.d(TAG, "Auto-brightness spline: " + spline);
1262 for (float v = 1f; v < lux[lux.length - 1] * 1.25f; v *= 1.25f) {
1263 Slog.d(TAG, String.format(" %7.1f: %7.1f", v, spline.interpolate(v)));
1264 }
1265 }
1266 return spline;
1267 } catch (IllegalArgumentException ex) {
1268 Slog.e(TAG, "Could not create auto-brightness spline.", ex);
1269 return null;
Jeff Brown96307042012-07-27 15:51:34 -07001270 }
Michael Wright639c8be2014-01-17 18:29:12 -08001271 }
1272
1273 private static float normalizeAbsoluteBrightness(int value) {
1274 return (float)clampAbsoluteBrightness(value) / PowerManager.BRIGHTNESS_ON;
1275 }
1276
1277 private static int clampAbsoluteBrightness(int value) {
1278 return MathUtils.constrain(value, PowerManager.BRIGHTNESS_OFF, PowerManager.BRIGHTNESS_ON);
Jeff Brown96307042012-07-27 15:51:34 -07001279 }
1280
Jeff Brown96307042012-07-27 15:51:34 -07001281 private final class DisplayControllerHandler extends Handler {
1282 public DisplayControllerHandler(Looper looper) {
Jeff Browna2910d02012-08-25 12:29:46 -07001283 super(looper, null, true /*async*/);
Jeff Brown96307042012-07-27 15:51:34 -07001284 }
1285
1286 @Override
1287 public void handleMessage(Message msg) {
1288 switch (msg.what) {
1289 case MSG_UPDATE_POWER_STATE:
1290 updatePowerState();
1291 break;
1292
1293 case MSG_PROXIMITY_SENSOR_DEBOUNCED:
1294 debounceProximitySensor();
1295 break;
Jeff Brown3ee549c2014-09-22 20:14:39 -07001296
1297 case MSG_SCREEN_ON_UNBLOCKED:
1298 if (mPendingScreenOnUnblocker == msg.obj) {
1299 unblockScreenOn();
1300 updatePowerState();
1301 }
1302 break;
Jeff Brown96307042012-07-27 15:51:34 -07001303 }
1304 }
1305 }
1306
1307 private final SensorEventListener mProximitySensorListener = new SensorEventListener() {
1308 @Override
1309 public void onSensorChanged(SensorEvent event) {
1310 if (mProximitySensorEnabled) {
1311 final long time = SystemClock.uptimeMillis();
1312 final float distance = event.values[0];
1313 boolean positive = distance >= 0.0f && distance < mProximityThreshold;
1314 handleProximitySensorEvent(time, positive);
1315 }
1316 }
1317
1318 @Override
1319 public void onAccuracyChanged(Sensor sensor, int accuracy) {
1320 // Not used.
1321 }
1322 };
Jeff Brown3ee549c2014-09-22 20:14:39 -07001323
1324 private final class ScreenOnUnblocker implements WindowManagerPolicy.ScreenOnListener {
1325 @Override
1326 public void onScreenOn() {
1327 Message msg = mHandler.obtainMessage(MSG_SCREEN_ON_UNBLOCKED, this);
1328 msg.setAsynchronous(true);
1329 mHandler.sendMessage(msg);
1330 }
1331 }
Jeff Brown96307042012-07-27 15:51:34 -07001332}