• 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.NonNull;
22 import android.annotation.Nullable;
23 import android.annotation.UserIdInt;
24 import android.app.ActivityManager;
25 import android.content.Context;
26 import android.content.pm.ParceledListSlice;
27 import android.content.res.Resources;
28 import android.database.ContentObserver;
29 import android.hardware.Sensor;
30 import android.hardware.SensorEvent;
31 import android.hardware.SensorEventListener;
32 import android.hardware.SensorManager;
33 import android.hardware.display.AmbientBrightnessDayStats;
34 import android.hardware.display.BrightnessChangeEvent;
35 import android.hardware.display.BrightnessConfiguration;
36 import android.hardware.display.BrightnessInfo;
37 import android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks;
38 import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
39 import android.metrics.LogMaker;
40 import android.net.Uri;
41 import android.os.Handler;
42 import android.os.IBinder;
43 import android.os.Looper;
44 import android.os.Message;
45 import android.os.PowerManager;
46 import android.os.RemoteException;
47 import android.os.SystemClock;
48 import android.os.SystemProperties;
49 import android.os.Trace;
50 import android.os.UserHandle;
51 import android.provider.Settings;
52 import android.util.FloatProperty;
53 import android.util.Log;
54 import android.util.MathUtils;
55 import android.util.MutableFloat;
56 import android.util.MutableInt;
57 import android.util.Slog;
58 import android.util.SparseArray;
59 import android.util.TimeUtils;
60 import android.view.Display;
61 
62 import com.android.internal.R;
63 import com.android.internal.annotations.GuardedBy;
64 import com.android.internal.annotations.VisibleForTesting;
65 import com.android.internal.app.IBatteryStats;
66 import com.android.internal.display.BrightnessSynchronizer;
67 import com.android.internal.logging.MetricsLogger;
68 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
69 import com.android.internal.util.FrameworkStatsLog;
70 import com.android.internal.util.RingBuffer;
71 import com.android.server.LocalServices;
72 import com.android.server.am.BatteryStatsService;
73 import com.android.server.display.RampAnimator.DualRampAnimator;
74 import com.android.server.display.brightness.BrightnessEvent;
75 import com.android.server.display.brightness.BrightnessReason;
76 import com.android.server.display.color.ColorDisplayService.ColorDisplayServiceInternal;
77 import com.android.server.display.color.ColorDisplayService.ReduceBrightColorsListener;
78 import com.android.server.display.layout.Layout;
79 import com.android.server.display.utils.SensorUtils;
80 import com.android.server.display.whitebalance.DisplayWhiteBalanceController;
81 import com.android.server.display.whitebalance.DisplayWhiteBalanceFactory;
82 import com.android.server.display.whitebalance.DisplayWhiteBalanceSettings;
83 import com.android.server.policy.WindowManagerPolicy;
84 
85 import java.io.PrintWriter;
86 import java.util.Objects;
87 
88 /**
89  * Controls the power state of the display.
90  *
91  * Handles the proximity sensor, light sensor, and animations between states
92  * including the screen off animation.
93  *
94  * This component acts independently of the rest of the power manager service.
95  * In particular, it does not share any state and it only communicates
96  * via asynchronous callbacks to inform the power manager that something has
97  * changed.
98  *
99  * Everything this class does internally is serialized on its handler although
100  * it may be accessed by other threads from the outside.
101  *
102  * Note that the power manager service guarantees that it will hold a suspend
103  * blocker as long as the display is not ready.  So most of the work done here
104  * does not need to worry about holding a suspend blocker unless it happens
105  * independently of the display ready signal.
106  *
107  * For debugging, you can make the color fade and brightness animations run
108  * slower by changing the "animator duration scale" option in Development Settings.
109  */
110 final class DisplayPowerController implements AutomaticBrightnessController.Callbacks,
111         DisplayWhiteBalanceController.Callbacks, DisplayPowerControllerInterface {
112     private static final String SCREEN_ON_BLOCKED_TRACE_NAME = "Screen on blocked";
113     private static final String SCREEN_OFF_BLOCKED_TRACE_NAME = "Screen off blocked";
114 
115     private static final boolean DEBUG = false;
116     private static final boolean DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT = false;
117 
118     // If true, uses the color fade on animation.
119     // We might want to turn this off if we cannot get a guarantee that the screen
120     // actually turns on and starts showing new content after the call to set the
121     // screen state returns.  Playing the animation can also be somewhat slow.
122     private static final boolean USE_COLOR_FADE_ON_ANIMATION = false;
123 
124     private static final float SCREEN_ANIMATION_RATE_MINIMUM = 0.0f;
125 
126     private static final int COLOR_FADE_ON_ANIMATION_DURATION_MILLIS = 250;
127     private static final int COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS = 400;
128 
129     private static final int MSG_UPDATE_POWER_STATE = 1;
130     private static final int MSG_PROXIMITY_SENSOR_DEBOUNCED = 2;
131     private static final int MSG_SCREEN_ON_UNBLOCKED = 3;
132     private static final int MSG_SCREEN_OFF_UNBLOCKED = 4;
133     private static final int MSG_CONFIGURE_BRIGHTNESS = 5;
134     private static final int MSG_SET_TEMPORARY_BRIGHTNESS = 6;
135     private static final int MSG_SET_TEMPORARY_AUTO_BRIGHTNESS_ADJUSTMENT = 7;
136     private static final int MSG_IGNORE_PROXIMITY = 8;
137     private static final int MSG_STOP = 9;
138     private static final int MSG_UPDATE_BRIGHTNESS = 10;
139     private static final int MSG_UPDATE_RBC = 11;
140     private static final int MSG_BRIGHTNESS_RAMP_DONE = 12;
141     private static final int MSG_STATSD_HBM_BRIGHTNESS = 13;
142     private static final int MSG_SWITCH_USER = 14;
143     private static final int MSG_BOOT_COMPLETED = 15;
144     private static final int MSG_SET_DWBC_STRONG_MODE = 16;
145     private static final int MSG_SET_DWBC_COLOR_OVERRIDE = 17;
146     private static final int MSG_SET_DWBC_LOGGING_ENABLED = 18;
147 
148     private static final int PROXIMITY_UNKNOWN = -1;
149     private static final int PROXIMITY_NEGATIVE = 0;
150     private static final int PROXIMITY_POSITIVE = 1;
151 
152     // Proximity sensor debounce delay in milliseconds for positive or negative transitions.
153     private static final int PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY = 0;
154     private static final int PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY = 250;
155 
156     private static final int BRIGHTNESS_CHANGE_STATSD_REPORT_INTERVAL_MS = 500;
157 
158     // Trigger proximity if distance is less than 5 cm.
159     private static final float TYPICAL_PROXIMITY_THRESHOLD = 5.0f;
160 
161     // State machine constants for tracking initial brightness ramp skipping when enabled.
162     private static final int RAMP_STATE_SKIP_NONE = 0;
163     private static final int RAMP_STATE_SKIP_INITIAL = 1;
164     private static final int RAMP_STATE_SKIP_AUTOBRIGHT = 2;
165 
166     private static final int REPORTED_TO_POLICY_UNREPORTED = -1;
167     private static final int REPORTED_TO_POLICY_SCREEN_OFF = 0;
168     private static final int REPORTED_TO_POLICY_SCREEN_TURNING_ON = 1;
169     private static final int REPORTED_TO_POLICY_SCREEN_ON = 2;
170     private static final int REPORTED_TO_POLICY_SCREEN_TURNING_OFF = 3;
171 
172     private static final int RINGBUFFER_MAX = 100;
173 
174     private static final float[] BRIGHTNESS_RANGE_BOUNDARIES = {
175         0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60, 70, 80,
176         90, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1200,
177         1400, 1600, 1800, 2000, 2250, 2500, 2750, 3000};
178     private static final int[] BRIGHTNESS_RANGE_INDEX = {
179         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_UNKNOWN,
180         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_0_1,
181         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1_2,
182         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2_3,
183         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_3_4,
184         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_4_5,
185         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_5_6,
186         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_6_7,
187         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_7_8,
188         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_8_9,
189         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_9_10,
190         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_10_20,
191         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_20_30,
192         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_30_40,
193         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_40_50,
194         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_50_60,
195         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_60_70,
196         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_70_80,
197         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_80_90,
198         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_90_100,
199         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_100_200,
200         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_200_300,
201         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_300_400,
202         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_400_500,
203         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_500_600,
204         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_600_700,
205         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_700_800,
206         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_800_900,
207         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_900_1000,
208         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1000_1200,
209         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1200_1400,
210         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1400_1600,
211         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1600_1800,
212         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1800_2000,
213         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2000_2250,
214         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2250_2500,
215         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2500_2750,
216         FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2750_3000,
217     };
218 
219     private final String mTag;
220 
221     private final Object mLock = new Object();
222 
223     private final Context mContext;
224 
225     // Our handler.
226     private final DisplayControllerHandler mHandler;
227 
228     // Asynchronous callbacks into the power manager service.
229     // Only invoked from the handler thread while no locks are held.
230     private final DisplayPowerCallbacks mCallbacks;
231 
232     // Battery stats.
233     @Nullable
234     private final IBatteryStats mBatteryStats;
235 
236     // The sensor manager.
237     private final SensorManager mSensorManager;
238 
239     // The window manager policy.
240     private final WindowManagerPolicy mWindowManagerPolicy;
241 
242     // The display blanker.
243     private final DisplayBlanker mBlanker;
244 
245     // The LogicalDisplay tied to this DisplayPowerController.
246     private final LogicalDisplay mLogicalDisplay;
247 
248     // The ID of the LogicalDisplay tied to this DisplayPowerController.
249     private final int mDisplayId;
250 
251     // The ID of the display which this display follows for brightness purposes.
252     private int mLeadDisplayId = Layout.NO_LEAD_DISPLAY;
253 
254     // The unique ID of the primary display device currently tied to this logical display
255     private String mUniqueDisplayId;
256 
257     // Tracker for brightness changes.
258     @Nullable
259     private final BrightnessTracker mBrightnessTracker;
260 
261     // Tracker for brightness settings changes.
262     private final SettingsObserver mSettingsObserver;
263 
264     // The proximity sensor, or null if not available or needed.
265     private Sensor mProximitySensor;
266 
267     // The doze screen brightness.
268     private final float mScreenBrightnessDozeConfig;
269 
270     // The dim screen brightness.
271     private final float mScreenBrightnessDimConfig;
272 
273     // The minimum dim amount to use if the screen brightness is already below
274     // mScreenBrightnessDimConfig.
275     private final float mScreenBrightnessMinimumDimAmount;
276 
277     private final float mScreenBrightnessDefault;
278 
279     // True if auto-brightness should be used.
280     private boolean mUseSoftwareAutoBrightnessConfig;
281 
282     // True if should use light sensor to automatically determine doze screen brightness.
283     private final boolean mAllowAutoBrightnessWhileDozingConfig;
284 
285     // True if we want to persist the brightness value in nits even if the underlying display
286     // device changes.
287     private final boolean mPersistBrightnessNitsForDefaultDisplay;
288 
289     // True if the brightness config has changed and the short-term model needs to be reset
290     private boolean mShouldResetShortTermModel;
291 
292     // Whether or not the color fade on screen on / off is enabled.
293     private final boolean mColorFadeEnabled;
294 
295     @GuardedBy("mCachedBrightnessInfo")
296     private final CachedBrightnessInfo mCachedBrightnessInfo = new CachedBrightnessInfo();
297 
298     private DisplayDevice mDisplayDevice;
299 
300     // True if we should fade the screen while turning it off, false if we should play
301     // a stylish color fade animation instead.
302     private final boolean mColorFadeFadesConfig;
303 
304     // True if we need to fake a transition to off when coming out of a doze state.
305     // Some display hardware will blank itself when coming out of doze in order to hide
306     // artifacts. For these displays we fake a transition into OFF so that policy can appropriately
307     // blank itself and begin an appropriate power on animation.
308     private final boolean mDisplayBlanksAfterDozeConfig;
309 
310     // True if there are only buckets of brightness values when the display is in the doze state,
311     // rather than a full range of values. If this is true, then we'll avoid animating the screen
312     // brightness since it'd likely be multiple jarring brightness transitions instead of just one
313     // to reach the final state.
314     private final boolean mBrightnessBucketsInDozeConfig;
315 
316     private final Clock mClock;
317     private final Injector mInjector;
318 
319     //  Maximum time a ramp animation can take.
320     private long mBrightnessRampIncreaseMaxTimeMillis;
321     private long mBrightnessRampDecreaseMaxTimeMillis;
322 
323     // The pending power request.
324     // Initially null until the first call to requestPowerState.
325     @GuardedBy("mLock")
326     private DisplayPowerRequest mPendingRequestLocked;
327 
328     // True if a request has been made to wait for the proximity sensor to go negative.
329     @GuardedBy("mLock")
330     private boolean mPendingWaitForNegativeProximityLocked;
331 
332     // True if the pending power request or wait for negative proximity flag
333     // has been changed since the last update occurred.
334     @GuardedBy("mLock")
335     private boolean mPendingRequestChangedLocked;
336 
337     // Set to true when the important parts of the pending power request have been applied.
338     // The important parts are mainly the screen state.  Brightness changes may occur
339     // concurrently.
340     @GuardedBy("mLock")
341     private boolean mDisplayReadyLocked;
342 
343     // Set to true if a power state update is required.
344     @GuardedBy("mLock")
345     private boolean mPendingUpdatePowerStateLocked;
346 
347     /* The following state must only be accessed by the handler thread. */
348 
349     // The currently requested power state.
350     // The power controller will progressively update its internal state to match
351     // the requested power state.  Initially null until the first update.
352     private DisplayPowerRequest mPowerRequest;
353 
354     // The current power state.
355     // Must only be accessed on the handler thread.
356     private DisplayPowerState mPowerState;
357 
358     // True if the device should wait for negative proximity sensor before
359     // waking up the screen.  This is set to false as soon as a negative
360     // proximity sensor measurement is observed or when the device is forced to
361     // go to sleep by the user.  While true, the screen remains off.
362     private boolean mWaitingForNegativeProximity;
363 
364     // True if the device should not take into account the proximity sensor
365     // until either the proximity sensor state changes, or there is no longer a
366     // request to listen to proximity sensor.
367     private boolean mIgnoreProximityUntilChanged;
368 
369     // The actual proximity sensor threshold value.
370     private float mProximityThreshold;
371 
372     // Set to true if the proximity sensor listener has been registered
373     // with the sensor manager.
374     private boolean mProximitySensorEnabled;
375 
376     // The debounced proximity sensor state.
377     private int mProximity = PROXIMITY_UNKNOWN;
378 
379     // The raw non-debounced proximity sensor state.
380     private int mPendingProximity = PROXIMITY_UNKNOWN;
381     private long mPendingProximityDebounceTime = -1; // -1 if fully debounced
382 
383     // True if the screen was turned off because of the proximity sensor.
384     // When the screen turns on again, we report user activity to the power manager.
385     private boolean mScreenOffBecauseOfProximity;
386 
387     // The currently active screen on unblocker.  This field is non-null whenever
388     // we are waiting for a callback to release it and unblock the screen.
389     private ScreenOnUnblocker mPendingScreenOnUnblocker;
390     private ScreenOffUnblocker mPendingScreenOffUnblocker;
391 
392     // True if we were in the process of turning off the screen.
393     // This allows us to recover more gracefully from situations where we abort
394     // turning off the screen.
395     private boolean mPendingScreenOff;
396 
397     // True if we have unfinished business and are holding a suspend blocker.
398     private boolean mUnfinishedBusiness;
399 
400     // The elapsed real time when the screen on was blocked.
401     private long mScreenOnBlockStartRealTime;
402     private long mScreenOffBlockStartRealTime;
403 
404     // Screen state we reported to policy. Must be one of REPORTED_TO_POLICY_* fields.
405     private int mReportedScreenStateToPolicy = REPORTED_TO_POLICY_UNREPORTED;
406 
407     // If the last recorded screen state was dozing or not.
408     private boolean mDozing;
409 
410     // Remembers whether certain kinds of brightness adjustments
411     // were recently applied so that we can decide how to transition.
412     private boolean mAppliedAutoBrightness;
413     private boolean mAppliedDimming;
414     private boolean mAppliedLowPower;
415     private boolean mAppliedScreenBrightnessOverride;
416     private boolean mAppliedTemporaryBrightness;
417     private boolean mAppliedTemporaryAutoBrightnessAdjustment;
418     private boolean mAppliedBrightnessBoost;
419     private boolean mAppliedThrottling;
420 
421     // Reason for which the brightness was last changed. See {@link BrightnessReason} for more
422     // information.
423     // At the time of this writing, this value is changed within updatePowerState() only, which is
424     // limited to the thread used by DisplayControllerHandler.
425     private final BrightnessReason mBrightnessReason = new BrightnessReason();
426     private final BrightnessReason mBrightnessReasonTemp = new BrightnessReason();
427 
428     // Brightness animation ramp rates in brightness units per second
429     private float mBrightnessRampRateFastDecrease;
430     private float mBrightnessRampRateFastIncrease;
431     private float mBrightnessRampRateSlowDecrease;
432     private float mBrightnessRampRateSlowIncrease;
433 
434     // Report HBM brightness change to StatsD
435     private int mDisplayStatsId;
436     private float mLastStatsBrightness = PowerManager.BRIGHTNESS_MIN;
437 
438     // Whether or not to skip the initial brightness ramps into STATE_ON.
439     private final boolean mSkipScreenOnBrightnessRamp;
440 
441     // Display white balance components.
442     // Critical methods must be called on DPC handler thread.
443     @Nullable
444     private final DisplayWhiteBalanceSettings mDisplayWhiteBalanceSettings;
445     @Nullable
446     private final DisplayWhiteBalanceController mDisplayWhiteBalanceController;
447 
448     @Nullable
449     private final ColorDisplayServiceInternal mCdsi;
450     private float[] mNitsRange;
451 
452     private final BrightnessRangeController mBrightnessRangeController;
453 
454     @Nullable
455     private final HighBrightnessModeMetadata mHighBrightnessModeMetadata;
456 
457     private final BrightnessThrottler mBrightnessThrottler;
458 
459     private final BrightnessSetting mBrightnessSetting;
460 
461     private final Runnable mOnBrightnessChangeRunnable;
462 
463     private final BrightnessEvent mLastBrightnessEvent;
464     private final BrightnessEvent mTempBrightnessEvent;
465 
466     // Keeps a record of brightness changes for dumpsys.
467     private RingBuffer<BrightnessEvent> mBrightnessEventRingBuffer;
468 
469     // A record of state for skipping brightness ramps.
470     private int mSkipRampState = RAMP_STATE_SKIP_NONE;
471 
472     // The first autobrightness value set when entering RAMP_STATE_SKIP_INITIAL.
473     private float mInitialAutoBrightness;
474 
475     // The controller for the automatic brightness level.
476     @Nullable
477     private AutomaticBrightnessController mAutomaticBrightnessController;
478 
479     // The controller for the sensor used to estimate ambient lux while the display is off.
480     @Nullable
481     private ScreenOffBrightnessSensorController mScreenOffBrightnessSensorController;
482 
483     private Sensor mLightSensor;
484     private Sensor mScreenOffBrightnessSensor;
485 
486     // The mappers between ambient lux, display backlight values, and display brightness.
487     // We will switch between the idle mapper and active mapper in AutomaticBrightnessController.
488     // Mapper used for active (normal) screen brightness mode
489     @Nullable
490     private BrightnessMappingStrategy mInteractiveModeBrightnessMapper;
491     // Mapper used for idle screen brightness mode
492     @Nullable
493     private BrightnessMappingStrategy mIdleModeBrightnessMapper;
494 
495     // The current brightness configuration.
496     @Nullable
497     private BrightnessConfiguration mBrightnessConfiguration;
498 
499     // The last brightness that was set by the user and not temporary. Set to
500     // PowerManager.BRIGHTNESS_INVALID_FLOAT when a brightness has yet to be recorded.
501     private float mLastUserSetScreenBrightness = Float.NaN;
502 
503     // The screen brightness setting has changed but not taken effect yet. If this is different
504     // from the current screen brightness setting then this is coming from something other than us
505     // and should be considered a user interaction.
506     private float mPendingScreenBrightnessSetting;
507 
508     // The last observed screen brightness setting, either set by us or by the settings app on
509     // behalf of the user.
510     private float mCurrentScreenBrightnessSetting;
511 
512     // The temporary screen brightness. Typically set when a user is interacting with the
513     // brightness slider but hasn't settled on a choice yet. Set to
514     // PowerManager.BRIGHTNESS_INVALID_FLOAT when there's no temporary brightness set.
515     private float mTemporaryScreenBrightness;
516 
517     // This brightness value is set in concurrent displays mode. It is the brightness value
518     // of the lead display that this DPC should follow.
519     private float mBrightnessToFollow;
520 
521     // Indicates whether we should ramp slowly to the brightness value to follow.
522     private boolean mBrightnessToFollowSlowChange;
523 
524     // The last auto brightness adjustment that was set by the user and not temporary. Set to
525     // Float.NaN when an auto-brightness adjustment hasn't been recorded yet.
526     private float mAutoBrightnessAdjustment;
527 
528     // The pending auto brightness adjustment that will take effect on the next power state update.
529     private float mPendingAutoBrightnessAdjustment;
530 
531     // The temporary auto brightness adjustment. Typically set when a user is interacting with the
532     // adjustment slider but hasn't settled on a choice yet. Set to
533     // PowerManager.BRIGHTNESS_INVALID_FLOAT when there's no temporary adjustment set.
534     private float mTemporaryAutoBrightnessAdjustment;
535 
536     private boolean mUseAutoBrightness;
537 
538     private boolean mIsRbcActive;
539 
540     // Whether there's a callback to tell listeners the display has changed scheduled to run. When
541     // true it implies a wakelock is being held to guarantee the update happens before we collapse
542     // into suspend and so needs to be cleaned up if the thread is exiting.
543     // Should only be accessed on the Handler thread.
544     private boolean mOnStateChangedPending;
545 
546     // Count of proximity messages currently on this DPC's Handler. Used to keep track of how many
547     // suspend blocker acquisitions are pending when shutting down this DPC.
548     // Should only be accessed on the Handler thread.
549     private int mOnProximityPositiveMessages;
550     private int mOnProximityNegativeMessages;
551 
552     // Animators.
553     private ObjectAnimator mColorFadeOnAnimator;
554     private ObjectAnimator mColorFadeOffAnimator;
555     private DualRampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator;
556     private BrightnessSetting.BrightnessSettingListener mBrightnessSettingListener;
557 
558     // True if this DisplayPowerController has been stopped and should no longer be running.
559     private boolean mStopped;
560 
561     private DisplayDeviceConfig mDisplayDeviceConfig;
562 
563     // Identifiers for suspend blocker acquisition requests
564     private final String mSuspendBlockerIdUnfinishedBusiness;
565     private final String mSuspendBlockerIdOnStateChanged;
566     private final String mSuspendBlockerIdProxPositive;
567     private final String mSuspendBlockerIdProxNegative;
568     private final String mSuspendBlockerIdProxDebounce;
569 
570     private boolean mIsEnabled;
571     private boolean mIsInTransition;
572     private boolean mIsDisplayInternal;
573 
574     // The id of the thermal brightness throttling policy that should be used.
575     private String mThermalBrightnessThrottlingDataId;
576 
577     // DPCs following the brightness of this DPC. This is used in concurrent displays mode - there
578     // is one lead display, the additional displays follow the brightness value of the lead display.
579     @GuardedBy("mLock")
580     private final SparseArray<DisplayPowerControllerInterface> mDisplayBrightnessFollowers =
581             new SparseArray<>();
582 
583     private boolean mBootCompleted;
584 
585     /**
586      * Creates the display power controller.
587      */
DisplayPowerController(Context context, Injector injector, DisplayPowerCallbacks callbacks, Handler handler, SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay, BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting, Runnable onBrightnessChangeRunnable, HighBrightnessModeMetadata hbmMetadata, boolean bootCompleted)588     DisplayPowerController(Context context, Injector injector,
589             DisplayPowerCallbacks callbacks, Handler handler,
590             SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay,
591             BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting,
592             Runnable onBrightnessChangeRunnable, HighBrightnessModeMetadata hbmMetadata,
593             boolean bootCompleted) {
594 
595         mInjector = injector != null ? injector : new Injector();
596         mClock = mInjector.getClock();
597         mLogicalDisplay = logicalDisplay;
598         mDisplayId = mLogicalDisplay.getDisplayIdLocked();
599         mTag = "DisplayPowerController[" + mDisplayId + "]";
600         mHighBrightnessModeMetadata = hbmMetadata;
601         mSuspendBlockerIdUnfinishedBusiness = getSuspendBlockerUnfinishedBusinessId(mDisplayId);
602         mSuspendBlockerIdOnStateChanged = getSuspendBlockerOnStateChangedId(mDisplayId);
603         mSuspendBlockerIdProxPositive = getSuspendBlockerProxPositiveId(mDisplayId);
604         mSuspendBlockerIdProxNegative = getSuspendBlockerProxNegativeId(mDisplayId);
605         mSuspendBlockerIdProxDebounce = getSuspendBlockerProxDebounceId(mDisplayId);
606 
607         mDisplayDevice = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
608         mUniqueDisplayId = logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId();
609         mDisplayStatsId = mUniqueDisplayId.hashCode();
610         mIsEnabled = logicalDisplay.isEnabledLocked();
611         mIsInTransition = logicalDisplay.isInTransitionLocked();
612         mIsDisplayInternal = logicalDisplay.getPrimaryDisplayDeviceLocked()
613                 .getDisplayDeviceInfoLocked().type == Display.TYPE_INTERNAL;
614         mHandler = new DisplayControllerHandler(handler.getLooper());
615         mLastBrightnessEvent = new BrightnessEvent(mDisplayId);
616         mTempBrightnessEvent = new BrightnessEvent(mDisplayId);
617         mThermalBrightnessThrottlingDataId =
618                 logicalDisplay.getDisplayInfoLocked().thermalBrightnessThrottlingDataId;
619 
620         if (mDisplayId == Display.DEFAULT_DISPLAY) {
621             mBatteryStats = BatteryStatsService.getService();
622         } else {
623             mBatteryStats = null;
624         }
625 
626         mSettingsObserver = new SettingsObserver(mHandler);
627         mCallbacks = callbacks;
628         mSensorManager = sensorManager;
629         mWindowManagerPolicy = LocalServices.getService(WindowManagerPolicy.class);
630         mBlanker = blanker;
631         mContext = context;
632         mBrightnessTracker = brightnessTracker;
633         // TODO: b/186428377 update brightness setting when display changes
634         mBrightnessSetting = brightnessSetting;
635         mOnBrightnessChangeRunnable = onBrightnessChangeRunnable;
636 
637         PowerManager pm = context.getSystemService(PowerManager.class);
638 
639         final Resources resources = context.getResources();
640 
641         // DOZE AND DIM SETTINGS
642         mScreenBrightnessDozeConfig = clampAbsoluteBrightness(
643                 pm.getBrightnessConstraint(PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DOZE));
644         mScreenBrightnessDimConfig = clampAbsoluteBrightness(
645                 pm.getBrightnessConstraint(PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DIM));
646         mScreenBrightnessMinimumDimAmount = resources.getFloat(
647                 com.android.internal.R.dimen.config_screenBrightnessMinimumDimAmountFloat);
648 
649 
650         // NORMAL SCREEN SETTINGS
651         mScreenBrightnessDefault = clampAbsoluteBrightness(
652                 mLogicalDisplay.getDisplayInfoLocked().brightnessDefault);
653 
654         mAllowAutoBrightnessWhileDozingConfig = resources.getBoolean(
655                 com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing);
656 
657         mPersistBrightnessNitsForDefaultDisplay = resources.getBoolean(
658                 com.android.internal.R.bool.config_persistBrightnessNitsForDefaultDisplay);
659 
660         mDisplayDeviceConfig = logicalDisplay.getPrimaryDisplayDeviceLocked()
661                 .getDisplayDeviceConfig();
662 
663         loadBrightnessRampRates();
664         mSkipScreenOnBrightnessRamp = resources.getBoolean(
665                 com.android.internal.R.bool.config_skipScreenOnBrightnessRamp);
666         Runnable modeChangeCallback = () -> {
667             sendUpdatePowerState();
668             postBrightnessChangeRunnable();
669             // TODO(b/192258832): Switch the HBMChangeCallback to a listener pattern.
670             if (mAutomaticBrightnessController != null) {
671                 mAutomaticBrightnessController.update();
672             }
673         };
674 
675         HighBrightnessModeController hbmController = createHbmControllerLocked(modeChangeCallback);
676 
677         mBrightnessRangeController = new BrightnessRangeController(hbmController,
678                 modeChangeCallback, mDisplayDeviceConfig, resources);
679 
680         mBrightnessThrottler = createBrightnessThrottlerLocked();
681 
682         // Seed the cached brightness
683         saveBrightnessInfo(getScreenBrightnessSetting());
684 
685         DisplayWhiteBalanceSettings displayWhiteBalanceSettings = null;
686         DisplayWhiteBalanceController displayWhiteBalanceController = null;
687         if (mDisplayId == Display.DEFAULT_DISPLAY) {
688             try {
689                 displayWhiteBalanceController = injector.getDisplayWhiteBalanceController(
690                         mHandler, mSensorManager, resources);
691                 displayWhiteBalanceSettings = new DisplayWhiteBalanceSettings(mContext, mHandler);
692                 displayWhiteBalanceSettings.setCallbacks(this);
693                 displayWhiteBalanceController.setCallbacks(this);
694             } catch (Exception e) {
695                 Slog.e(mTag, "failed to set up display white-balance: " + e);
696             }
697         }
698         mDisplayWhiteBalanceSettings = displayWhiteBalanceSettings;
699         mDisplayWhiteBalanceController = displayWhiteBalanceController;
700 
701         loadNitsRange(resources);
702 
703         if (mDisplayId == Display.DEFAULT_DISPLAY) {
704             mCdsi = LocalServices.getService(ColorDisplayServiceInternal.class);
705             boolean active = mCdsi.setReduceBrightColorsListener(new ReduceBrightColorsListener() {
706                 @Override
707                 public void onReduceBrightColorsActivationChanged(boolean activated,
708                         boolean userInitiated) {
709                     applyReduceBrightColorsSplineAdjustment();
710 
711                 }
712 
713                 @Override
714                 public void onReduceBrightColorsStrengthChanged(int strength) {
715                     applyReduceBrightColorsSplineAdjustment();
716                 }
717             });
718             if (active) {
719                 applyReduceBrightColorsSplineAdjustment();
720             }
721         } else {
722             mCdsi = null;
723         }
724 
725         setUpAutoBrightness(resources, handler);
726 
727         mColorFadeEnabled = !ActivityManager.isLowRamDeviceStatic()
728                 && !resources.getBoolean(
729                   com.android.internal.R.bool.config_displayColorFadeDisabled);
730         mColorFadeFadesConfig = resources.getBoolean(
731                 com.android.internal.R.bool.config_animateScreenLights);
732 
733         mDisplayBlanksAfterDozeConfig = resources.getBoolean(
734                 com.android.internal.R.bool.config_displayBlanksAfterDoze);
735 
736         mBrightnessBucketsInDozeConfig = resources.getBoolean(
737                 com.android.internal.R.bool.config_displayBrightnessBucketsInDoze);
738 
739         loadProximitySensor();
740 
741         loadNitBasedBrightnessSetting();
742         mBrightnessToFollow = PowerManager.BRIGHTNESS_INVALID_FLOAT;
743         mAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting();
744         mTemporaryScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
745         mPendingScreenBrightnessSetting = PowerManager.BRIGHTNESS_INVALID_FLOAT;
746         mTemporaryAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT;
747         mPendingAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT;
748 
749         mBootCompleted = bootCompleted;
750     }
751 
applyReduceBrightColorsSplineAdjustment()752     private void applyReduceBrightColorsSplineAdjustment() {
753         mHandler.obtainMessage(MSG_UPDATE_RBC).sendToTarget();
754         sendUpdatePowerState();
755     }
756 
handleRbcChanged()757     private void handleRbcChanged() {
758         if (mAutomaticBrightnessController == null) {
759             return;
760         }
761         if ((!mAutomaticBrightnessController.isInIdleMode()
762                 && mInteractiveModeBrightnessMapper == null)
763                 || (mAutomaticBrightnessController.isInIdleMode()
764                 && mIdleModeBrightnessMapper == null)) {
765             Log.w(mTag, "No brightness mapping available to recalculate splines for this mode");
766             return;
767         }
768 
769         float[] adjustedNits = new float[mNitsRange.length];
770         for (int i = 0; i < mNitsRange.length; i++) {
771             adjustedNits[i] = mCdsi.getReduceBrightColorsAdjustedBrightnessNits(mNitsRange[i]);
772         }
773         mIsRbcActive = mCdsi.isReduceBrightColorsActivated();
774         mAutomaticBrightnessController.recalculateSplines(mIsRbcActive, adjustedNits);
775     }
776 
777     /**
778      * Returns true if the proximity sensor screen-off function is available.
779      */
780     @Override
isProximitySensorAvailable()781     public boolean isProximitySensorAvailable() {
782         return mProximitySensor != null;
783     }
784 
785     /**
786      * Get the {@link BrightnessChangeEvent}s for the specified user.
787      *
788      * @param userId         userId to fetch data for
789      * @param includePackage if false will null out the package name in events
790      */
791     @Nullable
792     @Override
getBrightnessEvents( @serIdInt int userId, boolean includePackage)793     public ParceledListSlice<BrightnessChangeEvent> getBrightnessEvents(
794             @UserIdInt int userId, boolean includePackage) {
795         if (mBrightnessTracker == null) {
796             return null;
797         }
798         return mBrightnessTracker.getEvents(userId, includePackage);
799     }
800 
801     @Override
onSwitchUser(@serIdInt int newUserId)802     public void onSwitchUser(@UserIdInt int newUserId) {
803         Message msg = mHandler.obtainMessage(MSG_SWITCH_USER, newUserId);
804         mHandler.sendMessage(msg);
805     }
806 
handleOnSwitchUser(@serIdInt int newUserId)807     private void handleOnSwitchUser(@UserIdInt int newUserId) {
808         handleSettingsChange(true /* userSwitch */);
809         handleBrightnessModeChange();
810         if (mBrightnessTracker != null) {
811             mBrightnessTracker.onSwitchUser(newUserId);
812         }
813     }
814 
815     @Override
getDisplayId()816     public int getDisplayId() {
817         return mDisplayId;
818     }
819 
820     @Override
getLeadDisplayId()821     public int getLeadDisplayId() {
822         return mLeadDisplayId;
823     }
824 
825     @Override
setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux, boolean slowChange)826     public void setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux,
827             boolean slowChange) {
828         mBrightnessRangeController.onAmbientLuxChange(ambientLux);
829         if (nits < 0) {
830             mBrightnessToFollow = leadDisplayBrightness;
831         } else {
832             float brightness = convertToFloatScale(nits);
833             if (isValidBrightnessValue(brightness)) {
834                 mBrightnessToFollow = brightness;
835             } else {
836                 // The device does not support nits
837                 mBrightnessToFollow = leadDisplayBrightness;
838             }
839         }
840         mBrightnessToFollowSlowChange = slowChange;
841         sendUpdatePowerState();
842     }
843 
844     @Override
addDisplayBrightnessFollower(@onNull DisplayPowerControllerInterface follower)845     public void addDisplayBrightnessFollower(@NonNull DisplayPowerControllerInterface follower) {
846         synchronized (mLock) {
847             mDisplayBrightnessFollowers.append(follower.getDisplayId(), follower);
848             sendUpdatePowerStateLocked();
849         }
850     }
851 
852     @Override
removeDisplayBrightnessFollower(@onNull DisplayPowerControllerInterface follower)853     public void removeDisplayBrightnessFollower(@NonNull DisplayPowerControllerInterface follower) {
854         synchronized (mLock) {
855             mDisplayBrightnessFollowers.remove(follower.getDisplayId());
856             mHandler.postAtTime(() -> follower.setBrightnessToFollow(
857                     PowerManager.BRIGHTNESS_INVALID_FLOAT, /* nits= */ -1,
858                     /* ambientLux= */ 0, /* slowChange= */ false), mClock.uptimeMillis());
859         }
860     }
861 
862     @GuardedBy("mLock")
clearDisplayBrightnessFollowersLocked()863     private void clearDisplayBrightnessFollowersLocked() {
864         for (int i = 0; i < mDisplayBrightnessFollowers.size(); i++) {
865             DisplayPowerControllerInterface follower = mDisplayBrightnessFollowers.valueAt(i);
866             mHandler.postAtTime(() -> follower.setBrightnessToFollow(
867                     PowerManager.BRIGHTNESS_INVALID_FLOAT, /* nits= */ -1,
868                     /* ambientLux= */ 0, /* slowChange= */ false), mClock.uptimeMillis());
869         }
870         mDisplayBrightnessFollowers.clear();
871     }
872 
873     @Nullable
874     @Override
getAmbientBrightnessStats( @serIdInt int userId)875     public ParceledListSlice<AmbientBrightnessDayStats> getAmbientBrightnessStats(
876             @UserIdInt int userId) {
877         if (mBrightnessTracker == null) {
878             return null;
879         }
880         return mBrightnessTracker.getAmbientBrightnessStats(userId);
881     }
882 
883     /**
884      * Persist the brightness slider events and ambient brightness stats to disk.
885      */
886     @Override
persistBrightnessTrackerState()887     public void persistBrightnessTrackerState() {
888         if (mBrightnessTracker != null) {
889             mBrightnessTracker.persistBrightnessTrackerState();
890         }
891     }
892 
893     /**
894      * Requests a new power state.
895      * The controller makes a copy of the provided object and then
896      * begins adjusting the power state to match what was requested.
897      *
898      * @param request                  The requested power state.
899      * @param waitForNegativeProximity If true, issues a request to wait for
900      *                                 negative proximity before turning the screen back on,
901      *                                 assuming the screen
902      *                                 was turned off by the proximity sensor.
903      * @return True if display is ready, false if there are important changes that must
904      * be made asynchronously (such as turning the screen on), in which case the caller
905      * should grab a wake lock, watch for {@link DisplayPowerCallbacks#onStateChanged()}
906      * then try the request again later until the state converges.
907      */
requestPowerState(DisplayPowerRequest request, boolean waitForNegativeProximity)908     public boolean requestPowerState(DisplayPowerRequest request,
909             boolean waitForNegativeProximity) {
910         if (DEBUG) {
911             Slog.d(mTag, "requestPowerState: "
912                     + request + ", waitForNegativeProximity=" + waitForNegativeProximity);
913         }
914 
915         synchronized (mLock) {
916             if (mStopped) {
917                 return true;
918             }
919 
920             boolean changed = false;
921 
922             if (waitForNegativeProximity
923                     && !mPendingWaitForNegativeProximityLocked) {
924                 mPendingWaitForNegativeProximityLocked = true;
925                 changed = true;
926             }
927 
928             if (mPendingRequestLocked == null) {
929                 mPendingRequestLocked = new DisplayPowerRequest(request);
930                 changed = true;
931             } else if (!mPendingRequestLocked.equals(request)) {
932                 mPendingRequestLocked.copyFrom(request);
933                 changed = true;
934             }
935 
936             if (changed) {
937                 mDisplayReadyLocked = false;
938                 if (!mPendingRequestChangedLocked) {
939                     mPendingRequestChangedLocked = true;
940                     sendUpdatePowerStateLocked();
941                 }
942             }
943 
944             return mDisplayReadyLocked;
945         }
946     }
947 
948     @Override
getDefaultBrightnessConfiguration()949     public BrightnessConfiguration getDefaultBrightnessConfiguration() {
950         if (mAutomaticBrightnessController == null) {
951             return null;
952         }
953         return mAutomaticBrightnessController.getDefaultConfig();
954     }
955 
956     /**
957      * Notified when the display is changed. We use this to apply any changes that might be needed
958      * when displays get swapped on foldable devices.  For example, different brightness properties
959      * of each display need to be properly reflected in AutomaticBrightnessController.
960      *
961      * Make sure DisplayManagerService.mSyncRoot is held when this is called
962      */
963     @Override
onDisplayChanged(HighBrightnessModeMetadata hbmMetadata, int leadDisplayId)964     public void onDisplayChanged(HighBrightnessModeMetadata hbmMetadata, int leadDisplayId) {
965         mLeadDisplayId = leadDisplayId;
966         final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
967         if (device == null) {
968             Slog.wtf(mTag, "Display Device is null in DisplayPowerController for display: "
969                     + mLogicalDisplay.getDisplayIdLocked());
970             return;
971         }
972 
973         final String uniqueId = device.getUniqueId();
974         final DisplayDeviceConfig config = device.getDisplayDeviceConfig();
975         final IBinder token = device.getDisplayTokenLocked();
976         final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
977         final boolean isEnabled = mLogicalDisplay.isEnabledLocked();
978         final boolean isInTransition = mLogicalDisplay.isInTransitionLocked();
979         final boolean isDisplayInternal = mLogicalDisplay.getPrimaryDisplayDeviceLocked() != null
980                 && mLogicalDisplay.getPrimaryDisplayDeviceLocked()
981                 .getDisplayDeviceInfoLocked().type == Display.TYPE_INTERNAL;
982         final String thermalBrightnessThrottlingDataId =
983                 mLogicalDisplay.getDisplayInfoLocked().thermalBrightnessThrottlingDataId;
984         mHandler.postAtTime(() -> {
985             boolean changed = false;
986             if (mDisplayDevice != device) {
987                 changed = true;
988                 mDisplayDevice = device;
989                 mUniqueDisplayId = uniqueId;
990                 mDisplayStatsId = mUniqueDisplayId.hashCode();
991                 mDisplayDeviceConfig = config;
992                 mThermalBrightnessThrottlingDataId = thermalBrightnessThrottlingDataId;
993                 loadFromDisplayDeviceConfig(token, info, hbmMetadata);
994                 loadNitBasedBrightnessSetting();
995 
996                 /// Since the underlying display-device changed, we really don't know the
997                 // last command that was sent to change it's state. Let's assume it is unknown so
998                 // that we trigger a change immediately.
999                 mPowerState.resetScreenState();
1000             } else if (!Objects.equals(mThermalBrightnessThrottlingDataId,
1001                     thermalBrightnessThrottlingDataId)) {
1002                 changed = true;
1003                 mThermalBrightnessThrottlingDataId = thermalBrightnessThrottlingDataId;
1004                 mBrightnessThrottler.loadThermalBrightnessThrottlingDataFromDisplayDeviceConfig(
1005                         config.getThermalBrightnessThrottlingDataMapByThrottlingId(),
1006                         mThermalBrightnessThrottlingDataId,
1007                         mUniqueDisplayId);
1008             }
1009             if (mIsEnabled != isEnabled || mIsInTransition != isInTransition) {
1010                 changed = true;
1011                 mIsEnabled = isEnabled;
1012                 mIsInTransition = isInTransition;
1013             }
1014             mIsDisplayInternal = isDisplayInternal;
1015             if (changed) {
1016                 updatePowerState();
1017             }
1018         }, mClock.uptimeMillis());
1019     }
1020 
1021     /**
1022      * Unregisters all listeners and interrupts all running threads; halting future work.
1023      *
1024      * This method should be called when the DisplayPowerController is no longer in use; i.e. when
1025      * the {@link #mDisplayId display} has been removed.
1026      */
1027     @Override
stop()1028     public void stop() {
1029         synchronized (mLock) {
1030             clearDisplayBrightnessFollowersLocked();
1031 
1032             mStopped = true;
1033             Message msg = mHandler.obtainMessage(MSG_STOP);
1034             mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
1035 
1036             if (mAutomaticBrightnessController != null) {
1037                 mAutomaticBrightnessController.stop();
1038             }
1039 
1040             if (mBrightnessSetting != null) {
1041                 mBrightnessSetting.unregisterListener(mBrightnessSettingListener);
1042             }
1043 
1044             mContext.getContentResolver().unregisterContentObserver(mSettingsObserver);
1045         }
1046     }
1047 
loadFromDisplayDeviceConfig(IBinder token, DisplayDeviceInfo info, HighBrightnessModeMetadata hbmMetadata)1048     private void loadFromDisplayDeviceConfig(IBinder token, DisplayDeviceInfo info,
1049             HighBrightnessModeMetadata hbmMetadata) {
1050         // All properties that depend on the associated DisplayDevice and the DDC must be
1051         // updated here.
1052         loadBrightnessRampRates();
1053         loadProximitySensor();
1054         loadNitsRange(mContext.getResources());
1055         setUpAutoBrightness(mContext.getResources(), mHandler);
1056         reloadReduceBrightColours();
1057         if (mScreenBrightnessRampAnimator != null) {
1058             mScreenBrightnessRampAnimator.setAnimationTimeLimits(
1059                     mBrightnessRampIncreaseMaxTimeMillis,
1060                     mBrightnessRampDecreaseMaxTimeMillis);
1061         }
1062         mBrightnessRangeController.loadFromConfig(hbmMetadata, token, info, mDisplayDeviceConfig);
1063         mBrightnessThrottler.loadThermalBrightnessThrottlingDataFromDisplayDeviceConfig(
1064                 mDisplayDeviceConfig.getThermalBrightnessThrottlingDataMapByThrottlingId(),
1065                 mThermalBrightnessThrottlingDataId, mUniqueDisplayId);
1066     }
1067 
sendUpdatePowerState()1068     private void sendUpdatePowerState() {
1069         synchronized (mLock) {
1070             sendUpdatePowerStateLocked();
1071         }
1072     }
1073 
1074     @GuardedBy("mLock")
sendUpdatePowerStateLocked()1075     private void sendUpdatePowerStateLocked() {
1076         if (!mStopped && !mPendingUpdatePowerStateLocked) {
1077             mPendingUpdatePowerStateLocked = true;
1078             Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE);
1079             mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
1080         }
1081     }
1082 
initialize(int displayState)1083     private void initialize(int displayState) {
1084         mPowerState = mInjector.getDisplayPowerState(mBlanker,
1085                 mColorFadeEnabled ? new ColorFade(mDisplayId) : null, mDisplayId, displayState);
1086 
1087         if (mColorFadeEnabled) {
1088             mColorFadeOnAnimator = ObjectAnimator.ofFloat(
1089                     mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 0.0f, 1.0f);
1090             mColorFadeOnAnimator.setDuration(COLOR_FADE_ON_ANIMATION_DURATION_MILLIS);
1091             mColorFadeOnAnimator.addListener(mAnimatorListener);
1092 
1093             mColorFadeOffAnimator = ObjectAnimator.ofFloat(
1094                     mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 1.0f, 0.0f);
1095             mColorFadeOffAnimator.setDuration(COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS);
1096             mColorFadeOffAnimator.addListener(mAnimatorListener);
1097         }
1098 
1099         mScreenBrightnessRampAnimator = mInjector.getDualRampAnimator(mPowerState,
1100                 DisplayPowerState.SCREEN_BRIGHTNESS_FLOAT,
1101                 DisplayPowerState.SCREEN_SDR_BRIGHTNESS_FLOAT);
1102         mScreenBrightnessRampAnimator.setAnimationTimeLimits(
1103                 mBrightnessRampIncreaseMaxTimeMillis,
1104                 mBrightnessRampDecreaseMaxTimeMillis);
1105         mScreenBrightnessRampAnimator.setListener(mRampAnimatorListener);
1106 
1107         noteScreenState(mPowerState.getScreenState());
1108         noteScreenBrightness(mPowerState.getScreenBrightness());
1109 
1110         // Initialize all of the brightness tracking state
1111         final float brightness = convertToAdjustedNits(mPowerState.getScreenBrightness());
1112         if (mBrightnessTracker != null && brightness >= PowerManager.BRIGHTNESS_MIN) {
1113             mBrightnessTracker.start(brightness);
1114         }
1115         mBrightnessSettingListener = brightnessValue -> {
1116             Message msg = mHandler.obtainMessage(MSG_UPDATE_BRIGHTNESS, brightnessValue);
1117             mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
1118         };
1119 
1120         mBrightnessSetting.registerListener(mBrightnessSettingListener);
1121         mContext.getContentResolver().registerContentObserver(
1122                 Settings.System.getUriFor(Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ),
1123                 false /*notifyForDescendants*/, mSettingsObserver, UserHandle.USER_ALL);
1124         mContext.getContentResolver().registerContentObserver(
1125                 Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE),
1126                 false /*notifyForDescendants*/, mSettingsObserver, UserHandle.USER_ALL);
1127         handleBrightnessModeChange();
1128     }
1129 
setUpAutoBrightness(Resources resources, Handler handler)1130     private void setUpAutoBrightness(Resources resources, Handler handler) {
1131         mUseSoftwareAutoBrightnessConfig = mDisplayDeviceConfig.isAutoBrightnessAvailable();
1132 
1133         if (!mUseSoftwareAutoBrightnessConfig) {
1134             return;
1135         }
1136 
1137         float userLux = BrightnessMappingStrategy.NO_USER_LUX;
1138         float userNits = -1;
1139         if (mInteractiveModeBrightnessMapper != null) {
1140             userLux = mInteractiveModeBrightnessMapper.getUserLux();
1141             float userBrightness = mInteractiveModeBrightnessMapper.getUserBrightness();
1142             userNits = mInteractiveModeBrightnessMapper.convertToNits(userBrightness);
1143         }
1144 
1145         final boolean isIdleScreenBrightnessEnabled = resources.getBoolean(
1146                 R.bool.config_enableIdleScreenBrightnessMode);
1147         mInteractiveModeBrightnessMapper = mInjector.getInteractiveModeBrightnessMapper(resources,
1148                 mDisplayDeviceConfig, mDisplayWhiteBalanceController);
1149         if (isIdleScreenBrightnessEnabled) {
1150             mIdleModeBrightnessMapper = BrightnessMappingStrategy.createForIdleMode(resources,
1151                     mDisplayDeviceConfig, mDisplayWhiteBalanceController);
1152         }
1153 
1154         if (mInteractiveModeBrightnessMapper != null) {
1155             final float dozeScaleFactor = resources.getFraction(
1156                     com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor,
1157                     1, 1);
1158 
1159             // Ambient Lux - Active Mode Brightness Thresholds
1160             float[] ambientBrighteningThresholds =
1161                     mDisplayDeviceConfig.getAmbientBrighteningPercentages();
1162             float[] ambientDarkeningThresholds =
1163                     mDisplayDeviceConfig.getAmbientDarkeningPercentages();
1164             float[] ambientBrighteningLevels =
1165                     mDisplayDeviceConfig.getAmbientBrighteningLevels();
1166             float[] ambientDarkeningLevels =
1167                     mDisplayDeviceConfig.getAmbientDarkeningLevels();
1168             float ambientDarkeningMinThreshold =
1169                     mDisplayDeviceConfig.getAmbientLuxDarkeningMinThreshold();
1170             float ambientBrighteningMinThreshold =
1171                     mDisplayDeviceConfig.getAmbientLuxBrighteningMinThreshold();
1172             HysteresisLevels ambientBrightnessThresholds = mInjector.getHysteresisLevels(
1173                     ambientBrighteningThresholds, ambientDarkeningThresholds,
1174                     ambientBrighteningLevels, ambientDarkeningLevels, ambientDarkeningMinThreshold,
1175                     ambientBrighteningMinThreshold);
1176 
1177             // Display - Active Mode Brightness Thresholds
1178             float[] screenBrighteningThresholds =
1179                     mDisplayDeviceConfig.getScreenBrighteningPercentages();
1180             float[] screenDarkeningThresholds =
1181                     mDisplayDeviceConfig.getScreenDarkeningPercentages();
1182             float[] screenBrighteningLevels =
1183                     mDisplayDeviceConfig.getScreenBrighteningLevels();
1184             float[] screenDarkeningLevels =
1185                     mDisplayDeviceConfig.getScreenDarkeningLevels();
1186             float screenDarkeningMinThreshold =
1187                     mDisplayDeviceConfig.getScreenDarkeningMinThreshold();
1188             float screenBrighteningMinThreshold =
1189                     mDisplayDeviceConfig.getScreenBrighteningMinThreshold();
1190             HysteresisLevels screenBrightnessThresholds = mInjector.getHysteresisLevels(
1191                     screenBrighteningThresholds, screenDarkeningThresholds,
1192                     screenBrighteningLevels, screenDarkeningLevels, screenDarkeningMinThreshold,
1193                     screenBrighteningMinThreshold, true);
1194 
1195             // Ambient Lux - Idle Screen Brightness Thresholds
1196             float ambientDarkeningMinThresholdIdle =
1197                     mDisplayDeviceConfig.getAmbientLuxDarkeningMinThresholdIdle();
1198             float ambientBrighteningMinThresholdIdle =
1199                     mDisplayDeviceConfig.getAmbientLuxBrighteningMinThresholdIdle();
1200             float[] ambientBrighteningThresholdsIdle =
1201                     mDisplayDeviceConfig.getAmbientBrighteningPercentagesIdle();
1202             float[] ambientDarkeningThresholdsIdle =
1203                     mDisplayDeviceConfig.getAmbientDarkeningPercentagesIdle();
1204             float[] ambientBrighteningLevelsIdle =
1205                     mDisplayDeviceConfig.getAmbientBrighteningLevelsIdle();
1206             float[] ambientDarkeningLevelsIdle =
1207                     mDisplayDeviceConfig.getAmbientDarkeningLevelsIdle();
1208             HysteresisLevels ambientBrightnessThresholdsIdle = mInjector.getHysteresisLevels(
1209                     ambientBrighteningThresholdsIdle, ambientDarkeningThresholdsIdle,
1210                     ambientBrighteningLevelsIdle, ambientDarkeningLevelsIdle,
1211                     ambientDarkeningMinThresholdIdle, ambientBrighteningMinThresholdIdle);
1212 
1213             // Display - Idle Screen Brightness Thresholds
1214             float screenDarkeningMinThresholdIdle =
1215                     mDisplayDeviceConfig.getScreenDarkeningMinThresholdIdle();
1216             float screenBrighteningMinThresholdIdle =
1217                     mDisplayDeviceConfig.getScreenBrighteningMinThresholdIdle();
1218             float[] screenBrighteningThresholdsIdle =
1219                     mDisplayDeviceConfig.getScreenBrighteningPercentagesIdle();
1220             float[] screenDarkeningThresholdsIdle =
1221                     mDisplayDeviceConfig.getScreenDarkeningPercentagesIdle();
1222             float[] screenBrighteningLevelsIdle =
1223                     mDisplayDeviceConfig.getScreenBrighteningLevelsIdle();
1224             float[] screenDarkeningLevelsIdle =
1225                     mDisplayDeviceConfig.getScreenDarkeningLevelsIdle();
1226             HysteresisLevels screenBrightnessThresholdsIdle = mInjector.getHysteresisLevels(
1227                     screenBrighteningThresholdsIdle, screenDarkeningThresholdsIdle,
1228                     screenBrighteningLevelsIdle, screenDarkeningLevelsIdle,
1229                     screenDarkeningMinThresholdIdle, screenBrighteningMinThresholdIdle);
1230 
1231             long brighteningLightDebounce = mDisplayDeviceConfig
1232                     .getAutoBrightnessBrighteningLightDebounce();
1233             long darkeningLightDebounce = mDisplayDeviceConfig
1234                     .getAutoBrightnessDarkeningLightDebounce();
1235             boolean autoBrightnessResetAmbientLuxAfterWarmUp = resources.getBoolean(
1236                     com.android.internal.R.bool.config_autoBrightnessResetAmbientLuxAfterWarmUp);
1237 
1238             int lightSensorWarmUpTimeConfig = resources.getInteger(
1239                     com.android.internal.R.integer.config_lightSensorWarmupTime);
1240             int lightSensorRate = resources.getInteger(
1241                     com.android.internal.R.integer.config_autoBrightnessLightSensorRate);
1242             int initialLightSensorRate = resources.getInteger(
1243                     com.android.internal.R.integer.config_autoBrightnessInitialLightSensorRate);
1244             if (initialLightSensorRate == -1) {
1245                 initialLightSensorRate = lightSensorRate;
1246             } else if (initialLightSensorRate > lightSensorRate) {
1247                 Slog.w(mTag, "Expected config_autoBrightnessInitialLightSensorRate ("
1248                         + initialLightSensorRate + ") to be less than or equal to "
1249                         + "config_autoBrightnessLightSensorRate (" + lightSensorRate + ").");
1250             }
1251 
1252             loadAmbientLightSensor();
1253             // BrightnessTracker should only use one light sensor, we want to use the light sensor
1254             // from the default display and not e.g. temporary displays when switching layouts.
1255             if (mBrightnessTracker != null && mDisplayId == Display.DEFAULT_DISPLAY) {
1256                 mBrightnessTracker.setLightSensor(mLightSensor);
1257             }
1258 
1259             if (mAutomaticBrightnessController != null) {
1260                 mAutomaticBrightnessController.stop();
1261             }
1262             float userBrightness = BrightnessMappingStrategy.NO_USER_BRIGHTNESS;
1263             if (userNits >= 0) {
1264                 userBrightness = mInteractiveModeBrightnessMapper.convertToFloatScale(userNits);
1265                 if (Float.isNaN(userBrightness)) {
1266                     userBrightness = BrightnessMappingStrategy.NO_USER_BRIGHTNESS;
1267                 }
1268             }
1269             mAutomaticBrightnessController = mInjector.getAutomaticBrightnessController(
1270                     this, handler.getLooper(), mSensorManager, mLightSensor,
1271                     mInteractiveModeBrightnessMapper, lightSensorWarmUpTimeConfig,
1272                     PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX, dozeScaleFactor,
1273                     lightSensorRate, initialLightSensorRate, brighteningLightDebounce,
1274                     darkeningLightDebounce, autoBrightnessResetAmbientLuxAfterWarmUp,
1275                     ambientBrightnessThresholds, screenBrightnessThresholds,
1276                     ambientBrightnessThresholdsIdle, screenBrightnessThresholdsIdle, mContext,
1277                     mBrightnessRangeController, mBrightnessThrottler, mIdleModeBrightnessMapper,
1278                     mDisplayDeviceConfig.getAmbientHorizonShort(),
1279                     mDisplayDeviceConfig.getAmbientHorizonLong(), userLux, userBrightness);
1280 
1281             mBrightnessEventRingBuffer =
1282                     new RingBuffer<>(BrightnessEvent.class, RINGBUFFER_MAX);
1283 
1284             if (mScreenOffBrightnessSensorController != null) {
1285                 mScreenOffBrightnessSensorController.stop();
1286                 mScreenOffBrightnessSensorController = null;
1287             }
1288             loadScreenOffBrightnessSensor();
1289             int[] sensorValueToLux = mDisplayDeviceConfig.getScreenOffBrightnessSensorValueToLux();
1290             if (mScreenOffBrightnessSensor != null && sensorValueToLux != null) {
1291                 mScreenOffBrightnessSensorController =
1292                         mInjector.getScreenOffBrightnessSensorController(
1293                                 mSensorManager,
1294                                 mScreenOffBrightnessSensor,
1295                                 mHandler,
1296                                 SystemClock::uptimeMillis,
1297                                 sensorValueToLux,
1298                                 mInteractiveModeBrightnessMapper);
1299             }
1300         } else {
1301             mUseSoftwareAutoBrightnessConfig = false;
1302         }
1303     }
1304 
loadBrightnessRampRates()1305     private void loadBrightnessRampRates() {
1306         mBrightnessRampRateFastDecrease = mDisplayDeviceConfig.getBrightnessRampFastDecrease();
1307         mBrightnessRampRateFastIncrease = mDisplayDeviceConfig.getBrightnessRampFastIncrease();
1308         mBrightnessRampRateSlowDecrease = mDisplayDeviceConfig.getBrightnessRampSlowDecrease();
1309         mBrightnessRampRateSlowIncrease = mDisplayDeviceConfig.getBrightnessRampSlowIncrease();
1310         mBrightnessRampDecreaseMaxTimeMillis =
1311                 mDisplayDeviceConfig.getBrightnessRampDecreaseMaxMillis();
1312         mBrightnessRampIncreaseMaxTimeMillis =
1313                 mDisplayDeviceConfig.getBrightnessRampIncreaseMaxMillis();
1314     }
1315 
loadNitsRange(Resources resources)1316     private void loadNitsRange(Resources resources) {
1317         if (mDisplayDeviceConfig != null && mDisplayDeviceConfig.getNits() != null) {
1318             mNitsRange = mDisplayDeviceConfig.getNits();
1319         } else {
1320             Slog.w(mTag, "Screen brightness nits configuration is unavailable; falling back");
1321             mNitsRange = BrightnessMappingStrategy.getFloatArray(resources
1322                     .obtainTypedArray(com.android.internal.R.array.config_screenBrightnessNits));
1323         }
1324     }
1325 
reloadReduceBrightColours()1326     private void reloadReduceBrightColours() {
1327         if (mCdsi != null && mCdsi.isReduceBrightColorsActivated()) {
1328             applyReduceBrightColorsSplineAdjustment();
1329         }
1330     }
1331 
1332     @Override
setAutomaticScreenBrightnessMode(boolean isIdle)1333     public void setAutomaticScreenBrightnessMode(boolean isIdle) {
1334         if (mAutomaticBrightnessController != null) {
1335             if (isIdle) {
1336                 mAutomaticBrightnessController.switchToIdleMode();
1337             } else {
1338                 mAutomaticBrightnessController.switchToInteractiveScreenBrightnessMode();
1339             }
1340         }
1341 
1342         Message msg = mHandler.obtainMessage();
1343         msg.what = MSG_SET_DWBC_STRONG_MODE;
1344         msg.arg1 = isIdle ? 1 : 0;
1345         mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
1346     }
1347 
1348     private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() {
1349         @Override
1350         public void onAnimationStart(Animator animation) {
1351         }
1352 
1353         @Override
1354         public void onAnimationEnd(Animator animation) {
1355             sendUpdatePowerState();
1356         }
1357 
1358         @Override
1359         public void onAnimationRepeat(Animator animation) {
1360         }
1361 
1362         @Override
1363         public void onAnimationCancel(Animator animation) {
1364         }
1365     };
1366 
1367     private final RampAnimator.Listener mRampAnimatorListener = new RampAnimator.Listener() {
1368         @Override
1369         public void onAnimationEnd() {
1370             sendUpdatePowerState();
1371             Message msg = mHandler.obtainMessage(MSG_BRIGHTNESS_RAMP_DONE);
1372             mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
1373         }
1374     };
1375 
1376     /** Clean up all resources that are accessed via the {@link #mHandler} thread. */
cleanupHandlerThreadAfterStop()1377     private void cleanupHandlerThreadAfterStop() {
1378         setProximitySensorEnabled(false);
1379         mBrightnessRangeController.stop();
1380         mBrightnessThrottler.stop();
1381         mHandler.removeCallbacksAndMessages(null);
1382 
1383         // Release any outstanding wakelocks we're still holding because of pending messages.
1384         if (mUnfinishedBusiness) {
1385             mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdUnfinishedBusiness);
1386             mUnfinishedBusiness = false;
1387         }
1388         if (mOnStateChangedPending) {
1389             mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdOnStateChanged);
1390             mOnStateChangedPending = false;
1391         }
1392         for (int i = 0; i < mOnProximityPositiveMessages; i++) {
1393             mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdProxPositive);
1394         }
1395         mOnProximityPositiveMessages = 0;
1396         for (int i = 0; i < mOnProximityNegativeMessages; i++) {
1397             mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdProxNegative);
1398         }
1399         mOnProximityNegativeMessages = 0;
1400 
1401         final float brightness = mPowerState != null
1402                 ? mPowerState.getScreenBrightness()
1403                 : PowerManager.BRIGHTNESS_MIN;
1404         reportStats(brightness);
1405 
1406         if (mPowerState != null) {
1407             mPowerState.stop();
1408             mPowerState = null;
1409         }
1410 
1411         if (mScreenOffBrightnessSensorController != null) {
1412             mScreenOffBrightnessSensorController.stop();
1413         }
1414 
1415         if (mDisplayWhiteBalanceController != null) {
1416             mDisplayWhiteBalanceController.setEnabled(false);
1417         }
1418     }
1419 
1420     // Call from handler thread
updatePowerState()1421     private void updatePowerState() {
1422         Trace.traceBegin(Trace.TRACE_TAG_POWER,
1423                 "DisplayPowerController#updatePowerState");
1424         updatePowerStateInternal();
1425         Trace.traceEnd(Trace.TRACE_TAG_POWER);
1426     }
1427 
updatePowerStateInternal()1428     private void updatePowerStateInternal() {
1429         // Update the power state request.
1430         final boolean mustNotify;
1431         final int previousPolicy;
1432         boolean mustInitialize = false;
1433         int brightnessAdjustmentFlags = 0;
1434         mBrightnessReasonTemp.set(null);
1435         mTempBrightnessEvent.reset();
1436         SparseArray<DisplayPowerControllerInterface> displayBrightnessFollowers;
1437         synchronized (mLock) {
1438             if (mStopped) {
1439                 return;
1440             }
1441             mPendingUpdatePowerStateLocked = false;
1442             if (mPendingRequestLocked == null) {
1443                 return; // wait until first actual power request
1444             }
1445 
1446             if (mPowerRequest == null) {
1447                 mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked);
1448                 updatePendingProximityRequestsLocked();
1449                 mPendingRequestChangedLocked = false;
1450                 mustInitialize = true;
1451                 // Assume we're on and bright until told otherwise, since that's the state we turn
1452                 // on in.
1453                 previousPolicy = DisplayPowerRequest.POLICY_BRIGHT;
1454             } else if (mPendingRequestChangedLocked) {
1455                 previousPolicy = mPowerRequest.policy;
1456                 mPowerRequest.copyFrom(mPendingRequestLocked);
1457                 updatePendingProximityRequestsLocked();
1458                 mPendingRequestChangedLocked = false;
1459                 mDisplayReadyLocked = false;
1460             } else {
1461                 previousPolicy = mPowerRequest.policy;
1462             }
1463 
1464             mustNotify = !mDisplayReadyLocked;
1465 
1466             displayBrightnessFollowers = mDisplayBrightnessFollowers.clone();
1467         }
1468 
1469         // Compute the basic display state using the policy.
1470         // We might override this below based on other factors.
1471         // Initialise brightness as invalid.
1472         int state;
1473         float brightnessState = PowerManager.BRIGHTNESS_INVALID_FLOAT;
1474         boolean performScreenOffTransition = false;
1475         switch (mPowerRequest.policy) {
1476             case DisplayPowerRequest.POLICY_OFF:
1477                 state = Display.STATE_OFF;
1478                 performScreenOffTransition = true;
1479                 break;
1480             case DisplayPowerRequest.POLICY_DOZE:
1481                 if (mPowerRequest.dozeScreenState != Display.STATE_UNKNOWN) {
1482                     state = mPowerRequest.dozeScreenState;
1483                 } else {
1484                     state = Display.STATE_DOZE;
1485                 }
1486                 if (!mAllowAutoBrightnessWhileDozingConfig) {
1487                     brightnessState = mPowerRequest.dozeScreenBrightness;
1488                     mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE);
1489                 }
1490                 break;
1491             case DisplayPowerRequest.POLICY_DIM:
1492             case DisplayPowerRequest.POLICY_BRIGHT:
1493             default:
1494                 state = Display.STATE_ON;
1495                 break;
1496         }
1497         assert (state != Display.STATE_UNKNOWN);
1498 
1499         if (mScreenOffBrightnessSensorController != null) {
1500             mScreenOffBrightnessSensorController.setLightSensorEnabled(mUseAutoBrightness
1501                     && mIsEnabled && (state == Display.STATE_OFF || (state == Display.STATE_DOZE
1502                     && !mAllowAutoBrightnessWhileDozingConfig))
1503                     && mLeadDisplayId == Layout.NO_LEAD_DISPLAY);
1504         }
1505 
1506         boolean skipRampBecauseOfProximityChangeToNegative = false;
1507         // Apply the proximity sensor.
1508         if (mProximitySensor != null) {
1509             if (mPowerRequest.useProximitySensor && state != Display.STATE_OFF) {
1510                 // At this point the policy says that the screen should be on, but we've been
1511                 // asked to listen to the prox sensor to adjust the display state, so lets make
1512                 // sure the sensor is on.
1513                 setProximitySensorEnabled(true);
1514                 if (!mScreenOffBecauseOfProximity
1515                         && mProximity == PROXIMITY_POSITIVE
1516                         && !mIgnoreProximityUntilChanged) {
1517                     // Prox sensor already reporting "near" so we should turn off the screen.
1518                     // Also checked that we aren't currently set to ignore the proximity sensor
1519                     // temporarily.
1520                     mScreenOffBecauseOfProximity = true;
1521                     sendOnProximityPositiveWithWakelock();
1522                 }
1523             } else if (mWaitingForNegativeProximity
1524                     && mScreenOffBecauseOfProximity
1525                     && mProximity == PROXIMITY_POSITIVE
1526                     && state != Display.STATE_OFF) {
1527                 // The policy says that we should have the screen on, but it's off due to the prox
1528                 // and we've been asked to wait until the screen is far from the user to turn it
1529                 // back on. Let keep the prox sensor on so we can tell when it's far again.
1530                 setProximitySensorEnabled(true);
1531             } else {
1532                 // We haven't been asked to use the prox sensor and we're not waiting on the screen
1533                 // to turn back on...so lets shut down the prox sensor.
1534                 setProximitySensorEnabled(false);
1535                 mWaitingForNegativeProximity = false;
1536             }
1537 
1538             if (mScreenOffBecauseOfProximity
1539                     && (mProximity != PROXIMITY_POSITIVE || mIgnoreProximityUntilChanged)) {
1540                 // The screen *was* off due to prox being near, but now it's "far" so lets turn
1541                 // the screen back on.  Also turn it back on if we've been asked to ignore the
1542                 // prox sensor temporarily.
1543                 mScreenOffBecauseOfProximity = false;
1544                 skipRampBecauseOfProximityChangeToNegative = true;
1545                 sendOnProximityNegativeWithWakelock();
1546             }
1547         } else {
1548             setProximitySensorEnabled(false);
1549             mWaitingForNegativeProximity = false;
1550             mIgnoreProximityUntilChanged = false;
1551 
1552             if (mScreenOffBecauseOfProximity) {
1553                 // The screen *was* off due to prox being near, but now there's no prox sensor, so
1554                 // let's turn the screen back on.
1555                 mScreenOffBecauseOfProximity = false;
1556                 skipRampBecauseOfProximityChangeToNegative = true;
1557                 sendOnProximityNegativeWithWakelock();
1558             }
1559         }
1560 
1561         if (!mIsEnabled
1562                 || mIsInTransition
1563                 || mScreenOffBecauseOfProximity) {
1564             state = Display.STATE_OFF;
1565         }
1566 
1567         // Initialize things the first time the power state is changed.
1568         if (mustInitialize) {
1569             initialize(readyToUpdateDisplayState() ? state : Display.STATE_UNKNOWN);
1570         }
1571 
1572         // Animate the screen state change unless already animating.
1573         // The transition may be deferred, so after this point we will use the
1574         // actual state instead of the desired one.
1575         final int oldState = mPowerState.getScreenState();
1576         animateScreenStateChange(state, performScreenOffTransition);
1577         state = mPowerState.getScreenState();
1578         boolean slowChange = false;
1579 
1580         if (state == Display.STATE_OFF) {
1581             brightnessState = PowerManager.BRIGHTNESS_OFF_FLOAT;
1582             mBrightnessReasonTemp.setReason(BrightnessReason.REASON_SCREEN_OFF);
1583         }
1584 
1585         if (Float.isNaN(brightnessState) && isValidBrightnessValue(mBrightnessToFollow)) {
1586             brightnessState = mBrightnessToFollow;
1587             slowChange = mBrightnessToFollowSlowChange;
1588             mBrightnessReasonTemp.setReason(BrightnessReason.REASON_FOLLOWER);
1589         }
1590 
1591         if ((Float.isNaN(brightnessState))
1592                 && isValidBrightnessValue(mPowerRequest.screenBrightnessOverride)) {
1593             brightnessState = mPowerRequest.screenBrightnessOverride;
1594             mBrightnessReasonTemp.setReason(BrightnessReason.REASON_OVERRIDE);
1595             mAppliedScreenBrightnessOverride = true;
1596         } else {
1597             mAppliedScreenBrightnessOverride = false;
1598         }
1599 
1600         final boolean autoBrightnessEnabledInDoze =
1601                 mAllowAutoBrightnessWhileDozingConfig && Display.isDozeState(state);
1602         final boolean autoBrightnessEnabled = mUseAutoBrightness
1603                 && (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
1604                 && mBrightnessReasonTemp.getReason() != BrightnessReason.REASON_OVERRIDE
1605                 && mAutomaticBrightnessController != null;
1606         final boolean autoBrightnessDisabledDueToDisplayOff = mUseAutoBrightness
1607                 && !(state == Display.STATE_ON || autoBrightnessEnabledInDoze);
1608         final int autoBrightnessState = autoBrightnessEnabled
1609                     && mBrightnessReasonTemp.getReason() != BrightnessReason.REASON_FOLLOWER
1610                 ? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED
1611                 : autoBrightnessDisabledDueToDisplayOff
1612                         ? AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE
1613                         : AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED;
1614 
1615         final boolean userSetBrightnessChanged = updateUserSetScreenBrightness();
1616 
1617         // Use the temporary screen brightness if there isn't an override, either from
1618         // WindowManager or based on the display state.
1619         if (isValidBrightnessValue(mTemporaryScreenBrightness)) {
1620             brightnessState = mTemporaryScreenBrightness;
1621             mAppliedTemporaryBrightness = true;
1622             mBrightnessReasonTemp.setReason(BrightnessReason.REASON_TEMPORARY);
1623         } else {
1624             mAppliedTemporaryBrightness = false;
1625         }
1626 
1627         final boolean autoBrightnessAdjustmentChanged = updateAutoBrightnessAdjustment();
1628 
1629         // Use the autobrightness adjustment override if set.
1630         final float autoBrightnessAdjustment;
1631         if (!Float.isNaN(mTemporaryAutoBrightnessAdjustment)) {
1632             autoBrightnessAdjustment = mTemporaryAutoBrightnessAdjustment;
1633             brightnessAdjustmentFlags = BrightnessReason.ADJUSTMENT_AUTO_TEMP;
1634             mAppliedTemporaryAutoBrightnessAdjustment = true;
1635         } else {
1636             autoBrightnessAdjustment = mAutoBrightnessAdjustment;
1637             brightnessAdjustmentFlags = BrightnessReason.ADJUSTMENT_AUTO;
1638             mAppliedTemporaryAutoBrightnessAdjustment = false;
1639         }
1640         // Apply brightness boost.
1641         // We do this here after deciding whether auto-brightness is enabled so that we don't
1642         // disable the light sensor during this temporary state.  That way when boost ends we will
1643         // be able to resume normal auto-brightness behavior without any delay.
1644         if (mPowerRequest.boostScreenBrightness
1645                 && brightnessState != PowerManager.BRIGHTNESS_OFF_FLOAT) {
1646             brightnessState = PowerManager.BRIGHTNESS_MAX;
1647             mBrightnessReasonTemp.setReason(BrightnessReason.REASON_BOOST);
1648             mAppliedBrightnessBoost = true;
1649         } else {
1650             mAppliedBrightnessBoost = false;
1651         }
1652 
1653         // If the brightness is already set then it's been overridden by something other than the
1654         // user, or is a temporary adjustment.
1655         boolean userInitiatedChange = (Float.isNaN(brightnessState))
1656                 && (autoBrightnessAdjustmentChanged || userSetBrightnessChanged);
1657         boolean wasShortTermModelActive = false;
1658         // Configure auto-brightness.
1659         if (mAutomaticBrightnessController != null) {
1660             wasShortTermModelActive = mAutomaticBrightnessController.hasUserDataPoints();
1661             mAutomaticBrightnessController.configure(autoBrightnessState,
1662                     mBrightnessConfiguration,
1663                     mLastUserSetScreenBrightness,
1664                     userSetBrightnessChanged, autoBrightnessAdjustment,
1665                     autoBrightnessAdjustmentChanged, mPowerRequest.policy,
1666                     mShouldResetShortTermModel);
1667             mShouldResetShortTermModel = false;
1668         }
1669         mBrightnessRangeController.setAutoBrightnessEnabled(autoBrightnessEnabled
1670                 ? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED
1671                 : autoBrightnessDisabledDueToDisplayOff
1672                         ? AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE
1673                         : AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED);
1674 
1675         if (mBrightnessTracker != null) {
1676             mBrightnessTracker.setShouldCollectColorSample(mBrightnessConfiguration != null
1677                     && mBrightnessConfiguration.shouldCollectColorSamples());
1678         }
1679 
1680         boolean updateScreenBrightnessSetting = false;
1681         float rawBrightnessState = brightnessState;
1682 
1683         // Apply auto-brightness.
1684         if (Float.isNaN(brightnessState)) {
1685             float newAutoBrightnessAdjustment = autoBrightnessAdjustment;
1686             if (autoBrightnessEnabled) {
1687                 rawBrightnessState = mAutomaticBrightnessController
1688                         .getRawAutomaticScreenBrightness();
1689                 brightnessState = mAutomaticBrightnessController.getAutomaticScreenBrightness(
1690                         mTempBrightnessEvent);
1691                 newAutoBrightnessAdjustment =
1692                         mAutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment();
1693             }
1694             if (isValidBrightnessValue(brightnessState)
1695                     || brightnessState == PowerManager.BRIGHTNESS_OFF_FLOAT) {
1696                 // Use current auto-brightness value and slowly adjust to changes.
1697                 brightnessState = clampScreenBrightness(brightnessState);
1698                 if (mAppliedAutoBrightness && !autoBrightnessAdjustmentChanged) {
1699                     slowChange = true; // slowly adapt to auto-brightness
1700                 }
1701                 updateScreenBrightnessSetting = mCurrentScreenBrightnessSetting != brightnessState;
1702                 mAppliedAutoBrightness = true;
1703                 mBrightnessReasonTemp.setReason(BrightnessReason.REASON_AUTOMATIC);
1704                 if (mScreenOffBrightnessSensorController != null) {
1705                     mScreenOffBrightnessSensorController.setLightSensorEnabled(false);
1706                 }
1707             } else {
1708                 mAppliedAutoBrightness = false;
1709             }
1710             if (autoBrightnessAdjustment != newAutoBrightnessAdjustment) {
1711                 // If the autobrightness controller has decided to change the adjustment value
1712                 // used, make sure that's reflected in settings.
1713                 putAutoBrightnessAdjustmentSetting(newAutoBrightnessAdjustment);
1714             } else {
1715                 // Adjustment values resulted in no change
1716                 brightnessAdjustmentFlags = 0;
1717             }
1718         } else {
1719             // Any non-auto-brightness values such as override or temporary should still be subject
1720             // to clamping so that they don't go beyond the current max as specified by HBM
1721             // Controller.
1722             brightnessState = clampScreenBrightness(brightnessState);
1723             mAppliedAutoBrightness = false;
1724             brightnessAdjustmentFlags = 0;
1725         }
1726         // Use default brightness when dozing unless overridden.
1727         if ((Float.isNaN(brightnessState))
1728                 && Display.isDozeState(state)) {
1729             rawBrightnessState = mScreenBrightnessDozeConfig;
1730             brightnessState = clampScreenBrightness(rawBrightnessState);
1731             mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE_DEFAULT);
1732         }
1733 
1734         // The ALS is not available yet - use the screen off sensor to determine the initial
1735         // brightness
1736         if (Float.isNaN(brightnessState) && autoBrightnessEnabled
1737                 && mScreenOffBrightnessSensorController != null) {
1738             rawBrightnessState =
1739                     mScreenOffBrightnessSensorController.getAutomaticScreenBrightness();
1740             brightnessState = rawBrightnessState;
1741             if (isValidBrightnessValue(brightnessState)) {
1742                 brightnessState = clampScreenBrightness(brightnessState);
1743                 updateScreenBrightnessSetting = mCurrentScreenBrightnessSetting != brightnessState;
1744                 mBrightnessReasonTemp.setReason(
1745                         BrightnessReason.REASON_SCREEN_OFF_BRIGHTNESS_SENSOR);
1746             }
1747         }
1748 
1749         // Apply manual brightness.
1750         if (Float.isNaN(brightnessState)) {
1751             rawBrightnessState = mCurrentScreenBrightnessSetting;
1752             brightnessState = clampScreenBrightness(rawBrightnessState);
1753             if (brightnessState != mCurrentScreenBrightnessSetting) {
1754                 // The manually chosen screen brightness is outside of the currently allowed
1755                 // range (i.e., high-brightness-mode), make sure we tell the rest of the system
1756                 // by updating the setting.
1757                 updateScreenBrightnessSetting = true;
1758             }
1759             mBrightnessReasonTemp.setReason(BrightnessReason.REASON_MANUAL);
1760         }
1761 
1762         float ambientLux = mAutomaticBrightnessController == null ? 0
1763                 : mAutomaticBrightnessController.getAmbientLux();
1764         for (int i = 0; i < displayBrightnessFollowers.size(); i++) {
1765             DisplayPowerControllerInterface follower = displayBrightnessFollowers.valueAt(i);
1766             follower.setBrightnessToFollow(rawBrightnessState, convertToNits(rawBrightnessState),
1767                     ambientLux, slowChange);
1768         }
1769 
1770         // Now that a desired brightness has been calculated, apply brightness throttling. The
1771         // dimming and low power transformations that follow can only dim brightness further.
1772         //
1773         // We didn't do this earlier through brightness clamping because we need to know both
1774         // unthrottled (unclamped/ideal) and throttled brightness levels for subsequent operations.
1775         // Note throttling effectively changes the allowed brightness range, so, similarly to HBM,
1776         // we broadcast this change through setting.
1777         final float unthrottledBrightnessState = brightnessState;
1778         if (mBrightnessThrottler.isThrottled()) {
1779             mTempBrightnessEvent.setThermalMax(mBrightnessThrottler.getBrightnessCap());
1780             brightnessState = Math.min(brightnessState, mBrightnessThrottler.getBrightnessCap());
1781             mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_THROTTLED);
1782             if (!mAppliedThrottling) {
1783                 // Brightness throttling is needed, so do so quickly.
1784                 // Later, when throttling is removed, we let other mechanisms decide on speed.
1785                 slowChange = false;
1786             }
1787             mAppliedThrottling = true;
1788         } else if (mAppliedThrottling) {
1789             mAppliedThrottling = false;
1790         }
1791 
1792         if (updateScreenBrightnessSetting) {
1793             // Tell the rest of the system about the new brightness in case we had to change it
1794             // for things like auto-brightness or high-brightness-mode. Note that we do this
1795             // before applying the low power or dim transformations so that the slider
1796             // accurately represents the full possible range, even if they range changes what
1797             // it means in absolute terms.
1798             updateScreenBrightnessSetting(brightnessState);
1799         }
1800 
1801         // Apply dimming by at least some minimum amount when user activity
1802         // timeout is about to expire.
1803         if (mPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
1804             if (brightnessState > PowerManager.BRIGHTNESS_MIN) {
1805                 brightnessState = Math.max(
1806                         Math.min(brightnessState - mScreenBrightnessMinimumDimAmount,
1807                                 mScreenBrightnessDimConfig),
1808                         PowerManager.BRIGHTNESS_MIN);
1809                 mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_DIMMED);
1810             }
1811             if (!mAppliedDimming) {
1812                 slowChange = false;
1813             }
1814             mAppliedDimming = true;
1815         } else if (mAppliedDimming) {
1816             slowChange = false;
1817             mAppliedDimming = false;
1818         }
1819         // If low power mode is enabled, scale brightness by screenLowPowerBrightnessFactor
1820         // as long as it is above the minimum threshold.
1821         if (mPowerRequest.lowPowerMode) {
1822             if (brightnessState > PowerManager.BRIGHTNESS_MIN) {
1823                 final float brightnessFactor =
1824                         Math.min(mPowerRequest.screenLowPowerBrightnessFactor, 1);
1825                 final float lowPowerBrightnessFloat = (brightnessState * brightnessFactor);
1826                 brightnessState = Math.max(lowPowerBrightnessFloat, PowerManager.BRIGHTNESS_MIN);
1827                 mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_LOW_POWER);
1828             }
1829             if (!mAppliedLowPower) {
1830                 slowChange = false;
1831             }
1832             mAppliedLowPower = true;
1833         } else if (mAppliedLowPower) {
1834             slowChange = false;
1835             mAppliedLowPower = false;
1836         }
1837 
1838         // The current brightness to use has been calculated at this point, and HbmController should
1839         // be notified so that it can accurately calculate HDR or HBM levels. We specifically do it
1840         // here instead of having HbmController listen to the brightness setting because certain
1841         // brightness sources (such as an app override) are not saved to the setting, but should be
1842         // reflected in HBM calculations.
1843         mBrightnessRangeController.onBrightnessChanged(brightnessState, unthrottledBrightnessState,
1844                 mBrightnessThrottler.getBrightnessMaxReason());
1845 
1846         // Animate the screen brightness when the screen is on or dozing.
1847         // Skip the animation when the screen is off.
1848         boolean brightnessAdjusted = false;
1849         final boolean brightnessIsTemporary =
1850                 mAppliedTemporaryBrightness || mAppliedTemporaryAutoBrightnessAdjustment;
1851         if (!mPendingScreenOff) {
1852             if (mSkipScreenOnBrightnessRamp) {
1853                 if (state == Display.STATE_ON) {
1854                     if (mSkipRampState == RAMP_STATE_SKIP_NONE && mDozing) {
1855                         mInitialAutoBrightness = brightnessState;
1856                         mSkipRampState = RAMP_STATE_SKIP_INITIAL;
1857                     } else if (mSkipRampState == RAMP_STATE_SKIP_INITIAL
1858                             && mUseSoftwareAutoBrightnessConfig
1859                             && !BrightnessSynchronizer.floatEquals(brightnessState,
1860                             mInitialAutoBrightness)) {
1861                         mSkipRampState = RAMP_STATE_SKIP_AUTOBRIGHT;
1862                     } else if (mSkipRampState == RAMP_STATE_SKIP_AUTOBRIGHT) {
1863                         mSkipRampState = RAMP_STATE_SKIP_NONE;
1864                     }
1865                 } else {
1866                     mSkipRampState = RAMP_STATE_SKIP_NONE;
1867                 }
1868             }
1869 
1870             final boolean initialRampSkip = (state == Display.STATE_ON && mSkipRampState
1871                     != RAMP_STATE_SKIP_NONE) || skipRampBecauseOfProximityChangeToNegative;
1872             // While dozing, sometimes the brightness is split into buckets. Rather than animating
1873             // through the buckets, which is unlikely to be smooth in the first place, just jump
1874             // right to the suggested brightness.
1875             final boolean hasBrightnessBuckets =
1876                     Display.isDozeState(state) && mBrightnessBucketsInDozeConfig;
1877             // If the color fade is totally covering the screen then we can change the backlight
1878             // level without it being a noticeable jump since any actual content isn't yet visible.
1879             final boolean isDisplayContentVisible =
1880                     mColorFadeEnabled && mPowerState.getColorFadeLevel() == 1.0f;
1881             // We only want to animate the brightness if it is between 0.0f and 1.0f.
1882             // brightnessState can contain the values -1.0f and NaN, which we do not want to
1883             // animate to. To avoid this, we check the value first.
1884             // If the brightnessState is off (-1.0f) we still want to animate to the minimum
1885             // brightness (0.0f) to accommodate for LED displays, which can appear bright to the
1886             // user even when the display is all black. We also clamp here in case some
1887             // transformations to the brightness have pushed it outside of the currently
1888             // allowed range.
1889             float animateValue = clampScreenBrightness(brightnessState);
1890 
1891             // If there are any HDR layers on the screen, we have a special brightness value that we
1892             // use instead. We still preserve the calculated brightness for Standard Dynamic Range
1893             // (SDR) layers, but the main brightness value will be the one for HDR.
1894             float sdrAnimateValue = animateValue;
1895             // TODO(b/216365040): The decision to prevent HBM for HDR in low power mode should be
1896             // done in HighBrightnessModeController.
1897             if (mBrightnessRangeController.getHighBrightnessMode()
1898                     == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR
1899                     && (mBrightnessReasonTemp.getModifier() & BrightnessReason.MODIFIER_DIMMED) == 0
1900                     && (mBrightnessReasonTemp.getModifier() & BrightnessReason.MODIFIER_LOW_POWER)
1901                     == 0) {
1902                 // We want to scale HDR brightness level with the SDR level, we also need to restore
1903                 // SDR brightness immediately when entering dim or low power mode.
1904                 animateValue = mBrightnessRangeController.getHdrBrightnessValue();
1905             }
1906 
1907             final float currentBrightness = mPowerState.getScreenBrightness();
1908             final float currentSdrBrightness = mPowerState.getSdrScreenBrightness();
1909             if (isValidBrightnessValue(animateValue)
1910                     && (animateValue != currentBrightness
1911                     || sdrAnimateValue != currentSdrBrightness)) {
1912                 if (initialRampSkip || hasBrightnessBuckets
1913                         || !isDisplayContentVisible || brightnessIsTemporary) {
1914                     animateScreenBrightness(animateValue, sdrAnimateValue,
1915                             SCREEN_ANIMATION_RATE_MINIMUM);
1916                 } else {
1917                     boolean isIncreasing = animateValue > currentBrightness;
1918                     final float rampSpeed;
1919                     if (isIncreasing && slowChange) {
1920                         rampSpeed = mBrightnessRampRateSlowIncrease;
1921                     } else if (isIncreasing && !slowChange) {
1922                         rampSpeed = mBrightnessRampRateFastIncrease;
1923                     } else if (!isIncreasing && slowChange) {
1924                         rampSpeed = mBrightnessRampRateSlowDecrease;
1925                     } else {
1926                         rampSpeed = mBrightnessRampRateFastDecrease;
1927                     }
1928                     animateScreenBrightness(animateValue, sdrAnimateValue, rampSpeed);
1929                 }
1930             }
1931 
1932             notifyBrightnessTrackerChanged(brightnessState, userInitiatedChange,
1933                     wasShortTermModelActive, autoBrightnessEnabled, brightnessIsTemporary);
1934 
1935             // We save the brightness info *after* the brightness setting has been changed and
1936             // adjustments made so that the brightness info reflects the latest value.
1937             brightnessAdjusted = saveBrightnessInfo(getScreenBrightnessSetting(), animateValue);
1938         } else {
1939             brightnessAdjusted = saveBrightnessInfo(getScreenBrightnessSetting());
1940         }
1941 
1942         // Only notify if the brightness adjustment is not temporary (i.e. slider has been released)
1943         if (brightnessAdjusted && !brightnessIsTemporary) {
1944             postBrightnessChangeRunnable();
1945         }
1946 
1947         // Log any changes to what is currently driving the brightness setting.
1948         if (!mBrightnessReasonTemp.equals(mBrightnessReason) || brightnessAdjustmentFlags != 0) {
1949             Slog.v(mTag, "Brightness [" + brightnessState + "] reason changing to: '"
1950                     + mBrightnessReasonTemp.toString(brightnessAdjustmentFlags)
1951                     + "', previous reason: '" + mBrightnessReason + "'.");
1952             mBrightnessReason.set(mBrightnessReasonTemp);
1953         } else if (mBrightnessReasonTemp.getReason() == BrightnessReason.REASON_MANUAL
1954                 && userSetBrightnessChanged) {
1955             Slog.v(mTag, "Brightness [" + brightnessState + "] manual adjustment.");
1956         }
1957 
1958 
1959         // Log brightness events when a detail of significance has changed. Generally this is the
1960         // brightness itself changing, but also includes data like HBM cap, thermal throttling
1961         // brightness cap, RBC state, etc.
1962         mTempBrightnessEvent.setTime(System.currentTimeMillis());
1963         mTempBrightnessEvent.setBrightness(brightnessState);
1964         mTempBrightnessEvent.setPhysicalDisplayId(mUniqueDisplayId);
1965         mTempBrightnessEvent.setReason(mBrightnessReason);
1966         mTempBrightnessEvent.setHbmMax(mBrightnessRangeController.getCurrentBrightnessMax());
1967         mTempBrightnessEvent.setHbmMode(mBrightnessRangeController.getHighBrightnessMode());
1968         mTempBrightnessEvent.setFlags(mTempBrightnessEvent.getFlags()
1969                 | (mIsRbcActive ? BrightnessEvent.FLAG_RBC : 0)
1970                 | (mPowerRequest.lowPowerMode ? BrightnessEvent.FLAG_LOW_POWER_MODE : 0));
1971         mTempBrightnessEvent.setRbcStrength(mCdsi != null
1972                 ? mCdsi.getReduceBrightColorsStrength() : -1);
1973         mTempBrightnessEvent.setPowerFactor(mPowerRequest.screenLowPowerBrightnessFactor);
1974         mTempBrightnessEvent.setWasShortTermModelActive(wasShortTermModelActive);
1975         mTempBrightnessEvent.setAutomaticBrightnessEnabled(mUseAutoBrightness);
1976         // Temporary is what we use during slider interactions. We avoid logging those so that
1977         // we don't spam logcat when the slider is being used.
1978         boolean tempToTempTransition =
1979                 mTempBrightnessEvent.getReason().getReason() == BrightnessReason.REASON_TEMPORARY
1980                         && mLastBrightnessEvent.getReason().getReason()
1981                         == BrightnessReason.REASON_TEMPORARY;
1982         if ((!mTempBrightnessEvent.equalsMainData(mLastBrightnessEvent) && !tempToTempTransition)
1983                 || brightnessAdjustmentFlags != 0) {
1984             mTempBrightnessEvent.setInitialBrightness(mLastBrightnessEvent.getBrightness());
1985             mLastBrightnessEvent.copyFrom(mTempBrightnessEvent);
1986             BrightnessEvent newEvent = new BrightnessEvent(mTempBrightnessEvent);
1987             // Adjustment flags (and user-set flag) only get added after the equality checks since
1988             // they are transient.
1989             newEvent.setAdjustmentFlags(brightnessAdjustmentFlags);
1990             newEvent.setFlags(newEvent.getFlags() | (userSetBrightnessChanged
1991                     ? BrightnessEvent.FLAG_USER_SET : 0));
1992             Slog.i(mTag, newEvent.toString(/* includeTime= */ false));
1993 
1994             if (userSetBrightnessChanged
1995                     || newEvent.getReason().getReason() != BrightnessReason.REASON_TEMPORARY) {
1996                 logBrightnessEvent(newEvent, unthrottledBrightnessState);
1997             }
1998             if (mBrightnessEventRingBuffer != null) {
1999                 mBrightnessEventRingBuffer.append(newEvent);
2000             }
2001         }
2002 
2003         // Update display white-balance.
2004         if (mDisplayWhiteBalanceController != null) {
2005             if (state == Display.STATE_ON && mDisplayWhiteBalanceSettings.isEnabled()) {
2006                 mDisplayWhiteBalanceController.setEnabled(true);
2007                 mDisplayWhiteBalanceController.updateDisplayColorTemperature();
2008             } else {
2009                 mDisplayWhiteBalanceController.setEnabled(false);
2010             }
2011         }
2012 
2013         // Determine whether the display is ready for use in the newly requested state.
2014         // Note that we do not wait for the brightness ramp animation to complete before
2015         // reporting the display is ready because we only need to ensure the screen is in the
2016         // right power state even as it continues to converge on the desired brightness.
2017         final boolean ready = mPendingScreenOnUnblocker == null
2018                 && (!mColorFadeEnabled || (!mColorFadeOnAnimator.isStarted()
2019                         && !mColorFadeOffAnimator.isStarted()))
2020                 && mPowerState.waitUntilClean(mCleanListener);
2021         final boolean finished = ready
2022                 && !mScreenBrightnessRampAnimator.isAnimating();
2023 
2024         // Notify policy about screen turned on.
2025         if (ready && state != Display.STATE_OFF
2026                 && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_ON) {
2027             setReportedScreenState(REPORTED_TO_POLICY_SCREEN_ON);
2028             mWindowManagerPolicy.screenTurnedOn(mDisplayId);
2029         }
2030 
2031         // Grab a wake lock if we have unfinished business.
2032         if (!finished && !mUnfinishedBusiness) {
2033             if (DEBUG) {
2034                 Slog.d(mTag, "Unfinished business...");
2035             }
2036             mCallbacks.acquireSuspendBlocker(mSuspendBlockerIdUnfinishedBusiness);
2037             mUnfinishedBusiness = true;
2038         }
2039 
2040         // Notify the power manager when ready.
2041         if (ready && mustNotify) {
2042             // Send state change.
2043             synchronized (mLock) {
2044                 if (!mPendingRequestChangedLocked) {
2045                     mDisplayReadyLocked = true;
2046 
2047                     if (DEBUG) {
2048                         Slog.d(mTag, "Display ready!");
2049                     }
2050                 }
2051             }
2052             sendOnStateChangedWithWakelock();
2053         }
2054 
2055         // Release the wake lock when we have no unfinished business.
2056         if (finished && mUnfinishedBusiness) {
2057             if (DEBUG) {
2058                 Slog.d(mTag, "Finished business...");
2059             }
2060             mUnfinishedBusiness = false;
2061             mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdUnfinishedBusiness);
2062         }
2063 
2064         // Record if dozing for future comparison.
2065         mDozing = state != Display.STATE_ON;
2066 
2067         if (previousPolicy != mPowerRequest.policy) {
2068             logDisplayPolicyChanged(mPowerRequest.policy);
2069         }
2070     }
2071 
setDwbcOverride(float cct)2072     private void setDwbcOverride(float cct) {
2073         if (mDisplayWhiteBalanceController != null) {
2074             mDisplayWhiteBalanceController.setAmbientColorTemperatureOverride(cct);
2075             // The ambient color temperature override is only applied when the ambient color
2076             // temperature changes or is updated, so it doesn't necessarily change the screen color
2077             // temperature immediately. So, let's make it!
2078             // We can call this directly, since we're already on the handler thread.
2079             updatePowerState();
2080         }
2081     }
2082 
setDwbcStrongMode(int arg)2083     private void setDwbcStrongMode(int arg) {
2084         if (mDisplayWhiteBalanceController != null) {
2085             final boolean isIdle = (arg == 1);
2086             mDisplayWhiteBalanceController.setStrongModeEnabled(isIdle);
2087         }
2088     }
2089 
setDwbcLoggingEnabled(int arg)2090     private void setDwbcLoggingEnabled(int arg) {
2091         if (mDisplayWhiteBalanceController != null) {
2092             final boolean shouldEnable = (arg == 1);
2093             mDisplayWhiteBalanceController.setLoggingEnabled(shouldEnable);
2094             mDisplayWhiteBalanceSettings.setLoggingEnabled(shouldEnable);
2095         }
2096     }
2097 
2098     @Override
updateBrightness()2099     public void updateBrightness() {
2100         sendUpdatePowerState();
2101     }
2102 
2103     /**
2104      * Ignores the proximity sensor until the sensor state changes, but only if the sensor is
2105      * currently enabled and forcing the screen to be dark.
2106      */
2107     @Override
ignoreProximitySensorUntilChanged()2108     public void ignoreProximitySensorUntilChanged() {
2109         mHandler.sendEmptyMessage(MSG_IGNORE_PROXIMITY);
2110     }
2111 
2112     @Override
setBrightnessConfiguration(BrightnessConfiguration c, boolean shouldResetShortTermModel)2113     public void setBrightnessConfiguration(BrightnessConfiguration c,
2114             boolean shouldResetShortTermModel) {
2115         Message msg = mHandler.obtainMessage(MSG_CONFIGURE_BRIGHTNESS,
2116                 shouldResetShortTermModel ? 1 : 0, /* unused */ 0, c);
2117         msg.sendToTarget();
2118     }
2119 
2120     @Override
setTemporaryBrightness(float brightness)2121     public void setTemporaryBrightness(float brightness) {
2122         Message msg = mHandler.obtainMessage(MSG_SET_TEMPORARY_BRIGHTNESS,
2123                 Float.floatToIntBits(brightness), 0 /*unused*/);
2124         msg.sendToTarget();
2125     }
2126 
2127     @Override
setTemporaryAutoBrightnessAdjustment(float adjustment)2128     public void setTemporaryAutoBrightnessAdjustment(float adjustment) {
2129         Message msg = mHandler.obtainMessage(MSG_SET_TEMPORARY_AUTO_BRIGHTNESS_ADJUSTMENT,
2130                 Float.floatToIntBits(adjustment), 0 /*unused*/);
2131         msg.sendToTarget();
2132     }
2133 
2134     @Override
getBrightnessInfo()2135     public BrightnessInfo getBrightnessInfo() {
2136         synchronized (mCachedBrightnessInfo) {
2137             return new BrightnessInfo(
2138                     mCachedBrightnessInfo.brightness.value,
2139                     mCachedBrightnessInfo.adjustedBrightness.value,
2140                     mCachedBrightnessInfo.brightnessMin.value,
2141                     mCachedBrightnessInfo.brightnessMax.value,
2142                     mCachedBrightnessInfo.hbmMode.value,
2143                     mCachedBrightnessInfo.hbmTransitionPoint.value,
2144                     mCachedBrightnessInfo.brightnessMaxReason.value);
2145         }
2146     }
2147 
saveBrightnessInfo(float brightness)2148     private boolean saveBrightnessInfo(float brightness) {
2149         return saveBrightnessInfo(brightness, brightness);
2150     }
2151 
saveBrightnessInfo(float brightness, float adjustedBrightness)2152     private boolean saveBrightnessInfo(float brightness, float adjustedBrightness) {
2153         synchronized (mCachedBrightnessInfo) {
2154             final float minBrightness = Math.min(
2155                     mBrightnessRangeController.getCurrentBrightnessMin(),
2156                     mBrightnessThrottler.getBrightnessCap());
2157             final float maxBrightness = Math.min(
2158                     mBrightnessRangeController.getCurrentBrightnessMax(),
2159                     mBrightnessThrottler.getBrightnessCap());
2160             boolean changed = false;
2161 
2162             changed |=
2163                     mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.brightness,
2164                             brightness);
2165             changed |=
2166                     mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.adjustedBrightness,
2167                             adjustedBrightness);
2168             changed |=
2169                     mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.brightnessMin,
2170                             minBrightness);
2171             changed |=
2172                     mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.brightnessMax,
2173                             maxBrightness);
2174             changed |=
2175                     mCachedBrightnessInfo.checkAndSetInt(mCachedBrightnessInfo.hbmMode,
2176                             mBrightnessRangeController.getHighBrightnessMode());
2177             changed |=
2178                     mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.hbmTransitionPoint,
2179                             mBrightnessRangeController.getTransitionPoint());
2180             changed |=
2181                     mCachedBrightnessInfo.checkAndSetInt(mCachedBrightnessInfo.brightnessMaxReason,
2182                             mBrightnessThrottler.getBrightnessMaxReason());
2183 
2184             return changed;
2185         }
2186     }
2187 
postBrightnessChangeRunnable()2188     void postBrightnessChangeRunnable() {
2189         if (!mHandler.hasCallbacks(mOnBrightnessChangeRunnable)) {
2190             mHandler.post(mOnBrightnessChangeRunnable);
2191         }
2192     }
2193 
createHbmControllerLocked( Runnable modeChangeCallback)2194     private HighBrightnessModeController createHbmControllerLocked(
2195             Runnable modeChangeCallback) {
2196         final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
2197         final DisplayDeviceConfig ddConfig = device.getDisplayDeviceConfig();
2198         final IBinder displayToken =
2199                 mLogicalDisplay.getPrimaryDisplayDeviceLocked().getDisplayTokenLocked();
2200         final String displayUniqueId =
2201                 mLogicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId();
2202         final DisplayDeviceConfig.HighBrightnessModeData hbmData =
2203                 ddConfig != null ? ddConfig.getHighBrightnessModeData() : null;
2204         final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
2205         return mInjector.getHighBrightnessModeController(mHandler, info.width, info.height,
2206                 displayToken, displayUniqueId, PowerManager.BRIGHTNESS_MIN,
2207                 PowerManager.BRIGHTNESS_MAX, hbmData,
2208                 new HighBrightnessModeController.HdrBrightnessDeviceConfig() {
2209                     @Override
2210                     public float getHdrBrightnessFromSdr(
2211                             float sdrBrightness, float maxDesiredHdrSdrRatio) {
2212                         return mDisplayDeviceConfig.getHdrBrightnessFromSdr(
2213                                 sdrBrightness, maxDesiredHdrSdrRatio);
2214                     }
2215                 }, modeChangeCallback, mHighBrightnessModeMetadata, mContext);
2216     }
2217 
2218     private BrightnessThrottler createBrightnessThrottlerLocked() {
2219         final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
2220         final DisplayDeviceConfig ddConfig = device.getDisplayDeviceConfig();
2221         return new BrightnessThrottler(mHandler,
2222                 () -> {
2223                     sendUpdatePowerState();
2224                     postBrightnessChangeRunnable();
2225                 }, mUniqueDisplayId,
2226                 mLogicalDisplay.getDisplayInfoLocked().thermalBrightnessThrottlingDataId,
2227                 ddConfig.getThermalBrightnessThrottlingDataMapByThrottlingId());
2228     }
2229 
2230     private void blockScreenOn() {
2231         if (mPendingScreenOnUnblocker == null) {
2232             Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0);
2233             mPendingScreenOnUnblocker = new ScreenOnUnblocker();
2234             mScreenOnBlockStartRealTime = SystemClock.elapsedRealtime();
2235             Slog.i(mTag, "Blocking screen on until initial contents have been drawn.");
2236         }
2237     }
2238 
2239     private void unblockScreenOn() {
2240         if (mPendingScreenOnUnblocker != null) {
2241             mPendingScreenOnUnblocker = null;
2242             long delay = SystemClock.elapsedRealtime() - mScreenOnBlockStartRealTime;
2243             Slog.i(mTag, "Unblocked screen on after " + delay + " ms");
2244             Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0);
2245         }
2246     }
2247 
2248     private void blockScreenOff() {
2249         if (mPendingScreenOffUnblocker == null) {
2250             Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, SCREEN_OFF_BLOCKED_TRACE_NAME, 0);
2251             mPendingScreenOffUnblocker = new ScreenOffUnblocker();
2252             mScreenOffBlockStartRealTime = SystemClock.elapsedRealtime();
2253             Slog.i(mTag, "Blocking screen off");
2254         }
2255     }
2256 
2257     private void unblockScreenOff() {
2258         if (mPendingScreenOffUnblocker != null) {
2259             mPendingScreenOffUnblocker = null;
2260             long delay = SystemClock.elapsedRealtime() - mScreenOffBlockStartRealTime;
2261             Slog.i(mTag, "Unblocked screen off after " + delay + " ms");
2262             Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, SCREEN_OFF_BLOCKED_TRACE_NAME, 0);
2263         }
2264     }
2265 
2266     private boolean setScreenState(int state) {
2267         return setScreenState(state, false /*reportOnly*/);
2268     }
2269 
2270     private boolean setScreenState(int state, boolean reportOnly) {
2271         final boolean isOff = (state == Display.STATE_OFF);
2272 
2273         if (mPowerState.getScreenState() != state
2274                 || mReportedScreenStateToPolicy == REPORTED_TO_POLICY_UNREPORTED) {
2275             // If we are trying to turn screen off, give policy a chance to do something before we
2276             // actually turn the screen off.
2277             if (isOff && !mScreenOffBecauseOfProximity) {
2278                 if (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_ON
2279                         || mReportedScreenStateToPolicy == REPORTED_TO_POLICY_UNREPORTED) {
2280                     setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_OFF);
2281                     blockScreenOff();
2282                     mWindowManagerPolicy.screenTurningOff(mDisplayId, mPendingScreenOffUnblocker);
2283                     unblockScreenOff();
2284                 } else if (mPendingScreenOffUnblocker != null) {
2285                     // Abort doing the state change until screen off is unblocked.
2286                     return false;
2287                 }
2288             }
2289 
2290             if (!reportOnly && mPowerState.getScreenState() != state
2291                     && readyToUpdateDisplayState()) {
2292                 Trace.traceCounter(Trace.TRACE_TAG_POWER, "ScreenState", state);
2293 
2294                 String propertyKey = "debug.tracing.screen_state";
2295                 String propertyValue = String.valueOf(state);
2296                 try {
2297                     // TODO(b/153319140) remove when we can get this from the above trace invocation
2298                     SystemProperties.set(propertyKey, propertyValue);
2299                 } catch (RuntimeException e) {
2300                     Slog.e(mTag, "Failed to set a system property: key=" + propertyKey
2301                             + " value=" + propertyValue + " " + e.getMessage());
2302                 }
2303 
2304                 mPowerState.setScreenState(state);
2305                 // Tell battery stats about the transition.
2306                 noteScreenState(state);
2307             }
2308         }
2309 
2310         // Tell the window manager policy when the screen is turned off or on unless it's due
2311         // to the proximity sensor.  We temporarily block turning the screen on until the
2312         // window manager is ready by leaving a black surface covering the screen.
2313         // This surface is essentially the final state of the color fade animation and
2314         // it is only removed once the window manager tells us that the activity has
2315         // finished drawing underneath.
2316         if (isOff && mReportedScreenStateToPolicy != REPORTED_TO_POLICY_SCREEN_OFF
2317                 && !mScreenOffBecauseOfProximity) {
2318             setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
2319             unblockScreenOn();
2320             mWindowManagerPolicy.screenTurnedOff(mDisplayId, mIsInTransition);
2321         } else if (!isOff
2322                 && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_OFF) {
2323 
2324             // We told policy already that screen was turning off, but now we changed our minds.
2325             // Complete the full state transition on -> turningOff -> off.
2326             unblockScreenOff();
2327             mWindowManagerPolicy.screenTurnedOff(mDisplayId, mIsInTransition);
2328             setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
2329         }
2330         if (!isOff
2331                 && (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF
2332                 || mReportedScreenStateToPolicy == REPORTED_TO_POLICY_UNREPORTED)) {
2333             setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_ON);
2334             if (mPowerState.getColorFadeLevel() == 0.0f) {
2335                 blockScreenOn();
2336             } else {
2337                 unblockScreenOn();
2338             }
2339             mWindowManagerPolicy.screenTurningOn(mDisplayId, mPendingScreenOnUnblocker);
2340         }
2341 
2342         // Return true if the screen isn't blocked.
2343         return mPendingScreenOnUnblocker == null;
2344     }
2345 
2346     private void setReportedScreenState(int state) {
2347         Trace.traceCounter(Trace.TRACE_TAG_POWER, "ReportedScreenStateToPolicy", state);
2348         mReportedScreenStateToPolicy = state;
2349     }
2350 
2351     private void loadAmbientLightSensor() {
2352         final int fallbackType = mDisplayId == Display.DEFAULT_DISPLAY
2353                 ? Sensor.TYPE_LIGHT : SensorUtils.NO_FALLBACK;
2354         mLightSensor = SensorUtils.findSensor(mSensorManager,
2355                 mDisplayDeviceConfig.getAmbientLightSensor(), fallbackType);
2356     }
2357 
2358     private void loadScreenOffBrightnessSensor() {
2359         mScreenOffBrightnessSensor = SensorUtils.findSensor(mSensorManager,
2360                 mDisplayDeviceConfig.getScreenOffBrightnessSensor(), SensorUtils.NO_FALLBACK);
2361     }
2362 
2363     private void loadProximitySensor() {
2364         if (DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT || mDisplayId != Display.DEFAULT_DISPLAY) {
2365             return;
2366         }
2367         mProximitySensor = SensorUtils.findSensor(mSensorManager,
2368                 mDisplayDeviceConfig.getProximitySensor(), Sensor.TYPE_PROXIMITY);
2369         if (mProximitySensor != null) {
2370             mProximityThreshold = Math.min(mProximitySensor.getMaximumRange(),
2371                     TYPICAL_PROXIMITY_THRESHOLD);
2372         }
2373     }
2374 
2375     private float clampScreenBrightness(float value) {
2376         if (Float.isNaN(value)) {
2377             value = PowerManager.BRIGHTNESS_MIN;
2378         }
2379         return MathUtils.constrain(value, mBrightnessRangeController.getCurrentBrightnessMin(),
2380                 mBrightnessRangeController.getCurrentBrightnessMax());
2381     }
2382 
2383     // Checks whether the brightness is within the valid brightness range, not including off.
2384     private boolean isValidBrightnessValue(float brightness) {
2385         return brightness >= PowerManager.BRIGHTNESS_MIN
2386                 && brightness <= PowerManager.BRIGHTNESS_MAX;
2387     }
2388 
2389     private void animateScreenBrightness(float target, float sdrTarget, float rate) {
2390         if (DEBUG) {
2391             Slog.d(mTag, "Animating brightness: target=" + target + ", sdrTarget=" + sdrTarget
2392                     + ", rate=" + rate);
2393         }
2394         if (mScreenBrightnessRampAnimator.animateTo(target, sdrTarget, rate)) {
2395             Trace.traceCounter(Trace.TRACE_TAG_POWER, "TargetScreenBrightness", (int) target);
2396 
2397             String propertyKey = "debug.tracing.screen_brightness";
2398             String propertyValue = String.valueOf(target);
2399             try {
2400                 // TODO(b/153319140) remove when we can get this from the above trace invocation
2401                 SystemProperties.set(propertyKey, propertyValue);
2402             } catch (RuntimeException e) {
2403                 Slog.e(mTag, "Failed to set a system property: key=" + propertyKey
2404                         + " value=" + propertyValue + " " + e.getMessage());
2405             }
2406 
2407             noteScreenBrightness(target);
2408         }
2409     }
2410 
2411     private void animateScreenStateChange(int target, boolean performScreenOffTransition) {
2412         // If there is already an animation in progress, don't interfere with it.
2413         if (mColorFadeEnabled
2414                 && (mColorFadeOnAnimator.isStarted() || mColorFadeOffAnimator.isStarted())) {
2415             if (target != Display.STATE_ON) {
2416                 return;
2417             }
2418             // If display state changed to on, proceed and stop the color fade and turn screen on.
2419             mPendingScreenOff = false;
2420         }
2421 
2422         if (mDisplayBlanksAfterDozeConfig
2423                 && Display.isDozeState(mPowerState.getScreenState())
2424                 && !Display.isDozeState(target)) {
2425             // Skip the screen off animation and add a black surface to hide the
2426             // contents of the screen.
2427             mPowerState.prepareColorFade(mContext,
2428                     mColorFadeFadesConfig ? ColorFade.MODE_FADE : ColorFade.MODE_WARM_UP);
2429             if (mColorFadeOffAnimator != null) {
2430                 mColorFadeOffAnimator.end();
2431             }
2432             // Some display hardware will blank itself on the transition between doze and non-doze
2433             // but still on display states. In this case we want to report to policy that the
2434             // display has turned off so it can prepare the appropriate power on animation, but we
2435             // don't want to actually transition to the fully off state since that takes
2436             // significantly longer to transition from.
2437             setScreenState(Display.STATE_OFF, target != Display.STATE_OFF /*reportOnly*/);
2438         }
2439 
2440         // If we were in the process of turning off the screen but didn't quite
2441         // finish.  Then finish up now to prevent a jarring transition back
2442         // to screen on if we skipped blocking screen on as usual.
2443         if (mPendingScreenOff && target != Display.STATE_OFF) {
2444             setScreenState(Display.STATE_OFF);
2445             mPendingScreenOff = false;
2446             mPowerState.dismissColorFadeResources();
2447         }
2448 
2449         if (target == Display.STATE_ON) {
2450             // Want screen on.  The contents of the screen may not yet
2451             // be visible if the color fade has not been dismissed because
2452             // its last frame of animation is solid black.
2453             if (!setScreenState(Display.STATE_ON)) {
2454                 return; // screen on blocked
2455             }
2456             if (USE_COLOR_FADE_ON_ANIMATION && mColorFadeEnabled && mPowerRequest.isBrightOrDim()) {
2457                 // Perform screen on animation.
2458                 if (mPowerState.getColorFadeLevel() == 1.0f) {
2459                     mPowerState.dismissColorFade();
2460                 } else if (mPowerState.prepareColorFade(mContext,
2461                         mColorFadeFadesConfig
2462                                 ? ColorFade.MODE_FADE : ColorFade.MODE_WARM_UP)) {
2463                     mColorFadeOnAnimator.start();
2464                 } else {
2465                     mColorFadeOnAnimator.end();
2466                 }
2467             } else {
2468                 // Skip screen on animation.
2469                 mPowerState.setColorFadeLevel(1.0f);
2470                 mPowerState.dismissColorFade();
2471             }
2472         } else if (target == Display.STATE_DOZE) {
2473             // Want screen dozing.
2474             // Wait for brightness animation to complete beforehand when entering doze
2475             // from screen on to prevent a perceptible jump because brightness may operate
2476             // differently when the display is configured for dozing.
2477             if (mScreenBrightnessRampAnimator.isAnimating()
2478                     && mPowerState.getScreenState() == Display.STATE_ON) {
2479                 return;
2480             }
2481 
2482             // Set screen state.
2483             if (!setScreenState(Display.STATE_DOZE)) {
2484                 return; // screen on blocked
2485             }
2486 
2487             // Dismiss the black surface without fanfare.
2488             mPowerState.setColorFadeLevel(1.0f);
2489             mPowerState.dismissColorFade();
2490         } else if (target == Display.STATE_DOZE_SUSPEND) {
2491             // Want screen dozing and suspended.
2492             // Wait for brightness animation to complete beforehand unless already
2493             // suspended because we may not be able to change it after suspension.
2494             if (mScreenBrightnessRampAnimator.isAnimating()
2495                     && mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) {
2496                 return;
2497             }
2498 
2499             // If not already suspending, temporarily set the state to doze until the
2500             // screen on is unblocked, then suspend.
2501             if (mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) {
2502                 if (!setScreenState(Display.STATE_DOZE)) {
2503                     return; // screen on blocked
2504                 }
2505                 setScreenState(Display.STATE_DOZE_SUSPEND); // already on so can't block
2506             }
2507 
2508             // Dismiss the black surface without fanfare.
2509             mPowerState.setColorFadeLevel(1.0f);
2510             mPowerState.dismissColorFade();
2511         } else if (target == Display.STATE_ON_SUSPEND) {
2512             // Want screen full-power and suspended.
2513             // Wait for brightness animation to complete beforehand unless already
2514             // suspended because we may not be able to change it after suspension.
2515             if (mScreenBrightnessRampAnimator.isAnimating()
2516                     && mPowerState.getScreenState() != Display.STATE_ON_SUSPEND) {
2517                 return;
2518             }
2519 
2520             // If not already suspending, temporarily set the state to on until the
2521             // screen on is unblocked, then suspend.
2522             if (mPowerState.getScreenState() != Display.STATE_ON_SUSPEND) {
2523                 if (!setScreenState(Display.STATE_ON)) {
2524                     return;
2525                 }
2526                 setScreenState(Display.STATE_ON_SUSPEND);
2527             }
2528 
2529             // Dismiss the black surface without fanfare.
2530             mPowerState.setColorFadeLevel(1.0f);
2531             mPowerState.dismissColorFade();
2532         } else {
2533             // Want screen off.
2534             mPendingScreenOff = true;
2535             if (!mColorFadeEnabled) {
2536                 mPowerState.setColorFadeLevel(0.0f);
2537             }
2538 
2539             if (mPowerState.getColorFadeLevel() == 0.0f) {
2540                 // Turn the screen off.
2541                 // A black surface is already hiding the contents of the screen.
2542                 setScreenState(Display.STATE_OFF);
2543                 mPendingScreenOff = false;
2544                 mPowerState.dismissColorFadeResources();
2545             } else if (performScreenOffTransition
2546                     && mPowerState.prepareColorFade(mContext,
2547                     mColorFadeFadesConfig
2548                             ? ColorFade.MODE_FADE : ColorFade.MODE_COOL_DOWN)
2549                     && mPowerState.getScreenState() != Display.STATE_OFF) {
2550                 // Perform the screen off animation.
2551                 mColorFadeOffAnimator.start();
2552             } else {
2553                 // Skip the screen off animation and add a black surface to hide the
2554                 // contents of the screen.
2555                 mColorFadeOffAnimator.end();
2556             }
2557         }
2558     }
2559 
2560     private final Runnable mCleanListener = this::sendUpdatePowerState;
2561 
2562     private void setProximitySensorEnabled(boolean enable) {
2563         if (enable) {
2564             if (!mProximitySensorEnabled) {
2565                 // Register the listener.
2566                 // Proximity sensor state already cleared initially.
2567                 mProximitySensorEnabled = true;
2568                 mIgnoreProximityUntilChanged = false;
2569                 mSensorManager.registerListener(mProximitySensorListener, mProximitySensor,
2570                         SensorManager.SENSOR_DELAY_NORMAL, mHandler);
2571             }
2572         } else {
2573             if (mProximitySensorEnabled) {
2574                 // Unregister the listener.
2575                 // Clear the proximity sensor state for next time.
2576                 mProximitySensorEnabled = false;
2577                 mProximity = PROXIMITY_UNKNOWN;
2578                 mIgnoreProximityUntilChanged = false;
2579                 mPendingProximity = PROXIMITY_UNKNOWN;
2580                 mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
2581                 mSensorManager.unregisterListener(mProximitySensorListener);
2582                 clearPendingProximityDebounceTime(); // release wake lock (must be last)
2583             }
2584         }
2585     }
2586 
2587     private void handleProximitySensorEvent(long time, boolean positive) {
2588         if (mProximitySensorEnabled) {
2589             if (mPendingProximity == PROXIMITY_NEGATIVE && !positive) {
2590                 return; // no change
2591             }
2592             if (mPendingProximity == PROXIMITY_POSITIVE && positive) {
2593                 return; // no change
2594             }
2595 
2596             // Only accept a proximity sensor reading if it remains
2597             // stable for the entire debounce delay.  We hold a wake lock while
2598             // debouncing the sensor.
2599             mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
2600             if (positive) {
2601                 mPendingProximity = PROXIMITY_POSITIVE;
2602                 setPendingProximityDebounceTime(
2603                         time + PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY); // acquire wake lock
2604             } else {
2605                 mPendingProximity = PROXIMITY_NEGATIVE;
2606                 setPendingProximityDebounceTime(
2607                         time + PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY); // acquire wake lock
2608             }
2609 
2610             // Debounce the new sensor reading.
2611             debounceProximitySensor();
2612         }
2613     }
2614 
2615     private void debounceProximitySensor() {
2616         if (mProximitySensorEnabled
2617                 && mPendingProximity != PROXIMITY_UNKNOWN
2618                 && mPendingProximityDebounceTime >= 0) {
2619             final long now = mClock.uptimeMillis();
2620             if (mPendingProximityDebounceTime <= now) {
2621                 if (mProximity != mPendingProximity) {
2622                     // if the status of the sensor changed, stop ignoring.
2623                     mIgnoreProximityUntilChanged = false;
2624                     Slog.i(mTag, "No longer ignoring proximity [" + mPendingProximity + "]");
2625                 }
2626                 // Sensor reading accepted.  Apply the change then release the wake lock.
2627                 mProximity = mPendingProximity;
2628                 updatePowerState();
2629                 clearPendingProximityDebounceTime(); // release wake lock (must be last)
2630             } else {
2631                 // Need to wait a little longer.
2632                 // Debounce again later.  We continue holding a wake lock while waiting.
2633                 Message msg = mHandler.obtainMessage(MSG_PROXIMITY_SENSOR_DEBOUNCED);
2634                 mHandler.sendMessageAtTime(msg, mPendingProximityDebounceTime);
2635             }
2636         }
2637     }
2638 
2639     private void clearPendingProximityDebounceTime() {
2640         if (mPendingProximityDebounceTime >= 0) {
2641             mPendingProximityDebounceTime = -1;
2642             mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdProxDebounce);
2643         }
2644     }
2645 
2646     private void setPendingProximityDebounceTime(long debounceTime) {
2647         if (mPendingProximityDebounceTime < 0) {
2648             mCallbacks.acquireSuspendBlocker(mSuspendBlockerIdProxDebounce);
2649         }
2650         mPendingProximityDebounceTime = debounceTime;
2651     }
2652 
2653     private void sendOnStateChangedWithWakelock() {
2654         if (!mOnStateChangedPending) {
2655             mOnStateChangedPending = true;
2656             mCallbacks.acquireSuspendBlocker(mSuspendBlockerIdOnStateChanged);
2657             mHandler.post(mOnStateChangedRunnable);
2658         }
2659     }
2660 
2661     private void logDisplayPolicyChanged(int newPolicy) {
2662         LogMaker log = new LogMaker(MetricsEvent.DISPLAY_POLICY);
2663         log.setType(MetricsEvent.TYPE_UPDATE);
2664         log.setSubtype(newPolicy);
2665         MetricsLogger.action(log);
2666     }
2667 
2668     private void handleSettingsChange(boolean userSwitch) {
2669         mPendingScreenBrightnessSetting = getScreenBrightnessSetting();
2670         mPendingAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting();
2671         if (userSwitch) {
2672             // Don't treat user switches as user initiated change.
2673             setCurrentScreenBrightness(mPendingScreenBrightnessSetting);
2674             updateAutoBrightnessAdjustment();
2675             if (mAutomaticBrightnessController != null) {
2676                 mAutomaticBrightnessController.resetShortTermModel();
2677             }
2678         }
2679         sendUpdatePowerState();
2680     }
2681 
2682     private void handleBrightnessModeChange() {
2683         final int screenBrightnessModeSetting = Settings.System.getIntForUser(
2684                 mContext.getContentResolver(),
2685                 Settings.System.SCREEN_BRIGHTNESS_MODE,
2686                 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, UserHandle.USER_CURRENT);
2687         mHandler.postAtTime(() -> {
2688             mUseAutoBrightness = screenBrightnessModeSetting
2689                     == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
2690             updatePowerState();
2691         }, mClock.uptimeMillis());
2692     }
2693 
2694     private float getAutoBrightnessAdjustmentSetting() {
2695         final float adj = Settings.System.getFloatForUser(mContext.getContentResolver(),
2696                 Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f, UserHandle.USER_CURRENT);
2697         return Float.isNaN(adj) ? 0.0f : clampAutoBrightnessAdjustment(adj);
2698     }
2699 
2700     @Override
2701     public float getScreenBrightnessSetting() {
2702         float brightness = mBrightnessSetting.getBrightness();
2703         if (Float.isNaN(brightness)) {
2704             brightness = mScreenBrightnessDefault;
2705         }
2706         return clampAbsoluteBrightness(brightness);
2707     }
2708 
2709     private void loadNitBasedBrightnessSetting() {
2710         if (mDisplayId == Display.DEFAULT_DISPLAY && mPersistBrightnessNitsForDefaultDisplay) {
2711             float brightnessNitsForDefaultDisplay =
2712                     mBrightnessSetting.getBrightnessNitsForDefaultDisplay();
2713             if (brightnessNitsForDefaultDisplay >= 0) {
2714                 float brightnessForDefaultDisplay = convertToFloatScale(
2715                         brightnessNitsForDefaultDisplay);
2716                 if (isValidBrightnessValue(brightnessForDefaultDisplay)) {
2717                     mBrightnessSetting.setBrightness(brightnessForDefaultDisplay);
2718                     mCurrentScreenBrightnessSetting = brightnessForDefaultDisplay;
2719                     return;
2720                 }
2721             }
2722         }
2723         mCurrentScreenBrightnessSetting = getScreenBrightnessSetting();
2724     }
2725 
2726     @Override
2727     public void setBrightness(float brightnessValue, int userSerial) {
2728         // Update the setting, which will eventually call back into DPC to have us actually update
2729         // the display with the new value.
2730         mBrightnessSetting.setUserSerial(userSerial);
2731         mBrightnessSetting.setBrightness(brightnessValue);
2732         if (mDisplayId == Display.DEFAULT_DISPLAY && mPersistBrightnessNitsForDefaultDisplay) {
2733             float nits = convertToNits(brightnessValue);
2734             if (nits >= 0) {
2735                 mBrightnessSetting.setBrightnessNitsForDefaultDisplay(nits);
2736             }
2737         }
2738     }
2739 
2740     @Override
2741     public void onBootCompleted() {
2742         Message msg = mHandler.obtainMessage(MSG_BOOT_COMPLETED);
2743         mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
2744     }
2745 
2746     private void updateScreenBrightnessSetting(float brightnessValue) {
2747         if (!isValidBrightnessValue(brightnessValue)
2748                 || brightnessValue == mCurrentScreenBrightnessSetting) {
2749             return;
2750         }
2751         setCurrentScreenBrightness(brightnessValue);
2752         setBrightness(brightnessValue);
2753     }
2754 
2755     private void setCurrentScreenBrightness(float brightnessValue) {
2756         if (brightnessValue != mCurrentScreenBrightnessSetting) {
2757             mCurrentScreenBrightnessSetting = brightnessValue;
2758             postBrightnessChangeRunnable();
2759         }
2760     }
2761 
2762     private void putAutoBrightnessAdjustmentSetting(float adjustment) {
2763         if (mDisplayId == Display.DEFAULT_DISPLAY) {
2764             mAutoBrightnessAdjustment = adjustment;
2765             Settings.System.putFloatForUser(mContext.getContentResolver(),
2766                     Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, adjustment,
2767                     UserHandle.USER_CURRENT);
2768         }
2769     }
2770 
2771     private boolean updateAutoBrightnessAdjustment() {
2772         if (Float.isNaN(mPendingAutoBrightnessAdjustment)) {
2773             return false;
2774         }
2775         if (mAutoBrightnessAdjustment == mPendingAutoBrightnessAdjustment) {
2776             mPendingAutoBrightnessAdjustment = Float.NaN;
2777             return false;
2778         }
2779         mAutoBrightnessAdjustment = mPendingAutoBrightnessAdjustment;
2780         mPendingAutoBrightnessAdjustment = Float.NaN;
2781         mTemporaryAutoBrightnessAdjustment = Float.NaN;
2782         return true;
2783     }
2784 
2785     // We want to return true if the user has set the screen brightness.
2786     // RBC on, off, and intensity changes will return false.
2787     // Slider interactions whilst in RBC will return true, just as when in non-rbc.
2788     private boolean updateUserSetScreenBrightness() {
2789         if ((Float.isNaN(mPendingScreenBrightnessSetting)
2790                 || mPendingScreenBrightnessSetting < 0.0f)) {
2791             return false;
2792         }
2793         if (mCurrentScreenBrightnessSetting == mPendingScreenBrightnessSetting) {
2794             mPendingScreenBrightnessSetting = PowerManager.BRIGHTNESS_INVALID_FLOAT;
2795             mTemporaryScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
2796             return false;
2797         }
2798         setCurrentScreenBrightness(mPendingScreenBrightnessSetting);
2799         mLastUserSetScreenBrightness = mPendingScreenBrightnessSetting;
2800         mPendingScreenBrightnessSetting = PowerManager.BRIGHTNESS_INVALID_FLOAT;
2801         mTemporaryScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
2802         return true;
2803     }
2804 
2805     private void notifyBrightnessTrackerChanged(float brightness, boolean userInitiated,
2806             boolean wasShortTermModelActive, boolean autobrightnessEnabled,
2807             boolean brightnessIsTemporary) {
2808         final float brightnessInNits = convertToAdjustedNits(brightness);
2809 
2810         // Don't report brightness to brightnessTracker:
2811         // If brightness is temporary (ie the slider has not been released)
2812         // or if we are in idle screen brightness mode.
2813         // or display is not on
2814         // or we shouldn't be using autobrightness
2815         // or the nits is invalid.
2816         if (brightnessIsTemporary
2817                 || mAutomaticBrightnessController == null
2818                 || mAutomaticBrightnessController.isInIdleMode()
2819                 || !autobrightnessEnabled
2820                 || mBrightnessTracker == null
2821                 || !mUseAutoBrightness
2822                 || brightnessInNits < 0.0f) {
2823             return;
2824         }
2825 
2826         if (userInitiated && !mAutomaticBrightnessController.hasValidAmbientLux()) {
2827             // If we don't have a valid lux reading we can't report a valid
2828             // slider event so notify as if the system changed the brightness.
2829             userInitiated = false;
2830         }
2831 
2832         // We only want to track changes on devices that can actually map the display backlight
2833         // values into a physical brightness unit since the value provided by the API is in
2834         // nits and not using the arbitrary backlight units.
2835         final float powerFactor = mPowerRequest.lowPowerMode
2836                 ? mPowerRequest.screenLowPowerBrightnessFactor
2837                 : 1.0f;
2838         mBrightnessTracker.notifyBrightnessChanged(brightnessInNits, userInitiated,
2839                 powerFactor, wasShortTermModelActive,
2840                 mAutomaticBrightnessController.isDefaultConfig(), mUniqueDisplayId,
2841                 mAutomaticBrightnessController.getLastSensorValues(),
2842                 mAutomaticBrightnessController.getLastSensorTimestamps());
2843     }
2844 
2845     private float convertToNits(float brightness) {
2846         if (mAutomaticBrightnessController == null) {
2847             return -1f;
2848         }
2849         return mAutomaticBrightnessController.convertToNits(brightness);
2850     }
2851 
2852     private float convertToAdjustedNits(float brightness) {
2853         if (mAutomaticBrightnessController == null) {
2854             return -1f;
2855         }
2856         return mAutomaticBrightnessController.convertToAdjustedNits(brightness);
2857     }
2858 
2859     private float convertToFloatScale(float nits) {
2860         if (mAutomaticBrightnessController == null) {
2861             return PowerManager.BRIGHTNESS_INVALID_FLOAT;
2862         }
2863         return mAutomaticBrightnessController.convertToFloatScale(nits);
2864     }
2865 
2866     @GuardedBy("mLock")
2867     private void updatePendingProximityRequestsLocked() {
2868         mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked;
2869         mPendingWaitForNegativeProximityLocked = false;
2870 
2871         if (mIgnoreProximityUntilChanged) {
2872             // Also, lets stop waiting for negative proximity if we're ignoring it.
2873             mWaitingForNegativeProximity = false;
2874         }
2875     }
2876 
2877     private void ignoreProximitySensorUntilChangedInternal() {
2878         if (!mIgnoreProximityUntilChanged
2879                 && mProximity == PROXIMITY_POSITIVE) {
2880             // Only ignore if it is still reporting positive (near)
2881             mIgnoreProximityUntilChanged = true;
2882             Slog.i(mTag, "Ignoring proximity");
2883             updatePowerState();
2884         }
2885     }
2886 
2887     private final Runnable mOnStateChangedRunnable = new Runnable() {
2888         @Override
2889         public void run() {
2890             mOnStateChangedPending = false;
2891             mCallbacks.onStateChanged();
2892             mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdOnStateChanged);
2893         }
2894     };
2895 
2896     private void sendOnProximityPositiveWithWakelock() {
2897         mCallbacks.acquireSuspendBlocker(mSuspendBlockerIdProxPositive);
2898         mHandler.post(mOnProximityPositiveRunnable);
2899         mOnProximityPositiveMessages++;
2900     }
2901 
2902     private final Runnable mOnProximityPositiveRunnable = new Runnable() {
2903         @Override
2904         public void run() {
2905             mOnProximityPositiveMessages--;
2906             mCallbacks.onProximityPositive();
2907             mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdProxPositive);
2908         }
2909     };
2910 
2911     private void sendOnProximityNegativeWithWakelock() {
2912         mOnProximityNegativeMessages++;
2913         mCallbacks.acquireSuspendBlocker(mSuspendBlockerIdProxNegative);
2914         mHandler.post(mOnProximityNegativeRunnable);
2915     }
2916 
2917     private final Runnable mOnProximityNegativeRunnable = new Runnable() {
2918         @Override
2919         public void run() {
2920             mOnProximityNegativeMessages--;
2921             mCallbacks.onProximityNegative();
2922             mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdProxNegative);
2923         }
2924     };
2925 
2926     /**
2927      * Indicates whether the display state is ready to update. If this is the default display, we
2928      * want to update it right away so that we can draw the boot animation on it. If it is not
2929      * the default display, drawing the boot animation on it would look incorrect, so we need
2930      * to wait until boot is completed.
2931      * @return True if the display state is ready to update
2932      */
2933     private boolean readyToUpdateDisplayState() {
2934         return mDisplayId == Display.DEFAULT_DISPLAY || mBootCompleted;
2935     }
2936 
2937     @Override
2938     public void dump(final PrintWriter pw) {
2939         synchronized (mLock) {
2940             pw.println();
2941             pw.println("Display Power Controller:");
2942             pw.println("  mDisplayId=" + mDisplayId);
2943             pw.println("  mLeadDisplayId=" + mLeadDisplayId);
2944             pw.println("  mLightSensor=" + mLightSensor);
2945             pw.println("  mDisplayBrightnessFollowers=" + mDisplayBrightnessFollowers);
2946 
2947             pw.println();
2948             pw.println("Display Power Controller Locked State:");
2949             pw.println("  mDisplayReadyLocked=" + mDisplayReadyLocked);
2950             pw.println("  mPendingRequestLocked=" + mPendingRequestLocked);
2951             pw.println("  mPendingRequestChangedLocked=" + mPendingRequestChangedLocked);
2952             pw.println("  mPendingWaitForNegativeProximityLocked="
2953                     + mPendingWaitForNegativeProximityLocked);
2954             pw.println("  mPendingUpdatePowerStateLocked=" + mPendingUpdatePowerStateLocked);
2955         }
2956 
2957         pw.println();
2958         pw.println("Display Power Controller Configuration:");
2959         pw.println("  mScreenBrightnessRangeDefault=" + mScreenBrightnessDefault);
2960         pw.println("  mScreenBrightnessDozeConfig=" + mScreenBrightnessDozeConfig);
2961         pw.println("  mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig);
2962         pw.println("  mUseSoftwareAutoBrightnessConfig=" + mUseSoftwareAutoBrightnessConfig);
2963         pw.println("  mAllowAutoBrightnessWhileDozingConfig="
2964                 + mAllowAutoBrightnessWhileDozingConfig);
2965         pw.println("  mPersistBrightnessNitsForDefaultDisplay="
2966                 + mPersistBrightnessNitsForDefaultDisplay);
2967         pw.println("  mSkipScreenOnBrightnessRamp=" + mSkipScreenOnBrightnessRamp);
2968         pw.println("  mColorFadeFadesConfig=" + mColorFadeFadesConfig);
2969         pw.println("  mColorFadeEnabled=" + mColorFadeEnabled);
2970         synchronized (mCachedBrightnessInfo) {
2971             pw.println("  mCachedBrightnessInfo.brightness="
2972                     + mCachedBrightnessInfo.brightness.value);
2973             pw.println("  mCachedBrightnessInfo.adjustedBrightness="
2974                     + mCachedBrightnessInfo.adjustedBrightness.value);
2975             pw.println("  mCachedBrightnessInfo.brightnessMin="
2976                     + mCachedBrightnessInfo.brightnessMin.value);
2977             pw.println("  mCachedBrightnessInfo.brightnessMax="
2978                     + mCachedBrightnessInfo.brightnessMax.value);
2979             pw.println("  mCachedBrightnessInfo.hbmMode=" + mCachedBrightnessInfo.hbmMode.value);
2980             pw.println("  mCachedBrightnessInfo.hbmTransitionPoint="
2981                     + mCachedBrightnessInfo.hbmTransitionPoint.value);
2982             pw.println("  mCachedBrightnessInfo.brightnessMaxReason ="
2983                     + mCachedBrightnessInfo.brightnessMaxReason.value);
2984         }
2985         pw.println("  mDisplayBlanksAfterDozeConfig=" + mDisplayBlanksAfterDozeConfig);
2986         pw.println("  mBrightnessBucketsInDozeConfig=" + mBrightnessBucketsInDozeConfig);
2987 
2988         mHandler.runWithScissors(() -> dumpLocal(pw), 1000);
2989     }
2990 
2991     private void dumpLocal(PrintWriter pw) {
2992         pw.println();
2993         pw.println("Display Power Controller Thread State:");
2994         pw.println("  mPowerRequest=" + mPowerRequest);
2995         pw.println("  mUnfinishedBusiness=" + mUnfinishedBusiness);
2996         pw.println("  mWaitingForNegativeProximity=" + mWaitingForNegativeProximity);
2997         pw.println("  mProximitySensor=" + mProximitySensor);
2998         pw.println("  mProximitySensorEnabled=" + mProximitySensorEnabled);
2999         pw.println("  mProximityThreshold=" + mProximityThreshold);
3000         pw.println("  mProximity=" + proximityToString(mProximity));
3001         pw.println("  mPendingProximity=" + proximityToString(mPendingProximity));
3002         pw.println("  mPendingProximityDebounceTime="
3003                 + TimeUtils.formatUptime(mPendingProximityDebounceTime));
3004         pw.println("  mScreenOffBecauseOfProximity=" + mScreenOffBecauseOfProximity);
3005         pw.println("  mLastUserSetScreenBrightness=" + mLastUserSetScreenBrightness);
3006         pw.println("  mPendingScreenBrightnessSetting="
3007                 + mPendingScreenBrightnessSetting);
3008         pw.println("  mTemporaryScreenBrightness=" + mTemporaryScreenBrightness);
3009         pw.println("  mBrightnessToFollow=" + mBrightnessToFollow);
3010         pw.println("  mBrightnessToFollowSlowChange=" + mBrightnessToFollowSlowChange);
3011         pw.println("  mAutoBrightnessAdjustment=" + mAutoBrightnessAdjustment);
3012         pw.println("  mBrightnessReason=" + mBrightnessReason);
3013         pw.println("  mTemporaryAutoBrightnessAdjustment=" + mTemporaryAutoBrightnessAdjustment);
3014         pw.println("  mPendingAutoBrightnessAdjustment=" + mPendingAutoBrightnessAdjustment);
3015         pw.println("  mAppliedAutoBrightness=" + mAppliedAutoBrightness);
3016         pw.println("  mAppliedDimming=" + mAppliedDimming);
3017         pw.println("  mAppliedLowPower=" + mAppliedLowPower);
3018         pw.println("  mAppliedThrottling=" + mAppliedThrottling);
3019         pw.println("  mAppliedScreenBrightnessOverride=" + mAppliedScreenBrightnessOverride);
3020         pw.println("  mAppliedTemporaryBrightness=" + mAppliedTemporaryBrightness);
3021         pw.println("  mAppliedTemporaryAutoBrightnessAdjustment="
3022                 + mAppliedTemporaryAutoBrightnessAdjustment);
3023         pw.println("  mAppliedBrightnessBoost=" + mAppliedBrightnessBoost);
3024         pw.println("  mDozing=" + mDozing);
3025         pw.println("  mSkipRampState=" + skipRampStateToString(mSkipRampState));
3026         pw.println("  mScreenOnBlockStartRealTime=" + mScreenOnBlockStartRealTime);
3027         pw.println("  mScreenOffBlockStartRealTime=" + mScreenOffBlockStartRealTime);
3028         pw.println("  mPendingScreenOnUnblocker=" + mPendingScreenOnUnblocker);
3029         pw.println("  mPendingScreenOffUnblocker=" + mPendingScreenOffUnblocker);
3030         pw.println("  mPendingScreenOff=" + mPendingScreenOff);
3031         pw.println("  mReportedToPolicy="
3032                 + reportedToPolicyToString(mReportedScreenStateToPolicy));
3033         pw.println("  mIsRbcActive=" + mIsRbcActive);
3034         pw.println("  mOnStateChangePending=" + mOnStateChangedPending);
3035         pw.println("  mOnProximityPositiveMessages=" + mOnProximityPositiveMessages);
3036         pw.println("  mOnProximityNegativeMessages=" + mOnProximityNegativeMessages);
3037 
3038         if (mScreenBrightnessRampAnimator != null) {
3039             pw.println("  mScreenBrightnessRampAnimator.isAnimating()="
3040                     + mScreenBrightnessRampAnimator.isAnimating());
3041         }
3042 
3043         if (mColorFadeOnAnimator != null) {
3044             pw.println("  mColorFadeOnAnimator.isStarted()="
3045                     + mColorFadeOnAnimator.isStarted());
3046         }
3047         if (mColorFadeOffAnimator != null) {
3048             pw.println("  mColorFadeOffAnimator.isStarted()="
3049                     + mColorFadeOffAnimator.isStarted());
3050         }
3051 
3052         if (mPowerState != null) {
3053             mPowerState.dump(pw);
3054         }
3055 
3056         if (mAutomaticBrightnessController != null) {
3057             mAutomaticBrightnessController.dump(pw);
3058             dumpBrightnessEvents(pw);
3059         }
3060 
3061         if (mScreenOffBrightnessSensorController != null) {
3062             mScreenOffBrightnessSensorController.dump(pw);
3063         }
3064 
3065         if (mBrightnessRangeController != null) {
3066             mBrightnessRangeController.dump(pw);
3067         }
3068 
3069         if (mBrightnessThrottler != null) {
3070             mBrightnessThrottler.dump(pw);
3071         }
3072 
3073         pw.println();
3074         if (mDisplayWhiteBalanceController != null) {
3075             mDisplayWhiteBalanceController.dump(pw);
3076             mDisplayWhiteBalanceSettings.dump(pw);
3077         }
3078     }
3079 
3080     private static String proximityToString(int state) {
3081         switch (state) {
3082             case PROXIMITY_UNKNOWN:
3083                 return "Unknown";
3084             case PROXIMITY_NEGATIVE:
3085                 return "Negative";
3086             case PROXIMITY_POSITIVE:
3087                 return "Positive";
3088             default:
3089                 return Integer.toString(state);
3090         }
3091     }
3092 
3093     private static String reportedToPolicyToString(int state) {
3094         switch (state) {
3095             case REPORTED_TO_POLICY_SCREEN_OFF:
3096                 return "REPORTED_TO_POLICY_SCREEN_OFF";
3097             case REPORTED_TO_POLICY_SCREEN_TURNING_ON:
3098                 return "REPORTED_TO_POLICY_SCREEN_TURNING_ON";
3099             case REPORTED_TO_POLICY_SCREEN_ON:
3100                 return "REPORTED_TO_POLICY_SCREEN_ON";
3101             default:
3102                 return Integer.toString(state);
3103         }
3104     }
3105 
3106     private static String skipRampStateToString(int state) {
3107         switch (state) {
3108             case RAMP_STATE_SKIP_NONE:
3109                 return "RAMP_STATE_SKIP_NONE";
3110             case RAMP_STATE_SKIP_INITIAL:
3111                 return "RAMP_STATE_SKIP_INITIAL";
3112             case RAMP_STATE_SKIP_AUTOBRIGHT:
3113                 return "RAMP_STATE_SKIP_AUTOBRIGHT";
3114             default:
3115                 return Integer.toString(state);
3116         }
3117     }
3118 
3119     private void dumpBrightnessEvents(PrintWriter pw) {
3120         int size = mBrightnessEventRingBuffer.size();
3121         if (size < 1) {
3122             pw.println("No Automatic Brightness Adjustments");
3123             return;
3124         }
3125 
3126         pw.println("Automatic Brightness Adjustments Last " + size + " Events: ");
3127         BrightnessEvent[] eventArray = mBrightnessEventRingBuffer.toArray();
3128         for (int i = 0; i < mBrightnessEventRingBuffer.size(); i++) {
3129             pw.println("  " + eventArray[i].toString());
3130         }
3131     }
3132 
3133     private static float clampAbsoluteBrightness(float value) {
3134         return MathUtils.constrain(value, PowerManager.BRIGHTNESS_MIN,
3135                 PowerManager.BRIGHTNESS_MAX);
3136     }
3137 
3138     private static float clampAutoBrightnessAdjustment(float value) {
3139         return MathUtils.constrain(value, -1.0f, 1.0f);
3140     }
3141 
3142     private void noteScreenState(int screenState) {
3143         // Log screen state change with display id
3144         FrameworkStatsLog.write(FrameworkStatsLog.SCREEN_STATE_CHANGED_V2,
3145                 screenState, mDisplayStatsId);
3146         if (mBatteryStats != null) {
3147             try {
3148                 // TODO(multi-display): make this multi-display
3149                 mBatteryStats.noteScreenState(screenState);
3150             } catch (RemoteException e) {
3151                 // same process
3152             }
3153         }
3154     }
3155 
3156     private void noteScreenBrightness(float brightness) {
3157         if (mBatteryStats != null) {
3158             try {
3159                 // TODO(brightnessfloat): change BatteryStats to use float
3160                 mBatteryStats.noteScreenBrightness(BrightnessSynchronizer.brightnessFloatToInt(
3161                         brightness));
3162             } catch (RemoteException e) {
3163                 // same process
3164             }
3165         }
3166     }
3167 
3168     private void reportStats(float brightness) {
3169         if (mLastStatsBrightness == brightness) {
3170             return;
3171         }
3172 
3173         float hbmTransitionPoint = PowerManager.BRIGHTNESS_MAX;
3174         synchronized (mCachedBrightnessInfo) {
3175             if (mCachedBrightnessInfo.hbmTransitionPoint == null) {
3176                 return;
3177             }
3178             hbmTransitionPoint = mCachedBrightnessInfo.hbmTransitionPoint.value;
3179         }
3180 
3181         final boolean aboveTransition = brightness > hbmTransitionPoint;
3182         final boolean oldAboveTransition = mLastStatsBrightness > hbmTransitionPoint;
3183 
3184         if (aboveTransition || oldAboveTransition) {
3185             mLastStatsBrightness = brightness;
3186             mHandler.removeMessages(MSG_STATSD_HBM_BRIGHTNESS);
3187             if (aboveTransition != oldAboveTransition) {
3188                 // report immediately
3189                 logHbmBrightnessStats(brightness, mDisplayStatsId);
3190             } else {
3191                 // delay for rate limiting
3192                 Message msg = mHandler.obtainMessage();
3193                 msg.what = MSG_STATSD_HBM_BRIGHTNESS;
3194                 msg.arg1 = Float.floatToIntBits(brightness);
3195                 msg.arg2 = mDisplayStatsId;
3196                 mHandler.sendMessageAtTime(msg, mClock.uptimeMillis()
3197                         + BRIGHTNESS_CHANGE_STATSD_REPORT_INTERVAL_MS);
3198             }
3199         }
3200     }
3201 
3202     private void logHbmBrightnessStats(float brightness, int displayStatsId) {
3203         synchronized (mHandler) {
3204             FrameworkStatsLog.write(
3205                     FrameworkStatsLog.DISPLAY_HBM_BRIGHTNESS_CHANGED, displayStatsId, brightness);
3206         }
3207     }
3208 
3209     // Return bucket index of range_[left]_[right] where
3210     // left <= nits < right
3211     private int nitsToRangeIndex(float nits) {
3212         for (int i = 0; i < BRIGHTNESS_RANGE_BOUNDARIES.length; i++) {
3213             if (nits < BRIGHTNESS_RANGE_BOUNDARIES[i]) {
3214                 return BRIGHTNESS_RANGE_INDEX[i];
3215             }
3216         }
3217         return FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_3000_INF;
3218     }
3219 
3220     private int convertBrightnessReasonToStatsEnum(int brightnessReason) {
3221         switch(brightnessReason) {
3222             case BrightnessReason.REASON_UNKNOWN:
3223                 return FrameworkStatsLog
3224                     .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_UNKNOWN;
3225             case BrightnessReason.REASON_MANUAL:
3226                 return FrameworkStatsLog
3227                     .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_MANUAL;
3228             case BrightnessReason.REASON_DOZE:
3229                 return FrameworkStatsLog
3230                     .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_DOZE;
3231             case BrightnessReason.REASON_DOZE_DEFAULT:
3232                 return FrameworkStatsLog
3233                     .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_DOZE_DEFAULT;
3234             case BrightnessReason.REASON_AUTOMATIC:
3235                 return FrameworkStatsLog
3236                     .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_AUTOMATIC;
3237             case BrightnessReason.REASON_SCREEN_OFF:
3238                 return FrameworkStatsLog
3239                     .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_SCREEN_OFF;
3240             case BrightnessReason.REASON_OVERRIDE:
3241                 return FrameworkStatsLog
3242                     .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_OVERRIDE;
3243             case BrightnessReason.REASON_TEMPORARY:
3244                 return FrameworkStatsLog
3245                     .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_TEMPORARY;
3246             case BrightnessReason.REASON_BOOST:
3247                 return FrameworkStatsLog
3248                     .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_BOOST;
3249             case BrightnessReason.REASON_SCREEN_OFF_BRIGHTNESS_SENSOR:
3250                 return FrameworkStatsLog
3251                     .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_SCREEN_OFF_BRIGHTNESS_SENSOR;
3252             case BrightnessReason.REASON_FOLLOWER:
3253                 return FrameworkStatsLog
3254                     .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_FOLLOWER;
3255         }
3256         return FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_UNKNOWN;
3257     }
3258 
3259     private void logBrightnessEvent(BrightnessEvent event, float unmodifiedBrightness) {
3260         int modifier = event.getReason().getModifier();
3261         int flags = event.getFlags();
3262         // It's easier to check if the brightness is at maximum level using the brightness
3263         // value untouched by any modifiers
3264         boolean brightnessIsMax = unmodifiedBrightness == event.getHbmMax();
3265         float brightnessInNits = convertToAdjustedNits(event.getBrightness());
3266         float appliedLowPowerMode = event.isLowPowerModeSet() ? event.getPowerFactor() : -1f;
3267         int appliedRbcStrength  = event.isRbcEnabled() ? event.getRbcStrength() : -1;
3268         float appliedHbmMaxNits =
3269                 event.getHbmMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF
3270                 ? -1f : convertToAdjustedNits(event.getHbmMax());
3271         // thermalCapNits set to -1 if not currently capping max brightness
3272         float appliedThermalCapNits =
3273                 event.getThermalMax() == PowerManager.BRIGHTNESS_MAX
3274                 ? -1f : convertToAdjustedNits(event.getThermalMax());
3275 
3276         if (mIsDisplayInternal) {
3277             FrameworkStatsLog.write(FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED,
3278                     convertToAdjustedNits(event.getInitialBrightness()),
3279                     brightnessInNits,
3280                     event.getLux(),
3281                     event.getPhysicalDisplayId(),
3282                     event.wasShortTermModelActive(),
3283                     appliedLowPowerMode,
3284                     appliedRbcStrength,
3285                     appliedHbmMaxNits,
3286                     appliedThermalCapNits,
3287                     event.isAutomaticBrightnessEnabled(),
3288                     FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__REASON__REASON_MANUAL,
3289                     convertBrightnessReasonToStatsEnum(event.getReason().getReason()),
3290                     nitsToRangeIndex(brightnessInNits),
3291                     brightnessIsMax,
3292                     event.getHbmMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT,
3293                     event.getHbmMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR,
3294                     (modifier & BrightnessReason.MODIFIER_LOW_POWER) > 0,
3295                     mBrightnessThrottler.getBrightnessMaxReason(),
3296                     (modifier & BrightnessReason.MODIFIER_DIMMED) > 0,
3297                     event.isRbcEnabled(),
3298                     (flags & BrightnessEvent.FLAG_INVALID_LUX) > 0,
3299                     (flags & BrightnessEvent.FLAG_DOZE_SCALE) > 0,
3300                     (flags & BrightnessEvent.FLAG_USER_SET) > 0,
3301                     (flags & BrightnessEvent.FLAG_IDLE_CURVE) > 0,
3302                     (flags & BrightnessEvent.FLAG_LOW_POWER_MODE) > 0);
3303         }
3304     }
3305 
3306     private final class DisplayControllerHandler extends Handler {
3307         DisplayControllerHandler(Looper looper) {
3308             super(looper, null, true /*async*/);
3309         }
3310 
3311         @Override
3312         public void handleMessage(Message msg) {
3313             switch (msg.what) {
3314                 case MSG_UPDATE_POWER_STATE:
3315                     updatePowerState();
3316                     break;
3317 
3318                 case MSG_PROXIMITY_SENSOR_DEBOUNCED:
3319                     debounceProximitySensor();
3320                     break;
3321 
3322                 case MSG_SCREEN_ON_UNBLOCKED:
3323                     if (mPendingScreenOnUnblocker == msg.obj) {
3324                         unblockScreenOn();
3325                         updatePowerState();
3326                     }
3327                     break;
3328                 case MSG_SCREEN_OFF_UNBLOCKED:
3329                     if (mPendingScreenOffUnblocker == msg.obj) {
3330                         unblockScreenOff();
3331                         updatePowerState();
3332                     }
3333                     break;
3334                 case MSG_CONFIGURE_BRIGHTNESS:
3335                     mBrightnessConfiguration = (BrightnessConfiguration) msg.obj;
3336                     mShouldResetShortTermModel = msg.arg1 == 1;
3337                     updatePowerState();
3338                     break;
3339 
3340                 case MSG_SET_TEMPORARY_BRIGHTNESS:
3341                     // TODO: Should we have a a timeout for the temporary brightness?
3342                     mTemporaryScreenBrightness = Float.intBitsToFloat(msg.arg1);
3343                     updatePowerState();
3344                     break;
3345 
3346                 case MSG_SET_TEMPORARY_AUTO_BRIGHTNESS_ADJUSTMENT:
3347                     mTemporaryAutoBrightnessAdjustment = Float.intBitsToFloat(msg.arg1);
3348                     updatePowerState();
3349                     break;
3350 
3351                 case MSG_IGNORE_PROXIMITY:
3352                     ignoreProximitySensorUntilChangedInternal();
3353                     break;
3354 
3355                 case MSG_STOP:
3356                     cleanupHandlerThreadAfterStop();
3357                     break;
3358 
3359                 case MSG_UPDATE_BRIGHTNESS:
3360                     if (mStopped) {
3361                         return;
3362                     }
3363                     handleSettingsChange(false /*userSwitch*/);
3364                     break;
3365 
3366                 case MSG_UPDATE_RBC:
3367                     handleRbcChanged();
3368                     break;
3369 
3370                 case MSG_BRIGHTNESS_RAMP_DONE:
3371                     if (mPowerState != null) {
3372                         final float brightness = mPowerState.getScreenBrightness();
3373                         reportStats(brightness);
3374                     }
3375                     break;
3376 
3377                 case MSG_STATSD_HBM_BRIGHTNESS:
3378                     logHbmBrightnessStats(Float.intBitsToFloat(msg.arg1), msg.arg2);
3379                     break;
3380 
3381                 case MSG_SWITCH_USER:
3382                     handleOnSwitchUser(msg.arg1);
3383                     break;
3384 
3385                 case MSG_BOOT_COMPLETED:
3386                     mBootCompleted = true;
3387                     updatePowerState();
3388                     break;
3389 
3390                 case MSG_SET_DWBC_STRONG_MODE:
3391                     setDwbcStrongMode(msg.arg1);
3392                     break;
3393 
3394                 case MSG_SET_DWBC_COLOR_OVERRIDE:
3395                     final float cct = Float.intBitsToFloat(msg.arg1);
3396                     setDwbcOverride(cct);
3397                     break;
3398 
3399                 case MSG_SET_DWBC_LOGGING_ENABLED:
3400                     setDwbcLoggingEnabled(msg.arg1);
3401                     break;
3402             }
3403         }
3404     }
3405 
3406     private final SensorEventListener mProximitySensorListener = new SensorEventListener() {
3407         @Override
3408         public void onSensorChanged(SensorEvent event) {
3409             if (mProximitySensorEnabled) {
3410                 final long time = mClock.uptimeMillis();
3411                 final float distance = event.values[0];
3412                 boolean positive = distance >= 0.0f && distance < mProximityThreshold;
3413                 handleProximitySensorEvent(time, positive);
3414             }
3415         }
3416 
3417         @Override
3418         public void onAccuracyChanged(Sensor sensor, int accuracy) {
3419             // Not used.
3420         }
3421     };
3422 
3423 
3424     private final class SettingsObserver extends ContentObserver {
3425         SettingsObserver(Handler handler) {
3426             super(handler);
3427         }
3428 
3429         @Override
3430         public void onChange(boolean selfChange, Uri uri) {
3431             if (uri.equals(Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE))) {
3432                 handleBrightnessModeChange();
3433             } else {
3434                 handleSettingsChange(false /* userSwitch */);
3435             }
3436         }
3437     }
3438 
3439     private final class ScreenOnUnblocker implements WindowManagerPolicy.ScreenOnListener {
3440         @Override
3441         public void onScreenOn() {
3442             Message msg = mHandler.obtainMessage(MSG_SCREEN_ON_UNBLOCKED, this);
3443             mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
3444         }
3445     }
3446 
3447     private final class ScreenOffUnblocker implements WindowManagerPolicy.ScreenOffListener {
3448         @Override
3449         public void onScreenOff() {
3450             Message msg = mHandler.obtainMessage(MSG_SCREEN_OFF_UNBLOCKED, this);
3451             mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
3452         }
3453     }
3454 
3455     @Override
3456     public void setAutoBrightnessLoggingEnabled(boolean enabled) {
3457         if (mAutomaticBrightnessController != null) {
3458             mAutomaticBrightnessController.setLoggingEnabled(enabled);
3459         }
3460     }
3461 
3462     @Override // DisplayWhiteBalanceController.Callbacks
3463     public void updateWhiteBalance() {
3464         sendUpdatePowerState();
3465     }
3466 
3467     @Override
3468     public void setDisplayWhiteBalanceLoggingEnabled(boolean enabled) {
3469         Message msg = mHandler.obtainMessage();
3470         msg.what = MSG_SET_DWBC_LOGGING_ENABLED;
3471         msg.arg1 = enabled ? 1 : 0;
3472         msg.sendToTarget();
3473     }
3474 
3475     @Override
3476     public void setAmbientColorTemperatureOverride(float cct) {
3477         Message msg = mHandler.obtainMessage();
3478         msg.what = MSG_SET_DWBC_COLOR_OVERRIDE;
3479         msg.arg1 = Float.floatToIntBits(cct);
3480         msg.sendToTarget();
3481     }
3482 
3483     @VisibleForTesting
3484     String getSuspendBlockerUnfinishedBusinessId(int displayId) {
3485         return "[" + displayId + "]unfinished business";
3486     }
3487 
3488     String getSuspendBlockerOnStateChangedId(int displayId) {
3489         return "[" + displayId + "]on state changed";
3490     }
3491 
3492     String getSuspendBlockerProxPositiveId(int displayId) {
3493         return "[" + displayId + "]prox positive";
3494     }
3495 
3496     String getSuspendBlockerProxNegativeId(int displayId) {
3497         return "[" + displayId + "]prox negative";
3498     }
3499 
3500     @VisibleForTesting
3501     String getSuspendBlockerProxDebounceId(int displayId) {
3502         return "[" + displayId + "]prox debounce";
3503     }
3504 
3505     /** Functional interface for providing time. */
3506     @VisibleForTesting
3507     interface Clock {
3508         /**
3509          * Returns current time in milliseconds since boot, not counting time spent in deep sleep.
3510          */
3511         long uptimeMillis();
3512     }
3513 
3514     @VisibleForTesting
3515     static class Injector {
3516         Clock getClock() {
3517             return SystemClock::uptimeMillis;
3518         }
3519 
3520         DisplayPowerState getDisplayPowerState(DisplayBlanker blanker, ColorFade colorFade,
3521                 int displayId, int displayState) {
3522             return new DisplayPowerState(blanker, colorFade, displayId, displayState);
3523         }
3524 
3525         DualRampAnimator<DisplayPowerState> getDualRampAnimator(DisplayPowerState dps,
3526                 FloatProperty<DisplayPowerState> firstProperty,
3527                 FloatProperty<DisplayPowerState> secondProperty) {
3528             return new DualRampAnimator(dps, firstProperty, secondProperty);
3529         }
3530 
3531         AutomaticBrightnessController getAutomaticBrightnessController(
3532                 AutomaticBrightnessController.Callbacks callbacks, Looper looper,
3533                 SensorManager sensorManager, Sensor lightSensor,
3534                 BrightnessMappingStrategy interactiveModeBrightnessMapper,
3535                 int lightSensorWarmUpTime, float brightnessMin, float brightnessMax,
3536                 float dozeScaleFactor, int lightSensorRate, int initialLightSensorRate,
3537                 long brighteningLightDebounceConfig, long darkeningLightDebounceConfig,
3538                 boolean resetAmbientLuxAfterWarmUpConfig,
3539                 HysteresisLevels ambientBrightnessThresholds,
3540                 HysteresisLevels screenBrightnessThresholds,
3541                 HysteresisLevels ambientBrightnessThresholdsIdle,
3542                 HysteresisLevels screenBrightnessThresholdsIdle, Context context,
3543                 BrightnessRangeController brightnessRangeController,
3544                 BrightnessThrottler brightnessThrottler,
3545                 BrightnessMappingStrategy idleModeBrightnessMapper, int ambientLightHorizonShort,
3546                 int ambientLightHorizonLong, float userLux, float userBrightness) {
3547             return new AutomaticBrightnessController(callbacks, looper, sensorManager, lightSensor,
3548                     interactiveModeBrightnessMapper, lightSensorWarmUpTime, brightnessMin,
3549                     brightnessMax, dozeScaleFactor, lightSensorRate, initialLightSensorRate,
3550                     brighteningLightDebounceConfig, darkeningLightDebounceConfig,
3551                     resetAmbientLuxAfterWarmUpConfig, ambientBrightnessThresholds,
3552                     screenBrightnessThresholds, ambientBrightnessThresholdsIdle,
3553                     screenBrightnessThresholdsIdle, context, brightnessRangeController,
3554                     brightnessThrottler, idleModeBrightnessMapper, ambientLightHorizonShort,
3555                     ambientLightHorizonLong, userLux, userBrightness);
3556         }
3557 
3558         BrightnessMappingStrategy getInteractiveModeBrightnessMapper(Resources resources,
3559                 DisplayDeviceConfig displayDeviceConfig,
3560                 DisplayWhiteBalanceController displayWhiteBalanceController) {
3561             return BrightnessMappingStrategy.create(resources,
3562                     displayDeviceConfig, displayWhiteBalanceController);
3563         }
3564 
3565         HysteresisLevels getHysteresisLevels(float[] brighteningThresholdsPercentages,
3566                 float[] darkeningThresholdsPercentages, float[] brighteningThresholdLevels,
3567                 float[] darkeningThresholdLevels, float minDarkeningThreshold,
3568                 float minBrighteningThreshold) {
3569             return new HysteresisLevels(brighteningThresholdsPercentages,
3570                     darkeningThresholdsPercentages, brighteningThresholdLevels,
3571                     darkeningThresholdLevels, minDarkeningThreshold, minBrighteningThreshold);
3572         }
3573 
3574         HysteresisLevels getHysteresisLevels(float[] brighteningThresholdsPercentages,
3575                 float[] darkeningThresholdsPercentages, float[] brighteningThresholdLevels,
3576                 float[] darkeningThresholdLevels, float minDarkeningThreshold,
3577                 float minBrighteningThreshold, boolean potentialOldBrightnessRange) {
3578             return new HysteresisLevels(brighteningThresholdsPercentages,
3579                     darkeningThresholdsPercentages, brighteningThresholdLevels,
3580                     darkeningThresholdLevels, minDarkeningThreshold, minBrighteningThreshold,
3581                     potentialOldBrightnessRange);
3582         }
3583 
3584         ScreenOffBrightnessSensorController getScreenOffBrightnessSensorController(
3585                 SensorManager sensorManager,
3586                 Sensor lightSensor,
3587                 Handler handler,
3588                 ScreenOffBrightnessSensorController.Clock clock,
3589                 int[] sensorValueToLux,
3590                 BrightnessMappingStrategy brightnessMapper) {
3591             return new ScreenOffBrightnessSensorController(
3592                     sensorManager,
3593                     lightSensor,
3594                     handler,
3595                     clock,
3596                     sensorValueToLux,
3597                     brightnessMapper
3598             );
3599         }
3600 
3601         HighBrightnessModeController getHighBrightnessModeController(Handler handler, int width,
3602                 int height, IBinder displayToken, String displayUniqueId, float brightnessMin,
3603                 float brightnessMax, DisplayDeviceConfig.HighBrightnessModeData hbmData,
3604                 HighBrightnessModeController.HdrBrightnessDeviceConfig hdrBrightnessCfg,
3605                 Runnable hbmChangeCallback, HighBrightnessModeMetadata hbmMetadata,
3606                 Context context) {
3607             return new HighBrightnessModeController(handler, width, height, displayToken,
3608                     displayUniqueId, brightnessMin, brightnessMax, hbmData, hdrBrightnessCfg,
3609                     hbmChangeCallback, hbmMetadata, context);
3610         }
3611 
3612         DisplayWhiteBalanceController getDisplayWhiteBalanceController(Handler handler,
3613                 SensorManager sensorManager, Resources resources) {
3614             return DisplayWhiteBalanceFactory.create(handler,
3615                     sensorManager, resources);
3616         }
3617     }
3618 
3619     static class CachedBrightnessInfo {
3620         public MutableFloat brightness = new MutableFloat(PowerManager.BRIGHTNESS_INVALID_FLOAT);
3621         public MutableFloat adjustedBrightness =
3622                 new MutableFloat(PowerManager.BRIGHTNESS_INVALID_FLOAT);
3623         public MutableFloat brightnessMin =
3624                 new MutableFloat(PowerManager.BRIGHTNESS_INVALID_FLOAT);
3625         public MutableFloat brightnessMax =
3626                 new MutableFloat(PowerManager.BRIGHTNESS_INVALID_FLOAT);
3627         public MutableInt hbmMode = new MutableInt(BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF);
3628         public MutableFloat hbmTransitionPoint =
3629                 new MutableFloat(HighBrightnessModeController.HBM_TRANSITION_POINT_INVALID);
3630         public MutableInt brightnessMaxReason =
3631                 new MutableInt(BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE);
3632 
3633         public boolean checkAndSetFloat(MutableFloat mf, float f) {
3634             if (mf.value != f) {
3635                 mf.value = f;
3636                 return true;
3637             }
3638             return false;
3639         }
3640 
3641         public boolean checkAndSetInt(MutableInt mi, int i) {
3642             if (mi.value != i) {
3643                 mi.value = i;
3644                 return true;
3645             }
3646             return false;
3647         }
3648     }
3649 }
3650