blob: f930b523e626c052593934a359c0cba63318e627 [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
Narayan Kamath38819982017-07-06 18:15:30 +010019import android.app.ActivityManager;
Jeff Brown131206b2014-04-08 17:27:14 -070020import com.android.internal.app.IBatteryStats;
21import com.android.server.LocalServices;
22import com.android.server.am.BatteryStatsService;
Jeff Brown96307042012-07-27 15:51:34 -070023
24import android.animation.Animator;
25import android.animation.ObjectAnimator;
26import android.content.Context;
27import android.content.res.Resources;
28import android.hardware.Sensor;
29import android.hardware.SensorEvent;
30import android.hardware.SensorEventListener;
31import android.hardware.SensorManager;
Jeff Brown131206b2014-04-08 17:27:14 -070032import android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks;
33import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
Jeff Brown96307042012-07-27 15:51:34 -070034import android.os.Handler;
35import android.os.Looper;
36import android.os.Message;
Jeff Brown330560f2012-08-21 22:10:57 -070037import android.os.PowerManager;
Jeff Brown131206b2014-04-08 17:27:14 -070038import android.os.RemoteException;
Jeff Brown96307042012-07-27 15:51:34 -070039import android.os.SystemClock;
Jeff Brown3edf5272014-08-14 19:25:14 -070040import android.os.Trace;
Michael Wright41a5cdf2013-11-13 16:18:32 -080041import android.util.MathUtils;
Jeff Brown96307042012-07-27 15:51:34 -070042import android.util.Slog;
Jeff Brown1a30b552012-08-16 01:31:11 -070043import android.util.Spline;
Jeff Brown96307042012-07-27 15:51:34 -070044import android.util.TimeUtils;
Jeff Brown037c33e2014-04-09 00:31:55 -070045import android.view.Display;
Jeff Brown3ee549c2014-09-22 20:14:39 -070046import android.view.WindowManagerPolicy;
Jeff Brown96307042012-07-27 15:51:34 -070047
48import java.io.PrintWriter;
Jeff Brown96307042012-07-27 15:51:34 -070049
50/**
51 * Controls the power state of the display.
52 *
53 * Handles the proximity sensor, light sensor, and animations between states
54 * including the screen off animation.
55 *
56 * This component acts independently of the rest of the power manager service.
57 * In particular, it does not share any state and it only communicates
58 * via asynchronous callbacks to inform the power manager that something has
59 * changed.
60 *
61 * Everything this class does internally is serialized on its handler although
62 * it may be accessed by other threads from the outside.
63 *
64 * Note that the power manager service guarantees that it will hold a suspend
65 * blocker as long as the display is not ready. So most of the work done here
66 * does not need to worry about holding a suspend blocker unless it happens
67 * independently of the display ready signal.
Michael Lentine0839adb2014-07-29 18:47:56 -070068 *
Jeff Brown3ee549c2014-09-22 20:14:39 -070069 * For debugging, you can make the color fade and brightness animations run
Jeff Brown96307042012-07-27 15:51:34 -070070 * slower by changing the "animator duration scale" option in Development Settings.
71 */
Michael Wright639c8be2014-01-17 18:29:12 -080072final class DisplayPowerController implements AutomaticBrightnessController.Callbacks {
Jeff Brown96307042012-07-27 15:51:34 -070073 private static final String TAG = "DisplayPowerController";
Jeff Browna576b4d2015-04-23 19:58:06 -070074 private static final String SCREEN_ON_BLOCKED_TRACE_NAME = "Screen on blocked";
Jorim Jaggi51304d72017-05-17 17:25:32 +020075 private static final String SCREEN_OFF_BLOCKED_TRACE_NAME = "Screen off blocked";
Jeff Brown96307042012-07-27 15:51:34 -070076
Julius D'souza428aed02016-08-07 19:08:30 -070077 private static final boolean DEBUG = false;
Jeff Brown96307042012-07-27 15:51:34 -070078 private static final boolean DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT = false;
Jeff Brown96307042012-07-27 15:51:34 -070079
Jeff Brown3ee549c2014-09-22 20:14:39 -070080 // If true, uses the color fade on animation.
Jeff Brown13c589b2012-08-16 16:20:54 -070081 // We might want to turn this off if we cannot get a guarantee that the screen
82 // actually turns on and starts showing new content after the call to set the
Jeff Brown5356c7dc2012-08-20 20:17:36 -070083 // screen state returns. Playing the animation can also be somewhat slow.
Michael Lentine0839adb2014-07-29 18:47:56 -070084 private static final boolean USE_COLOR_FADE_ON_ANIMATION = false;
Jeff Brown13c589b2012-08-16 16:20:54 -070085
Jeff Brownb76eebff2012-10-05 22:26:44 -070086 // The minimum reduction in brightness when dimmed.
87 private static final int SCREEN_DIM_MINIMUM_REDUCTION = 10;
88
Michael Lentine0839adb2014-07-29 18:47:56 -070089 private static final int COLOR_FADE_ON_ANIMATION_DURATION_MILLIS = 250;
Michael Lentine0c9a62d2014-08-20 09:19:07 -070090 private static final int COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS = 400;
Jeff Brown96307042012-07-27 15:51:34 -070091
92 private static final int MSG_UPDATE_POWER_STATE = 1;
93 private static final int MSG_PROXIMITY_SENSOR_DEBOUNCED = 2;
Jeff Brown3ee549c2014-09-22 20:14:39 -070094 private static final int MSG_SCREEN_ON_UNBLOCKED = 3;
Jorim Jaggi51304d72017-05-17 17:25:32 +020095 private static final int MSG_SCREEN_OFF_UNBLOCKED = 4;
Jeff Brown96307042012-07-27 15:51:34 -070096
97 private static final int PROXIMITY_UNKNOWN = -1;
98 private static final int PROXIMITY_NEGATIVE = 0;
99 private static final int PROXIMITY_POSITIVE = 1;
100
Jeff Brown93cbbb22012-10-04 13:18:36 -0700101 // Proximity sensor debounce delay in milliseconds for positive or negative transitions.
102 private static final int PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY = 0;
Jeff Brownec083212013-09-11 20:45:25 -0700103 private static final int PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY = 250;
Jeff Brown96307042012-07-27 15:51:34 -0700104
105 // Trigger proximity if distance is less than 5 cm.
106 private static final float TYPICAL_PROXIMITY_THRESHOLD = 5.0f;
107
Julius D'souzad5105dd2017-06-02 11:03:53 -0700108 // State machine constants for tracking initial brightness ramp skipping when enabled.
109 private static final int RAMP_STATE_SKIP_NONE = 0;
110 private static final int RAMP_STATE_SKIP_INITIAL = 1;
111 private static final int RAMP_STATE_SKIP_AUTOBRIGHT = 2;
112
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700113 private static final int REPORTED_TO_POLICY_SCREEN_OFF = 0;
114 private static final int REPORTED_TO_POLICY_SCREEN_TURNING_ON = 1;
115 private static final int REPORTED_TO_POLICY_SCREEN_ON = 2;
Jorim Jaggi51304d72017-05-17 17:25:32 +0200116 private static final int REPORTED_TO_POLICY_SCREEN_TURNING_OFF = 3;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700117
Jeff Brown96307042012-07-27 15:51:34 -0700118 private final Object mLock = new Object();
119
Michael Lentine0839adb2014-07-29 18:47:56 -0700120 private final Context mContext;
121
Jeff Brown96307042012-07-27 15:51:34 -0700122 // Our handler.
123 private final DisplayControllerHandler mHandler;
124
125 // Asynchronous callbacks into the power manager service.
126 // Only invoked from the handler thread while no locks are held.
Jeff Brown131206b2014-04-08 17:27:14 -0700127 private final DisplayPowerCallbacks mCallbacks;
128
129 // Battery stats.
130 private final IBatteryStats mBatteryStats;
Jeff Brown96307042012-07-27 15:51:34 -0700131
Jeff Brown96307042012-07-27 15:51:34 -0700132 // The sensor manager.
133 private final SensorManager mSensorManager;
134
Jeff Brown3ee549c2014-09-22 20:14:39 -0700135 // The window manager policy.
136 private final WindowManagerPolicy mWindowManagerPolicy;
137
Jeff Brown037c33e2014-04-09 00:31:55 -0700138 // The display blanker.
139 private final DisplayBlanker mBlanker;
140
Jeff Brown96307042012-07-27 15:51:34 -0700141 // The proximity sensor, or null if not available or needed.
142 private Sensor mProximitySensor;
143
Jeff Brown26875502014-01-30 21:47:47 -0800144 // The doze screen brightness.
145 private final int mScreenBrightnessDozeConfig;
146
Jeff Brown96307042012-07-27 15:51:34 -0700147 // The dim screen brightness.
148 private final int mScreenBrightnessDimConfig;
149
Jeff Brown1bfd0f42014-08-22 01:59:06 -0700150 // The minimum screen brightness to use in a very dark room.
151 private final int mScreenBrightnessDarkConfig;
152
Jeff Brownb76eebff2012-10-05 22:26:44 -0700153 // The minimum allowed brightness.
154 private final int mScreenBrightnessRangeMinimum;
155
156 // The maximum allowed brightness.
157 private final int mScreenBrightnessRangeMaximum;
158
Jeff Brown330560f2012-08-21 22:10:57 -0700159 // True if auto-brightness should be used.
Jeff Brown96307042012-07-27 15:51:34 -0700160 private boolean mUseSoftwareAutoBrightnessConfig;
Jeff Brown330560f2012-08-21 22:10:57 -0700161
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700162 // True if should use light sensor to automatically determine doze screen brightness.
163 private final boolean mAllowAutoBrightnessWhileDozingConfig;
164
Narayan Kamath38819982017-07-06 18:15:30 +0100165 // Whether or not the color fade on screen on / off is enabled.
166 private final boolean mColorFadeEnabled;
167
Jeff Brown252c2062012-10-08 16:21:01 -0700168 // True if we should fade the screen while turning it off, false if we should play
Jeff Brown3ee549c2014-09-22 20:14:39 -0700169 // a stylish color fade animation instead.
Michael Lentine0839adb2014-07-29 18:47:56 -0700170 private boolean mColorFadeFadesConfig;
Jeff Browna52772f2012-10-04 18:38:09 -0700171
Michael Wrightc3e6af82017-07-25 22:31:03 +0100172 // True if we need to fake a transition to off when coming out of a doze state.
173 // Some display hardware will blank itself when coming out of doze in order to hide
174 // artifacts. For these displays we fake a transition into OFF so that policy can appropriately
175 // blank itself and begin an appropriate power on animation.
176 private boolean mDisplayBlanksAfterDozeConfig;
Michael Wright05e76fe2017-07-20 18:18:33 +0100177
Michael Wright63a40062017-07-26 01:10:59 +0100178 // True if there are only buckets of brightness values when the display is in the doze state,
179 // rather than a full range of values. If this is true, then we'll avoid animating the screen
180 // brightness since it'd likely be multiple jarring brightness transitions instead of just one
181 // to reach the final state.
182 private boolean mBrightnessBucketsInDozeConfig;
183
Jeff Brown96307042012-07-27 15:51:34 -0700184 // The pending power request.
185 // Initially null until the first call to requestPowerState.
186 // Guarded by mLock.
187 private DisplayPowerRequest mPendingRequestLocked;
188
189 // True if a request has been made to wait for the proximity sensor to go negative.
190 // Guarded by mLock.
191 private boolean mPendingWaitForNegativeProximityLocked;
192
193 // True if the pending power request or wait for negative proximity flag
194 // has been changed since the last update occurred.
195 // Guarded by mLock.
196 private boolean mPendingRequestChangedLocked;
197
198 // Set to true when the important parts of the pending power request have been applied.
199 // The important parts are mainly the screen state. Brightness changes may occur
200 // concurrently.
201 // Guarded by mLock.
202 private boolean mDisplayReadyLocked;
203
204 // Set to true if a power state update is required.
205 // Guarded by mLock.
206 private boolean mPendingUpdatePowerStateLocked;
207
208 /* The following state must only be accessed by the handler thread. */
209
210 // The currently requested power state.
211 // The power controller will progressively update its internal state to match
212 // the requested power state. Initially null until the first update.
213 private DisplayPowerRequest mPowerRequest;
214
215 // The current power state.
216 // Must only be accessed on the handler thread.
217 private DisplayPowerState mPowerState;
218
219 // True if the device should wait for negative proximity sensor before
220 // waking up the screen. This is set to false as soon as a negative
221 // proximity sensor measurement is observed or when the device is forced to
222 // go to sleep by the user. While true, the screen remains off.
223 private boolean mWaitingForNegativeProximity;
224
225 // The actual proximity sensor threshold value.
226 private float mProximityThreshold;
227
228 // Set to true if the proximity sensor listener has been registered
229 // with the sensor manager.
230 private boolean mProximitySensorEnabled;
231
232 // The debounced proximity sensor state.
233 private int mProximity = PROXIMITY_UNKNOWN;
234
235 // The raw non-debounced proximity sensor state.
236 private int mPendingProximity = PROXIMITY_UNKNOWN;
Jeff Brownec083212013-09-11 20:45:25 -0700237 private long mPendingProximityDebounceTime = -1; // -1 if fully debounced
Jeff Brown96307042012-07-27 15:51:34 -0700238
239 // True if the screen was turned off because of the proximity sensor.
240 // When the screen turns on again, we report user activity to the power manager.
241 private boolean mScreenOffBecauseOfProximity;
242
Jeff Brown3ee549c2014-09-22 20:14:39 -0700243 // The currently active screen on unblocker. This field is non-null whenever
244 // we are waiting for a callback to release it and unblock the screen.
245 private ScreenOnUnblocker mPendingScreenOnUnblocker;
Jorim Jaggi51304d72017-05-17 17:25:32 +0200246 private ScreenOffUnblocker mPendingScreenOffUnblocker;
Jeff Brown3ee549c2014-09-22 20:14:39 -0700247
248 // True if we were in the process of turning off the screen.
249 // This allows us to recover more gracefully from situations where we abort
250 // turning off the screen.
251 private boolean mPendingScreenOff;
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700252
Jeff Brown0a434772014-09-30 14:42:27 -0700253 // True if we have unfinished business and are holding a suspend blocker.
254 private boolean mUnfinishedBusiness;
255
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700256 // The elapsed real time when the screen on was blocked.
257 private long mScreenOnBlockStartRealTime;
Jorim Jaggi51304d72017-05-17 17:25:32 +0200258 private long mScreenOffBlockStartRealTime;
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700259
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700260 // Screen state we reported to policy. Must be one of REPORTED_TO_POLICY_SCREEN_* fields.
261 private int mReportedScreenStateToPolicy;
Jeff Browne1633ad2015-06-22 19:24:24 -0700262
Julius D'souzad5105dd2017-06-02 11:03:53 -0700263 // If the last recorded screen state was dozing or not.
264 private boolean mDozing;
265
Jeff Brown970d4132014-07-19 11:33:47 -0700266 // Remembers whether certain kinds of brightness adjustments
267 // were recently applied so that we can decide how to transition.
268 private boolean mAppliedAutoBrightness;
269 private boolean mAppliedDimming;
270 private boolean mAppliedLowPower;
Jeff Brown96307042012-07-27 15:51:34 -0700271
Julius D'souzafeadad12016-08-05 14:34:38 -0700272 // Brightness animation ramp rates in brightness units per second
Prashant Malani99e6d432016-03-29 16:32:37 -0700273 private final int mBrightnessRampRateFast;
Julius D'souzafeadad12016-08-05 14:34:38 -0700274 private final int mBrightnessRampRateSlow;
Prashant Malani99e6d432016-03-29 16:32:37 -0700275
Julius D'souzad5105dd2017-06-02 11:03:53 -0700276 // Whether or not to skip the initial brightness ramps into STATE_ON.
277 private final boolean mSkipScreenOnBrightnessRamp;
278
279 // A record of state for skipping brightness ramps.
280 private int mSkipRampState = RAMP_STATE_SKIP_NONE;
281
282 // The first autobrightness value set when entering RAMP_STATE_SKIP_INITIAL.
283 private int mInitialAutoBrightness;
284
Michael Wright639c8be2014-01-17 18:29:12 -0800285 // The controller for the automatic brightness level.
286 private AutomaticBrightnessController mAutomaticBrightnessController;
287
Jeff Brown96307042012-07-27 15:51:34 -0700288 // Animators.
Michael Lentine0839adb2014-07-29 18:47:56 -0700289 private ObjectAnimator mColorFadeOnAnimator;
290 private ObjectAnimator mColorFadeOffAnimator;
Jeff Brown96307042012-07-27 15:51:34 -0700291 private RampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator;
292
293 /**
294 * Creates the display power controller.
295 */
Jeff Brown131206b2014-04-08 17:27:14 -0700296 public DisplayPowerController(Context context,
Jeff Brown037c33e2014-04-09 00:31:55 -0700297 DisplayPowerCallbacks callbacks, Handler handler,
298 SensorManager sensorManager, DisplayBlanker blanker) {
Jeff Brown131206b2014-04-08 17:27:14 -0700299 mHandler = new DisplayControllerHandler(handler.getLooper());
Jeff Brown96307042012-07-27 15:51:34 -0700300 mCallbacks = callbacks;
Jeff Brown96307042012-07-27 15:51:34 -0700301
Jeff Brown131206b2014-04-08 17:27:14 -0700302 mBatteryStats = BatteryStatsService.getService();
Jeff Brown3b971592013-01-09 18:46:37 -0800303 mSensorManager = sensorManager;
Jeff Brown3ee549c2014-09-22 20:14:39 -0700304 mWindowManagerPolicy = LocalServices.getService(WindowManagerPolicy.class);
Jeff Brown037c33e2014-04-09 00:31:55 -0700305 mBlanker = blanker;
Michael Lentine0839adb2014-07-29 18:47:56 -0700306 mContext = context;
Jeff Brown96307042012-07-27 15:51:34 -0700307
308 final Resources resources = context.getResources();
Jeff Brown1bfd0f42014-08-22 01:59:06 -0700309 final int screenBrightnessSettingMinimum = clampAbsoluteBrightness(resources.getInteger(
310 com.android.internal.R.integer.config_screenBrightnessSettingMinimum));
Jeff Brownb76eebff2012-10-05 22:26:44 -0700311
Jeff Brown26875502014-01-30 21:47:47 -0800312 mScreenBrightnessDozeConfig = clampAbsoluteBrightness(resources.getInteger(
313 com.android.internal.R.integer.config_screenBrightnessDoze));
314
Jeff Brownb76eebff2012-10-05 22:26:44 -0700315 mScreenBrightnessDimConfig = clampAbsoluteBrightness(resources.getInteger(
316 com.android.internal.R.integer.config_screenBrightnessDim));
317
Jeff Brown1bfd0f42014-08-22 01:59:06 -0700318 mScreenBrightnessDarkConfig = clampAbsoluteBrightness(resources.getInteger(
319 com.android.internal.R.integer.config_screenBrightnessDark));
320 if (mScreenBrightnessDarkConfig > mScreenBrightnessDimConfig) {
321 Slog.w(TAG, "Expected config_screenBrightnessDark ("
322 + mScreenBrightnessDarkConfig + ") to be less than or equal to "
323 + "config_screenBrightnessDim (" + mScreenBrightnessDimConfig + ").");
324 }
liulvpingd01db542016-10-20 19:51:38 +0800325 if (mScreenBrightnessDarkConfig > screenBrightnessSettingMinimum) {
Jeff Brown1bfd0f42014-08-22 01:59:06 -0700326 Slog.w(TAG, "Expected config_screenBrightnessDark ("
327 + mScreenBrightnessDarkConfig + ") to be less than or equal to "
328 + "config_screenBrightnessSettingMinimum ("
329 + screenBrightnessSettingMinimum + ").");
330 }
331
332 int screenBrightnessRangeMinimum = Math.min(Math.min(
333 screenBrightnessSettingMinimum, mScreenBrightnessDimConfig),
334 mScreenBrightnessDarkConfig);
Michael Wright639c8be2014-01-17 18:29:12 -0800335
336 mScreenBrightnessRangeMaximum = PowerManager.BRIGHTNESS_ON;
Jeff Brownb76eebff2012-10-05 22:26:44 -0700337
Jeff Brown96307042012-07-27 15:51:34 -0700338 mUseSoftwareAutoBrightnessConfig = resources.getBoolean(
339 com.android.internal.R.bool.config_automatic_brightness_available);
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700340
341 mAllowAutoBrightnessWhileDozingConfig = resources.getBoolean(
342 com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing);
343
Prashant Malani99e6d432016-03-29 16:32:37 -0700344 mBrightnessRampRateFast = resources.getInteger(
345 com.android.internal.R.integer.config_brightness_ramp_rate_fast);
Julius D'souzafeadad12016-08-05 14:34:38 -0700346 mBrightnessRampRateSlow = resources.getInteger(
347 com.android.internal.R.integer.config_brightness_ramp_rate_slow);
Julius D'souzad5105dd2017-06-02 11:03:53 -0700348 mSkipScreenOnBrightnessRamp = resources.getBoolean(
349 com.android.internal.R.bool.config_skipScreenOnBrightnessRamp);
Prashant Malani99e6d432016-03-29 16:32:37 -0700350
Filip Gruszczynskid81ecd12015-02-06 12:38:47 -0800351 int lightSensorRate = resources.getInteger(
352 com.android.internal.R.integer.config_autoBrightnessLightSensorRate);
Julius D'souza5d717092016-10-24 19:26:45 -0700353 int initialLightSensorRate = resources.getInteger(
354 com.android.internal.R.integer.config_autoBrightnessInitialLightSensorRate);
355 if (initialLightSensorRate == -1) {
356 initialLightSensorRate = lightSensorRate;
357 } else if (initialLightSensorRate > lightSensorRate) {
358 Slog.w(TAG, "Expected config_autoBrightnessInitialLightSensorRate ("
359 + initialLightSensorRate + ") to be less than or equal to "
360 + "config_autoBrightnessLightSensorRate (" + lightSensorRate + ").");
361 }
Filip Gruszczynskid81ecd12015-02-06 12:38:47 -0800362 long brighteningLightDebounce = resources.getInteger(
363 com.android.internal.R.integer.config_autoBrightnessBrighteningLightDebounce);
364 long darkeningLightDebounce = resources.getInteger(
365 com.android.internal.R.integer.config_autoBrightnessDarkeningLightDebounce);
366 boolean autoBrightnessResetAmbientLuxAfterWarmUp = resources.getBoolean(
367 com.android.internal.R.bool.config_autoBrightnessResetAmbientLuxAfterWarmUp);
Zoran Jovanovic6fc42f52015-12-10 17:01:16 +0100368 int ambientLightHorizon = resources.getInteger(
369 com.android.internal.R.integer.config_autoBrightnessAmbientLightHorizon);
370 float autoBrightnessAdjustmentMaxGamma = resources.getFraction(
371 com.android.internal.R.fraction.config_autoBrightnessAdjustmentMaxGamma,
372 1, 1);
Filip Gruszczynskid81ecd12015-02-06 12:38:47 -0800373
Julius D'souza428aed02016-08-07 19:08:30 -0700374 int[] brightLevels = resources.getIntArray(
375 com.android.internal.R.array.config_dynamicHysteresisBrightLevels);
376 int[] darkLevels = resources.getIntArray(
377 com.android.internal.R.array.config_dynamicHysteresisDarkLevels);
378 int[] luxLevels = resources.getIntArray(
379 com.android.internal.R.array.config_dynamicHysteresisLuxLevels);
380 HysteresisLevels dynamicHysteresis = new HysteresisLevels(
381 brightLevels, darkLevels, luxLevels);
382
Jeff Brown96307042012-07-27 15:51:34 -0700383 if (mUseSoftwareAutoBrightnessConfig) {
Jeff Brown1a30b552012-08-16 01:31:11 -0700384 int[] lux = resources.getIntArray(
Jeff Brown96307042012-07-27 15:51:34 -0700385 com.android.internal.R.array.config_autoBrightnessLevels);
Jeff Brown1a30b552012-08-16 01:31:11 -0700386 int[] screenBrightness = resources.getIntArray(
Jeff Brown96307042012-07-27 15:51:34 -0700387 com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
Michael Wright639c8be2014-01-17 18:29:12 -0800388 int lightSensorWarmUpTimeConfig = resources.getInteger(
389 com.android.internal.R.integer.config_lightSensorWarmupTime);
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700390 final float dozeScaleFactor = resources.getFraction(
391 com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor,
392 1, 1);
Jeff Brown1a30b552012-08-16 01:31:11 -0700393
Michael Wright639c8be2014-01-17 18:29:12 -0800394 Spline screenAutoBrightnessSpline = createAutoBrightnessSpline(lux, screenBrightness);
395 if (screenAutoBrightnessSpline == null) {
Jeff Brown96307042012-07-27 15:51:34 -0700396 Slog.e(TAG, "Error in config.xml. config_autoBrightnessLcdBacklightValues "
Jeff Brown1a30b552012-08-16 01:31:11 -0700397 + "(size " + screenBrightness.length + ") "
398 + "must be monotic and have exactly one more entry than "
399 + "config_autoBrightnessLevels (size " + lux.length + ") "
400 + "which must be strictly increasing. "
Jeff Brown96307042012-07-27 15:51:34 -0700401 + "Auto-brightness will be disabled.");
402 mUseSoftwareAutoBrightnessConfig = false;
Jeff Brownb76eebff2012-10-05 22:26:44 -0700403 } else {
Jeff Brown1bfd0f42014-08-22 01:59:06 -0700404 int bottom = clampAbsoluteBrightness(screenBrightness[0]);
405 if (mScreenBrightnessDarkConfig > bottom) {
406 Slog.w(TAG, "config_screenBrightnessDark (" + mScreenBrightnessDarkConfig
407 + ") should be less than or equal to the first value of "
408 + "config_autoBrightnessLcdBacklightValues ("
409 + bottom + ").");
410 }
411 if (bottom < screenBrightnessRangeMinimum) {
412 screenBrightnessRangeMinimum = bottom;
Jeff Brownb76eebff2012-10-05 22:26:44 -0700413 }
Jeff Brown131206b2014-04-08 17:27:14 -0700414 mAutomaticBrightnessController = new AutomaticBrightnessController(this,
415 handler.getLooper(), sensorManager, screenAutoBrightnessSpline,
Michael Wright639c8be2014-01-17 18:29:12 -0800416 lightSensorWarmUpTimeConfig, screenBrightnessRangeMinimum,
Filip Gruszczynskid81ecd12015-02-06 12:38:47 -0800417 mScreenBrightnessRangeMaximum, dozeScaleFactor, lightSensorRate,
Julius D'souza5d717092016-10-24 19:26:45 -0700418 initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce,
Julius D'souza428aed02016-08-07 19:08:30 -0700419 autoBrightnessResetAmbientLuxAfterWarmUp, ambientLightHorizon,
420 autoBrightnessAdjustmentMaxGamma, dynamicHysteresis);
Jeff Brown96307042012-07-27 15:51:34 -0700421 }
Jeff Brown96307042012-07-27 15:51:34 -0700422 }
423
Michael Wright639c8be2014-01-17 18:29:12 -0800424 mScreenBrightnessRangeMinimum = screenBrightnessRangeMinimum;
Jeff Brownb76eebff2012-10-05 22:26:44 -0700425
Narayan Kamath38819982017-07-06 18:15:30 +0100426
427 mColorFadeEnabled = !ActivityManager.isLowRamDeviceStatic();
Michael Lentine0839adb2014-07-29 18:47:56 -0700428 mColorFadeFadesConfig = resources.getBoolean(
Jeff Browna52772f2012-10-04 18:38:09 -0700429 com.android.internal.R.bool.config_animateScreenLights);
430
Michael Wrightc3e6af82017-07-25 22:31:03 +0100431 mDisplayBlanksAfterDozeConfig = resources.getBoolean(
432 com.android.internal.R.bool.config_displayBlanksAfterDoze);
Michael Wright05e76fe2017-07-20 18:18:33 +0100433
Michael Wright63a40062017-07-26 01:10:59 +0100434 mBrightnessBucketsInDozeConfig = resources.getBoolean(
435 com.android.internal.R.bool.config_displayBrightnessBucketsInDoze);
436
Jeff Brown96307042012-07-27 15:51:34 -0700437 if (!DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) {
438 mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
439 if (mProximitySensor != null) {
440 mProximityThreshold = Math.min(mProximitySensor.getMaximumRange(),
441 TYPICAL_PROXIMITY_THRESHOLD);
442 }
443 }
444
Jeff Brown1a30b552012-08-16 01:31:11 -0700445 }
446
Jeff Brown96307042012-07-27 15:51:34 -0700447 /**
448 * Returns true if the proximity sensor screen-off function is available.
449 */
450 public boolean isProximitySensorAvailable() {
451 return mProximitySensor != null;
452 }
453
454 /**
455 * Requests a new power state.
456 * The controller makes a copy of the provided object and then
457 * begins adjusting the power state to match what was requested.
458 *
459 * @param request The requested power state.
460 * @param waitForNegativeProximity If true, issues a request to wait for
461 * negative proximity before turning the screen back on, assuming the screen
462 * was turned off by the proximity sensor.
463 * @return True if display is ready, false if there are important changes that must
464 * be made asynchronously (such as turning the screen on), in which case the caller
Jeff Brown606e4e82014-09-18 15:22:26 -0700465 * should grab a wake lock, watch for {@link DisplayPowerCallbacks#onStateChanged()}
466 * then try the request again later until the state converges.
Jeff Brown96307042012-07-27 15:51:34 -0700467 */
468 public boolean requestPowerState(DisplayPowerRequest request,
469 boolean waitForNegativeProximity) {
470 if (DEBUG) {
471 Slog.d(TAG, "requestPowerState: "
472 + request + ", waitForNegativeProximity=" + waitForNegativeProximity);
473 }
474
475 synchronized (mLock) {
476 boolean changed = false;
477
478 if (waitForNegativeProximity
479 && !mPendingWaitForNegativeProximityLocked) {
480 mPendingWaitForNegativeProximityLocked = true;
481 changed = true;
482 }
483
484 if (mPendingRequestLocked == null) {
485 mPendingRequestLocked = new DisplayPowerRequest(request);
486 changed = true;
487 } else if (!mPendingRequestLocked.equals(request)) {
488 mPendingRequestLocked.copyFrom(request);
489 changed = true;
490 }
491
492 if (changed) {
493 mDisplayReadyLocked = false;
494 }
495
496 if (changed && !mPendingRequestChangedLocked) {
497 mPendingRequestChangedLocked = true;
498 sendUpdatePowerStateLocked();
499 }
500
501 return mDisplayReadyLocked;
502 }
503 }
504
505 private void sendUpdatePowerState() {
506 synchronized (mLock) {
507 sendUpdatePowerStateLocked();
508 }
509 }
510
511 private void sendUpdatePowerStateLocked() {
512 if (!mPendingUpdatePowerStateLocked) {
513 mPendingUpdatePowerStateLocked = true;
514 Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE);
515 msg.setAsynchronous(true);
516 mHandler.sendMessage(msg);
517 }
518 }
519
520 private void initialize() {
Jeff Brown037c33e2014-04-09 00:31:55 -0700521 // Initialize the power state object for the default display.
522 // In the future, we might manage multiple displays independently.
523 mPowerState = new DisplayPowerState(mBlanker,
Narayan Kamath38819982017-07-06 18:15:30 +0100524 mColorFadeEnabled ? new ColorFade(Display.DEFAULT_DISPLAY) : null);
Jeff Brown96307042012-07-27 15:51:34 -0700525
Narayan Kamath38819982017-07-06 18:15:30 +0100526 if (mColorFadeEnabled) {
527 mColorFadeOnAnimator = ObjectAnimator.ofFloat(
528 mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 0.0f, 1.0f);
529 mColorFadeOnAnimator.setDuration(COLOR_FADE_ON_ANIMATION_DURATION_MILLIS);
530 mColorFadeOnAnimator.addListener(mAnimatorListener);
Jeff Brown96307042012-07-27 15:51:34 -0700531
Narayan Kamath38819982017-07-06 18:15:30 +0100532 mColorFadeOffAnimator = ObjectAnimator.ofFloat(
533 mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 1.0f, 0.0f);
534 mColorFadeOffAnimator.setDuration(COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS);
535 mColorFadeOffAnimator.addListener(mAnimatorListener);
536 }
Jeff Brown96307042012-07-27 15:51:34 -0700537
538 mScreenBrightnessRampAnimator = new RampAnimator<DisplayPowerState>(
539 mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS);
Jeff Brown42558692014-05-20 22:02:46 -0700540 mScreenBrightnessRampAnimator.setListener(mRampAnimatorListener);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800541
Jeff Brown131206b2014-04-08 17:27:14 -0700542 // Initialize screen state for battery stats.
543 try {
Jeff Browne95c3cd2014-05-02 16:59:26 -0700544 mBatteryStats.noteScreenState(mPowerState.getScreenState());
Jeff Brown131206b2014-04-08 17:27:14 -0700545 mBatteryStats.noteScreenBrightness(mPowerState.getScreenBrightness());
546 } catch (RemoteException ex) {
547 // same process
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800548 }
Jeff Brown96307042012-07-27 15:51:34 -0700549 }
550
551 private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() {
552 @Override
553 public void onAnimationStart(Animator animation) {
554 }
555 @Override
556 public void onAnimationEnd(Animator animation) {
557 sendUpdatePowerState();
558 }
559 @Override
560 public void onAnimationRepeat(Animator animation) {
561 }
562 @Override
563 public void onAnimationCancel(Animator animation) {
564 }
565 };
566
Jeff Brown42558692014-05-20 22:02:46 -0700567 private final RampAnimator.Listener mRampAnimatorListener = new RampAnimator.Listener() {
568 @Override
569 public void onAnimationEnd() {
570 sendUpdatePowerState();
571 }
572 };
573
Jeff Brown96307042012-07-27 15:51:34 -0700574 private void updatePowerState() {
575 // Update the power state request.
576 final boolean mustNotify;
577 boolean mustInitialize = false;
Adrian Roos6da87ab2014-05-16 23:09:41 +0200578 boolean autoBrightnessAdjustmentChanged = false;
Jeff Brown330560f2012-08-21 22:10:57 -0700579
Jeff Brown96307042012-07-27 15:51:34 -0700580 synchronized (mLock) {
581 mPendingUpdatePowerStateLocked = false;
582 if (mPendingRequestLocked == null) {
583 return; // wait until first actual power request
584 }
585
586 if (mPowerRequest == null) {
587 mPowerRequest = new DisplayPowerRequest(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 mustInitialize = true;
592 } else if (mPendingRequestChangedLocked) {
Adrian Roos6da87ab2014-05-16 23:09:41 +0200593 autoBrightnessAdjustmentChanged = (mPowerRequest.screenAutoBrightnessAdjustment
594 != mPendingRequestLocked.screenAutoBrightnessAdjustment);
Jeff Brown96307042012-07-27 15:51:34 -0700595 mPowerRequest.copyFrom(mPendingRequestLocked);
596 mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked;
Jeff Brown6307a152012-08-20 13:24:23 -0700597 mPendingWaitForNegativeProximityLocked = false;
Jeff Brown96307042012-07-27 15:51:34 -0700598 mPendingRequestChangedLocked = false;
599 mDisplayReadyLocked = false;
600 }
601
602 mustNotify = !mDisplayReadyLocked;
603 }
604
605 // Initialize things the first time the power state is changed.
606 if (mustInitialize) {
607 initialize();
608 }
609
Jeff Brown970d4132014-07-19 11:33:47 -0700610 // Compute the basic display state using the policy.
611 // We might override this below based on other factors.
612 int state;
613 int brightness = PowerManager.BRIGHTNESS_DEFAULT;
Jeff Brown2175e9c2014-09-12 16:11:07 -0700614 boolean performScreenOffTransition = false;
Jeff Brown970d4132014-07-19 11:33:47 -0700615 switch (mPowerRequest.policy) {
616 case DisplayPowerRequest.POLICY_OFF:
617 state = Display.STATE_OFF;
Jeff Brown2175e9c2014-09-12 16:11:07 -0700618 performScreenOffTransition = true;
Jeff Brown970d4132014-07-19 11:33:47 -0700619 break;
620 case DisplayPowerRequest.POLICY_DOZE:
621 if (mPowerRequest.dozeScreenState != Display.STATE_UNKNOWN) {
622 state = mPowerRequest.dozeScreenState;
623 } else {
624 state = Display.STATE_DOZE;
625 }
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700626 if (!mAllowAutoBrightnessWhileDozingConfig) {
627 brightness = mPowerRequest.dozeScreenBrightness;
628 }
Jeff Brown970d4132014-07-19 11:33:47 -0700629 break;
Santos Cordon3107d292016-09-20 15:50:35 -0700630 case DisplayPowerRequest.POLICY_VR:
631 state = Display.STATE_VR;
632 break;
Jeff Brown970d4132014-07-19 11:33:47 -0700633 case DisplayPowerRequest.POLICY_DIM:
634 case DisplayPowerRequest.POLICY_BRIGHT:
635 default:
636 state = Display.STATE_ON;
637 break;
638 }
Jeff Brown2175e9c2014-09-12 16:11:07 -0700639 assert(state != Display.STATE_UNKNOWN);
Jeff Brown970d4132014-07-19 11:33:47 -0700640
Jeff Brown6307a152012-08-20 13:24:23 -0700641 // Apply the proximity sensor.
Jeff Brown96307042012-07-27 15:51:34 -0700642 if (mProximitySensor != null) {
Jeff Brown970d4132014-07-19 11:33:47 -0700643 if (mPowerRequest.useProximitySensor && state != Display.STATE_OFF) {
Jeff Brown6307a152012-08-20 13:24:23 -0700644 setProximitySensorEnabled(true);
645 if (!mScreenOffBecauseOfProximity
646 && mProximity == PROXIMITY_POSITIVE) {
647 mScreenOffBecauseOfProximity = true;
Jeff Brownec083212013-09-11 20:45:25 -0700648 sendOnProximityPositiveWithWakelock();
Jeff Brown6307a152012-08-20 13:24:23 -0700649 }
650 } else if (mWaitingForNegativeProximity
651 && mScreenOffBecauseOfProximity
652 && mProximity == PROXIMITY_POSITIVE
Jeff Brown970d4132014-07-19 11:33:47 -0700653 && state != Display.STATE_OFF) {
Jeff Brown6307a152012-08-20 13:24:23 -0700654 setProximitySensorEnabled(true);
655 } else {
656 setProximitySensorEnabled(false);
657 mWaitingForNegativeProximity = false;
658 }
659 if (mScreenOffBecauseOfProximity
660 && mProximity != PROXIMITY_POSITIVE) {
Jeff Brown96307042012-07-27 15:51:34 -0700661 mScreenOffBecauseOfProximity = false;
Jeff Brownec083212013-09-11 20:45:25 -0700662 sendOnProximityNegativeWithWakelock();
Jeff Brown96307042012-07-27 15:51:34 -0700663 }
Jeff Brown6307a152012-08-20 13:24:23 -0700664 } else {
665 mWaitingForNegativeProximity = false;
Jeff Brown96307042012-07-27 15:51:34 -0700666 }
Jeff Brown970d4132014-07-19 11:33:47 -0700667 if (mScreenOffBecauseOfProximity) {
668 state = Display.STATE_OFF;
Jeff Brown96307042012-07-27 15:51:34 -0700669 }
670
Jeff Brownbf4e4142014-10-02 13:08:05 -0700671 // Animate the screen state change unless already animating.
672 // The transition may be deferred, so after this point we will use the
673 // actual state instead of the desired one.
Santos Cordon3107d292016-09-20 15:50:35 -0700674 final int oldState = mPowerState.getScreenState();
Jeff Brownbf4e4142014-10-02 13:08:05 -0700675 animateScreenStateChange(state, performScreenOffTransition);
676 state = mPowerState.getScreenState();
677
Jeff Brown970d4132014-07-19 11:33:47 -0700678 // Use zero brightness when screen is off.
679 if (state == Display.STATE_OFF) {
680 brightness = PowerManager.BRIGHTNESS_OFF;
681 }
682
Jeff Brown970d4132014-07-19 11:33:47 -0700683 // Configure auto-brightness.
684 boolean autoBrightnessEnabled = false;
685 if (mAutomaticBrightnessController != null) {
Michael Wrightb0a1d3d2017-09-22 15:05:02 +0100686 final boolean autoBrightnessEnabledInDoze =
687 mAllowAutoBrightnessWhileDozingConfig && Display.isDozeState(state);
Jeff Brown970d4132014-07-19 11:33:47 -0700688 autoBrightnessEnabled = mPowerRequest.useAutoBrightness
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700689 && (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
690 && brightness < 0;
Jeff Browna576b4d2015-04-23 19:58:06 -0700691 final boolean userInitiatedChange = autoBrightnessAdjustmentChanged
692 && mPowerRequest.brightnessSetByUser;
Jeff Brown970d4132014-07-19 11:33:47 -0700693 mAutomaticBrightnessController.configure(autoBrightnessEnabled,
Jeff Browna576b4d2015-04-23 19:58:06 -0700694 mPowerRequest.screenAutoBrightnessAdjustment, state != Display.STATE_ON,
Justin Klaassen5483cea2017-02-02 09:02:35 -0800695 userInitiatedChange);
Jeff Brown970d4132014-07-19 11:33:47 -0700696 }
697
Jeff Brown7b5be5e2014-11-12 18:45:31 -0800698 // Apply brightness boost.
699 // We do this here after configuring auto-brightness so that we don't
700 // disable the light sensor during this temporary state. That way when
701 // boost ends we will be able to resume normal auto-brightness behavior
702 // without any delay.
703 if (mPowerRequest.boostScreenBrightness
704 && brightness != PowerManager.BRIGHTNESS_OFF) {
705 brightness = PowerManager.BRIGHTNESS_ON;
706 }
707
Jeff Brown970d4132014-07-19 11:33:47 -0700708 // Apply auto-brightness.
709 boolean slowChange = false;
710 if (brightness < 0) {
711 if (autoBrightnessEnabled) {
712 brightness = mAutomaticBrightnessController.getAutomaticScreenBrightness();
713 }
714 if (brightness >= 0) {
715 // Use current auto-brightness value and slowly adjust to changes.
716 brightness = clampScreenBrightness(brightness);
717 if (mAppliedAutoBrightness && !autoBrightnessAdjustmentChanged) {
718 slowChange = true; // slowly adapt to auto-brightness
719 }
720 mAppliedAutoBrightness = true;
Jeff Brown96307042012-07-27 15:51:34 -0700721 } else {
Jeff Brown970d4132014-07-19 11:33:47 -0700722 mAppliedAutoBrightness = false;
Jeff Brown96307042012-07-27 15:51:34 -0700723 }
724 } else {
Jeff Brown970d4132014-07-19 11:33:47 -0700725 mAppliedAutoBrightness = false;
726 }
727
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700728 // Use default brightness when dozing unless overridden.
Michael Wrightb0a1d3d2017-09-22 15:05:02 +0100729 if (brightness < 0 && Display.isDozeState(state)) {
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700730 brightness = mScreenBrightnessDozeConfig;
731 }
732
Jeff Brown970d4132014-07-19 11:33:47 -0700733 // Apply manual brightness.
734 // Use the current brightness setting from the request, which is expected
735 // provide a nominal default value for the case where auto-brightness
736 // is not ready yet.
737 if (brightness < 0) {
738 brightness = clampScreenBrightness(mPowerRequest.screenBrightness);
739 }
740
741 // Apply dimming by at least some minimum amount when user activity
742 // timeout is about to expire.
743 if (mPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
Jeff Brown5c8ea082014-07-24 19:30:31 -0700744 if (brightness > mScreenBrightnessRangeMinimum) {
745 brightness = Math.max(Math.min(brightness - SCREEN_DIM_MINIMUM_REDUCTION,
746 mScreenBrightnessDimConfig), mScreenBrightnessRangeMinimum);
747 }
Jeff Brown970d4132014-07-19 11:33:47 -0700748 if (!mAppliedDimming) {
749 slowChange = false;
750 }
751 mAppliedDimming = true;
mochangmingf0cb46c2015-12-29 13:55:24 +0800752 } else if (mAppliedDimming) {
753 slowChange = false;
754 mAppliedDimming = false;
Jeff Brown970d4132014-07-19 11:33:47 -0700755 }
756
jackqdyulei92681e82017-02-28 11:26:28 -0800757 // If low power mode is enabled, scale brightness by screenLowPowerBrightnessFactor
Jeff Brown970d4132014-07-19 11:33:47 -0700758 // as long as it is above the minimum threshold.
759 if (mPowerRequest.lowPowerMode) {
760 if (brightness > mScreenBrightnessRangeMinimum) {
jackqdyulei92681e82017-02-28 11:26:28 -0800761 final float brightnessFactor =
762 Math.min(mPowerRequest.screenLowPowerBrightnessFactor, 1);
763 final int lowPowerBrightness = (int) (brightness * brightnessFactor);
764 brightness = Math.max(lowPowerBrightness, mScreenBrightnessRangeMinimum);
Jeff Brown970d4132014-07-19 11:33:47 -0700765 }
766 if (!mAppliedLowPower) {
767 slowChange = false;
768 }
769 mAppliedLowPower = true;
mochangmingf0cb46c2015-12-29 13:55:24 +0800770 } else if (mAppliedLowPower) {
771 slowChange = false;
772 mAppliedLowPower = false;
Jeff Brown970d4132014-07-19 11:33:47 -0700773 }
774
Jeff Brown0a434772014-09-30 14:42:27 -0700775 // Animate the screen brightness when the screen is on or dozing.
Santos Cordon3107d292016-09-20 15:50:35 -0700776 // Skip the animation when the screen is off or suspended or transition to/from VR.
Prashant Malani33538242014-11-13 14:04:00 -0800777 if (!mPendingScreenOff) {
Julius D'souzad5105dd2017-06-02 11:03:53 -0700778 if (mSkipScreenOnBrightnessRamp) {
Julius D'souzad5105dd2017-06-02 11:03:53 -0700779 if (state == Display.STATE_ON) {
780 if (mSkipRampState == RAMP_STATE_SKIP_NONE && mDozing) {
781 mInitialAutoBrightness = brightness;
782 mSkipRampState = RAMP_STATE_SKIP_INITIAL;
783 } else if (mSkipRampState == RAMP_STATE_SKIP_INITIAL
784 && mUseSoftwareAutoBrightnessConfig
785 && brightness != mInitialAutoBrightness) {
786 mSkipRampState = RAMP_STATE_SKIP_AUTOBRIGHT;
787 } else if (mSkipRampState == RAMP_STATE_SKIP_AUTOBRIGHT) {
788 mSkipRampState = RAMP_STATE_SKIP_NONE;
789 }
790 } else {
791 mSkipRampState = RAMP_STATE_SKIP_NONE;
792 }
793 }
794
Michael Wrightb0a1d3d2017-09-22 15:05:02 +0100795 final boolean wasOrWillBeInVr =
796 (state == Display.STATE_VR || oldState == Display.STATE_VR);
797 final boolean initialRampSkip =
798 state == Display.STATE_ON && mSkipRampState != RAMP_STATE_SKIP_NONE;
799 // While dozing, sometimes the brightness is split into buckets. Rather than animating
800 // through the buckets, which is unlikely to be smooth in the first place, just jump
801 // right to the suggested brightness.
802 final boolean hasBrightnessBuckets =
803 Display.isDozeState(state) && mBrightnessBucketsInDozeConfig;
804 // If the color fade is totally covering the screen then we can change the backlight
805 // level without it being a noticeable jump since any actual content isn't yet visible.
806 final boolean isDisplayContentVisible =
807 mColorFadeEnabled && mPowerState.getColorFadeLevel() == 1.0f;
808 if (initialRampSkip || hasBrightnessBuckets
809 || wasOrWillBeInVr || !isDisplayContentVisible) {
810 animateScreenBrightness(brightness, 0);
811 } else {
Prashant Malani33538242014-11-13 14:04:00 -0800812 animateScreenBrightness(brightness,
Julius D'souzafeadad12016-08-05 14:34:38 -0700813 slowChange ? mBrightnessRampRateSlow : mBrightnessRampRateFast);
Prashant Malani33538242014-11-13 14:04:00 -0800814 }
Jeff Brown0a434772014-09-30 14:42:27 -0700815 }
816
817 // Determine whether the display is ready for use in the newly requested state.
818 // Note that we do not wait for the brightness ramp animation to complete before
819 // reporting the display is ready because we only need to ensure the screen is in the
820 // right power state even as it continues to converge on the desired brightness.
Narayan Kamath38819982017-07-06 18:15:30 +0100821 final boolean ready = mPendingScreenOnUnblocker == null &&
822 (!mColorFadeEnabled ||
823 (!mColorFadeOnAnimator.isStarted() && !mColorFadeOffAnimator.isStarted()))
Jeff Brown0a434772014-09-30 14:42:27 -0700824 && mPowerState.waitUntilClean(mCleanListener);
825 final boolean finished = ready
826 && !mScreenBrightnessRampAnimator.isAnimating();
827
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700828 // Notify policy about screen turned on.
829 if (ready && state != Display.STATE_OFF
830 && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_ON) {
Michael Wrightc3e6af82017-07-25 22:31:03 +0100831 setReportedScreenState(REPORTED_TO_POLICY_SCREEN_ON);
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700832 mWindowManagerPolicy.screenTurnedOn();
833 }
834
Jeff Brown0a434772014-09-30 14:42:27 -0700835 // Grab a wake lock if we have unfinished business.
836 if (!finished && !mUnfinishedBusiness) {
837 if (DEBUG) {
838 Slog.d(TAG, "Unfinished business...");
839 }
840 mCallbacks.acquireSuspendBlocker();
841 mUnfinishedBusiness = true;
842 }
843
844 // Notify the power manager when ready.
845 if (ready && mustNotify) {
846 // Send state change.
Jeff Brown96307042012-07-27 15:51:34 -0700847 synchronized (mLock) {
848 if (!mPendingRequestChangedLocked) {
849 mDisplayReadyLocked = true;
Jeff Brownc38c9be2012-10-04 13:16:19 -0700850
851 if (DEBUG) {
852 Slog.d(TAG, "Display ready!");
853 }
Jeff Brown96307042012-07-27 15:51:34 -0700854 }
855 }
Jeff Brownec083212013-09-11 20:45:25 -0700856 sendOnStateChangedWithWakelock();
Jeff Brown96307042012-07-27 15:51:34 -0700857 }
Jeff Brown0a434772014-09-30 14:42:27 -0700858
859 // Release the wake lock when we have no unfinished business.
860 if (finished && mUnfinishedBusiness) {
861 if (DEBUG) {
862 Slog.d(TAG, "Finished business...");
863 }
864 mUnfinishedBusiness = false;
865 mCallbacks.releaseSuspendBlocker();
866 }
Julius D'souzad5105dd2017-06-02 11:03:53 -0700867
868 // Record if dozing for future comparison.
869 mDozing = state != Display.STATE_ON;
Jeff Brown96307042012-07-27 15:51:34 -0700870 }
871
Michael Wright639c8be2014-01-17 18:29:12 -0800872 @Override
873 public void updateBrightness() {
874 sendUpdatePowerState();
875 }
876
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700877 private void blockScreenOn() {
Jeff Brown3ee549c2014-09-22 20:14:39 -0700878 if (mPendingScreenOnUnblocker == null) {
Jeff Brown3edf5272014-08-14 19:25:14 -0700879 Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0);
Jeff Brown3ee549c2014-09-22 20:14:39 -0700880 mPendingScreenOnUnblocker = new ScreenOnUnblocker();
Jeff Brown037c33e2014-04-09 00:31:55 -0700881 mScreenOnBlockStartRealTime = SystemClock.elapsedRealtime();
Jeff Brown3edf5272014-08-14 19:25:14 -0700882 Slog.i(TAG, "Blocking screen on until initial contents have been drawn.");
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700883 }
884 }
885
886 private void unblockScreenOn() {
Jeff Brown3ee549c2014-09-22 20:14:39 -0700887 if (mPendingScreenOnUnblocker != null) {
888 mPendingScreenOnUnblocker = null;
Jeff Brown2d8a3902014-03-11 23:02:35 -0700889 long delay = SystemClock.elapsedRealtime() - mScreenOnBlockStartRealTime;
Jeff Brown3edf5272014-08-14 19:25:14 -0700890 Slog.i(TAG, "Unblocked screen on after " + delay + " ms");
891 Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0);
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700892 }
893 }
894
Jorim Jaggi51304d72017-05-17 17:25:32 +0200895 private void blockScreenOff() {
896 if (mPendingScreenOffUnblocker == null) {
897 Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, SCREEN_OFF_BLOCKED_TRACE_NAME, 0);
898 mPendingScreenOffUnblocker = new ScreenOffUnblocker();
899 mScreenOffBlockStartRealTime = SystemClock.elapsedRealtime();
900 Slog.i(TAG, "Blocking screen off");
901 }
902 }
903
904 private void unblockScreenOff() {
905 if (mPendingScreenOffUnblocker != null) {
906 mPendingScreenOffUnblocker = null;
907 long delay = SystemClock.elapsedRealtime() - mScreenOffBlockStartRealTime;
908 Slog.i(TAG, "Unblocked screen off after " + delay + " ms");
909 Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, SCREEN_OFF_BLOCKED_TRACE_NAME, 0);
910 }
911 }
912
Jeff Brown3ee549c2014-09-22 20:14:39 -0700913 private boolean setScreenState(int state) {
Michael Wrightc3e6af82017-07-25 22:31:03 +0100914 return setScreenState(state, false /*reportOnly*/);
Michael Wright05e76fe2017-07-20 18:18:33 +0100915 }
916
Michael Wrightc3e6af82017-07-25 22:31:03 +0100917 private boolean setScreenState(int state, boolean reportOnly) {
Jorim Jaggi51304d72017-05-17 17:25:32 +0200918 final boolean isOff = (state == Display.STATE_OFF);
Jeff Brown037c33e2014-04-09 00:31:55 -0700919 if (mPowerState.getScreenState() != state) {
Jorim Jaggi51304d72017-05-17 17:25:32 +0200920
921 // If we are trying to turn screen off, give policy a chance to do something before we
922 // actually turn the screen off.
923 if (isOff && !mScreenOffBecauseOfProximity) {
924 if (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_ON) {
Michael Wrightc3e6af82017-07-25 22:31:03 +0100925 setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_OFF);
Jorim Jaggi51304d72017-05-17 17:25:32 +0200926 blockScreenOff();
927 mWindowManagerPolicy.screenTurningOff(mPendingScreenOffUnblocker);
Michael Wrightc3e6af82017-07-25 22:31:03 +0100928 unblockScreenOff();
Jorim Jaggi51304d72017-05-17 17:25:32 +0200929 } else if (mPendingScreenOffUnblocker != null) {
Jorim Jaggi51304d72017-05-17 17:25:32 +0200930 // Abort doing the state change until screen off is unblocked.
931 return false;
932 }
933 }
934
Michael Wrightc3e6af82017-07-25 22:31:03 +0100935 if (!reportOnly) {
Michael Wrightb0a1d3d2017-09-22 15:05:02 +0100936 Trace.traceCounter(Trace.TRACE_TAG_POWER, "ScreenState", state);
Michael Wrightc3e6af82017-07-25 22:31:03 +0100937 mPowerState.setScreenState(state);
938 // Tell battery stats about the transition.
939 try {
940 mBatteryStats.noteScreenState(state);
941 } catch (RemoteException ex) {
942 // same process
943 }
Jeff Brown96307042012-07-27 15:51:34 -0700944 }
945 }
Jeff Browne1633ad2015-06-22 19:24:24 -0700946
947 // Tell the window manager policy when the screen is turned off or on unless it's due
948 // to the proximity sensor. We temporarily block turning the screen on until the
949 // window manager is ready by leaving a black surface covering the screen.
950 // This surface is essentially the final state of the color fade animation and
951 // it is only removed once the window manager tells us that the activity has
952 // finished drawing underneath.
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700953 if (isOff && mReportedScreenStateToPolicy != REPORTED_TO_POLICY_SCREEN_OFF
954 && !mScreenOffBecauseOfProximity) {
Michael Wrightc3e6af82017-07-25 22:31:03 +0100955 setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
Jeff Browne1633ad2015-06-22 19:24:24 -0700956 unblockScreenOn();
957 mWindowManagerPolicy.screenTurnedOff();
Jorim Jaggi51304d72017-05-17 17:25:32 +0200958 } else if (!isOff
959 && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_OFF) {
960
961 // We told policy already that screen was turning off, but now we changed our minds.
962 // Complete the full state transition on -> turningOff -> off.
963 unblockScreenOff();
964 mWindowManagerPolicy.screenTurnedOff();
Michael Wrightc3e6af82017-07-25 22:31:03 +0100965 setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
Jorim Jaggi51304d72017-05-17 17:25:32 +0200966 }
967 if (!isOff && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF) {
Michael Wrightc3e6af82017-07-25 22:31:03 +0100968 setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_ON);
Jeff Browne1633ad2015-06-22 19:24:24 -0700969 if (mPowerState.getColorFadeLevel() == 0.0f) {
970 blockScreenOn();
971 } else {
972 unblockScreenOn();
973 }
974 mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker);
975 }
976
977 // Return true if the screen isn't blocked.
Jeff Brown3ee549c2014-09-22 20:14:39 -0700978 return mPendingScreenOnUnblocker == null;
Jeff Brown96307042012-07-27 15:51:34 -0700979 }
980
Michael Wrightc3e6af82017-07-25 22:31:03 +0100981 private void setReportedScreenState(int state) {
982 Trace.traceCounter(Trace.TRACE_TAG_POWER, "ReportedScreenStateToPolicy", state);
983 mReportedScreenStateToPolicy = state;
984 }
985
Jeff Brown330560f2012-08-21 22:10:57 -0700986 private int clampScreenBrightness(int value) {
Michael Wright639c8be2014-01-17 18:29:12 -0800987 return MathUtils.constrain(
988 value, mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum);
Jeff Brown330560f2012-08-21 22:10:57 -0700989 }
990
Jeff Brown96307042012-07-27 15:51:34 -0700991 private void animateScreenBrightness(int target, int rate) {
Jeff Brown0a434772014-09-30 14:42:27 -0700992 if (DEBUG) {
993 Slog.d(TAG, "Animating brightness: target=" + target +", rate=" + rate);
994 }
Jeff Brown96307042012-07-27 15:51:34 -0700995 if (mScreenBrightnessRampAnimator.animateTo(target, rate)) {
Michael Wrighta9f37ab2017-08-15 17:14:20 +0100996 Trace.traceCounter(Trace.TRACE_TAG_POWER, "TargetScreenBrightness", target);
Jeff Brown131206b2014-04-08 17:27:14 -0700997 try {
998 mBatteryStats.noteScreenBrightness(target);
999 } catch (RemoteException ex) {
1000 // same process
1001 }
Jeff Brown96307042012-07-27 15:51:34 -07001002 }
1003 }
1004
Jeff Brown606e4e82014-09-18 15:22:26 -07001005 private void animateScreenStateChange(int target, boolean performScreenOffTransition) {
1006 // If there is already an animation in progress, don't interfere with it.
Narayan Kamath38819982017-07-06 18:15:30 +01001007 if (mColorFadeEnabled &&
1008 (mColorFadeOnAnimator.isStarted() || mColorFadeOffAnimator.isStarted())) {
Chong Zhangb131c702016-02-16 16:31:48 -08001009 if (target != Display.STATE_ON) {
1010 return;
1011 }
1012 // If display state changed to on, proceed and stop the color fade and turn screen on.
1013 mPendingScreenOff = false;
Jeff Brown606e4e82014-09-18 15:22:26 -07001014 }
1015
Michael Wrightc3e6af82017-07-25 22:31:03 +01001016 if (mDisplayBlanksAfterDozeConfig
1017 && Display.isDozeState(mPowerState.getScreenState())
Michael Wright05e76fe2017-07-20 18:18:33 +01001018 && !Display.isDozeState(target)) {
Michael Wright05e76fe2017-07-20 18:18:33 +01001019 // Skip the screen off animation and add a black surface to hide the
Michael Wrightc3e6af82017-07-25 22:31:03 +01001020 // contents of the screen.
1021 mPowerState.prepareColorFade(mContext,
1022 mColorFadeFadesConfig ? ColorFade.MODE_FADE : ColorFade.MODE_WARM_UP);
Lucas Dupina84952b2017-08-15 15:56:50 -07001023 if (mColorFadeOffAnimator != null) {
1024 mColorFadeOffAnimator.end();
1025 }
Michael Wrightc3e6af82017-07-25 22:31:03 +01001026 // Some display hardware will blank itself on the transition between doze and non-doze
1027 // but still on display states. In this case we want to report to policy that the
1028 // display has turned off so it can prepare the appropriate power on animation, but we
1029 // don't want to actually transition to the fully off state since that takes
1030 // significantly longer to transition from.
1031 setScreenState(Display.STATE_OFF, target != Display.STATE_OFF /*reportOnly*/);
Michael Wright05e76fe2017-07-20 18:18:33 +01001032 }
1033
Jeff Brown3ee549c2014-09-22 20:14:39 -07001034 // If we were in the process of turning off the screen but didn't quite
1035 // finish. Then finish up now to prevent a jarring transition back
1036 // to screen on if we skipped blocking screen on as usual.
1037 if (mPendingScreenOff && target != Display.STATE_OFF) {
1038 setScreenState(Display.STATE_OFF);
1039 mPendingScreenOff = false;
Michael Lentined73854d2015-09-25 10:55:26 -07001040 mPowerState.dismissColorFadeResources();
Jeff Brown606e4e82014-09-18 15:22:26 -07001041 }
1042
1043 if (target == Display.STATE_ON) {
1044 // Want screen on. The contents of the screen may not yet
Jeff Brown3ee549c2014-09-22 20:14:39 -07001045 // be visible if the color fade has not been dismissed because
Jeff Brown606e4e82014-09-18 15:22:26 -07001046 // its last frame of animation is solid black.
Jeff Brown3ee549c2014-09-22 20:14:39 -07001047 if (!setScreenState(Display.STATE_ON)) {
1048 return; // screen on blocked
1049 }
Narayan Kamath38819982017-07-06 18:15:30 +01001050 if (USE_COLOR_FADE_ON_ANIMATION && mColorFadeEnabled && mPowerRequest.isBrightOrDim()) {
Jeff Brown606e4e82014-09-18 15:22:26 -07001051 // Perform screen on animation.
1052 if (mPowerState.getColorFadeLevel() == 1.0f) {
1053 mPowerState.dismissColorFade();
1054 } else if (mPowerState.prepareColorFade(mContext,
1055 mColorFadeFadesConfig ?
1056 ColorFade.MODE_FADE :
1057 ColorFade.MODE_WARM_UP)) {
1058 mColorFadeOnAnimator.start();
1059 } else {
1060 mColorFadeOnAnimator.end();
1061 }
1062 } else {
1063 // Skip screen on animation.
1064 mPowerState.setColorFadeLevel(1.0f);
1065 mPowerState.dismissColorFade();
1066 }
Santos Cordon3107d292016-09-20 15:50:35 -07001067 } else if (target == Display.STATE_VR) {
1068 // Wait for brightness animation to complete beforehand when entering VR
1069 // from screen on to prevent a perceptible jump because brightness may operate
1070 // differently when the display is configured for dozing.
1071 if (mScreenBrightnessRampAnimator.isAnimating()
1072 && mPowerState.getScreenState() == Display.STATE_ON) {
1073 return;
1074 }
1075
1076 // Set screen state.
1077 if (!setScreenState(Display.STATE_VR)) {
1078 return; // screen on blocked
1079 }
1080
1081 // Dismiss the black surface without fanfare.
1082 mPowerState.setColorFadeLevel(1.0f);
1083 mPowerState.dismissColorFade();
Jeff Brown606e4e82014-09-18 15:22:26 -07001084 } else if (target == Display.STATE_DOZE) {
1085 // Want screen dozing.
1086 // Wait for brightness animation to complete beforehand when entering doze
1087 // from screen on to prevent a perceptible jump because brightness may operate
1088 // differently when the display is configured for dozing.
1089 if (mScreenBrightnessRampAnimator.isAnimating()
1090 && mPowerState.getScreenState() == Display.STATE_ON) {
1091 return;
1092 }
1093
Jeff Brown3ee549c2014-09-22 20:14:39 -07001094 // Set screen state.
1095 if (!setScreenState(Display.STATE_DOZE)) {
1096 return; // screen on blocked
1097 }
1098
1099 // Dismiss the black surface without fanfare.
Jeff Brown606e4e82014-09-18 15:22:26 -07001100 mPowerState.setColorFadeLevel(1.0f);
1101 mPowerState.dismissColorFade();
1102 } else if (target == Display.STATE_DOZE_SUSPEND) {
1103 // Want screen dozing and suspended.
1104 // Wait for brightness animation to complete beforehand unless already
1105 // suspended because we may not be able to change it after suspension.
1106 if (mScreenBrightnessRampAnimator.isAnimating()
1107 && mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) {
1108 return;
1109 }
1110
Jeff Brown3ee549c2014-09-22 20:14:39 -07001111 // If not already suspending, temporarily set the state to doze until the
1112 // screen on is unblocked, then suspend.
1113 if (mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) {
1114 if (!setScreenState(Display.STATE_DOZE)) {
1115 return; // screen on blocked
1116 }
1117 setScreenState(Display.STATE_DOZE_SUSPEND); // already on so can't block
1118 }
1119
1120 // Dismiss the black surface without fanfare.
Jeff Brown606e4e82014-09-18 15:22:26 -07001121 mPowerState.setColorFadeLevel(1.0f);
1122 mPowerState.dismissColorFade();
1123 } else {
1124 // Want screen off.
Jeff Brown3ee549c2014-09-22 20:14:39 -07001125 mPendingScreenOff = true;
Narayan Kamath38819982017-07-06 18:15:30 +01001126 if (!mColorFadeEnabled) {
1127 mPowerState.setColorFadeLevel(0.0f);
1128 }
1129
Jeff Brown606e4e82014-09-18 15:22:26 -07001130 if (mPowerState.getColorFadeLevel() == 0.0f) {
1131 // Turn the screen off.
1132 // A black surface is already hiding the contents of the screen.
1133 setScreenState(Display.STATE_OFF);
Jeff Brown3ee549c2014-09-22 20:14:39 -07001134 mPendingScreenOff = false;
Michael Lentined73854d2015-09-25 10:55:26 -07001135 mPowerState.dismissColorFadeResources();
Jeff Brown606e4e82014-09-18 15:22:26 -07001136 } else if (performScreenOffTransition
1137 && mPowerState.prepareColorFade(mContext,
1138 mColorFadeFadesConfig ?
1139 ColorFade.MODE_FADE : ColorFade.MODE_COOL_DOWN)
1140 && mPowerState.getScreenState() != Display.STATE_OFF) {
1141 // Perform the screen off animation.
1142 mColorFadeOffAnimator.start();
1143 } else {
1144 // Skip the screen off animation and add a black surface to hide the
1145 // contents of the screen.
1146 mColorFadeOffAnimator.end();
1147 }
1148 }
1149 }
1150
Jeff Brown96307042012-07-27 15:51:34 -07001151 private final Runnable mCleanListener = new Runnable() {
1152 @Override
1153 public void run() {
1154 sendUpdatePowerState();
1155 }
1156 };
1157
1158 private void setProximitySensorEnabled(boolean enable) {
1159 if (enable) {
1160 if (!mProximitySensorEnabled) {
Jeff Brownec083212013-09-11 20:45:25 -07001161 // Register the listener.
1162 // Proximity sensor state already cleared initially.
Jeff Brown96307042012-07-27 15:51:34 -07001163 mProximitySensorEnabled = true;
Jeff Brown96307042012-07-27 15:51:34 -07001164 mSensorManager.registerListener(mProximitySensorListener, mProximitySensor,
1165 SensorManager.SENSOR_DELAY_NORMAL, mHandler);
1166 }
1167 } else {
1168 if (mProximitySensorEnabled) {
Jeff Brownec083212013-09-11 20:45:25 -07001169 // Unregister the listener.
1170 // Clear the proximity sensor state for next time.
Jeff Brown96307042012-07-27 15:51:34 -07001171 mProximitySensorEnabled = false;
1172 mProximity = PROXIMITY_UNKNOWN;
Jeff Brownec083212013-09-11 20:45:25 -07001173 mPendingProximity = PROXIMITY_UNKNOWN;
Jeff Brown96307042012-07-27 15:51:34 -07001174 mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
1175 mSensorManager.unregisterListener(mProximitySensorListener);
Jeff Brownec083212013-09-11 20:45:25 -07001176 clearPendingProximityDebounceTime(); // release wake lock (must be last)
Jeff Brown96307042012-07-27 15:51:34 -07001177 }
1178 }
1179 }
1180
1181 private void handleProximitySensorEvent(long time, boolean positive) {
Jeff Brownec083212013-09-11 20:45:25 -07001182 if (mProximitySensorEnabled) {
1183 if (mPendingProximity == PROXIMITY_NEGATIVE && !positive) {
1184 return; // no change
1185 }
1186 if (mPendingProximity == PROXIMITY_POSITIVE && positive) {
1187 return; // no change
1188 }
Jeff Brown96307042012-07-27 15:51:34 -07001189
Jeff Brownec083212013-09-11 20:45:25 -07001190 // Only accept a proximity sensor reading if it remains
1191 // stable for the entire debounce delay. We hold a wake lock while
1192 // debouncing the sensor.
1193 mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
1194 if (positive) {
1195 mPendingProximity = PROXIMITY_POSITIVE;
1196 setPendingProximityDebounceTime(
1197 time + PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY); // acquire wake lock
1198 } else {
1199 mPendingProximity = PROXIMITY_NEGATIVE;
1200 setPendingProximityDebounceTime(
1201 time + PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY); // acquire wake lock
1202 }
1203
1204 // Debounce the new sensor reading.
1205 debounceProximitySensor();
Jeff Brown93cbbb22012-10-04 13:18:36 -07001206 }
Jeff Brown96307042012-07-27 15:51:34 -07001207 }
1208
1209 private void debounceProximitySensor() {
Jeff Brownec083212013-09-11 20:45:25 -07001210 if (mProximitySensorEnabled
1211 && mPendingProximity != PROXIMITY_UNKNOWN
1212 && mPendingProximityDebounceTime >= 0) {
Jeff Brown96307042012-07-27 15:51:34 -07001213 final long now = SystemClock.uptimeMillis();
1214 if (mPendingProximityDebounceTime <= now) {
Jeff Brownec083212013-09-11 20:45:25 -07001215 // Sensor reading accepted. Apply the change then release the wake lock.
Jeff Brown96307042012-07-27 15:51:34 -07001216 mProximity = mPendingProximity;
Jeff Brownec083212013-09-11 20:45:25 -07001217 updatePowerState();
1218 clearPendingProximityDebounceTime(); // release wake lock (must be last)
Jeff Brown96307042012-07-27 15:51:34 -07001219 } else {
Jeff Brownec083212013-09-11 20:45:25 -07001220 // Need to wait a little longer.
1221 // Debounce again later. We continue holding a wake lock while waiting.
Jeff Brown96307042012-07-27 15:51:34 -07001222 Message msg = mHandler.obtainMessage(MSG_PROXIMITY_SENSOR_DEBOUNCED);
1223 msg.setAsynchronous(true);
1224 mHandler.sendMessageAtTime(msg, mPendingProximityDebounceTime);
1225 }
1226 }
1227 }
1228
Jeff Brownec083212013-09-11 20:45:25 -07001229 private void clearPendingProximityDebounceTime() {
1230 if (mPendingProximityDebounceTime >= 0) {
1231 mPendingProximityDebounceTime = -1;
Jeff Brown131206b2014-04-08 17:27:14 -07001232 mCallbacks.releaseSuspendBlocker(); // release wake lock
Jeff Brownec083212013-09-11 20:45:25 -07001233 }
1234 }
1235
1236 private void setPendingProximityDebounceTime(long debounceTime) {
1237 if (mPendingProximityDebounceTime < 0) {
Jeff Brown131206b2014-04-08 17:27:14 -07001238 mCallbacks.acquireSuspendBlocker(); // acquire wake lock
Jeff Brownec083212013-09-11 20:45:25 -07001239 }
1240 mPendingProximityDebounceTime = debounceTime;
1241 }
1242
Jeff Brownec083212013-09-11 20:45:25 -07001243 private void sendOnStateChangedWithWakelock() {
Jeff Brown131206b2014-04-08 17:27:14 -07001244 mCallbacks.acquireSuspendBlocker();
1245 mHandler.post(mOnStateChangedRunnable);
Jeff Brown96307042012-07-27 15:51:34 -07001246 }
1247
1248 private final Runnable mOnStateChangedRunnable = new Runnable() {
1249 @Override
1250 public void run() {
1251 mCallbacks.onStateChanged();
Jeff Brown131206b2014-04-08 17:27:14 -07001252 mCallbacks.releaseSuspendBlocker();
Jeff Brown96307042012-07-27 15:51:34 -07001253 }
1254 };
1255
Jeff Brownec083212013-09-11 20:45:25 -07001256 private void sendOnProximityPositiveWithWakelock() {
Jeff Brown131206b2014-04-08 17:27:14 -07001257 mCallbacks.acquireSuspendBlocker();
1258 mHandler.post(mOnProximityPositiveRunnable);
Jeff Brown93cbbb22012-10-04 13:18:36 -07001259 }
1260
1261 private final Runnable mOnProximityPositiveRunnable = new Runnable() {
1262 @Override
1263 public void run() {
1264 mCallbacks.onProximityPositive();
Jeff Brown131206b2014-04-08 17:27:14 -07001265 mCallbacks.releaseSuspendBlocker();
Jeff Brown93cbbb22012-10-04 13:18:36 -07001266 }
1267 };
1268
Jeff Brownec083212013-09-11 20:45:25 -07001269 private void sendOnProximityNegativeWithWakelock() {
Jeff Brown131206b2014-04-08 17:27:14 -07001270 mCallbacks.acquireSuspendBlocker();
1271 mHandler.post(mOnProximityNegativeRunnable);
Jeff Brown96307042012-07-27 15:51:34 -07001272 }
1273
1274 private final Runnable mOnProximityNegativeRunnable = new Runnable() {
1275 @Override
1276 public void run() {
1277 mCallbacks.onProximityNegative();
Jeff Brown131206b2014-04-08 17:27:14 -07001278 mCallbacks.releaseSuspendBlocker();
Jeff Brown96307042012-07-27 15:51:34 -07001279 }
1280 };
1281
Jeff Brownbd6e1502012-08-28 03:27:37 -07001282 public void dump(final PrintWriter pw) {
Jeff Brown96307042012-07-27 15:51:34 -07001283 synchronized (mLock) {
1284 pw.println();
Jeff Brown131206b2014-04-08 17:27:14 -07001285 pw.println("Display Power Controller Locked State:");
Jeff Brown96307042012-07-27 15:51:34 -07001286 pw.println(" mDisplayReadyLocked=" + mDisplayReadyLocked);
1287 pw.println(" mPendingRequestLocked=" + mPendingRequestLocked);
1288 pw.println(" mPendingRequestChangedLocked=" + mPendingRequestChangedLocked);
1289 pw.println(" mPendingWaitForNegativeProximityLocked="
1290 + mPendingWaitForNegativeProximityLocked);
1291 pw.println(" mPendingUpdatePowerStateLocked=" + mPendingUpdatePowerStateLocked);
1292 }
1293
1294 pw.println();
Jeff Brown131206b2014-04-08 17:27:14 -07001295 pw.println("Display Power Controller Configuration:");
Jeff Brown26875502014-01-30 21:47:47 -08001296 pw.println(" mScreenBrightnessDozeConfig=" + mScreenBrightnessDozeConfig);
Jeff Brown96307042012-07-27 15:51:34 -07001297 pw.println(" mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig);
Jeff Brown1bfd0f42014-08-22 01:59:06 -07001298 pw.println(" mScreenBrightnessDarkConfig=" + mScreenBrightnessDarkConfig);
Jeff Brownb76eebff2012-10-05 22:26:44 -07001299 pw.println(" mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum);
1300 pw.println(" mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum);
Jeff Brown2175e9c2014-09-12 16:11:07 -07001301 pw.println(" mUseSoftwareAutoBrightnessConfig=" + mUseSoftwareAutoBrightnessConfig);
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -07001302 pw.println(" mAllowAutoBrightnessWhileDozingConfig=" +
1303 mAllowAutoBrightnessWhileDozingConfig);
Jeff Brown2175e9c2014-09-12 16:11:07 -07001304 pw.println(" mColorFadeFadesConfig=" + mColorFadeFadesConfig);
Jeff Brown96307042012-07-27 15:51:34 -07001305
Jeff Brownbd6e1502012-08-28 03:27:37 -07001306 mHandler.runWithScissors(new Runnable() {
1307 @Override
1308 public void run() {
1309 dumpLocal(pw);
Jeff Brown96307042012-07-27 15:51:34 -07001310 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001311 }, 1000);
Jeff Brown96307042012-07-27 15:51:34 -07001312 }
1313
1314 private void dumpLocal(PrintWriter pw) {
1315 pw.println();
Jeff Brown131206b2014-04-08 17:27:14 -07001316 pw.println("Display Power Controller Thread State:");
Jeff Brown96307042012-07-27 15:51:34 -07001317 pw.println(" mPowerRequest=" + mPowerRequest);
1318 pw.println(" mWaitingForNegativeProximity=" + mWaitingForNegativeProximity);
1319
1320 pw.println(" mProximitySensor=" + mProximitySensor);
1321 pw.println(" mProximitySensorEnabled=" + mProximitySensorEnabled);
1322 pw.println(" mProximityThreshold=" + mProximityThreshold);
1323 pw.println(" mProximity=" + proximityToString(mProximity));
1324 pw.println(" mPendingProximity=" + proximityToString(mPendingProximity));
1325 pw.println(" mPendingProximityDebounceTime="
1326 + TimeUtils.formatUptime(mPendingProximityDebounceTime));
1327 pw.println(" mScreenOffBecauseOfProximity=" + mScreenOffBecauseOfProximity);
Jeff Brown970d4132014-07-19 11:33:47 -07001328 pw.println(" mAppliedAutoBrightness=" + mAppliedAutoBrightness);
1329 pw.println(" mAppliedDimming=" + mAppliedDimming);
1330 pw.println(" mAppliedLowPower=" + mAppliedLowPower);
Jeff Brown3ee549c2014-09-22 20:14:39 -07001331 pw.println(" mPendingScreenOnUnblocker=" + mPendingScreenOnUnblocker);
1332 pw.println(" mPendingScreenOff=" + mPendingScreenOff);
Michael Wrightc3e6af82017-07-25 22:31:03 +01001333 pw.println(" mReportedToPolicy=" +
1334 reportedToPolicyToString(mReportedScreenStateToPolicy));
Jeff Brown96307042012-07-27 15:51:34 -07001335
Jeff Brown42558692014-05-20 22:02:46 -07001336 pw.println(" mScreenBrightnessRampAnimator.isAnimating()=" +
1337 mScreenBrightnessRampAnimator.isAnimating());
1338
Michael Lentine0839adb2014-07-29 18:47:56 -07001339 if (mColorFadeOnAnimator != null) {
1340 pw.println(" mColorFadeOnAnimator.isStarted()=" +
1341 mColorFadeOnAnimator.isStarted());
Jeff Brown96307042012-07-27 15:51:34 -07001342 }
Michael Lentine0839adb2014-07-29 18:47:56 -07001343 if (mColorFadeOffAnimator != null) {
1344 pw.println(" mColorFadeOffAnimator.isStarted()=" +
1345 mColorFadeOffAnimator.isStarted());
Jeff Brown96307042012-07-27 15:51:34 -07001346 }
1347
1348 if (mPowerState != null) {
1349 mPowerState.dump(pw);
1350 }
Michael Wright639c8be2014-01-17 18:29:12 -08001351
1352 if (mAutomaticBrightnessController != null) {
1353 mAutomaticBrightnessController.dump(pw);
1354 }
1355
Jeff Brown96307042012-07-27 15:51:34 -07001356 }
1357
1358 private static String proximityToString(int state) {
1359 switch (state) {
1360 case PROXIMITY_UNKNOWN:
1361 return "Unknown";
1362 case PROXIMITY_NEGATIVE:
1363 return "Negative";
1364 case PROXIMITY_POSITIVE:
1365 return "Positive";
1366 default:
1367 return Integer.toString(state);
1368 }
1369 }
1370
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001371 private static String reportedToPolicyToString(int state) {
1372 switch (state) {
1373 case REPORTED_TO_POLICY_SCREEN_OFF:
1374 return "REPORTED_TO_POLICY_SCREEN_OFF";
1375 case REPORTED_TO_POLICY_SCREEN_TURNING_ON:
1376 return "REPORTED_TO_POLICY_SCREEN_TURNING_ON";
1377 case REPORTED_TO_POLICY_SCREEN_ON:
1378 return "REPORTED_TO_POLICY_SCREEN_ON";
1379 default:
1380 return Integer.toString(state);
1381 }
1382 }
1383
Michael Wright639c8be2014-01-17 18:29:12 -08001384 private static Spline createAutoBrightnessSpline(int[] lux, int[] brightness) {
Erik Wolsheimerad82aca2016-06-28 14:51:07 -07001385 if (lux == null || lux.length == 0 || brightness == null || brightness.length == 0) {
1386 Slog.e(TAG, "Could not create auto-brightness spline.");
1387 return null;
1388 }
Michael Wright639c8be2014-01-17 18:29:12 -08001389 try {
1390 final int n = brightness.length;
1391 float[] x = new float[n];
1392 float[] y = new float[n];
1393 y[0] = normalizeAbsoluteBrightness(brightness[0]);
1394 for (int i = 1; i < n; i++) {
1395 x[i] = lux[i - 1];
1396 y[i] = normalizeAbsoluteBrightness(brightness[i]);
1397 }
1398
Michael Wright3e9a1342014-08-28 17:42:16 -07001399 Spline spline = Spline.createSpline(x, y);
Michael Wright639c8be2014-01-17 18:29:12 -08001400 if (DEBUG) {
1401 Slog.d(TAG, "Auto-brightness spline: " + spline);
1402 for (float v = 1f; v < lux[lux.length - 1] * 1.25f; v *= 1.25f) {
1403 Slog.d(TAG, String.format(" %7.1f: %7.1f", v, spline.interpolate(v)));
1404 }
1405 }
1406 return spline;
1407 } catch (IllegalArgumentException ex) {
1408 Slog.e(TAG, "Could not create auto-brightness spline.", ex);
1409 return null;
Jeff Brown96307042012-07-27 15:51:34 -07001410 }
Michael Wright639c8be2014-01-17 18:29:12 -08001411 }
1412
1413 private static float normalizeAbsoluteBrightness(int value) {
1414 return (float)clampAbsoluteBrightness(value) / PowerManager.BRIGHTNESS_ON;
1415 }
1416
1417 private static int clampAbsoluteBrightness(int value) {
1418 return MathUtils.constrain(value, PowerManager.BRIGHTNESS_OFF, PowerManager.BRIGHTNESS_ON);
Jeff Brown96307042012-07-27 15:51:34 -07001419 }
1420
Jeff Brown96307042012-07-27 15:51:34 -07001421 private final class DisplayControllerHandler extends Handler {
1422 public DisplayControllerHandler(Looper looper) {
Jeff Browna2910d02012-08-25 12:29:46 -07001423 super(looper, null, true /*async*/);
Jeff Brown96307042012-07-27 15:51:34 -07001424 }
1425
1426 @Override
1427 public void handleMessage(Message msg) {
1428 switch (msg.what) {
1429 case MSG_UPDATE_POWER_STATE:
1430 updatePowerState();
1431 break;
1432
1433 case MSG_PROXIMITY_SENSOR_DEBOUNCED:
1434 debounceProximitySensor();
1435 break;
Jeff Brown3ee549c2014-09-22 20:14:39 -07001436
1437 case MSG_SCREEN_ON_UNBLOCKED:
1438 if (mPendingScreenOnUnblocker == msg.obj) {
1439 unblockScreenOn();
1440 updatePowerState();
1441 }
1442 break;
Jorim Jaggi51304d72017-05-17 17:25:32 +02001443 case MSG_SCREEN_OFF_UNBLOCKED:
1444 if (mPendingScreenOffUnblocker == msg.obj) {
1445 unblockScreenOff();
1446 updatePowerState();
1447 }
1448 break;
Jeff Brown96307042012-07-27 15:51:34 -07001449 }
1450 }
1451 }
1452
1453 private final SensorEventListener mProximitySensorListener = new SensorEventListener() {
1454 @Override
1455 public void onSensorChanged(SensorEvent event) {
1456 if (mProximitySensorEnabled) {
1457 final long time = SystemClock.uptimeMillis();
1458 final float distance = event.values[0];
1459 boolean positive = distance >= 0.0f && distance < mProximityThreshold;
1460 handleProximitySensorEvent(time, positive);
1461 }
1462 }
1463
1464 @Override
1465 public void onAccuracyChanged(Sensor sensor, int accuracy) {
1466 // Not used.
1467 }
1468 };
Jeff Brown3ee549c2014-09-22 20:14:39 -07001469
1470 private final class ScreenOnUnblocker implements WindowManagerPolicy.ScreenOnListener {
1471 @Override
1472 public void onScreenOn() {
1473 Message msg = mHandler.obtainMessage(MSG_SCREEN_ON_UNBLOCKED, this);
1474 msg.setAsynchronous(true);
1475 mHandler.sendMessage(msg);
1476 }
1477 }
Jorim Jaggi51304d72017-05-17 17:25:32 +02001478
1479 private final class ScreenOffUnblocker implements WindowManagerPolicy.ScreenOffListener {
1480
1481 @Override
1482 public void onScreenOff() {
1483 Message msg = mHandler.obtainMessage(MSG_SCREEN_OFF_UNBLOCKED, this);
1484 msg.setAsynchronous(true);
1485 mHandler.sendMessage(msg);
1486 }
1487 }
Jeff Brown96307042012-07-27 15:51:34 -07001488}