• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package com.android.server.display;
18 
19 import android.animation.Animator;
20 import android.animation.ObjectAnimator;
21 import android.annotation.Nullable;
22 import android.annotation.UserIdInt;
23 import android.app.ActivityManager;
24 import android.content.Context;
25 import android.content.pm.ParceledListSlice;
26 import android.content.res.Resources;
27 import android.database.ContentObserver;
28 import android.hardware.Sensor;
29 import android.hardware.SensorEvent;
30 import android.hardware.SensorEventListener;
31 import android.hardware.SensorManager;
32 import android.hardware.display.AmbientBrightnessDayStats;
33 import android.hardware.display.BrightnessChangeEvent;
34 import android.hardware.display.BrightnessConfiguration;
35 import android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks;
36 import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
37 import android.metrics.LogMaker;
38 import android.net.Uri;
39 import android.os.Handler;
40 import android.os.Looper;
41 import android.os.Message;
42 import android.os.PowerManager;
43 import android.os.RemoteException;
44 import android.os.SystemClock;
45 import android.os.Trace;
46 import android.os.UserHandle;
47 import android.provider.Settings;
48 import android.text.TextUtils;
49 import android.util.MathUtils;
50 import android.util.Slog;
51 import android.util.TimeUtils;
52 import android.view.Display;
53 
54 import com.android.internal.app.IBatteryStats;
55 import com.android.internal.logging.MetricsLogger;
56 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
57 import com.android.server.LocalServices;
58 import com.android.server.am.BatteryStatsService;
59 import com.android.server.display.whitebalance.DisplayWhiteBalanceController;
60 import com.android.server.display.whitebalance.DisplayWhiteBalanceFactory;
61 import com.android.server.display.whitebalance.DisplayWhiteBalanceSettings;
62 import com.android.server.policy.WindowManagerPolicy;
63 
64 import java.io.PrintWriter;
65 import java.util.List;
66 
67 /**
68  * Controls the power state of the display.
69  *
70  * Handles the proximity sensor, light sensor, and animations between states
71  * including the screen off animation.
72  *
73  * This component acts independently of the rest of the power manager service.
74  * In particular, it does not share any state and it only communicates
75  * via asynchronous callbacks to inform the power manager that something has
76  * changed.
77  *
78  * Everything this class does internally is serialized on its handler although
79  * it may be accessed by other threads from the outside.
80  *
81  * Note that the power manager service guarantees that it will hold a suspend
82  * blocker as long as the display is not ready.  So most of the work done here
83  * does not need to worry about holding a suspend blocker unless it happens
84  * independently of the display ready signal.
85    *
86  * For debugging, you can make the color fade and brightness animations run
87  * slower by changing the "animator duration scale" option in Development Settings.
88  */
89 final class DisplayPowerController implements AutomaticBrightnessController.Callbacks,
90         DisplayWhiteBalanceController.Callbacks {
91     private static final String TAG = "DisplayPowerController";
92     private static final String SCREEN_ON_BLOCKED_TRACE_NAME = "Screen on blocked";
93     private static final String SCREEN_OFF_BLOCKED_TRACE_NAME = "Screen off blocked";
94 
95     private static final boolean DEBUG = false;
96     private static final boolean DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT = false;
97 
98     // If true, uses the color fade on animation.
99     // We might want to turn this off if we cannot get a guarantee that the screen
100     // actually turns on and starts showing new content after the call to set the
101     // screen state returns.  Playing the animation can also be somewhat slow.
102     private static final boolean USE_COLOR_FADE_ON_ANIMATION = false;
103 
104     // The minimum reduction in brightness when dimmed.
105     private static final int SCREEN_DIM_MINIMUM_REDUCTION = 10;
106 
107     private static final int COLOR_FADE_ON_ANIMATION_DURATION_MILLIS = 250;
108     private static final int COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS = 400;
109 
110     private static final int MSG_UPDATE_POWER_STATE = 1;
111     private static final int MSG_PROXIMITY_SENSOR_DEBOUNCED = 2;
112     private static final int MSG_SCREEN_ON_UNBLOCKED = 3;
113     private static final int MSG_SCREEN_OFF_UNBLOCKED = 4;
114     private static final int MSG_CONFIGURE_BRIGHTNESS = 5;
115     private static final int MSG_SET_TEMPORARY_BRIGHTNESS = 6;
116     private static final int MSG_SET_TEMPORARY_AUTO_BRIGHTNESS_ADJUSTMENT = 7;
117 
118     private static final int PROXIMITY_UNKNOWN = -1;
119     private static final int PROXIMITY_NEGATIVE = 0;
120     private static final int PROXIMITY_POSITIVE = 1;
121 
122     // Proximity sensor debounce delay in milliseconds for positive or negative transitions.
123     private static final int PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY = 0;
124     private static final int PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY = 250;
125 
126     // Trigger proximity if distance is less than 5 cm.
127     private static final float TYPICAL_PROXIMITY_THRESHOLD = 5.0f;
128 
129     // State machine constants for tracking initial brightness ramp skipping when enabled.
130     private static final int RAMP_STATE_SKIP_NONE = 0;
131     private static final int RAMP_STATE_SKIP_INITIAL = 1;
132     private static final int RAMP_STATE_SKIP_AUTOBRIGHT = 2;
133 
134     private static final int REPORTED_TO_POLICY_SCREEN_OFF = 0;
135     private static final int REPORTED_TO_POLICY_SCREEN_TURNING_ON = 1;
136     private static final int REPORTED_TO_POLICY_SCREEN_ON = 2;
137     private static final int REPORTED_TO_POLICY_SCREEN_TURNING_OFF = 3;
138 
139     private final Object mLock = new Object();
140 
141     private final Context mContext;
142 
143     // Our handler.
144     private final DisplayControllerHandler mHandler;
145 
146     // Asynchronous callbacks into the power manager service.
147     // Only invoked from the handler thread while no locks are held.
148     private final DisplayPowerCallbacks mCallbacks;
149 
150     // Battery stats.
151     private final IBatteryStats mBatteryStats;
152 
153     // The sensor manager.
154     private final SensorManager mSensorManager;
155 
156     // The window manager policy.
157     private final WindowManagerPolicy mWindowManagerPolicy;
158 
159     // The display blanker.
160     private final DisplayBlanker mBlanker;
161 
162     // Tracker for brightness changes.
163     private final BrightnessTracker mBrightnessTracker;
164 
165     // Tracker for brightness settings changes.
166     private final SettingsObserver mSettingsObserver;
167 
168     // The proximity sensor, or null if not available or needed.
169     private Sensor mProximitySensor;
170 
171     // The doze screen brightness.
172     private final int mScreenBrightnessDozeConfig;
173 
174     // The dim screen brightness.
175     private final int mScreenBrightnessDimConfig;
176 
177     // The minimum allowed brightness.
178     private final int mScreenBrightnessRangeMinimum;
179 
180     // The maximum allowed brightness.
181     private final int mScreenBrightnessRangeMaximum;
182 
183     // The default screen brightness.
184     private final int mScreenBrightnessDefault;
185 
186     // The minimum allowed brightness while in VR.
187     private final int mScreenBrightnessForVrRangeMinimum;
188 
189     // The maximum allowed brightness while in VR.
190     private final int mScreenBrightnessForVrRangeMaximum;
191 
192     // The default screen brightness for VR.
193     private final int mScreenBrightnessForVrDefault;
194 
195     // True if auto-brightness should be used.
196     private boolean mUseSoftwareAutoBrightnessConfig;
197 
198     // True if should use light sensor to automatically determine doze screen brightness.
199     private final boolean mAllowAutoBrightnessWhileDozingConfig;
200 
201     // Whether or not the color fade on screen on / off is enabled.
202     private final boolean mColorFadeEnabled;
203 
204     // True if we should fade the screen while turning it off, false if we should play
205     // a stylish color fade animation instead.
206     private boolean mColorFadeFadesConfig;
207 
208     // True if we need to fake a transition to off when coming out of a doze state.
209     // Some display hardware will blank itself when coming out of doze in order to hide
210     // artifacts. For these displays we fake a transition into OFF so that policy can appropriately
211     // blank itself and begin an appropriate power on animation.
212     private boolean mDisplayBlanksAfterDozeConfig;
213 
214     // True if there are only buckets of brightness values when the display is in the doze state,
215     // rather than a full range of values. If this is true, then we'll avoid animating the screen
216     // brightness since it'd likely be multiple jarring brightness transitions instead of just one
217     // to reach the final state.
218     private boolean mBrightnessBucketsInDozeConfig;
219 
220     // The pending power request.
221     // Initially null until the first call to requestPowerState.
222     // Guarded by mLock.
223     private DisplayPowerRequest mPendingRequestLocked;
224 
225     // True if a request has been made to wait for the proximity sensor to go negative.
226     // Guarded by mLock.
227     private boolean mPendingWaitForNegativeProximityLocked;
228 
229     // True if the pending power request or wait for negative proximity flag
230     // has been changed since the last update occurred.
231     // Guarded by mLock.
232     private boolean mPendingRequestChangedLocked;
233 
234     // Set to true when the important parts of the pending power request have been applied.
235     // The important parts are mainly the screen state.  Brightness changes may occur
236     // concurrently.
237     // Guarded by mLock.
238     private boolean mDisplayReadyLocked;
239 
240     // Set to true if a power state update is required.
241     // Guarded by mLock.
242     private boolean mPendingUpdatePowerStateLocked;
243 
244     /* The following state must only be accessed by the handler thread. */
245 
246     // The currently requested power state.
247     // The power controller will progressively update its internal state to match
248     // the requested power state.  Initially null until the first update.
249     private DisplayPowerRequest mPowerRequest;
250 
251     // The current power state.
252     // Must only be accessed on the handler thread.
253     private DisplayPowerState mPowerState;
254 
255     // True if the device should wait for negative proximity sensor before
256     // waking up the screen.  This is set to false as soon as a negative
257     // proximity sensor measurement is observed or when the device is forced to
258     // go to sleep by the user.  While true, the screen remains off.
259     private boolean mWaitingForNegativeProximity;
260 
261     // The actual proximity sensor threshold value.
262     private float mProximityThreshold;
263 
264     // Set to true if the proximity sensor listener has been registered
265     // with the sensor manager.
266     private boolean mProximitySensorEnabled;
267 
268     // The debounced proximity sensor state.
269     private int mProximity = PROXIMITY_UNKNOWN;
270 
271     // The raw non-debounced proximity sensor state.
272     private int mPendingProximity = PROXIMITY_UNKNOWN;
273     private long mPendingProximityDebounceTime = -1; // -1 if fully debounced
274 
275     // True if the screen was turned off because of the proximity sensor.
276     // When the screen turns on again, we report user activity to the power manager.
277     private boolean mScreenOffBecauseOfProximity;
278 
279     // The currently active screen on unblocker.  This field is non-null whenever
280     // we are waiting for a callback to release it and unblock the screen.
281     private ScreenOnUnblocker mPendingScreenOnUnblocker;
282     private ScreenOffUnblocker mPendingScreenOffUnblocker;
283 
284     // True if we were in the process of turning off the screen.
285     // This allows us to recover more gracefully from situations where we abort
286     // turning off the screen.
287     private boolean mPendingScreenOff;
288 
289     // True if we have unfinished business and are holding a suspend blocker.
290     private boolean mUnfinishedBusiness;
291 
292     // The elapsed real time when the screen on was blocked.
293     private long mScreenOnBlockStartRealTime;
294     private long mScreenOffBlockStartRealTime;
295 
296     // Screen state we reported to policy. Must be one of REPORTED_TO_POLICY_SCREEN_* fields.
297     private int mReportedScreenStateToPolicy;
298 
299     // If the last recorded screen state was dozing or not.
300     private boolean mDozing;
301 
302     // Remembers whether certain kinds of brightness adjustments
303     // were recently applied so that we can decide how to transition.
304     private boolean mAppliedAutoBrightness;
305     private boolean mAppliedDimming;
306     private boolean mAppliedLowPower;
307     private boolean mAppliedScreenBrightnessOverride;
308     private boolean mAppliedTemporaryBrightness;
309     private boolean mAppliedTemporaryAutoBrightnessAdjustment;
310     private boolean mAppliedBrightnessBoost;
311 
312     // Reason for which the brightness was last changed. See {@link BrightnessReason} for more
313     // information.
314     // At the time of this writing, this value is changed within updatePowerState() only, which is
315     // limited to the thread used by DisplayControllerHandler.
316     private BrightnessReason mBrightnessReason = new BrightnessReason();
317     private BrightnessReason mBrightnessReasonTemp = new BrightnessReason();
318 
319     // Brightness animation ramp rates in brightness units per second
320     private final int mBrightnessRampRateFast;
321     private final int mBrightnessRampRateSlow;
322 
323     // Whether or not to skip the initial brightness ramps into STATE_ON.
324     private final boolean mSkipScreenOnBrightnessRamp;
325 
326     // Display white balance components.
327     @Nullable
328     private final DisplayWhiteBalanceSettings mDisplayWhiteBalanceSettings;
329     @Nullable
330     private final DisplayWhiteBalanceController mDisplayWhiteBalanceController;
331 
332     // A record of state for skipping brightness ramps.
333     private int mSkipRampState = RAMP_STATE_SKIP_NONE;
334 
335     // The first autobrightness value set when entering RAMP_STATE_SKIP_INITIAL.
336     private int mInitialAutoBrightness;
337 
338     // The controller for the automatic brightness level.
339     private AutomaticBrightnessController mAutomaticBrightnessController;
340 
341     // The mapper between ambient lux, display backlight values, and display brightness.
342     @Nullable
343     private BrightnessMappingStrategy mBrightnessMapper;
344 
345     // The current brightness configuration.
346     @Nullable
347     private BrightnessConfiguration mBrightnessConfiguration;
348 
349     // The last brightness that was set by the user and not temporary. Set to -1 when a brightness
350     // has yet to be recorded.
351     private int mLastUserSetScreenBrightness;
352 
353     // The screen brightenss setting has changed but not taken effect yet. If this is different
354     // from the current screen brightness setting then this is coming from something other than us
355     // and should be considered a user interaction.
356     private int mPendingScreenBrightnessSetting;
357 
358     // The last observed screen brightness setting, either set by us or by the settings app on
359     // behalf of the user.
360     private int mCurrentScreenBrightnessSetting;
361 
362     // The temporary screen brightness. Typically set when a user is interacting with the
363     // brightness slider but hasn't settled on a choice yet. Set to -1 when there's no temporary
364     // brightness set.
365     private int mTemporaryScreenBrightness;
366 
367     // The current screen brightness while in VR mode.
368     private int mScreenBrightnessForVr;
369 
370     // The last auto brightness adjustment that was set by the user and not temporary. Set to
371     // Float.NaN when an auto-brightness adjustment hasn't been recorded yet.
372     private float mAutoBrightnessAdjustment;
373 
374     // The pending auto brightness adjustment that will take effect on the next power state update.
375     private float mPendingAutoBrightnessAdjustment;
376 
377     // The temporary auto brightness adjustment. Typically set when a user is interacting with the
378     // adjustment slider but hasn't settled on a choice yet. Set to Float.NaN when there's no
379     // temporary adjustment set.
380     private float mTemporaryAutoBrightnessAdjustment;
381 
382     // Animators.
383     private ObjectAnimator mColorFadeOnAnimator;
384     private ObjectAnimator mColorFadeOffAnimator;
385     private RampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator;
386 
387     /**
388      * Creates the display power controller.
389      */
DisplayPowerController(Context context, DisplayPowerCallbacks callbacks, Handler handler, SensorManager sensorManager, DisplayBlanker blanker)390     public DisplayPowerController(Context context,
391             DisplayPowerCallbacks callbacks, Handler handler,
392             SensorManager sensorManager, DisplayBlanker blanker) {
393         mHandler = new DisplayControllerHandler(handler.getLooper());
394         mBrightnessTracker = new BrightnessTracker(context, null);
395         mSettingsObserver = new SettingsObserver(mHandler);
396         mCallbacks = callbacks;
397 
398         mBatteryStats = BatteryStatsService.getService();
399         mSensorManager = sensorManager;
400         mWindowManagerPolicy = LocalServices.getService(WindowManagerPolicy.class);
401         mBlanker = blanker;
402         mContext = context;
403 
404         final Resources resources = context.getResources();
405         final int screenBrightnessSettingMinimum = clampAbsoluteBrightness(resources.getInteger(
406                 com.android.internal.R.integer.config_screenBrightnessSettingMinimum));
407 
408         mScreenBrightnessDozeConfig = clampAbsoluteBrightness(resources.getInteger(
409                 com.android.internal.R.integer.config_screenBrightnessDoze));
410 
411         mScreenBrightnessDimConfig = clampAbsoluteBrightness(resources.getInteger(
412                 com.android.internal.R.integer.config_screenBrightnessDim));
413 
414         mScreenBrightnessRangeMinimum =
415                 Math.min(screenBrightnessSettingMinimum, mScreenBrightnessDimConfig);
416 
417         mScreenBrightnessRangeMaximum = clampAbsoluteBrightness(resources.getInteger(
418                     com.android.internal.R.integer.config_screenBrightnessSettingMaximum));
419         mScreenBrightnessDefault = clampAbsoluteBrightness(resources.getInteger(
420                     com.android.internal.R.integer.config_screenBrightnessSettingDefault));
421 
422         mScreenBrightnessForVrRangeMinimum = clampAbsoluteBrightness(resources.getInteger(
423                     com.android.internal.R.integer.config_screenBrightnessForVrSettingMinimum));
424         mScreenBrightnessForVrRangeMaximum = clampAbsoluteBrightness(resources.getInteger(
425                     com.android.internal.R.integer.config_screenBrightnessForVrSettingMaximum));
426         mScreenBrightnessForVrDefault = clampAbsoluteBrightness(resources.getInteger(
427                     com.android.internal.R.integer.config_screenBrightnessForVrSettingDefault));
428 
429         mUseSoftwareAutoBrightnessConfig = resources.getBoolean(
430                 com.android.internal.R.bool.config_automatic_brightness_available);
431 
432         mAllowAutoBrightnessWhileDozingConfig = resources.getBoolean(
433                 com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing);
434 
435         mBrightnessRampRateFast = resources.getInteger(
436                 com.android.internal.R.integer.config_brightness_ramp_rate_fast);
437         mBrightnessRampRateSlow = resources.getInteger(
438                 com.android.internal.R.integer.config_brightness_ramp_rate_slow);
439         mSkipScreenOnBrightnessRamp = resources.getBoolean(
440                 com.android.internal.R.bool.config_skipScreenOnBrightnessRamp);
441 
442         if (mUseSoftwareAutoBrightnessConfig) {
443             final float dozeScaleFactor = resources.getFraction(
444                     com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor,
445                     1, 1);
446 
447             int[] ambientBrighteningThresholds = resources.getIntArray(
448                     com.android.internal.R.array.config_ambientBrighteningThresholds);
449             int[] ambientDarkeningThresholds = resources.getIntArray(
450                     com.android.internal.R.array.config_ambientDarkeningThresholds);
451             int[] ambientThresholdLevels = resources.getIntArray(
452                     com.android.internal.R.array.config_ambientThresholdLevels);
453             HysteresisLevels ambientBrightnessThresholds = new HysteresisLevels(
454                     ambientBrighteningThresholds, ambientDarkeningThresholds,
455                     ambientThresholdLevels);
456 
457             int[] screenBrighteningThresholds = resources.getIntArray(
458                     com.android.internal.R.array.config_screenBrighteningThresholds);
459             int[] screenDarkeningThresholds = resources.getIntArray(
460                     com.android.internal.R.array.config_screenDarkeningThresholds);
461             int[] screenThresholdLevels = resources.getIntArray(
462                     com.android.internal.R.array.config_screenThresholdLevels);
463             HysteresisLevels screenBrightnessThresholds = new HysteresisLevels(
464                     screenBrighteningThresholds, screenDarkeningThresholds, screenThresholdLevels);
465 
466             long brighteningLightDebounce = resources.getInteger(
467                     com.android.internal.R.integer.config_autoBrightnessBrighteningLightDebounce);
468             long darkeningLightDebounce = resources.getInteger(
469                     com.android.internal.R.integer.config_autoBrightnessDarkeningLightDebounce);
470             boolean autoBrightnessResetAmbientLuxAfterWarmUp = resources.getBoolean(
471                     com.android.internal.R.bool.config_autoBrightnessResetAmbientLuxAfterWarmUp);
472 
473             int lightSensorWarmUpTimeConfig = resources.getInteger(
474                     com.android.internal.R.integer.config_lightSensorWarmupTime);
475             int lightSensorRate = resources.getInteger(
476                     com.android.internal.R.integer.config_autoBrightnessLightSensorRate);
477             int initialLightSensorRate = resources.getInteger(
478                     com.android.internal.R.integer.config_autoBrightnessInitialLightSensorRate);
479             if (initialLightSensorRate == -1) {
480                 initialLightSensorRate = lightSensorRate;
481             } else if (initialLightSensorRate > lightSensorRate) {
482                 Slog.w(TAG, "Expected config_autoBrightnessInitialLightSensorRate ("
483                         + initialLightSensorRate + ") to be less than or equal to "
484                         + "config_autoBrightnessLightSensorRate (" + lightSensorRate + ").");
485             }
486             int shortTermModelTimeout = resources.getInteger(
487                     com.android.internal.R.integer.config_autoBrightnessShortTermModelTimeout);
488 
489             String lightSensorType = resources.getString(
490                     com.android.internal.R.string.config_displayLightSensorType);
491             Sensor lightSensor = findDisplayLightSensor(lightSensorType);
492 
493             mBrightnessMapper = BrightnessMappingStrategy.create(resources);
494             if (mBrightnessMapper != null) {
495                 mAutomaticBrightnessController = new AutomaticBrightnessController(this,
496                         handler.getLooper(), sensorManager, lightSensor, mBrightnessMapper,
497                         lightSensorWarmUpTimeConfig, mScreenBrightnessRangeMinimum,
498                         mScreenBrightnessRangeMaximum, dozeScaleFactor, lightSensorRate,
499                         initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce,
500                         autoBrightnessResetAmbientLuxAfterWarmUp, ambientBrightnessThresholds,
501                         screenBrightnessThresholds, shortTermModelTimeout,
502                         context.getPackageManager());
503             } else {
504                 mUseSoftwareAutoBrightnessConfig = false;
505             }
506         }
507 
508         mColorFadeEnabled = !ActivityManager.isLowRamDeviceStatic();
509         mColorFadeFadesConfig = resources.getBoolean(
510                 com.android.internal.R.bool.config_animateScreenLights);
511 
512         mDisplayBlanksAfterDozeConfig = resources.getBoolean(
513                 com.android.internal.R.bool.config_displayBlanksAfterDoze);
514 
515         mBrightnessBucketsInDozeConfig = resources.getBoolean(
516                 com.android.internal.R.bool.config_displayBrightnessBucketsInDoze);
517 
518         if (!DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) {
519             mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
520             if (mProximitySensor != null) {
521                 mProximityThreshold = Math.min(mProximitySensor.getMaximumRange(),
522                         TYPICAL_PROXIMITY_THRESHOLD);
523             }
524         }
525 
526         mCurrentScreenBrightnessSetting = getScreenBrightnessSetting();
527         mScreenBrightnessForVr = getScreenBrightnessForVrSetting();
528         mAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting();
529         mTemporaryScreenBrightness = -1;
530         mPendingScreenBrightnessSetting = -1;
531         mTemporaryAutoBrightnessAdjustment = Float.NaN;
532         mPendingAutoBrightnessAdjustment = Float.NaN;
533 
534         DisplayWhiteBalanceSettings displayWhiteBalanceSettings = null;
535         DisplayWhiteBalanceController displayWhiteBalanceController = null;
536         try {
537             displayWhiteBalanceSettings = new DisplayWhiteBalanceSettings(mContext, mHandler);
538             displayWhiteBalanceController = DisplayWhiteBalanceFactory.create(mHandler,
539                     mSensorManager, resources);
540             displayWhiteBalanceSettings.setCallbacks(this);
541             displayWhiteBalanceController.setCallbacks(this);
542         } catch (Exception e) {
543             Slog.e(TAG, "failed to set up display white-balance: " + e);
544         }
545         mDisplayWhiteBalanceSettings = displayWhiteBalanceSettings;
546         mDisplayWhiteBalanceController = displayWhiteBalanceController;
547     }
548 
findDisplayLightSensor(String sensorType)549     private Sensor findDisplayLightSensor(String sensorType) {
550         if (!TextUtils.isEmpty(sensorType)) {
551             List<Sensor> sensors = mSensorManager.getSensorList(Sensor.TYPE_ALL);
552             for (int i = 0; i < sensors.size(); i++) {
553                 Sensor sensor = sensors.get(i);
554                 if (sensorType.equals(sensor.getStringType())) {
555                     return sensor;
556                 }
557             }
558         }
559         return mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
560     }
561 
562     /**
563      * Returns true if the proximity sensor screen-off function is available.
564      */
isProximitySensorAvailable()565     public boolean isProximitySensorAvailable() {
566         return mProximitySensor != null;
567     }
568 
569     /**
570      * Get the {@link BrightnessChangeEvent}s for the specified user.
571      * @param userId userId to fetch data for
572      * @param includePackage if false will null out the package name in events
573      */
getBrightnessEvents( @serIdInt int userId, boolean includePackage)574     public ParceledListSlice<BrightnessChangeEvent> getBrightnessEvents(
575             @UserIdInt int userId, boolean includePackage) {
576         return mBrightnessTracker.getEvents(userId, includePackage);
577     }
578 
onSwitchUser(@serIdInt int newUserId)579     public void onSwitchUser(@UserIdInt int newUserId) {
580         handleSettingsChange(true /* userSwitch */);
581         mBrightnessTracker.onSwitchUser(newUserId);
582     }
583 
getAmbientBrightnessStats( @serIdInt int userId)584     public ParceledListSlice<AmbientBrightnessDayStats> getAmbientBrightnessStats(
585             @UserIdInt int userId) {
586         return mBrightnessTracker.getAmbientBrightnessStats(userId);
587     }
588 
589     /**
590      * Persist the brightness slider events and ambient brightness stats to disk.
591      */
persistBrightnessTrackerState()592     public void persistBrightnessTrackerState() {
593         mBrightnessTracker.persistBrightnessTrackerState();
594     }
595 
596     /**
597      * Requests a new power state.
598      * The controller makes a copy of the provided object and then
599      * begins adjusting the power state to match what was requested.
600      *
601      * @param request The requested power state.
602      * @param waitForNegativeProximity If true, issues a request to wait for
603      * negative proximity before turning the screen back on, assuming the screen
604      * was turned off by the proximity sensor.
605      * @return True if display is ready, false if there are important changes that must
606      * be made asynchronously (such as turning the screen on), in which case the caller
607      * should grab a wake lock, watch for {@link DisplayPowerCallbacks#onStateChanged()}
608      * then try the request again later until the state converges.
609      */
requestPowerState(DisplayPowerRequest request, boolean waitForNegativeProximity)610     public boolean requestPowerState(DisplayPowerRequest request,
611             boolean waitForNegativeProximity) {
612         if (DEBUG) {
613             Slog.d(TAG, "requestPowerState: "
614                     + request + ", waitForNegativeProximity=" + waitForNegativeProximity);
615         }
616 
617         synchronized (mLock) {
618             boolean changed = false;
619 
620             if (waitForNegativeProximity
621                     && !mPendingWaitForNegativeProximityLocked) {
622                 mPendingWaitForNegativeProximityLocked = true;
623                 changed = true;
624             }
625 
626             if (mPendingRequestLocked == null) {
627                 mPendingRequestLocked = new DisplayPowerRequest(request);
628                 changed = true;
629             } else if (!mPendingRequestLocked.equals(request)) {
630                 mPendingRequestLocked.copyFrom(request);
631                 changed = true;
632             }
633 
634             if (changed) {
635                 mDisplayReadyLocked = false;
636             }
637 
638             if (changed && !mPendingRequestChangedLocked) {
639                 mPendingRequestChangedLocked = true;
640                 sendUpdatePowerStateLocked();
641             }
642 
643             return mDisplayReadyLocked;
644         }
645     }
646 
getDefaultBrightnessConfiguration()647     public BrightnessConfiguration getDefaultBrightnessConfiguration() {
648         if (mAutomaticBrightnessController == null) {
649             return null;
650         }
651         return mAutomaticBrightnessController.getDefaultConfig();
652     }
653 
sendUpdatePowerState()654     private void sendUpdatePowerState() {
655         synchronized (mLock) {
656             sendUpdatePowerStateLocked();
657         }
658     }
659 
sendUpdatePowerStateLocked()660     private void sendUpdatePowerStateLocked() {
661         if (!mPendingUpdatePowerStateLocked) {
662             mPendingUpdatePowerStateLocked = true;
663             Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE);
664             mHandler.sendMessage(msg);
665         }
666     }
667 
initialize()668     private void initialize() {
669         // Initialize the power state object for the default display.
670         // In the future, we might manage multiple displays independently.
671         mPowerState = new DisplayPowerState(mBlanker,
672                 mColorFadeEnabled ? new ColorFade(Display.DEFAULT_DISPLAY) : null);
673 
674         if (mColorFadeEnabled) {
675             mColorFadeOnAnimator = ObjectAnimator.ofFloat(
676                     mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 0.0f, 1.0f);
677             mColorFadeOnAnimator.setDuration(COLOR_FADE_ON_ANIMATION_DURATION_MILLIS);
678             mColorFadeOnAnimator.addListener(mAnimatorListener);
679 
680             mColorFadeOffAnimator = ObjectAnimator.ofFloat(
681                     mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 1.0f, 0.0f);
682             mColorFadeOffAnimator.setDuration(COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS);
683             mColorFadeOffAnimator.addListener(mAnimatorListener);
684         }
685 
686         mScreenBrightnessRampAnimator = new RampAnimator<DisplayPowerState>(
687                 mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS);
688         mScreenBrightnessRampAnimator.setListener(mRampAnimatorListener);
689 
690         // Initialize screen state for battery stats.
691         try {
692             mBatteryStats.noteScreenState(mPowerState.getScreenState());
693             mBatteryStats.noteScreenBrightness(mPowerState.getScreenBrightness());
694         } catch (RemoteException ex) {
695             // same process
696         }
697 
698         // Initialize all of the brightness tracking state
699         final float brightness = convertToNits(mPowerState.getScreenBrightness());
700         if (brightness >= 0.0f) {
701             mBrightnessTracker.start(brightness);
702         }
703 
704         mContext.getContentResolver().registerContentObserver(
705                 Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS),
706                 false /*notifyForDescendants*/, mSettingsObserver, UserHandle.USER_ALL);
707         mContext.getContentResolver().registerContentObserver(
708                 Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_FOR_VR),
709                 false /*notifyForDescendants*/, mSettingsObserver, UserHandle.USER_ALL);
710         mContext.getContentResolver().registerContentObserver(
711                 Settings.System.getUriFor(Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ),
712                 false /*notifyForDescendants*/, mSettingsObserver, UserHandle.USER_ALL);
713     }
714 
715     private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() {
716         @Override
717         public void onAnimationStart(Animator animation) {
718         }
719         @Override
720         public void onAnimationEnd(Animator animation) {
721             sendUpdatePowerState();
722         }
723         @Override
724         public void onAnimationRepeat(Animator animation) {
725         }
726         @Override
727         public void onAnimationCancel(Animator animation) {
728         }
729     };
730 
731     private final RampAnimator.Listener mRampAnimatorListener = new RampAnimator.Listener() {
732         @Override
733         public void onAnimationEnd() {
734             sendUpdatePowerState();
735         }
736     };
737 
updatePowerState()738     private void updatePowerState() {
739         // Update the power state request.
740         final boolean mustNotify;
741         final int previousPolicy;
742         boolean mustInitialize = false;
743         int brightnessAdjustmentFlags = 0;
744         mBrightnessReasonTemp.set(null);
745 
746         synchronized (mLock) {
747             mPendingUpdatePowerStateLocked = false;
748             if (mPendingRequestLocked == null) {
749                 return; // wait until first actual power request
750             }
751 
752             if (mPowerRequest == null) {
753                 mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked);
754                 mWaitingForNegativeProximity = mPendingWaitForNegativeProximityLocked;
755                 mPendingWaitForNegativeProximityLocked = false;
756                 mPendingRequestChangedLocked = false;
757                 mustInitialize = true;
758                 // Assume we're on and bright until told otherwise, since that's the state we turn
759                 // on in.
760                 previousPolicy = DisplayPowerRequest.POLICY_BRIGHT;
761             } else if (mPendingRequestChangedLocked) {
762                 previousPolicy = mPowerRequest.policy;
763                 mPowerRequest.copyFrom(mPendingRequestLocked);
764                 mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked;
765                 mPendingWaitForNegativeProximityLocked = false;
766                 mPendingRequestChangedLocked = false;
767                 mDisplayReadyLocked = false;
768             } else {
769                 previousPolicy = mPowerRequest.policy;
770             }
771 
772             mustNotify = !mDisplayReadyLocked;
773         }
774 
775         // Initialize things the first time the power state is changed.
776         if (mustInitialize) {
777             initialize();
778         }
779 
780         // Compute the basic display state using the policy.
781         // We might override this below based on other factors.
782         int state;
783         int brightness = PowerManager.BRIGHTNESS_DEFAULT;
784         boolean performScreenOffTransition = false;
785         switch (mPowerRequest.policy) {
786             case DisplayPowerRequest.POLICY_OFF:
787                 state = Display.STATE_OFF;
788                 performScreenOffTransition = true;
789                 break;
790             case DisplayPowerRequest.POLICY_DOZE:
791                 if (mPowerRequest.dozeScreenState != Display.STATE_UNKNOWN) {
792                     state = mPowerRequest.dozeScreenState;
793                 } else {
794                     state = Display.STATE_DOZE;
795                 }
796                 if (!mAllowAutoBrightnessWhileDozingConfig) {
797                     brightness = mPowerRequest.dozeScreenBrightness;
798                     mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE);
799                 }
800                 break;
801             case DisplayPowerRequest.POLICY_VR:
802                 state = Display.STATE_VR;
803                 break;
804             case DisplayPowerRequest.POLICY_DIM:
805             case DisplayPowerRequest.POLICY_BRIGHT:
806             default:
807                 state = Display.STATE_ON;
808                 break;
809         }
810         assert(state != Display.STATE_UNKNOWN);
811 
812         // Apply the proximity sensor.
813         if (mProximitySensor != null) {
814             if (mPowerRequest.useProximitySensor && state != Display.STATE_OFF) {
815                 setProximitySensorEnabled(true);
816                 if (!mScreenOffBecauseOfProximity
817                         && mProximity == PROXIMITY_POSITIVE) {
818                     mScreenOffBecauseOfProximity = true;
819                     sendOnProximityPositiveWithWakelock();
820                 }
821             } else if (mWaitingForNegativeProximity
822                     && mScreenOffBecauseOfProximity
823                     && mProximity == PROXIMITY_POSITIVE
824                     && state != Display.STATE_OFF) {
825                 setProximitySensorEnabled(true);
826             } else {
827                 setProximitySensorEnabled(false);
828                 mWaitingForNegativeProximity = false;
829             }
830             if (mScreenOffBecauseOfProximity
831                     && mProximity != PROXIMITY_POSITIVE) {
832                 mScreenOffBecauseOfProximity = false;
833                 sendOnProximityNegativeWithWakelock();
834             }
835         } else {
836             mWaitingForNegativeProximity = false;
837         }
838         if (mScreenOffBecauseOfProximity) {
839             state = Display.STATE_OFF;
840         }
841 
842         // Animate the screen state change unless already animating.
843         // The transition may be deferred, so after this point we will use the
844         // actual state instead of the desired one.
845         final int oldState = mPowerState.getScreenState();
846         animateScreenStateChange(state, performScreenOffTransition);
847         state = mPowerState.getScreenState();
848 
849         // Use zero brightness when screen is off.
850         if (state == Display.STATE_OFF) {
851             brightness = PowerManager.BRIGHTNESS_OFF;
852             mBrightnessReasonTemp.setReason(BrightnessReason.REASON_SCREEN_OFF);
853         }
854 
855         // Always use the VR brightness when in the VR state.
856         if (state == Display.STATE_VR) {
857             brightness = mScreenBrightnessForVr;
858             mBrightnessReasonTemp.setReason(BrightnessReason.REASON_VR);
859         }
860 
861         if (brightness < 0 && mPowerRequest.screenBrightnessOverride > 0) {
862             brightness = mPowerRequest.screenBrightnessOverride;
863             mBrightnessReasonTemp.setReason(BrightnessReason.REASON_OVERRIDE);
864             mAppliedScreenBrightnessOverride = true;
865         } else {
866             mAppliedScreenBrightnessOverride = false;
867         }
868 
869         final boolean autoBrightnessEnabledInDoze =
870                 mAllowAutoBrightnessWhileDozingConfig && Display.isDozeState(state);
871         final boolean autoBrightnessEnabled = mPowerRequest.useAutoBrightness
872                     && (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
873                     && brightness < 0
874                     && mAutomaticBrightnessController != null;
875 
876         final boolean userSetBrightnessChanged = updateUserSetScreenBrightness();
877 
878         // Use the temporary screen brightness if there isn't an override, either from
879         // WindowManager or based on the display state.
880         if (mTemporaryScreenBrightness > 0) {
881             brightness = mTemporaryScreenBrightness;
882             mAppliedTemporaryBrightness = true;
883             mBrightnessReasonTemp.setReason(BrightnessReason.REASON_TEMPORARY);
884         } else {
885             mAppliedTemporaryBrightness = false;
886         }
887 
888         final boolean autoBrightnessAdjustmentChanged = updateAutoBrightnessAdjustment();
889         if (autoBrightnessAdjustmentChanged) {
890             mTemporaryAutoBrightnessAdjustment = Float.NaN;
891         }
892 
893         // Use the autobrightness adjustment override if set.
894         final float autoBrightnessAdjustment;
895         if (!Float.isNaN(mTemporaryAutoBrightnessAdjustment)) {
896             autoBrightnessAdjustment = mTemporaryAutoBrightnessAdjustment;
897             brightnessAdjustmentFlags = BrightnessReason.ADJUSTMENT_AUTO_TEMP;
898             mAppliedTemporaryAutoBrightnessAdjustment = true;
899         } else {
900             autoBrightnessAdjustment = mAutoBrightnessAdjustment;
901             brightnessAdjustmentFlags = BrightnessReason.ADJUSTMENT_AUTO;
902             mAppliedTemporaryAutoBrightnessAdjustment = false;
903         }
904 
905         // Apply brightness boost.
906         // We do this here after deciding whether auto-brightness is enabled so that we don't
907         // disable the light sensor during this temporary state.  That way when boost ends we will
908         // be able to resume normal auto-brightness behavior without any delay.
909         if (mPowerRequest.boostScreenBrightness
910                 && brightness != PowerManager.BRIGHTNESS_OFF) {
911             brightness = PowerManager.BRIGHTNESS_ON;
912             mBrightnessReasonTemp.setReason(BrightnessReason.REASON_BOOST);
913             mAppliedBrightnessBoost = true;
914         } else {
915             mAppliedBrightnessBoost = false;
916         }
917 
918         // If the brightness is already set then it's been overridden by something other than the
919         // user, or is a temporary adjustment.
920         boolean userInitiatedChange = brightness < 0
921                 && (autoBrightnessAdjustmentChanged || userSetBrightnessChanged);
922 
923         boolean hadUserBrightnessPoint = false;
924         // Configure auto-brightness.
925         if (mAutomaticBrightnessController != null) {
926             hadUserBrightnessPoint = mAutomaticBrightnessController.hasUserDataPoints();
927             mAutomaticBrightnessController.configure(autoBrightnessEnabled,
928                     mBrightnessConfiguration,
929                     mLastUserSetScreenBrightness / (float) PowerManager.BRIGHTNESS_ON,
930                     userSetBrightnessChanged, autoBrightnessAdjustment,
931                     autoBrightnessAdjustmentChanged, mPowerRequest.policy);
932         }
933 
934         // Apply auto-brightness.
935         boolean slowChange = false;
936         if (brightness < 0) {
937             float newAutoBrightnessAdjustment = autoBrightnessAdjustment;
938             if (autoBrightnessEnabled) {
939                 brightness = mAutomaticBrightnessController.getAutomaticScreenBrightness();
940                 newAutoBrightnessAdjustment =
941                         mAutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment();
942             }
943 
944             if (brightness >= 0) {
945                 // Use current auto-brightness value and slowly adjust to changes.
946                 brightness = clampScreenBrightness(brightness);
947                 if (mAppliedAutoBrightness && !autoBrightnessAdjustmentChanged) {
948                     slowChange = true; // slowly adapt to auto-brightness
949                 }
950                 // Tell the rest of the system about the new brightness. Note that we do this
951                 // before applying the low power or dim transformations so that the slider
952                 // accurately represents the full possible range, even if they range changes what
953                 // it means in absolute terms.
954                 putScreenBrightnessSetting(brightness);
955                 mAppliedAutoBrightness = true;
956                 mBrightnessReasonTemp.setReason(BrightnessReason.REASON_AUTOMATIC);
957             } else {
958                 mAppliedAutoBrightness = false;
959             }
960             if (autoBrightnessAdjustment != newAutoBrightnessAdjustment) {
961                 // If the autobrightness controller has decided to change the adjustment value
962                 // used, make sure that's reflected in settings.
963                 putAutoBrightnessAdjustmentSetting(newAutoBrightnessAdjustment);
964             } else {
965                 // Adjustment values resulted in no change
966                 brightnessAdjustmentFlags = 0;
967             }
968         } else {
969             mAppliedAutoBrightness = false;
970             brightnessAdjustmentFlags = 0;
971         }
972 
973         // Use default brightness when dozing unless overridden.
974         if (brightness < 0 && Display.isDozeState(state)) {
975             brightness = mScreenBrightnessDozeConfig;
976             mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE_DEFAULT);
977         }
978 
979         // Apply manual brightness.
980         if (brightness < 0) {
981             brightness = clampScreenBrightness(mCurrentScreenBrightnessSetting);
982             mBrightnessReasonTemp.setReason(BrightnessReason.REASON_MANUAL);
983         }
984 
985         // Apply dimming by at least some minimum amount when user activity
986         // timeout is about to expire.
987         if (mPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
988             if (brightness > mScreenBrightnessRangeMinimum) {
989                 brightness = Math.max(Math.min(brightness - SCREEN_DIM_MINIMUM_REDUCTION,
990                         mScreenBrightnessDimConfig), mScreenBrightnessRangeMinimum);
991                 mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_DIMMED);
992             }
993             if (!mAppliedDimming) {
994                 slowChange = false;
995             }
996             mAppliedDimming = true;
997         } else if (mAppliedDimming) {
998             slowChange = false;
999             mAppliedDimming = false;
1000         }
1001 
1002         // If low power mode is enabled, scale brightness by screenLowPowerBrightnessFactor
1003         // as long as it is above the minimum threshold.
1004         if (mPowerRequest.lowPowerMode) {
1005             if (brightness > mScreenBrightnessRangeMinimum) {
1006                 final float brightnessFactor =
1007                         Math.min(mPowerRequest.screenLowPowerBrightnessFactor, 1);
1008                 final int lowPowerBrightness = (int) (brightness * brightnessFactor);
1009                 brightness = Math.max(lowPowerBrightness, mScreenBrightnessRangeMinimum);
1010                 mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_LOW_POWER);
1011             }
1012             if (!mAppliedLowPower) {
1013                 slowChange = false;
1014             }
1015             mAppliedLowPower = true;
1016         } else if (mAppliedLowPower) {
1017             slowChange = false;
1018             mAppliedLowPower = false;
1019         }
1020 
1021         // Animate the screen brightness when the screen is on or dozing.
1022         // Skip the animation when the screen is off or suspended or transition to/from VR.
1023         if (!mPendingScreenOff) {
1024             if (mSkipScreenOnBrightnessRamp) {
1025                 if (state == Display.STATE_ON) {
1026                     if (mSkipRampState == RAMP_STATE_SKIP_NONE && mDozing) {
1027                         mInitialAutoBrightness = brightness;
1028                         mSkipRampState = RAMP_STATE_SKIP_INITIAL;
1029                     } else if (mSkipRampState == RAMP_STATE_SKIP_INITIAL
1030                             && mUseSoftwareAutoBrightnessConfig
1031                             && brightness != mInitialAutoBrightness) {
1032                         mSkipRampState = RAMP_STATE_SKIP_AUTOBRIGHT;
1033                     } else if (mSkipRampState == RAMP_STATE_SKIP_AUTOBRIGHT) {
1034                         mSkipRampState = RAMP_STATE_SKIP_NONE;
1035                     }
1036                 } else {
1037                     mSkipRampState = RAMP_STATE_SKIP_NONE;
1038                 }
1039             }
1040 
1041             final boolean wasOrWillBeInVr =
1042                     (state == Display.STATE_VR || oldState == Display.STATE_VR);
1043             final boolean initialRampSkip =
1044                     state == Display.STATE_ON && mSkipRampState != RAMP_STATE_SKIP_NONE;
1045             // While dozing, sometimes the brightness is split into buckets. Rather than animating
1046             // through the buckets, which is unlikely to be smooth in the first place, just jump
1047             // right to the suggested brightness.
1048             final boolean hasBrightnessBuckets =
1049                     Display.isDozeState(state) && mBrightnessBucketsInDozeConfig;
1050             // If the color fade is totally covering the screen then we can change the backlight
1051             // level without it being a noticeable jump since any actual content isn't yet visible.
1052             final boolean isDisplayContentVisible =
1053                     mColorFadeEnabled && mPowerState.getColorFadeLevel() == 1.0f;
1054             final boolean brightnessIsTemporary =
1055                     mAppliedTemporaryBrightness || mAppliedTemporaryAutoBrightnessAdjustment;
1056             if (initialRampSkip || hasBrightnessBuckets
1057                     || wasOrWillBeInVr || !isDisplayContentVisible || brightnessIsTemporary) {
1058                 animateScreenBrightness(brightness, 0);
1059             } else {
1060                 animateScreenBrightness(brightness,
1061                         slowChange ? mBrightnessRampRateSlow : mBrightnessRampRateFast);
1062             }
1063 
1064             if (!brightnessIsTemporary) {
1065                 if (userInitiatedChange && (mAutomaticBrightnessController == null
1066                         || !mAutomaticBrightnessController.hasValidAmbientLux())) {
1067                     // If we don't have a valid lux reading we can't report a valid
1068                     // slider event so notify as if the system changed the brightness.
1069                     userInitiatedChange = false;
1070                 }
1071                 notifyBrightnessChanged(brightness, userInitiatedChange, hadUserBrightnessPoint);
1072             }
1073 
1074         }
1075 
1076         // Log any changes to what is currently driving the brightness setting.
1077         if (!mBrightnessReasonTemp.equals(mBrightnessReason) || brightnessAdjustmentFlags != 0) {
1078             Slog.v(TAG, "Brightness [" + brightness + "] reason changing to: '"
1079                     + mBrightnessReasonTemp.toString(brightnessAdjustmentFlags)
1080                     + "', previous reason: '" + mBrightnessReason + "'.");
1081             mBrightnessReason.set(mBrightnessReasonTemp);
1082         }
1083 
1084         // Update display white-balance.
1085         if (mDisplayWhiteBalanceController != null) {
1086             if (state == Display.STATE_ON && mDisplayWhiteBalanceSettings.isEnabled()) {
1087                 mDisplayWhiteBalanceController.setEnabled(true);
1088                 mDisplayWhiteBalanceController.updateDisplayColorTemperature();
1089             } else {
1090                 mDisplayWhiteBalanceController.setEnabled(false);
1091             }
1092         }
1093 
1094         // Determine whether the display is ready for use in the newly requested state.
1095         // Note that we do not wait for the brightness ramp animation to complete before
1096         // reporting the display is ready because we only need to ensure the screen is in the
1097         // right power state even as it continues to converge on the desired brightness.
1098         final boolean ready = mPendingScreenOnUnblocker == null &&
1099                 (!mColorFadeEnabled ||
1100                         (!mColorFadeOnAnimator.isStarted() && !mColorFadeOffAnimator.isStarted()))
1101                 && mPowerState.waitUntilClean(mCleanListener);
1102         final boolean finished = ready
1103                 && !mScreenBrightnessRampAnimator.isAnimating();
1104 
1105         // Notify policy about screen turned on.
1106         if (ready && state != Display.STATE_OFF
1107                 && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_ON) {
1108             setReportedScreenState(REPORTED_TO_POLICY_SCREEN_ON);
1109             mWindowManagerPolicy.screenTurnedOn();
1110         }
1111 
1112         // Grab a wake lock if we have unfinished business.
1113         if (!finished && !mUnfinishedBusiness) {
1114             if (DEBUG) {
1115                 Slog.d(TAG, "Unfinished business...");
1116             }
1117             mCallbacks.acquireSuspendBlocker();
1118             mUnfinishedBusiness = true;
1119         }
1120 
1121         // Notify the power manager when ready.
1122         if (ready && mustNotify) {
1123             // Send state change.
1124             synchronized (mLock) {
1125                 if (!mPendingRequestChangedLocked) {
1126                     mDisplayReadyLocked = true;
1127 
1128                     if (DEBUG) {
1129                         Slog.d(TAG, "Display ready!");
1130                     }
1131                 }
1132             }
1133             sendOnStateChangedWithWakelock();
1134         }
1135 
1136         // Release the wake lock when we have no unfinished business.
1137         if (finished && mUnfinishedBusiness) {
1138             if (DEBUG) {
1139                 Slog.d(TAG, "Finished business...");
1140             }
1141             mUnfinishedBusiness = false;
1142             mCallbacks.releaseSuspendBlocker();
1143         }
1144 
1145         // Record if dozing for future comparison.
1146         mDozing = state != Display.STATE_ON;
1147 
1148         if (previousPolicy != mPowerRequest.policy) {
1149             logDisplayPolicyChanged(mPowerRequest.policy);
1150         }
1151     }
1152 
1153     @Override
1154     public void updateBrightness() {
1155         sendUpdatePowerState();
1156     }
1157 
1158     public void setBrightnessConfiguration(BrightnessConfiguration c) {
1159         Message msg = mHandler.obtainMessage(MSG_CONFIGURE_BRIGHTNESS, c);
1160         msg.sendToTarget();
1161     }
1162 
1163     public void setTemporaryBrightness(int brightness) {
1164         Message msg = mHandler.obtainMessage(MSG_SET_TEMPORARY_BRIGHTNESS,
1165                 brightness, 0 /*unused*/);
1166         msg.sendToTarget();
1167     }
1168 
1169     public void setTemporaryAutoBrightnessAdjustment(float adjustment) {
1170         Message msg = mHandler.obtainMessage(MSG_SET_TEMPORARY_AUTO_BRIGHTNESS_ADJUSTMENT,
1171                 Float.floatToIntBits(adjustment), 0 /*unused*/);
1172         msg.sendToTarget();
1173     }
1174 
1175     private void blockScreenOn() {
1176         if (mPendingScreenOnUnblocker == null) {
1177             Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0);
1178             mPendingScreenOnUnblocker = new ScreenOnUnblocker();
1179             mScreenOnBlockStartRealTime = SystemClock.elapsedRealtime();
1180             Slog.i(TAG, "Blocking screen on until initial contents have been drawn.");
1181         }
1182     }
1183 
1184     private void unblockScreenOn() {
1185         if (mPendingScreenOnUnblocker != null) {
1186             mPendingScreenOnUnblocker = null;
1187             long delay = SystemClock.elapsedRealtime() - mScreenOnBlockStartRealTime;
1188             Slog.i(TAG, "Unblocked screen on after " + delay + " ms");
1189             Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0);
1190         }
1191     }
1192 
1193     private void blockScreenOff() {
1194         if (mPendingScreenOffUnblocker == null) {
1195             Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, SCREEN_OFF_BLOCKED_TRACE_NAME, 0);
1196             mPendingScreenOffUnblocker = new ScreenOffUnblocker();
1197             mScreenOffBlockStartRealTime = SystemClock.elapsedRealtime();
1198             Slog.i(TAG, "Blocking screen off");
1199         }
1200     }
1201 
1202     private void unblockScreenOff() {
1203         if (mPendingScreenOffUnblocker != null) {
1204             mPendingScreenOffUnblocker = null;
1205             long delay = SystemClock.elapsedRealtime() - mScreenOffBlockStartRealTime;
1206             Slog.i(TAG, "Unblocked screen off after " + delay + " ms");
1207             Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, SCREEN_OFF_BLOCKED_TRACE_NAME, 0);
1208         }
1209     }
1210 
1211     private boolean setScreenState(int state) {
1212         return setScreenState(state, false /*reportOnly*/);
1213     }
1214 
1215     private boolean setScreenState(int state, boolean reportOnly) {
1216         final boolean isOff = (state == Display.STATE_OFF);
1217         if (mPowerState.getScreenState() != state) {
1218 
1219             // If we are trying to turn screen off, give policy a chance to do something before we
1220             // actually turn the screen off.
1221             if (isOff && !mScreenOffBecauseOfProximity) {
1222                 if (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_ON) {
1223                     setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_OFF);
1224                     blockScreenOff();
1225                     mWindowManagerPolicy.screenTurningOff(mPendingScreenOffUnblocker);
1226                     unblockScreenOff();
1227                 } else if (mPendingScreenOffUnblocker != null) {
1228                     // Abort doing the state change until screen off is unblocked.
1229                     return false;
1230                 }
1231             }
1232 
1233             if (!reportOnly) {
1234                 Trace.traceCounter(Trace.TRACE_TAG_POWER, "ScreenState", state);
1235                 mPowerState.setScreenState(state);
1236                 // Tell battery stats about the transition.
1237                 try {
1238                     mBatteryStats.noteScreenState(state);
1239                 } catch (RemoteException ex) {
1240                     // same process
1241                 }
1242             }
1243         }
1244 
1245         // Tell the window manager policy when the screen is turned off or on unless it's due
1246         // to the proximity sensor.  We temporarily block turning the screen on until the
1247         // window manager is ready by leaving a black surface covering the screen.
1248         // This surface is essentially the final state of the color fade animation and
1249         // it is only removed once the window manager tells us that the activity has
1250         // finished drawing underneath.
1251         if (isOff && mReportedScreenStateToPolicy != REPORTED_TO_POLICY_SCREEN_OFF
1252                 && !mScreenOffBecauseOfProximity) {
1253             setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
1254             unblockScreenOn();
1255             mWindowManagerPolicy.screenTurnedOff();
1256         } else if (!isOff
1257                 && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_OFF) {
1258 
1259             // We told policy already that screen was turning off, but now we changed our minds.
1260             // Complete the full state transition on -> turningOff -> off.
1261             unblockScreenOff();
1262             mWindowManagerPolicy.screenTurnedOff();
1263             setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
1264         }
1265         if (!isOff && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF) {
1266             setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_ON);
1267             if (mPowerState.getColorFadeLevel() == 0.0f) {
1268                 blockScreenOn();
1269             } else {
1270                 unblockScreenOn();
1271             }
1272             mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker);
1273         }
1274 
1275         // Return true if the screen isn't blocked.
1276         return mPendingScreenOnUnblocker == null;
1277     }
1278 
1279     private void setReportedScreenState(int state) {
1280         Trace.traceCounter(Trace.TRACE_TAG_POWER, "ReportedScreenStateToPolicy", state);
1281         mReportedScreenStateToPolicy = state;
1282     }
1283 
1284     private int clampScreenBrightnessForVr(int value) {
1285         return MathUtils.constrain(
1286                 value, mScreenBrightnessForVrRangeMinimum, mScreenBrightnessForVrRangeMaximum);
1287     }
1288 
1289     private int clampScreenBrightness(int value) {
1290         return MathUtils.constrain(
1291                 value, mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum);
1292     }
1293 
1294     private void animateScreenBrightness(int target, int rate) {
1295         if (DEBUG) {
1296             Slog.d(TAG, "Animating brightness: target=" + target +", rate=" + rate);
1297         }
1298         if (mScreenBrightnessRampAnimator.animateTo(target, rate)) {
1299             Trace.traceCounter(Trace.TRACE_TAG_POWER, "TargetScreenBrightness", target);
1300             try {
1301                 mBatteryStats.noteScreenBrightness(target);
1302             } catch (RemoteException ex) {
1303                 // same process
1304             }
1305         }
1306     }
1307 
1308     private void animateScreenStateChange(int target, boolean performScreenOffTransition) {
1309         // If there is already an animation in progress, don't interfere with it.
1310         if (mColorFadeEnabled &&
1311                 (mColorFadeOnAnimator.isStarted() || mColorFadeOffAnimator.isStarted())) {
1312             if (target != Display.STATE_ON) {
1313                 return;
1314             }
1315             // If display state changed to on, proceed and stop the color fade and turn screen on.
1316             mPendingScreenOff = false;
1317         }
1318 
1319         if (mDisplayBlanksAfterDozeConfig
1320                 && Display.isDozeState(mPowerState.getScreenState())
1321                 && !Display.isDozeState(target)) {
1322             // Skip the screen off animation and add a black surface to hide the
1323             // contents of the screen.
1324             mPowerState.prepareColorFade(mContext,
1325                     mColorFadeFadesConfig ? ColorFade.MODE_FADE : ColorFade.MODE_WARM_UP);
1326             if (mColorFadeOffAnimator != null) {
1327                 mColorFadeOffAnimator.end();
1328             }
1329             // Some display hardware will blank itself on the transition between doze and non-doze
1330             // but still on display states. In this case we want to report to policy that the
1331             // display has turned off so it can prepare the appropriate power on animation, but we
1332             // don't want to actually transition to the fully off state since that takes
1333             // significantly longer to transition from.
1334             setScreenState(Display.STATE_OFF, target != Display.STATE_OFF /*reportOnly*/);
1335         }
1336 
1337         // If we were in the process of turning off the screen but didn't quite
1338         // finish.  Then finish up now to prevent a jarring transition back
1339         // to screen on if we skipped blocking screen on as usual.
1340         if (mPendingScreenOff && target != Display.STATE_OFF) {
1341             setScreenState(Display.STATE_OFF);
1342             mPendingScreenOff = false;
1343             mPowerState.dismissColorFadeResources();
1344         }
1345 
1346         if (target == Display.STATE_ON) {
1347             // Want screen on.  The contents of the screen may not yet
1348             // be visible if the color fade has not been dismissed because
1349             // its last frame of animation is solid black.
1350             if (!setScreenState(Display.STATE_ON)) {
1351                 return; // screen on blocked
1352             }
1353             if (USE_COLOR_FADE_ON_ANIMATION && mColorFadeEnabled && mPowerRequest.isBrightOrDim()) {
1354                 // Perform screen on animation.
1355                 if (mPowerState.getColorFadeLevel() == 1.0f) {
1356                     mPowerState.dismissColorFade();
1357                 } else if (mPowerState.prepareColorFade(mContext,
1358                         mColorFadeFadesConfig ?
1359                                 ColorFade.MODE_FADE :
1360                                         ColorFade.MODE_WARM_UP)) {
1361                     mColorFadeOnAnimator.start();
1362                 } else {
1363                     mColorFadeOnAnimator.end();
1364                 }
1365             } else {
1366                 // Skip screen on animation.
1367                 mPowerState.setColorFadeLevel(1.0f);
1368                 mPowerState.dismissColorFade();
1369             }
1370         } else if (target == Display.STATE_VR) {
1371             // Wait for brightness animation to complete beforehand when entering VR
1372             // from screen on to prevent a perceptible jump because brightness may operate
1373             // differently when the display is configured for dozing.
1374             if (mScreenBrightnessRampAnimator.isAnimating()
1375                     && mPowerState.getScreenState() == Display.STATE_ON) {
1376                 return;
1377             }
1378 
1379             // Set screen state.
1380             if (!setScreenState(Display.STATE_VR)) {
1381                 return; // screen on blocked
1382             }
1383 
1384             // Dismiss the black surface without fanfare.
1385             mPowerState.setColorFadeLevel(1.0f);
1386             mPowerState.dismissColorFade();
1387         } else if (target == Display.STATE_DOZE) {
1388             // Want screen dozing.
1389             // Wait for brightness animation to complete beforehand when entering doze
1390             // from screen on to prevent a perceptible jump because brightness may operate
1391             // differently when the display is configured for dozing.
1392             if (mScreenBrightnessRampAnimator.isAnimating()
1393                     && mPowerState.getScreenState() == Display.STATE_ON) {
1394                 return;
1395             }
1396 
1397             // Set screen state.
1398             if (!setScreenState(Display.STATE_DOZE)) {
1399                 return; // screen on blocked
1400             }
1401 
1402             // Dismiss the black surface without fanfare.
1403             mPowerState.setColorFadeLevel(1.0f);
1404             mPowerState.dismissColorFade();
1405         } else if (target == Display.STATE_DOZE_SUSPEND) {
1406             // Want screen dozing and suspended.
1407             // Wait for brightness animation to complete beforehand unless already
1408             // suspended because we may not be able to change it after suspension.
1409             if (mScreenBrightnessRampAnimator.isAnimating()
1410                     && mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) {
1411                 return;
1412             }
1413 
1414             // If not already suspending, temporarily set the state to doze until the
1415             // screen on is unblocked, then suspend.
1416             if (mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) {
1417                 if (!setScreenState(Display.STATE_DOZE)) {
1418                     return; // screen on blocked
1419                 }
1420                 setScreenState(Display.STATE_DOZE_SUSPEND); // already on so can't block
1421             }
1422 
1423             // Dismiss the black surface without fanfare.
1424             mPowerState.setColorFadeLevel(1.0f);
1425             mPowerState.dismissColorFade();
1426         } else if (target == Display.STATE_ON_SUSPEND) {
1427             // Want screen full-power and suspended.
1428             // Wait for brightness animation to complete beforehand unless already
1429             // suspended because we may not be able to change it after suspension.
1430             if (mScreenBrightnessRampAnimator.isAnimating()
1431                     && mPowerState.getScreenState() != Display.STATE_ON_SUSPEND) {
1432                 return;
1433             }
1434 
1435             // If not already suspending, temporarily set the state to on until the
1436             // screen on is unblocked, then suspend.
1437             if (mPowerState.getScreenState() != Display.STATE_ON_SUSPEND) {
1438                 if (!setScreenState(Display.STATE_ON)) {
1439                     return;
1440                 }
1441                 setScreenState(Display.STATE_ON_SUSPEND);
1442             }
1443 
1444             // Dismiss the black surface without fanfare.
1445             mPowerState.setColorFadeLevel(1.0f);
1446             mPowerState.dismissColorFade();
1447         } else {
1448             // Want screen off.
1449             mPendingScreenOff = true;
1450             if (!mColorFadeEnabled) {
1451                 mPowerState.setColorFadeLevel(0.0f);
1452             }
1453 
1454             if (mPowerState.getColorFadeLevel() == 0.0f) {
1455                 // Turn the screen off.
1456                 // A black surface is already hiding the contents of the screen.
1457                 setScreenState(Display.STATE_OFF);
1458                 mPendingScreenOff = false;
1459                 mPowerState.dismissColorFadeResources();
1460             } else if (performScreenOffTransition
1461                     && mPowerState.prepareColorFade(mContext,
1462                             mColorFadeFadesConfig ?
1463                                     ColorFade.MODE_FADE : ColorFade.MODE_COOL_DOWN)
1464                     && mPowerState.getScreenState() != Display.STATE_OFF) {
1465                 // Perform the screen off animation.
1466                 mColorFadeOffAnimator.start();
1467             } else {
1468                 // Skip the screen off animation and add a black surface to hide the
1469                 // contents of the screen.
1470                 mColorFadeOffAnimator.end();
1471             }
1472         }
1473     }
1474 
1475     private final Runnable mCleanListener = new Runnable() {
1476         @Override
1477         public void run() {
1478             sendUpdatePowerState();
1479         }
1480     };
1481 
1482     private void setProximitySensorEnabled(boolean enable) {
1483         if (enable) {
1484             if (!mProximitySensorEnabled) {
1485                 // Register the listener.
1486                 // Proximity sensor state already cleared initially.
1487                 mProximitySensorEnabled = true;
1488                 mSensorManager.registerListener(mProximitySensorListener, mProximitySensor,
1489                         SensorManager.SENSOR_DELAY_NORMAL, mHandler);
1490             }
1491         } else {
1492             if (mProximitySensorEnabled) {
1493                 // Unregister the listener.
1494                 // Clear the proximity sensor state for next time.
1495                 mProximitySensorEnabled = false;
1496                 mProximity = PROXIMITY_UNKNOWN;
1497                 mPendingProximity = PROXIMITY_UNKNOWN;
1498                 mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
1499                 mSensorManager.unregisterListener(mProximitySensorListener);
1500                 clearPendingProximityDebounceTime(); // release wake lock (must be last)
1501             }
1502         }
1503     }
1504 
1505     private void handleProximitySensorEvent(long time, boolean positive) {
1506         if (mProximitySensorEnabled) {
1507             if (mPendingProximity == PROXIMITY_NEGATIVE && !positive) {
1508                 return; // no change
1509             }
1510             if (mPendingProximity == PROXIMITY_POSITIVE && positive) {
1511                 return; // no change
1512             }
1513 
1514             // Only accept a proximity sensor reading if it remains
1515             // stable for the entire debounce delay.  We hold a wake lock while
1516             // debouncing the sensor.
1517             mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
1518             if (positive) {
1519                 mPendingProximity = PROXIMITY_POSITIVE;
1520                 setPendingProximityDebounceTime(
1521                         time + PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY); // acquire wake lock
1522             } else {
1523                 mPendingProximity = PROXIMITY_NEGATIVE;
1524                 setPendingProximityDebounceTime(
1525                         time + PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY); // acquire wake lock
1526             }
1527 
1528             // Debounce the new sensor reading.
1529             debounceProximitySensor();
1530         }
1531     }
1532 
1533     private void debounceProximitySensor() {
1534         if (mProximitySensorEnabled
1535                 && mPendingProximity != PROXIMITY_UNKNOWN
1536                 && mPendingProximityDebounceTime >= 0) {
1537             final long now = SystemClock.uptimeMillis();
1538             if (mPendingProximityDebounceTime <= now) {
1539                 // Sensor reading accepted.  Apply the change then release the wake lock.
1540                 mProximity = mPendingProximity;
1541                 updatePowerState();
1542                 clearPendingProximityDebounceTime(); // release wake lock (must be last)
1543             } else {
1544                 // Need to wait a little longer.
1545                 // Debounce again later.  We continue holding a wake lock while waiting.
1546                 Message msg = mHandler.obtainMessage(MSG_PROXIMITY_SENSOR_DEBOUNCED);
1547                 mHandler.sendMessageAtTime(msg, mPendingProximityDebounceTime);
1548             }
1549         }
1550     }
1551 
1552     private void clearPendingProximityDebounceTime() {
1553         if (mPendingProximityDebounceTime >= 0) {
1554             mPendingProximityDebounceTime = -1;
1555             mCallbacks.releaseSuspendBlocker(); // release wake lock
1556         }
1557     }
1558 
1559     private void setPendingProximityDebounceTime(long debounceTime) {
1560         if (mPendingProximityDebounceTime < 0) {
1561             mCallbacks.acquireSuspendBlocker(); // acquire wake lock
1562         }
1563         mPendingProximityDebounceTime = debounceTime;
1564     }
1565 
1566     private void sendOnStateChangedWithWakelock() {
1567         mCallbacks.acquireSuspendBlocker();
1568         mHandler.post(mOnStateChangedRunnable);
1569     }
1570 
1571     private void logDisplayPolicyChanged(int newPolicy) {
1572         LogMaker log = new LogMaker(MetricsEvent.DISPLAY_POLICY);
1573         log.setType(MetricsEvent.TYPE_UPDATE);
1574         log.setSubtype(newPolicy);
1575         MetricsLogger.action(log);
1576     }
1577 
1578     private void handleSettingsChange(boolean userSwitch) {
1579         mPendingScreenBrightnessSetting = getScreenBrightnessSetting();
1580         if (userSwitch) {
1581             // Don't treat user switches as user initiated change.
1582             mCurrentScreenBrightnessSetting = mPendingScreenBrightnessSetting;
1583             if (mAutomaticBrightnessController != null) {
1584                 mAutomaticBrightnessController.resetShortTermModel();
1585             }
1586         }
1587         mPendingAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting();
1588         // We don't bother with a pending variable for VR screen brightness since we just
1589         // immediately adapt to it.
1590         mScreenBrightnessForVr = getScreenBrightnessForVrSetting();
1591         sendUpdatePowerState();
1592     }
1593 
1594     private float getAutoBrightnessAdjustmentSetting() {
1595         final float adj = Settings.System.getFloatForUser(mContext.getContentResolver(),
1596                 Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f, UserHandle.USER_CURRENT);
1597         return Float.isNaN(adj) ? 0.0f : clampAutoBrightnessAdjustment(adj);
1598     }
1599 
1600     private int getScreenBrightnessSetting() {
1601         final int brightness = Settings.System.getIntForUser(mContext.getContentResolver(),
1602                 Settings.System.SCREEN_BRIGHTNESS, mScreenBrightnessDefault,
1603                 UserHandle.USER_CURRENT);
1604         return clampAbsoluteBrightness(brightness);
1605     }
1606 
1607     private int getScreenBrightnessForVrSetting() {
1608         final int brightness = Settings.System.getIntForUser(mContext.getContentResolver(),
1609                 Settings.System.SCREEN_BRIGHTNESS_FOR_VR, mScreenBrightnessForVrDefault,
1610                 UserHandle.USER_CURRENT);
1611         return clampScreenBrightnessForVr(brightness);
1612     }
1613 
1614     private void putScreenBrightnessSetting(int brightness) {
1615         mCurrentScreenBrightnessSetting = brightness;
1616         Settings.System.putIntForUser(mContext.getContentResolver(),
1617                 Settings.System.SCREEN_BRIGHTNESS, brightness, UserHandle.USER_CURRENT);
1618     }
1619 
1620     private void putAutoBrightnessAdjustmentSetting(float adjustment) {
1621         mAutoBrightnessAdjustment = adjustment;
1622         Settings.System.putFloatForUser(mContext.getContentResolver(),
1623                 Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, adjustment, UserHandle.USER_CURRENT);
1624     }
1625 
1626     private boolean updateAutoBrightnessAdjustment() {
1627         if (Float.isNaN(mPendingAutoBrightnessAdjustment)) {
1628             return false;
1629         }
1630         if (mAutoBrightnessAdjustment == mPendingAutoBrightnessAdjustment) {
1631             mPendingAutoBrightnessAdjustment = Float.NaN;
1632             return false;
1633         }
1634         mAutoBrightnessAdjustment = mPendingAutoBrightnessAdjustment;
1635         mPendingAutoBrightnessAdjustment = Float.NaN;
1636         return true;
1637     }
1638 
1639     private boolean updateUserSetScreenBrightness() {
1640         if (mPendingScreenBrightnessSetting < 0) {
1641             return false;
1642         }
1643         if (mCurrentScreenBrightnessSetting == mPendingScreenBrightnessSetting) {
1644             mPendingScreenBrightnessSetting = -1;
1645             mTemporaryScreenBrightness = -1;
1646             return false;
1647         }
1648         mCurrentScreenBrightnessSetting = mPendingScreenBrightnessSetting;
1649         mLastUserSetScreenBrightness = mPendingScreenBrightnessSetting;
1650         mPendingScreenBrightnessSetting = -1;
1651         mTemporaryScreenBrightness = -1;
1652         return true;
1653     }
1654 
1655     private void notifyBrightnessChanged(int brightness, boolean userInitiated,
1656             boolean hadUserDataPoint) {
1657         final float brightnessInNits = convertToNits(brightness);
1658         if (mPowerRequest.useAutoBrightness && brightnessInNits >= 0.0f
1659                 && mAutomaticBrightnessController != null) {
1660             // We only want to track changes on devices that can actually map the display backlight
1661             // values into a physical brightness unit since the value provided by the API is in
1662             // nits and not using the arbitrary backlight units.
1663             final float powerFactor = mPowerRequest.lowPowerMode
1664                     ? mPowerRequest.screenLowPowerBrightnessFactor
1665                     : 1.0f;
1666             mBrightnessTracker.notifyBrightnessChanged(brightnessInNits, userInitiated,
1667                     powerFactor, hadUserDataPoint,
1668                     mAutomaticBrightnessController.isDefaultConfig());
1669         }
1670     }
1671 
1672     private float convertToNits(int backlight) {
1673         if (mBrightnessMapper != null) {
1674             return mBrightnessMapper.convertToNits(backlight);
1675         } else {
1676             return -1.0f;
1677         }
1678     }
1679 
1680     private final Runnable mOnStateChangedRunnable = new Runnable() {
1681         @Override
1682         public void run() {
1683             mCallbacks.onStateChanged();
1684             mCallbacks.releaseSuspendBlocker();
1685         }
1686     };
1687 
sendOnProximityPositiveWithWakelock()1688     private void sendOnProximityPositiveWithWakelock() {
1689         mCallbacks.acquireSuspendBlocker();
1690         mHandler.post(mOnProximityPositiveRunnable);
1691     }
1692 
1693     private final Runnable mOnProximityPositiveRunnable = new Runnable() {
1694         @Override
1695         public void run() {
1696             mCallbacks.onProximityPositive();
1697             mCallbacks.releaseSuspendBlocker();
1698         }
1699     };
1700 
sendOnProximityNegativeWithWakelock()1701     private void sendOnProximityNegativeWithWakelock() {
1702         mCallbacks.acquireSuspendBlocker();
1703         mHandler.post(mOnProximityNegativeRunnable);
1704     }
1705 
1706     private final Runnable mOnProximityNegativeRunnable = new Runnable() {
1707         @Override
1708         public void run() {
1709             mCallbacks.onProximityNegative();
1710             mCallbacks.releaseSuspendBlocker();
1711         }
1712     };
1713 
dump(final PrintWriter pw)1714     public void dump(final PrintWriter pw) {
1715         synchronized (mLock) {
1716             pw.println();
1717             pw.println("Display Power Controller Locked State:");
1718             pw.println("  mDisplayReadyLocked=" + mDisplayReadyLocked);
1719             pw.println("  mPendingRequestLocked=" + mPendingRequestLocked);
1720             pw.println("  mPendingRequestChangedLocked=" + mPendingRequestChangedLocked);
1721             pw.println("  mPendingWaitForNegativeProximityLocked="
1722                     + mPendingWaitForNegativeProximityLocked);
1723             pw.println("  mPendingUpdatePowerStateLocked=" + mPendingUpdatePowerStateLocked);
1724         }
1725 
1726         pw.println();
1727         pw.println("Display Power Controller Configuration:");
1728         pw.println("  mScreenBrightnessDozeConfig=" + mScreenBrightnessDozeConfig);
1729         pw.println("  mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig);
1730         pw.println("  mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum);
1731         pw.println("  mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum);
1732         pw.println("  mScreenBrightnessDefault=" + mScreenBrightnessDefault);
1733         pw.println("  mScreenBrightnessForVrRangeMinimum=" + mScreenBrightnessForVrRangeMinimum);
1734         pw.println("  mScreenBrightnessForVrRangeMaximum=" + mScreenBrightnessForVrRangeMaximum);
1735         pw.println("  mScreenBrightnessForVrDefault=" + mScreenBrightnessForVrDefault);
1736         pw.println("  mUseSoftwareAutoBrightnessConfig=" + mUseSoftwareAutoBrightnessConfig);
1737         pw.println("  mAllowAutoBrightnessWhileDozingConfig=" +
1738                 mAllowAutoBrightnessWhileDozingConfig);
1739         pw.println("  mBrightnessRampRateFast=" + mBrightnessRampRateFast);
1740         pw.println("  mBrightnessRampRateSlow=" + mBrightnessRampRateSlow);
1741         pw.println("  mSkipScreenOnBrightnessRamp=" + mSkipScreenOnBrightnessRamp);
1742         pw.println("  mColorFadeFadesConfig=" + mColorFadeFadesConfig);
1743         pw.println("  mColorFadeEnabled=" + mColorFadeEnabled);
1744         pw.println("  mDisplayBlanksAfterDozeConfig=" + mDisplayBlanksAfterDozeConfig);
1745         pw.println("  mBrightnessBucketsInDozeConfig=" + mBrightnessBucketsInDozeConfig);
1746 
1747         mHandler.runWithScissors(new Runnable() {
1748             @Override
1749             public void run() {
1750                 dumpLocal(pw);
1751             }
1752         }, 1000);
1753     }
1754 
dumpLocal(PrintWriter pw)1755     private void dumpLocal(PrintWriter pw) {
1756         pw.println();
1757         pw.println("Display Power Controller Thread State:");
1758         pw.println("  mPowerRequest=" + mPowerRequest);
1759         pw.println("  mUnfinishedBusiness=" + mUnfinishedBusiness);
1760         pw.println("  mWaitingForNegativeProximity=" + mWaitingForNegativeProximity);
1761         pw.println("  mProximitySensor=" + mProximitySensor);
1762         pw.println("  mProximitySensorEnabled=" + mProximitySensorEnabled);
1763         pw.println("  mProximityThreshold=" + mProximityThreshold);
1764         pw.println("  mProximity=" + proximityToString(mProximity));
1765         pw.println("  mPendingProximity=" + proximityToString(mPendingProximity));
1766         pw.println("  mPendingProximityDebounceTime="
1767                 + TimeUtils.formatUptime(mPendingProximityDebounceTime));
1768         pw.println("  mScreenOffBecauseOfProximity=" + mScreenOffBecauseOfProximity);
1769         pw.println("  mLastUserSetScreenBrightness=" + mLastUserSetScreenBrightness);
1770         pw.println("  mCurrentScreenBrightnessSetting=" + mCurrentScreenBrightnessSetting);
1771         pw.println("  mPendingScreenBrightnessSetting=" + mPendingScreenBrightnessSetting);
1772         pw.println("  mTemporaryScreenBrightness=" + mTemporaryScreenBrightness);
1773         pw.println("  mAutoBrightnessAdjustment=" + mAutoBrightnessAdjustment);
1774         pw.println("  mBrightnessReason=" + mBrightnessReason);
1775         pw.println("  mTemporaryAutoBrightnessAdjustment=" + mTemporaryAutoBrightnessAdjustment);
1776         pw.println("  mPendingAutoBrightnessAdjustment=" + mPendingAutoBrightnessAdjustment);
1777         pw.println("  mScreenBrightnessForVr=" + mScreenBrightnessForVr);
1778         pw.println("  mAppliedAutoBrightness=" + mAppliedAutoBrightness);
1779         pw.println("  mAppliedDimming=" + mAppliedDimming);
1780         pw.println("  mAppliedLowPower=" + mAppliedLowPower);
1781         pw.println("  mAppliedScreenBrightnessOverride=" + mAppliedScreenBrightnessOverride);
1782         pw.println("  mAppliedTemporaryBrightness=" + mAppliedTemporaryBrightness);
1783         pw.println("  mDozing=" + mDozing);
1784         pw.println("  mSkipRampState=" + skipRampStateToString(mSkipRampState));
1785         pw.println("  mInitialAutoBrightness=" + mInitialAutoBrightness);
1786         pw.println("  mScreenOnBlockStartRealTime=" + mScreenOnBlockStartRealTime);
1787         pw.println("  mScreenOffBlockStartRealTime=" + mScreenOffBlockStartRealTime);
1788         pw.println("  mPendingScreenOnUnblocker=" + mPendingScreenOnUnblocker);
1789         pw.println("  mPendingScreenOffUnblocker=" + mPendingScreenOffUnblocker);
1790         pw.println("  mPendingScreenOff=" + mPendingScreenOff);
1791         pw.println("  mReportedToPolicy=" +
1792                 reportedToPolicyToString(mReportedScreenStateToPolicy));
1793 
1794         if (mScreenBrightnessRampAnimator != null) {
1795             pw.println("  mScreenBrightnessRampAnimator.isAnimating()=" +
1796                     mScreenBrightnessRampAnimator.isAnimating());
1797         }
1798 
1799         if (mColorFadeOnAnimator != null) {
1800             pw.println("  mColorFadeOnAnimator.isStarted()=" +
1801                     mColorFadeOnAnimator.isStarted());
1802         }
1803         if (mColorFadeOffAnimator != null) {
1804             pw.println("  mColorFadeOffAnimator.isStarted()=" +
1805                     mColorFadeOffAnimator.isStarted());
1806         }
1807 
1808         if (mPowerState != null) {
1809             mPowerState.dump(pw);
1810         }
1811 
1812         if (mAutomaticBrightnessController != null) {
1813             mAutomaticBrightnessController.dump(pw);
1814         }
1815 
1816         if (mBrightnessTracker != null) {
1817             pw.println();
1818             mBrightnessTracker.dump(pw);
1819         }
1820 
1821         pw.println();
1822         if (mDisplayWhiteBalanceController != null) {
1823             mDisplayWhiteBalanceController.dump(pw);
1824             mDisplayWhiteBalanceSettings.dump(pw);
1825         }
1826     }
1827 
proximityToString(int state)1828     private static String proximityToString(int state) {
1829         switch (state) {
1830             case PROXIMITY_UNKNOWN:
1831                 return "Unknown";
1832             case PROXIMITY_NEGATIVE:
1833                 return "Negative";
1834             case PROXIMITY_POSITIVE:
1835                 return "Positive";
1836             default:
1837                 return Integer.toString(state);
1838         }
1839     }
1840 
reportedToPolicyToString(int state)1841     private static String reportedToPolicyToString(int state) {
1842         switch (state) {
1843             case REPORTED_TO_POLICY_SCREEN_OFF:
1844                 return "REPORTED_TO_POLICY_SCREEN_OFF";
1845             case REPORTED_TO_POLICY_SCREEN_TURNING_ON:
1846                 return "REPORTED_TO_POLICY_SCREEN_TURNING_ON";
1847             case REPORTED_TO_POLICY_SCREEN_ON:
1848                 return "REPORTED_TO_POLICY_SCREEN_ON";
1849             default:
1850                 return Integer.toString(state);
1851         }
1852     }
1853 
skipRampStateToString(int state)1854     private static String skipRampStateToString(int state) {
1855         switch (state) {
1856             case RAMP_STATE_SKIP_NONE:
1857                 return "RAMP_STATE_SKIP_NONE";
1858             case RAMP_STATE_SKIP_INITIAL:
1859                 return "RAMP_STATE_SKIP_INITIAL";
1860             case RAMP_STATE_SKIP_AUTOBRIGHT:
1861                 return "RAMP_STATE_SKIP_AUTOBRIGHT";
1862             default:
1863                 return Integer.toString(state);
1864         }
1865     }
1866 
clampAbsoluteBrightness(int value)1867     private static int clampAbsoluteBrightness(int value) {
1868         return MathUtils.constrain(value, PowerManager.BRIGHTNESS_OFF, PowerManager.BRIGHTNESS_ON);
1869     }
1870 
clampAutoBrightnessAdjustment(float value)1871     private static float clampAutoBrightnessAdjustment(float value) {
1872         return MathUtils.constrain(value, -1.0f, 1.0f);
1873     }
1874 
1875     private final class DisplayControllerHandler extends Handler {
DisplayControllerHandler(Looper looper)1876         public DisplayControllerHandler(Looper looper) {
1877             super(looper, null, true /*async*/);
1878         }
1879 
1880         @Override
handleMessage(Message msg)1881         public void handleMessage(Message msg) {
1882             switch (msg.what) {
1883                 case MSG_UPDATE_POWER_STATE:
1884                     updatePowerState();
1885                     break;
1886 
1887                 case MSG_PROXIMITY_SENSOR_DEBOUNCED:
1888                     debounceProximitySensor();
1889                     break;
1890 
1891                 case MSG_SCREEN_ON_UNBLOCKED:
1892                     if (mPendingScreenOnUnblocker == msg.obj) {
1893                         unblockScreenOn();
1894                         updatePowerState();
1895                     }
1896                     break;
1897                 case MSG_SCREEN_OFF_UNBLOCKED:
1898                     if (mPendingScreenOffUnblocker == msg.obj) {
1899                         unblockScreenOff();
1900                         updatePowerState();
1901                     }
1902                     break;
1903                 case MSG_CONFIGURE_BRIGHTNESS:
1904                     mBrightnessConfiguration = (BrightnessConfiguration)msg.obj;
1905                     updatePowerState();
1906                     break;
1907 
1908                 case MSG_SET_TEMPORARY_BRIGHTNESS:
1909                     // TODO: Should we have a a timeout for the temporary brightness?
1910                     mTemporaryScreenBrightness = msg.arg1;
1911                     updatePowerState();
1912                     break;
1913 
1914                 case MSG_SET_TEMPORARY_AUTO_BRIGHTNESS_ADJUSTMENT:
1915                     mTemporaryAutoBrightnessAdjustment = Float.intBitsToFloat(msg.arg1);
1916                     updatePowerState();
1917                     break;
1918             }
1919         }
1920     }
1921 
1922     private final SensorEventListener mProximitySensorListener = new SensorEventListener() {
1923         @Override
1924         public void onSensorChanged(SensorEvent event) {
1925             if (mProximitySensorEnabled) {
1926                 final long time = SystemClock.uptimeMillis();
1927                 final float distance = event.values[0];
1928                 boolean positive = distance >= 0.0f && distance < mProximityThreshold;
1929                 handleProximitySensorEvent(time, positive);
1930             }
1931         }
1932 
1933         @Override
1934         public void onAccuracyChanged(Sensor sensor, int accuracy) {
1935             // Not used.
1936         }
1937     };
1938 
1939 
1940     private final class SettingsObserver extends ContentObserver {
SettingsObserver(Handler handler)1941         public SettingsObserver(Handler handler) {
1942             super(handler);
1943         }
1944 
1945         @Override
onChange(boolean selfChange, Uri uri)1946         public void onChange(boolean selfChange, Uri uri) {
1947             handleSettingsChange(false /* userSwitch */);
1948         }
1949     }
1950 
1951     private final class ScreenOnUnblocker implements WindowManagerPolicy.ScreenOnListener {
1952         @Override
onScreenOn()1953         public void onScreenOn() {
1954             Message msg = mHandler.obtainMessage(MSG_SCREEN_ON_UNBLOCKED, this);
1955             mHandler.sendMessage(msg);
1956         }
1957     }
1958 
1959     private final class ScreenOffUnblocker implements WindowManagerPolicy.ScreenOffListener {
1960         @Override
onScreenOff()1961         public void onScreenOff() {
1962             Message msg = mHandler.obtainMessage(MSG_SCREEN_OFF_UNBLOCKED, this);
1963             mHandler.sendMessage(msg);
1964         }
1965     }
1966 
setAutoBrightnessLoggingEnabled(boolean enabled)1967     void setAutoBrightnessLoggingEnabled(boolean enabled) {
1968         if (mAutomaticBrightnessController != null) {
1969             mAutomaticBrightnessController.setLoggingEnabled(enabled);
1970         }
1971     }
1972 
1973     @Override // DisplayWhiteBalanceController.Callbacks
updateWhiteBalance()1974     public void updateWhiteBalance() {
1975         sendUpdatePowerState();
1976     }
1977 
setDisplayWhiteBalanceLoggingEnabled(boolean enabled)1978     void setDisplayWhiteBalanceLoggingEnabled(boolean enabled) {
1979         if (mDisplayWhiteBalanceController != null) {
1980             mDisplayWhiteBalanceController.setLoggingEnabled(enabled);
1981             mDisplayWhiteBalanceSettings.setLoggingEnabled(enabled);
1982         }
1983     }
1984 
setAmbientColorTemperatureOverride(float cct)1985     void setAmbientColorTemperatureOverride(float cct) {
1986         if (mDisplayWhiteBalanceController != null) {
1987             mDisplayWhiteBalanceController.setAmbientColorTemperatureOverride(cct);
1988             // The ambient color temperature override is only applied when the ambient color
1989             // temperature changes or is updated, so it doesn't necessarily change the screen color
1990             // temperature immediately. So, let's make it!
1991             sendUpdatePowerState();
1992         }
1993     }
1994 
1995     /**
1996      * Stores data about why the brightness was changed.  Made up of one main
1997      * {@code BrightnessReason.REASON_*} reason and various {@code BrightnessReason.MODIFIER_*}
1998      * modifiers.
1999      */
2000     private final class BrightnessReason {
2001         static final int REASON_UNKNOWN = 0;
2002         static final int REASON_MANUAL = 1;
2003         static final int REASON_DOZE = 2;
2004         static final int REASON_DOZE_DEFAULT = 3;
2005         static final int REASON_AUTOMATIC = 4;
2006         static final int REASON_SCREEN_OFF = 5;
2007         static final int REASON_VR = 6;
2008         static final int REASON_OVERRIDE = 7;
2009         static final int REASON_TEMPORARY = 8;
2010         static final int REASON_BOOST = 9;
2011         static final int REASON_MAX = REASON_BOOST;
2012 
2013         static final int MODIFIER_DIMMED = 0x1;
2014         static final int MODIFIER_LOW_POWER = 0x2;
2015         static final int MODIFIER_MASK = 0x3;
2016 
2017         // ADJUSTMENT_*
2018         // These things can happen at any point, even if the main brightness reason doesn't
2019         // fundamentally change, so they're not stored.
2020 
2021         // Auto-brightness adjustment factor changed
2022         static final int ADJUSTMENT_AUTO_TEMP = 0x1;
2023         // Temporary adjustment to the auto-brightness adjustment factor.
2024         static final int ADJUSTMENT_AUTO = 0x2;
2025 
2026         // One of REASON_*
2027         public int reason;
2028         // Any number of MODIFIER_*
2029         public int modifier;
2030 
set(BrightnessReason other)2031         public void set(BrightnessReason other) {
2032             setReason(other == null ? REASON_UNKNOWN : other.reason);
2033             setModifier(other == null ? 0 : other.modifier);
2034         }
2035 
setReason(int reason)2036         public void setReason(int reason) {
2037             if (reason < REASON_UNKNOWN || reason > REASON_MAX) {
2038                 Slog.w(TAG, "brightness reason out of bounds: " + reason);
2039             } else {
2040                 this.reason = reason;
2041             }
2042         }
2043 
setModifier(int modifier)2044         public void setModifier(int modifier) {
2045             if ((modifier & ~MODIFIER_MASK) != 0) {
2046                 Slog.w(TAG, "brightness modifier out of bounds: 0x"
2047                         + Integer.toHexString(modifier));
2048             } else {
2049                 this.modifier = modifier;
2050             }
2051         }
2052 
addModifier(int modifier)2053         public void addModifier(int modifier) {
2054             setModifier(modifier | this.modifier);
2055         }
2056 
2057         @Override
equals(Object obj)2058         public boolean equals(Object obj) {
2059             if (obj == null || !(obj instanceof BrightnessReason)) {
2060                 return false;
2061             }
2062             BrightnessReason other = (BrightnessReason) obj;
2063             return other.reason == reason && other.modifier == modifier;
2064         }
2065 
2066         @Override
toString()2067         public String toString() {
2068             return toString(0);
2069         }
2070 
toString(int adjustments)2071         public String toString(int adjustments) {
2072             final StringBuilder sb = new StringBuilder();
2073             sb.append(reasonToString(reason));
2074             sb.append(" [");
2075             if ((adjustments & ADJUSTMENT_AUTO_TEMP) != 0) {
2076                 sb.append(" temp_adj");
2077             }
2078             if ((adjustments & ADJUSTMENT_AUTO) != 0) {
2079                 sb.append(" auto_adj");
2080             }
2081             if ((modifier & MODIFIER_LOW_POWER) != 0) {
2082                 sb.append(" low_pwr");
2083             }
2084             if ((modifier & MODIFIER_DIMMED) != 0) {
2085                 sb.append(" dim");
2086             }
2087             int strlen = sb.length();
2088             if (sb.charAt(strlen - 1) == '[') {
2089                 sb.setLength(strlen - 2);
2090             } else {
2091                 sb.append(" ]");
2092             }
2093             return sb.toString();
2094         }
2095 
reasonToString(int reason)2096         private String reasonToString(int reason) {
2097             switch (reason) {
2098                 case REASON_MANUAL: return "manual";
2099                 case REASON_DOZE: return "doze";
2100                 case REASON_DOZE_DEFAULT: return "doze_default";
2101                 case REASON_AUTOMATIC: return "automatic";
2102                 case REASON_SCREEN_OFF: return "screen_off";
2103                 case REASON_VR: return "vr";
2104                 case REASON_OVERRIDE: return "override";
2105                 case REASON_TEMPORARY: return "temporary";
2106                 case REASON_BOOST: return "boost";
2107                 default: return Integer.toString(reason);
2108             }
2109         }
2110     }
2111 }
2112