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