blob: d2b8e5c677b46d61f5d1b2df010f7a8662ae0553 [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;
Adrian Roose99bc052017-11-20 17:55:31 +010023import com.android.server.policy.WindowManagerPolicy;
Jeff Brown96307042012-07-27 15:51:34 -070024
25import android.animation.Animator;
26import android.animation.ObjectAnimator;
Michael Wright144aac92017-12-21 18:37:41 +000027import android.annotation.Nullable;
28import android.annotation.UserIdInt;
Jeff Brown96307042012-07-27 15:51:34 -070029import android.content.Context;
Michael Wright144aac92017-12-21 18:37:41 +000030import android.content.pm.ParceledListSlice;
Jeff Brown96307042012-07-27 15:51:34 -070031import android.content.res.Resources;
32import android.hardware.Sensor;
33import android.hardware.SensorEvent;
34import android.hardware.SensorEventListener;
35import android.hardware.SensorManager;
Michael Wright144aac92017-12-21 18:37:41 +000036import android.hardware.display.BrightnessChangeEvent;
Michael Wrighteef0e132017-11-21 17:57:52 +000037import android.hardware.display.BrightnessConfiguration;
Jeff Brown131206b2014-04-08 17:27:14 -070038import android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks;
39import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
Jeff Brown96307042012-07-27 15:51:34 -070040import android.os.Handler;
41import android.os.Looper;
42import android.os.Message;
Jeff Brown330560f2012-08-21 22:10:57 -070043import android.os.PowerManager;
Jeff Brown131206b2014-04-08 17:27:14 -070044import android.os.RemoteException;
Jeff Brown96307042012-07-27 15:51:34 -070045import android.os.SystemClock;
Jeff Brown3edf5272014-08-14 19:25:14 -070046import android.os.Trace;
Michael Wright41a5cdf2013-11-13 16:18:32 -080047import android.util.MathUtils;
Jeff Brown96307042012-07-27 15:51:34 -070048import android.util.Slog;
Jeff Brown1a30b552012-08-16 01:31:11 -070049import android.util.Spline;
Jeff Brown96307042012-07-27 15:51:34 -070050import android.util.TimeUtils;
Jeff Brown037c33e2014-04-09 00:31:55 -070051import android.view.Display;
Jeff Brown96307042012-07-27 15:51:34 -070052
53import java.io.PrintWriter;
Jeff Brown96307042012-07-27 15:51:34 -070054
55/**
56 * Controls the power state of the display.
57 *
58 * Handles the proximity sensor, light sensor, and animations between states
59 * including the screen off animation.
60 *
61 * This component acts independently of the rest of the power manager service.
62 * In particular, it does not share any state and it only communicates
63 * via asynchronous callbacks to inform the power manager that something has
64 * changed.
65 *
66 * Everything this class does internally is serialized on its handler although
67 * it may be accessed by other threads from the outside.
68 *
69 * Note that the power manager service guarantees that it will hold a suspend
70 * blocker as long as the display is not ready. So most of the work done here
71 * does not need to worry about holding a suspend blocker unless it happens
72 * independently of the display ready signal.
Michael Lentine0839adb2014-07-29 18:47:56 -070073 *
Jeff Brown3ee549c2014-09-22 20:14:39 -070074 * For debugging, you can make the color fade and brightness animations run
Jeff Brown96307042012-07-27 15:51:34 -070075 * slower by changing the "animator duration scale" option in Development Settings.
76 */
Michael Wright639c8be2014-01-17 18:29:12 -080077final class DisplayPowerController implements AutomaticBrightnessController.Callbacks {
Jeff Brown96307042012-07-27 15:51:34 -070078 private static final String TAG = "DisplayPowerController";
Jeff Browna576b4d2015-04-23 19:58:06 -070079 private static final String SCREEN_ON_BLOCKED_TRACE_NAME = "Screen on blocked";
Jorim Jaggi51304d72017-05-17 17:25:32 +020080 private static final String SCREEN_OFF_BLOCKED_TRACE_NAME = "Screen off blocked";
Jeff Brown96307042012-07-27 15:51:34 -070081
Julius D'souza428aed02016-08-07 19:08:30 -070082 private static final boolean DEBUG = false;
Jeff Brown96307042012-07-27 15:51:34 -070083 private static final boolean DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT = false;
Jeff Brown96307042012-07-27 15:51:34 -070084
Jeff Brown3ee549c2014-09-22 20:14:39 -070085 // If true, uses the color fade on animation.
Jeff Brown13c589b2012-08-16 16:20:54 -070086 // We might want to turn this off if we cannot get a guarantee that the screen
87 // actually turns on and starts showing new content after the call to set the
Jeff Brown5356c7dc2012-08-20 20:17:36 -070088 // screen state returns. Playing the animation can also be somewhat slow.
Michael Lentine0839adb2014-07-29 18:47:56 -070089 private static final boolean USE_COLOR_FADE_ON_ANIMATION = false;
Jeff Brown13c589b2012-08-16 16:20:54 -070090
Jeff Brownb76eebff2012-10-05 22:26:44 -070091 // The minimum reduction in brightness when dimmed.
92 private static final int SCREEN_DIM_MINIMUM_REDUCTION = 10;
93
Michael Lentine0839adb2014-07-29 18:47:56 -070094 private static final int COLOR_FADE_ON_ANIMATION_DURATION_MILLIS = 250;
Michael Lentine0c9a62d2014-08-20 09:19:07 -070095 private static final int COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS = 400;
Jeff Brown96307042012-07-27 15:51:34 -070096
97 private static final int MSG_UPDATE_POWER_STATE = 1;
98 private static final int MSG_PROXIMITY_SENSOR_DEBOUNCED = 2;
Jeff Brown3ee549c2014-09-22 20:14:39 -070099 private static final int MSG_SCREEN_ON_UNBLOCKED = 3;
Jorim Jaggi51304d72017-05-17 17:25:32 +0200100 private static final int MSG_SCREEN_OFF_UNBLOCKED = 4;
Michael Wrighteef0e132017-11-21 17:57:52 +0000101 private static final int MSG_CONFIGURE_BRIGHTNESS = 5;
Jeff Brown96307042012-07-27 15:51:34 -0700102
103 private static final int PROXIMITY_UNKNOWN = -1;
104 private static final int PROXIMITY_NEGATIVE = 0;
105 private static final int PROXIMITY_POSITIVE = 1;
106
Jeff Brown93cbbb22012-10-04 13:18:36 -0700107 // Proximity sensor debounce delay in milliseconds for positive or negative transitions.
108 private static final int PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY = 0;
Jeff Brownec083212013-09-11 20:45:25 -0700109 private static final int PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY = 250;
Jeff Brown96307042012-07-27 15:51:34 -0700110
111 // Trigger proximity if distance is less than 5 cm.
112 private static final float TYPICAL_PROXIMITY_THRESHOLD = 5.0f;
113
Julius D'souzad5105dd2017-06-02 11:03:53 -0700114 // State machine constants for tracking initial brightness ramp skipping when enabled.
115 private static final int RAMP_STATE_SKIP_NONE = 0;
116 private static final int RAMP_STATE_SKIP_INITIAL = 1;
117 private static final int RAMP_STATE_SKIP_AUTOBRIGHT = 2;
118
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700119 private static final int REPORTED_TO_POLICY_SCREEN_OFF = 0;
120 private static final int REPORTED_TO_POLICY_SCREEN_TURNING_ON = 1;
121 private static final int REPORTED_TO_POLICY_SCREEN_ON = 2;
Jorim Jaggi51304d72017-05-17 17:25:32 +0200122 private static final int REPORTED_TO_POLICY_SCREEN_TURNING_OFF = 3;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700123
Jeff Brown96307042012-07-27 15:51:34 -0700124 private final Object mLock = new Object();
125
Michael Lentine0839adb2014-07-29 18:47:56 -0700126 private final Context mContext;
127
Jeff Brown96307042012-07-27 15:51:34 -0700128 // Our handler.
129 private final DisplayControllerHandler mHandler;
130
131 // Asynchronous callbacks into the power manager service.
132 // Only invoked from the handler thread while no locks are held.
Jeff Brown131206b2014-04-08 17:27:14 -0700133 private final DisplayPowerCallbacks mCallbacks;
134
135 // Battery stats.
136 private final IBatteryStats mBatteryStats;
Jeff Brown96307042012-07-27 15:51:34 -0700137
Jeff Brown96307042012-07-27 15:51:34 -0700138 // The sensor manager.
139 private final SensorManager mSensorManager;
140
Jeff Brown3ee549c2014-09-22 20:14:39 -0700141 // The window manager policy.
142 private final WindowManagerPolicy mWindowManagerPolicy;
143
Jeff Brown037c33e2014-04-09 00:31:55 -0700144 // The display blanker.
145 private final DisplayBlanker mBlanker;
146
Jeff Brown96307042012-07-27 15:51:34 -0700147 // The proximity sensor, or null if not available or needed.
148 private Sensor mProximitySensor;
149
Jeff Brown26875502014-01-30 21:47:47 -0800150 // The doze screen brightness.
151 private final int mScreenBrightnessDozeConfig;
152
Jeff Brown96307042012-07-27 15:51:34 -0700153 // The dim screen brightness.
154 private final int mScreenBrightnessDimConfig;
155
Jeff Brownb76eebff2012-10-05 22:26:44 -0700156 // The minimum allowed brightness.
157 private final int mScreenBrightnessRangeMinimum;
158
159 // The maximum allowed brightness.
160 private final int mScreenBrightnessRangeMaximum;
161
Jeff Brown330560f2012-08-21 22:10:57 -0700162 // True if auto-brightness should be used.
Jeff Brown96307042012-07-27 15:51:34 -0700163 private boolean mUseSoftwareAutoBrightnessConfig;
Jeff Brown330560f2012-08-21 22:10:57 -0700164
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700165 // True if should use light sensor to automatically determine doze screen brightness.
166 private final boolean mAllowAutoBrightnessWhileDozingConfig;
167
Narayan Kamath38819982017-07-06 18:15:30 +0100168 // Whether or not the color fade on screen on / off is enabled.
169 private final boolean mColorFadeEnabled;
170
Jeff Brown252c2062012-10-08 16:21:01 -0700171 // True if we should fade the screen while turning it off, false if we should play
Jeff Brown3ee549c2014-09-22 20:14:39 -0700172 // a stylish color fade animation instead.
Michael Lentine0839adb2014-07-29 18:47:56 -0700173 private boolean mColorFadeFadesConfig;
Jeff Browna52772f2012-10-04 18:38:09 -0700174
Michael Wrightc3e6af82017-07-25 22:31:03 +0100175 // True if we need to fake a transition to off when coming out of a doze state.
176 // Some display hardware will blank itself when coming out of doze in order to hide
177 // artifacts. For these displays we fake a transition into OFF so that policy can appropriately
178 // blank itself and begin an appropriate power on animation.
179 private boolean mDisplayBlanksAfterDozeConfig;
Michael Wright05e76fe2017-07-20 18:18:33 +0100180
Michael Wright63a40062017-07-26 01:10:59 +0100181 // True if there are only buckets of brightness values when the display is in the doze state,
182 // rather than a full range of values. If this is true, then we'll avoid animating the screen
183 // brightness since it'd likely be multiple jarring brightness transitions instead of just one
184 // to reach the final state.
185 private boolean mBrightnessBucketsInDozeConfig;
186
Jeff Brown96307042012-07-27 15:51:34 -0700187 // The pending power request.
188 // Initially null until the first call to requestPowerState.
189 // Guarded by mLock.
190 private DisplayPowerRequest mPendingRequestLocked;
191
192 // True if a request has been made to wait for the proximity sensor to go negative.
193 // Guarded by mLock.
194 private boolean mPendingWaitForNegativeProximityLocked;
195
196 // True if the pending power request or wait for negative proximity flag
197 // has been changed since the last update occurred.
198 // Guarded by mLock.
199 private boolean mPendingRequestChangedLocked;
200
201 // Set to true when the important parts of the pending power request have been applied.
202 // The important parts are mainly the screen state. Brightness changes may occur
203 // concurrently.
204 // Guarded by mLock.
205 private boolean mDisplayReadyLocked;
206
207 // Set to true if a power state update is required.
208 // Guarded by mLock.
209 private boolean mPendingUpdatePowerStateLocked;
210
211 /* The following state must only be accessed by the handler thread. */
212
213 // The currently requested power state.
214 // The power controller will progressively update its internal state to match
215 // the requested power state. Initially null until the first update.
216 private DisplayPowerRequest mPowerRequest;
217
218 // The current power state.
219 // Must only be accessed on the handler thread.
220 private DisplayPowerState mPowerState;
221
222 // True if the device should wait for negative proximity sensor before
223 // waking up the screen. This is set to false as soon as a negative
224 // proximity sensor measurement is observed or when the device is forced to
225 // go to sleep by the user. While true, the screen remains off.
226 private boolean mWaitingForNegativeProximity;
227
228 // The actual proximity sensor threshold value.
229 private float mProximityThreshold;
230
231 // Set to true if the proximity sensor listener has been registered
232 // with the sensor manager.
233 private boolean mProximitySensorEnabled;
234
235 // The debounced proximity sensor state.
236 private int mProximity = PROXIMITY_UNKNOWN;
237
238 // The raw non-debounced proximity sensor state.
239 private int mPendingProximity = PROXIMITY_UNKNOWN;
Jeff Brownec083212013-09-11 20:45:25 -0700240 private long mPendingProximityDebounceTime = -1; // -1 if fully debounced
Jeff Brown96307042012-07-27 15:51:34 -0700241
242 // True if the screen was turned off because of the proximity sensor.
243 // When the screen turns on again, we report user activity to the power manager.
244 private boolean mScreenOffBecauseOfProximity;
245
Jeff Brown3ee549c2014-09-22 20:14:39 -0700246 // The currently active screen on unblocker. This field is non-null whenever
247 // we are waiting for a callback to release it and unblock the screen.
248 private ScreenOnUnblocker mPendingScreenOnUnblocker;
Jorim Jaggi51304d72017-05-17 17:25:32 +0200249 private ScreenOffUnblocker mPendingScreenOffUnblocker;
Jeff Brown3ee549c2014-09-22 20:14:39 -0700250
251 // True if we were in the process of turning off the screen.
252 // This allows us to recover more gracefully from situations where we abort
253 // turning off the screen.
254 private boolean mPendingScreenOff;
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700255
Jeff Brown0a434772014-09-30 14:42:27 -0700256 // True if we have unfinished business and are holding a suspend blocker.
257 private boolean mUnfinishedBusiness;
258
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700259 // The elapsed real time when the screen on was blocked.
260 private long mScreenOnBlockStartRealTime;
Jorim Jaggi51304d72017-05-17 17:25:32 +0200261 private long mScreenOffBlockStartRealTime;
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700262
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700263 // Screen state we reported to policy. Must be one of REPORTED_TO_POLICY_SCREEN_* fields.
264 private int mReportedScreenStateToPolicy;
Jeff Browne1633ad2015-06-22 19:24:24 -0700265
Julius D'souzad5105dd2017-06-02 11:03:53 -0700266 // If the last recorded screen state was dozing or not.
267 private boolean mDozing;
268
Jeff Brown970d4132014-07-19 11:33:47 -0700269 // Remembers whether certain kinds of brightness adjustments
270 // were recently applied so that we can decide how to transition.
271 private boolean mAppliedAutoBrightness;
272 private boolean mAppliedDimming;
273 private boolean mAppliedLowPower;
Jeff Brown96307042012-07-27 15:51:34 -0700274
Julius D'souzafeadad12016-08-05 14:34:38 -0700275 // Brightness animation ramp rates in brightness units per second
Prashant Malani99e6d432016-03-29 16:32:37 -0700276 private final int mBrightnessRampRateFast;
Julius D'souzafeadad12016-08-05 14:34:38 -0700277 private final int mBrightnessRampRateSlow;
Prashant Malani99e6d432016-03-29 16:32:37 -0700278
Julius D'souzad5105dd2017-06-02 11:03:53 -0700279 // Whether or not to skip the initial brightness ramps into STATE_ON.
280 private final boolean mSkipScreenOnBrightnessRamp;
281
282 // A record of state for skipping brightness ramps.
283 private int mSkipRampState = RAMP_STATE_SKIP_NONE;
284
285 // The first autobrightness value set when entering RAMP_STATE_SKIP_INITIAL.
286 private int mInitialAutoBrightness;
287
Michael Wright639c8be2014-01-17 18:29:12 -0800288 // The controller for the automatic brightness level.
289 private AutomaticBrightnessController mAutomaticBrightnessController;
290
Michael Wright144aac92017-12-21 18:37:41 +0000291 // The mapper between ambient lux, display backlight values, and display brightness.
292 @Nullable
293 private BrightnessMappingStrategy mBrightnessMapper;
294
Michael Wrighteef0e132017-11-21 17:57:52 +0000295 // The current brightness configuration.
Michael Wrightd5df3612018-01-02 12:44:52 +0000296 @Nullable
Michael Wrighteef0e132017-11-21 17:57:52 +0000297 private BrightnessConfiguration mBrightnessConfiguration;
298
Michael Wrightd5df3612018-01-02 12:44:52 +0000299 // The last brightness that was set by the user and not temporary. Set to -1 when a brightness
300 // has yet to be recorded.
301 private int mLastBrightness;
302
303 // The last auto brightness adjustment that was set by the user and not temporary. Set to
304 // Float.NaN when an auto-brightness adjustment hasn't been recorded yet.
305 private float mLastAutoBrightnessAdjustment;
306
Jeff Brown96307042012-07-27 15:51:34 -0700307 // Animators.
Michael Lentine0839adb2014-07-29 18:47:56 -0700308 private ObjectAnimator mColorFadeOnAnimator;
309 private ObjectAnimator mColorFadeOffAnimator;
Jeff Brown96307042012-07-27 15:51:34 -0700310 private RampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator;
311
Michael Wright144aac92017-12-21 18:37:41 +0000312 // Tracker for brightness changes
313 private final BrightnessTracker mBrightnessTracker;
314
Jeff Brown96307042012-07-27 15:51:34 -0700315 /**
316 * Creates the display power controller.
317 */
Jeff Brown131206b2014-04-08 17:27:14 -0700318 public DisplayPowerController(Context context,
Jeff Brown037c33e2014-04-09 00:31:55 -0700319 DisplayPowerCallbacks callbacks, Handler handler,
320 SensorManager sensorManager, DisplayBlanker blanker) {
Jeff Brown131206b2014-04-08 17:27:14 -0700321 mHandler = new DisplayControllerHandler(handler.getLooper());
Michael Wright144aac92017-12-21 18:37:41 +0000322 mBrightnessTracker = new BrightnessTracker(context, null);
Jeff Brown96307042012-07-27 15:51:34 -0700323 mCallbacks = callbacks;
Jeff Brown96307042012-07-27 15:51:34 -0700324
Jeff Brown131206b2014-04-08 17:27:14 -0700325 mBatteryStats = BatteryStatsService.getService();
Jeff Brown3b971592013-01-09 18:46:37 -0800326 mSensorManager = sensorManager;
Jeff Brown3ee549c2014-09-22 20:14:39 -0700327 mWindowManagerPolicy = LocalServices.getService(WindowManagerPolicy.class);
Jeff Brown037c33e2014-04-09 00:31:55 -0700328 mBlanker = blanker;
Michael Lentine0839adb2014-07-29 18:47:56 -0700329 mContext = context;
Jeff Brown96307042012-07-27 15:51:34 -0700330
331 final Resources resources = context.getResources();
Jeff Brown1bfd0f42014-08-22 01:59:06 -0700332 final int screenBrightnessSettingMinimum = clampAbsoluteBrightness(resources.getInteger(
333 com.android.internal.R.integer.config_screenBrightnessSettingMinimum));
Jeff Brownb76eebff2012-10-05 22:26:44 -0700334
Jeff Brown26875502014-01-30 21:47:47 -0800335 mScreenBrightnessDozeConfig = clampAbsoluteBrightness(resources.getInteger(
336 com.android.internal.R.integer.config_screenBrightnessDoze));
337
Jeff Brownb76eebff2012-10-05 22:26:44 -0700338 mScreenBrightnessDimConfig = clampAbsoluteBrightness(resources.getInteger(
339 com.android.internal.R.integer.config_screenBrightnessDim));
340
Michael Wright144aac92017-12-21 18:37:41 +0000341 mScreenBrightnessRangeMinimum =
342 Math.min(screenBrightnessSettingMinimum, mScreenBrightnessDimConfig);
Michael Wright639c8be2014-01-17 18:29:12 -0800343
Michael Wrighteef0e132017-11-21 17:57:52 +0000344 mScreenBrightnessRangeMaximum = clampAbsoluteBrightness(resources.getInteger(
345 com.android.internal.R.integer.config_screenBrightnessSettingMaximum));
Jeff Brownb76eebff2012-10-05 22:26:44 -0700346
Jeff Brown96307042012-07-27 15:51:34 -0700347 mUseSoftwareAutoBrightnessConfig = resources.getBoolean(
348 com.android.internal.R.bool.config_automatic_brightness_available);
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700349
350 mAllowAutoBrightnessWhileDozingConfig = resources.getBoolean(
351 com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing);
352
Prashant Malani99e6d432016-03-29 16:32:37 -0700353 mBrightnessRampRateFast = resources.getInteger(
354 com.android.internal.R.integer.config_brightness_ramp_rate_fast);
Julius D'souzafeadad12016-08-05 14:34:38 -0700355 mBrightnessRampRateSlow = resources.getInteger(
356 com.android.internal.R.integer.config_brightness_ramp_rate_slow);
Julius D'souzad5105dd2017-06-02 11:03:53 -0700357 mSkipScreenOnBrightnessRamp = resources.getBoolean(
358 com.android.internal.R.bool.config_skipScreenOnBrightnessRamp);
Prashant Malani99e6d432016-03-29 16:32:37 -0700359
Jeff Brown96307042012-07-27 15:51:34 -0700360 if (mUseSoftwareAutoBrightnessConfig) {
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700361 final float dozeScaleFactor = resources.getFraction(
362 com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor,
363 1, 1);
Jeff Brown1a30b552012-08-16 01:31:11 -0700364
Michael Wrighteef0e132017-11-21 17:57:52 +0000365 int[] brightLevels = resources.getIntArray(
366 com.android.internal.R.array.config_dynamicHysteresisBrightLevels);
367 int[] darkLevels = resources.getIntArray(
368 com.android.internal.R.array.config_dynamicHysteresisDarkLevels);
369 int[] luxHysteresisLevels = resources.getIntArray(
370 com.android.internal.R.array.config_dynamicHysteresisLuxLevels);
371 HysteresisLevels dynamicHysteresis = new HysteresisLevels(
372 brightLevels, darkLevels, luxHysteresisLevels);
373
374 long brighteningLightDebounce = resources.getInteger(
375 com.android.internal.R.integer.config_autoBrightnessBrighteningLightDebounce);
376 long darkeningLightDebounce = resources.getInteger(
377 com.android.internal.R.integer.config_autoBrightnessDarkeningLightDebounce);
378 boolean autoBrightnessResetAmbientLuxAfterWarmUp = resources.getBoolean(
379 com.android.internal.R.bool.config_autoBrightnessResetAmbientLuxAfterWarmUp);
380 int ambientLightHorizon = resources.getInteger(
381 com.android.internal.R.integer.config_autoBrightnessAmbientLightHorizon);
382 float autoBrightnessAdjustmentMaxGamma = resources.getFraction(
383 com.android.internal.R.fraction.config_autoBrightnessAdjustmentMaxGamma,
384 1, 1);
385
386 int lightSensorWarmUpTimeConfig = resources.getInteger(
387 com.android.internal.R.integer.config_lightSensorWarmupTime);
388 int lightSensorRate = resources.getInteger(
389 com.android.internal.R.integer.config_autoBrightnessLightSensorRate);
390 int initialLightSensorRate = resources.getInteger(
391 com.android.internal.R.integer.config_autoBrightnessInitialLightSensorRate);
392 if (initialLightSensorRate == -1) {
393 initialLightSensorRate = lightSensorRate;
394 } else if (initialLightSensorRate > lightSensorRate) {
395 Slog.w(TAG, "Expected config_autoBrightnessInitialLightSensorRate ("
396 + initialLightSensorRate + ") to be less than or equal to "
397 + "config_autoBrightnessLightSensorRate (" + lightSensorRate + ").");
398 }
399
Michael Wright144aac92017-12-21 18:37:41 +0000400 mBrightnessMapper = BrightnessMappingStrategy.create(resources);
401 if (mBrightnessMapper != null) {
Jeff Brown131206b2014-04-08 17:27:14 -0700402 mAutomaticBrightnessController = new AutomaticBrightnessController(this,
Michael Wright144aac92017-12-21 18:37:41 +0000403 handler.getLooper(), sensorManager, mBrightnessMapper,
404 lightSensorWarmUpTimeConfig, mScreenBrightnessRangeMinimum,
405 mScreenBrightnessRangeMaximum, dozeScaleFactor, lightSensorRate,
406 initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce,
Julius D'souza428aed02016-08-07 19:08:30 -0700407 autoBrightnessResetAmbientLuxAfterWarmUp, ambientLightHorizon,
408 autoBrightnessAdjustmentMaxGamma, dynamicHysteresis);
Michael Wrighteef0e132017-11-21 17:57:52 +0000409 } else {
410 mUseSoftwareAutoBrightnessConfig = false;
Jeff Brown96307042012-07-27 15:51:34 -0700411 }
Jeff Brown96307042012-07-27 15:51:34 -0700412 }
413
Narayan Kamath38819982017-07-06 18:15:30 +0100414 mColorFadeEnabled = !ActivityManager.isLowRamDeviceStatic();
Michael Lentine0839adb2014-07-29 18:47:56 -0700415 mColorFadeFadesConfig = resources.getBoolean(
Jeff Browna52772f2012-10-04 18:38:09 -0700416 com.android.internal.R.bool.config_animateScreenLights);
417
Michael Wrightc3e6af82017-07-25 22:31:03 +0100418 mDisplayBlanksAfterDozeConfig = resources.getBoolean(
419 com.android.internal.R.bool.config_displayBlanksAfterDoze);
Michael Wright05e76fe2017-07-20 18:18:33 +0100420
Michael Wright63a40062017-07-26 01:10:59 +0100421 mBrightnessBucketsInDozeConfig = resources.getBoolean(
422 com.android.internal.R.bool.config_displayBrightnessBucketsInDoze);
423
Jeff Brown96307042012-07-27 15:51:34 -0700424 if (!DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) {
425 mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
426 if (mProximitySensor != null) {
427 mProximityThreshold = Math.min(mProximitySensor.getMaximumRange(),
428 TYPICAL_PROXIMITY_THRESHOLD);
429 }
430 }
431
Michael Wright144aac92017-12-21 18:37:41 +0000432 mLastBrightness = -1;
433 mLastAutoBrightnessAdjustment = Float.NaN;
Michael Wrighteef0e132017-11-21 17:57:52 +0000434 }
435
Jeff Brown96307042012-07-27 15:51:34 -0700436 /**
437 * Returns true if the proximity sensor screen-off function is available.
438 */
439 public boolean isProximitySensorAvailable() {
440 return mProximitySensor != null;
441 }
442
443 /**
Michael Wright144aac92017-12-21 18:37:41 +0000444 * Get the {@link BrightnessChangeEvent}s for the specified user.
445 * @param userId userId to fetch data for
446 * @param includePackage if false will null out the package name in events
447 */
448 public ParceledListSlice<BrightnessChangeEvent> getBrightnessEvents(
449 @UserIdInt int userId, boolean includePackage) {
450 return mBrightnessTracker.getEvents(userId, includePackage);
451 }
452
453 /**
454 * Persist the brightness slider events to disk.
455 */
456 public void persistBrightnessSliderEvents() {
457 mBrightnessTracker.persistEvents();
458 }
459
460 /**
Jeff Brown96307042012-07-27 15:51:34 -0700461 * Requests a new power state.
462 * The controller makes a copy of the provided object and then
463 * begins adjusting the power state to match what was requested.
464 *
465 * @param request The requested power state.
466 * @param waitForNegativeProximity If true, issues a request to wait for
467 * negative proximity before turning the screen back on, assuming the screen
468 * was turned off by the proximity sensor.
469 * @return True if display is ready, false if there are important changes that must
470 * be made asynchronously (such as turning the screen on), in which case the caller
Jeff Brown606e4e82014-09-18 15:22:26 -0700471 * should grab a wake lock, watch for {@link DisplayPowerCallbacks#onStateChanged()}
472 * then try the request again later until the state converges.
Jeff Brown96307042012-07-27 15:51:34 -0700473 */
474 public boolean requestPowerState(DisplayPowerRequest request,
475 boolean waitForNegativeProximity) {
476 if (DEBUG) {
477 Slog.d(TAG, "requestPowerState: "
478 + request + ", waitForNegativeProximity=" + waitForNegativeProximity);
479 }
480
481 synchronized (mLock) {
482 boolean changed = false;
483
484 if (waitForNegativeProximity
485 && !mPendingWaitForNegativeProximityLocked) {
486 mPendingWaitForNegativeProximityLocked = true;
487 changed = true;
488 }
489
490 if (mPendingRequestLocked == null) {
491 mPendingRequestLocked = new DisplayPowerRequest(request);
492 changed = true;
493 } else if (!mPendingRequestLocked.equals(request)) {
494 mPendingRequestLocked.copyFrom(request);
495 changed = true;
496 }
497
498 if (changed) {
499 mDisplayReadyLocked = false;
500 }
501
502 if (changed && !mPendingRequestChangedLocked) {
503 mPendingRequestChangedLocked = true;
504 sendUpdatePowerStateLocked();
505 }
506
507 return mDisplayReadyLocked;
508 }
509 }
510
511 private void sendUpdatePowerState() {
512 synchronized (mLock) {
513 sendUpdatePowerStateLocked();
514 }
515 }
516
517 private void sendUpdatePowerStateLocked() {
518 if (!mPendingUpdatePowerStateLocked) {
519 mPendingUpdatePowerStateLocked = true;
520 Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE);
Jeff Brown96307042012-07-27 15:51:34 -0700521 mHandler.sendMessage(msg);
522 }
523 }
524
525 private void initialize() {
Jeff Brown037c33e2014-04-09 00:31:55 -0700526 // Initialize the power state object for the default display.
527 // In the future, we might manage multiple displays independently.
528 mPowerState = new DisplayPowerState(mBlanker,
Narayan Kamath38819982017-07-06 18:15:30 +0100529 mColorFadeEnabled ? new ColorFade(Display.DEFAULT_DISPLAY) : null);
Jeff Brown96307042012-07-27 15:51:34 -0700530
Narayan Kamath38819982017-07-06 18:15:30 +0100531 if (mColorFadeEnabled) {
532 mColorFadeOnAnimator = ObjectAnimator.ofFloat(
533 mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 0.0f, 1.0f);
534 mColorFadeOnAnimator.setDuration(COLOR_FADE_ON_ANIMATION_DURATION_MILLIS);
535 mColorFadeOnAnimator.addListener(mAnimatorListener);
Jeff Brown96307042012-07-27 15:51:34 -0700536
Narayan Kamath38819982017-07-06 18:15:30 +0100537 mColorFadeOffAnimator = ObjectAnimator.ofFloat(
538 mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 1.0f, 0.0f);
539 mColorFadeOffAnimator.setDuration(COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS);
540 mColorFadeOffAnimator.addListener(mAnimatorListener);
541 }
Jeff Brown96307042012-07-27 15:51:34 -0700542
543 mScreenBrightnessRampAnimator = new RampAnimator<DisplayPowerState>(
544 mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS);
Jeff Brown42558692014-05-20 22:02:46 -0700545 mScreenBrightnessRampAnimator.setListener(mRampAnimatorListener);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800546
Jeff Brown131206b2014-04-08 17:27:14 -0700547 // Initialize screen state for battery stats.
548 try {
Jeff Browne95c3cd2014-05-02 16:59:26 -0700549 mBatteryStats.noteScreenState(mPowerState.getScreenState());
Jeff Brown131206b2014-04-08 17:27:14 -0700550 mBatteryStats.noteScreenBrightness(mPowerState.getScreenBrightness());
551 } catch (RemoteException ex) {
552 // same process
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800553 }
Michael Wright144aac92017-12-21 18:37:41 +0000554
555 // Initialize all of the brightness tracking state
556 final float brightness = getNits(mPowerState.getScreenBrightness());
557 if (brightness >= 0.0f) {
558 mBrightnessTracker.start(brightness);
559 }
Jeff Brown96307042012-07-27 15:51:34 -0700560 }
561
562 private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() {
563 @Override
564 public void onAnimationStart(Animator animation) {
565 }
566 @Override
567 public void onAnimationEnd(Animator animation) {
568 sendUpdatePowerState();
569 }
570 @Override
571 public void onAnimationRepeat(Animator animation) {
572 }
573 @Override
574 public void onAnimationCancel(Animator animation) {
575 }
576 };
577
Jeff Brown42558692014-05-20 22:02:46 -0700578 private final RampAnimator.Listener mRampAnimatorListener = new RampAnimator.Listener() {
579 @Override
580 public void onAnimationEnd() {
581 sendUpdatePowerState();
582 }
583 };
584
Jeff Brown96307042012-07-27 15:51:34 -0700585 private void updatePowerState() {
586 // Update the power state request.
587 final boolean mustNotify;
588 boolean mustInitialize = false;
Adrian Roos6da87ab2014-05-16 23:09:41 +0200589 boolean autoBrightnessAdjustmentChanged = false;
Jeff Brown330560f2012-08-21 22:10:57 -0700590
Jeff Brown96307042012-07-27 15:51:34 -0700591 synchronized (mLock) {
592 mPendingUpdatePowerStateLocked = false;
593 if (mPendingRequestLocked == null) {
594 return; // wait until first actual power request
595 }
596
597 if (mPowerRequest == null) {
598 mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked);
599 mWaitingForNegativeProximity = mPendingWaitForNegativeProximityLocked;
Jeff Brown6307a152012-08-20 13:24:23 -0700600 mPendingWaitForNegativeProximityLocked = false;
Jeff Brown96307042012-07-27 15:51:34 -0700601 mPendingRequestChangedLocked = false;
602 mustInitialize = true;
603 } else if (mPendingRequestChangedLocked) {
Adrian Roos6da87ab2014-05-16 23:09:41 +0200604 autoBrightnessAdjustmentChanged = (mPowerRequest.screenAutoBrightnessAdjustment
605 != mPendingRequestLocked.screenAutoBrightnessAdjustment);
Jeff Brown96307042012-07-27 15:51:34 -0700606 mPowerRequest.copyFrom(mPendingRequestLocked);
607 mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked;
Jeff Brown6307a152012-08-20 13:24:23 -0700608 mPendingWaitForNegativeProximityLocked = false;
Jeff Brown96307042012-07-27 15:51:34 -0700609 mPendingRequestChangedLocked = false;
610 mDisplayReadyLocked = false;
611 }
612
613 mustNotify = !mDisplayReadyLocked;
614 }
615
616 // Initialize things the first time the power state is changed.
617 if (mustInitialize) {
618 initialize();
619 }
620
Jeff Brown970d4132014-07-19 11:33:47 -0700621 // Compute the basic display state using the policy.
622 // We might override this below based on other factors.
623 int state;
624 int brightness = PowerManager.BRIGHTNESS_DEFAULT;
Jeff Brown2175e9c2014-09-12 16:11:07 -0700625 boolean performScreenOffTransition = false;
Jeff Brown970d4132014-07-19 11:33:47 -0700626 switch (mPowerRequest.policy) {
627 case DisplayPowerRequest.POLICY_OFF:
628 state = Display.STATE_OFF;
Jeff Brown2175e9c2014-09-12 16:11:07 -0700629 performScreenOffTransition = true;
Jeff Brown970d4132014-07-19 11:33:47 -0700630 break;
631 case DisplayPowerRequest.POLICY_DOZE:
632 if (mPowerRequest.dozeScreenState != Display.STATE_UNKNOWN) {
633 state = mPowerRequest.dozeScreenState;
634 } else {
635 state = Display.STATE_DOZE;
636 }
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700637 if (!mAllowAutoBrightnessWhileDozingConfig) {
638 brightness = mPowerRequest.dozeScreenBrightness;
639 }
Jeff Brown970d4132014-07-19 11:33:47 -0700640 break;
Santos Cordon3107d292016-09-20 15:50:35 -0700641 case DisplayPowerRequest.POLICY_VR:
642 state = Display.STATE_VR;
643 break;
Jeff Brown970d4132014-07-19 11:33:47 -0700644 case DisplayPowerRequest.POLICY_DIM:
645 case DisplayPowerRequest.POLICY_BRIGHT:
646 default:
647 state = Display.STATE_ON;
648 break;
649 }
Jeff Brown2175e9c2014-09-12 16:11:07 -0700650 assert(state != Display.STATE_UNKNOWN);
Jeff Brown970d4132014-07-19 11:33:47 -0700651
Jeff Brown6307a152012-08-20 13:24:23 -0700652 // Apply the proximity sensor.
Jeff Brown96307042012-07-27 15:51:34 -0700653 if (mProximitySensor != null) {
Jeff Brown970d4132014-07-19 11:33:47 -0700654 if (mPowerRequest.useProximitySensor && state != Display.STATE_OFF) {
Jeff Brown6307a152012-08-20 13:24:23 -0700655 setProximitySensorEnabled(true);
656 if (!mScreenOffBecauseOfProximity
657 && mProximity == PROXIMITY_POSITIVE) {
658 mScreenOffBecauseOfProximity = true;
Jeff Brownec083212013-09-11 20:45:25 -0700659 sendOnProximityPositiveWithWakelock();
Jeff Brown6307a152012-08-20 13:24:23 -0700660 }
661 } else if (mWaitingForNegativeProximity
662 && mScreenOffBecauseOfProximity
663 && mProximity == PROXIMITY_POSITIVE
Jeff Brown970d4132014-07-19 11:33:47 -0700664 && state != Display.STATE_OFF) {
Jeff Brown6307a152012-08-20 13:24:23 -0700665 setProximitySensorEnabled(true);
666 } else {
667 setProximitySensorEnabled(false);
668 mWaitingForNegativeProximity = false;
669 }
670 if (mScreenOffBecauseOfProximity
671 && mProximity != PROXIMITY_POSITIVE) {
Jeff Brown96307042012-07-27 15:51:34 -0700672 mScreenOffBecauseOfProximity = false;
Jeff Brownec083212013-09-11 20:45:25 -0700673 sendOnProximityNegativeWithWakelock();
Jeff Brown96307042012-07-27 15:51:34 -0700674 }
Jeff Brown6307a152012-08-20 13:24:23 -0700675 } else {
676 mWaitingForNegativeProximity = false;
Jeff Brown96307042012-07-27 15:51:34 -0700677 }
Jeff Brown970d4132014-07-19 11:33:47 -0700678 if (mScreenOffBecauseOfProximity) {
679 state = Display.STATE_OFF;
Jeff Brown96307042012-07-27 15:51:34 -0700680 }
681
Jeff Brownbf4e4142014-10-02 13:08:05 -0700682 // Animate the screen state change unless already animating.
683 // The transition may be deferred, so after this point we will use the
684 // actual state instead of the desired one.
Santos Cordon3107d292016-09-20 15:50:35 -0700685 final int oldState = mPowerState.getScreenState();
Jeff Brownbf4e4142014-10-02 13:08:05 -0700686 animateScreenStateChange(state, performScreenOffTransition);
687 state = mPowerState.getScreenState();
688
Jeff Brown970d4132014-07-19 11:33:47 -0700689 // Use zero brightness when screen is off.
690 if (state == Display.STATE_OFF) {
691 brightness = PowerManager.BRIGHTNESS_OFF;
692 }
693
Michael Wright144aac92017-12-21 18:37:41 +0000694
695 final boolean autoBrightnessEnabledInDoze =
696 mAllowAutoBrightnessWhileDozingConfig && Display.isDozeState(state);
697 final boolean autoBrightnessEnabled = mPowerRequest.useAutoBrightness
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700698 && (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
Michael Wright144aac92017-12-21 18:37:41 +0000699 && brightness < 0
700 && mAutomaticBrightnessController != null;
701 final boolean brightnessAdjustmentChanged =
702 !Float.isNaN(mLastAutoBrightnessAdjustment)
703 && mPowerRequest.screenAutoBrightnessAdjustment != mLastAutoBrightnessAdjustment;
704 final boolean brightnessChanged = mLastBrightness >= 0
705 && mPowerRequest.screenBrightness != mLastBrightness;
706
707 // Update the last set brightness values.
708 final boolean userInitiatedChange;
709 if (mPowerRequest.brightnessSetByUser && !mPowerRequest.brightnessIsTemporary) {
710 userInitiatedChange = autoBrightnessEnabled && brightnessAdjustmentChanged
711 || !autoBrightnessEnabled && brightnessChanged;
712 mLastBrightness = mPowerRequest.screenBrightness;
713 mLastAutoBrightnessAdjustment = mPowerRequest.screenAutoBrightnessAdjustment;
714 } else {
715 userInitiatedChange = false;
716 }
717
718 // Configure auto-brightness.
719 if (mAutomaticBrightnessController != null) {
Jeff Brown970d4132014-07-19 11:33:47 -0700720 mAutomaticBrightnessController.configure(autoBrightnessEnabled,
Michael Wrighteef0e132017-11-21 17:57:52 +0000721 mBrightnessConfiguration, mPowerRequest.screenAutoBrightnessAdjustment,
722 state != Display.STATE_ON, userInitiatedChange);
Jeff Brown970d4132014-07-19 11:33:47 -0700723 }
724
Jeff Brown7b5be5e2014-11-12 18:45:31 -0800725 // Apply brightness boost.
726 // We do this here after configuring auto-brightness so that we don't
727 // disable the light sensor during this temporary state. That way when
728 // boost ends we will be able to resume normal auto-brightness behavior
729 // without any delay.
730 if (mPowerRequest.boostScreenBrightness
731 && brightness != PowerManager.BRIGHTNESS_OFF) {
732 brightness = PowerManager.BRIGHTNESS_ON;
733 }
734
Jeff Brown970d4132014-07-19 11:33:47 -0700735 // Apply auto-brightness.
736 boolean slowChange = false;
737 if (brightness < 0) {
738 if (autoBrightnessEnabled) {
739 brightness = mAutomaticBrightnessController.getAutomaticScreenBrightness();
740 }
741 if (brightness >= 0) {
742 // Use current auto-brightness value and slowly adjust to changes.
743 brightness = clampScreenBrightness(brightness);
744 if (mAppliedAutoBrightness && !autoBrightnessAdjustmentChanged) {
745 slowChange = true; // slowly adapt to auto-brightness
746 }
747 mAppliedAutoBrightness = true;
Jeff Brown96307042012-07-27 15:51:34 -0700748 } else {
Jeff Brown970d4132014-07-19 11:33:47 -0700749 mAppliedAutoBrightness = false;
Jeff Brown96307042012-07-27 15:51:34 -0700750 }
751 } else {
Jeff Brown970d4132014-07-19 11:33:47 -0700752 mAppliedAutoBrightness = false;
753 }
754
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700755 // Use default brightness when dozing unless overridden.
Michael Wrightb0a1d3d2017-09-22 15:05:02 +0100756 if (brightness < 0 && Display.isDozeState(state)) {
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700757 brightness = mScreenBrightnessDozeConfig;
758 }
759
Jeff Brown970d4132014-07-19 11:33:47 -0700760 // Apply manual brightness.
761 // Use the current brightness setting from the request, which is expected
762 // provide a nominal default value for the case where auto-brightness
763 // is not ready yet.
764 if (brightness < 0) {
765 brightness = clampScreenBrightness(mPowerRequest.screenBrightness);
766 }
767
768 // Apply dimming by at least some minimum amount when user activity
769 // timeout is about to expire.
770 if (mPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
Jeff Brown5c8ea082014-07-24 19:30:31 -0700771 if (brightness > mScreenBrightnessRangeMinimum) {
772 brightness = Math.max(Math.min(brightness - SCREEN_DIM_MINIMUM_REDUCTION,
773 mScreenBrightnessDimConfig), mScreenBrightnessRangeMinimum);
774 }
Jeff Brown970d4132014-07-19 11:33:47 -0700775 if (!mAppliedDimming) {
776 slowChange = false;
777 }
778 mAppliedDimming = true;
mochangmingf0cb46c2015-12-29 13:55:24 +0800779 } else if (mAppliedDimming) {
780 slowChange = false;
781 mAppliedDimming = false;
Jeff Brown970d4132014-07-19 11:33:47 -0700782 }
783
jackqdyulei92681e82017-02-28 11:26:28 -0800784 // If low power mode is enabled, scale brightness by screenLowPowerBrightnessFactor
Jeff Brown970d4132014-07-19 11:33:47 -0700785 // as long as it is above the minimum threshold.
786 if (mPowerRequest.lowPowerMode) {
787 if (brightness > mScreenBrightnessRangeMinimum) {
jackqdyulei92681e82017-02-28 11:26:28 -0800788 final float brightnessFactor =
789 Math.min(mPowerRequest.screenLowPowerBrightnessFactor, 1);
790 final int lowPowerBrightness = (int) (brightness * brightnessFactor);
791 brightness = Math.max(lowPowerBrightness, mScreenBrightnessRangeMinimum);
Jeff Brown970d4132014-07-19 11:33:47 -0700792 }
793 if (!mAppliedLowPower) {
794 slowChange = false;
795 }
796 mAppliedLowPower = true;
mochangmingf0cb46c2015-12-29 13:55:24 +0800797 } else if (mAppliedLowPower) {
798 slowChange = false;
799 mAppliedLowPower = false;
Jeff Brown970d4132014-07-19 11:33:47 -0700800 }
801
Jeff Brown0a434772014-09-30 14:42:27 -0700802 // Animate the screen brightness when the screen is on or dozing.
Santos Cordon3107d292016-09-20 15:50:35 -0700803 // Skip the animation when the screen is off or suspended or transition to/from VR.
Prashant Malani33538242014-11-13 14:04:00 -0800804 if (!mPendingScreenOff) {
Julius D'souzad5105dd2017-06-02 11:03:53 -0700805 if (mSkipScreenOnBrightnessRamp) {
Julius D'souzad5105dd2017-06-02 11:03:53 -0700806 if (state == Display.STATE_ON) {
807 if (mSkipRampState == RAMP_STATE_SKIP_NONE && mDozing) {
808 mInitialAutoBrightness = brightness;
809 mSkipRampState = RAMP_STATE_SKIP_INITIAL;
810 } else if (mSkipRampState == RAMP_STATE_SKIP_INITIAL
811 && mUseSoftwareAutoBrightnessConfig
812 && brightness != mInitialAutoBrightness) {
813 mSkipRampState = RAMP_STATE_SKIP_AUTOBRIGHT;
814 } else if (mSkipRampState == RAMP_STATE_SKIP_AUTOBRIGHT) {
815 mSkipRampState = RAMP_STATE_SKIP_NONE;
816 }
817 } else {
818 mSkipRampState = RAMP_STATE_SKIP_NONE;
819 }
820 }
821
Michael Wrightb0a1d3d2017-09-22 15:05:02 +0100822 final boolean wasOrWillBeInVr =
823 (state == Display.STATE_VR || oldState == Display.STATE_VR);
824 final boolean initialRampSkip =
825 state == Display.STATE_ON && mSkipRampState != RAMP_STATE_SKIP_NONE;
826 // While dozing, sometimes the brightness is split into buckets. Rather than animating
827 // through the buckets, which is unlikely to be smooth in the first place, just jump
828 // right to the suggested brightness.
829 final boolean hasBrightnessBuckets =
830 Display.isDozeState(state) && mBrightnessBucketsInDozeConfig;
831 // If the color fade is totally covering the screen then we can change the backlight
832 // level without it being a noticeable jump since any actual content isn't yet visible.
833 final boolean isDisplayContentVisible =
834 mColorFadeEnabled && mPowerState.getColorFadeLevel() == 1.0f;
835 if (initialRampSkip || hasBrightnessBuckets
836 || wasOrWillBeInVr || !isDisplayContentVisible) {
837 animateScreenBrightness(brightness, 0);
838 } else {
Prashant Malani33538242014-11-13 14:04:00 -0800839 animateScreenBrightness(brightness,
Julius D'souzafeadad12016-08-05 14:34:38 -0700840 slowChange ? mBrightnessRampRateSlow : mBrightnessRampRateFast);
Prashant Malani33538242014-11-13 14:04:00 -0800841 }
Michael Wright144aac92017-12-21 18:37:41 +0000842
843 final float brightnessInNits = getNits(brightness);
844 if (!mPowerRequest.brightnessIsTemporary && brightnessInNits >= 0.0f) {
845 // We only want to track changes made by the user and on devices that can actually
846 // map the display backlight values into a physical brightness unit.
847 mBrightnessTracker.notifyBrightnessChanged(brightnessInNits, userInitiatedChange);
848 }
Jeff Brown0a434772014-09-30 14:42:27 -0700849 }
850
851 // Determine whether the display is ready for use in the newly requested state.
852 // Note that we do not wait for the brightness ramp animation to complete before
853 // reporting the display is ready because we only need to ensure the screen is in the
854 // right power state even as it continues to converge on the desired brightness.
Narayan Kamath38819982017-07-06 18:15:30 +0100855 final boolean ready = mPendingScreenOnUnblocker == null &&
856 (!mColorFadeEnabled ||
857 (!mColorFadeOnAnimator.isStarted() && !mColorFadeOffAnimator.isStarted()))
Jeff Brown0a434772014-09-30 14:42:27 -0700858 && mPowerState.waitUntilClean(mCleanListener);
859 final boolean finished = ready
860 && !mScreenBrightnessRampAnimator.isAnimating();
861
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700862 // Notify policy about screen turned on.
863 if (ready && state != Display.STATE_OFF
864 && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_ON) {
Michael Wrightc3e6af82017-07-25 22:31:03 +0100865 setReportedScreenState(REPORTED_TO_POLICY_SCREEN_ON);
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700866 mWindowManagerPolicy.screenTurnedOn();
867 }
868
Jeff Brown0a434772014-09-30 14:42:27 -0700869 // Grab a wake lock if we have unfinished business.
870 if (!finished && !mUnfinishedBusiness) {
871 if (DEBUG) {
872 Slog.d(TAG, "Unfinished business...");
873 }
874 mCallbacks.acquireSuspendBlocker();
875 mUnfinishedBusiness = true;
876 }
877
878 // Notify the power manager when ready.
879 if (ready && mustNotify) {
880 // Send state change.
Jeff Brown96307042012-07-27 15:51:34 -0700881 synchronized (mLock) {
882 if (!mPendingRequestChangedLocked) {
883 mDisplayReadyLocked = true;
Jeff Brownc38c9be2012-10-04 13:16:19 -0700884
885 if (DEBUG) {
886 Slog.d(TAG, "Display ready!");
887 }
Jeff Brown96307042012-07-27 15:51:34 -0700888 }
889 }
Jeff Brownec083212013-09-11 20:45:25 -0700890 sendOnStateChangedWithWakelock();
Jeff Brown96307042012-07-27 15:51:34 -0700891 }
Jeff Brown0a434772014-09-30 14:42:27 -0700892
893 // Release the wake lock when we have no unfinished business.
894 if (finished && mUnfinishedBusiness) {
895 if (DEBUG) {
896 Slog.d(TAG, "Finished business...");
897 }
898 mUnfinishedBusiness = false;
899 mCallbacks.releaseSuspendBlocker();
900 }
Julius D'souzad5105dd2017-06-02 11:03:53 -0700901
902 // Record if dozing for future comparison.
903 mDozing = state != Display.STATE_ON;
Jeff Brown96307042012-07-27 15:51:34 -0700904 }
905
Michael Wright639c8be2014-01-17 18:29:12 -0800906 @Override
907 public void updateBrightness() {
908 sendUpdatePowerState();
909 }
910
Michael Wrighteef0e132017-11-21 17:57:52 +0000911 public void setBrightnessConfiguration(BrightnessConfiguration c) {
912 Message msg = mHandler.obtainMessage(MSG_CONFIGURE_BRIGHTNESS, c);
913 msg.sendToTarget();
914 }
915
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700916 private void blockScreenOn() {
Jeff Brown3ee549c2014-09-22 20:14:39 -0700917 if (mPendingScreenOnUnblocker == null) {
Jeff Brown3edf5272014-08-14 19:25:14 -0700918 Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0);
Jeff Brown3ee549c2014-09-22 20:14:39 -0700919 mPendingScreenOnUnblocker = new ScreenOnUnblocker();
Jeff Brown037c33e2014-04-09 00:31:55 -0700920 mScreenOnBlockStartRealTime = SystemClock.elapsedRealtime();
Jeff Brown3edf5272014-08-14 19:25:14 -0700921 Slog.i(TAG, "Blocking screen on until initial contents have been drawn.");
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700922 }
923 }
924
925 private void unblockScreenOn() {
Jeff Brown3ee549c2014-09-22 20:14:39 -0700926 if (mPendingScreenOnUnblocker != null) {
927 mPendingScreenOnUnblocker = null;
Jeff Brown2d8a3902014-03-11 23:02:35 -0700928 long delay = SystemClock.elapsedRealtime() - mScreenOnBlockStartRealTime;
Jeff Brown3edf5272014-08-14 19:25:14 -0700929 Slog.i(TAG, "Unblocked screen on after " + delay + " ms");
930 Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0);
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700931 }
932 }
933
Jorim Jaggi51304d72017-05-17 17:25:32 +0200934 private void blockScreenOff() {
935 if (mPendingScreenOffUnblocker == null) {
936 Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, SCREEN_OFF_BLOCKED_TRACE_NAME, 0);
937 mPendingScreenOffUnblocker = new ScreenOffUnblocker();
938 mScreenOffBlockStartRealTime = SystemClock.elapsedRealtime();
939 Slog.i(TAG, "Blocking screen off");
940 }
941 }
942
943 private void unblockScreenOff() {
944 if (mPendingScreenOffUnblocker != null) {
945 mPendingScreenOffUnblocker = null;
946 long delay = SystemClock.elapsedRealtime() - mScreenOffBlockStartRealTime;
947 Slog.i(TAG, "Unblocked screen off after " + delay + " ms");
948 Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, SCREEN_OFF_BLOCKED_TRACE_NAME, 0);
949 }
950 }
951
Jeff Brown3ee549c2014-09-22 20:14:39 -0700952 private boolean setScreenState(int state) {
Michael Wrightc3e6af82017-07-25 22:31:03 +0100953 return setScreenState(state, false /*reportOnly*/);
Michael Wright05e76fe2017-07-20 18:18:33 +0100954 }
955
Michael Wrightc3e6af82017-07-25 22:31:03 +0100956 private boolean setScreenState(int state, boolean reportOnly) {
Jorim Jaggi51304d72017-05-17 17:25:32 +0200957 final boolean isOff = (state == Display.STATE_OFF);
Jeff Brown037c33e2014-04-09 00:31:55 -0700958 if (mPowerState.getScreenState() != state) {
Jorim Jaggi51304d72017-05-17 17:25:32 +0200959
960 // If we are trying to turn screen off, give policy a chance to do something before we
961 // actually turn the screen off.
962 if (isOff && !mScreenOffBecauseOfProximity) {
963 if (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_ON) {
Michael Wrightc3e6af82017-07-25 22:31:03 +0100964 setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_OFF);
Jorim Jaggi51304d72017-05-17 17:25:32 +0200965 blockScreenOff();
966 mWindowManagerPolicy.screenTurningOff(mPendingScreenOffUnblocker);
Michael Wrightc3e6af82017-07-25 22:31:03 +0100967 unblockScreenOff();
Jorim Jaggi51304d72017-05-17 17:25:32 +0200968 } else if (mPendingScreenOffUnblocker != null) {
Jorim Jaggi51304d72017-05-17 17:25:32 +0200969 // Abort doing the state change until screen off is unblocked.
970 return false;
971 }
972 }
973
Michael Wrightc3e6af82017-07-25 22:31:03 +0100974 if (!reportOnly) {
Michael Wrightb0a1d3d2017-09-22 15:05:02 +0100975 Trace.traceCounter(Trace.TRACE_TAG_POWER, "ScreenState", state);
Michael Wrightc3e6af82017-07-25 22:31:03 +0100976 mPowerState.setScreenState(state);
977 // Tell battery stats about the transition.
978 try {
979 mBatteryStats.noteScreenState(state);
980 } catch (RemoteException ex) {
981 // same process
982 }
Jeff Brown96307042012-07-27 15:51:34 -0700983 }
984 }
Jeff Browne1633ad2015-06-22 19:24:24 -0700985
986 // Tell the window manager policy when the screen is turned off or on unless it's due
987 // to the proximity sensor. We temporarily block turning the screen on until the
988 // window manager is ready by leaving a black surface covering the screen.
989 // This surface is essentially the final state of the color fade animation and
990 // it is only removed once the window manager tells us that the activity has
991 // finished drawing underneath.
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700992 if (isOff && mReportedScreenStateToPolicy != REPORTED_TO_POLICY_SCREEN_OFF
993 && !mScreenOffBecauseOfProximity) {
Michael Wrightc3e6af82017-07-25 22:31:03 +0100994 setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
Jeff Browne1633ad2015-06-22 19:24:24 -0700995 unblockScreenOn();
996 mWindowManagerPolicy.screenTurnedOff();
Jorim Jaggi51304d72017-05-17 17:25:32 +0200997 } else if (!isOff
998 && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_OFF) {
999
1000 // We told policy already that screen was turning off, but now we changed our minds.
1001 // Complete the full state transition on -> turningOff -> off.
1002 unblockScreenOff();
1003 mWindowManagerPolicy.screenTurnedOff();
Michael Wrightc3e6af82017-07-25 22:31:03 +01001004 setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
Jorim Jaggi51304d72017-05-17 17:25:32 +02001005 }
1006 if (!isOff && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF) {
Michael Wrightc3e6af82017-07-25 22:31:03 +01001007 setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_ON);
Jeff Browne1633ad2015-06-22 19:24:24 -07001008 if (mPowerState.getColorFadeLevel() == 0.0f) {
1009 blockScreenOn();
1010 } else {
1011 unblockScreenOn();
1012 }
1013 mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker);
1014 }
1015
1016 // Return true if the screen isn't blocked.
Jeff Brown3ee549c2014-09-22 20:14:39 -07001017 return mPendingScreenOnUnblocker == null;
Jeff Brown96307042012-07-27 15:51:34 -07001018 }
1019
Michael Wrightc3e6af82017-07-25 22:31:03 +01001020 private void setReportedScreenState(int state) {
1021 Trace.traceCounter(Trace.TRACE_TAG_POWER, "ReportedScreenStateToPolicy", state);
1022 mReportedScreenStateToPolicy = state;
1023 }
1024
Jeff Brown330560f2012-08-21 22:10:57 -07001025 private int clampScreenBrightness(int value) {
Michael Wright639c8be2014-01-17 18:29:12 -08001026 return MathUtils.constrain(
1027 value, mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum);
Jeff Brown330560f2012-08-21 22:10:57 -07001028 }
1029
Jeff Brown96307042012-07-27 15:51:34 -07001030 private void animateScreenBrightness(int target, int rate) {
Jeff Brown0a434772014-09-30 14:42:27 -07001031 if (DEBUG) {
1032 Slog.d(TAG, "Animating brightness: target=" + target +", rate=" + rate);
1033 }
Jeff Brown96307042012-07-27 15:51:34 -07001034 if (mScreenBrightnessRampAnimator.animateTo(target, rate)) {
Michael Wrighta9f37ab2017-08-15 17:14:20 +01001035 Trace.traceCounter(Trace.TRACE_TAG_POWER, "TargetScreenBrightness", target);
Jeff Brown131206b2014-04-08 17:27:14 -07001036 try {
1037 mBatteryStats.noteScreenBrightness(target);
1038 } catch (RemoteException ex) {
1039 // same process
1040 }
Jeff Brown96307042012-07-27 15:51:34 -07001041 }
1042 }
1043
Jeff Brown606e4e82014-09-18 15:22:26 -07001044 private void animateScreenStateChange(int target, boolean performScreenOffTransition) {
1045 // If there is already an animation in progress, don't interfere with it.
Narayan Kamath38819982017-07-06 18:15:30 +01001046 if (mColorFadeEnabled &&
1047 (mColorFadeOnAnimator.isStarted() || mColorFadeOffAnimator.isStarted())) {
Chong Zhangb131c702016-02-16 16:31:48 -08001048 if (target != Display.STATE_ON) {
1049 return;
1050 }
1051 // If display state changed to on, proceed and stop the color fade and turn screen on.
1052 mPendingScreenOff = false;
Jeff Brown606e4e82014-09-18 15:22:26 -07001053 }
1054
Michael Wrightc3e6af82017-07-25 22:31:03 +01001055 if (mDisplayBlanksAfterDozeConfig
1056 && Display.isDozeState(mPowerState.getScreenState())
Michael Wright05e76fe2017-07-20 18:18:33 +01001057 && !Display.isDozeState(target)) {
Michael Wright05e76fe2017-07-20 18:18:33 +01001058 // Skip the screen off animation and add a black surface to hide the
Michael Wrightc3e6af82017-07-25 22:31:03 +01001059 // contents of the screen.
1060 mPowerState.prepareColorFade(mContext,
1061 mColorFadeFadesConfig ? ColorFade.MODE_FADE : ColorFade.MODE_WARM_UP);
Lucas Dupina84952b2017-08-15 15:56:50 -07001062 if (mColorFadeOffAnimator != null) {
1063 mColorFadeOffAnimator.end();
1064 }
Michael Wrightc3e6af82017-07-25 22:31:03 +01001065 // Some display hardware will blank itself on the transition between doze and non-doze
1066 // but still on display states. In this case we want to report to policy that the
1067 // display has turned off so it can prepare the appropriate power on animation, but we
1068 // don't want to actually transition to the fully off state since that takes
1069 // significantly longer to transition from.
1070 setScreenState(Display.STATE_OFF, target != Display.STATE_OFF /*reportOnly*/);
Michael Wright05e76fe2017-07-20 18:18:33 +01001071 }
1072
Jeff Brown3ee549c2014-09-22 20:14:39 -07001073 // If we were in the process of turning off the screen but didn't quite
1074 // finish. Then finish up now to prevent a jarring transition back
1075 // to screen on if we skipped blocking screen on as usual.
1076 if (mPendingScreenOff && target != Display.STATE_OFF) {
1077 setScreenState(Display.STATE_OFF);
1078 mPendingScreenOff = false;
Michael Lentined73854d2015-09-25 10:55:26 -07001079 mPowerState.dismissColorFadeResources();
Jeff Brown606e4e82014-09-18 15:22:26 -07001080 }
1081
1082 if (target == Display.STATE_ON) {
1083 // Want screen on. The contents of the screen may not yet
Jeff Brown3ee549c2014-09-22 20:14:39 -07001084 // be visible if the color fade has not been dismissed because
Jeff Brown606e4e82014-09-18 15:22:26 -07001085 // its last frame of animation is solid black.
Jeff Brown3ee549c2014-09-22 20:14:39 -07001086 if (!setScreenState(Display.STATE_ON)) {
1087 return; // screen on blocked
1088 }
Narayan Kamath38819982017-07-06 18:15:30 +01001089 if (USE_COLOR_FADE_ON_ANIMATION && mColorFadeEnabled && mPowerRequest.isBrightOrDim()) {
Jeff Brown606e4e82014-09-18 15:22:26 -07001090 // Perform screen on animation.
1091 if (mPowerState.getColorFadeLevel() == 1.0f) {
1092 mPowerState.dismissColorFade();
1093 } else if (mPowerState.prepareColorFade(mContext,
1094 mColorFadeFadesConfig ?
1095 ColorFade.MODE_FADE :
1096 ColorFade.MODE_WARM_UP)) {
1097 mColorFadeOnAnimator.start();
1098 } else {
1099 mColorFadeOnAnimator.end();
1100 }
1101 } else {
1102 // Skip screen on animation.
1103 mPowerState.setColorFadeLevel(1.0f);
1104 mPowerState.dismissColorFade();
1105 }
Santos Cordon3107d292016-09-20 15:50:35 -07001106 } else if (target == Display.STATE_VR) {
1107 // Wait for brightness animation to complete beforehand when entering VR
1108 // from screen on to prevent a perceptible jump because brightness may operate
1109 // differently when the display is configured for dozing.
1110 if (mScreenBrightnessRampAnimator.isAnimating()
1111 && mPowerState.getScreenState() == Display.STATE_ON) {
1112 return;
1113 }
1114
1115 // Set screen state.
1116 if (!setScreenState(Display.STATE_VR)) {
1117 return; // screen on blocked
1118 }
1119
1120 // Dismiss the black surface without fanfare.
1121 mPowerState.setColorFadeLevel(1.0f);
1122 mPowerState.dismissColorFade();
Jeff Brown606e4e82014-09-18 15:22:26 -07001123 } else if (target == Display.STATE_DOZE) {
1124 // Want screen dozing.
1125 // Wait for brightness animation to complete beforehand when entering doze
1126 // from screen on to prevent a perceptible jump because brightness may operate
1127 // differently when the display is configured for dozing.
1128 if (mScreenBrightnessRampAnimator.isAnimating()
1129 && mPowerState.getScreenState() == Display.STATE_ON) {
1130 return;
1131 }
1132
Jeff Brown3ee549c2014-09-22 20:14:39 -07001133 // Set screen state.
1134 if (!setScreenState(Display.STATE_DOZE)) {
1135 return; // screen on blocked
1136 }
1137
1138 // Dismiss the black surface without fanfare.
Jeff Brown606e4e82014-09-18 15:22:26 -07001139 mPowerState.setColorFadeLevel(1.0f);
1140 mPowerState.dismissColorFade();
1141 } else if (target == Display.STATE_DOZE_SUSPEND) {
1142 // Want screen dozing and suspended.
1143 // Wait for brightness animation to complete beforehand unless already
1144 // suspended because we may not be able to change it after suspension.
1145 if (mScreenBrightnessRampAnimator.isAnimating()
1146 && mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) {
1147 return;
1148 }
1149
Jeff Brown3ee549c2014-09-22 20:14:39 -07001150 // If not already suspending, temporarily set the state to doze until the
1151 // screen on is unblocked, then suspend.
1152 if (mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) {
1153 if (!setScreenState(Display.STATE_DOZE)) {
1154 return; // screen on blocked
1155 }
1156 setScreenState(Display.STATE_DOZE_SUSPEND); // already on so can't block
1157 }
1158
1159 // Dismiss the black surface without fanfare.
Jeff Brown606e4e82014-09-18 15:22:26 -07001160 mPowerState.setColorFadeLevel(1.0f);
1161 mPowerState.dismissColorFade();
Chris Phoenix10a4a642017-09-25 13:21:00 -07001162 } else if (target == Display.STATE_ON_SUSPEND) {
1163 // Want screen full-power and suspended.
1164 // Wait for brightness animation to complete beforehand unless already
1165 // suspended because we may not be able to change it after suspension.
1166 if (mScreenBrightnessRampAnimator.isAnimating()
1167 && mPowerState.getScreenState() != Display.STATE_ON_SUSPEND) {
1168 return;
1169 }
1170
1171 // If not already suspending, temporarily set the state to on until the
1172 // screen on is unblocked, then suspend.
1173 if (mPowerState.getScreenState() != Display.STATE_ON_SUSPEND) {
1174 if (!setScreenState(Display.STATE_ON)) {
1175 return;
1176 }
1177 setScreenState(Display.STATE_ON_SUSPEND);
1178 }
1179
1180 // Dismiss the black surface without fanfare.
1181 mPowerState.setColorFadeLevel(1.0f);
1182 mPowerState.dismissColorFade();
Jeff Brown606e4e82014-09-18 15:22:26 -07001183 } else {
1184 // Want screen off.
Jeff Brown3ee549c2014-09-22 20:14:39 -07001185 mPendingScreenOff = true;
Narayan Kamath38819982017-07-06 18:15:30 +01001186 if (!mColorFadeEnabled) {
1187 mPowerState.setColorFadeLevel(0.0f);
1188 }
1189
Jeff Brown606e4e82014-09-18 15:22:26 -07001190 if (mPowerState.getColorFadeLevel() == 0.0f) {
1191 // Turn the screen off.
1192 // A black surface is already hiding the contents of the screen.
1193 setScreenState(Display.STATE_OFF);
Jeff Brown3ee549c2014-09-22 20:14:39 -07001194 mPendingScreenOff = false;
Michael Lentined73854d2015-09-25 10:55:26 -07001195 mPowerState.dismissColorFadeResources();
Jeff Brown606e4e82014-09-18 15:22:26 -07001196 } else if (performScreenOffTransition
1197 && mPowerState.prepareColorFade(mContext,
1198 mColorFadeFadesConfig ?
1199 ColorFade.MODE_FADE : ColorFade.MODE_COOL_DOWN)
1200 && mPowerState.getScreenState() != Display.STATE_OFF) {
1201 // Perform the screen off animation.
1202 mColorFadeOffAnimator.start();
1203 } else {
1204 // Skip the screen off animation and add a black surface to hide the
1205 // contents of the screen.
1206 mColorFadeOffAnimator.end();
1207 }
1208 }
1209 }
1210
Jeff Brown96307042012-07-27 15:51:34 -07001211 private final Runnable mCleanListener = new Runnable() {
1212 @Override
1213 public void run() {
1214 sendUpdatePowerState();
1215 }
1216 };
1217
1218 private void setProximitySensorEnabled(boolean enable) {
1219 if (enable) {
1220 if (!mProximitySensorEnabled) {
Jeff Brownec083212013-09-11 20:45:25 -07001221 // Register the listener.
1222 // Proximity sensor state already cleared initially.
Jeff Brown96307042012-07-27 15:51:34 -07001223 mProximitySensorEnabled = true;
Jeff Brown96307042012-07-27 15:51:34 -07001224 mSensorManager.registerListener(mProximitySensorListener, mProximitySensor,
1225 SensorManager.SENSOR_DELAY_NORMAL, mHandler);
1226 }
1227 } else {
1228 if (mProximitySensorEnabled) {
Jeff Brownec083212013-09-11 20:45:25 -07001229 // Unregister the listener.
1230 // Clear the proximity sensor state for next time.
Jeff Brown96307042012-07-27 15:51:34 -07001231 mProximitySensorEnabled = false;
1232 mProximity = PROXIMITY_UNKNOWN;
Jeff Brownec083212013-09-11 20:45:25 -07001233 mPendingProximity = PROXIMITY_UNKNOWN;
Jeff Brown96307042012-07-27 15:51:34 -07001234 mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
1235 mSensorManager.unregisterListener(mProximitySensorListener);
Jeff Brownec083212013-09-11 20:45:25 -07001236 clearPendingProximityDebounceTime(); // release wake lock (must be last)
Jeff Brown96307042012-07-27 15:51:34 -07001237 }
1238 }
1239 }
1240
1241 private void handleProximitySensorEvent(long time, boolean positive) {
Jeff Brownec083212013-09-11 20:45:25 -07001242 if (mProximitySensorEnabled) {
1243 if (mPendingProximity == PROXIMITY_NEGATIVE && !positive) {
1244 return; // no change
1245 }
1246 if (mPendingProximity == PROXIMITY_POSITIVE && positive) {
1247 return; // no change
1248 }
Jeff Brown96307042012-07-27 15:51:34 -07001249
Jeff Brownec083212013-09-11 20:45:25 -07001250 // Only accept a proximity sensor reading if it remains
1251 // stable for the entire debounce delay. We hold a wake lock while
1252 // debouncing the sensor.
1253 mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
1254 if (positive) {
1255 mPendingProximity = PROXIMITY_POSITIVE;
1256 setPendingProximityDebounceTime(
1257 time + PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY); // acquire wake lock
1258 } else {
1259 mPendingProximity = PROXIMITY_NEGATIVE;
1260 setPendingProximityDebounceTime(
1261 time + PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY); // acquire wake lock
1262 }
1263
1264 // Debounce the new sensor reading.
1265 debounceProximitySensor();
Jeff Brown93cbbb22012-10-04 13:18:36 -07001266 }
Jeff Brown96307042012-07-27 15:51:34 -07001267 }
1268
1269 private void debounceProximitySensor() {
Jeff Brownec083212013-09-11 20:45:25 -07001270 if (mProximitySensorEnabled
1271 && mPendingProximity != PROXIMITY_UNKNOWN
1272 && mPendingProximityDebounceTime >= 0) {
Jeff Brown96307042012-07-27 15:51:34 -07001273 final long now = SystemClock.uptimeMillis();
1274 if (mPendingProximityDebounceTime <= now) {
Jeff Brownec083212013-09-11 20:45:25 -07001275 // Sensor reading accepted. Apply the change then release the wake lock.
Jeff Brown96307042012-07-27 15:51:34 -07001276 mProximity = mPendingProximity;
Jeff Brownec083212013-09-11 20:45:25 -07001277 updatePowerState();
1278 clearPendingProximityDebounceTime(); // release wake lock (must be last)
Jeff Brown96307042012-07-27 15:51:34 -07001279 } else {
Jeff Brownec083212013-09-11 20:45:25 -07001280 // Need to wait a little longer.
1281 // Debounce again later. We continue holding a wake lock while waiting.
Jeff Brown96307042012-07-27 15:51:34 -07001282 Message msg = mHandler.obtainMessage(MSG_PROXIMITY_SENSOR_DEBOUNCED);
Jeff Brown96307042012-07-27 15:51:34 -07001283 mHandler.sendMessageAtTime(msg, mPendingProximityDebounceTime);
1284 }
1285 }
1286 }
1287
Jeff Brownec083212013-09-11 20:45:25 -07001288 private void clearPendingProximityDebounceTime() {
1289 if (mPendingProximityDebounceTime >= 0) {
1290 mPendingProximityDebounceTime = -1;
Jeff Brown131206b2014-04-08 17:27:14 -07001291 mCallbacks.releaseSuspendBlocker(); // release wake lock
Jeff Brownec083212013-09-11 20:45:25 -07001292 }
1293 }
1294
1295 private void setPendingProximityDebounceTime(long debounceTime) {
1296 if (mPendingProximityDebounceTime < 0) {
Jeff Brown131206b2014-04-08 17:27:14 -07001297 mCallbacks.acquireSuspendBlocker(); // acquire wake lock
Jeff Brownec083212013-09-11 20:45:25 -07001298 }
1299 mPendingProximityDebounceTime = debounceTime;
1300 }
1301
Jeff Brownec083212013-09-11 20:45:25 -07001302 private void sendOnStateChangedWithWakelock() {
Jeff Brown131206b2014-04-08 17:27:14 -07001303 mCallbacks.acquireSuspendBlocker();
1304 mHandler.post(mOnStateChangedRunnable);
Jeff Brown96307042012-07-27 15:51:34 -07001305 }
1306
Michael Wright144aac92017-12-21 18:37:41 +00001307 private float getNits(int backlight) {
1308 if (mBrightnessMapper != null) {
1309 return mBrightnessMapper.getNits(backlight);
1310 } else {
1311 return -1.0f;
1312 }
1313 }
1314
Jeff Brown96307042012-07-27 15:51:34 -07001315 private final Runnable mOnStateChangedRunnable = new Runnable() {
1316 @Override
1317 public void run() {
1318 mCallbacks.onStateChanged();
Jeff Brown131206b2014-04-08 17:27:14 -07001319 mCallbacks.releaseSuspendBlocker();
Jeff Brown96307042012-07-27 15:51:34 -07001320 }
1321 };
1322
Jeff Brownec083212013-09-11 20:45:25 -07001323 private void sendOnProximityPositiveWithWakelock() {
Jeff Brown131206b2014-04-08 17:27:14 -07001324 mCallbacks.acquireSuspendBlocker();
1325 mHandler.post(mOnProximityPositiveRunnable);
Jeff Brown93cbbb22012-10-04 13:18:36 -07001326 }
1327
1328 private final Runnable mOnProximityPositiveRunnable = new Runnable() {
1329 @Override
1330 public void run() {
1331 mCallbacks.onProximityPositive();
Jeff Brown131206b2014-04-08 17:27:14 -07001332 mCallbacks.releaseSuspendBlocker();
Jeff Brown93cbbb22012-10-04 13:18:36 -07001333 }
1334 };
1335
Jeff Brownec083212013-09-11 20:45:25 -07001336 private void sendOnProximityNegativeWithWakelock() {
Jeff Brown131206b2014-04-08 17:27:14 -07001337 mCallbacks.acquireSuspendBlocker();
1338 mHandler.post(mOnProximityNegativeRunnable);
Jeff Brown96307042012-07-27 15:51:34 -07001339 }
1340
1341 private final Runnable mOnProximityNegativeRunnable = new Runnable() {
1342 @Override
1343 public void run() {
1344 mCallbacks.onProximityNegative();
Jeff Brown131206b2014-04-08 17:27:14 -07001345 mCallbacks.releaseSuspendBlocker();
Jeff Brown96307042012-07-27 15:51:34 -07001346 }
1347 };
1348
Jeff Brownbd6e1502012-08-28 03:27:37 -07001349 public void dump(final PrintWriter pw) {
Jeff Brown96307042012-07-27 15:51:34 -07001350 synchronized (mLock) {
1351 pw.println();
Jeff Brown131206b2014-04-08 17:27:14 -07001352 pw.println("Display Power Controller Locked State:");
Jeff Brown96307042012-07-27 15:51:34 -07001353 pw.println(" mDisplayReadyLocked=" + mDisplayReadyLocked);
1354 pw.println(" mPendingRequestLocked=" + mPendingRequestLocked);
1355 pw.println(" mPendingRequestChangedLocked=" + mPendingRequestChangedLocked);
1356 pw.println(" mPendingWaitForNegativeProximityLocked="
1357 + mPendingWaitForNegativeProximityLocked);
1358 pw.println(" mPendingUpdatePowerStateLocked=" + mPendingUpdatePowerStateLocked);
1359 }
1360
1361 pw.println();
Jeff Brown131206b2014-04-08 17:27:14 -07001362 pw.println("Display Power Controller Configuration:");
Jeff Brown26875502014-01-30 21:47:47 -08001363 pw.println(" mScreenBrightnessDozeConfig=" + mScreenBrightnessDozeConfig);
Jeff Brown96307042012-07-27 15:51:34 -07001364 pw.println(" mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig);
Jeff Brownb76eebff2012-10-05 22:26:44 -07001365 pw.println(" mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum);
1366 pw.println(" mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum);
Jeff Brown2175e9c2014-09-12 16:11:07 -07001367 pw.println(" mUseSoftwareAutoBrightnessConfig=" + mUseSoftwareAutoBrightnessConfig);
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -07001368 pw.println(" mAllowAutoBrightnessWhileDozingConfig=" +
1369 mAllowAutoBrightnessWhileDozingConfig);
Jeff Brown2175e9c2014-09-12 16:11:07 -07001370 pw.println(" mColorFadeFadesConfig=" + mColorFadeFadesConfig);
Jeff Brown96307042012-07-27 15:51:34 -07001371
Jeff Brownbd6e1502012-08-28 03:27:37 -07001372 mHandler.runWithScissors(new Runnable() {
1373 @Override
1374 public void run() {
1375 dumpLocal(pw);
Jeff Brown96307042012-07-27 15:51:34 -07001376 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001377 }, 1000);
Jeff Brown96307042012-07-27 15:51:34 -07001378 }
1379
1380 private void dumpLocal(PrintWriter pw) {
1381 pw.println();
Jeff Brown131206b2014-04-08 17:27:14 -07001382 pw.println("Display Power Controller Thread State:");
Jeff Brown96307042012-07-27 15:51:34 -07001383 pw.println(" mPowerRequest=" + mPowerRequest);
1384 pw.println(" mWaitingForNegativeProximity=" + mWaitingForNegativeProximity);
Jeff Brown96307042012-07-27 15:51:34 -07001385 pw.println(" mProximitySensor=" + mProximitySensor);
1386 pw.println(" mProximitySensorEnabled=" + mProximitySensorEnabled);
1387 pw.println(" mProximityThreshold=" + mProximityThreshold);
1388 pw.println(" mProximity=" + proximityToString(mProximity));
1389 pw.println(" mPendingProximity=" + proximityToString(mPendingProximity));
1390 pw.println(" mPendingProximityDebounceTime="
1391 + TimeUtils.formatUptime(mPendingProximityDebounceTime));
1392 pw.println(" mScreenOffBecauseOfProximity=" + mScreenOffBecauseOfProximity);
Michael Wright144aac92017-12-21 18:37:41 +00001393 pw.println(" mLastBrightness=" + mLastBrightness);
1394 pw.println(" mLastAutoBrightnessAdjustment=" + mLastAutoBrightnessAdjustment);
Jeff Brown970d4132014-07-19 11:33:47 -07001395 pw.println(" mAppliedAutoBrightness=" + mAppliedAutoBrightness);
1396 pw.println(" mAppliedDimming=" + mAppliedDimming);
1397 pw.println(" mAppliedLowPower=" + mAppliedLowPower);
Jeff Brown3ee549c2014-09-22 20:14:39 -07001398 pw.println(" mPendingScreenOnUnblocker=" + mPendingScreenOnUnblocker);
1399 pw.println(" mPendingScreenOff=" + mPendingScreenOff);
Michael Wrightc3e6af82017-07-25 22:31:03 +01001400 pw.println(" mReportedToPolicy=" +
1401 reportedToPolicyToString(mReportedScreenStateToPolicy));
Jeff Brown96307042012-07-27 15:51:34 -07001402
Jeff Brown42558692014-05-20 22:02:46 -07001403 pw.println(" mScreenBrightnessRampAnimator.isAnimating()=" +
1404 mScreenBrightnessRampAnimator.isAnimating());
1405
Michael Lentine0839adb2014-07-29 18:47:56 -07001406 if (mColorFadeOnAnimator != null) {
1407 pw.println(" mColorFadeOnAnimator.isStarted()=" +
1408 mColorFadeOnAnimator.isStarted());
Jeff Brown96307042012-07-27 15:51:34 -07001409 }
Michael Lentine0839adb2014-07-29 18:47:56 -07001410 if (mColorFadeOffAnimator != null) {
1411 pw.println(" mColorFadeOffAnimator.isStarted()=" +
1412 mColorFadeOffAnimator.isStarted());
Jeff Brown96307042012-07-27 15:51:34 -07001413 }
1414
1415 if (mPowerState != null) {
1416 mPowerState.dump(pw);
1417 }
Michael Wright639c8be2014-01-17 18:29:12 -08001418
1419 if (mAutomaticBrightnessController != null) {
1420 mAutomaticBrightnessController.dump(pw);
1421 }
1422
Michael Wright144aac92017-12-21 18:37:41 +00001423 if (mBrightnessTracker != null) {
1424 pw.println();
1425 mBrightnessTracker.dump(pw);
1426 }
Jeff Brown96307042012-07-27 15:51:34 -07001427 }
1428
1429 private static String proximityToString(int state) {
1430 switch (state) {
1431 case PROXIMITY_UNKNOWN:
1432 return "Unknown";
1433 case PROXIMITY_NEGATIVE:
1434 return "Negative";
1435 case PROXIMITY_POSITIVE:
1436 return "Positive";
1437 default:
1438 return Integer.toString(state);
1439 }
1440 }
1441
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001442 private static String reportedToPolicyToString(int state) {
1443 switch (state) {
1444 case REPORTED_TO_POLICY_SCREEN_OFF:
1445 return "REPORTED_TO_POLICY_SCREEN_OFF";
1446 case REPORTED_TO_POLICY_SCREEN_TURNING_ON:
1447 return "REPORTED_TO_POLICY_SCREEN_TURNING_ON";
1448 case REPORTED_TO_POLICY_SCREEN_ON:
1449 return "REPORTED_TO_POLICY_SCREEN_ON";
1450 default:
1451 return Integer.toString(state);
1452 }
1453 }
1454
Michael Wright639c8be2014-01-17 18:29:12 -08001455 private static int clampAbsoluteBrightness(int value) {
1456 return MathUtils.constrain(value, PowerManager.BRIGHTNESS_OFF, PowerManager.BRIGHTNESS_ON);
Jeff Brown96307042012-07-27 15:51:34 -07001457 }
1458
Jeff Brown96307042012-07-27 15:51:34 -07001459 private final class DisplayControllerHandler extends Handler {
1460 public DisplayControllerHandler(Looper looper) {
Jeff Browna2910d02012-08-25 12:29:46 -07001461 super(looper, null, true /*async*/);
Jeff Brown96307042012-07-27 15:51:34 -07001462 }
1463
1464 @Override
1465 public void handleMessage(Message msg) {
1466 switch (msg.what) {
1467 case MSG_UPDATE_POWER_STATE:
1468 updatePowerState();
1469 break;
1470
1471 case MSG_PROXIMITY_SENSOR_DEBOUNCED:
1472 debounceProximitySensor();
1473 break;
Jeff Brown3ee549c2014-09-22 20:14:39 -07001474
1475 case MSG_SCREEN_ON_UNBLOCKED:
1476 if (mPendingScreenOnUnblocker == msg.obj) {
1477 unblockScreenOn();
1478 updatePowerState();
1479 }
1480 break;
Jorim Jaggi51304d72017-05-17 17:25:32 +02001481 case MSG_SCREEN_OFF_UNBLOCKED:
1482 if (mPendingScreenOffUnblocker == msg.obj) {
1483 unblockScreenOff();
1484 updatePowerState();
1485 }
1486 break;
Michael Wrighteef0e132017-11-21 17:57:52 +00001487 case MSG_CONFIGURE_BRIGHTNESS:
Michael Wrightd5df3612018-01-02 12:44:52 +00001488 mBrightnessConfiguration = (BrightnessConfiguration)msg.obj;
Michael Wrighteef0e132017-11-21 17:57:52 +00001489 updatePowerState();
1490 break;
Jeff Brown96307042012-07-27 15:51:34 -07001491 }
1492 }
1493 }
1494
1495 private final SensorEventListener mProximitySensorListener = new SensorEventListener() {
1496 @Override
1497 public void onSensorChanged(SensorEvent event) {
1498 if (mProximitySensorEnabled) {
1499 final long time = SystemClock.uptimeMillis();
1500 final float distance = event.values[0];
1501 boolean positive = distance >= 0.0f && distance < mProximityThreshold;
1502 handleProximitySensorEvent(time, positive);
1503 }
1504 }
1505
1506 @Override
1507 public void onAccuracyChanged(Sensor sensor, int accuracy) {
1508 // Not used.
1509 }
1510 };
Jeff Brown3ee549c2014-09-22 20:14:39 -07001511
1512 private final class ScreenOnUnblocker implements WindowManagerPolicy.ScreenOnListener {
1513 @Override
1514 public void onScreenOn() {
1515 Message msg = mHandler.obtainMessage(MSG_SCREEN_ON_UNBLOCKED, this);
Jeff Brown3ee549c2014-09-22 20:14:39 -07001516 mHandler.sendMessage(msg);
1517 }
1518 }
Jorim Jaggi51304d72017-05-17 17:25:32 +02001519
1520 private final class ScreenOffUnblocker implements WindowManagerPolicy.ScreenOffListener {
Jorim Jaggi51304d72017-05-17 17:25:32 +02001521 @Override
1522 public void onScreenOff() {
1523 Message msg = mHandler.obtainMessage(MSG_SCREEN_OFF_UNBLOCKED, this);
Jorim Jaggi51304d72017-05-17 17:25:32 +02001524 mHandler.sendMessage(msg);
1525 }
1526 }
Jeff Brown96307042012-07-27 15:51:34 -07001527}