blob: 6e6e7d112d83e34028cfa1c8c10be1a905916cf1 [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";
Jorim Jaggi51304d72017-05-17 17:25:32 +020074 private static final String SCREEN_OFF_BLOCKED_TRACE_NAME = "Screen off blocked";
Jeff Brown96307042012-07-27 15:51:34 -070075
Julius D'souza428aed02016-08-07 19:08:30 -070076 private static final boolean DEBUG = false;
Jeff Brown96307042012-07-27 15:51:34 -070077 private static final boolean DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT = false;
Jeff Brown96307042012-07-27 15:51:34 -070078
Jeff Brown3ee549c2014-09-22 20:14:39 -070079 // If true, uses the color fade on animation.
Jeff Brown13c589b2012-08-16 16:20:54 -070080 // We might want to turn this off if we cannot get a guarantee that the screen
81 // actually turns on and starts showing new content after the call to set the
Jeff Brown5356c7dc2012-08-20 20:17:36 -070082 // screen state returns. Playing the animation can also be somewhat slow.
Michael Lentine0839adb2014-07-29 18:47:56 -070083 private static final boolean USE_COLOR_FADE_ON_ANIMATION = false;
Jeff Brown13c589b2012-08-16 16:20:54 -070084
Jeff Brownb76eebff2012-10-05 22:26:44 -070085 // The minimum reduction in brightness when dimmed.
86 private static final int SCREEN_DIM_MINIMUM_REDUCTION = 10;
87
Michael Lentine0839adb2014-07-29 18:47:56 -070088 private static final int COLOR_FADE_ON_ANIMATION_DURATION_MILLIS = 250;
Michael Lentine0c9a62d2014-08-20 09:19:07 -070089 private static final int COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS = 400;
Jeff Brown96307042012-07-27 15:51:34 -070090
91 private static final int MSG_UPDATE_POWER_STATE = 1;
92 private static final int MSG_PROXIMITY_SENSOR_DEBOUNCED = 2;
Jeff Brown3ee549c2014-09-22 20:14:39 -070093 private static final int MSG_SCREEN_ON_UNBLOCKED = 3;
Jorim Jaggi51304d72017-05-17 17:25:32 +020094 private static final int MSG_SCREEN_OFF_UNBLOCKED = 4;
Jeff Brown96307042012-07-27 15:51:34 -070095
96 private static final int PROXIMITY_UNKNOWN = -1;
97 private static final int PROXIMITY_NEGATIVE = 0;
98 private static final int PROXIMITY_POSITIVE = 1;
99
Jeff Brown93cbbb22012-10-04 13:18:36 -0700100 // Proximity sensor debounce delay in milliseconds for positive or negative transitions.
101 private static final int PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY = 0;
Jeff Brownec083212013-09-11 20:45:25 -0700102 private static final int PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY = 250;
Jeff Brown96307042012-07-27 15:51:34 -0700103
104 // Trigger proximity if distance is less than 5 cm.
105 private static final float TYPICAL_PROXIMITY_THRESHOLD = 5.0f;
106
Julius D'souzad5105dd2017-06-02 11:03:53 -0700107 // State machine constants for tracking initial brightness ramp skipping when enabled.
108 private static final int RAMP_STATE_SKIP_NONE = 0;
109 private static final int RAMP_STATE_SKIP_INITIAL = 1;
110 private static final int RAMP_STATE_SKIP_AUTOBRIGHT = 2;
111
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700112 private static final int REPORTED_TO_POLICY_SCREEN_OFF = 0;
113 private static final int REPORTED_TO_POLICY_SCREEN_TURNING_ON = 1;
114 private static final int REPORTED_TO_POLICY_SCREEN_ON = 2;
Jorim Jaggi51304d72017-05-17 17:25:32 +0200115 private static final int REPORTED_TO_POLICY_SCREEN_TURNING_OFF = 3;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700116
Jeff Brown96307042012-07-27 15:51:34 -0700117 private final Object mLock = new Object();
118
Michael Lentine0839adb2014-07-29 18:47:56 -0700119 private final Context mContext;
120
Jeff Brown96307042012-07-27 15:51:34 -0700121 // Our handler.
122 private final DisplayControllerHandler mHandler;
123
124 // Asynchronous callbacks into the power manager service.
125 // Only invoked from the handler thread while no locks are held.
Jeff Brown131206b2014-04-08 17:27:14 -0700126 private final DisplayPowerCallbacks mCallbacks;
127
128 // Battery stats.
129 private final IBatteryStats mBatteryStats;
Jeff Brown96307042012-07-27 15:51:34 -0700130
Jeff Brown96307042012-07-27 15:51:34 -0700131 // The sensor manager.
132 private final SensorManager mSensorManager;
133
Jeff Brown3ee549c2014-09-22 20:14:39 -0700134 // The window manager policy.
135 private final WindowManagerPolicy mWindowManagerPolicy;
136
Jeff Brown037c33e2014-04-09 00:31:55 -0700137 // The display blanker.
138 private final DisplayBlanker mBlanker;
139
Jeff Brown96307042012-07-27 15:51:34 -0700140 // The proximity sensor, or null if not available or needed.
141 private Sensor mProximitySensor;
142
Jeff Brown26875502014-01-30 21:47:47 -0800143 // The doze screen brightness.
144 private final int mScreenBrightnessDozeConfig;
145
Jeff Brown96307042012-07-27 15:51:34 -0700146 // The dim screen brightness.
147 private final int mScreenBrightnessDimConfig;
148
Jeff Brown1bfd0f42014-08-22 01:59:06 -0700149 // The minimum screen brightness to use in a very dark room.
150 private final int mScreenBrightnessDarkConfig;
151
Jeff Brownb76eebff2012-10-05 22:26:44 -0700152 // The minimum allowed brightness.
153 private final int mScreenBrightnessRangeMinimum;
154
155 // The maximum allowed brightness.
156 private final int mScreenBrightnessRangeMaximum;
157
Jeff Brown330560f2012-08-21 22:10:57 -0700158 // True if auto-brightness should be used.
Jeff Brown96307042012-07-27 15:51:34 -0700159 private boolean mUseSoftwareAutoBrightnessConfig;
Jeff Brown330560f2012-08-21 22:10:57 -0700160
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700161 // True if should use light sensor to automatically determine doze screen brightness.
162 private final boolean mAllowAutoBrightnessWhileDozingConfig;
163
Jeff Brown252c2062012-10-08 16:21:01 -0700164 // True if we should fade the screen while turning it off, false if we should play
Jeff Brown3ee549c2014-09-22 20:14:39 -0700165 // a stylish color fade animation instead.
Michael Lentine0839adb2014-07-29 18:47:56 -0700166 private boolean mColorFadeFadesConfig;
Jeff Browna52772f2012-10-04 18:38:09 -0700167
Michael Wright410fd1b2017-07-25 22:31:03 +0100168 // True if we need to fake a transition to off when coming out of a doze state.
169 // Some display hardware will blank itself when coming out of doze in order to hide
170 // artifacts. For these displays we fake a transition into OFF so that policy can appropriately
171 // blank itself and begin an appropriate power on animation.
172 private boolean mDisplayBlanksAfterDozeConfig;
Michael Wright05e76fe2017-07-20 18:18:33 +0100173
Michael Wright65d3e702017-07-26 01:10:59 +0100174 // True if there are only buckets of brightness values when the display is in the doze state,
175 // rather than a full range of values. If this is true, then we'll avoid animating the screen
176 // brightness since it'd likely be multiple jarring brightness transitions instead of just one
177 // to reach the final state.
178 private boolean mBrightnessBucketsInDozeConfig;
179
Jeff Brown96307042012-07-27 15:51:34 -0700180 // The pending power request.
181 // Initially null until the first call to requestPowerState.
182 // Guarded by mLock.
183 private DisplayPowerRequest mPendingRequestLocked;
184
185 // True if a request has been made to wait for the proximity sensor to go negative.
186 // Guarded by mLock.
187 private boolean mPendingWaitForNegativeProximityLocked;
188
189 // True if the pending power request or wait for negative proximity flag
190 // has been changed since the last update occurred.
191 // Guarded by mLock.
192 private boolean mPendingRequestChangedLocked;
193
194 // Set to true when the important parts of the pending power request have been applied.
195 // The important parts are mainly the screen state. Brightness changes may occur
196 // concurrently.
197 // Guarded by mLock.
198 private boolean mDisplayReadyLocked;
199
200 // Set to true if a power state update is required.
201 // Guarded by mLock.
202 private boolean mPendingUpdatePowerStateLocked;
203
204 /* The following state must only be accessed by the handler thread. */
205
206 // The currently requested power state.
207 // The power controller will progressively update its internal state to match
208 // the requested power state. Initially null until the first update.
209 private DisplayPowerRequest mPowerRequest;
210
211 // The current power state.
212 // Must only be accessed on the handler thread.
213 private DisplayPowerState mPowerState;
214
215 // True if the device should wait for negative proximity sensor before
216 // waking up the screen. This is set to false as soon as a negative
217 // proximity sensor measurement is observed or when the device is forced to
218 // go to sleep by the user. While true, the screen remains off.
219 private boolean mWaitingForNegativeProximity;
220
221 // The actual proximity sensor threshold value.
222 private float mProximityThreshold;
223
224 // Set to true if the proximity sensor listener has been registered
225 // with the sensor manager.
226 private boolean mProximitySensorEnabled;
227
228 // The debounced proximity sensor state.
229 private int mProximity = PROXIMITY_UNKNOWN;
230
231 // The raw non-debounced proximity sensor state.
232 private int mPendingProximity = PROXIMITY_UNKNOWN;
Jeff Brownec083212013-09-11 20:45:25 -0700233 private long mPendingProximityDebounceTime = -1; // -1 if fully debounced
Jeff Brown96307042012-07-27 15:51:34 -0700234
235 // True if the screen was turned off because of the proximity sensor.
236 // When the screen turns on again, we report user activity to the power manager.
237 private boolean mScreenOffBecauseOfProximity;
238
Jeff Brown3ee549c2014-09-22 20:14:39 -0700239 // The currently active screen on unblocker. This field is non-null whenever
240 // we are waiting for a callback to release it and unblock the screen.
241 private ScreenOnUnblocker mPendingScreenOnUnblocker;
Jorim Jaggi51304d72017-05-17 17:25:32 +0200242 private ScreenOffUnblocker mPendingScreenOffUnblocker;
Jeff Brown3ee549c2014-09-22 20:14:39 -0700243
244 // True if we were in the process of turning off the screen.
245 // This allows us to recover more gracefully from situations where we abort
246 // turning off the screen.
247 private boolean mPendingScreenOff;
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700248
Jeff Brown0a434772014-09-30 14:42:27 -0700249 // True if we have unfinished business and are holding a suspend blocker.
250 private boolean mUnfinishedBusiness;
251
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700252 // The elapsed real time when the screen on was blocked.
253 private long mScreenOnBlockStartRealTime;
Jorim Jaggi51304d72017-05-17 17:25:32 +0200254 private long mScreenOffBlockStartRealTime;
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700255
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700256 // Screen state we reported to policy. Must be one of REPORTED_TO_POLICY_SCREEN_* fields.
257 private int mReportedScreenStateToPolicy;
Jeff Browne1633ad2015-06-22 19:24:24 -0700258
Julius D'souzad5105dd2017-06-02 11:03:53 -0700259 // If the last recorded screen state was dozing or not.
260 private boolean mDozing;
261
Jeff Brown970d4132014-07-19 11:33:47 -0700262 // Remembers whether certain kinds of brightness adjustments
263 // were recently applied so that we can decide how to transition.
264 private boolean mAppliedAutoBrightness;
265 private boolean mAppliedDimming;
266 private boolean mAppliedLowPower;
Jeff Brown96307042012-07-27 15:51:34 -0700267
Julius D'souzafeadad12016-08-05 14:34:38 -0700268 // Brightness animation ramp rates in brightness units per second
Prashant Malani99e6d432016-03-29 16:32:37 -0700269 private final int mBrightnessRampRateFast;
Julius D'souzafeadad12016-08-05 14:34:38 -0700270 private final int mBrightnessRampRateSlow;
Prashant Malani99e6d432016-03-29 16:32:37 -0700271
Julius D'souzad5105dd2017-06-02 11:03:53 -0700272 // Whether or not to skip the initial brightness ramps into STATE_ON.
273 private final boolean mSkipScreenOnBrightnessRamp;
274
275 // A record of state for skipping brightness ramps.
276 private int mSkipRampState = RAMP_STATE_SKIP_NONE;
277
278 // The first autobrightness value set when entering RAMP_STATE_SKIP_INITIAL.
279 private int mInitialAutoBrightness;
280
Michael Wright639c8be2014-01-17 18:29:12 -0800281 // The controller for the automatic brightness level.
282 private AutomaticBrightnessController mAutomaticBrightnessController;
283
Jeff Brown96307042012-07-27 15:51:34 -0700284 // Animators.
Michael Lentine0839adb2014-07-29 18:47:56 -0700285 private ObjectAnimator mColorFadeOnAnimator;
286 private ObjectAnimator mColorFadeOffAnimator;
Jeff Brown96307042012-07-27 15:51:34 -0700287 private RampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator;
288
289 /**
290 * Creates the display power controller.
291 */
Jeff Brown131206b2014-04-08 17:27:14 -0700292 public DisplayPowerController(Context context,
Jeff Brown037c33e2014-04-09 00:31:55 -0700293 DisplayPowerCallbacks callbacks, Handler handler,
294 SensorManager sensorManager, DisplayBlanker blanker) {
Jeff Brown131206b2014-04-08 17:27:14 -0700295 mHandler = new DisplayControllerHandler(handler.getLooper());
Jeff Brown96307042012-07-27 15:51:34 -0700296 mCallbacks = callbacks;
Jeff Brown96307042012-07-27 15:51:34 -0700297
Jeff Brown131206b2014-04-08 17:27:14 -0700298 mBatteryStats = BatteryStatsService.getService();
Jeff Brown3b971592013-01-09 18:46:37 -0800299 mSensorManager = sensorManager;
Jeff Brown3ee549c2014-09-22 20:14:39 -0700300 mWindowManagerPolicy = LocalServices.getService(WindowManagerPolicy.class);
Jeff Brown037c33e2014-04-09 00:31:55 -0700301 mBlanker = blanker;
Michael Lentine0839adb2014-07-29 18:47:56 -0700302 mContext = context;
Jeff Brown96307042012-07-27 15:51:34 -0700303
304 final Resources resources = context.getResources();
Jeff Brown1bfd0f42014-08-22 01:59:06 -0700305 final int screenBrightnessSettingMinimum = clampAbsoluteBrightness(resources.getInteger(
306 com.android.internal.R.integer.config_screenBrightnessSettingMinimum));
Jeff Brownb76eebff2012-10-05 22:26:44 -0700307
Jeff Brown26875502014-01-30 21:47:47 -0800308 mScreenBrightnessDozeConfig = clampAbsoluteBrightness(resources.getInteger(
309 com.android.internal.R.integer.config_screenBrightnessDoze));
310
Jeff Brownb76eebff2012-10-05 22:26:44 -0700311 mScreenBrightnessDimConfig = clampAbsoluteBrightness(resources.getInteger(
312 com.android.internal.R.integer.config_screenBrightnessDim));
313
Jeff Brown1bfd0f42014-08-22 01:59:06 -0700314 mScreenBrightnessDarkConfig = clampAbsoluteBrightness(resources.getInteger(
315 com.android.internal.R.integer.config_screenBrightnessDark));
316 if (mScreenBrightnessDarkConfig > mScreenBrightnessDimConfig) {
317 Slog.w(TAG, "Expected config_screenBrightnessDark ("
318 + mScreenBrightnessDarkConfig + ") to be less than or equal to "
319 + "config_screenBrightnessDim (" + mScreenBrightnessDimConfig + ").");
320 }
liulvpingd01db542016-10-20 19:51:38 +0800321 if (mScreenBrightnessDarkConfig > screenBrightnessSettingMinimum) {
Jeff Brown1bfd0f42014-08-22 01:59:06 -0700322 Slog.w(TAG, "Expected config_screenBrightnessDark ("
323 + mScreenBrightnessDarkConfig + ") to be less than or equal to "
324 + "config_screenBrightnessSettingMinimum ("
325 + screenBrightnessSettingMinimum + ").");
326 }
327
328 int screenBrightnessRangeMinimum = Math.min(Math.min(
329 screenBrightnessSettingMinimum, mScreenBrightnessDimConfig),
330 mScreenBrightnessDarkConfig);
Michael Wright639c8be2014-01-17 18:29:12 -0800331
332 mScreenBrightnessRangeMaximum = PowerManager.BRIGHTNESS_ON;
Jeff Brownb76eebff2012-10-05 22:26:44 -0700333
Jeff Brown96307042012-07-27 15:51:34 -0700334 mUseSoftwareAutoBrightnessConfig = resources.getBoolean(
335 com.android.internal.R.bool.config_automatic_brightness_available);
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700336
337 mAllowAutoBrightnessWhileDozingConfig = resources.getBoolean(
338 com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing);
339
Prashant Malani99e6d432016-03-29 16:32:37 -0700340 mBrightnessRampRateFast = resources.getInteger(
341 com.android.internal.R.integer.config_brightness_ramp_rate_fast);
Julius D'souzafeadad12016-08-05 14:34:38 -0700342 mBrightnessRampRateSlow = resources.getInteger(
343 com.android.internal.R.integer.config_brightness_ramp_rate_slow);
Julius D'souzad5105dd2017-06-02 11:03:53 -0700344 mSkipScreenOnBrightnessRamp = resources.getBoolean(
345 com.android.internal.R.bool.config_skipScreenOnBrightnessRamp);
Prashant Malani99e6d432016-03-29 16:32:37 -0700346
Filip Gruszczynskid81ecd12015-02-06 12:38:47 -0800347 int lightSensorRate = resources.getInteger(
348 com.android.internal.R.integer.config_autoBrightnessLightSensorRate);
Julius D'souza5d717092016-10-24 19:26:45 -0700349 int initialLightSensorRate = resources.getInteger(
350 com.android.internal.R.integer.config_autoBrightnessInitialLightSensorRate);
351 if (initialLightSensorRate == -1) {
352 initialLightSensorRate = lightSensorRate;
353 } else if (initialLightSensorRate > lightSensorRate) {
354 Slog.w(TAG, "Expected config_autoBrightnessInitialLightSensorRate ("
355 + initialLightSensorRate + ") to be less than or equal to "
356 + "config_autoBrightnessLightSensorRate (" + lightSensorRate + ").");
357 }
Filip Gruszczynskid81ecd12015-02-06 12:38:47 -0800358 long brighteningLightDebounce = resources.getInteger(
359 com.android.internal.R.integer.config_autoBrightnessBrighteningLightDebounce);
360 long darkeningLightDebounce = resources.getInteger(
361 com.android.internal.R.integer.config_autoBrightnessDarkeningLightDebounce);
362 boolean autoBrightnessResetAmbientLuxAfterWarmUp = resources.getBoolean(
363 com.android.internal.R.bool.config_autoBrightnessResetAmbientLuxAfterWarmUp);
Zoran Jovanovic6fc42f52015-12-10 17:01:16 +0100364 int ambientLightHorizon = resources.getInteger(
365 com.android.internal.R.integer.config_autoBrightnessAmbientLightHorizon);
366 float autoBrightnessAdjustmentMaxGamma = resources.getFraction(
367 com.android.internal.R.fraction.config_autoBrightnessAdjustmentMaxGamma,
368 1, 1);
Filip Gruszczynskid81ecd12015-02-06 12:38:47 -0800369
Julius D'souza428aed02016-08-07 19:08:30 -0700370 int[] brightLevels = resources.getIntArray(
371 com.android.internal.R.array.config_dynamicHysteresisBrightLevels);
372 int[] darkLevels = resources.getIntArray(
373 com.android.internal.R.array.config_dynamicHysteresisDarkLevels);
374 int[] luxLevels = resources.getIntArray(
375 com.android.internal.R.array.config_dynamicHysteresisLuxLevels);
376 HysteresisLevels dynamicHysteresis = new HysteresisLevels(
377 brightLevels, darkLevels, luxLevels);
378
Jeff Brown96307042012-07-27 15:51:34 -0700379 if (mUseSoftwareAutoBrightnessConfig) {
Jeff Brown1a30b552012-08-16 01:31:11 -0700380 int[] lux = resources.getIntArray(
Jeff Brown96307042012-07-27 15:51:34 -0700381 com.android.internal.R.array.config_autoBrightnessLevels);
Jeff Brown1a30b552012-08-16 01:31:11 -0700382 int[] screenBrightness = resources.getIntArray(
Jeff Brown96307042012-07-27 15:51:34 -0700383 com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
Michael Wright639c8be2014-01-17 18:29:12 -0800384 int lightSensorWarmUpTimeConfig = resources.getInteger(
385 com.android.internal.R.integer.config_lightSensorWarmupTime);
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700386 final float dozeScaleFactor = resources.getFraction(
387 com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor,
388 1, 1);
Jeff Brown1a30b552012-08-16 01:31:11 -0700389
Michael Wright639c8be2014-01-17 18:29:12 -0800390 Spline screenAutoBrightnessSpline = createAutoBrightnessSpline(lux, screenBrightness);
391 if (screenAutoBrightnessSpline == null) {
Jeff Brown96307042012-07-27 15:51:34 -0700392 Slog.e(TAG, "Error in config.xml. config_autoBrightnessLcdBacklightValues "
Jeff Brown1a30b552012-08-16 01:31:11 -0700393 + "(size " + screenBrightness.length + ") "
394 + "must be monotic and have exactly one more entry than "
395 + "config_autoBrightnessLevels (size " + lux.length + ") "
396 + "which must be strictly increasing. "
Jeff Brown96307042012-07-27 15:51:34 -0700397 + "Auto-brightness will be disabled.");
398 mUseSoftwareAutoBrightnessConfig = false;
Jeff Brownb76eebff2012-10-05 22:26:44 -0700399 } else {
Jeff Brown1bfd0f42014-08-22 01:59:06 -0700400 int bottom = clampAbsoluteBrightness(screenBrightness[0]);
401 if (mScreenBrightnessDarkConfig > bottom) {
402 Slog.w(TAG, "config_screenBrightnessDark (" + mScreenBrightnessDarkConfig
403 + ") should be less than or equal to the first value of "
404 + "config_autoBrightnessLcdBacklightValues ("
405 + bottom + ").");
406 }
407 if (bottom < screenBrightnessRangeMinimum) {
408 screenBrightnessRangeMinimum = bottom;
Jeff Brownb76eebff2012-10-05 22:26:44 -0700409 }
Jeff Brown131206b2014-04-08 17:27:14 -0700410 mAutomaticBrightnessController = new AutomaticBrightnessController(this,
411 handler.getLooper(), sensorManager, screenAutoBrightnessSpline,
Michael Wright639c8be2014-01-17 18:29:12 -0800412 lightSensorWarmUpTimeConfig, screenBrightnessRangeMinimum,
Filip Gruszczynskid81ecd12015-02-06 12:38:47 -0800413 mScreenBrightnessRangeMaximum, dozeScaleFactor, lightSensorRate,
Julius D'souza5d717092016-10-24 19:26:45 -0700414 initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce,
Julius D'souza428aed02016-08-07 19:08:30 -0700415 autoBrightnessResetAmbientLuxAfterWarmUp, ambientLightHorizon,
416 autoBrightnessAdjustmentMaxGamma, dynamicHysteresis);
Jeff Brown96307042012-07-27 15:51:34 -0700417 }
Jeff Brown96307042012-07-27 15:51:34 -0700418 }
419
Michael Wright639c8be2014-01-17 18:29:12 -0800420 mScreenBrightnessRangeMinimum = screenBrightnessRangeMinimum;
Jeff Brownb76eebff2012-10-05 22:26:44 -0700421
Michael Lentine0839adb2014-07-29 18:47:56 -0700422 mColorFadeFadesConfig = resources.getBoolean(
Jeff Browna52772f2012-10-04 18:38:09 -0700423 com.android.internal.R.bool.config_animateScreenLights);
424
Michael Wright410fd1b2017-07-25 22:31:03 +0100425 mDisplayBlanksAfterDozeConfig = resources.getBoolean(
426 com.android.internal.R.bool.config_displayBlanksAfterDoze);
Michael Wright05e76fe2017-07-20 18:18:33 +0100427
Michael Wright65d3e702017-07-26 01:10:59 +0100428 mBrightnessBucketsInDozeConfig = resources.getBoolean(
429 com.android.internal.R.bool.config_displayBrightnessBucketsInDoze);
430
Jeff Brown96307042012-07-27 15:51:34 -0700431 if (!DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) {
432 mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
433 if (mProximitySensor != null) {
434 mProximityThreshold = Math.min(mProximitySensor.getMaximumRange(),
435 TYPICAL_PROXIMITY_THRESHOLD);
436 }
437 }
438
Jeff Brown1a30b552012-08-16 01:31:11 -0700439 }
440
Jeff Brown96307042012-07-27 15:51:34 -0700441 /**
442 * Returns true if the proximity sensor screen-off function is available.
443 */
444 public boolean isProximitySensorAvailable() {
445 return mProximitySensor != null;
446 }
447
448 /**
449 * Requests a new power state.
450 * The controller makes a copy of the provided object and then
451 * begins adjusting the power state to match what was requested.
452 *
453 * @param request The requested power state.
454 * @param waitForNegativeProximity If true, issues a request to wait for
455 * negative proximity before turning the screen back on, assuming the screen
456 * was turned off by the proximity sensor.
457 * @return True if display is ready, false if there are important changes that must
458 * be made asynchronously (such as turning the screen on), in which case the caller
Jeff Brown606e4e82014-09-18 15:22:26 -0700459 * should grab a wake lock, watch for {@link DisplayPowerCallbacks#onStateChanged()}
460 * then try the request again later until the state converges.
Jeff Brown96307042012-07-27 15:51:34 -0700461 */
462 public boolean requestPowerState(DisplayPowerRequest request,
463 boolean waitForNegativeProximity) {
464 if (DEBUG) {
465 Slog.d(TAG, "requestPowerState: "
466 + request + ", waitForNegativeProximity=" + waitForNegativeProximity);
467 }
468
469 synchronized (mLock) {
470 boolean changed = false;
471
472 if (waitForNegativeProximity
473 && !mPendingWaitForNegativeProximityLocked) {
474 mPendingWaitForNegativeProximityLocked = true;
475 changed = true;
476 }
477
478 if (mPendingRequestLocked == null) {
479 mPendingRequestLocked = new DisplayPowerRequest(request);
480 changed = true;
481 } else if (!mPendingRequestLocked.equals(request)) {
482 mPendingRequestLocked.copyFrom(request);
483 changed = true;
484 }
485
486 if (changed) {
487 mDisplayReadyLocked = false;
488 }
489
490 if (changed && !mPendingRequestChangedLocked) {
491 mPendingRequestChangedLocked = true;
492 sendUpdatePowerStateLocked();
493 }
494
495 return mDisplayReadyLocked;
496 }
497 }
498
499 private void sendUpdatePowerState() {
500 synchronized (mLock) {
501 sendUpdatePowerStateLocked();
502 }
503 }
504
505 private void sendUpdatePowerStateLocked() {
506 if (!mPendingUpdatePowerStateLocked) {
507 mPendingUpdatePowerStateLocked = true;
508 Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE);
509 msg.setAsynchronous(true);
510 mHandler.sendMessage(msg);
511 }
512 }
513
514 private void initialize() {
Jeff Brown037c33e2014-04-09 00:31:55 -0700515 // Initialize the power state object for the default display.
516 // In the future, we might manage multiple displays independently.
517 mPowerState = new DisplayPowerState(mBlanker,
Michael Lentine0839adb2014-07-29 18:47:56 -0700518 new ColorFade(Display.DEFAULT_DISPLAY));
Jeff Brown96307042012-07-27 15:51:34 -0700519
Michael Lentine0839adb2014-07-29 18:47:56 -0700520 mColorFadeOnAnimator = ObjectAnimator.ofFloat(
521 mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 0.0f, 1.0f);
522 mColorFadeOnAnimator.setDuration(COLOR_FADE_ON_ANIMATION_DURATION_MILLIS);
523 mColorFadeOnAnimator.addListener(mAnimatorListener);
Jeff Brown96307042012-07-27 15:51:34 -0700524
Michael Lentine0839adb2014-07-29 18:47:56 -0700525 mColorFadeOffAnimator = ObjectAnimator.ofFloat(
526 mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 1.0f, 0.0f);
527 mColorFadeOffAnimator.setDuration(COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS);
528 mColorFadeOffAnimator.addListener(mAnimatorListener);
Jeff Brown96307042012-07-27 15:51:34 -0700529
530 mScreenBrightnessRampAnimator = new RampAnimator<DisplayPowerState>(
531 mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS);
Jeff Brown42558692014-05-20 22:02:46 -0700532 mScreenBrightnessRampAnimator.setListener(mRampAnimatorListener);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800533
Jeff Brown131206b2014-04-08 17:27:14 -0700534 // Initialize screen state for battery stats.
535 try {
Jeff Browne95c3cd2014-05-02 16:59:26 -0700536 mBatteryStats.noteScreenState(mPowerState.getScreenState());
Jeff Brown131206b2014-04-08 17:27:14 -0700537 mBatteryStats.noteScreenBrightness(mPowerState.getScreenBrightness());
538 } catch (RemoteException ex) {
539 // same process
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800540 }
Jeff Brown96307042012-07-27 15:51:34 -0700541 }
542
543 private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() {
544 @Override
545 public void onAnimationStart(Animator animation) {
546 }
547 @Override
548 public void onAnimationEnd(Animator animation) {
549 sendUpdatePowerState();
550 }
551 @Override
552 public void onAnimationRepeat(Animator animation) {
553 }
554 @Override
555 public void onAnimationCancel(Animator animation) {
556 }
557 };
558
Jeff Brown42558692014-05-20 22:02:46 -0700559 private final RampAnimator.Listener mRampAnimatorListener = new RampAnimator.Listener() {
560 @Override
561 public void onAnimationEnd() {
562 sendUpdatePowerState();
563 }
564 };
565
Jeff Brown96307042012-07-27 15:51:34 -0700566 private void updatePowerState() {
567 // Update the power state request.
568 final boolean mustNotify;
569 boolean mustInitialize = false;
Adrian Roos6da87ab2014-05-16 23:09:41 +0200570 boolean autoBrightnessAdjustmentChanged = false;
Jeff Brown330560f2012-08-21 22:10:57 -0700571
Jeff Brown96307042012-07-27 15:51:34 -0700572 synchronized (mLock) {
573 mPendingUpdatePowerStateLocked = false;
574 if (mPendingRequestLocked == null) {
575 return; // wait until first actual power request
576 }
577
578 if (mPowerRequest == null) {
579 mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked);
580 mWaitingForNegativeProximity = mPendingWaitForNegativeProximityLocked;
Jeff Brown6307a152012-08-20 13:24:23 -0700581 mPendingWaitForNegativeProximityLocked = false;
Jeff Brown96307042012-07-27 15:51:34 -0700582 mPendingRequestChangedLocked = false;
583 mustInitialize = true;
584 } else if (mPendingRequestChangedLocked) {
Adrian Roos6da87ab2014-05-16 23:09:41 +0200585 autoBrightnessAdjustmentChanged = (mPowerRequest.screenAutoBrightnessAdjustment
586 != mPendingRequestLocked.screenAutoBrightnessAdjustment);
Jeff Brown96307042012-07-27 15:51:34 -0700587 mPowerRequest.copyFrom(mPendingRequestLocked);
588 mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked;
Jeff Brown6307a152012-08-20 13:24:23 -0700589 mPendingWaitForNegativeProximityLocked = false;
Jeff Brown96307042012-07-27 15:51:34 -0700590 mPendingRequestChangedLocked = false;
591 mDisplayReadyLocked = false;
592 }
593
594 mustNotify = !mDisplayReadyLocked;
595 }
596
597 // Initialize things the first time the power state is changed.
598 if (mustInitialize) {
599 initialize();
600 }
601
Jeff Brown970d4132014-07-19 11:33:47 -0700602 // Compute the basic display state using the policy.
603 // We might override this below based on other factors.
604 int state;
605 int brightness = PowerManager.BRIGHTNESS_DEFAULT;
Jeff Brown2175e9c2014-09-12 16:11:07 -0700606 boolean performScreenOffTransition = false;
Jeff Brown970d4132014-07-19 11:33:47 -0700607 switch (mPowerRequest.policy) {
608 case DisplayPowerRequest.POLICY_OFF:
609 state = Display.STATE_OFF;
Jeff Brown2175e9c2014-09-12 16:11:07 -0700610 performScreenOffTransition = true;
Jeff Brown970d4132014-07-19 11:33:47 -0700611 break;
612 case DisplayPowerRequest.POLICY_DOZE:
613 if (mPowerRequest.dozeScreenState != Display.STATE_UNKNOWN) {
614 state = mPowerRequest.dozeScreenState;
615 } else {
616 state = Display.STATE_DOZE;
617 }
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700618 if (!mAllowAutoBrightnessWhileDozingConfig) {
619 brightness = mPowerRequest.dozeScreenBrightness;
620 }
Jeff Brown970d4132014-07-19 11:33:47 -0700621 break;
Santos Cordon3107d292016-09-20 15:50:35 -0700622 case DisplayPowerRequest.POLICY_VR:
623 state = Display.STATE_VR;
624 break;
Jeff Brown970d4132014-07-19 11:33:47 -0700625 case DisplayPowerRequest.POLICY_DIM:
626 case DisplayPowerRequest.POLICY_BRIGHT:
627 default:
628 state = Display.STATE_ON;
629 break;
630 }
Jeff Brown2175e9c2014-09-12 16:11:07 -0700631 assert(state != Display.STATE_UNKNOWN);
Jeff Brown970d4132014-07-19 11:33:47 -0700632
Jeff Brown6307a152012-08-20 13:24:23 -0700633 // Apply the proximity sensor.
Jeff Brown96307042012-07-27 15:51:34 -0700634 if (mProximitySensor != null) {
Jeff Brown970d4132014-07-19 11:33:47 -0700635 if (mPowerRequest.useProximitySensor && state != Display.STATE_OFF) {
Jeff Brown6307a152012-08-20 13:24:23 -0700636 setProximitySensorEnabled(true);
637 if (!mScreenOffBecauseOfProximity
638 && mProximity == PROXIMITY_POSITIVE) {
639 mScreenOffBecauseOfProximity = true;
Jeff Brownec083212013-09-11 20:45:25 -0700640 sendOnProximityPositiveWithWakelock();
Jeff Brown6307a152012-08-20 13:24:23 -0700641 }
642 } else if (mWaitingForNegativeProximity
643 && mScreenOffBecauseOfProximity
644 && mProximity == PROXIMITY_POSITIVE
Jeff Brown970d4132014-07-19 11:33:47 -0700645 && state != Display.STATE_OFF) {
Jeff Brown6307a152012-08-20 13:24:23 -0700646 setProximitySensorEnabled(true);
647 } else {
648 setProximitySensorEnabled(false);
649 mWaitingForNegativeProximity = false;
650 }
651 if (mScreenOffBecauseOfProximity
652 && mProximity != PROXIMITY_POSITIVE) {
Jeff Brown96307042012-07-27 15:51:34 -0700653 mScreenOffBecauseOfProximity = false;
Jeff Brownec083212013-09-11 20:45:25 -0700654 sendOnProximityNegativeWithWakelock();
Jeff Brown96307042012-07-27 15:51:34 -0700655 }
Jeff Brown6307a152012-08-20 13:24:23 -0700656 } else {
657 mWaitingForNegativeProximity = false;
Jeff Brown96307042012-07-27 15:51:34 -0700658 }
Jeff Brown970d4132014-07-19 11:33:47 -0700659 if (mScreenOffBecauseOfProximity) {
660 state = Display.STATE_OFF;
Jeff Brown96307042012-07-27 15:51:34 -0700661 }
662
Jeff Brownbf4e4142014-10-02 13:08:05 -0700663 // Animate the screen state change unless already animating.
664 // The transition may be deferred, so after this point we will use the
665 // actual state instead of the desired one.
Santos Cordon3107d292016-09-20 15:50:35 -0700666 final int oldState = mPowerState.getScreenState();
Jeff Brownbf4e4142014-10-02 13:08:05 -0700667 animateScreenStateChange(state, performScreenOffTransition);
668 state = mPowerState.getScreenState();
669
Jeff Brown970d4132014-07-19 11:33:47 -0700670 // Use zero brightness when screen is off.
671 if (state == Display.STATE_OFF) {
672 brightness = PowerManager.BRIGHTNESS_OFF;
673 }
674
Jeff Brown970d4132014-07-19 11:33:47 -0700675 // Configure auto-brightness.
676 boolean autoBrightnessEnabled = false;
677 if (mAutomaticBrightnessController != null) {
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700678 final boolean autoBrightnessEnabledInDoze = mAllowAutoBrightnessWhileDozingConfig
679 && (state == Display.STATE_DOZE || state == Display.STATE_DOZE_SUSPEND);
Jeff Brown970d4132014-07-19 11:33:47 -0700680 autoBrightnessEnabled = mPowerRequest.useAutoBrightness
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700681 && (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
682 && brightness < 0;
Jeff Browna576b4d2015-04-23 19:58:06 -0700683 final boolean userInitiatedChange = autoBrightnessAdjustmentChanged
684 && mPowerRequest.brightnessSetByUser;
Jeff Brown970d4132014-07-19 11:33:47 -0700685 mAutomaticBrightnessController.configure(autoBrightnessEnabled,
Jeff Browna576b4d2015-04-23 19:58:06 -0700686 mPowerRequest.screenAutoBrightnessAdjustment, state != Display.STATE_ON,
Justin Klaassen5483cea2017-02-02 09:02:35 -0800687 userInitiatedChange);
Jeff Brown970d4132014-07-19 11:33:47 -0700688 }
689
Jeff Brown7b5be5e2014-11-12 18:45:31 -0800690 // Apply brightness boost.
691 // We do this here after configuring auto-brightness so that we don't
692 // disable the light sensor during this temporary state. That way when
693 // boost ends we will be able to resume normal auto-brightness behavior
694 // without any delay.
695 if (mPowerRequest.boostScreenBrightness
696 && brightness != PowerManager.BRIGHTNESS_OFF) {
697 brightness = PowerManager.BRIGHTNESS_ON;
698 }
699
Jeff Brown970d4132014-07-19 11:33:47 -0700700 // Apply auto-brightness.
701 boolean slowChange = false;
702 if (brightness < 0) {
703 if (autoBrightnessEnabled) {
704 brightness = mAutomaticBrightnessController.getAutomaticScreenBrightness();
705 }
706 if (brightness >= 0) {
707 // Use current auto-brightness value and slowly adjust to changes.
708 brightness = clampScreenBrightness(brightness);
709 if (mAppliedAutoBrightness && !autoBrightnessAdjustmentChanged) {
710 slowChange = true; // slowly adapt to auto-brightness
711 }
712 mAppliedAutoBrightness = true;
Jeff Brown96307042012-07-27 15:51:34 -0700713 } else {
Jeff Brown970d4132014-07-19 11:33:47 -0700714 mAppliedAutoBrightness = false;
Jeff Brown96307042012-07-27 15:51:34 -0700715 }
716 } else {
Jeff Brown970d4132014-07-19 11:33:47 -0700717 mAppliedAutoBrightness = false;
718 }
719
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700720 // Use default brightness when dozing unless overridden.
721 if (brightness < 0 && (state == Display.STATE_DOZE
722 || state == Display.STATE_DOZE_SUSPEND)) {
723 brightness = mScreenBrightnessDozeConfig;
724 }
725
Jeff Brown970d4132014-07-19 11:33:47 -0700726 // Apply manual brightness.
727 // Use the current brightness setting from the request, which is expected
728 // provide a nominal default value for the case where auto-brightness
729 // is not ready yet.
730 if (brightness < 0) {
731 brightness = clampScreenBrightness(mPowerRequest.screenBrightness);
732 }
733
734 // Apply dimming by at least some minimum amount when user activity
735 // timeout is about to expire.
736 if (mPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
Jeff Brown5c8ea082014-07-24 19:30:31 -0700737 if (brightness > mScreenBrightnessRangeMinimum) {
738 brightness = Math.max(Math.min(brightness - SCREEN_DIM_MINIMUM_REDUCTION,
739 mScreenBrightnessDimConfig), mScreenBrightnessRangeMinimum);
740 }
Jeff Brown970d4132014-07-19 11:33:47 -0700741 if (!mAppliedDimming) {
742 slowChange = false;
743 }
744 mAppliedDimming = true;
mochangmingf0cb46c2015-12-29 13:55:24 +0800745 } else if (mAppliedDimming) {
746 slowChange = false;
747 mAppliedDimming = false;
Jeff Brown970d4132014-07-19 11:33:47 -0700748 }
749
jackqdyulei92681e82017-02-28 11:26:28 -0800750 // If low power mode is enabled, scale brightness by screenLowPowerBrightnessFactor
Jeff Brown970d4132014-07-19 11:33:47 -0700751 // as long as it is above the minimum threshold.
752 if (mPowerRequest.lowPowerMode) {
753 if (brightness > mScreenBrightnessRangeMinimum) {
jackqdyulei92681e82017-02-28 11:26:28 -0800754 final float brightnessFactor =
755 Math.min(mPowerRequest.screenLowPowerBrightnessFactor, 1);
756 final int lowPowerBrightness = (int) (brightness * brightnessFactor);
757 brightness = Math.max(lowPowerBrightness, mScreenBrightnessRangeMinimum);
Jeff Brown970d4132014-07-19 11:33:47 -0700758 }
759 if (!mAppliedLowPower) {
760 slowChange = false;
761 }
762 mAppliedLowPower = true;
mochangmingf0cb46c2015-12-29 13:55:24 +0800763 } else if (mAppliedLowPower) {
764 slowChange = false;
765 mAppliedLowPower = false;
Jeff Brown970d4132014-07-19 11:33:47 -0700766 }
767
Jeff Brown0a434772014-09-30 14:42:27 -0700768 // Animate the screen brightness when the screen is on or dozing.
Santos Cordon3107d292016-09-20 15:50:35 -0700769 // Skip the animation when the screen is off or suspended or transition to/from VR.
Prashant Malani33538242014-11-13 14:04:00 -0800770 if (!mPendingScreenOff) {
Julius D'souzad5105dd2017-06-02 11:03:53 -0700771 if (mSkipScreenOnBrightnessRamp) {
772
773 if (state == Display.STATE_ON) {
774 if (mSkipRampState == RAMP_STATE_SKIP_NONE && mDozing) {
775 mInitialAutoBrightness = brightness;
776 mSkipRampState = RAMP_STATE_SKIP_INITIAL;
777 } else if (mSkipRampState == RAMP_STATE_SKIP_INITIAL
778 && mUseSoftwareAutoBrightnessConfig
779 && brightness != mInitialAutoBrightness) {
780 mSkipRampState = RAMP_STATE_SKIP_AUTOBRIGHT;
781 } else if (mSkipRampState == RAMP_STATE_SKIP_AUTOBRIGHT) {
782 mSkipRampState = RAMP_STATE_SKIP_NONE;
783 }
784 } else {
785 mSkipRampState = RAMP_STATE_SKIP_NONE;
786 }
787 }
788
Santos Cordon3107d292016-09-20 15:50:35 -0700789 boolean wasOrWillBeInVr = (state == Display.STATE_VR || oldState == Display.STATE_VR);
Julius D'souzad5105dd2017-06-02 11:03:53 -0700790 if ((state == Display.STATE_ON
791 && mSkipRampState == RAMP_STATE_SKIP_NONE
Michael Wright65d3e702017-07-26 01:10:59 +0100792 || state == Display.STATE_DOZE && !mBrightnessBucketsInDozeConfig)
Julius D'souzad5105dd2017-06-02 11:03:53 -0700793 && !wasOrWillBeInVr) {
Prashant Malani33538242014-11-13 14:04:00 -0800794 animateScreenBrightness(brightness,
Julius D'souzafeadad12016-08-05 14:34:38 -0700795 slowChange ? mBrightnessRampRateSlow : mBrightnessRampRateFast);
Prashant Malani33538242014-11-13 14:04:00 -0800796 } else {
797 animateScreenBrightness(brightness, 0);
798 }
Jeff Brown0a434772014-09-30 14:42:27 -0700799 }
800
801 // Determine whether the display is ready for use in the newly requested state.
802 // Note that we do not wait for the brightness ramp animation to complete before
803 // reporting the display is ready because we only need to ensure the screen is in the
804 // right power state even as it continues to converge on the desired brightness.
805 final boolean ready = mPendingScreenOnUnblocker == null
Michael Lentine0839adb2014-07-29 18:47:56 -0700806 && !mColorFadeOnAnimator.isStarted()
807 && !mColorFadeOffAnimator.isStarted()
Jeff Brown0a434772014-09-30 14:42:27 -0700808 && mPowerState.waitUntilClean(mCleanListener);
809 final boolean finished = ready
810 && !mScreenBrightnessRampAnimator.isAnimating();
811
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700812 // Notify policy about screen turned on.
813 if (ready && state != Display.STATE_OFF
814 && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_ON) {
Michael Wright410fd1b2017-07-25 22:31:03 +0100815 setReportedScreenState(REPORTED_TO_POLICY_SCREEN_ON);
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700816 mWindowManagerPolicy.screenTurnedOn();
817 }
818
Jeff Brown0a434772014-09-30 14:42:27 -0700819 // Grab a wake lock if we have unfinished business.
820 if (!finished && !mUnfinishedBusiness) {
821 if (DEBUG) {
822 Slog.d(TAG, "Unfinished business...");
823 }
824 mCallbacks.acquireSuspendBlocker();
825 mUnfinishedBusiness = true;
826 }
827
828 // Notify the power manager when ready.
829 if (ready && mustNotify) {
830 // Send state change.
Jeff Brown96307042012-07-27 15:51:34 -0700831 synchronized (mLock) {
832 if (!mPendingRequestChangedLocked) {
833 mDisplayReadyLocked = true;
Jeff Brownc38c9be2012-10-04 13:16:19 -0700834
835 if (DEBUG) {
836 Slog.d(TAG, "Display ready!");
837 }
Jeff Brown96307042012-07-27 15:51:34 -0700838 }
839 }
Jeff Brownec083212013-09-11 20:45:25 -0700840 sendOnStateChangedWithWakelock();
Jeff Brown96307042012-07-27 15:51:34 -0700841 }
Jeff Brown0a434772014-09-30 14:42:27 -0700842
843 // Release the wake lock when we have no unfinished business.
844 if (finished && mUnfinishedBusiness) {
845 if (DEBUG) {
846 Slog.d(TAG, "Finished business...");
847 }
848 mUnfinishedBusiness = false;
849 mCallbacks.releaseSuspendBlocker();
850 }
Julius D'souzad5105dd2017-06-02 11:03:53 -0700851
852 // Record if dozing for future comparison.
853 mDozing = state != Display.STATE_ON;
Jeff Brown96307042012-07-27 15:51:34 -0700854 }
855
Michael Wright639c8be2014-01-17 18:29:12 -0800856 @Override
857 public void updateBrightness() {
858 sendUpdatePowerState();
859 }
860
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700861 private void blockScreenOn() {
Jeff Brown3ee549c2014-09-22 20:14:39 -0700862 if (mPendingScreenOnUnblocker == null) {
Jeff Brown3edf5272014-08-14 19:25:14 -0700863 Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0);
Jeff Brown3ee549c2014-09-22 20:14:39 -0700864 mPendingScreenOnUnblocker = new ScreenOnUnblocker();
Jeff Brown037c33e2014-04-09 00:31:55 -0700865 mScreenOnBlockStartRealTime = SystemClock.elapsedRealtime();
Jeff Brown3edf5272014-08-14 19:25:14 -0700866 Slog.i(TAG, "Blocking screen on until initial contents have been drawn.");
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700867 }
868 }
869
870 private void unblockScreenOn() {
Jeff Brown3ee549c2014-09-22 20:14:39 -0700871 if (mPendingScreenOnUnblocker != null) {
872 mPendingScreenOnUnblocker = null;
Jeff Brown2d8a3902014-03-11 23:02:35 -0700873 long delay = SystemClock.elapsedRealtime() - mScreenOnBlockStartRealTime;
Jeff Brown3edf5272014-08-14 19:25:14 -0700874 Slog.i(TAG, "Unblocked screen on after " + delay + " ms");
875 Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0);
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700876 }
877 }
878
Jorim Jaggi51304d72017-05-17 17:25:32 +0200879 private void blockScreenOff() {
880 if (mPendingScreenOffUnblocker == null) {
881 Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, SCREEN_OFF_BLOCKED_TRACE_NAME, 0);
882 mPendingScreenOffUnblocker = new ScreenOffUnblocker();
883 mScreenOffBlockStartRealTime = SystemClock.elapsedRealtime();
884 Slog.i(TAG, "Blocking screen off");
885 }
886 }
887
888 private void unblockScreenOff() {
889 if (mPendingScreenOffUnblocker != null) {
890 mPendingScreenOffUnblocker = null;
891 long delay = SystemClock.elapsedRealtime() - mScreenOffBlockStartRealTime;
892 Slog.i(TAG, "Unblocked screen off after " + delay + " ms");
893 Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, SCREEN_OFF_BLOCKED_TRACE_NAME, 0);
894 }
895 }
896
Jeff Brown3ee549c2014-09-22 20:14:39 -0700897 private boolean setScreenState(int state) {
Michael Wright410fd1b2017-07-25 22:31:03 +0100898 return setScreenState(state, false /*reportOnly*/);
Michael Wright05e76fe2017-07-20 18:18:33 +0100899 }
900
Michael Wright410fd1b2017-07-25 22:31:03 +0100901 private boolean setScreenState(int state, boolean reportOnly) {
Jorim Jaggi51304d72017-05-17 17:25:32 +0200902 final boolean isOff = (state == Display.STATE_OFF);
Jeff Brown037c33e2014-04-09 00:31:55 -0700903 if (mPowerState.getScreenState() != state) {
Jorim Jaggi51304d72017-05-17 17:25:32 +0200904
905 // If we are trying to turn screen off, give policy a chance to do something before we
906 // actually turn the screen off.
907 if (isOff && !mScreenOffBecauseOfProximity) {
908 if (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_ON) {
Michael Wright410fd1b2017-07-25 22:31:03 +0100909 setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_OFF);
Jorim Jaggi51304d72017-05-17 17:25:32 +0200910 blockScreenOff();
911 mWindowManagerPolicy.screenTurningOff(mPendingScreenOffUnblocker);
Michael Wright410fd1b2017-07-25 22:31:03 +0100912 unblockScreenOff();
Jorim Jaggi51304d72017-05-17 17:25:32 +0200913 } else if (mPendingScreenOffUnblocker != null) {
Jorim Jaggi51304d72017-05-17 17:25:32 +0200914 // Abort doing the state change until screen off is unblocked.
915 return false;
916 }
917 }
918
Michael Wright410fd1b2017-07-25 22:31:03 +0100919 if (!reportOnly) {
920 mPowerState.setScreenState(state);
921 // Tell battery stats about the transition.
922 try {
923 mBatteryStats.noteScreenState(state);
924 } catch (RemoteException ex) {
925 // same process
926 }
Jeff Brown96307042012-07-27 15:51:34 -0700927 }
928 }
Jeff Browne1633ad2015-06-22 19:24:24 -0700929
930 // Tell the window manager policy when the screen is turned off or on unless it's due
931 // to the proximity sensor. We temporarily block turning the screen on until the
932 // window manager is ready by leaving a black surface covering the screen.
933 // This surface is essentially the final state of the color fade animation and
934 // it is only removed once the window manager tells us that the activity has
935 // finished drawing underneath.
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700936 if (isOff && mReportedScreenStateToPolicy != REPORTED_TO_POLICY_SCREEN_OFF
937 && !mScreenOffBecauseOfProximity) {
Michael Wright410fd1b2017-07-25 22:31:03 +0100938 setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
Jeff Browne1633ad2015-06-22 19:24:24 -0700939 unblockScreenOn();
940 mWindowManagerPolicy.screenTurnedOff();
Jorim Jaggi51304d72017-05-17 17:25:32 +0200941 } else if (!isOff
942 && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_OFF) {
943
944 // We told policy already that screen was turning off, but now we changed our minds.
945 // Complete the full state transition on -> turningOff -> off.
946 unblockScreenOff();
947 mWindowManagerPolicy.screenTurnedOff();
Michael Wright410fd1b2017-07-25 22:31:03 +0100948 setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
Jorim Jaggi51304d72017-05-17 17:25:32 +0200949 }
950 if (!isOff && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF) {
Michael Wright410fd1b2017-07-25 22:31:03 +0100951 setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_ON);
Jeff Browne1633ad2015-06-22 19:24:24 -0700952 if (mPowerState.getColorFadeLevel() == 0.0f) {
953 blockScreenOn();
954 } else {
955 unblockScreenOn();
956 }
957 mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker);
958 }
959
960 // Return true if the screen isn't blocked.
Jeff Brown3ee549c2014-09-22 20:14:39 -0700961 return mPendingScreenOnUnblocker == null;
Jeff Brown96307042012-07-27 15:51:34 -0700962 }
963
Michael Wright410fd1b2017-07-25 22:31:03 +0100964 private void setReportedScreenState(int state) {
965 Trace.traceCounter(Trace.TRACE_TAG_POWER, "ReportedScreenStateToPolicy", state);
966 mReportedScreenStateToPolicy = state;
967 }
968
Jeff Brown330560f2012-08-21 22:10:57 -0700969 private int clampScreenBrightness(int value) {
Michael Wright639c8be2014-01-17 18:29:12 -0800970 return MathUtils.constrain(
971 value, mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum);
Jeff Brown330560f2012-08-21 22:10:57 -0700972 }
973
Jeff Brown96307042012-07-27 15:51:34 -0700974 private void animateScreenBrightness(int target, int rate) {
Jeff Brown0a434772014-09-30 14:42:27 -0700975 if (DEBUG) {
976 Slog.d(TAG, "Animating brightness: target=" + target +", rate=" + rate);
977 }
Jeff Brown96307042012-07-27 15:51:34 -0700978 if (mScreenBrightnessRampAnimator.animateTo(target, rate)) {
Jeff Brown131206b2014-04-08 17:27:14 -0700979 try {
980 mBatteryStats.noteScreenBrightness(target);
981 } catch (RemoteException ex) {
982 // same process
983 }
Jeff Brown96307042012-07-27 15:51:34 -0700984 }
985 }
986
Jeff Brown606e4e82014-09-18 15:22:26 -0700987 private void animateScreenStateChange(int target, boolean performScreenOffTransition) {
988 // If there is already an animation in progress, don't interfere with it.
989 if (mColorFadeOnAnimator.isStarted()
990 || mColorFadeOffAnimator.isStarted()) {
Chong Zhangb131c702016-02-16 16:31:48 -0800991 if (target != Display.STATE_ON) {
992 return;
993 }
994 // If display state changed to on, proceed and stop the color fade and turn screen on.
995 mPendingScreenOff = false;
Jeff Brown606e4e82014-09-18 15:22:26 -0700996 }
997
Michael Wright410fd1b2017-07-25 22:31:03 +0100998 if (mDisplayBlanksAfterDozeConfig
999 && Display.isDozeState(mPowerState.getScreenState())
Michael Wright05e76fe2017-07-20 18:18:33 +01001000 && !Display.isDozeState(target)) {
Michael Wright05e76fe2017-07-20 18:18:33 +01001001 // Skip the screen off animation and add a black surface to hide the
Michael Wright410fd1b2017-07-25 22:31:03 +01001002 // contents of the screen.
1003 mPowerState.prepareColorFade(mContext,
1004 mColorFadeFadesConfig ? ColorFade.MODE_FADE : ColorFade.MODE_WARM_UP);
Michael Wright05e76fe2017-07-20 18:18:33 +01001005 mColorFadeOffAnimator.end();
Michael Wright410fd1b2017-07-25 22:31:03 +01001006 // Some display hardware will blank itself on the transition between doze and non-doze
1007 // but still on display states. In this case we want to report to policy that the
1008 // display has turned off so it can prepare the appropriate power on animation, but we
1009 // don't want to actually transition to the fully off state since that takes
1010 // significantly longer to transition from.
1011 setScreenState(Display.STATE_OFF, target != Display.STATE_OFF /*reportOnly*/);
Michael Wright05e76fe2017-07-20 18:18:33 +01001012 }
1013
Jeff Brown3ee549c2014-09-22 20:14:39 -07001014 // If we were in the process of turning off the screen but didn't quite
1015 // finish. Then finish up now to prevent a jarring transition back
1016 // to screen on if we skipped blocking screen on as usual.
1017 if (mPendingScreenOff && target != Display.STATE_OFF) {
1018 setScreenState(Display.STATE_OFF);
1019 mPendingScreenOff = false;
Michael Lentined73854d2015-09-25 10:55:26 -07001020 mPowerState.dismissColorFadeResources();
Jeff Brown606e4e82014-09-18 15:22:26 -07001021 }
1022
1023 if (target == Display.STATE_ON) {
1024 // Want screen on. The contents of the screen may not yet
Jeff Brown3ee549c2014-09-22 20:14:39 -07001025 // be visible if the color fade has not been dismissed because
Jeff Brown606e4e82014-09-18 15:22:26 -07001026 // its last frame of animation is solid black.
Jeff Brown3ee549c2014-09-22 20:14:39 -07001027 if (!setScreenState(Display.STATE_ON)) {
1028 return; // screen on blocked
1029 }
Jeff Brown606e4e82014-09-18 15:22:26 -07001030 if (USE_COLOR_FADE_ON_ANIMATION && mPowerRequest.isBrightOrDim()) {
1031 // Perform screen on animation.
1032 if (mPowerState.getColorFadeLevel() == 1.0f) {
1033 mPowerState.dismissColorFade();
1034 } else if (mPowerState.prepareColorFade(mContext,
1035 mColorFadeFadesConfig ?
1036 ColorFade.MODE_FADE :
1037 ColorFade.MODE_WARM_UP)) {
1038 mColorFadeOnAnimator.start();
1039 } else {
1040 mColorFadeOnAnimator.end();
1041 }
1042 } else {
1043 // Skip screen on animation.
1044 mPowerState.setColorFadeLevel(1.0f);
1045 mPowerState.dismissColorFade();
1046 }
Santos Cordon3107d292016-09-20 15:50:35 -07001047 } else if (target == Display.STATE_VR) {
1048 // Wait for brightness animation to complete beforehand when entering VR
1049 // from screen on to prevent a perceptible jump because brightness may operate
1050 // differently when the display is configured for dozing.
1051 if (mScreenBrightnessRampAnimator.isAnimating()
1052 && mPowerState.getScreenState() == Display.STATE_ON) {
1053 return;
1054 }
1055
1056 // Set screen state.
1057 if (!setScreenState(Display.STATE_VR)) {
1058 return; // screen on blocked
1059 }
1060
1061 // Dismiss the black surface without fanfare.
1062 mPowerState.setColorFadeLevel(1.0f);
1063 mPowerState.dismissColorFade();
Jeff Brown606e4e82014-09-18 15:22:26 -07001064 } else if (target == Display.STATE_DOZE) {
1065 // Want screen dozing.
1066 // Wait for brightness animation to complete beforehand when entering doze
1067 // from screen on to prevent a perceptible jump because brightness may operate
1068 // differently when the display is configured for dozing.
1069 if (mScreenBrightnessRampAnimator.isAnimating()
1070 && mPowerState.getScreenState() == Display.STATE_ON) {
1071 return;
1072 }
1073
Jeff Brown3ee549c2014-09-22 20:14:39 -07001074 // Set screen state.
1075 if (!setScreenState(Display.STATE_DOZE)) {
1076 return; // screen on blocked
1077 }
1078
1079 // Dismiss the black surface without fanfare.
Jeff Brown606e4e82014-09-18 15:22:26 -07001080 mPowerState.setColorFadeLevel(1.0f);
1081 mPowerState.dismissColorFade();
1082 } else if (target == Display.STATE_DOZE_SUSPEND) {
1083 // Want screen dozing and suspended.
1084 // Wait for brightness animation to complete beforehand unless already
1085 // suspended because we may not be able to change it after suspension.
1086 if (mScreenBrightnessRampAnimator.isAnimating()
1087 && mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) {
1088 return;
1089 }
1090
Jeff Brown3ee549c2014-09-22 20:14:39 -07001091 // If not already suspending, temporarily set the state to doze until the
1092 // screen on is unblocked, then suspend.
1093 if (mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) {
1094 if (!setScreenState(Display.STATE_DOZE)) {
1095 return; // screen on blocked
1096 }
1097 setScreenState(Display.STATE_DOZE_SUSPEND); // already on so can't block
1098 }
1099
1100 // Dismiss the black surface without fanfare.
Jeff Brown606e4e82014-09-18 15:22:26 -07001101 mPowerState.setColorFadeLevel(1.0f);
1102 mPowerState.dismissColorFade();
1103 } else {
1104 // Want screen off.
Jeff Brown3ee549c2014-09-22 20:14:39 -07001105 mPendingScreenOff = true;
Jeff Brown606e4e82014-09-18 15:22:26 -07001106 if (mPowerState.getColorFadeLevel() == 0.0f) {
1107 // Turn the screen off.
1108 // A black surface is already hiding the contents of the screen.
1109 setScreenState(Display.STATE_OFF);
Jeff Brown3ee549c2014-09-22 20:14:39 -07001110 mPendingScreenOff = false;
Michael Lentined73854d2015-09-25 10:55:26 -07001111 mPowerState.dismissColorFadeResources();
Jeff Brown606e4e82014-09-18 15:22:26 -07001112 } else if (performScreenOffTransition
1113 && mPowerState.prepareColorFade(mContext,
1114 mColorFadeFadesConfig ?
1115 ColorFade.MODE_FADE : ColorFade.MODE_COOL_DOWN)
1116 && mPowerState.getScreenState() != Display.STATE_OFF) {
1117 // Perform the screen off animation.
1118 mColorFadeOffAnimator.start();
1119 } else {
1120 // Skip the screen off animation and add a black surface to hide the
1121 // contents of the screen.
1122 mColorFadeOffAnimator.end();
1123 }
1124 }
1125 }
1126
Jeff Brown96307042012-07-27 15:51:34 -07001127 private final Runnable mCleanListener = new Runnable() {
1128 @Override
1129 public void run() {
1130 sendUpdatePowerState();
1131 }
1132 };
1133
1134 private void setProximitySensorEnabled(boolean enable) {
1135 if (enable) {
1136 if (!mProximitySensorEnabled) {
Jeff Brownec083212013-09-11 20:45:25 -07001137 // Register the listener.
1138 // Proximity sensor state already cleared initially.
Jeff Brown96307042012-07-27 15:51:34 -07001139 mProximitySensorEnabled = true;
Jeff Brown96307042012-07-27 15:51:34 -07001140 mSensorManager.registerListener(mProximitySensorListener, mProximitySensor,
1141 SensorManager.SENSOR_DELAY_NORMAL, mHandler);
1142 }
1143 } else {
1144 if (mProximitySensorEnabled) {
Jeff Brownec083212013-09-11 20:45:25 -07001145 // Unregister the listener.
1146 // Clear the proximity sensor state for next time.
Jeff Brown96307042012-07-27 15:51:34 -07001147 mProximitySensorEnabled = false;
1148 mProximity = PROXIMITY_UNKNOWN;
Jeff Brownec083212013-09-11 20:45:25 -07001149 mPendingProximity = PROXIMITY_UNKNOWN;
Jeff Brown96307042012-07-27 15:51:34 -07001150 mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
1151 mSensorManager.unregisterListener(mProximitySensorListener);
Jeff Brownec083212013-09-11 20:45:25 -07001152 clearPendingProximityDebounceTime(); // release wake lock (must be last)
Jeff Brown96307042012-07-27 15:51:34 -07001153 }
1154 }
1155 }
1156
1157 private void handleProximitySensorEvent(long time, boolean positive) {
Jeff Brownec083212013-09-11 20:45:25 -07001158 if (mProximitySensorEnabled) {
1159 if (mPendingProximity == PROXIMITY_NEGATIVE && !positive) {
1160 return; // no change
1161 }
1162 if (mPendingProximity == PROXIMITY_POSITIVE && positive) {
1163 return; // no change
1164 }
Jeff Brown96307042012-07-27 15:51:34 -07001165
Jeff Brownec083212013-09-11 20:45:25 -07001166 // Only accept a proximity sensor reading if it remains
1167 // stable for the entire debounce delay. We hold a wake lock while
1168 // debouncing the sensor.
1169 mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
1170 if (positive) {
1171 mPendingProximity = PROXIMITY_POSITIVE;
1172 setPendingProximityDebounceTime(
1173 time + PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY); // acquire wake lock
1174 } else {
1175 mPendingProximity = PROXIMITY_NEGATIVE;
1176 setPendingProximityDebounceTime(
1177 time + PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY); // acquire wake lock
1178 }
1179
1180 // Debounce the new sensor reading.
1181 debounceProximitySensor();
Jeff Brown93cbbb22012-10-04 13:18:36 -07001182 }
Jeff Brown96307042012-07-27 15:51:34 -07001183 }
1184
1185 private void debounceProximitySensor() {
Jeff Brownec083212013-09-11 20:45:25 -07001186 if (mProximitySensorEnabled
1187 && mPendingProximity != PROXIMITY_UNKNOWN
1188 && mPendingProximityDebounceTime >= 0) {
Jeff Brown96307042012-07-27 15:51:34 -07001189 final long now = SystemClock.uptimeMillis();
1190 if (mPendingProximityDebounceTime <= now) {
Jeff Brownec083212013-09-11 20:45:25 -07001191 // Sensor reading accepted. Apply the change then release the wake lock.
Jeff Brown96307042012-07-27 15:51:34 -07001192 mProximity = mPendingProximity;
Jeff Brownec083212013-09-11 20:45:25 -07001193 updatePowerState();
1194 clearPendingProximityDebounceTime(); // release wake lock (must be last)
Jeff Brown96307042012-07-27 15:51:34 -07001195 } else {
Jeff Brownec083212013-09-11 20:45:25 -07001196 // Need to wait a little longer.
1197 // Debounce again later. We continue holding a wake lock while waiting.
Jeff Brown96307042012-07-27 15:51:34 -07001198 Message msg = mHandler.obtainMessage(MSG_PROXIMITY_SENSOR_DEBOUNCED);
1199 msg.setAsynchronous(true);
1200 mHandler.sendMessageAtTime(msg, mPendingProximityDebounceTime);
1201 }
1202 }
1203 }
1204
Jeff Brownec083212013-09-11 20:45:25 -07001205 private void clearPendingProximityDebounceTime() {
1206 if (mPendingProximityDebounceTime >= 0) {
1207 mPendingProximityDebounceTime = -1;
Jeff Brown131206b2014-04-08 17:27:14 -07001208 mCallbacks.releaseSuspendBlocker(); // release wake lock
Jeff Brownec083212013-09-11 20:45:25 -07001209 }
1210 }
1211
1212 private void setPendingProximityDebounceTime(long debounceTime) {
1213 if (mPendingProximityDebounceTime < 0) {
Jeff Brown131206b2014-04-08 17:27:14 -07001214 mCallbacks.acquireSuspendBlocker(); // acquire wake lock
Jeff Brownec083212013-09-11 20:45:25 -07001215 }
1216 mPendingProximityDebounceTime = debounceTime;
1217 }
1218
Jeff Brownec083212013-09-11 20:45:25 -07001219 private void sendOnStateChangedWithWakelock() {
Jeff Brown131206b2014-04-08 17:27:14 -07001220 mCallbacks.acquireSuspendBlocker();
1221 mHandler.post(mOnStateChangedRunnable);
Jeff Brown96307042012-07-27 15:51:34 -07001222 }
1223
1224 private final Runnable mOnStateChangedRunnable = new Runnable() {
1225 @Override
1226 public void run() {
1227 mCallbacks.onStateChanged();
Jeff Brown131206b2014-04-08 17:27:14 -07001228 mCallbacks.releaseSuspendBlocker();
Jeff Brown96307042012-07-27 15:51:34 -07001229 }
1230 };
1231
Jeff Brownec083212013-09-11 20:45:25 -07001232 private void sendOnProximityPositiveWithWakelock() {
Jeff Brown131206b2014-04-08 17:27:14 -07001233 mCallbacks.acquireSuspendBlocker();
1234 mHandler.post(mOnProximityPositiveRunnable);
Jeff Brown93cbbb22012-10-04 13:18:36 -07001235 }
1236
1237 private final Runnable mOnProximityPositiveRunnable = new Runnable() {
1238 @Override
1239 public void run() {
1240 mCallbacks.onProximityPositive();
Jeff Brown131206b2014-04-08 17:27:14 -07001241 mCallbacks.releaseSuspendBlocker();
Jeff Brown93cbbb22012-10-04 13:18:36 -07001242 }
1243 };
1244
Jeff Brownec083212013-09-11 20:45:25 -07001245 private void sendOnProximityNegativeWithWakelock() {
Jeff Brown131206b2014-04-08 17:27:14 -07001246 mCallbacks.acquireSuspendBlocker();
1247 mHandler.post(mOnProximityNegativeRunnable);
Jeff Brown96307042012-07-27 15:51:34 -07001248 }
1249
1250 private final Runnable mOnProximityNegativeRunnable = new Runnable() {
1251 @Override
1252 public void run() {
1253 mCallbacks.onProximityNegative();
Jeff Brown131206b2014-04-08 17:27:14 -07001254 mCallbacks.releaseSuspendBlocker();
Jeff Brown96307042012-07-27 15:51:34 -07001255 }
1256 };
1257
Jeff Brownbd6e1502012-08-28 03:27:37 -07001258 public void dump(final PrintWriter pw) {
Jeff Brown96307042012-07-27 15:51:34 -07001259 synchronized (mLock) {
1260 pw.println();
Jeff Brown131206b2014-04-08 17:27:14 -07001261 pw.println("Display Power Controller Locked State:");
Jeff Brown96307042012-07-27 15:51:34 -07001262 pw.println(" mDisplayReadyLocked=" + mDisplayReadyLocked);
1263 pw.println(" mPendingRequestLocked=" + mPendingRequestLocked);
1264 pw.println(" mPendingRequestChangedLocked=" + mPendingRequestChangedLocked);
1265 pw.println(" mPendingWaitForNegativeProximityLocked="
1266 + mPendingWaitForNegativeProximityLocked);
1267 pw.println(" mPendingUpdatePowerStateLocked=" + mPendingUpdatePowerStateLocked);
1268 }
1269
1270 pw.println();
Jeff Brown131206b2014-04-08 17:27:14 -07001271 pw.println("Display Power Controller Configuration:");
Jeff Brown26875502014-01-30 21:47:47 -08001272 pw.println(" mScreenBrightnessDozeConfig=" + mScreenBrightnessDozeConfig);
Jeff Brown96307042012-07-27 15:51:34 -07001273 pw.println(" mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig);
Jeff Brown1bfd0f42014-08-22 01:59:06 -07001274 pw.println(" mScreenBrightnessDarkConfig=" + mScreenBrightnessDarkConfig);
Jeff Brownb76eebff2012-10-05 22:26:44 -07001275 pw.println(" mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum);
1276 pw.println(" mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum);
Jeff Brown2175e9c2014-09-12 16:11:07 -07001277 pw.println(" mUseSoftwareAutoBrightnessConfig=" + mUseSoftwareAutoBrightnessConfig);
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -07001278 pw.println(" mAllowAutoBrightnessWhileDozingConfig=" +
1279 mAllowAutoBrightnessWhileDozingConfig);
Jeff Brown2175e9c2014-09-12 16:11:07 -07001280 pw.println(" mColorFadeFadesConfig=" + mColorFadeFadesConfig);
Jeff Brown96307042012-07-27 15:51:34 -07001281
Jeff Brownbd6e1502012-08-28 03:27:37 -07001282 mHandler.runWithScissors(new Runnable() {
1283 @Override
1284 public void run() {
1285 dumpLocal(pw);
Jeff Brown96307042012-07-27 15:51:34 -07001286 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001287 }, 1000);
Jeff Brown96307042012-07-27 15:51:34 -07001288 }
1289
1290 private void dumpLocal(PrintWriter pw) {
1291 pw.println();
Jeff Brown131206b2014-04-08 17:27:14 -07001292 pw.println("Display Power Controller Thread State:");
Jeff Brown96307042012-07-27 15:51:34 -07001293 pw.println(" mPowerRequest=" + mPowerRequest);
1294 pw.println(" mWaitingForNegativeProximity=" + mWaitingForNegativeProximity);
1295
1296 pw.println(" mProximitySensor=" + mProximitySensor);
1297 pw.println(" mProximitySensorEnabled=" + mProximitySensorEnabled);
1298 pw.println(" mProximityThreshold=" + mProximityThreshold);
1299 pw.println(" mProximity=" + proximityToString(mProximity));
1300 pw.println(" mPendingProximity=" + proximityToString(mPendingProximity));
1301 pw.println(" mPendingProximityDebounceTime="
1302 + TimeUtils.formatUptime(mPendingProximityDebounceTime));
1303 pw.println(" mScreenOffBecauseOfProximity=" + mScreenOffBecauseOfProximity);
Jeff Brown970d4132014-07-19 11:33:47 -07001304 pw.println(" mAppliedAutoBrightness=" + mAppliedAutoBrightness);
1305 pw.println(" mAppliedDimming=" + mAppliedDimming);
1306 pw.println(" mAppliedLowPower=" + mAppliedLowPower);
Jeff Brown3ee549c2014-09-22 20:14:39 -07001307 pw.println(" mPendingScreenOnUnblocker=" + mPendingScreenOnUnblocker);
1308 pw.println(" mPendingScreenOff=" + mPendingScreenOff);
Michael Wright410fd1b2017-07-25 22:31:03 +01001309 pw.println(" mReportedToPolicy=" +
1310 reportedToPolicyToString(mReportedScreenStateToPolicy));
Jeff Brown96307042012-07-27 15:51:34 -07001311
Jeff Brown42558692014-05-20 22:02:46 -07001312 pw.println(" mScreenBrightnessRampAnimator.isAnimating()=" +
1313 mScreenBrightnessRampAnimator.isAnimating());
1314
Michael Lentine0839adb2014-07-29 18:47:56 -07001315 if (mColorFadeOnAnimator != null) {
1316 pw.println(" mColorFadeOnAnimator.isStarted()=" +
1317 mColorFadeOnAnimator.isStarted());
Jeff Brown96307042012-07-27 15:51:34 -07001318 }
Michael Lentine0839adb2014-07-29 18:47:56 -07001319 if (mColorFadeOffAnimator != null) {
1320 pw.println(" mColorFadeOffAnimator.isStarted()=" +
1321 mColorFadeOffAnimator.isStarted());
Jeff Brown96307042012-07-27 15:51:34 -07001322 }
1323
1324 if (mPowerState != null) {
1325 mPowerState.dump(pw);
1326 }
Michael Wright639c8be2014-01-17 18:29:12 -08001327
1328 if (mAutomaticBrightnessController != null) {
1329 mAutomaticBrightnessController.dump(pw);
1330 }
1331
Jeff Brown96307042012-07-27 15:51:34 -07001332 }
1333
1334 private static String proximityToString(int state) {
1335 switch (state) {
1336 case PROXIMITY_UNKNOWN:
1337 return "Unknown";
1338 case PROXIMITY_NEGATIVE:
1339 return "Negative";
1340 case PROXIMITY_POSITIVE:
1341 return "Positive";
1342 default:
1343 return Integer.toString(state);
1344 }
1345 }
1346
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001347 private static String reportedToPolicyToString(int state) {
1348 switch (state) {
1349 case REPORTED_TO_POLICY_SCREEN_OFF:
1350 return "REPORTED_TO_POLICY_SCREEN_OFF";
1351 case REPORTED_TO_POLICY_SCREEN_TURNING_ON:
1352 return "REPORTED_TO_POLICY_SCREEN_TURNING_ON";
1353 case REPORTED_TO_POLICY_SCREEN_ON:
1354 return "REPORTED_TO_POLICY_SCREEN_ON";
1355 default:
1356 return Integer.toString(state);
1357 }
1358 }
1359
Michael Wright639c8be2014-01-17 18:29:12 -08001360 private static Spline createAutoBrightnessSpline(int[] lux, int[] brightness) {
Erik Wolsheimerad82aca2016-06-28 14:51:07 -07001361 if (lux == null || lux.length == 0 || brightness == null || brightness.length == 0) {
1362 Slog.e(TAG, "Could not create auto-brightness spline.");
1363 return null;
1364 }
Michael Wright639c8be2014-01-17 18:29:12 -08001365 try {
1366 final int n = brightness.length;
1367 float[] x = new float[n];
1368 float[] y = new float[n];
1369 y[0] = normalizeAbsoluteBrightness(brightness[0]);
1370 for (int i = 1; i < n; i++) {
1371 x[i] = lux[i - 1];
1372 y[i] = normalizeAbsoluteBrightness(brightness[i]);
1373 }
1374
Michael Wright3e9a1342014-08-28 17:42:16 -07001375 Spline spline = Spline.createSpline(x, y);
Michael Wright639c8be2014-01-17 18:29:12 -08001376 if (DEBUG) {
1377 Slog.d(TAG, "Auto-brightness spline: " + spline);
1378 for (float v = 1f; v < lux[lux.length - 1] * 1.25f; v *= 1.25f) {
1379 Slog.d(TAG, String.format(" %7.1f: %7.1f", v, spline.interpolate(v)));
1380 }
1381 }
1382 return spline;
1383 } catch (IllegalArgumentException ex) {
1384 Slog.e(TAG, "Could not create auto-brightness spline.", ex);
1385 return null;
Jeff Brown96307042012-07-27 15:51:34 -07001386 }
Michael Wright639c8be2014-01-17 18:29:12 -08001387 }
1388
1389 private static float normalizeAbsoluteBrightness(int value) {
1390 return (float)clampAbsoluteBrightness(value) / PowerManager.BRIGHTNESS_ON;
1391 }
1392
1393 private static int clampAbsoluteBrightness(int value) {
1394 return MathUtils.constrain(value, PowerManager.BRIGHTNESS_OFF, PowerManager.BRIGHTNESS_ON);
Jeff Brown96307042012-07-27 15:51:34 -07001395 }
1396
Jeff Brown96307042012-07-27 15:51:34 -07001397 private final class DisplayControllerHandler extends Handler {
1398 public DisplayControllerHandler(Looper looper) {
Jeff Browna2910d02012-08-25 12:29:46 -07001399 super(looper, null, true /*async*/);
Jeff Brown96307042012-07-27 15:51:34 -07001400 }
1401
1402 @Override
1403 public void handleMessage(Message msg) {
1404 switch (msg.what) {
1405 case MSG_UPDATE_POWER_STATE:
1406 updatePowerState();
1407 break;
1408
1409 case MSG_PROXIMITY_SENSOR_DEBOUNCED:
1410 debounceProximitySensor();
1411 break;
Jeff Brown3ee549c2014-09-22 20:14:39 -07001412
1413 case MSG_SCREEN_ON_UNBLOCKED:
1414 if (mPendingScreenOnUnblocker == msg.obj) {
1415 unblockScreenOn();
1416 updatePowerState();
1417 }
1418 break;
Jorim Jaggi51304d72017-05-17 17:25:32 +02001419 case MSG_SCREEN_OFF_UNBLOCKED:
1420 if (mPendingScreenOffUnblocker == msg.obj) {
1421 unblockScreenOff();
1422 updatePowerState();
1423 }
1424 break;
Jeff Brown96307042012-07-27 15:51:34 -07001425 }
1426 }
1427 }
1428
1429 private final SensorEventListener mProximitySensorListener = new SensorEventListener() {
1430 @Override
1431 public void onSensorChanged(SensorEvent event) {
1432 if (mProximitySensorEnabled) {
1433 final long time = SystemClock.uptimeMillis();
1434 final float distance = event.values[0];
1435 boolean positive = distance >= 0.0f && distance < mProximityThreshold;
1436 handleProximitySensorEvent(time, positive);
1437 }
1438 }
1439
1440 @Override
1441 public void onAccuracyChanged(Sensor sensor, int accuracy) {
1442 // Not used.
1443 }
1444 };
Jeff Brown3ee549c2014-09-22 20:14:39 -07001445
1446 private final class ScreenOnUnblocker implements WindowManagerPolicy.ScreenOnListener {
1447 @Override
1448 public void onScreenOn() {
1449 Message msg = mHandler.obtainMessage(MSG_SCREEN_ON_UNBLOCKED, this);
1450 msg.setAsynchronous(true);
1451 mHandler.sendMessage(msg);
1452 }
1453 }
Jorim Jaggi51304d72017-05-17 17:25:32 +02001454
1455 private final class ScreenOffUnblocker implements WindowManagerPolicy.ScreenOffListener {
1456
1457 @Override
1458 public void onScreenOff() {
1459 Message msg = mHandler.obtainMessage(MSG_SCREEN_OFF_UNBLOCKED, this);
1460 msg.setAsynchronous(true);
1461 mHandler.sendMessage(msg);
1462 }
1463 }
Jeff Brown96307042012-07-27 15:51:34 -07001464}