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