blob: 056c3e641c4a85a907da8c98ee8e4a772bb7916f [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;
Michael Wrightd8460232018-01-16 18:04:59 +000032import android.database.ContentObserver;
Jeff Brown96307042012-07-27 15:51:34 -070033import android.hardware.Sensor;
34import android.hardware.SensorEvent;
35import android.hardware.SensorEventListener;
36import android.hardware.SensorManager;
Michael Wright144aac92017-12-21 18:37:41 +000037import android.hardware.display.BrightnessChangeEvent;
Michael Wrighteef0e132017-11-21 17:57:52 +000038import android.hardware.display.BrightnessConfiguration;
Jeff Brown131206b2014-04-08 17:27:14 -070039import android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks;
40import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
Michael Wrightd8460232018-01-16 18:04:59 +000041import android.net.Uri;
Jeff Brown96307042012-07-27 15:51:34 -070042import android.os.Handler;
43import android.os.Looper;
44import android.os.Message;
Jeff Brown330560f2012-08-21 22:10:57 -070045import android.os.PowerManager;
Jeff Brown131206b2014-04-08 17:27:14 -070046import android.os.RemoteException;
Jeff Brown96307042012-07-27 15:51:34 -070047import android.os.SystemClock;
Jeff Brown3edf5272014-08-14 19:25:14 -070048import android.os.Trace;
Michael Wrightd8460232018-01-16 18:04:59 +000049import android.os.UserHandle;
50import android.provider.Settings;
Michael Wright41a5cdf2013-11-13 16:18:32 -080051import android.util.MathUtils;
Jeff Brown96307042012-07-27 15:51:34 -070052import android.util.Slog;
Jeff Brown1a30b552012-08-16 01:31:11 -070053import android.util.Spline;
Jeff Brown96307042012-07-27 15:51:34 -070054import android.util.TimeUtils;
Jeff Brown037c33e2014-04-09 00:31:55 -070055import android.view.Display;
Jeff Brown96307042012-07-27 15:51:34 -070056
57import java.io.PrintWriter;
Jeff Brown96307042012-07-27 15:51:34 -070058
59/**
60 * Controls the power state of the display.
61 *
62 * Handles the proximity sensor, light sensor, and animations between states
63 * including the screen off animation.
64 *
65 * This component acts independently of the rest of the power manager service.
66 * In particular, it does not share any state and it only communicates
67 * via asynchronous callbacks to inform the power manager that something has
68 * changed.
69 *
70 * Everything this class does internally is serialized on its handler although
71 * it may be accessed by other threads from the outside.
72 *
73 * Note that the power manager service guarantees that it will hold a suspend
74 * blocker as long as the display is not ready. So most of the work done here
75 * does not need to worry about holding a suspend blocker unless it happens
76 * independently of the display ready signal.
Michael Lentine0839adb2014-07-29 18:47:56 -070077 *
Jeff Brown3ee549c2014-09-22 20:14:39 -070078 * For debugging, you can make the color fade and brightness animations run
Jeff Brown96307042012-07-27 15:51:34 -070079 * slower by changing the "animator duration scale" option in Development Settings.
80 */
Michael Wright639c8be2014-01-17 18:29:12 -080081final class DisplayPowerController implements AutomaticBrightnessController.Callbacks {
Jeff Brown96307042012-07-27 15:51:34 -070082 private static final String TAG = "DisplayPowerController";
Jeff Browna576b4d2015-04-23 19:58:06 -070083 private static final String SCREEN_ON_BLOCKED_TRACE_NAME = "Screen on blocked";
Jorim Jaggi51304d72017-05-17 17:25:32 +020084 private static final String SCREEN_OFF_BLOCKED_TRACE_NAME = "Screen off blocked";
Jeff Brown96307042012-07-27 15:51:34 -070085
Julius D'souza428aed02016-08-07 19:08:30 -070086 private static final boolean DEBUG = false;
Jeff Brown96307042012-07-27 15:51:34 -070087 private static final boolean DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT = false;
Jeff Brown96307042012-07-27 15:51:34 -070088
Jeff Brown3ee549c2014-09-22 20:14:39 -070089 // If true, uses the color fade on animation.
Jeff Brown13c589b2012-08-16 16:20:54 -070090 // We might want to turn this off if we cannot get a guarantee that the screen
91 // actually turns on and starts showing new content after the call to set the
Jeff Brown5356c7dc2012-08-20 20:17:36 -070092 // screen state returns. Playing the animation can also be somewhat slow.
Michael Lentine0839adb2014-07-29 18:47:56 -070093 private static final boolean USE_COLOR_FADE_ON_ANIMATION = false;
Jeff Brown13c589b2012-08-16 16:20:54 -070094
Jeff Brownb76eebff2012-10-05 22:26:44 -070095 // The minimum reduction in brightness when dimmed.
96 private static final int SCREEN_DIM_MINIMUM_REDUCTION = 10;
97
Michael Lentine0839adb2014-07-29 18:47:56 -070098 private static final int COLOR_FADE_ON_ANIMATION_DURATION_MILLIS = 250;
Michael Lentine0c9a62d2014-08-20 09:19:07 -070099 private static final int COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS = 400;
Jeff Brown96307042012-07-27 15:51:34 -0700100
101 private static final int MSG_UPDATE_POWER_STATE = 1;
102 private static final int MSG_PROXIMITY_SENSOR_DEBOUNCED = 2;
Jeff Brown3ee549c2014-09-22 20:14:39 -0700103 private static final int MSG_SCREEN_ON_UNBLOCKED = 3;
Jorim Jaggi51304d72017-05-17 17:25:32 +0200104 private static final int MSG_SCREEN_OFF_UNBLOCKED = 4;
Michael Wrighteef0e132017-11-21 17:57:52 +0000105 private static final int MSG_CONFIGURE_BRIGHTNESS = 5;
Michael Wrightd8460232018-01-16 18:04:59 +0000106 private static final int MSG_SET_TEMPORARY_BRIGHTNESS = 6;
107 private static final int MSG_SET_TEMPORARY_AUTO_BRIGHTNESS_ADJUSTMENT = 7;
Jeff Brown96307042012-07-27 15:51:34 -0700108
109 private static final int PROXIMITY_UNKNOWN = -1;
110 private static final int PROXIMITY_NEGATIVE = 0;
111 private static final int PROXIMITY_POSITIVE = 1;
112
Jeff Brown93cbbb22012-10-04 13:18:36 -0700113 // Proximity sensor debounce delay in milliseconds for positive or negative transitions.
114 private static final int PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY = 0;
Jeff Brownec083212013-09-11 20:45:25 -0700115 private static final int PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY = 250;
Jeff Brown96307042012-07-27 15:51:34 -0700116
117 // Trigger proximity if distance is less than 5 cm.
118 private static final float TYPICAL_PROXIMITY_THRESHOLD = 5.0f;
119
Julius D'souzad5105dd2017-06-02 11:03:53 -0700120 // State machine constants for tracking initial brightness ramp skipping when enabled.
121 private static final int RAMP_STATE_SKIP_NONE = 0;
122 private static final int RAMP_STATE_SKIP_INITIAL = 1;
123 private static final int RAMP_STATE_SKIP_AUTOBRIGHT = 2;
124
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700125 private static final int REPORTED_TO_POLICY_SCREEN_OFF = 0;
126 private static final int REPORTED_TO_POLICY_SCREEN_TURNING_ON = 1;
127 private static final int REPORTED_TO_POLICY_SCREEN_ON = 2;
Jorim Jaggi51304d72017-05-17 17:25:32 +0200128 private static final int REPORTED_TO_POLICY_SCREEN_TURNING_OFF = 3;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700129
Jeff Brown96307042012-07-27 15:51:34 -0700130 private final Object mLock = new Object();
131
Michael Lentine0839adb2014-07-29 18:47:56 -0700132 private final Context mContext;
133
Jeff Brown96307042012-07-27 15:51:34 -0700134 // Our handler.
135 private final DisplayControllerHandler mHandler;
136
137 // Asynchronous callbacks into the power manager service.
138 // Only invoked from the handler thread while no locks are held.
Jeff Brown131206b2014-04-08 17:27:14 -0700139 private final DisplayPowerCallbacks mCallbacks;
140
141 // Battery stats.
142 private final IBatteryStats mBatteryStats;
Jeff Brown96307042012-07-27 15:51:34 -0700143
Jeff Brown96307042012-07-27 15:51:34 -0700144 // The sensor manager.
145 private final SensorManager mSensorManager;
146
Jeff Brown3ee549c2014-09-22 20:14:39 -0700147 // The window manager policy.
148 private final WindowManagerPolicy mWindowManagerPolicy;
149
Jeff Brown037c33e2014-04-09 00:31:55 -0700150 // The display blanker.
151 private final DisplayBlanker mBlanker;
152
Michael Wrightd8460232018-01-16 18:04:59 +0000153 // Tracker for brightness changes.
154 private final BrightnessTracker mBrightnessTracker;
155
156 // Tracker for brightness settings changes.
157 private final SettingsObserver mSettingsObserver;
158
Jeff Brown96307042012-07-27 15:51:34 -0700159 // The proximity sensor, or null if not available or needed.
160 private Sensor mProximitySensor;
161
Jeff Brown26875502014-01-30 21:47:47 -0800162 // The doze screen brightness.
163 private final int mScreenBrightnessDozeConfig;
164
Jeff Brown96307042012-07-27 15:51:34 -0700165 // The dim screen brightness.
166 private final int mScreenBrightnessDimConfig;
167
Jeff Brownb76eebff2012-10-05 22:26:44 -0700168 // The minimum allowed brightness.
169 private final int mScreenBrightnessRangeMinimum;
170
171 // The maximum allowed brightness.
172 private final int mScreenBrightnessRangeMaximum;
173
Michael Wrightd8460232018-01-16 18:04:59 +0000174 // The default screen brightness.
175 private final int mScreenBrightnessDefault;
176
177 // The default screen brightness for VR.
178 private final int mScreenBrightnessForVrDefault;
179
Jeff Brown330560f2012-08-21 22:10:57 -0700180 // True if auto-brightness should be used.
Jeff Brown96307042012-07-27 15:51:34 -0700181 private boolean mUseSoftwareAutoBrightnessConfig;
Jeff Brown330560f2012-08-21 22:10:57 -0700182
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700183 // True if should use light sensor to automatically determine doze screen brightness.
184 private final boolean mAllowAutoBrightnessWhileDozingConfig;
185
Narayan Kamath38819982017-07-06 18:15:30 +0100186 // Whether or not the color fade on screen on / off is enabled.
187 private final boolean mColorFadeEnabled;
188
Jeff Brown252c2062012-10-08 16:21:01 -0700189 // True if we should fade the screen while turning it off, false if we should play
Jeff Brown3ee549c2014-09-22 20:14:39 -0700190 // a stylish color fade animation instead.
Michael Lentine0839adb2014-07-29 18:47:56 -0700191 private boolean mColorFadeFadesConfig;
Jeff Browna52772f2012-10-04 18:38:09 -0700192
Michael Wrightc3e6af82017-07-25 22:31:03 +0100193 // True if we need to fake a transition to off when coming out of a doze state.
194 // Some display hardware will blank itself when coming out of doze in order to hide
195 // artifacts. For these displays we fake a transition into OFF so that policy can appropriately
196 // blank itself and begin an appropriate power on animation.
197 private boolean mDisplayBlanksAfterDozeConfig;
Michael Wright05e76fe2017-07-20 18:18:33 +0100198
Michael Wright63a40062017-07-26 01:10:59 +0100199 // True if there are only buckets of brightness values when the display is in the doze state,
200 // rather than a full range of values. If this is true, then we'll avoid animating the screen
201 // brightness since it'd likely be multiple jarring brightness transitions instead of just one
202 // to reach the final state.
203 private boolean mBrightnessBucketsInDozeConfig;
204
Jeff Brown96307042012-07-27 15:51:34 -0700205 // The pending power request.
206 // Initially null until the first call to requestPowerState.
207 // Guarded by mLock.
208 private DisplayPowerRequest mPendingRequestLocked;
209
210 // True if a request has been made to wait for the proximity sensor to go negative.
211 // Guarded by mLock.
212 private boolean mPendingWaitForNegativeProximityLocked;
213
214 // True if the pending power request or wait for negative proximity flag
215 // has been changed since the last update occurred.
216 // Guarded by mLock.
217 private boolean mPendingRequestChangedLocked;
218
219 // Set to true when the important parts of the pending power request have been applied.
220 // The important parts are mainly the screen state. Brightness changes may occur
221 // concurrently.
222 // Guarded by mLock.
223 private boolean mDisplayReadyLocked;
224
225 // Set to true if a power state update is required.
226 // Guarded by mLock.
227 private boolean mPendingUpdatePowerStateLocked;
228
229 /* The following state must only be accessed by the handler thread. */
230
231 // The currently requested power state.
232 // The power controller will progressively update its internal state to match
233 // the requested power state. Initially null until the first update.
234 private DisplayPowerRequest mPowerRequest;
235
236 // The current power state.
237 // Must only be accessed on the handler thread.
238 private DisplayPowerState mPowerState;
239
240 // True if the device should wait for negative proximity sensor before
241 // waking up the screen. This is set to false as soon as a negative
242 // proximity sensor measurement is observed or when the device is forced to
243 // go to sleep by the user. While true, the screen remains off.
244 private boolean mWaitingForNegativeProximity;
245
246 // The actual proximity sensor threshold value.
247 private float mProximityThreshold;
248
249 // Set to true if the proximity sensor listener has been registered
250 // with the sensor manager.
251 private boolean mProximitySensorEnabled;
252
253 // The debounced proximity sensor state.
254 private int mProximity = PROXIMITY_UNKNOWN;
255
256 // The raw non-debounced proximity sensor state.
257 private int mPendingProximity = PROXIMITY_UNKNOWN;
Jeff Brownec083212013-09-11 20:45:25 -0700258 private long mPendingProximityDebounceTime = -1; // -1 if fully debounced
Jeff Brown96307042012-07-27 15:51:34 -0700259
260 // True if the screen was turned off because of the proximity sensor.
261 // When the screen turns on again, we report user activity to the power manager.
262 private boolean mScreenOffBecauseOfProximity;
263
Jeff Brown3ee549c2014-09-22 20:14:39 -0700264 // The currently active screen on unblocker. This field is non-null whenever
265 // we are waiting for a callback to release it and unblock the screen.
266 private ScreenOnUnblocker mPendingScreenOnUnblocker;
Jorim Jaggi51304d72017-05-17 17:25:32 +0200267 private ScreenOffUnblocker mPendingScreenOffUnblocker;
Jeff Brown3ee549c2014-09-22 20:14:39 -0700268
269 // True if we were in the process of turning off the screen.
270 // This allows us to recover more gracefully from situations where we abort
271 // turning off the screen.
272 private boolean mPendingScreenOff;
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700273
Jeff Brown0a434772014-09-30 14:42:27 -0700274 // True if we have unfinished business and are holding a suspend blocker.
275 private boolean mUnfinishedBusiness;
276
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700277 // The elapsed real time when the screen on was blocked.
278 private long mScreenOnBlockStartRealTime;
Jorim Jaggi51304d72017-05-17 17:25:32 +0200279 private long mScreenOffBlockStartRealTime;
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700280
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700281 // Screen state we reported to policy. Must be one of REPORTED_TO_POLICY_SCREEN_* fields.
282 private int mReportedScreenStateToPolicy;
Jeff Browne1633ad2015-06-22 19:24:24 -0700283
Julius D'souzad5105dd2017-06-02 11:03:53 -0700284 // If the last recorded screen state was dozing or not.
285 private boolean mDozing;
286
Jeff Brown970d4132014-07-19 11:33:47 -0700287 // Remembers whether certain kinds of brightness adjustments
288 // were recently applied so that we can decide how to transition.
289 private boolean mAppliedAutoBrightness;
290 private boolean mAppliedDimming;
291 private boolean mAppliedLowPower;
Jeff Brown96307042012-07-27 15:51:34 -0700292
Julius D'souzafeadad12016-08-05 14:34:38 -0700293 // Brightness animation ramp rates in brightness units per second
Prashant Malani99e6d432016-03-29 16:32:37 -0700294 private final int mBrightnessRampRateFast;
Julius D'souzafeadad12016-08-05 14:34:38 -0700295 private final int mBrightnessRampRateSlow;
Prashant Malani99e6d432016-03-29 16:32:37 -0700296
Julius D'souzad5105dd2017-06-02 11:03:53 -0700297 // Whether or not to skip the initial brightness ramps into STATE_ON.
298 private final boolean mSkipScreenOnBrightnessRamp;
299
300 // A record of state for skipping brightness ramps.
301 private int mSkipRampState = RAMP_STATE_SKIP_NONE;
302
303 // The first autobrightness value set when entering RAMP_STATE_SKIP_INITIAL.
304 private int mInitialAutoBrightness;
305
Michael Wright639c8be2014-01-17 18:29:12 -0800306 // The controller for the automatic brightness level.
307 private AutomaticBrightnessController mAutomaticBrightnessController;
308
Michael Wright144aac92017-12-21 18:37:41 +0000309 // The mapper between ambient lux, display backlight values, and display brightness.
310 @Nullable
311 private BrightnessMappingStrategy mBrightnessMapper;
312
Michael Wrighteef0e132017-11-21 17:57:52 +0000313 // The current brightness configuration.
Michael Wrightd5df3612018-01-02 12:44:52 +0000314 @Nullable
Michael Wrighteef0e132017-11-21 17:57:52 +0000315 private BrightnessConfiguration mBrightnessConfiguration;
316
Michael Wrightd5df3612018-01-02 12:44:52 +0000317 // The last brightness that was set by the user and not temporary. Set to -1 when a brightness
318 // has yet to be recorded.
Michael Wrightd8460232018-01-16 18:04:59 +0000319 private int mLastUserSetScreenBrightness;
320
321 // The screen brightenss setting has changed but not taken effect yet. If this is different
322 // from the current screen brightness setting then this is coming from something other than us
323 // and should be considered a user interaction.
324 private int mPendingScreenBrightnessSetting;
325
326 // The last observed screen brightness setting, either set by us or by the settings app on
327 // behalf of the user.
328 private int mCurrentScreenBrightnessSetting;
329
330 // The temporary screen brightness. Typically set when a user is interacting with the
331 // brightness slider but hasn't settled on a choice yet. Set to -1 when there's no temporary
332 // brightness set.
333 private int mTemporaryScreenBrightness;
334
335 // The current screen brightness while in VR mode.
336 private int mScreenBrightnessForVr;
Michael Wrightd5df3612018-01-02 12:44:52 +0000337
338 // The last auto brightness adjustment that was set by the user and not temporary. Set to
339 // Float.NaN when an auto-brightness adjustment hasn't been recorded yet.
Michael Wrightd8460232018-01-16 18:04:59 +0000340 private float mAutoBrightnessAdjustment;
341
342 // The pending auto brightness adjustment that will take effect on the next power state update.
343 private float mPendingAutoBrightnessAdjustment;
344
345 // The temporary auto brightness adjustment. Typically set when a user is interacting with the
346 // adjustment slider but hasn't settled on a choice yet. Set to Float.NaN when there's no
347 // temporary adjustment set.
348 private float mTemporaryAutoBrightnessAdjustment;
Michael Wrightd5df3612018-01-02 12:44:52 +0000349
Jeff Brown96307042012-07-27 15:51:34 -0700350 // Animators.
Michael Lentine0839adb2014-07-29 18:47:56 -0700351 private ObjectAnimator mColorFadeOnAnimator;
352 private ObjectAnimator mColorFadeOffAnimator;
Jeff Brown96307042012-07-27 15:51:34 -0700353 private RampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator;
354
355 /**
356 * Creates the display power controller.
357 */
Jeff Brown131206b2014-04-08 17:27:14 -0700358 public DisplayPowerController(Context context,
Jeff Brown037c33e2014-04-09 00:31:55 -0700359 DisplayPowerCallbacks callbacks, Handler handler,
360 SensorManager sensorManager, DisplayBlanker blanker) {
Jeff Brown131206b2014-04-08 17:27:14 -0700361 mHandler = new DisplayControllerHandler(handler.getLooper());
Michael Wright144aac92017-12-21 18:37:41 +0000362 mBrightnessTracker = new BrightnessTracker(context, null);
Michael Wrightd8460232018-01-16 18:04:59 +0000363 mSettingsObserver = new SettingsObserver(mHandler);
Jeff Brown96307042012-07-27 15:51:34 -0700364 mCallbacks = callbacks;
Jeff Brown96307042012-07-27 15:51:34 -0700365
Jeff Brown131206b2014-04-08 17:27:14 -0700366 mBatteryStats = BatteryStatsService.getService();
Jeff Brown3b971592013-01-09 18:46:37 -0800367 mSensorManager = sensorManager;
Jeff Brown3ee549c2014-09-22 20:14:39 -0700368 mWindowManagerPolicy = LocalServices.getService(WindowManagerPolicy.class);
Jeff Brown037c33e2014-04-09 00:31:55 -0700369 mBlanker = blanker;
Michael Lentine0839adb2014-07-29 18:47:56 -0700370 mContext = context;
Jeff Brown96307042012-07-27 15:51:34 -0700371
372 final Resources resources = context.getResources();
Jeff Brown1bfd0f42014-08-22 01:59:06 -0700373 final int screenBrightnessSettingMinimum = clampAbsoluteBrightness(resources.getInteger(
374 com.android.internal.R.integer.config_screenBrightnessSettingMinimum));
Jeff Brownb76eebff2012-10-05 22:26:44 -0700375
Jeff Brown26875502014-01-30 21:47:47 -0800376 mScreenBrightnessDozeConfig = clampAbsoluteBrightness(resources.getInteger(
377 com.android.internal.R.integer.config_screenBrightnessDoze));
378
Jeff Brownb76eebff2012-10-05 22:26:44 -0700379 mScreenBrightnessDimConfig = clampAbsoluteBrightness(resources.getInteger(
380 com.android.internal.R.integer.config_screenBrightnessDim));
381
Michael Wright144aac92017-12-21 18:37:41 +0000382 mScreenBrightnessRangeMinimum =
383 Math.min(screenBrightnessSettingMinimum, mScreenBrightnessDimConfig);
Michael Wright639c8be2014-01-17 18:29:12 -0800384
Michael Wrighteef0e132017-11-21 17:57:52 +0000385 mScreenBrightnessRangeMaximum = clampAbsoluteBrightness(resources.getInteger(
386 com.android.internal.R.integer.config_screenBrightnessSettingMaximum));
Michael Wrightd8460232018-01-16 18:04:59 +0000387 mScreenBrightnessDefault = clampAbsoluteBrightness(resources.getInteger(
388 com.android.internal.R.integer.config_screenBrightnessSettingDefault));
389 mScreenBrightnessForVrDefault = clampAbsoluteBrightness(resources.getInteger(
390 com.android.internal.R.integer.config_screenBrightnessForVrSettingDefault));
Jeff Brownb76eebff2012-10-05 22:26:44 -0700391
Jeff Brown96307042012-07-27 15:51:34 -0700392 mUseSoftwareAutoBrightnessConfig = resources.getBoolean(
393 com.android.internal.R.bool.config_automatic_brightness_available);
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700394
395 mAllowAutoBrightnessWhileDozingConfig = resources.getBoolean(
396 com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing);
397
Prashant Malani99e6d432016-03-29 16:32:37 -0700398 mBrightnessRampRateFast = resources.getInteger(
399 com.android.internal.R.integer.config_brightness_ramp_rate_fast);
Julius D'souzafeadad12016-08-05 14:34:38 -0700400 mBrightnessRampRateSlow = resources.getInteger(
401 com.android.internal.R.integer.config_brightness_ramp_rate_slow);
Julius D'souzad5105dd2017-06-02 11:03:53 -0700402 mSkipScreenOnBrightnessRamp = resources.getBoolean(
403 com.android.internal.R.bool.config_skipScreenOnBrightnessRamp);
Prashant Malani99e6d432016-03-29 16:32:37 -0700404
Jeff Brown96307042012-07-27 15:51:34 -0700405 if (mUseSoftwareAutoBrightnessConfig) {
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700406 final float dozeScaleFactor = resources.getFraction(
407 com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor,
408 1, 1);
Jeff Brown1a30b552012-08-16 01:31:11 -0700409
Michael Wrighteef0e132017-11-21 17:57:52 +0000410 int[] brightLevels = resources.getIntArray(
411 com.android.internal.R.array.config_dynamicHysteresisBrightLevels);
412 int[] darkLevels = resources.getIntArray(
413 com.android.internal.R.array.config_dynamicHysteresisDarkLevels);
414 int[] luxHysteresisLevels = resources.getIntArray(
415 com.android.internal.R.array.config_dynamicHysteresisLuxLevels);
416 HysteresisLevels dynamicHysteresis = new HysteresisLevels(
417 brightLevels, darkLevels, luxHysteresisLevels);
418
419 long brighteningLightDebounce = resources.getInteger(
420 com.android.internal.R.integer.config_autoBrightnessBrighteningLightDebounce);
421 long darkeningLightDebounce = resources.getInteger(
422 com.android.internal.R.integer.config_autoBrightnessDarkeningLightDebounce);
423 boolean autoBrightnessResetAmbientLuxAfterWarmUp = resources.getBoolean(
424 com.android.internal.R.bool.config_autoBrightnessResetAmbientLuxAfterWarmUp);
425 int ambientLightHorizon = resources.getInteger(
426 com.android.internal.R.integer.config_autoBrightnessAmbientLightHorizon);
427 float autoBrightnessAdjustmentMaxGamma = resources.getFraction(
428 com.android.internal.R.fraction.config_autoBrightnessAdjustmentMaxGamma,
429 1, 1);
430
431 int lightSensorWarmUpTimeConfig = resources.getInteger(
432 com.android.internal.R.integer.config_lightSensorWarmupTime);
433 int lightSensorRate = resources.getInteger(
434 com.android.internal.R.integer.config_autoBrightnessLightSensorRate);
435 int initialLightSensorRate = resources.getInteger(
436 com.android.internal.R.integer.config_autoBrightnessInitialLightSensorRate);
437 if (initialLightSensorRate == -1) {
438 initialLightSensorRate = lightSensorRate;
439 } else if (initialLightSensorRate > lightSensorRate) {
440 Slog.w(TAG, "Expected config_autoBrightnessInitialLightSensorRate ("
441 + initialLightSensorRate + ") to be less than or equal to "
442 + "config_autoBrightnessLightSensorRate (" + lightSensorRate + ").");
443 }
444
Michael Wright144aac92017-12-21 18:37:41 +0000445 mBrightnessMapper = BrightnessMappingStrategy.create(resources);
446 if (mBrightnessMapper != null) {
Jeff Brown131206b2014-04-08 17:27:14 -0700447 mAutomaticBrightnessController = new AutomaticBrightnessController(this,
Michael Wright144aac92017-12-21 18:37:41 +0000448 handler.getLooper(), sensorManager, mBrightnessMapper,
449 lightSensorWarmUpTimeConfig, mScreenBrightnessRangeMinimum,
450 mScreenBrightnessRangeMaximum, dozeScaleFactor, lightSensorRate,
451 initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce,
Julius D'souza428aed02016-08-07 19:08:30 -0700452 autoBrightnessResetAmbientLuxAfterWarmUp, ambientLightHorizon,
453 autoBrightnessAdjustmentMaxGamma, dynamicHysteresis);
Michael Wrighteef0e132017-11-21 17:57:52 +0000454 } else {
455 mUseSoftwareAutoBrightnessConfig = false;
Jeff Brown96307042012-07-27 15:51:34 -0700456 }
Jeff Brown96307042012-07-27 15:51:34 -0700457 }
458
Narayan Kamath38819982017-07-06 18:15:30 +0100459 mColorFadeEnabled = !ActivityManager.isLowRamDeviceStatic();
Michael Lentine0839adb2014-07-29 18:47:56 -0700460 mColorFadeFadesConfig = resources.getBoolean(
Jeff Browna52772f2012-10-04 18:38:09 -0700461 com.android.internal.R.bool.config_animateScreenLights);
462
Michael Wrightc3e6af82017-07-25 22:31:03 +0100463 mDisplayBlanksAfterDozeConfig = resources.getBoolean(
464 com.android.internal.R.bool.config_displayBlanksAfterDoze);
Michael Wright05e76fe2017-07-20 18:18:33 +0100465
Michael Wright63a40062017-07-26 01:10:59 +0100466 mBrightnessBucketsInDozeConfig = resources.getBoolean(
467 com.android.internal.R.bool.config_displayBrightnessBucketsInDoze);
468
Jeff Brown96307042012-07-27 15:51:34 -0700469 if (!DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) {
470 mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
471 if (mProximitySensor != null) {
472 mProximityThreshold = Math.min(mProximitySensor.getMaximumRange(),
473 TYPICAL_PROXIMITY_THRESHOLD);
474 }
475 }
476
Michael Wrightd8460232018-01-16 18:04:59 +0000477 mCurrentScreenBrightnessSetting = getScreenBrightnessSetting();
478 mScreenBrightnessForVr = getScreenBrightnessForVrSetting();
479 mAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting();
480 mTemporaryScreenBrightness = -1;
481 mTemporaryAutoBrightnessAdjustment = Float.NaN;
Michael Wrighteef0e132017-11-21 17:57:52 +0000482 }
483
Jeff Brown96307042012-07-27 15:51:34 -0700484 /**
485 * Returns true if the proximity sensor screen-off function is available.
486 */
487 public boolean isProximitySensorAvailable() {
488 return mProximitySensor != null;
489 }
490
491 /**
Michael Wright144aac92017-12-21 18:37:41 +0000492 * Get the {@link BrightnessChangeEvent}s for the specified user.
493 * @param userId userId to fetch data for
494 * @param includePackage if false will null out the package name in events
495 */
496 public ParceledListSlice<BrightnessChangeEvent> getBrightnessEvents(
497 @UserIdInt int userId, boolean includePackage) {
498 return mBrightnessTracker.getEvents(userId, includePackage);
499 }
500
501 /**
502 * Persist the brightness slider events to disk.
503 */
504 public void persistBrightnessSliderEvents() {
505 mBrightnessTracker.persistEvents();
506 }
507
508 /**
Jeff Brown96307042012-07-27 15:51:34 -0700509 * Requests a new power state.
510 * The controller makes a copy of the provided object and then
511 * begins adjusting the power state to match what was requested.
512 *
513 * @param request The requested power state.
514 * @param waitForNegativeProximity If true, issues a request to wait for
515 * negative proximity before turning the screen back on, assuming the screen
516 * was turned off by the proximity sensor.
517 * @return True if display is ready, false if there are important changes that must
518 * be made asynchronously (such as turning the screen on), in which case the caller
Jeff Brown606e4e82014-09-18 15:22:26 -0700519 * should grab a wake lock, watch for {@link DisplayPowerCallbacks#onStateChanged()}
520 * then try the request again later until the state converges.
Jeff Brown96307042012-07-27 15:51:34 -0700521 */
522 public boolean requestPowerState(DisplayPowerRequest request,
523 boolean waitForNegativeProximity) {
524 if (DEBUG) {
525 Slog.d(TAG, "requestPowerState: "
526 + request + ", waitForNegativeProximity=" + waitForNegativeProximity);
527 }
528
529 synchronized (mLock) {
530 boolean changed = false;
531
532 if (waitForNegativeProximity
533 && !mPendingWaitForNegativeProximityLocked) {
534 mPendingWaitForNegativeProximityLocked = true;
535 changed = true;
536 }
537
538 if (mPendingRequestLocked == null) {
539 mPendingRequestLocked = new DisplayPowerRequest(request);
540 changed = true;
541 } else if (!mPendingRequestLocked.equals(request)) {
542 mPendingRequestLocked.copyFrom(request);
543 changed = true;
544 }
545
546 if (changed) {
547 mDisplayReadyLocked = false;
548 }
549
550 if (changed && !mPendingRequestChangedLocked) {
551 mPendingRequestChangedLocked = true;
552 sendUpdatePowerStateLocked();
553 }
554
555 return mDisplayReadyLocked;
556 }
557 }
558
559 private void sendUpdatePowerState() {
560 synchronized (mLock) {
561 sendUpdatePowerStateLocked();
562 }
563 }
564
565 private void sendUpdatePowerStateLocked() {
566 if (!mPendingUpdatePowerStateLocked) {
567 mPendingUpdatePowerStateLocked = true;
568 Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE);
Jeff Brown96307042012-07-27 15:51:34 -0700569 mHandler.sendMessage(msg);
570 }
571 }
572
573 private void initialize() {
Jeff Brown037c33e2014-04-09 00:31:55 -0700574 // Initialize the power state object for the default display.
575 // In the future, we might manage multiple displays independently.
576 mPowerState = new DisplayPowerState(mBlanker,
Narayan Kamath38819982017-07-06 18:15:30 +0100577 mColorFadeEnabled ? new ColorFade(Display.DEFAULT_DISPLAY) : null);
Jeff Brown96307042012-07-27 15:51:34 -0700578
Narayan Kamath38819982017-07-06 18:15:30 +0100579 if (mColorFadeEnabled) {
580 mColorFadeOnAnimator = ObjectAnimator.ofFloat(
581 mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 0.0f, 1.0f);
582 mColorFadeOnAnimator.setDuration(COLOR_FADE_ON_ANIMATION_DURATION_MILLIS);
583 mColorFadeOnAnimator.addListener(mAnimatorListener);
Jeff Brown96307042012-07-27 15:51:34 -0700584
Narayan Kamath38819982017-07-06 18:15:30 +0100585 mColorFadeOffAnimator = ObjectAnimator.ofFloat(
586 mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 1.0f, 0.0f);
587 mColorFadeOffAnimator.setDuration(COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS);
588 mColorFadeOffAnimator.addListener(mAnimatorListener);
589 }
Jeff Brown96307042012-07-27 15:51:34 -0700590
591 mScreenBrightnessRampAnimator = new RampAnimator<DisplayPowerState>(
592 mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS);
Jeff Brown42558692014-05-20 22:02:46 -0700593 mScreenBrightnessRampAnimator.setListener(mRampAnimatorListener);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800594
Jeff Brown131206b2014-04-08 17:27:14 -0700595 // Initialize screen state for battery stats.
596 try {
Jeff Browne95c3cd2014-05-02 16:59:26 -0700597 mBatteryStats.noteScreenState(mPowerState.getScreenState());
Jeff Brown131206b2014-04-08 17:27:14 -0700598 mBatteryStats.noteScreenBrightness(mPowerState.getScreenBrightness());
599 } catch (RemoteException ex) {
600 // same process
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800601 }
Michael Wright144aac92017-12-21 18:37:41 +0000602
603 // Initialize all of the brightness tracking state
Michael Wrightd8460232018-01-16 18:04:59 +0000604 final float brightness = convertToNits(mPowerState.getScreenBrightness());
Michael Wright144aac92017-12-21 18:37:41 +0000605 if (brightness >= 0.0f) {
606 mBrightnessTracker.start(brightness);
607 }
Michael Wrightd8460232018-01-16 18:04:59 +0000608
609 mContext.getContentResolver().registerContentObserver(
610 Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS),
611 false /*notifyForDescendants*/, mSettingsObserver, UserHandle.USER_ALL);
612 mContext.getContentResolver().registerContentObserver(
613 Settings.System.getUriFor(Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ),
614 false /*notifyForDescendants*/, mSettingsObserver, UserHandle.USER_ALL);
Jeff Brown96307042012-07-27 15:51:34 -0700615 }
616
617 private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() {
618 @Override
619 public void onAnimationStart(Animator animation) {
620 }
621 @Override
622 public void onAnimationEnd(Animator animation) {
623 sendUpdatePowerState();
624 }
625 @Override
626 public void onAnimationRepeat(Animator animation) {
627 }
628 @Override
629 public void onAnimationCancel(Animator animation) {
630 }
631 };
632
Jeff Brown42558692014-05-20 22:02:46 -0700633 private final RampAnimator.Listener mRampAnimatorListener = new RampAnimator.Listener() {
634 @Override
635 public void onAnimationEnd() {
636 sendUpdatePowerState();
637 }
638 };
639
Jeff Brown96307042012-07-27 15:51:34 -0700640 private void updatePowerState() {
641 // Update the power state request.
642 final boolean mustNotify;
643 boolean mustInitialize = false;
Jeff Brown330560f2012-08-21 22:10:57 -0700644
Jeff Brown96307042012-07-27 15:51:34 -0700645 synchronized (mLock) {
646 mPendingUpdatePowerStateLocked = false;
647 if (mPendingRequestLocked == null) {
648 return; // wait until first actual power request
649 }
650
651 if (mPowerRequest == null) {
652 mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked);
653 mWaitingForNegativeProximity = mPendingWaitForNegativeProximityLocked;
Jeff Brown6307a152012-08-20 13:24:23 -0700654 mPendingWaitForNegativeProximityLocked = false;
Jeff Brown96307042012-07-27 15:51:34 -0700655 mPendingRequestChangedLocked = false;
656 mustInitialize = true;
657 } else if (mPendingRequestChangedLocked) {
658 mPowerRequest.copyFrom(mPendingRequestLocked);
659 mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked;
Jeff Brown6307a152012-08-20 13:24:23 -0700660 mPendingWaitForNegativeProximityLocked = false;
Jeff Brown96307042012-07-27 15:51:34 -0700661 mPendingRequestChangedLocked = false;
662 mDisplayReadyLocked = false;
663 }
664
665 mustNotify = !mDisplayReadyLocked;
666 }
667
668 // Initialize things the first time the power state is changed.
669 if (mustInitialize) {
670 initialize();
671 }
672
Jeff Brown970d4132014-07-19 11:33:47 -0700673 // Compute the basic display state using the policy.
674 // We might override this below based on other factors.
675 int state;
676 int brightness = PowerManager.BRIGHTNESS_DEFAULT;
Jeff Brown2175e9c2014-09-12 16:11:07 -0700677 boolean performScreenOffTransition = false;
Jeff Brown970d4132014-07-19 11:33:47 -0700678 switch (mPowerRequest.policy) {
679 case DisplayPowerRequest.POLICY_OFF:
680 state = Display.STATE_OFF;
Jeff Brown2175e9c2014-09-12 16:11:07 -0700681 performScreenOffTransition = true;
Jeff Brown970d4132014-07-19 11:33:47 -0700682 break;
683 case DisplayPowerRequest.POLICY_DOZE:
684 if (mPowerRequest.dozeScreenState != Display.STATE_UNKNOWN) {
685 state = mPowerRequest.dozeScreenState;
686 } else {
687 state = Display.STATE_DOZE;
688 }
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700689 if (!mAllowAutoBrightnessWhileDozingConfig) {
690 brightness = mPowerRequest.dozeScreenBrightness;
691 }
Jeff Brown970d4132014-07-19 11:33:47 -0700692 break;
Santos Cordon3107d292016-09-20 15:50:35 -0700693 case DisplayPowerRequest.POLICY_VR:
694 state = Display.STATE_VR;
695 break;
Jeff Brown970d4132014-07-19 11:33:47 -0700696 case DisplayPowerRequest.POLICY_DIM:
697 case DisplayPowerRequest.POLICY_BRIGHT:
698 default:
699 state = Display.STATE_ON;
700 break;
701 }
Jeff Brown2175e9c2014-09-12 16:11:07 -0700702 assert(state != Display.STATE_UNKNOWN);
Jeff Brown970d4132014-07-19 11:33:47 -0700703
Jeff Brown6307a152012-08-20 13:24:23 -0700704 // Apply the proximity sensor.
Jeff Brown96307042012-07-27 15:51:34 -0700705 if (mProximitySensor != null) {
Jeff Brown970d4132014-07-19 11:33:47 -0700706 if (mPowerRequest.useProximitySensor && state != Display.STATE_OFF) {
Jeff Brown6307a152012-08-20 13:24:23 -0700707 setProximitySensorEnabled(true);
708 if (!mScreenOffBecauseOfProximity
709 && mProximity == PROXIMITY_POSITIVE) {
710 mScreenOffBecauseOfProximity = true;
Jeff Brownec083212013-09-11 20:45:25 -0700711 sendOnProximityPositiveWithWakelock();
Jeff Brown6307a152012-08-20 13:24:23 -0700712 }
713 } else if (mWaitingForNegativeProximity
714 && mScreenOffBecauseOfProximity
715 && mProximity == PROXIMITY_POSITIVE
Jeff Brown970d4132014-07-19 11:33:47 -0700716 && state != Display.STATE_OFF) {
Jeff Brown6307a152012-08-20 13:24:23 -0700717 setProximitySensorEnabled(true);
718 } else {
719 setProximitySensorEnabled(false);
720 mWaitingForNegativeProximity = false;
721 }
722 if (mScreenOffBecauseOfProximity
723 && mProximity != PROXIMITY_POSITIVE) {
Jeff Brown96307042012-07-27 15:51:34 -0700724 mScreenOffBecauseOfProximity = false;
Jeff Brownec083212013-09-11 20:45:25 -0700725 sendOnProximityNegativeWithWakelock();
Jeff Brown96307042012-07-27 15:51:34 -0700726 }
Jeff Brown6307a152012-08-20 13:24:23 -0700727 } else {
728 mWaitingForNegativeProximity = false;
Jeff Brown96307042012-07-27 15:51:34 -0700729 }
Jeff Brown970d4132014-07-19 11:33:47 -0700730 if (mScreenOffBecauseOfProximity) {
731 state = Display.STATE_OFF;
Jeff Brown96307042012-07-27 15:51:34 -0700732 }
733
Jeff Brownbf4e4142014-10-02 13:08:05 -0700734 // Animate the screen state change unless already animating.
735 // The transition may be deferred, so after this point we will use the
736 // actual state instead of the desired one.
Santos Cordon3107d292016-09-20 15:50:35 -0700737 final int oldState = mPowerState.getScreenState();
Jeff Brownbf4e4142014-10-02 13:08:05 -0700738 animateScreenStateChange(state, performScreenOffTransition);
739 state = mPowerState.getScreenState();
740
Jeff Brown970d4132014-07-19 11:33:47 -0700741 // Use zero brightness when screen is off.
742 if (state == Display.STATE_OFF) {
743 brightness = PowerManager.BRIGHTNESS_OFF;
744 }
745
Michael Wrightd8460232018-01-16 18:04:59 +0000746 // Always use the VR brightness when in the VR state.
747 if (state == Display.STATE_VR) {
748 brightness = mScreenBrightnessForVr;
749 }
750
751 if (brightness < 0 && mPowerRequest.screenBrightnessOverride > 0) {
752 brightness = mPowerRequest.screenBrightnessOverride;
753 }
Michael Wright144aac92017-12-21 18:37:41 +0000754
755 final boolean autoBrightnessEnabledInDoze =
756 mAllowAutoBrightnessWhileDozingConfig && Display.isDozeState(state);
757 final boolean autoBrightnessEnabled = mPowerRequest.useAutoBrightness
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700758 && (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
Michael Wright144aac92017-12-21 18:37:41 +0000759 && brightness < 0
760 && mAutomaticBrightnessController != null;
Michael Wrightd8460232018-01-16 18:04:59 +0000761 boolean brightnessIsTemporary = false;
Michael Wright144aac92017-12-21 18:37:41 +0000762
Michael Wrightd8460232018-01-16 18:04:59 +0000763 final boolean userSetBrightnessChanged = updateUserSetScreenBrightness();
764 if (userSetBrightnessChanged) {
765 mTemporaryScreenBrightness = -1;
Michael Wright144aac92017-12-21 18:37:41 +0000766 }
767
Michael Wrightd8460232018-01-16 18:04:59 +0000768 // Use the temporary screen brightness if there isn't an override, either from
769 // WindowManager or based on the display state.
770 if (mTemporaryScreenBrightness > 0) {
771 brightness = mTemporaryScreenBrightness;
772 brightnessIsTemporary = true;
773 }
774
775 final boolean autoBrightnessAdjustmentChanged = updateAutoBrightnessAdjustment();
776 if (autoBrightnessAdjustmentChanged) {
777 mTemporaryAutoBrightnessAdjustment = Float.NaN;
778 }
779
780 // Use the autobrightness adjustment override if set.
781 final float autoBrightnessAdjustment;
782 if (!Float.isNaN(mTemporaryAutoBrightnessAdjustment)) {
783 autoBrightnessAdjustment = mTemporaryAutoBrightnessAdjustment;
784 brightnessIsTemporary = true;
785 } else {
786 autoBrightnessAdjustment = mAutoBrightnessAdjustment;
787 }
788
789 // Apply brightness boost.
790 // We do this here after deciding whether auto-brightness is enabled so that we don't
791 // disable the light sensor during this temporary state. That way when boost ends we will
792 // be able to resume normal auto-brightness behavior without any delay.
793 if (mPowerRequest.boostScreenBrightness
794 && brightness != PowerManager.BRIGHTNESS_OFF) {
795 brightness = PowerManager.BRIGHTNESS_ON;
796 }
797
798 // If the brightness is already set then it's been overriden by something other than the
799 // user, or is a temporary adjustment.
800 final boolean userInitiatedChange = brightness < 0
801 && (autoBrightnessAdjustmentChanged || userSetBrightnessChanged);
802
Michael Wright144aac92017-12-21 18:37:41 +0000803 // Configure auto-brightness.
804 if (mAutomaticBrightnessController != null) {
Jeff Brown970d4132014-07-19 11:33:47 -0700805 mAutomaticBrightnessController.configure(autoBrightnessEnabled,
Michael Wrightd8460232018-01-16 18:04:59 +0000806 mBrightnessConfiguration,
807 mLastUserSetScreenBrightness / (float) PowerManager.BRIGHTNESS_ON,
808 autoBrightnessAdjustment, mPowerRequest.policy, userInitiatedChange);
Jeff Brown7b5be5e2014-11-12 18:45:31 -0800809 }
810
Jeff Brown970d4132014-07-19 11:33:47 -0700811 // Apply auto-brightness.
812 boolean slowChange = false;
813 if (brightness < 0) {
814 if (autoBrightnessEnabled) {
815 brightness = mAutomaticBrightnessController.getAutomaticScreenBrightness();
816 }
817 if (brightness >= 0) {
818 // Use current auto-brightness value and slowly adjust to changes.
819 brightness = clampScreenBrightness(brightness);
820 if (mAppliedAutoBrightness && !autoBrightnessAdjustmentChanged) {
821 slowChange = true; // slowly adapt to auto-brightness
822 }
Michael Wrightd8460232018-01-16 18:04:59 +0000823 // Tell the rest of the system about the new brightness. Note that we do this
824 // before applying the low power or dim transformations so that the slider
825 // accurately represents the full possible range, even if they range changes what
826 // it means in absolute terms.
827 putScreenBrightnessSetting(brightness);
Jeff Brown970d4132014-07-19 11:33:47 -0700828 mAppliedAutoBrightness = true;
Jeff Brown96307042012-07-27 15:51:34 -0700829 } else {
Jeff Brown970d4132014-07-19 11:33:47 -0700830 mAppliedAutoBrightness = false;
Jeff Brown96307042012-07-27 15:51:34 -0700831 }
832 } else {
Jeff Brown970d4132014-07-19 11:33:47 -0700833 mAppliedAutoBrightness = false;
834 }
835
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700836 // Use default brightness when dozing unless overridden.
Michael Wrightb0a1d3d2017-09-22 15:05:02 +0100837 if (brightness < 0 && Display.isDozeState(state)) {
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -0700838 brightness = mScreenBrightnessDozeConfig;
839 }
840
Jeff Brown970d4132014-07-19 11:33:47 -0700841 // Apply manual brightness.
842 // Use the current brightness setting from the request, which is expected
843 // provide a nominal default value for the case where auto-brightness
844 // is not ready yet.
845 if (brightness < 0) {
Michael Wrightd8460232018-01-16 18:04:59 +0000846 brightness = clampScreenBrightness(mLastUserSetScreenBrightness);
Jeff Brown970d4132014-07-19 11:33:47 -0700847 }
848
Michael Wrightd8460232018-01-16 18:04:59 +0000849
Jeff Brown970d4132014-07-19 11:33:47 -0700850 // Apply dimming by at least some minimum amount when user activity
851 // timeout is about to expire.
852 if (mPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
Jeff Brown5c8ea082014-07-24 19:30:31 -0700853 if (brightness > mScreenBrightnessRangeMinimum) {
854 brightness = Math.max(Math.min(brightness - SCREEN_DIM_MINIMUM_REDUCTION,
855 mScreenBrightnessDimConfig), mScreenBrightnessRangeMinimum);
856 }
Jeff Brown970d4132014-07-19 11:33:47 -0700857 if (!mAppliedDimming) {
858 slowChange = false;
859 }
860 mAppliedDimming = true;
mochangmingf0cb46c2015-12-29 13:55:24 +0800861 } else if (mAppliedDimming) {
862 slowChange = false;
863 mAppliedDimming = false;
Jeff Brown970d4132014-07-19 11:33:47 -0700864 }
865
jackqdyulei92681e82017-02-28 11:26:28 -0800866 // If low power mode is enabled, scale brightness by screenLowPowerBrightnessFactor
Jeff Brown970d4132014-07-19 11:33:47 -0700867 // as long as it is above the minimum threshold.
868 if (mPowerRequest.lowPowerMode) {
869 if (brightness > mScreenBrightnessRangeMinimum) {
jackqdyulei92681e82017-02-28 11:26:28 -0800870 final float brightnessFactor =
871 Math.min(mPowerRequest.screenLowPowerBrightnessFactor, 1);
872 final int lowPowerBrightness = (int) (brightness * brightnessFactor);
873 brightness = Math.max(lowPowerBrightness, mScreenBrightnessRangeMinimum);
Jeff Brown970d4132014-07-19 11:33:47 -0700874 }
875 if (!mAppliedLowPower) {
876 slowChange = false;
877 }
878 mAppliedLowPower = true;
mochangmingf0cb46c2015-12-29 13:55:24 +0800879 } else if (mAppliedLowPower) {
880 slowChange = false;
881 mAppliedLowPower = false;
Jeff Brown970d4132014-07-19 11:33:47 -0700882 }
883
Jeff Brown0a434772014-09-30 14:42:27 -0700884 // Animate the screen brightness when the screen is on or dozing.
Santos Cordon3107d292016-09-20 15:50:35 -0700885 // Skip the animation when the screen is off or suspended or transition to/from VR.
Prashant Malani33538242014-11-13 14:04:00 -0800886 if (!mPendingScreenOff) {
Julius D'souzad5105dd2017-06-02 11:03:53 -0700887 if (mSkipScreenOnBrightnessRamp) {
Julius D'souzad5105dd2017-06-02 11:03:53 -0700888 if (state == Display.STATE_ON) {
889 if (mSkipRampState == RAMP_STATE_SKIP_NONE && mDozing) {
890 mInitialAutoBrightness = brightness;
891 mSkipRampState = RAMP_STATE_SKIP_INITIAL;
892 } else if (mSkipRampState == RAMP_STATE_SKIP_INITIAL
893 && mUseSoftwareAutoBrightnessConfig
894 && brightness != mInitialAutoBrightness) {
895 mSkipRampState = RAMP_STATE_SKIP_AUTOBRIGHT;
896 } else if (mSkipRampState == RAMP_STATE_SKIP_AUTOBRIGHT) {
897 mSkipRampState = RAMP_STATE_SKIP_NONE;
898 }
899 } else {
900 mSkipRampState = RAMP_STATE_SKIP_NONE;
901 }
902 }
903
Michael Wrightb0a1d3d2017-09-22 15:05:02 +0100904 final boolean wasOrWillBeInVr =
905 (state == Display.STATE_VR || oldState == Display.STATE_VR);
906 final boolean initialRampSkip =
907 state == Display.STATE_ON && mSkipRampState != RAMP_STATE_SKIP_NONE;
908 // While dozing, sometimes the brightness is split into buckets. Rather than animating
909 // through the buckets, which is unlikely to be smooth in the first place, just jump
910 // right to the suggested brightness.
911 final boolean hasBrightnessBuckets =
912 Display.isDozeState(state) && mBrightnessBucketsInDozeConfig;
913 // If the color fade is totally covering the screen then we can change the backlight
914 // level without it being a noticeable jump since any actual content isn't yet visible.
915 final boolean isDisplayContentVisible =
916 mColorFadeEnabled && mPowerState.getColorFadeLevel() == 1.0f;
917 if (initialRampSkip || hasBrightnessBuckets
Michael Wrightd8460232018-01-16 18:04:59 +0000918 || wasOrWillBeInVr || !isDisplayContentVisible || brightnessIsTemporary) {
Michael Wrightb0a1d3d2017-09-22 15:05:02 +0100919 animateScreenBrightness(brightness, 0);
920 } else {
Prashant Malani33538242014-11-13 14:04:00 -0800921 animateScreenBrightness(brightness,
Julius D'souzafeadad12016-08-05 14:34:38 -0700922 slowChange ? mBrightnessRampRateSlow : mBrightnessRampRateFast);
Prashant Malani33538242014-11-13 14:04:00 -0800923 }
Michael Wright144aac92017-12-21 18:37:41 +0000924
Michael Wrightd8460232018-01-16 18:04:59 +0000925 if (!brightnessIsTemporary) {
926 notifyBrightnessChanged(brightness, userInitiatedChange);
Michael Wright144aac92017-12-21 18:37:41 +0000927 }
Michael Wrightd8460232018-01-16 18:04:59 +0000928
Jeff Brown0a434772014-09-30 14:42:27 -0700929 }
930
931 // Determine whether the display is ready for use in the newly requested state.
932 // Note that we do not wait for the brightness ramp animation to complete before
933 // reporting the display is ready because we only need to ensure the screen is in the
934 // right power state even as it continues to converge on the desired brightness.
Narayan Kamath38819982017-07-06 18:15:30 +0100935 final boolean ready = mPendingScreenOnUnblocker == null &&
936 (!mColorFadeEnabled ||
937 (!mColorFadeOnAnimator.isStarted() && !mColorFadeOffAnimator.isStarted()))
Jeff Brown0a434772014-09-30 14:42:27 -0700938 && mPowerState.waitUntilClean(mCleanListener);
939 final boolean finished = ready
940 && !mScreenBrightnessRampAnimator.isAnimating();
941
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700942 // Notify policy about screen turned on.
943 if (ready && state != Display.STATE_OFF
944 && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_ON) {
Michael Wrightc3e6af82017-07-25 22:31:03 +0100945 setReportedScreenState(REPORTED_TO_POLICY_SCREEN_ON);
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700946 mWindowManagerPolicy.screenTurnedOn();
947 }
948
Jeff Brown0a434772014-09-30 14:42:27 -0700949 // Grab a wake lock if we have unfinished business.
950 if (!finished && !mUnfinishedBusiness) {
951 if (DEBUG) {
952 Slog.d(TAG, "Unfinished business...");
953 }
954 mCallbacks.acquireSuspendBlocker();
955 mUnfinishedBusiness = true;
956 }
957
958 // Notify the power manager when ready.
959 if (ready && mustNotify) {
960 // Send state change.
Jeff Brown96307042012-07-27 15:51:34 -0700961 synchronized (mLock) {
962 if (!mPendingRequestChangedLocked) {
963 mDisplayReadyLocked = true;
Jeff Brownc38c9be2012-10-04 13:16:19 -0700964
965 if (DEBUG) {
966 Slog.d(TAG, "Display ready!");
967 }
Jeff Brown96307042012-07-27 15:51:34 -0700968 }
969 }
Jeff Brownec083212013-09-11 20:45:25 -0700970 sendOnStateChangedWithWakelock();
Jeff Brown96307042012-07-27 15:51:34 -0700971 }
Jeff Brown0a434772014-09-30 14:42:27 -0700972
973 // Release the wake lock when we have no unfinished business.
974 if (finished && mUnfinishedBusiness) {
975 if (DEBUG) {
976 Slog.d(TAG, "Finished business...");
977 }
978 mUnfinishedBusiness = false;
979 mCallbacks.releaseSuspendBlocker();
980 }
Julius D'souzad5105dd2017-06-02 11:03:53 -0700981
982 // Record if dozing for future comparison.
983 mDozing = state != Display.STATE_ON;
Jeff Brown96307042012-07-27 15:51:34 -0700984 }
985
Michael Wright639c8be2014-01-17 18:29:12 -0800986 @Override
987 public void updateBrightness() {
988 sendUpdatePowerState();
989 }
990
Michael Wrighteef0e132017-11-21 17:57:52 +0000991 public void setBrightnessConfiguration(BrightnessConfiguration c) {
992 Message msg = mHandler.obtainMessage(MSG_CONFIGURE_BRIGHTNESS, c);
993 msg.sendToTarget();
994 }
995
Michael Wrightd8460232018-01-16 18:04:59 +0000996 public void setTemporaryBrightness(int brightness) {
997 Message msg = mHandler.obtainMessage(MSG_SET_TEMPORARY_BRIGHTNESS,
998 brightness, 0 /*unused*/);
999 msg.sendToTarget();
1000 }
1001
1002 public void setTemporaryAutoBrightnessAdjustment(float adjustment) {
1003 Message msg = mHandler.obtainMessage(MSG_SET_TEMPORARY_AUTO_BRIGHTNESS_ADJUSTMENT,
1004 Float.floatToIntBits(adjustment), 0 /*unused*/);
1005 msg.sendToTarget();
1006 }
1007
Jeff Brown8b9cf1c2012-10-07 14:54:17 -07001008 private void blockScreenOn() {
Jeff Brown3ee549c2014-09-22 20:14:39 -07001009 if (mPendingScreenOnUnblocker == null) {
Jeff Brown3edf5272014-08-14 19:25:14 -07001010 Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0);
Jeff Brown3ee549c2014-09-22 20:14:39 -07001011 mPendingScreenOnUnblocker = new ScreenOnUnblocker();
Jeff Brown037c33e2014-04-09 00:31:55 -07001012 mScreenOnBlockStartRealTime = SystemClock.elapsedRealtime();
Jeff Brown3edf5272014-08-14 19:25:14 -07001013 Slog.i(TAG, "Blocking screen on until initial contents have been drawn.");
Jeff Brown8b9cf1c2012-10-07 14:54:17 -07001014 }
1015 }
1016
1017 private void unblockScreenOn() {
Jeff Brown3ee549c2014-09-22 20:14:39 -07001018 if (mPendingScreenOnUnblocker != null) {
1019 mPendingScreenOnUnblocker = null;
Jeff Brown2d8a3902014-03-11 23:02:35 -07001020 long delay = SystemClock.elapsedRealtime() - mScreenOnBlockStartRealTime;
Jeff Brown3edf5272014-08-14 19:25:14 -07001021 Slog.i(TAG, "Unblocked screen on after " + delay + " ms");
1022 Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0);
Jeff Brown8b9cf1c2012-10-07 14:54:17 -07001023 }
1024 }
1025
Jorim Jaggi51304d72017-05-17 17:25:32 +02001026 private void blockScreenOff() {
1027 if (mPendingScreenOffUnblocker == null) {
1028 Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, SCREEN_OFF_BLOCKED_TRACE_NAME, 0);
1029 mPendingScreenOffUnblocker = new ScreenOffUnblocker();
1030 mScreenOffBlockStartRealTime = SystemClock.elapsedRealtime();
1031 Slog.i(TAG, "Blocking screen off");
1032 }
1033 }
1034
1035 private void unblockScreenOff() {
1036 if (mPendingScreenOffUnblocker != null) {
1037 mPendingScreenOffUnblocker = null;
1038 long delay = SystemClock.elapsedRealtime() - mScreenOffBlockStartRealTime;
1039 Slog.i(TAG, "Unblocked screen off after " + delay + " ms");
1040 Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, SCREEN_OFF_BLOCKED_TRACE_NAME, 0);
1041 }
1042 }
1043
Jeff Brown3ee549c2014-09-22 20:14:39 -07001044 private boolean setScreenState(int state) {
Michael Wrightc3e6af82017-07-25 22:31:03 +01001045 return setScreenState(state, false /*reportOnly*/);
Michael Wright05e76fe2017-07-20 18:18:33 +01001046 }
1047
Michael Wrightc3e6af82017-07-25 22:31:03 +01001048 private boolean setScreenState(int state, boolean reportOnly) {
Jorim Jaggi51304d72017-05-17 17:25:32 +02001049 final boolean isOff = (state == Display.STATE_OFF);
Jeff Brown037c33e2014-04-09 00:31:55 -07001050 if (mPowerState.getScreenState() != state) {
Jorim Jaggi51304d72017-05-17 17:25:32 +02001051
1052 // If we are trying to turn screen off, give policy a chance to do something before we
1053 // actually turn the screen off.
1054 if (isOff && !mScreenOffBecauseOfProximity) {
1055 if (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_ON) {
Michael Wrightc3e6af82017-07-25 22:31:03 +01001056 setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_OFF);
Jorim Jaggi51304d72017-05-17 17:25:32 +02001057 blockScreenOff();
1058 mWindowManagerPolicy.screenTurningOff(mPendingScreenOffUnblocker);
Michael Wrightc3e6af82017-07-25 22:31:03 +01001059 unblockScreenOff();
Jorim Jaggi51304d72017-05-17 17:25:32 +02001060 } else if (mPendingScreenOffUnblocker != null) {
Jorim Jaggi51304d72017-05-17 17:25:32 +02001061 // Abort doing the state change until screen off is unblocked.
1062 return false;
1063 }
1064 }
1065
Michael Wrightc3e6af82017-07-25 22:31:03 +01001066 if (!reportOnly) {
Michael Wrightb0a1d3d2017-09-22 15:05:02 +01001067 Trace.traceCounter(Trace.TRACE_TAG_POWER, "ScreenState", state);
Michael Wrightc3e6af82017-07-25 22:31:03 +01001068 mPowerState.setScreenState(state);
1069 // Tell battery stats about the transition.
1070 try {
1071 mBatteryStats.noteScreenState(state);
1072 } catch (RemoteException ex) {
1073 // same process
1074 }
Jeff Brown96307042012-07-27 15:51:34 -07001075 }
1076 }
Jeff Browne1633ad2015-06-22 19:24:24 -07001077
1078 // Tell the window manager policy when the screen is turned off or on unless it's due
1079 // to the proximity sensor. We temporarily block turning the screen on until the
1080 // window manager is ready by leaving a black surface covering the screen.
1081 // This surface is essentially the final state of the color fade animation and
1082 // it is only removed once the window manager tells us that the activity has
1083 // finished drawing underneath.
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001084 if (isOff && mReportedScreenStateToPolicy != REPORTED_TO_POLICY_SCREEN_OFF
1085 && !mScreenOffBecauseOfProximity) {
Michael Wrightc3e6af82017-07-25 22:31:03 +01001086 setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
Jeff Browne1633ad2015-06-22 19:24:24 -07001087 unblockScreenOn();
1088 mWindowManagerPolicy.screenTurnedOff();
Jorim Jaggi51304d72017-05-17 17:25:32 +02001089 } else if (!isOff
1090 && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_OFF) {
1091
1092 // We told policy already that screen was turning off, but now we changed our minds.
1093 // Complete the full state transition on -> turningOff -> off.
1094 unblockScreenOff();
1095 mWindowManagerPolicy.screenTurnedOff();
Michael Wrightc3e6af82017-07-25 22:31:03 +01001096 setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
Jorim Jaggi51304d72017-05-17 17:25:32 +02001097 }
1098 if (!isOff && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF) {
Michael Wrightc3e6af82017-07-25 22:31:03 +01001099 setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_ON);
Jeff Browne1633ad2015-06-22 19:24:24 -07001100 if (mPowerState.getColorFadeLevel() == 0.0f) {
1101 blockScreenOn();
1102 } else {
1103 unblockScreenOn();
1104 }
1105 mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker);
1106 }
1107
1108 // Return true if the screen isn't blocked.
Jeff Brown3ee549c2014-09-22 20:14:39 -07001109 return mPendingScreenOnUnblocker == null;
Jeff Brown96307042012-07-27 15:51:34 -07001110 }
1111
Michael Wrightc3e6af82017-07-25 22:31:03 +01001112 private void setReportedScreenState(int state) {
1113 Trace.traceCounter(Trace.TRACE_TAG_POWER, "ReportedScreenStateToPolicy", state);
1114 mReportedScreenStateToPolicy = state;
1115 }
1116
Jeff Brown330560f2012-08-21 22:10:57 -07001117 private int clampScreenBrightness(int value) {
Michael Wright639c8be2014-01-17 18:29:12 -08001118 return MathUtils.constrain(
1119 value, mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum);
Jeff Brown330560f2012-08-21 22:10:57 -07001120 }
1121
Jeff Brown96307042012-07-27 15:51:34 -07001122 private void animateScreenBrightness(int target, int rate) {
Jeff Brown0a434772014-09-30 14:42:27 -07001123 if (DEBUG) {
1124 Slog.d(TAG, "Animating brightness: target=" + target +", rate=" + rate);
1125 }
Jeff Brown96307042012-07-27 15:51:34 -07001126 if (mScreenBrightnessRampAnimator.animateTo(target, rate)) {
Michael Wrighta9f37ab2017-08-15 17:14:20 +01001127 Trace.traceCounter(Trace.TRACE_TAG_POWER, "TargetScreenBrightness", target);
Jeff Brown131206b2014-04-08 17:27:14 -07001128 try {
1129 mBatteryStats.noteScreenBrightness(target);
1130 } catch (RemoteException ex) {
1131 // same process
1132 }
Jeff Brown96307042012-07-27 15:51:34 -07001133 }
1134 }
1135
Jeff Brown606e4e82014-09-18 15:22:26 -07001136 private void animateScreenStateChange(int target, boolean performScreenOffTransition) {
1137 // If there is already an animation in progress, don't interfere with it.
Narayan Kamath38819982017-07-06 18:15:30 +01001138 if (mColorFadeEnabled &&
1139 (mColorFadeOnAnimator.isStarted() || mColorFadeOffAnimator.isStarted())) {
Chong Zhangb131c702016-02-16 16:31:48 -08001140 if (target != Display.STATE_ON) {
1141 return;
1142 }
1143 // If display state changed to on, proceed and stop the color fade and turn screen on.
1144 mPendingScreenOff = false;
Jeff Brown606e4e82014-09-18 15:22:26 -07001145 }
1146
Michael Wrightc3e6af82017-07-25 22:31:03 +01001147 if (mDisplayBlanksAfterDozeConfig
1148 && Display.isDozeState(mPowerState.getScreenState())
Michael Wright05e76fe2017-07-20 18:18:33 +01001149 && !Display.isDozeState(target)) {
Michael Wright05e76fe2017-07-20 18:18:33 +01001150 // Skip the screen off animation and add a black surface to hide the
Michael Wrightc3e6af82017-07-25 22:31:03 +01001151 // contents of the screen.
1152 mPowerState.prepareColorFade(mContext,
1153 mColorFadeFadesConfig ? ColorFade.MODE_FADE : ColorFade.MODE_WARM_UP);
Lucas Dupina84952b2017-08-15 15:56:50 -07001154 if (mColorFadeOffAnimator != null) {
1155 mColorFadeOffAnimator.end();
1156 }
Michael Wrightc3e6af82017-07-25 22:31:03 +01001157 // Some display hardware will blank itself on the transition between doze and non-doze
1158 // but still on display states. In this case we want to report to policy that the
1159 // display has turned off so it can prepare the appropriate power on animation, but we
1160 // don't want to actually transition to the fully off state since that takes
1161 // significantly longer to transition from.
1162 setScreenState(Display.STATE_OFF, target != Display.STATE_OFF /*reportOnly*/);
Michael Wright05e76fe2017-07-20 18:18:33 +01001163 }
1164
Jeff Brown3ee549c2014-09-22 20:14:39 -07001165 // If we were in the process of turning off the screen but didn't quite
1166 // finish. Then finish up now to prevent a jarring transition back
1167 // to screen on if we skipped blocking screen on as usual.
1168 if (mPendingScreenOff && target != Display.STATE_OFF) {
1169 setScreenState(Display.STATE_OFF);
1170 mPendingScreenOff = false;
Michael Lentined73854d2015-09-25 10:55:26 -07001171 mPowerState.dismissColorFadeResources();
Jeff Brown606e4e82014-09-18 15:22:26 -07001172 }
1173
1174 if (target == Display.STATE_ON) {
1175 // Want screen on. The contents of the screen may not yet
Jeff Brown3ee549c2014-09-22 20:14:39 -07001176 // be visible if the color fade has not been dismissed because
Jeff Brown606e4e82014-09-18 15:22:26 -07001177 // its last frame of animation is solid black.
Jeff Brown3ee549c2014-09-22 20:14:39 -07001178 if (!setScreenState(Display.STATE_ON)) {
1179 return; // screen on blocked
1180 }
Narayan Kamath38819982017-07-06 18:15:30 +01001181 if (USE_COLOR_FADE_ON_ANIMATION && mColorFadeEnabled && mPowerRequest.isBrightOrDim()) {
Jeff Brown606e4e82014-09-18 15:22:26 -07001182 // Perform screen on animation.
1183 if (mPowerState.getColorFadeLevel() == 1.0f) {
1184 mPowerState.dismissColorFade();
1185 } else if (mPowerState.prepareColorFade(mContext,
1186 mColorFadeFadesConfig ?
1187 ColorFade.MODE_FADE :
1188 ColorFade.MODE_WARM_UP)) {
1189 mColorFadeOnAnimator.start();
1190 } else {
1191 mColorFadeOnAnimator.end();
1192 }
1193 } else {
1194 // Skip screen on animation.
1195 mPowerState.setColorFadeLevel(1.0f);
1196 mPowerState.dismissColorFade();
1197 }
Santos Cordon3107d292016-09-20 15:50:35 -07001198 } else if (target == Display.STATE_VR) {
1199 // Wait for brightness animation to complete beforehand when entering VR
1200 // from screen on to prevent a perceptible jump because brightness may operate
1201 // differently when the display is configured for dozing.
1202 if (mScreenBrightnessRampAnimator.isAnimating()
1203 && mPowerState.getScreenState() == Display.STATE_ON) {
1204 return;
1205 }
1206
1207 // Set screen state.
1208 if (!setScreenState(Display.STATE_VR)) {
1209 return; // screen on blocked
1210 }
1211
1212 // Dismiss the black surface without fanfare.
1213 mPowerState.setColorFadeLevel(1.0f);
1214 mPowerState.dismissColorFade();
Jeff Brown606e4e82014-09-18 15:22:26 -07001215 } else if (target == Display.STATE_DOZE) {
1216 // Want screen dozing.
1217 // Wait for brightness animation to complete beforehand when entering doze
1218 // from screen on to prevent a perceptible jump because brightness may operate
1219 // differently when the display is configured for dozing.
1220 if (mScreenBrightnessRampAnimator.isAnimating()
1221 && mPowerState.getScreenState() == Display.STATE_ON) {
1222 return;
1223 }
1224
Jeff Brown3ee549c2014-09-22 20:14:39 -07001225 // Set screen state.
1226 if (!setScreenState(Display.STATE_DOZE)) {
1227 return; // screen on blocked
1228 }
1229
1230 // Dismiss the black surface without fanfare.
Jeff Brown606e4e82014-09-18 15:22:26 -07001231 mPowerState.setColorFadeLevel(1.0f);
1232 mPowerState.dismissColorFade();
1233 } else if (target == Display.STATE_DOZE_SUSPEND) {
1234 // Want screen dozing and suspended.
1235 // Wait for brightness animation to complete beforehand unless already
1236 // suspended because we may not be able to change it after suspension.
1237 if (mScreenBrightnessRampAnimator.isAnimating()
1238 && mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) {
1239 return;
1240 }
1241
Jeff Brown3ee549c2014-09-22 20:14:39 -07001242 // If not already suspending, temporarily set the state to doze until the
1243 // screen on is unblocked, then suspend.
1244 if (mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) {
1245 if (!setScreenState(Display.STATE_DOZE)) {
1246 return; // screen on blocked
1247 }
1248 setScreenState(Display.STATE_DOZE_SUSPEND); // already on so can't block
1249 }
1250
1251 // Dismiss the black surface without fanfare.
Jeff Brown606e4e82014-09-18 15:22:26 -07001252 mPowerState.setColorFadeLevel(1.0f);
1253 mPowerState.dismissColorFade();
Chris Phoenix10a4a642017-09-25 13:21:00 -07001254 } else if (target == Display.STATE_ON_SUSPEND) {
1255 // Want screen full-power and suspended.
1256 // Wait for brightness animation to complete beforehand unless already
1257 // suspended because we may not be able to change it after suspension.
1258 if (mScreenBrightnessRampAnimator.isAnimating()
1259 && mPowerState.getScreenState() != Display.STATE_ON_SUSPEND) {
1260 return;
1261 }
1262
1263 // If not already suspending, temporarily set the state to on until the
1264 // screen on is unblocked, then suspend.
1265 if (mPowerState.getScreenState() != Display.STATE_ON_SUSPEND) {
1266 if (!setScreenState(Display.STATE_ON)) {
1267 return;
1268 }
1269 setScreenState(Display.STATE_ON_SUSPEND);
1270 }
1271
1272 // Dismiss the black surface without fanfare.
1273 mPowerState.setColorFadeLevel(1.0f);
1274 mPowerState.dismissColorFade();
Jeff Brown606e4e82014-09-18 15:22:26 -07001275 } else {
1276 // Want screen off.
Jeff Brown3ee549c2014-09-22 20:14:39 -07001277 mPendingScreenOff = true;
Narayan Kamath38819982017-07-06 18:15:30 +01001278 if (!mColorFadeEnabled) {
1279 mPowerState.setColorFadeLevel(0.0f);
1280 }
1281
Jeff Brown606e4e82014-09-18 15:22:26 -07001282 if (mPowerState.getColorFadeLevel() == 0.0f) {
1283 // Turn the screen off.
1284 // A black surface is already hiding the contents of the screen.
1285 setScreenState(Display.STATE_OFF);
Jeff Brown3ee549c2014-09-22 20:14:39 -07001286 mPendingScreenOff = false;
Michael Lentined73854d2015-09-25 10:55:26 -07001287 mPowerState.dismissColorFadeResources();
Jeff Brown606e4e82014-09-18 15:22:26 -07001288 } else if (performScreenOffTransition
1289 && mPowerState.prepareColorFade(mContext,
1290 mColorFadeFadesConfig ?
1291 ColorFade.MODE_FADE : ColorFade.MODE_COOL_DOWN)
1292 && mPowerState.getScreenState() != Display.STATE_OFF) {
1293 // Perform the screen off animation.
1294 mColorFadeOffAnimator.start();
1295 } else {
1296 // Skip the screen off animation and add a black surface to hide the
1297 // contents of the screen.
1298 mColorFadeOffAnimator.end();
1299 }
1300 }
1301 }
1302
Jeff Brown96307042012-07-27 15:51:34 -07001303 private final Runnable mCleanListener = new Runnable() {
1304 @Override
1305 public void run() {
1306 sendUpdatePowerState();
1307 }
1308 };
1309
1310 private void setProximitySensorEnabled(boolean enable) {
1311 if (enable) {
1312 if (!mProximitySensorEnabled) {
Jeff Brownec083212013-09-11 20:45:25 -07001313 // Register the listener.
1314 // Proximity sensor state already cleared initially.
Jeff Brown96307042012-07-27 15:51:34 -07001315 mProximitySensorEnabled = true;
Jeff Brown96307042012-07-27 15:51:34 -07001316 mSensorManager.registerListener(mProximitySensorListener, mProximitySensor,
1317 SensorManager.SENSOR_DELAY_NORMAL, mHandler);
1318 }
1319 } else {
1320 if (mProximitySensorEnabled) {
Jeff Brownec083212013-09-11 20:45:25 -07001321 // Unregister the listener.
1322 // Clear the proximity sensor state for next time.
Jeff Brown96307042012-07-27 15:51:34 -07001323 mProximitySensorEnabled = false;
1324 mProximity = PROXIMITY_UNKNOWN;
Jeff Brownec083212013-09-11 20:45:25 -07001325 mPendingProximity = PROXIMITY_UNKNOWN;
Jeff Brown96307042012-07-27 15:51:34 -07001326 mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
1327 mSensorManager.unregisterListener(mProximitySensorListener);
Jeff Brownec083212013-09-11 20:45:25 -07001328 clearPendingProximityDebounceTime(); // release wake lock (must be last)
Jeff Brown96307042012-07-27 15:51:34 -07001329 }
1330 }
1331 }
1332
1333 private void handleProximitySensorEvent(long time, boolean positive) {
Jeff Brownec083212013-09-11 20:45:25 -07001334 if (mProximitySensorEnabled) {
1335 if (mPendingProximity == PROXIMITY_NEGATIVE && !positive) {
1336 return; // no change
1337 }
1338 if (mPendingProximity == PROXIMITY_POSITIVE && positive) {
1339 return; // no change
1340 }
Jeff Brown96307042012-07-27 15:51:34 -07001341
Jeff Brownec083212013-09-11 20:45:25 -07001342 // Only accept a proximity sensor reading if it remains
1343 // stable for the entire debounce delay. We hold a wake lock while
1344 // debouncing the sensor.
1345 mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
1346 if (positive) {
1347 mPendingProximity = PROXIMITY_POSITIVE;
1348 setPendingProximityDebounceTime(
1349 time + PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY); // acquire wake lock
1350 } else {
1351 mPendingProximity = PROXIMITY_NEGATIVE;
1352 setPendingProximityDebounceTime(
1353 time + PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY); // acquire wake lock
1354 }
1355
1356 // Debounce the new sensor reading.
1357 debounceProximitySensor();
Jeff Brown93cbbb22012-10-04 13:18:36 -07001358 }
Jeff Brown96307042012-07-27 15:51:34 -07001359 }
1360
1361 private void debounceProximitySensor() {
Jeff Brownec083212013-09-11 20:45:25 -07001362 if (mProximitySensorEnabled
1363 && mPendingProximity != PROXIMITY_UNKNOWN
1364 && mPendingProximityDebounceTime >= 0) {
Jeff Brown96307042012-07-27 15:51:34 -07001365 final long now = SystemClock.uptimeMillis();
1366 if (mPendingProximityDebounceTime <= now) {
Jeff Brownec083212013-09-11 20:45:25 -07001367 // Sensor reading accepted. Apply the change then release the wake lock.
Jeff Brown96307042012-07-27 15:51:34 -07001368 mProximity = mPendingProximity;
Jeff Brownec083212013-09-11 20:45:25 -07001369 updatePowerState();
1370 clearPendingProximityDebounceTime(); // release wake lock (must be last)
Jeff Brown96307042012-07-27 15:51:34 -07001371 } else {
Jeff Brownec083212013-09-11 20:45:25 -07001372 // Need to wait a little longer.
1373 // Debounce again later. We continue holding a wake lock while waiting.
Jeff Brown96307042012-07-27 15:51:34 -07001374 Message msg = mHandler.obtainMessage(MSG_PROXIMITY_SENSOR_DEBOUNCED);
Jeff Brown96307042012-07-27 15:51:34 -07001375 mHandler.sendMessageAtTime(msg, mPendingProximityDebounceTime);
1376 }
1377 }
1378 }
1379
Jeff Brownec083212013-09-11 20:45:25 -07001380 private void clearPendingProximityDebounceTime() {
1381 if (mPendingProximityDebounceTime >= 0) {
1382 mPendingProximityDebounceTime = -1;
Jeff Brown131206b2014-04-08 17:27:14 -07001383 mCallbacks.releaseSuspendBlocker(); // release wake lock
Jeff Brownec083212013-09-11 20:45:25 -07001384 }
1385 }
1386
1387 private void setPendingProximityDebounceTime(long debounceTime) {
1388 if (mPendingProximityDebounceTime < 0) {
Jeff Brown131206b2014-04-08 17:27:14 -07001389 mCallbacks.acquireSuspendBlocker(); // acquire wake lock
Jeff Brownec083212013-09-11 20:45:25 -07001390 }
1391 mPendingProximityDebounceTime = debounceTime;
1392 }
1393
Jeff Brownec083212013-09-11 20:45:25 -07001394 private void sendOnStateChangedWithWakelock() {
Jeff Brown131206b2014-04-08 17:27:14 -07001395 mCallbacks.acquireSuspendBlocker();
1396 mHandler.post(mOnStateChangedRunnable);
Jeff Brown96307042012-07-27 15:51:34 -07001397 }
1398
Michael Wrightd8460232018-01-16 18:04:59 +00001399 private void handleSettingsChange() {
1400 mPendingScreenBrightnessSetting = getScreenBrightnessSetting();
1401 mPendingAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting();
1402 // We don't bother with a pending variable for VR screen brightness since we just
1403 // immediately adapt to it.
1404 mScreenBrightnessForVr = getScreenBrightnessForVrSetting();
1405 sendUpdatePowerState();
1406 }
1407
1408 private float getAutoBrightnessAdjustmentSetting() {
1409 final float adj = Settings.System.getFloatForUser(mContext.getContentResolver(),
1410 Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f, UserHandle.USER_CURRENT);
1411 return Float.isNaN(adj) ? 0.0f : clampAutoBrightnessAdjustment(adj);
1412 }
1413
1414 private int getScreenBrightnessSetting() {
1415 final int brightness = Settings.System.getIntForUser(mContext.getContentResolver(),
1416 Settings.System.SCREEN_BRIGHTNESS, mScreenBrightnessDefault,
1417 UserHandle.USER_CURRENT);
1418 return clampAbsoluteBrightness(brightness);
1419 }
1420
1421 private int getScreenBrightnessForVrSetting() {
1422 final int brightness = Settings.System.getIntForUser(mContext.getContentResolver(),
1423 Settings.System.SCREEN_BRIGHTNESS_FOR_VR, mScreenBrightnessForVrDefault,
1424 UserHandle.USER_CURRENT);
1425 return clampAbsoluteBrightness(brightness);
1426 }
1427
1428 private void putScreenBrightnessSetting(int brightness) {
1429 mCurrentScreenBrightnessSetting = brightness;
1430 Settings.System.putIntForUser(mContext.getContentResolver(),
1431 Settings.System.SCREEN_BRIGHTNESS, brightness,
1432 UserHandle.USER_CURRENT);
1433 }
1434
1435 private boolean updateAutoBrightnessAdjustment() {
1436 if (Float.isNaN(mPendingAutoBrightnessAdjustment)) {
1437 return false;
1438 }
1439 if (mAutoBrightnessAdjustment == mPendingAutoBrightnessAdjustment) {
1440 return false;
1441 }
1442 mAutoBrightnessAdjustment = mPendingAutoBrightnessAdjustment;
1443 mPendingAutoBrightnessAdjustment = Float.NaN;
1444 return true;
1445 }
1446
1447 private boolean updateUserSetScreenBrightness() {
1448 if (mPendingScreenBrightnessSetting < 0) {
1449 return false;
1450 }
1451 if (mCurrentScreenBrightnessSetting == mPendingScreenBrightnessSetting) {
1452 return false;
1453 }
1454 mLastUserSetScreenBrightness = mPendingScreenBrightnessSetting;
1455 mPendingScreenBrightnessSetting = -1;
1456 return true;
1457 }
1458
1459 private void notifyBrightnessChanged(int brightness, boolean userInitiated) {
1460 final float brightnessInNits = convertToNits(brightness);
1461 if (brightnessInNits >= 0.0f) {
1462 // We only want to track changes on devices that can actually map the display backlight
1463 // values into a physical brightness unit since the value provided by the API is in
1464 // nits and not using the arbitrary backlight units.
1465 mBrightnessTracker.notifyBrightnessChanged(brightnessInNits, userInitiated);
1466 }
1467 }
1468
1469 private float convertToNits(int backlight) {
Michael Wright144aac92017-12-21 18:37:41 +00001470 if (mBrightnessMapper != null) {
Michael Wrightd8460232018-01-16 18:04:59 +00001471 return mBrightnessMapper.convertToNits(backlight);
Michael Wright144aac92017-12-21 18:37:41 +00001472 } else {
1473 return -1.0f;
1474 }
1475 }
1476
Jeff Brown96307042012-07-27 15:51:34 -07001477 private final Runnable mOnStateChangedRunnable = new Runnable() {
1478 @Override
1479 public void run() {
1480 mCallbacks.onStateChanged();
Jeff Brown131206b2014-04-08 17:27:14 -07001481 mCallbacks.releaseSuspendBlocker();
Jeff Brown96307042012-07-27 15:51:34 -07001482 }
1483 };
1484
Jeff Brownec083212013-09-11 20:45:25 -07001485 private void sendOnProximityPositiveWithWakelock() {
Jeff Brown131206b2014-04-08 17:27:14 -07001486 mCallbacks.acquireSuspendBlocker();
1487 mHandler.post(mOnProximityPositiveRunnable);
Jeff Brown93cbbb22012-10-04 13:18:36 -07001488 }
1489
1490 private final Runnable mOnProximityPositiveRunnable = new Runnable() {
1491 @Override
1492 public void run() {
1493 mCallbacks.onProximityPositive();
Jeff Brown131206b2014-04-08 17:27:14 -07001494 mCallbacks.releaseSuspendBlocker();
Jeff Brown93cbbb22012-10-04 13:18:36 -07001495 }
1496 };
1497
Jeff Brownec083212013-09-11 20:45:25 -07001498 private void sendOnProximityNegativeWithWakelock() {
Jeff Brown131206b2014-04-08 17:27:14 -07001499 mCallbacks.acquireSuspendBlocker();
1500 mHandler.post(mOnProximityNegativeRunnable);
Jeff Brown96307042012-07-27 15:51:34 -07001501 }
1502
1503 private final Runnable mOnProximityNegativeRunnable = new Runnable() {
1504 @Override
1505 public void run() {
1506 mCallbacks.onProximityNegative();
Jeff Brown131206b2014-04-08 17:27:14 -07001507 mCallbacks.releaseSuspendBlocker();
Jeff Brown96307042012-07-27 15:51:34 -07001508 }
1509 };
1510
Jeff Brownbd6e1502012-08-28 03:27:37 -07001511 public void dump(final PrintWriter pw) {
Jeff Brown96307042012-07-27 15:51:34 -07001512 synchronized (mLock) {
1513 pw.println();
Jeff Brown131206b2014-04-08 17:27:14 -07001514 pw.println("Display Power Controller Locked State:");
Jeff Brown96307042012-07-27 15:51:34 -07001515 pw.println(" mDisplayReadyLocked=" + mDisplayReadyLocked);
1516 pw.println(" mPendingRequestLocked=" + mPendingRequestLocked);
1517 pw.println(" mPendingRequestChangedLocked=" + mPendingRequestChangedLocked);
1518 pw.println(" mPendingWaitForNegativeProximityLocked="
1519 + mPendingWaitForNegativeProximityLocked);
1520 pw.println(" mPendingUpdatePowerStateLocked=" + mPendingUpdatePowerStateLocked);
1521 }
1522
1523 pw.println();
Jeff Brown131206b2014-04-08 17:27:14 -07001524 pw.println("Display Power Controller Configuration:");
Jeff Brown26875502014-01-30 21:47:47 -08001525 pw.println(" mScreenBrightnessDozeConfig=" + mScreenBrightnessDozeConfig);
Jeff Brown96307042012-07-27 15:51:34 -07001526 pw.println(" mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig);
Jeff Brownb76eebff2012-10-05 22:26:44 -07001527 pw.println(" mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum);
1528 pw.println(" mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum);
Jeff Brown2175e9c2014-09-12 16:11:07 -07001529 pw.println(" mUseSoftwareAutoBrightnessConfig=" + mUseSoftwareAutoBrightnessConfig);
Filip Gruszczynskia15aa7d2014-10-28 14:12:40 -07001530 pw.println(" mAllowAutoBrightnessWhileDozingConfig=" +
1531 mAllowAutoBrightnessWhileDozingConfig);
Jeff Brown2175e9c2014-09-12 16:11:07 -07001532 pw.println(" mColorFadeFadesConfig=" + mColorFadeFadesConfig);
Jeff Brown96307042012-07-27 15:51:34 -07001533
Jeff Brownbd6e1502012-08-28 03:27:37 -07001534 mHandler.runWithScissors(new Runnable() {
1535 @Override
1536 public void run() {
1537 dumpLocal(pw);
Jeff Brown96307042012-07-27 15:51:34 -07001538 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001539 }, 1000);
Jeff Brown96307042012-07-27 15:51:34 -07001540 }
1541
1542 private void dumpLocal(PrintWriter pw) {
1543 pw.println();
Jeff Brown131206b2014-04-08 17:27:14 -07001544 pw.println("Display Power Controller Thread State:");
Jeff Brown96307042012-07-27 15:51:34 -07001545 pw.println(" mPowerRequest=" + mPowerRequest);
1546 pw.println(" mWaitingForNegativeProximity=" + mWaitingForNegativeProximity);
Jeff Brown96307042012-07-27 15:51:34 -07001547 pw.println(" mProximitySensor=" + mProximitySensor);
1548 pw.println(" mProximitySensorEnabled=" + mProximitySensorEnabled);
1549 pw.println(" mProximityThreshold=" + mProximityThreshold);
1550 pw.println(" mProximity=" + proximityToString(mProximity));
1551 pw.println(" mPendingProximity=" + proximityToString(mPendingProximity));
1552 pw.println(" mPendingProximityDebounceTime="
1553 + TimeUtils.formatUptime(mPendingProximityDebounceTime));
1554 pw.println(" mScreenOffBecauseOfProximity=" + mScreenOffBecauseOfProximity);
Michael Wrightd8460232018-01-16 18:04:59 +00001555 pw.println(" mLastUserSetScreenBrightness=" + mLastUserSetScreenBrightness);
1556 pw.println(" mCurrentScreenBrightnessSetting=" + mCurrentScreenBrightnessSetting);
1557 pw.println(" mPendingScreenBrightnessSetting=" + mPendingScreenBrightnessSetting);
1558 pw.println(" mAutoBrightnessAdjustment=" + mAutoBrightnessAdjustment);
1559 pw.println(" mPendingAutoBrightnessAdjustment=" + mPendingAutoBrightnessAdjustment);
Jeff Brown970d4132014-07-19 11:33:47 -07001560 pw.println(" mAppliedAutoBrightness=" + mAppliedAutoBrightness);
1561 pw.println(" mAppliedDimming=" + mAppliedDimming);
1562 pw.println(" mAppliedLowPower=" + mAppliedLowPower);
Jeff Brown3ee549c2014-09-22 20:14:39 -07001563 pw.println(" mPendingScreenOnUnblocker=" + mPendingScreenOnUnblocker);
1564 pw.println(" mPendingScreenOff=" + mPendingScreenOff);
Michael Wrightc3e6af82017-07-25 22:31:03 +01001565 pw.println(" mReportedToPolicy=" +
1566 reportedToPolicyToString(mReportedScreenStateToPolicy));
Jeff Brown96307042012-07-27 15:51:34 -07001567
Jeff Brown42558692014-05-20 22:02:46 -07001568 pw.println(" mScreenBrightnessRampAnimator.isAnimating()=" +
1569 mScreenBrightnessRampAnimator.isAnimating());
1570
Michael Lentine0839adb2014-07-29 18:47:56 -07001571 if (mColorFadeOnAnimator != null) {
1572 pw.println(" mColorFadeOnAnimator.isStarted()=" +
1573 mColorFadeOnAnimator.isStarted());
Jeff Brown96307042012-07-27 15:51:34 -07001574 }
Michael Lentine0839adb2014-07-29 18:47:56 -07001575 if (mColorFadeOffAnimator != null) {
1576 pw.println(" mColorFadeOffAnimator.isStarted()=" +
1577 mColorFadeOffAnimator.isStarted());
Jeff Brown96307042012-07-27 15:51:34 -07001578 }
1579
1580 if (mPowerState != null) {
1581 mPowerState.dump(pw);
1582 }
Michael Wright639c8be2014-01-17 18:29:12 -08001583
1584 if (mAutomaticBrightnessController != null) {
1585 mAutomaticBrightnessController.dump(pw);
1586 }
1587
Michael Wright144aac92017-12-21 18:37:41 +00001588 if (mBrightnessTracker != null) {
1589 pw.println();
1590 mBrightnessTracker.dump(pw);
1591 }
Jeff Brown96307042012-07-27 15:51:34 -07001592 }
1593
1594 private static String proximityToString(int state) {
1595 switch (state) {
1596 case PROXIMITY_UNKNOWN:
1597 return "Unknown";
1598 case PROXIMITY_NEGATIVE:
1599 return "Negative";
1600 case PROXIMITY_POSITIVE:
1601 return "Positive";
1602 default:
1603 return Integer.toString(state);
1604 }
1605 }
1606
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001607 private static String reportedToPolicyToString(int state) {
1608 switch (state) {
1609 case REPORTED_TO_POLICY_SCREEN_OFF:
1610 return "REPORTED_TO_POLICY_SCREEN_OFF";
1611 case REPORTED_TO_POLICY_SCREEN_TURNING_ON:
1612 return "REPORTED_TO_POLICY_SCREEN_TURNING_ON";
1613 case REPORTED_TO_POLICY_SCREEN_ON:
1614 return "REPORTED_TO_POLICY_SCREEN_ON";
1615 default:
1616 return Integer.toString(state);
1617 }
1618 }
1619
Michael Wright639c8be2014-01-17 18:29:12 -08001620 private static int clampAbsoluteBrightness(int value) {
1621 return MathUtils.constrain(value, PowerManager.BRIGHTNESS_OFF, PowerManager.BRIGHTNESS_ON);
Jeff Brown96307042012-07-27 15:51:34 -07001622 }
1623
Michael Wrightd8460232018-01-16 18:04:59 +00001624 private static float clampAutoBrightnessAdjustment(float value) {
1625 return MathUtils.constrain(value, -1.0f, 1.0f);
1626 }
1627
Jeff Brown96307042012-07-27 15:51:34 -07001628 private final class DisplayControllerHandler extends Handler {
1629 public DisplayControllerHandler(Looper looper) {
Jeff Browna2910d02012-08-25 12:29:46 -07001630 super(looper, null, true /*async*/);
Jeff Brown96307042012-07-27 15:51:34 -07001631 }
1632
1633 @Override
1634 public void handleMessage(Message msg) {
1635 switch (msg.what) {
1636 case MSG_UPDATE_POWER_STATE:
1637 updatePowerState();
1638 break;
1639
1640 case MSG_PROXIMITY_SENSOR_DEBOUNCED:
1641 debounceProximitySensor();
1642 break;
Jeff Brown3ee549c2014-09-22 20:14:39 -07001643
1644 case MSG_SCREEN_ON_UNBLOCKED:
1645 if (mPendingScreenOnUnblocker == msg.obj) {
1646 unblockScreenOn();
1647 updatePowerState();
1648 }
1649 break;
Jorim Jaggi51304d72017-05-17 17:25:32 +02001650 case MSG_SCREEN_OFF_UNBLOCKED:
1651 if (mPendingScreenOffUnblocker == msg.obj) {
1652 unblockScreenOff();
1653 updatePowerState();
1654 }
1655 break;
Michael Wrighteef0e132017-11-21 17:57:52 +00001656 case MSG_CONFIGURE_BRIGHTNESS:
Michael Wrightd5df3612018-01-02 12:44:52 +00001657 mBrightnessConfiguration = (BrightnessConfiguration)msg.obj;
Michael Wrighteef0e132017-11-21 17:57:52 +00001658 updatePowerState();
1659 break;
Michael Wrightd8460232018-01-16 18:04:59 +00001660
1661 case MSG_SET_TEMPORARY_BRIGHTNESS:
1662 // TODO: Should we have a a timeout for the temporary brightness?
1663 mTemporaryScreenBrightness = msg.arg1;
1664 updatePowerState();
1665 break;
1666
1667 case MSG_SET_TEMPORARY_AUTO_BRIGHTNESS_ADJUSTMENT:
1668 mTemporaryAutoBrightnessAdjustment = Float.intBitsToFloat(msg.arg1);
1669 updatePowerState();
1670 break;
Jeff Brown96307042012-07-27 15:51:34 -07001671 }
1672 }
1673 }
1674
1675 private final SensorEventListener mProximitySensorListener = new SensorEventListener() {
1676 @Override
1677 public void onSensorChanged(SensorEvent event) {
1678 if (mProximitySensorEnabled) {
1679 final long time = SystemClock.uptimeMillis();
1680 final float distance = event.values[0];
1681 boolean positive = distance >= 0.0f && distance < mProximityThreshold;
1682 handleProximitySensorEvent(time, positive);
1683 }
1684 }
1685
1686 @Override
1687 public void onAccuracyChanged(Sensor sensor, int accuracy) {
1688 // Not used.
1689 }
1690 };
Jeff Brown3ee549c2014-09-22 20:14:39 -07001691
Michael Wrightd8460232018-01-16 18:04:59 +00001692
1693 private final class SettingsObserver extends ContentObserver {
1694 public SettingsObserver(Handler handler) {
1695 super(handler);
1696 }
1697
1698 @Override
1699 public void onChange(boolean selfChange, Uri uri) {
1700 handleSettingsChange();
1701 }
1702 }
1703
Jeff Brown3ee549c2014-09-22 20:14:39 -07001704 private final class ScreenOnUnblocker implements WindowManagerPolicy.ScreenOnListener {
1705 @Override
1706 public void onScreenOn() {
1707 Message msg = mHandler.obtainMessage(MSG_SCREEN_ON_UNBLOCKED, this);
Jeff Brown3ee549c2014-09-22 20:14:39 -07001708 mHandler.sendMessage(msg);
1709 }
1710 }
Jorim Jaggi51304d72017-05-17 17:25:32 +02001711
1712 private final class ScreenOffUnblocker implements WindowManagerPolicy.ScreenOffListener {
Jorim Jaggi51304d72017-05-17 17:25:32 +02001713 @Override
1714 public void onScreenOff() {
1715 Message msg = mHandler.obtainMessage(MSG_SCREEN_OFF_UNBLOCKED, this);
Jorim Jaggi51304d72017-05-17 17:25:32 +02001716 mHandler.sendMessage(msg);
1717 }
1718 }
Jeff Brown96307042012-07-27 15:51:34 -07001719}