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