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