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