1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.display; 18 19 import android.animation.Animator; 20 import android.animation.ObjectAnimator; 21 import android.annotation.Nullable; 22 import android.annotation.UserIdInt; 23 import android.app.ActivityManager; 24 import android.content.Context; 25 import android.content.pm.ParceledListSlice; 26 import android.content.res.Resources; 27 import android.database.ContentObserver; 28 import android.hardware.Sensor; 29 import android.hardware.SensorEvent; 30 import android.hardware.SensorEventListener; 31 import android.hardware.SensorManager; 32 import android.hardware.display.AmbientBrightnessDayStats; 33 import android.hardware.display.BrightnessChangeEvent; 34 import android.hardware.display.BrightnessConfiguration; 35 import android.hardware.display.BrightnessInfo; 36 import android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks; 37 import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest; 38 import android.metrics.LogMaker; 39 import android.net.Uri; 40 import android.os.Handler; 41 import android.os.IBinder; 42 import android.os.Looper; 43 import android.os.Message; 44 import android.os.PowerManager; 45 import android.os.RemoteException; 46 import android.os.SystemClock; 47 import android.os.SystemProperties; 48 import android.os.Trace; 49 import android.os.UserHandle; 50 import android.provider.Settings; 51 import android.util.Log; 52 import android.util.MathUtils; 53 import android.util.Slog; 54 import android.util.TimeUtils; 55 import android.view.Display; 56 57 import com.android.internal.annotations.GuardedBy; 58 import com.android.internal.app.IBatteryStats; 59 import com.android.internal.display.BrightnessSynchronizer; 60 import com.android.internal.logging.MetricsLogger; 61 import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 62 import com.android.server.LocalServices; 63 import com.android.server.am.BatteryStatsService; 64 import com.android.server.display.RampAnimator.DualRampAnimator; 65 import com.android.server.display.color.ColorDisplayService.ColorDisplayServiceInternal; 66 import com.android.server.display.color.ColorDisplayService.ReduceBrightColorsListener; 67 import com.android.server.display.utils.SensorUtils; 68 import com.android.server.display.whitebalance.DisplayWhiteBalanceController; 69 import com.android.server.display.whitebalance.DisplayWhiteBalanceFactory; 70 import com.android.server.display.whitebalance.DisplayWhiteBalanceSettings; 71 import com.android.server.policy.WindowManagerPolicy; 72 73 import java.io.PrintWriter; 74 75 /** 76 * Controls the power state of the display. 77 * 78 * Handles the proximity sensor, light sensor, and animations between states 79 * including the screen off animation. 80 * 81 * This component acts independently of the rest of the power manager service. 82 * In particular, it does not share any state and it only communicates 83 * via asynchronous callbacks to inform the power manager that something has 84 * changed. 85 * 86 * Everything this class does internally is serialized on its handler although 87 * it may be accessed by other threads from the outside. 88 * 89 * Note that the power manager service guarantees that it will hold a suspend 90 * blocker as long as the display is not ready. So most of the work done here 91 * does not need to worry about holding a suspend blocker unless it happens 92 * independently of the display ready signal. 93 * 94 * For debugging, you can make the color fade and brightness animations run 95 * slower by changing the "animator duration scale" option in Development Settings. 96 */ 97 final class DisplayPowerController implements AutomaticBrightnessController.Callbacks, 98 DisplayWhiteBalanceController.Callbacks { 99 private static final String SCREEN_ON_BLOCKED_TRACE_NAME = "Screen on blocked"; 100 private static final String SCREEN_OFF_BLOCKED_TRACE_NAME = "Screen off blocked"; 101 102 private static final boolean DEBUG = false; 103 private static final boolean DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT = false; 104 105 // If true, uses the color fade on animation. 106 // We might want to turn this off if we cannot get a guarantee that the screen 107 // actually turns on and starts showing new content after the call to set the 108 // screen state returns. Playing the animation can also be somewhat slow. 109 private static final boolean USE_COLOR_FADE_ON_ANIMATION = false; 110 111 // The minimum reduction in brightness when dimmed. 112 private static final float SCREEN_DIM_MINIMUM_REDUCTION_FLOAT = 0.04f; 113 private static final float SCREEN_ANIMATION_RATE_MINIMUM = 0.0f; 114 115 private static final int COLOR_FADE_ON_ANIMATION_DURATION_MILLIS = 250; 116 private static final int COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS = 400; 117 118 private static final int MSG_UPDATE_POWER_STATE = 1; 119 private static final int MSG_PROXIMITY_SENSOR_DEBOUNCED = 2; 120 private static final int MSG_SCREEN_ON_UNBLOCKED = 3; 121 private static final int MSG_SCREEN_OFF_UNBLOCKED = 4; 122 private static final int MSG_CONFIGURE_BRIGHTNESS = 5; 123 private static final int MSG_SET_TEMPORARY_BRIGHTNESS = 6; 124 private static final int MSG_SET_TEMPORARY_AUTO_BRIGHTNESS_ADJUSTMENT = 7; 125 private static final int MSG_IGNORE_PROXIMITY = 8; 126 private static final int MSG_STOP = 9; 127 private static final int MSG_UPDATE_BRIGHTNESS = 10; 128 129 private static final int PROXIMITY_UNKNOWN = -1; 130 private static final int PROXIMITY_NEGATIVE = 0; 131 private static final int PROXIMITY_POSITIVE = 1; 132 133 // Proximity sensor debounce delay in milliseconds for positive or negative transitions. 134 private static final int PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY = 0; 135 private static final int PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY = 250; 136 137 // Trigger proximity if distance is less than 5 cm. 138 private static final float TYPICAL_PROXIMITY_THRESHOLD = 5.0f; 139 140 // State machine constants for tracking initial brightness ramp skipping when enabled. 141 private static final int RAMP_STATE_SKIP_NONE = 0; 142 private static final int RAMP_STATE_SKIP_INITIAL = 1; 143 private static final int RAMP_STATE_SKIP_AUTOBRIGHT = 2; 144 145 private static final int REPORTED_TO_POLICY_UNREPORTED = -1; 146 private static final int REPORTED_TO_POLICY_SCREEN_OFF = 0; 147 private static final int REPORTED_TO_POLICY_SCREEN_TURNING_ON = 1; 148 private static final int REPORTED_TO_POLICY_SCREEN_ON = 2; 149 private static final int REPORTED_TO_POLICY_SCREEN_TURNING_OFF = 3; 150 151 private final String TAG; 152 153 private final Object mLock = new Object(); 154 155 private final Context mContext; 156 157 // Our handler. 158 private final DisplayControllerHandler mHandler; 159 160 // Asynchronous callbacks into the power manager service. 161 // Only invoked from the handler thread while no locks are held. 162 private final DisplayPowerCallbacks mCallbacks; 163 164 // Battery stats. 165 @Nullable 166 private final IBatteryStats mBatteryStats; 167 168 // The sensor manager. 169 private final SensorManager mSensorManager; 170 171 // The window manager policy. 172 private final WindowManagerPolicy mWindowManagerPolicy; 173 174 // The display blanker. 175 private final DisplayBlanker mBlanker; 176 177 // The LogicalDisplay tied to this DisplayPowerController. 178 private final LogicalDisplay mLogicalDisplay; 179 180 // The ID of the LogicalDisplay tied to this DisplayPowerController. 181 private final int mDisplayId; 182 183 // The unique ID of the primary display device currently tied to this logical display 184 private String mUniqueDisplayId; 185 186 // Tracker for brightness changes. 187 @Nullable 188 private final BrightnessTracker mBrightnessTracker; 189 190 // Tracker for brightness settings changes. 191 private final SettingsObserver mSettingsObserver; 192 193 // The proximity sensor, or null if not available or needed. 194 private Sensor mProximitySensor; 195 196 // The doze screen brightness. 197 private final float mScreenBrightnessDozeConfig; 198 199 // The dim screen brightness. 200 private final float mScreenBrightnessDimConfig; 201 202 private final float mScreenBrightnessDefault; 203 204 // The minimum allowed brightness while in VR. 205 private final float mScreenBrightnessForVrRangeMinimum; 206 207 // The maximum allowed brightness while in VR. 208 private final float mScreenBrightnessForVrRangeMaximum; 209 210 // The default screen brightness for VR. 211 private final float mScreenBrightnessForVrDefault; 212 213 // True if auto-brightness should be used. 214 private boolean mUseSoftwareAutoBrightnessConfig; 215 216 // True if should use light sensor to automatically determine doze screen brightness. 217 private final boolean mAllowAutoBrightnessWhileDozingConfig; 218 219 // Whether or not the color fade on screen on / off is enabled. 220 private final boolean mColorFadeEnabled; 221 222 @GuardedBy("mCachedBrightnessInfo") 223 private final CachedBrightnessInfo mCachedBrightnessInfo = new CachedBrightnessInfo(); 224 225 private DisplayDevice mDisplayDevice; 226 227 // True if we should fade the screen while turning it off, false if we should play 228 // a stylish color fade animation instead. 229 private boolean mColorFadeFadesConfig; 230 231 // True if we need to fake a transition to off when coming out of a doze state. 232 // Some display hardware will blank itself when coming out of doze in order to hide 233 // artifacts. For these displays we fake a transition into OFF so that policy can appropriately 234 // blank itself and begin an appropriate power on animation. 235 private boolean mDisplayBlanksAfterDozeConfig; 236 237 // True if there are only buckets of brightness values when the display is in the doze state, 238 // rather than a full range of values. If this is true, then we'll avoid animating the screen 239 // brightness since it'd likely be multiple jarring brightness transitions instead of just one 240 // to reach the final state. 241 private boolean mBrightnessBucketsInDozeConfig; 242 243 // The pending power request. 244 // Initially null until the first call to requestPowerState. 245 // Guarded by mLock. 246 private DisplayPowerRequest mPendingRequestLocked; 247 248 // True if a request has been made to wait for the proximity sensor to go negative. 249 // Guarded by mLock. 250 private boolean mPendingWaitForNegativeProximityLocked; 251 252 // True if the pending power request or wait for negative proximity flag 253 // has been changed since the last update occurred. 254 // Guarded by mLock. 255 private boolean mPendingRequestChangedLocked; 256 257 // Set to true when the important parts of the pending power request have been applied. 258 // The important parts are mainly the screen state. Brightness changes may occur 259 // concurrently. 260 // Guarded by mLock. 261 private boolean mDisplayReadyLocked; 262 263 // Set to true if a power state update is required. 264 // Guarded by mLock. 265 private boolean mPendingUpdatePowerStateLocked; 266 267 /* The following state must only be accessed by the handler thread. */ 268 269 // The currently requested power state. 270 // The power controller will progressively update its internal state to match 271 // the requested power state. Initially null until the first update. 272 private DisplayPowerRequest mPowerRequest; 273 274 // The current power state. 275 // Must only be accessed on the handler thread. 276 private DisplayPowerState mPowerState; 277 278 // True if the device should wait for negative proximity sensor before 279 // waking up the screen. This is set to false as soon as a negative 280 // proximity sensor measurement is observed or when the device is forced to 281 // go to sleep by the user. While true, the screen remains off. 282 private boolean mWaitingForNegativeProximity; 283 284 // True if the device should not take into account the proximity sensor 285 // until either the proximity sensor state changes, or there is no longer a 286 // request to listen to proximity sensor. 287 private boolean mIgnoreProximityUntilChanged; 288 289 // The actual proximity sensor threshold value. 290 private float mProximityThreshold; 291 292 // Set to true if the proximity sensor listener has been registered 293 // with the sensor manager. 294 private boolean mProximitySensorEnabled; 295 296 // The debounced proximity sensor state. 297 private int mProximity = PROXIMITY_UNKNOWN; 298 299 // The raw non-debounced proximity sensor state. 300 private int mPendingProximity = PROXIMITY_UNKNOWN; 301 private long mPendingProximityDebounceTime = -1; // -1 if fully debounced 302 303 // True if the screen was turned off because of the proximity sensor. 304 // When the screen turns on again, we report user activity to the power manager. 305 private boolean mScreenOffBecauseOfProximity; 306 307 // The currently active screen on unblocker. This field is non-null whenever 308 // we are waiting for a callback to release it and unblock the screen. 309 private ScreenOnUnblocker mPendingScreenOnUnblocker; 310 private ScreenOffUnblocker mPendingScreenOffUnblocker; 311 312 // True if we were in the process of turning off the screen. 313 // This allows us to recover more gracefully from situations where we abort 314 // turning off the screen. 315 private boolean mPendingScreenOff; 316 317 // True if we have unfinished business and are holding a suspend blocker. 318 private boolean mUnfinishedBusiness; 319 320 // The elapsed real time when the screen on was blocked. 321 private long mScreenOnBlockStartRealTime; 322 private long mScreenOffBlockStartRealTime; 323 324 // Screen state we reported to policy. Must be one of REPORTED_TO_POLICY_* fields. 325 private int mReportedScreenStateToPolicy = REPORTED_TO_POLICY_UNREPORTED; 326 327 // If the last recorded screen state was dozing or not. 328 private boolean mDozing; 329 330 // Remembers whether certain kinds of brightness adjustments 331 // were recently applied so that we can decide how to transition. 332 private boolean mAppliedAutoBrightness; 333 private boolean mAppliedDimming; 334 private boolean mAppliedLowPower; 335 private boolean mAppliedScreenBrightnessOverride; 336 private boolean mAppliedTemporaryBrightness; 337 private boolean mAppliedTemporaryAutoBrightnessAdjustment; 338 private boolean mAppliedBrightnessBoost; 339 340 // Reason for which the brightness was last changed. See {@link BrightnessReason} for more 341 // information. 342 // At the time of this writing, this value is changed within updatePowerState() only, which is 343 // limited to the thread used by DisplayControllerHandler. 344 private BrightnessReason mBrightnessReason = new BrightnessReason(); 345 private BrightnessReason mBrightnessReasonTemp = new BrightnessReason(); 346 347 // Brightness animation ramp rates in brightness units per second 348 private float mBrightnessRampRateFastDecrease; 349 private float mBrightnessRampRateFastIncrease; 350 private float mBrightnessRampRateSlowDecrease; 351 private float mBrightnessRampRateSlowIncrease; 352 353 354 // Whether or not to skip the initial brightness ramps into STATE_ON. 355 private final boolean mSkipScreenOnBrightnessRamp; 356 357 // Display white balance components. 358 @Nullable 359 private final DisplayWhiteBalanceSettings mDisplayWhiteBalanceSettings; 360 @Nullable 361 private final DisplayWhiteBalanceController mDisplayWhiteBalanceController; 362 363 @Nullable 364 private final ColorDisplayServiceInternal mCdsi; 365 private float[] mNitsRange; 366 367 private final HighBrightnessModeController mHbmController; 368 369 private final BrightnessSetting mBrightnessSetting; 370 371 private final Runnable mOnBrightnessChangeRunnable; 372 373 // A record of state for skipping brightness ramps. 374 private int mSkipRampState = RAMP_STATE_SKIP_NONE; 375 376 // The first autobrightness value set when entering RAMP_STATE_SKIP_INITIAL. 377 private float mInitialAutoBrightness; 378 379 // The controller for the automatic brightness level. 380 private AutomaticBrightnessController mAutomaticBrightnessController; 381 382 private Sensor mLightSensor; 383 384 // The mapper between ambient lux, display backlight values, and display brightness. 385 @Nullable 386 private BrightnessMappingStrategy mBrightnessMapper; 387 388 // The current brightness configuration. 389 @Nullable 390 private BrightnessConfiguration mBrightnessConfiguration; 391 392 // The last brightness that was set by the user and not temporary. Set to 393 // PowerManager.BRIGHTNESS_INVALID_FLOAT when a brightness has yet to be recorded. 394 private float mLastUserSetScreenBrightness = Float.NaN; 395 396 // The screen brightness setting has changed but not taken effect yet. If this is different 397 // from the current screen brightness setting then this is coming from something other than us 398 // and should be considered a user interaction. 399 private float mPendingScreenBrightnessSetting; 400 401 // The last observed screen brightness setting, either set by us or by the settings app on 402 // behalf of the user. 403 private float mCurrentScreenBrightnessSetting; 404 405 // The temporary screen brightness. Typically set when a user is interacting with the 406 // brightness slider but hasn't settled on a choice yet. Set to 407 // PowerManager.BRIGHNTESS_INVALID_FLOAT when there's no temporary brightness set. 408 private float mTemporaryScreenBrightness; 409 410 // The current screen brightness while in VR mode. 411 private float mScreenBrightnessForVr; 412 413 // The last auto brightness adjustment that was set by the user and not temporary. Set to 414 // Float.NaN when an auto-brightness adjustment hasn't been recorded yet. 415 private float mAutoBrightnessAdjustment; 416 417 // The pending auto brightness adjustment that will take effect on the next power state update. 418 private float mPendingAutoBrightnessAdjustment; 419 420 // The temporary auto brightness adjustment. Typically set when a user is interacting with the 421 // adjustment slider but hasn't settled on a choice yet. Set to 422 // PowerManager.BRIGHTNESS_INVALID_FLOAT when there's no temporary adjustment set. 423 private float mTemporaryAutoBrightnessAdjustment; 424 425 // Whether a reduce bright colors (rbc) change has been initiated by the user. We want to 426 // retain the current backlight level when rbc is toggled, since rbc additionally makes the 427 // screen appear dimmer using screen colors rather than backlight levels, and therefore we 428 // don't actually want to compensate for this by then in/decreasing the backlight when 429 // toggling this feature. 430 // This should be false during system start up. 431 private boolean mPendingUserRbcChange; 432 433 // Animators. 434 private ObjectAnimator mColorFadeOnAnimator; 435 private ObjectAnimator mColorFadeOffAnimator; 436 private DualRampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator; 437 private BrightnessSetting.BrightnessSettingListener mBrightnessSettingListener; 438 439 // True if this DisplayPowerController has been stopped and should no longer be running. 440 private boolean mStopped; 441 442 private DisplayDeviceConfig mDisplayDeviceConfig; 443 444 /** 445 * Creates the display power controller. 446 */ DisplayPowerController(Context context, DisplayPowerCallbacks callbacks, Handler handler, SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay, BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting, Runnable onBrightnessChangeRunnable)447 public DisplayPowerController(Context context, 448 DisplayPowerCallbacks callbacks, Handler handler, 449 SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay, 450 BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting, 451 Runnable onBrightnessChangeRunnable) { 452 mLogicalDisplay = logicalDisplay; 453 mDisplayId = mLogicalDisplay.getDisplayIdLocked(); 454 TAG = "DisplayPowerController[" + mDisplayId + "]"; 455 mDisplayDevice = mLogicalDisplay.getPrimaryDisplayDeviceLocked(); 456 mUniqueDisplayId = logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId(); 457 mHandler = new DisplayControllerHandler(handler.getLooper()); 458 459 if (mDisplayId == Display.DEFAULT_DISPLAY) { 460 mBatteryStats = BatteryStatsService.getService(); 461 } else { 462 mBatteryStats = null; 463 } 464 465 mSettingsObserver = new SettingsObserver(mHandler); 466 mCallbacks = callbacks; 467 mSensorManager = sensorManager; 468 mWindowManagerPolicy = LocalServices.getService(WindowManagerPolicy.class); 469 mBlanker = blanker; 470 mContext = context; 471 mBrightnessTracker = brightnessTracker; 472 // TODO: b/186428377 update brightness setting when display changes 473 mBrightnessSetting = brightnessSetting; 474 mOnBrightnessChangeRunnable = onBrightnessChangeRunnable; 475 476 PowerManager pm = context.getSystemService(PowerManager.class); 477 478 final Resources resources = context.getResources(); 479 480 481 // DOZE AND DIM SETTINGS 482 mScreenBrightnessDozeConfig = clampAbsoluteBrightness( 483 pm.getBrightnessConstraint(PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DOZE)); 484 mScreenBrightnessDimConfig = clampAbsoluteBrightness( 485 pm.getBrightnessConstraint(PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DIM)); 486 487 // NORMAL SCREEN SETTINGS 488 mScreenBrightnessDefault = clampAbsoluteBrightness( 489 mLogicalDisplay.getDisplayInfoLocked().brightnessDefault); 490 491 // VR SETTINGS 492 mScreenBrightnessForVrDefault = clampAbsoluteBrightness( 493 pm.getBrightnessConstraint(PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT_VR)); 494 mScreenBrightnessForVrRangeMaximum = clampAbsoluteBrightness( 495 pm.getBrightnessConstraint(PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM_VR)); 496 mScreenBrightnessForVrRangeMinimum = clampAbsoluteBrightness( 497 pm.getBrightnessConstraint(PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM_VR)); 498 499 // Check the setting, but also verify that it is the default display. Only the default 500 // display has an automatic brightness controller running. 501 // TODO: b/179021925 - Fix to work with multiple displays 502 mUseSoftwareAutoBrightnessConfig = resources.getBoolean( 503 com.android.internal.R.bool.config_automatic_brightness_available) 504 && mDisplayId == Display.DEFAULT_DISPLAY; 505 506 mAllowAutoBrightnessWhileDozingConfig = resources.getBoolean( 507 com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing); 508 509 mDisplayDeviceConfig = logicalDisplay.getPrimaryDisplayDeviceLocked() 510 .getDisplayDeviceConfig(); 511 512 loadBrightnessRampRates(); 513 mSkipScreenOnBrightnessRamp = resources.getBoolean( 514 com.android.internal.R.bool.config_skipScreenOnBrightnessRamp); 515 516 mHbmController = createHbmControllerLocked(); 517 518 // Seed the cached brightness 519 saveBrightnessInfo(getScreenBrightnessSetting()); 520 521 setUpAutoBrightness(resources, handler); 522 523 mColorFadeEnabled = !ActivityManager.isLowRamDeviceStatic(); 524 mColorFadeFadesConfig = resources.getBoolean( 525 com.android.internal.R.bool.config_animateScreenLights); 526 527 mDisplayBlanksAfterDozeConfig = resources.getBoolean( 528 com.android.internal.R.bool.config_displayBlanksAfterDoze); 529 530 mBrightnessBucketsInDozeConfig = resources.getBoolean( 531 com.android.internal.R.bool.config_displayBrightnessBucketsInDoze); 532 533 loadProximitySensor(); 534 535 mCurrentScreenBrightnessSetting = getScreenBrightnessSetting(); 536 mScreenBrightnessForVr = getScreenBrightnessForVrSetting(); 537 mAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting(); 538 mTemporaryScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; 539 mPendingScreenBrightnessSetting = PowerManager.BRIGHTNESS_INVALID_FLOAT; 540 mTemporaryAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT; 541 mPendingAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT; 542 543 DisplayWhiteBalanceSettings displayWhiteBalanceSettings = null; 544 DisplayWhiteBalanceController displayWhiteBalanceController = null; 545 if (mDisplayId == Display.DEFAULT_DISPLAY) { 546 try { 547 displayWhiteBalanceSettings = new DisplayWhiteBalanceSettings(mContext, mHandler); 548 displayWhiteBalanceController = DisplayWhiteBalanceFactory.create(mHandler, 549 mSensorManager, resources); 550 displayWhiteBalanceSettings.setCallbacks(this); 551 displayWhiteBalanceController.setCallbacks(this); 552 } catch (Exception e) { 553 Slog.e(TAG, "failed to set up display white-balance: " + e); 554 } 555 } 556 mDisplayWhiteBalanceSettings = displayWhiteBalanceSettings; 557 mDisplayWhiteBalanceController = displayWhiteBalanceController; 558 559 loadNitsRange(resources); 560 561 if (mDisplayId == Display.DEFAULT_DISPLAY) { 562 mCdsi = LocalServices.getService(ColorDisplayServiceInternal.class); 563 boolean active = mCdsi.setReduceBrightColorsListener(new ReduceBrightColorsListener() { 564 @Override 565 public void onReduceBrightColorsActivationChanged(boolean activated, 566 boolean userInitiated) { 567 applyReduceBrightColorsSplineAdjustment(userInitiated); 568 } 569 570 @Override 571 public void onReduceBrightColorsStrengthChanged(int strength) { 572 applyReduceBrightColorsSplineAdjustment(/*userInitiated*/ false); 573 } 574 }); 575 if (active) { 576 applyReduceBrightColorsSplineAdjustment(/*userInitiated*/ false); 577 } 578 } else { 579 mCdsi = null; 580 } 581 } 582 applyReduceBrightColorsSplineAdjustment(boolean userInitiated)583 private void applyReduceBrightColorsSplineAdjustment(boolean userInitiated) { 584 if (mBrightnessMapper == null) { 585 Log.w(TAG, "No brightness mapping available to recalculate splines"); 586 return; 587 } 588 589 float[] adjustedNits = new float[mNitsRange.length]; 590 for (int i = 0; i < mNitsRange.length; i++) { 591 adjustedNits[i] = mCdsi.getReduceBrightColorsAdjustedBrightnessNits(mNitsRange[i]); 592 } 593 mBrightnessMapper.recalculateSplines(mCdsi.isReduceBrightColorsActivated(), adjustedNits); 594 mPendingUserRbcChange = userInitiated; 595 sendUpdatePowerState(); 596 } 597 598 /** 599 * Returns true if the proximity sensor screen-off function is available. 600 */ isProximitySensorAvailable()601 public boolean isProximitySensorAvailable() { 602 return mProximitySensor != null; 603 } 604 605 /** 606 * Get the {@link BrightnessChangeEvent}s for the specified user. 607 * @param userId userId to fetch data for 608 * @param includePackage if false will null out the package name in events 609 */ 610 @Nullable getBrightnessEvents( @serIdInt int userId, boolean includePackage)611 public ParceledListSlice<BrightnessChangeEvent> getBrightnessEvents( 612 @UserIdInt int userId, boolean includePackage) { 613 if (mBrightnessTracker == null) { 614 return null; 615 } 616 return mBrightnessTracker.getEvents(userId, includePackage); 617 } 618 onSwitchUser(@serIdInt int newUserId)619 public void onSwitchUser(@UserIdInt int newUserId) { 620 handleSettingsChange(true /* userSwitch */); 621 if (mBrightnessTracker != null) { 622 mBrightnessTracker.onSwitchUser(newUserId); 623 } 624 } 625 626 @Nullable getAmbientBrightnessStats( @serIdInt int userId)627 public ParceledListSlice<AmbientBrightnessDayStats> getAmbientBrightnessStats( 628 @UserIdInt int userId) { 629 if (mBrightnessTracker == null) { 630 return null; 631 } 632 return mBrightnessTracker.getAmbientBrightnessStats(userId); 633 } 634 635 /** 636 * Persist the brightness slider events and ambient brightness stats to disk. 637 */ persistBrightnessTrackerState()638 public void persistBrightnessTrackerState() { 639 if (mBrightnessTracker != null) { 640 mBrightnessTracker.persistBrightnessTrackerState(); 641 } 642 } 643 644 /** 645 * Requests a new power state. 646 * The controller makes a copy of the provided object and then 647 * begins adjusting the power state to match what was requested. 648 * 649 * @param request The requested power state. 650 * @param waitForNegativeProximity If true, issues a request to wait for 651 * negative proximity before turning the screen back on, assuming the screen 652 * was turned off by the proximity sensor. 653 * @return True if display is ready, false if there are important changes that must 654 * be made asynchronously (such as turning the screen on), in which case the caller 655 * should grab a wake lock, watch for {@link DisplayPowerCallbacks#onStateChanged()} 656 * then try the request again later until the state converges. 657 */ requestPowerState(DisplayPowerRequest request, boolean waitForNegativeProximity)658 public boolean requestPowerState(DisplayPowerRequest request, 659 boolean waitForNegativeProximity) { 660 if (DEBUG) { 661 Slog.d(TAG, "requestPowerState: " 662 + request + ", waitForNegativeProximity=" + waitForNegativeProximity); 663 } 664 665 synchronized (mLock) { 666 if (mStopped) { 667 return true; 668 } 669 670 boolean changed = false; 671 672 if (waitForNegativeProximity 673 && !mPendingWaitForNegativeProximityLocked) { 674 mPendingWaitForNegativeProximityLocked = true; 675 changed = true; 676 } 677 678 if (mPendingRequestLocked == null) { 679 mPendingRequestLocked = new DisplayPowerRequest(request); 680 changed = true; 681 } else if (!mPendingRequestLocked.equals(request)) { 682 mPendingRequestLocked.copyFrom(request); 683 changed = true; 684 } 685 686 if (changed) { 687 mDisplayReadyLocked = false; 688 if (!mPendingRequestChangedLocked) { 689 mPendingRequestChangedLocked = true; 690 sendUpdatePowerStateLocked(); 691 } 692 } 693 694 return mDisplayReadyLocked; 695 } 696 } 697 getDefaultBrightnessConfiguration()698 public BrightnessConfiguration getDefaultBrightnessConfiguration() { 699 if (mAutomaticBrightnessController == null) { 700 return null; 701 } 702 return mAutomaticBrightnessController.getDefaultConfig(); 703 } 704 705 /** 706 * Notified when the display is changed. We use this to apply any changes that might be needed 707 * when displays get swapped on foldable devices. For example, different brightness properties 708 * of each display need to be properly reflected in AutomaticBrightnessController. 709 */ 710 @GuardedBy("DisplayManagerService.mSyncRoot") onDisplayChanged()711 public void onDisplayChanged() { 712 final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked(); 713 if (device == null) { 714 Slog.wtf(TAG, "Display Device is null in DisplayPowerController for display: " 715 + mLogicalDisplay.getDisplayIdLocked()); 716 return; 717 } 718 719 final String uniqueId = device.getUniqueId(); 720 final DisplayDeviceConfig config = device.getDisplayDeviceConfig(); 721 final IBinder token = device.getDisplayTokenLocked(); 722 final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); 723 mHandler.post(() -> { 724 if (mDisplayDevice == device) { 725 return; 726 } 727 mDisplayDevice = device; 728 mUniqueDisplayId = uniqueId; 729 mDisplayDeviceConfig = config; 730 loadFromDisplayDeviceConfig(token, info); 731 }); 732 } 733 734 /** 735 * Called when the displays are preparing to transition from one device state to another. 736 * This process involves turning off some displays so we need updatePowerState() to run and 737 * calculate the new state. 738 */ onDeviceStateTransition()739 public void onDeviceStateTransition() { 740 sendUpdatePowerState(); 741 } 742 743 /** 744 * Unregisters all listeners and interrupts all running threads; halting future work. 745 * 746 * This method should be called when the DisplayPowerController is no longer in use; i.e. when 747 * the {@link #mDisplayId display} has been removed. 748 */ stop()749 public void stop() { 750 synchronized (mLock) { 751 mStopped = true; 752 Message msg = mHandler.obtainMessage(MSG_STOP); 753 mHandler.sendMessage(msg); 754 755 if (mDisplayWhiteBalanceController != null) { 756 mDisplayWhiteBalanceController.setEnabled(false); 757 } 758 759 if (mAutomaticBrightnessController != null) { 760 mAutomaticBrightnessController.stop(); 761 } 762 763 if (mBrightnessSetting != null) { 764 mBrightnessSetting.unregisterListener(mBrightnessSettingListener); 765 } 766 767 mContext.getContentResolver().unregisterContentObserver(mSettingsObserver); 768 } 769 } 770 loadFromDisplayDeviceConfig(IBinder token, DisplayDeviceInfo info)771 private void loadFromDisplayDeviceConfig(IBinder token, DisplayDeviceInfo info) { 772 // All properties that depend on the associated DisplayDevice and the DDC must be 773 // updated here. 774 loadAmbientLightSensor(); 775 loadBrightnessRampRates(); 776 loadProximitySensor(); 777 loadNitsRange(mContext.getResources()); 778 setUpAutoBrightness(mContext.getResources(), mHandler); 779 reloadReduceBrightColours(); 780 mHbmController.resetHbmData(info.width, info.height, token, 781 mDisplayDeviceConfig.getHighBrightnessModeData()); 782 } 783 sendUpdatePowerState()784 private void sendUpdatePowerState() { 785 synchronized (mLock) { 786 sendUpdatePowerStateLocked(); 787 } 788 } 789 sendUpdatePowerStateLocked()790 private void sendUpdatePowerStateLocked() { 791 if (!mStopped && !mPendingUpdatePowerStateLocked) { 792 mPendingUpdatePowerStateLocked = true; 793 Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE); 794 mHandler.sendMessage(msg); 795 } 796 } 797 initialize(int displayState)798 private void initialize(int displayState) { 799 mPowerState = new DisplayPowerState(mBlanker, 800 mColorFadeEnabled ? new ColorFade(mDisplayId) : null, mDisplayId, displayState); 801 802 if (mColorFadeEnabled) { 803 mColorFadeOnAnimator = ObjectAnimator.ofFloat( 804 mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 0.0f, 1.0f); 805 mColorFadeOnAnimator.setDuration(COLOR_FADE_ON_ANIMATION_DURATION_MILLIS); 806 mColorFadeOnAnimator.addListener(mAnimatorListener); 807 808 mColorFadeOffAnimator = ObjectAnimator.ofFloat( 809 mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 1.0f, 0.0f); 810 mColorFadeOffAnimator.setDuration(COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS); 811 mColorFadeOffAnimator.addListener(mAnimatorListener); 812 } 813 814 mScreenBrightnessRampAnimator = new DualRampAnimator<>(mPowerState, 815 DisplayPowerState.SCREEN_BRIGHTNESS_FLOAT, 816 DisplayPowerState.SCREEN_SDR_BRIGHTNESS_FLOAT); 817 mScreenBrightnessRampAnimator.setListener(mRampAnimatorListener); 818 819 noteScreenState(mPowerState.getScreenState()); 820 noteScreenBrightness(mPowerState.getScreenBrightness()); 821 822 // Initialize all of the brightness tracking state 823 final float brightness = convertToNits(mPowerState.getScreenBrightness()); 824 if (brightness >= PowerManager.BRIGHTNESS_MIN) { 825 mBrightnessTracker.start(brightness); 826 } 827 mBrightnessSettingListener = brightnessValue -> { 828 Message msg = mHandler.obtainMessage(MSG_UPDATE_BRIGHTNESS, brightnessValue); 829 mHandler.sendMessage(msg); 830 }; 831 832 mBrightnessSetting.registerListener(mBrightnessSettingListener); 833 mContext.getContentResolver().registerContentObserver( 834 Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_FOR_VR_FLOAT), 835 false /*notifyForDescendants*/, mSettingsObserver, UserHandle.USER_ALL); 836 mContext.getContentResolver().registerContentObserver( 837 Settings.System.getUriFor(Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ), 838 false /*notifyForDescendants*/, mSettingsObserver, UserHandle.USER_ALL); 839 } 840 setUpAutoBrightness(Resources resources, Handler handler)841 private void setUpAutoBrightness(Resources resources, Handler handler) { 842 if (!mUseSoftwareAutoBrightnessConfig) { 843 return; 844 } 845 846 mBrightnessMapper = BrightnessMappingStrategy.create(resources, mDisplayDeviceConfig); 847 848 if (mBrightnessMapper != null) { 849 final float dozeScaleFactor = resources.getFraction( 850 com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor, 851 1, 1); 852 853 int[] ambientBrighteningThresholds = resources.getIntArray( 854 com.android.internal.R.array.config_ambientBrighteningThresholds); 855 int[] ambientDarkeningThresholds = resources.getIntArray( 856 com.android.internal.R.array.config_ambientDarkeningThresholds); 857 int[] ambientThresholdLevels = resources.getIntArray( 858 com.android.internal.R.array.config_ambientThresholdLevels); 859 HysteresisLevels ambientBrightnessThresholds = new HysteresisLevels( 860 ambientBrighteningThresholds, ambientDarkeningThresholds, 861 ambientThresholdLevels); 862 863 int[] screenBrighteningThresholds = resources.getIntArray( 864 com.android.internal.R.array.config_screenBrighteningThresholds); 865 int[] screenDarkeningThresholds = resources.getIntArray( 866 com.android.internal.R.array.config_screenDarkeningThresholds); 867 int[] screenThresholdLevels = resources.getIntArray( 868 com.android.internal.R.array.config_screenThresholdLevels); 869 HysteresisLevels screenBrightnessThresholds = new HysteresisLevels( 870 screenBrighteningThresholds, screenDarkeningThresholds, screenThresholdLevels); 871 872 long brighteningLightDebounce = resources.getInteger( 873 com.android.internal.R.integer.config_autoBrightnessBrighteningLightDebounce); 874 long darkeningLightDebounce = resources.getInteger( 875 com.android.internal.R.integer.config_autoBrightnessDarkeningLightDebounce); 876 boolean autoBrightnessResetAmbientLuxAfterWarmUp = resources.getBoolean( 877 com.android.internal.R.bool.config_autoBrightnessResetAmbientLuxAfterWarmUp); 878 879 int lightSensorWarmUpTimeConfig = resources.getInteger( 880 com.android.internal.R.integer.config_lightSensorWarmupTime); 881 int lightSensorRate = resources.getInteger( 882 com.android.internal.R.integer.config_autoBrightnessLightSensorRate); 883 int initialLightSensorRate = resources.getInteger( 884 com.android.internal.R.integer.config_autoBrightnessInitialLightSensorRate); 885 if (initialLightSensorRate == -1) { 886 initialLightSensorRate = lightSensorRate; 887 } else if (initialLightSensorRate > lightSensorRate) { 888 Slog.w(TAG, "Expected config_autoBrightnessInitialLightSensorRate (" 889 + initialLightSensorRate + ") to be less than or equal to " 890 + "config_autoBrightnessLightSensorRate (" + lightSensorRate + ")."); 891 } 892 893 loadAmbientLightSensor(); 894 895 if (mAutomaticBrightnessController != null) { 896 mAutomaticBrightnessController.stop(); 897 } 898 mAutomaticBrightnessController = new AutomaticBrightnessController(this, 899 handler.getLooper(), mSensorManager, mLightSensor, mBrightnessMapper, 900 lightSensorWarmUpTimeConfig, PowerManager.BRIGHTNESS_MIN, 901 PowerManager.BRIGHTNESS_MAX, dozeScaleFactor, lightSensorRate, 902 initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce, 903 autoBrightnessResetAmbientLuxAfterWarmUp, ambientBrightnessThresholds, 904 screenBrightnessThresholds, mLogicalDisplay, mContext, mHbmController); 905 } else { 906 mUseSoftwareAutoBrightnessConfig = false; 907 } 908 } 909 loadBrightnessRampRates()910 private void loadBrightnessRampRates() { 911 mBrightnessRampRateFastDecrease = mDisplayDeviceConfig.getBrightnessRampFastDecrease(); 912 mBrightnessRampRateFastIncrease = mDisplayDeviceConfig.getBrightnessRampFastIncrease(); 913 mBrightnessRampRateSlowDecrease = mDisplayDeviceConfig.getBrightnessRampSlowDecrease(); 914 mBrightnessRampRateSlowIncrease = mDisplayDeviceConfig.getBrightnessRampSlowIncrease(); 915 } 916 loadNitsRange(Resources resources)917 private void loadNitsRange(Resources resources) { 918 if (mDisplayDeviceConfig != null && mDisplayDeviceConfig.getNits() != null) { 919 mNitsRange = mDisplayDeviceConfig.getNits(); 920 } else { 921 Slog.w(TAG, "Screen brightness nits configuration is unavailable; falling back"); 922 mNitsRange = BrightnessMappingStrategy.getFloatArray(resources 923 .obtainTypedArray(com.android.internal.R.array.config_screenBrightnessNits)); 924 } 925 } 926 reloadReduceBrightColours()927 private void reloadReduceBrightColours() { 928 if (mCdsi != null && mCdsi.isReduceBrightColorsActivated()) { 929 applyReduceBrightColorsSplineAdjustment(/*userInitiated*/ false); 930 } 931 } 932 933 private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() { 934 @Override 935 public void onAnimationStart(Animator animation) { 936 } 937 @Override 938 public void onAnimationEnd(Animator animation) { 939 sendUpdatePowerState(); 940 } 941 @Override 942 public void onAnimationRepeat(Animator animation) { 943 } 944 @Override 945 public void onAnimationCancel(Animator animation) { 946 } 947 }; 948 949 private final RampAnimator.Listener mRampAnimatorListener = this::sendUpdatePowerState; 950 951 /** Clean up all resources that are accessed via the {@link #mHandler} thread. */ cleanupHandlerThreadAfterStop()952 private void cleanupHandlerThreadAfterStop() { 953 setProximitySensorEnabled(false); 954 mHbmController.stop(); 955 mHandler.removeCallbacksAndMessages(null); 956 if (mUnfinishedBusiness) { 957 mCallbacks.releaseSuspendBlocker(); 958 mUnfinishedBusiness = false; 959 } 960 if (mPowerState != null) { 961 mPowerState.stop(); 962 mPowerState = null; 963 } 964 } 965 updatePowerState()966 private void updatePowerState() { 967 // Update the power state request. 968 final boolean mustNotify; 969 final int previousPolicy; 970 boolean mustInitialize = false; 971 int brightnessAdjustmentFlags = 0; 972 mBrightnessReasonTemp.set(null); 973 synchronized (mLock) { 974 if (mStopped) { 975 return; 976 } 977 mPendingUpdatePowerStateLocked = false; 978 if (mPendingRequestLocked == null) { 979 return; // wait until first actual power request 980 } 981 982 if (mPowerRequest == null) { 983 mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked); 984 updatePendingProximityRequestsLocked(); 985 mPendingRequestChangedLocked = false; 986 mustInitialize = true; 987 // Assume we're on and bright until told otherwise, since that's the state we turn 988 // on in. 989 previousPolicy = DisplayPowerRequest.POLICY_BRIGHT; 990 } else if (mPendingRequestChangedLocked) { 991 previousPolicy = mPowerRequest.policy; 992 mPowerRequest.copyFrom(mPendingRequestLocked); 993 updatePendingProximityRequestsLocked(); 994 mPendingRequestChangedLocked = false; 995 mDisplayReadyLocked = false; 996 } else { 997 previousPolicy = mPowerRequest.policy; 998 } 999 1000 mustNotify = !mDisplayReadyLocked; 1001 } 1002 1003 // Compute the basic display state using the policy. 1004 // We might override this below based on other factors. 1005 // Initialise brightness as invalid. 1006 int state; 1007 float brightnessState = PowerManager.BRIGHTNESS_INVALID_FLOAT; 1008 boolean performScreenOffTransition = false; 1009 switch (mPowerRequest.policy) { 1010 case DisplayPowerRequest.POLICY_OFF: 1011 state = Display.STATE_OFF; 1012 performScreenOffTransition = true; 1013 break; 1014 case DisplayPowerRequest.POLICY_DOZE: 1015 if (mPowerRequest.dozeScreenState != Display.STATE_UNKNOWN) { 1016 state = mPowerRequest.dozeScreenState; 1017 } else { 1018 state = Display.STATE_DOZE; 1019 } 1020 if (!mAllowAutoBrightnessWhileDozingConfig) { 1021 brightnessState = mPowerRequest.dozeScreenBrightness; 1022 mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE); 1023 } 1024 break; 1025 case DisplayPowerRequest.POLICY_VR: 1026 state = Display.STATE_VR; 1027 break; 1028 case DisplayPowerRequest.POLICY_DIM: 1029 case DisplayPowerRequest.POLICY_BRIGHT: 1030 default: 1031 state = Display.STATE_ON; 1032 break; 1033 } 1034 assert(state != Display.STATE_UNKNOWN); 1035 1036 // Initialize things the first time the power state is changed. 1037 if (mustInitialize) { 1038 initialize(state); 1039 } 1040 1041 // Apply the proximity sensor. 1042 if (mProximitySensor != null) { 1043 if (mPowerRequest.useProximitySensor && state != Display.STATE_OFF) { 1044 // At this point the policy says that the screen should be on, but we've been 1045 // asked to listen to the prox sensor to adjust the display state, so lets make 1046 // sure the sensor is on. 1047 setProximitySensorEnabled(true); 1048 if (!mScreenOffBecauseOfProximity 1049 && mProximity == PROXIMITY_POSITIVE 1050 && !mIgnoreProximityUntilChanged) { 1051 // Prox sensor already reporting "near" so we should turn off the screen. 1052 // Also checked that we aren't currently set to ignore the proximity sensor 1053 // temporarily. 1054 mScreenOffBecauseOfProximity = true; 1055 sendOnProximityPositiveWithWakelock(); 1056 } 1057 } else if (mWaitingForNegativeProximity 1058 && mScreenOffBecauseOfProximity 1059 && mProximity == PROXIMITY_POSITIVE 1060 && state != Display.STATE_OFF) { 1061 // The policy says that we should have the screen on, but it's off due to the prox 1062 // and we've been asked to wait until the screen is far from the user to turn it 1063 // back on. Let keep the prox sensor on so we can tell when it's far again. 1064 setProximitySensorEnabled(true); 1065 } else { 1066 // We haven't been asked to use the prox sensor and we're not waiting on the screen 1067 // to turn back on...so lets shut down the prox sensor. 1068 setProximitySensorEnabled(false); 1069 mWaitingForNegativeProximity = false; 1070 } 1071 1072 if (mScreenOffBecauseOfProximity 1073 && (mProximity != PROXIMITY_POSITIVE || mIgnoreProximityUntilChanged)) { 1074 // The screen *was* off due to prox being near, but now it's "far" so lets turn 1075 // the screen back on. Also turn it back on if we've been asked to ignore the 1076 // prox sensor temporarily. 1077 mScreenOffBecauseOfProximity = false; 1078 sendOnProximityNegativeWithWakelock(); 1079 } 1080 } else { 1081 mWaitingForNegativeProximity = false; 1082 mIgnoreProximityUntilChanged = false; 1083 } 1084 1085 if (!mLogicalDisplay.isEnabled() 1086 || mLogicalDisplay.getPhase() == LogicalDisplay.DISPLAY_PHASE_LAYOUT_TRANSITION 1087 || mScreenOffBecauseOfProximity) { 1088 state = Display.STATE_OFF; 1089 } 1090 1091 // Animate the screen state change unless already animating. 1092 // The transition may be deferred, so after this point we will use the 1093 // actual state instead of the desired one. 1094 final int oldState = mPowerState.getScreenState(); 1095 animateScreenStateChange(state, performScreenOffTransition); 1096 state = mPowerState.getScreenState(); 1097 1098 if (state == Display.STATE_OFF) { 1099 brightnessState = PowerManager.BRIGHTNESS_OFF_FLOAT; 1100 mBrightnessReasonTemp.setReason(BrightnessReason.REASON_SCREEN_OFF); 1101 } 1102 1103 // Always use the VR brightness when in the VR state. 1104 if (state == Display.STATE_VR) { 1105 brightnessState = mScreenBrightnessForVr; 1106 mBrightnessReasonTemp.setReason(BrightnessReason.REASON_VR); 1107 } 1108 1109 if ((Float.isNaN(brightnessState)) 1110 && isValidBrightnessValue(mPowerRequest.screenBrightnessOverride)) { 1111 brightnessState = mPowerRequest.screenBrightnessOverride; 1112 mBrightnessReasonTemp.setReason(BrightnessReason.REASON_OVERRIDE); 1113 mAppliedScreenBrightnessOverride = true; 1114 } else { 1115 mAppliedScreenBrightnessOverride = false; 1116 } 1117 1118 final boolean autoBrightnessEnabledInDoze = 1119 mAllowAutoBrightnessWhileDozingConfig && Display.isDozeState(state); 1120 final boolean autoBrightnessEnabled = mPowerRequest.useAutoBrightness 1121 && (state == Display.STATE_ON || autoBrightnessEnabledInDoze) 1122 && Float.isNaN(brightnessState) 1123 && mAutomaticBrightnessController != null; 1124 1125 final boolean userSetBrightnessChanged = updateUserSetScreenBrightness(); 1126 1127 // Use the temporary screen brightness if there isn't an override, either from 1128 // WindowManager or based on the display state. 1129 if (isValidBrightnessValue(mTemporaryScreenBrightness)) { 1130 brightnessState = mTemporaryScreenBrightness; 1131 mAppliedTemporaryBrightness = true; 1132 mBrightnessReasonTemp.setReason(BrightnessReason.REASON_TEMPORARY); 1133 } else { 1134 mAppliedTemporaryBrightness = false; 1135 } 1136 1137 final boolean autoBrightnessAdjustmentChanged = updateAutoBrightnessAdjustment(); 1138 if (autoBrightnessAdjustmentChanged) { 1139 mTemporaryAutoBrightnessAdjustment = Float.NaN; 1140 } 1141 1142 // Use the autobrightness adjustment override if set. 1143 final float autoBrightnessAdjustment; 1144 if (!Float.isNaN(mTemporaryAutoBrightnessAdjustment)) { 1145 autoBrightnessAdjustment = mTemporaryAutoBrightnessAdjustment; 1146 brightnessAdjustmentFlags = BrightnessReason.ADJUSTMENT_AUTO_TEMP; 1147 mAppliedTemporaryAutoBrightnessAdjustment = true; 1148 } else { 1149 autoBrightnessAdjustment = mAutoBrightnessAdjustment; 1150 brightnessAdjustmentFlags = BrightnessReason.ADJUSTMENT_AUTO; 1151 mAppliedTemporaryAutoBrightnessAdjustment = false; 1152 } 1153 // Apply brightness boost. 1154 // We do this here after deciding whether auto-brightness is enabled so that we don't 1155 // disable the light sensor during this temporary state. That way when boost ends we will 1156 // be able to resume normal auto-brightness behavior without any delay. 1157 if (mPowerRequest.boostScreenBrightness 1158 && brightnessState != PowerManager.BRIGHTNESS_OFF_FLOAT) { 1159 brightnessState = PowerManager.BRIGHTNESS_MAX; 1160 mBrightnessReasonTemp.setReason(BrightnessReason.REASON_BOOST); 1161 mAppliedBrightnessBoost = true; 1162 } else { 1163 mAppliedBrightnessBoost = false; 1164 } 1165 1166 // If the brightness is already set then it's been overridden by something other than the 1167 // user, or is a temporary adjustment. 1168 boolean userInitiatedChange = (Float.isNaN(brightnessState)) 1169 && (autoBrightnessAdjustmentChanged || userSetBrightnessChanged); 1170 boolean hadUserBrightnessPoint = false; 1171 // Configure auto-brightness. 1172 if (mAutomaticBrightnessController != null) { 1173 hadUserBrightnessPoint = mAutomaticBrightnessController.hasUserDataPoints(); 1174 mAutomaticBrightnessController.configure(autoBrightnessEnabled, 1175 mBrightnessConfiguration, 1176 mLastUserSetScreenBrightness, 1177 userSetBrightnessChanged, autoBrightnessAdjustment, 1178 autoBrightnessAdjustmentChanged, mPowerRequest.policy); 1179 } 1180 1181 if (mBrightnessTracker != null) { 1182 mBrightnessTracker.setBrightnessConfiguration(mBrightnessConfiguration); 1183 } 1184 1185 boolean updateScreenBrightnessSetting = false; 1186 1187 // Apply auto-brightness. 1188 boolean slowChange = false; 1189 if (Float.isNaN(brightnessState)) { 1190 float newAutoBrightnessAdjustment = autoBrightnessAdjustment; 1191 if (autoBrightnessEnabled) { 1192 brightnessState = mAutomaticBrightnessController.getAutomaticScreenBrightness(); 1193 newAutoBrightnessAdjustment = 1194 mAutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment(); 1195 } 1196 if (isValidBrightnessValue(brightnessState) 1197 || brightnessState == PowerManager.BRIGHTNESS_OFF_FLOAT) { 1198 // Use current auto-brightness value and slowly adjust to changes. 1199 brightnessState = clampScreenBrightness(brightnessState); 1200 if (mAppliedAutoBrightness && !autoBrightnessAdjustmentChanged) { 1201 slowChange = true; // slowly adapt to auto-brightness 1202 } 1203 updateScreenBrightnessSetting = true; 1204 mAppliedAutoBrightness = true; 1205 mBrightnessReasonTemp.setReason(BrightnessReason.REASON_AUTOMATIC); 1206 } else { 1207 mAppliedAutoBrightness = false; 1208 } 1209 if (autoBrightnessAdjustment != newAutoBrightnessAdjustment) { 1210 // If the autobrightness controller has decided to change the adjustment value 1211 // used, make sure that's reflected in settings. 1212 putAutoBrightnessAdjustmentSetting(newAutoBrightnessAdjustment); 1213 } else { 1214 // Adjustment values resulted in no change 1215 brightnessAdjustmentFlags = 0; 1216 } 1217 } else { 1218 // Any non-auto-brightness values such as override or temporary should still be subject 1219 // to clamping so that they don't go beyond the current max as specified by HBM 1220 // Controller. 1221 brightnessState = clampScreenBrightness(brightnessState); 1222 mAppliedAutoBrightness = false; 1223 brightnessAdjustmentFlags = 0; 1224 } 1225 1226 // Use default brightness when dozing unless overridden. 1227 if ((Float.isNaN(brightnessState)) 1228 && Display.isDozeState(state)) { 1229 brightnessState = clampScreenBrightness(mScreenBrightnessDozeConfig); 1230 mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE_DEFAULT); 1231 } 1232 1233 // Apply manual brightness. 1234 if (Float.isNaN(brightnessState)) { 1235 brightnessState = clampScreenBrightness(mCurrentScreenBrightnessSetting); 1236 if (brightnessState != mCurrentScreenBrightnessSetting) { 1237 // The manually chosen screen brightness is outside of the currently allowed 1238 // range (i.e., high-brightness-mode), make sure we tell the rest of the system 1239 // by updating the setting. 1240 updateScreenBrightnessSetting = true; 1241 } 1242 mBrightnessReasonTemp.setReason(BrightnessReason.REASON_MANUAL); 1243 } 1244 1245 // The current brightness to use has been calculated at this point (minus the adjustments 1246 // like low-power and dim), and HbmController should be notified so that it can accurately 1247 // calculate HDR or HBM levels. We specifically do it here instead of having HbmController 1248 // listen to the brightness setting because certain brightness sources (just as an app 1249 // override) are not saved to the setting, but should be reflected in HBM 1250 // calculations. 1251 mHbmController.onBrightnessChanged(brightnessState); 1252 1253 if (updateScreenBrightnessSetting) { 1254 // Tell the rest of the system about the new brightness in case we had to change it 1255 // for things like auto-brightness or high-brightness-mode. Note that we do this 1256 // before applying the low power or dim transformations so that the slider 1257 // accurately represents the full possible range, even if they range changes what 1258 // it means in absolute terms. 1259 putScreenBrightnessSetting(brightnessState, /* updateCurrent */ true); 1260 } 1261 1262 // We save the brightness info *after* the brightness setting has been changed so that 1263 // the brightness info reflects the latest value. 1264 saveBrightnessInfo(getScreenBrightnessSetting()); 1265 1266 // Apply dimming by at least some minimum amount when user activity 1267 // timeout is about to expire. 1268 if (mPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) { 1269 if (brightnessState > PowerManager.BRIGHTNESS_MIN) { 1270 brightnessState = Math.max( 1271 Math.min(brightnessState - SCREEN_DIM_MINIMUM_REDUCTION_FLOAT, 1272 mScreenBrightnessDimConfig), 1273 PowerManager.BRIGHTNESS_MIN); 1274 mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_DIMMED); 1275 } 1276 if (!mAppliedDimming) { 1277 slowChange = false; 1278 } 1279 mAppliedDimming = true; 1280 } else if (mAppliedDimming) { 1281 slowChange = false; 1282 mAppliedDimming = false; 1283 } 1284 // If low power mode is enabled, scale brightness by screenLowPowerBrightnessFactor 1285 // as long as it is above the minimum threshold. 1286 if (mPowerRequest.lowPowerMode) { 1287 if (brightnessState > PowerManager.BRIGHTNESS_MIN) { 1288 final float brightnessFactor = 1289 Math.min(mPowerRequest.screenLowPowerBrightnessFactor, 1); 1290 final float lowPowerBrightnessFloat = (brightnessState * brightnessFactor); 1291 brightnessState = Math.max(lowPowerBrightnessFloat, PowerManager.BRIGHTNESS_MIN); 1292 mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_LOW_POWER); 1293 } 1294 if (!mAppliedLowPower) { 1295 slowChange = false; 1296 } 1297 mAppliedLowPower = true; 1298 } else if (mAppliedLowPower) { 1299 slowChange = false; 1300 mAppliedLowPower = false; 1301 } 1302 1303 // Animate the screen brightness when the screen is on or dozing. 1304 // Skip the animation when the screen is off or suspended or transition to/from VR. 1305 if (!mPendingScreenOff) { 1306 if (mSkipScreenOnBrightnessRamp) { 1307 if (state == Display.STATE_ON) { 1308 if (mSkipRampState == RAMP_STATE_SKIP_NONE && mDozing) { 1309 mInitialAutoBrightness = brightnessState; 1310 mSkipRampState = RAMP_STATE_SKIP_INITIAL; 1311 } else if (mSkipRampState == RAMP_STATE_SKIP_INITIAL 1312 && mUseSoftwareAutoBrightnessConfig 1313 && !BrightnessSynchronizer.floatEquals(brightnessState, 1314 mInitialAutoBrightness)) { 1315 mSkipRampState = RAMP_STATE_SKIP_AUTOBRIGHT; 1316 } else if (mSkipRampState == RAMP_STATE_SKIP_AUTOBRIGHT) { 1317 mSkipRampState = RAMP_STATE_SKIP_NONE; 1318 } 1319 } else { 1320 mSkipRampState = RAMP_STATE_SKIP_NONE; 1321 } 1322 } 1323 1324 final boolean wasOrWillBeInVr = 1325 (state == Display.STATE_VR || oldState == Display.STATE_VR); 1326 final boolean initialRampSkip = 1327 state == Display.STATE_ON && mSkipRampState != RAMP_STATE_SKIP_NONE; 1328 // While dozing, sometimes the brightness is split into buckets. Rather than animating 1329 // through the buckets, which is unlikely to be smooth in the first place, just jump 1330 // right to the suggested brightness. 1331 final boolean hasBrightnessBuckets = 1332 Display.isDozeState(state) && mBrightnessBucketsInDozeConfig; 1333 // If the color fade is totally covering the screen then we can change the backlight 1334 // level without it being a noticeable jump since any actual content isn't yet visible. 1335 final boolean isDisplayContentVisible = 1336 mColorFadeEnabled && mPowerState.getColorFadeLevel() == 1.0f; 1337 final boolean brightnessIsTemporary = 1338 mAppliedTemporaryBrightness || mAppliedTemporaryAutoBrightnessAdjustment; 1339 // We only want to animate the brightness if it is between 0.0f and 1.0f. 1340 // brightnessState can contain the values -1.0f and NaN, which we do not want to 1341 // animate to. To avoid this, we check the value first. 1342 // If the brightnessState is off (-1.0f) we still want to animate to the minimum 1343 // brightness (0.0f) to accommodate for LED displays, which can appear bright to the 1344 // user even when the display is all black. We also clamp here in case some 1345 // transformations to the brightness have pushed it outside of the currently 1346 // allowed range. 1347 float animateValue = clampScreenBrightness(brightnessState); 1348 1349 // If there are any HDR layers on the screen, we have a special brightness value that we 1350 // use instead. We still preserve the calculated brightness for Standard Dynamic Range 1351 // (SDR) layers, but the main brightness value will be the one for HDR. 1352 float sdrAnimateValue = animateValue; 1353 if (mHbmController.getHighBrightnessMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR 1354 && ((mBrightnessReason.modifier & BrightnessReason.MODIFIER_DIMMED) == 0 1355 || (mBrightnessReason.modifier & BrightnessReason.MODIFIER_LOW_POWER) == 0)) { 1356 // We want to scale HDR brightness level with the SDR level 1357 animateValue = mHbmController.getHdrBrightnessValue(); 1358 } 1359 1360 final float currentBrightness = mPowerState.getScreenBrightness(); 1361 final float currentSdrBrightness = mPowerState.getSdrScreenBrightness(); 1362 if (isValidBrightnessValue(animateValue) 1363 && (animateValue != currentBrightness 1364 || sdrAnimateValue != currentSdrBrightness)) { 1365 if (initialRampSkip || hasBrightnessBuckets 1366 || wasOrWillBeInVr || !isDisplayContentVisible || brightnessIsTemporary) { 1367 animateScreenBrightness(animateValue, sdrAnimateValue, 1368 SCREEN_ANIMATION_RATE_MINIMUM); 1369 } else { 1370 boolean isIncreasing = animateValue > currentBrightness; 1371 final float rampSpeed; 1372 if (isIncreasing && slowChange) { 1373 rampSpeed = mBrightnessRampRateSlowIncrease; 1374 } else if (isIncreasing && !slowChange) { 1375 rampSpeed = mBrightnessRampRateFastIncrease; 1376 } else if (!isIncreasing && slowChange) { 1377 rampSpeed = mBrightnessRampRateSlowDecrease; 1378 } else { 1379 rampSpeed = mBrightnessRampRateFastDecrease; 1380 } 1381 animateScreenBrightness(animateValue, sdrAnimateValue, rampSpeed); 1382 } 1383 } 1384 1385 if (!brightnessIsTemporary) { 1386 if (userInitiatedChange && (mAutomaticBrightnessController == null 1387 || !mAutomaticBrightnessController.hasValidAmbientLux())) { 1388 // If we don't have a valid lux reading we can't report a valid 1389 // slider event so notify as if the system changed the brightness. 1390 userInitiatedChange = false; 1391 } 1392 notifyBrightnessChanged(brightnessState, userInitiatedChange, 1393 hadUserBrightnessPoint); 1394 } 1395 1396 } 1397 1398 // Log any changes to what is currently driving the brightness setting. 1399 if (!mBrightnessReasonTemp.equals(mBrightnessReason) || brightnessAdjustmentFlags != 0) { 1400 Slog.v(TAG, "Brightness [" + brightnessState + "] reason changing to: '" 1401 + mBrightnessReasonTemp.toString(brightnessAdjustmentFlags) 1402 + "', previous reason: '" + mBrightnessReason + "'."); 1403 mBrightnessReason.set(mBrightnessReasonTemp); 1404 } else if (mBrightnessReasonTemp.reason == BrightnessReason.REASON_MANUAL 1405 && userSetBrightnessChanged) { 1406 Slog.v(TAG, "Brightness [" + brightnessState + "] manual adjustment."); 1407 } 1408 1409 // Update display white-balance. 1410 if (mDisplayWhiteBalanceController != null) { 1411 if (state == Display.STATE_ON && mDisplayWhiteBalanceSettings.isEnabled()) { 1412 mDisplayWhiteBalanceController.setEnabled(true); 1413 mDisplayWhiteBalanceController.updateDisplayColorTemperature(); 1414 } else { 1415 mDisplayWhiteBalanceController.setEnabled(false); 1416 } 1417 } 1418 1419 // Determine whether the display is ready for use in the newly requested state. 1420 // Note that we do not wait for the brightness ramp animation to complete before 1421 // reporting the display is ready because we only need to ensure the screen is in the 1422 // right power state even as it continues to converge on the desired brightness. 1423 final boolean ready = mPendingScreenOnUnblocker == null && 1424 (!mColorFadeEnabled || 1425 (!mColorFadeOnAnimator.isStarted() && !mColorFadeOffAnimator.isStarted())) 1426 && mPowerState.waitUntilClean(mCleanListener); 1427 final boolean finished = ready 1428 && !mScreenBrightnessRampAnimator.isAnimating(); 1429 1430 // Notify policy about screen turned on. 1431 if (ready && state != Display.STATE_OFF 1432 && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_ON) { 1433 setReportedScreenState(REPORTED_TO_POLICY_SCREEN_ON); 1434 mWindowManagerPolicy.screenTurnedOn(mDisplayId); 1435 } 1436 1437 // Grab a wake lock if we have unfinished business. 1438 if (!finished && !mUnfinishedBusiness) { 1439 if (DEBUG) { 1440 Slog.d(TAG, "Unfinished business..."); 1441 } 1442 mCallbacks.acquireSuspendBlocker(); 1443 mUnfinishedBusiness = true; 1444 } 1445 1446 // Notify the power manager when ready. 1447 if (ready && mustNotify) { 1448 // Send state change. 1449 synchronized (mLock) { 1450 if (!mPendingRequestChangedLocked) { 1451 mDisplayReadyLocked = true; 1452 1453 if (DEBUG) { 1454 Slog.d(TAG, "Display ready!"); 1455 } 1456 } 1457 } 1458 sendOnStateChangedWithWakelock(); 1459 } 1460 1461 // Release the wake lock when we have no unfinished business. 1462 if (finished && mUnfinishedBusiness) { 1463 if (DEBUG) { 1464 Slog.d(TAG, "Finished business..."); 1465 } 1466 mUnfinishedBusiness = false; 1467 mCallbacks.releaseSuspendBlocker(); 1468 } 1469 1470 // Record if dozing for future comparison. 1471 mDozing = state != Display.STATE_ON; 1472 1473 if (previousPolicy != mPowerRequest.policy) { 1474 logDisplayPolicyChanged(mPowerRequest.policy); 1475 } 1476 } 1477 1478 @Override updateBrightness()1479 public void updateBrightness() { 1480 sendUpdatePowerState(); 1481 } 1482 1483 /** 1484 * Ignores the proximity sensor until the sensor state changes, but only if the sensor is 1485 * currently enabled and forcing the screen to be dark. 1486 */ ignoreProximitySensorUntilChanged()1487 public void ignoreProximitySensorUntilChanged() { 1488 mHandler.sendEmptyMessage(MSG_IGNORE_PROXIMITY); 1489 } 1490 setBrightnessConfiguration(BrightnessConfiguration c)1491 public void setBrightnessConfiguration(BrightnessConfiguration c) { 1492 Message msg = mHandler.obtainMessage(MSG_CONFIGURE_BRIGHTNESS, c); 1493 msg.sendToTarget(); 1494 } 1495 setTemporaryBrightness(float brightness)1496 public void setTemporaryBrightness(float brightness) { 1497 Message msg = mHandler.obtainMessage(MSG_SET_TEMPORARY_BRIGHTNESS, 1498 Float.floatToIntBits(brightness), 0 /*unused*/); 1499 msg.sendToTarget(); 1500 } 1501 setTemporaryAutoBrightnessAdjustment(float adjustment)1502 public void setTemporaryAutoBrightnessAdjustment(float adjustment) { 1503 Message msg = mHandler.obtainMessage(MSG_SET_TEMPORARY_AUTO_BRIGHTNESS_ADJUSTMENT, 1504 Float.floatToIntBits(adjustment), 0 /*unused*/); 1505 msg.sendToTarget(); 1506 } 1507 getBrightnessInfo()1508 public BrightnessInfo getBrightnessInfo() { 1509 synchronized (mCachedBrightnessInfo) { 1510 return new BrightnessInfo( 1511 mCachedBrightnessInfo.brightness, 1512 mCachedBrightnessInfo.brightnessMin, 1513 mCachedBrightnessInfo.brightnessMax, 1514 mCachedBrightnessInfo.hbmMode); 1515 } 1516 } 1517 saveBrightnessInfo(float brightness)1518 private void saveBrightnessInfo(float brightness) { 1519 synchronized (mCachedBrightnessInfo) { 1520 mCachedBrightnessInfo.brightness = brightness; 1521 mCachedBrightnessInfo.brightnessMin = mHbmController.getCurrentBrightnessMin(); 1522 mCachedBrightnessInfo.brightnessMax = mHbmController.getCurrentBrightnessMax(); 1523 mCachedBrightnessInfo.hbmMode = mHbmController.getHighBrightnessMode(); 1524 } 1525 } 1526 createHbmControllerLocked()1527 private HighBrightnessModeController createHbmControllerLocked() { 1528 final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked(); 1529 final DisplayDeviceConfig ddConfig = device.getDisplayDeviceConfig(); 1530 final IBinder displayToken = 1531 mLogicalDisplay.getPrimaryDisplayDeviceLocked().getDisplayTokenLocked(); 1532 final DisplayDeviceConfig.HighBrightnessModeData hbmData = 1533 ddConfig != null ? ddConfig.getHighBrightnessModeData() : null; 1534 final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); 1535 return new HighBrightnessModeController(mHandler, info.width, info.height, displayToken, 1536 PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX, hbmData, 1537 () -> { 1538 sendUpdatePowerStateLocked(); 1539 mHandler.post(mOnBrightnessChangeRunnable); 1540 // TODO(b/192258832): Switch the HBMChangeCallback to a listener pattern. 1541 mAutomaticBrightnessController.update(); 1542 }, mContext); 1543 } 1544 blockScreenOn()1545 private void blockScreenOn() { 1546 if (mPendingScreenOnUnblocker == null) { 1547 Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0); 1548 mPendingScreenOnUnblocker = new ScreenOnUnblocker(); 1549 mScreenOnBlockStartRealTime = SystemClock.elapsedRealtime(); 1550 Slog.i(TAG, "Blocking screen on until initial contents have been drawn."); 1551 } 1552 } 1553 unblockScreenOn()1554 private void unblockScreenOn() { 1555 if (mPendingScreenOnUnblocker != null) { 1556 mPendingScreenOnUnblocker = null; 1557 long delay = SystemClock.elapsedRealtime() - mScreenOnBlockStartRealTime; 1558 Slog.i(TAG, "Unblocked screen on after " + delay + " ms"); 1559 Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0); 1560 } 1561 } 1562 blockScreenOff()1563 private void blockScreenOff() { 1564 if (mPendingScreenOffUnblocker == null) { 1565 Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, SCREEN_OFF_BLOCKED_TRACE_NAME, 0); 1566 mPendingScreenOffUnblocker = new ScreenOffUnblocker(); 1567 mScreenOffBlockStartRealTime = SystemClock.elapsedRealtime(); 1568 Slog.i(TAG, "Blocking screen off"); 1569 } 1570 } 1571 unblockScreenOff()1572 private void unblockScreenOff() { 1573 if (mPendingScreenOffUnblocker != null) { 1574 mPendingScreenOffUnblocker = null; 1575 long delay = SystemClock.elapsedRealtime() - mScreenOffBlockStartRealTime; 1576 Slog.i(TAG, "Unblocked screen off after " + delay + " ms"); 1577 Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, SCREEN_OFF_BLOCKED_TRACE_NAME, 0); 1578 } 1579 } 1580 setScreenState(int state)1581 private boolean setScreenState(int state) { 1582 return setScreenState(state, false /*reportOnly*/); 1583 } 1584 setScreenState(int state, boolean reportOnly)1585 private boolean setScreenState(int state, boolean reportOnly) { 1586 final boolean isOff = (state == Display.STATE_OFF); 1587 1588 if (mPowerState.getScreenState() != state 1589 || mReportedScreenStateToPolicy == REPORTED_TO_POLICY_UNREPORTED) { 1590 // If we are trying to turn screen off, give policy a chance to do something before we 1591 // actually turn the screen off. 1592 if (isOff && !mScreenOffBecauseOfProximity) { 1593 if (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_ON 1594 || mReportedScreenStateToPolicy == REPORTED_TO_POLICY_UNREPORTED) { 1595 setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_OFF); 1596 blockScreenOff(); 1597 mWindowManagerPolicy.screenTurningOff(mDisplayId, mPendingScreenOffUnblocker); 1598 unblockScreenOff(); 1599 } else if (mPendingScreenOffUnblocker != null) { 1600 // Abort doing the state change until screen off is unblocked. 1601 return false; 1602 } 1603 } 1604 1605 if (!reportOnly && mPowerState.getScreenState() != state) { 1606 Trace.traceCounter(Trace.TRACE_TAG_POWER, "ScreenState", state); 1607 // TODO(b/153319140) remove when we can get this from the above trace invocation 1608 SystemProperties.set("debug.tracing.screen_state", String.valueOf(state)); 1609 mPowerState.setScreenState(state); 1610 // Tell battery stats about the transition. 1611 noteScreenState(state); 1612 } 1613 } 1614 1615 // Tell the window manager policy when the screen is turned off or on unless it's due 1616 // to the proximity sensor. We temporarily block turning the screen on until the 1617 // window manager is ready by leaving a black surface covering the screen. 1618 // This surface is essentially the final state of the color fade animation and 1619 // it is only removed once the window manager tells us that the activity has 1620 // finished drawing underneath. 1621 if (isOff && mReportedScreenStateToPolicy != REPORTED_TO_POLICY_SCREEN_OFF 1622 && !mScreenOffBecauseOfProximity) { 1623 setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF); 1624 unblockScreenOn(); 1625 mWindowManagerPolicy.screenTurnedOff(mDisplayId); 1626 } else if (!isOff 1627 && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_OFF) { 1628 1629 // We told policy already that screen was turning off, but now we changed our minds. 1630 // Complete the full state transition on -> turningOff -> off. 1631 unblockScreenOff(); 1632 mWindowManagerPolicy.screenTurnedOff(mDisplayId); 1633 setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF); 1634 } 1635 if (!isOff 1636 && (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF 1637 || mReportedScreenStateToPolicy == REPORTED_TO_POLICY_UNREPORTED)) { 1638 setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_ON); 1639 if (mPowerState.getColorFadeLevel() == 0.0f) { 1640 blockScreenOn(); 1641 } else { 1642 unblockScreenOn(); 1643 } 1644 mWindowManagerPolicy.screenTurningOn(mDisplayId, mPendingScreenOnUnblocker); 1645 } 1646 1647 // Return true if the screen isn't blocked. 1648 return mPendingScreenOnUnblocker == null; 1649 } 1650 setReportedScreenState(int state)1651 private void setReportedScreenState(int state) { 1652 Trace.traceCounter(Trace.TRACE_TAG_POWER, "ReportedScreenStateToPolicy", state); 1653 mReportedScreenStateToPolicy = state; 1654 } 1655 loadAmbientLightSensor()1656 private void loadAmbientLightSensor() { 1657 DisplayDeviceConfig.SensorData lightSensor = mDisplayDeviceConfig.getAmbientLightSensor(); 1658 final int fallbackType = mDisplayId == Display.DEFAULT_DISPLAY 1659 ? Sensor.TYPE_LIGHT : SensorUtils.NO_FALLBACK; 1660 mLightSensor = SensorUtils.findSensor(mSensorManager, lightSensor.type, lightSensor.name, 1661 fallbackType); 1662 } 1663 loadProximitySensor()1664 private void loadProximitySensor() { 1665 if (DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) { 1666 return; 1667 } 1668 final DisplayDeviceConfig.SensorData proxSensor = 1669 mDisplayDeviceConfig.getProximitySensor(); 1670 final int fallbackType = mDisplayId == Display.DEFAULT_DISPLAY 1671 ? Sensor.TYPE_PROXIMITY : SensorUtils.NO_FALLBACK; 1672 mProximitySensor = SensorUtils.findSensor(mSensorManager, proxSensor.type, proxSensor.name, 1673 fallbackType); 1674 if (mProximitySensor != null) { 1675 mProximityThreshold = Math.min(mProximitySensor.getMaximumRange(), 1676 TYPICAL_PROXIMITY_THRESHOLD); 1677 } 1678 } 1679 clampScreenBrightnessForVr(float value)1680 private float clampScreenBrightnessForVr(float value) { 1681 return MathUtils.constrain( 1682 value, mScreenBrightnessForVrRangeMinimum, 1683 mScreenBrightnessForVrRangeMaximum); 1684 } 1685 clampScreenBrightness(float value)1686 private float clampScreenBrightness(float value) { 1687 if (Float.isNaN(value)) { 1688 value = PowerManager.BRIGHTNESS_MIN; 1689 } 1690 return MathUtils.constrain(value, 1691 mHbmController.getCurrentBrightnessMin(), mHbmController.getCurrentBrightnessMax()); 1692 } 1693 1694 // Checks whether the brightness is within the valid brightness range, not including off. isValidBrightnessValue(float brightness)1695 private boolean isValidBrightnessValue(float brightness) { 1696 return brightness >= PowerManager.BRIGHTNESS_MIN 1697 && brightness <= PowerManager.BRIGHTNESS_MAX; 1698 } 1699 animateScreenBrightness(float target, float sdrTarget, float rate)1700 private void animateScreenBrightness(float target, float sdrTarget, float rate) { 1701 if (DEBUG) { 1702 Slog.d(TAG, "Animating brightness: target=" + target + ", sdrTarget=" + sdrTarget 1703 + ", rate=" + rate); 1704 } 1705 if (mScreenBrightnessRampAnimator.animateTo(target, sdrTarget, rate)) { 1706 Trace.traceCounter(Trace.TRACE_TAG_POWER, "TargetScreenBrightness", (int) target); 1707 // TODO(b/153319140) remove when we can get this from the above trace invocation 1708 SystemProperties.set("debug.tracing.screen_brightness", String.valueOf(target)); 1709 noteScreenBrightness(target); 1710 } 1711 } 1712 animateScreenStateChange(int target, boolean performScreenOffTransition)1713 private void animateScreenStateChange(int target, boolean performScreenOffTransition) { 1714 // If there is already an animation in progress, don't interfere with it. 1715 if (mColorFadeEnabled && 1716 (mColorFadeOnAnimator.isStarted() || mColorFadeOffAnimator.isStarted())) { 1717 if (target != Display.STATE_ON) { 1718 return; 1719 } 1720 // If display state changed to on, proceed and stop the color fade and turn screen on. 1721 mPendingScreenOff = false; 1722 } 1723 1724 if (mDisplayBlanksAfterDozeConfig 1725 && Display.isDozeState(mPowerState.getScreenState()) 1726 && !Display.isDozeState(target)) { 1727 // Skip the screen off animation and add a black surface to hide the 1728 // contents of the screen. 1729 mPowerState.prepareColorFade(mContext, 1730 mColorFadeFadesConfig ? ColorFade.MODE_FADE : ColorFade.MODE_WARM_UP); 1731 if (mColorFadeOffAnimator != null) { 1732 mColorFadeOffAnimator.end(); 1733 } 1734 // Some display hardware will blank itself on the transition between doze and non-doze 1735 // but still on display states. In this case we want to report to policy that the 1736 // display has turned off so it can prepare the appropriate power on animation, but we 1737 // don't want to actually transition to the fully off state since that takes 1738 // significantly longer to transition from. 1739 setScreenState(Display.STATE_OFF, target != Display.STATE_OFF /*reportOnly*/); 1740 } 1741 1742 // If we were in the process of turning off the screen but didn't quite 1743 // finish. Then finish up now to prevent a jarring transition back 1744 // to screen on if we skipped blocking screen on as usual. 1745 if (mPendingScreenOff && target != Display.STATE_OFF) { 1746 setScreenState(Display.STATE_OFF); 1747 mPendingScreenOff = false; 1748 mPowerState.dismissColorFadeResources(); 1749 } 1750 1751 if (target == Display.STATE_ON) { 1752 // Want screen on. The contents of the screen may not yet 1753 // be visible if the color fade has not been dismissed because 1754 // its last frame of animation is solid black. 1755 if (!setScreenState(Display.STATE_ON)) { 1756 return; // screen on blocked 1757 } 1758 if (USE_COLOR_FADE_ON_ANIMATION && mColorFadeEnabled && mPowerRequest.isBrightOrDim()) { 1759 // Perform screen on animation. 1760 if (mPowerState.getColorFadeLevel() == 1.0f) { 1761 mPowerState.dismissColorFade(); 1762 } else if (mPowerState.prepareColorFade(mContext, 1763 mColorFadeFadesConfig ? 1764 ColorFade.MODE_FADE : 1765 ColorFade.MODE_WARM_UP)) { 1766 mColorFadeOnAnimator.start(); 1767 } else { 1768 mColorFadeOnAnimator.end(); 1769 } 1770 } else { 1771 // Skip screen on animation. 1772 mPowerState.setColorFadeLevel(1.0f); 1773 mPowerState.dismissColorFade(); 1774 } 1775 } else if (target == Display.STATE_VR) { 1776 // Wait for brightness animation to complete beforehand when entering VR 1777 // from screen on to prevent a perceptible jump because brightness may operate 1778 // differently when the display is configured for dozing. 1779 if (mScreenBrightnessRampAnimator.isAnimating() 1780 && mPowerState.getScreenState() == Display.STATE_ON) { 1781 return; 1782 } 1783 1784 // Set screen state. 1785 if (!setScreenState(Display.STATE_VR)) { 1786 return; // screen on blocked 1787 } 1788 1789 // Dismiss the black surface without fanfare. 1790 mPowerState.setColorFadeLevel(1.0f); 1791 mPowerState.dismissColorFade(); 1792 } else if (target == Display.STATE_DOZE) { 1793 // Want screen dozing. 1794 // Wait for brightness animation to complete beforehand when entering doze 1795 // from screen on to prevent a perceptible jump because brightness may operate 1796 // differently when the display is configured for dozing. 1797 if (mScreenBrightnessRampAnimator.isAnimating() 1798 && mPowerState.getScreenState() == Display.STATE_ON) { 1799 return; 1800 } 1801 1802 // Set screen state. 1803 if (!setScreenState(Display.STATE_DOZE)) { 1804 return; // screen on blocked 1805 } 1806 1807 // Dismiss the black surface without fanfare. 1808 mPowerState.setColorFadeLevel(1.0f); 1809 mPowerState.dismissColorFade(); 1810 } else if (target == Display.STATE_DOZE_SUSPEND) { 1811 // Want screen dozing and suspended. 1812 // Wait for brightness animation to complete beforehand unless already 1813 // suspended because we may not be able to change it after suspension. 1814 if (mScreenBrightnessRampAnimator.isAnimating() 1815 && mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) { 1816 return; 1817 } 1818 1819 // If not already suspending, temporarily set the state to doze until the 1820 // screen on is unblocked, then suspend. 1821 if (mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) { 1822 if (!setScreenState(Display.STATE_DOZE)) { 1823 return; // screen on blocked 1824 } 1825 setScreenState(Display.STATE_DOZE_SUSPEND); // already on so can't block 1826 } 1827 1828 // Dismiss the black surface without fanfare. 1829 mPowerState.setColorFadeLevel(1.0f); 1830 mPowerState.dismissColorFade(); 1831 } else if (target == Display.STATE_ON_SUSPEND) { 1832 // Want screen full-power and suspended. 1833 // Wait for brightness animation to complete beforehand unless already 1834 // suspended because we may not be able to change it after suspension. 1835 if (mScreenBrightnessRampAnimator.isAnimating() 1836 && mPowerState.getScreenState() != Display.STATE_ON_SUSPEND) { 1837 return; 1838 } 1839 1840 // If not already suspending, temporarily set the state to on until the 1841 // screen on is unblocked, then suspend. 1842 if (mPowerState.getScreenState() != Display.STATE_ON_SUSPEND) { 1843 if (!setScreenState(Display.STATE_ON)) { 1844 return; 1845 } 1846 setScreenState(Display.STATE_ON_SUSPEND); 1847 } 1848 1849 // Dismiss the black surface without fanfare. 1850 mPowerState.setColorFadeLevel(1.0f); 1851 mPowerState.dismissColorFade(); 1852 } else { 1853 // Want screen off. 1854 mPendingScreenOff = true; 1855 if (!mColorFadeEnabled) { 1856 mPowerState.setColorFadeLevel(0.0f); 1857 } 1858 1859 if (mPowerState.getColorFadeLevel() == 0.0f) { 1860 // Turn the screen off. 1861 // A black surface is already hiding the contents of the screen. 1862 setScreenState(Display.STATE_OFF); 1863 mPendingScreenOff = false; 1864 mPowerState.dismissColorFadeResources(); 1865 } else if (performScreenOffTransition 1866 && mPowerState.prepareColorFade(mContext, 1867 mColorFadeFadesConfig ? 1868 ColorFade.MODE_FADE : ColorFade.MODE_COOL_DOWN) 1869 && mPowerState.getScreenState() != Display.STATE_OFF) { 1870 // Perform the screen off animation. 1871 mColorFadeOffAnimator.start(); 1872 } else { 1873 // Skip the screen off animation and add a black surface to hide the 1874 // contents of the screen. 1875 mColorFadeOffAnimator.end(); 1876 } 1877 } 1878 } 1879 1880 private final Runnable mCleanListener = this::sendUpdatePowerState; 1881 setProximitySensorEnabled(boolean enable)1882 private void setProximitySensorEnabled(boolean enable) { 1883 if (enable) { 1884 if (!mProximitySensorEnabled) { 1885 // Register the listener. 1886 // Proximity sensor state already cleared initially. 1887 mProximitySensorEnabled = true; 1888 mIgnoreProximityUntilChanged = false; 1889 mSensorManager.registerListener(mProximitySensorListener, mProximitySensor, 1890 SensorManager.SENSOR_DELAY_NORMAL, mHandler); 1891 } 1892 } else { 1893 if (mProximitySensorEnabled) { 1894 // Unregister the listener. 1895 // Clear the proximity sensor state for next time. 1896 mProximitySensorEnabled = false; 1897 mProximity = PROXIMITY_UNKNOWN; 1898 mIgnoreProximityUntilChanged = false; 1899 mPendingProximity = PROXIMITY_UNKNOWN; 1900 mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED); 1901 mSensorManager.unregisterListener(mProximitySensorListener); 1902 clearPendingProximityDebounceTime(); // release wake lock (must be last) 1903 } 1904 } 1905 } 1906 handleProximitySensorEvent(long time, boolean positive)1907 private void handleProximitySensorEvent(long time, boolean positive) { 1908 if (mProximitySensorEnabled) { 1909 if (mPendingProximity == PROXIMITY_NEGATIVE && !positive) { 1910 return; // no change 1911 } 1912 if (mPendingProximity == PROXIMITY_POSITIVE && positive) { 1913 return; // no change 1914 } 1915 1916 // Only accept a proximity sensor reading if it remains 1917 // stable for the entire debounce delay. We hold a wake lock while 1918 // debouncing the sensor. 1919 mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED); 1920 if (positive) { 1921 mPendingProximity = PROXIMITY_POSITIVE; 1922 setPendingProximityDebounceTime( 1923 time + PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY); // acquire wake lock 1924 } else { 1925 mPendingProximity = PROXIMITY_NEGATIVE; 1926 setPendingProximityDebounceTime( 1927 time + PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY); // acquire wake lock 1928 } 1929 1930 // Debounce the new sensor reading. 1931 debounceProximitySensor(); 1932 } 1933 } 1934 debounceProximitySensor()1935 private void debounceProximitySensor() { 1936 if (mProximitySensorEnabled 1937 && mPendingProximity != PROXIMITY_UNKNOWN 1938 && mPendingProximityDebounceTime >= 0) { 1939 final long now = SystemClock.uptimeMillis(); 1940 if (mPendingProximityDebounceTime <= now) { 1941 if (mProximity != mPendingProximity) { 1942 // if the status of the sensor changed, stop ignoring. 1943 mIgnoreProximityUntilChanged = false; 1944 Slog.i(TAG, "No longer ignoring proximity [" + mPendingProximity + "]"); 1945 } 1946 // Sensor reading accepted. Apply the change then release the wake lock. 1947 mProximity = mPendingProximity; 1948 updatePowerState(); 1949 clearPendingProximityDebounceTime(); // release wake lock (must be last) 1950 } else { 1951 // Need to wait a little longer. 1952 // Debounce again later. We continue holding a wake lock while waiting. 1953 Message msg = mHandler.obtainMessage(MSG_PROXIMITY_SENSOR_DEBOUNCED); 1954 mHandler.sendMessageAtTime(msg, mPendingProximityDebounceTime); 1955 } 1956 } 1957 } 1958 clearPendingProximityDebounceTime()1959 private void clearPendingProximityDebounceTime() { 1960 if (mPendingProximityDebounceTime >= 0) { 1961 mPendingProximityDebounceTime = -1; 1962 mCallbacks.releaseSuspendBlocker(); // release wake lock 1963 } 1964 } 1965 setPendingProximityDebounceTime(long debounceTime)1966 private void setPendingProximityDebounceTime(long debounceTime) { 1967 if (mPendingProximityDebounceTime < 0) { 1968 mCallbacks.acquireSuspendBlocker(); // acquire wake lock 1969 } 1970 mPendingProximityDebounceTime = debounceTime; 1971 } 1972 sendOnStateChangedWithWakelock()1973 private void sendOnStateChangedWithWakelock() { 1974 mCallbacks.acquireSuspendBlocker(); 1975 mHandler.post(mOnStateChangedRunnable); 1976 } 1977 logDisplayPolicyChanged(int newPolicy)1978 private void logDisplayPolicyChanged(int newPolicy) { 1979 LogMaker log = new LogMaker(MetricsEvent.DISPLAY_POLICY); 1980 log.setType(MetricsEvent.TYPE_UPDATE); 1981 log.setSubtype(newPolicy); 1982 MetricsLogger.action(log); 1983 } 1984 handleSettingsChange(boolean userSwitch)1985 private void handleSettingsChange(boolean userSwitch) { 1986 mPendingScreenBrightnessSetting = getScreenBrightnessSetting(); 1987 if (userSwitch) { 1988 // Don't treat user switches as user initiated change. 1989 setCurrentScreenBrightness(mPendingScreenBrightnessSetting); 1990 if (mAutomaticBrightnessController != null) { 1991 mAutomaticBrightnessController.resetShortTermModel(); 1992 } 1993 } 1994 mPendingAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting(); 1995 // We don't bother with a pending variable for VR screen brightness since we just 1996 // immediately adapt to it. 1997 mScreenBrightnessForVr = getScreenBrightnessForVrSetting(); 1998 sendUpdatePowerState(); 1999 } 2000 getAutoBrightnessAdjustmentSetting()2001 private float getAutoBrightnessAdjustmentSetting() { 2002 final float adj = Settings.System.getFloatForUser(mContext.getContentResolver(), 2003 Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f, UserHandle.USER_CURRENT); 2004 return Float.isNaN(adj) ? 0.0f : clampAutoBrightnessAdjustment(adj); 2005 } 2006 getScreenBrightnessSetting()2007 float getScreenBrightnessSetting() { 2008 float brightness = mBrightnessSetting.getBrightness(); 2009 if (Float.isNaN(brightness)) { 2010 brightness = mScreenBrightnessDefault; 2011 } 2012 return clampAbsoluteBrightness(brightness); 2013 } 2014 getScreenBrightnessForVrSetting()2015 private float getScreenBrightnessForVrSetting() { 2016 final float brightnessFloat = Settings.System.getFloatForUser(mContext.getContentResolver(), 2017 Settings.System.SCREEN_BRIGHTNESS_FOR_VR_FLOAT, mScreenBrightnessForVrDefault, 2018 UserHandle.USER_CURRENT); 2019 return clampScreenBrightnessForVr(brightnessFloat); 2020 } 2021 putScreenBrightnessSetting(float brightnessValue)2022 void putScreenBrightnessSetting(float brightnessValue) { 2023 putScreenBrightnessSetting(brightnessValue, false); 2024 } 2025 putScreenBrightnessSetting(float brightnessValue, boolean updateCurrent)2026 private void putScreenBrightnessSetting(float brightnessValue, boolean updateCurrent) { 2027 if (!isValidBrightnessValue(brightnessValue)) { 2028 return; 2029 } 2030 if (updateCurrent) { 2031 setCurrentScreenBrightness(brightnessValue); 2032 } 2033 mBrightnessSetting.setBrightness(brightnessValue); 2034 } 2035 setCurrentScreenBrightness(float brightnessValue)2036 private void setCurrentScreenBrightness(float brightnessValue) { 2037 if (brightnessValue != mCurrentScreenBrightnessSetting) { 2038 mCurrentScreenBrightnessSetting = brightnessValue; 2039 mHandler.post(mOnBrightnessChangeRunnable); 2040 } 2041 } 2042 putAutoBrightnessAdjustmentSetting(float adjustment)2043 private void putAutoBrightnessAdjustmentSetting(float adjustment) { 2044 if (mDisplayId == Display.DEFAULT_DISPLAY) { 2045 mAutoBrightnessAdjustment = adjustment; 2046 Settings.System.putFloatForUser(mContext.getContentResolver(), 2047 Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, adjustment, 2048 UserHandle.USER_CURRENT); 2049 } 2050 } 2051 updateAutoBrightnessAdjustment()2052 private boolean updateAutoBrightnessAdjustment() { 2053 if (Float.isNaN(mPendingAutoBrightnessAdjustment)) { 2054 return false; 2055 } 2056 if (mAutoBrightnessAdjustment == mPendingAutoBrightnessAdjustment) { 2057 mPendingAutoBrightnessAdjustment = Float.NaN; 2058 return false; 2059 } 2060 mAutoBrightnessAdjustment = mPendingAutoBrightnessAdjustment; 2061 mPendingAutoBrightnessAdjustment = Float.NaN; 2062 return true; 2063 } 2064 updateUserSetScreenBrightness()2065 private boolean updateUserSetScreenBrightness() { 2066 final boolean brightnessSplineChanged = mPendingUserRbcChange; 2067 if (mPendingUserRbcChange && !Float.isNaN(mCurrentScreenBrightnessSetting)) { 2068 mLastUserSetScreenBrightness = mCurrentScreenBrightnessSetting; 2069 } 2070 mPendingUserRbcChange = false; 2071 2072 if ((Float.isNaN(mPendingScreenBrightnessSetting) 2073 || mPendingScreenBrightnessSetting < 0.0f)) { 2074 return brightnessSplineChanged; 2075 } 2076 if (mCurrentScreenBrightnessSetting == mPendingScreenBrightnessSetting) { 2077 mPendingScreenBrightnessSetting = PowerManager.BRIGHTNESS_INVALID_FLOAT; 2078 mTemporaryScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; 2079 return brightnessSplineChanged; 2080 } 2081 setCurrentScreenBrightness(mPendingScreenBrightnessSetting); 2082 mLastUserSetScreenBrightness = mPendingScreenBrightnessSetting; 2083 mPendingScreenBrightnessSetting = PowerManager.BRIGHTNESS_INVALID_FLOAT; 2084 mTemporaryScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; 2085 return true; 2086 } 2087 notifyBrightnessChanged(float brightness, boolean userInitiated, boolean hadUserDataPoint)2088 private void notifyBrightnessChanged(float brightness, boolean userInitiated, 2089 boolean hadUserDataPoint) { 2090 final float brightnessInNits = convertToNits(brightness); 2091 if (mPowerRequest.useAutoBrightness && brightnessInNits >= 0.0f 2092 && mAutomaticBrightnessController != null) { 2093 // We only want to track changes on devices that can actually map the display backlight 2094 // values into a physical brightness unit since the value provided by the API is in 2095 // nits and not using the arbitrary backlight units. 2096 final float powerFactor = mPowerRequest.lowPowerMode 2097 ? mPowerRequest.screenLowPowerBrightnessFactor 2098 : 1.0f; 2099 mBrightnessTracker.notifyBrightnessChanged(brightnessInNits, userInitiated, 2100 powerFactor, hadUserDataPoint, 2101 mAutomaticBrightnessController.isDefaultConfig(), mUniqueDisplayId); 2102 } 2103 } 2104 convertToNits(float brightness)2105 private float convertToNits(float brightness) { 2106 if (mBrightnessMapper != null) { 2107 return mBrightnessMapper.convertToNits(brightness); 2108 } else { 2109 return -1.0f; 2110 } 2111 } 2112 updatePendingProximityRequestsLocked()2113 private void updatePendingProximityRequestsLocked() { 2114 mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked; 2115 mPendingWaitForNegativeProximityLocked = false; 2116 2117 if (mIgnoreProximityUntilChanged) { 2118 // Also, lets stop waiting for negative proximity if we're ignoring it. 2119 mWaitingForNegativeProximity = false; 2120 } 2121 } 2122 ignoreProximitySensorUntilChangedInternal()2123 private void ignoreProximitySensorUntilChangedInternal() { 2124 if (!mIgnoreProximityUntilChanged 2125 && mProximity == PROXIMITY_POSITIVE) { 2126 // Only ignore if it is still reporting positive (near) 2127 mIgnoreProximityUntilChanged = true; 2128 Slog.i(TAG, "Ignoring proximity"); 2129 updatePowerState(); 2130 } 2131 } 2132 2133 private final Runnable mOnStateChangedRunnable = new Runnable() { 2134 @Override 2135 public void run() { 2136 mCallbacks.onStateChanged(); 2137 mCallbacks.releaseSuspendBlocker(); 2138 } 2139 }; 2140 sendOnProximityPositiveWithWakelock()2141 private void sendOnProximityPositiveWithWakelock() { 2142 mCallbacks.acquireSuspendBlocker(); 2143 mHandler.post(mOnProximityPositiveRunnable); 2144 } 2145 2146 private final Runnable mOnProximityPositiveRunnable = new Runnable() { 2147 @Override 2148 public void run() { 2149 mCallbacks.onProximityPositive(); 2150 mCallbacks.releaseSuspendBlocker(); 2151 } 2152 }; 2153 sendOnProximityNegativeWithWakelock()2154 private void sendOnProximityNegativeWithWakelock() { 2155 mCallbacks.acquireSuspendBlocker(); 2156 mHandler.post(mOnProximityNegativeRunnable); 2157 } 2158 2159 private final Runnable mOnProximityNegativeRunnable = new Runnable() { 2160 @Override 2161 public void run() { 2162 mCallbacks.onProximityNegative(); 2163 mCallbacks.releaseSuspendBlocker(); 2164 } 2165 }; 2166 dump(final PrintWriter pw)2167 public void dump(final PrintWriter pw) { 2168 synchronized (mLock) { 2169 pw.println(); 2170 pw.println("Display Power Controller:"); 2171 pw.println(" mDisplayId=" + mDisplayId); 2172 pw.println(" mLightSensor=" + mLightSensor); 2173 2174 pw.println(); 2175 pw.println("Display Power Controller Locked State:"); 2176 pw.println(" mDisplayReadyLocked=" + mDisplayReadyLocked); 2177 pw.println(" mPendingRequestLocked=" + mPendingRequestLocked); 2178 pw.println(" mPendingRequestChangedLocked=" + mPendingRequestChangedLocked); 2179 pw.println(" mPendingWaitForNegativeProximityLocked=" 2180 + mPendingWaitForNegativeProximityLocked); 2181 pw.println(" mPendingUpdatePowerStateLocked=" + mPendingUpdatePowerStateLocked); 2182 } 2183 2184 pw.println(); 2185 pw.println("Display Power Controller Configuration:"); 2186 pw.println(" mScreenBrightnessRangeDefault=" + mScreenBrightnessDefault); 2187 pw.println(" mScreenBrightnessDozeConfig=" + mScreenBrightnessDozeConfig); 2188 pw.println(" mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig); 2189 pw.println(" mScreenBrightnessForVrRangeMinimum=" + mScreenBrightnessForVrRangeMinimum); 2190 pw.println(" mScreenBrightnessForVrRangeMaximum=" + mScreenBrightnessForVrRangeMaximum); 2191 pw.println(" mScreenBrightnessForVrDefault=" + mScreenBrightnessForVrDefault); 2192 pw.println(" mUseSoftwareAutoBrightnessConfig=" + mUseSoftwareAutoBrightnessConfig); 2193 pw.println(" mAllowAutoBrightnessWhileDozingConfig=" + 2194 mAllowAutoBrightnessWhileDozingConfig); 2195 pw.println(" mSkipScreenOnBrightnessRamp=" + mSkipScreenOnBrightnessRamp); 2196 pw.println(" mColorFadeFadesConfig=" + mColorFadeFadesConfig); 2197 pw.println(" mColorFadeEnabled=" + mColorFadeEnabled); 2198 pw.println(" mDisplayBlanksAfterDozeConfig=" + mDisplayBlanksAfterDozeConfig); 2199 pw.println(" mBrightnessBucketsInDozeConfig=" + mBrightnessBucketsInDozeConfig); 2200 2201 mHandler.runWithScissors(new Runnable() { 2202 @Override 2203 public void run() { 2204 dumpLocal(pw); 2205 } 2206 }, 1000); 2207 } 2208 dumpLocal(PrintWriter pw)2209 private void dumpLocal(PrintWriter pw) { 2210 pw.println(); 2211 pw.println("Display Power Controller Thread State:"); 2212 pw.println(" mPowerRequest=" + mPowerRequest); 2213 pw.println(" mUnfinishedBusiness=" + mUnfinishedBusiness); 2214 pw.println(" mWaitingForNegativeProximity=" + mWaitingForNegativeProximity); 2215 pw.println(" mProximitySensor=" + mProximitySensor); 2216 pw.println(" mProximitySensorEnabled=" + mProximitySensorEnabled); 2217 pw.println(" mProximityThreshold=" + mProximityThreshold); 2218 pw.println(" mProximity=" + proximityToString(mProximity)); 2219 pw.println(" mPendingProximity=" + proximityToString(mPendingProximity)); 2220 pw.println(" mPendingProximityDebounceTime=" 2221 + TimeUtils.formatUptime(mPendingProximityDebounceTime)); 2222 pw.println(" mScreenOffBecauseOfProximity=" + mScreenOffBecauseOfProximity); 2223 pw.println(" mLastUserSetScreenBrightness=" + mLastUserSetScreenBrightness); 2224 pw.println(" mPendingScreenBrightnessSetting=" 2225 + mPendingScreenBrightnessSetting); 2226 pw.println(" mTemporaryScreenBrightness=" + mTemporaryScreenBrightness); 2227 pw.println(" mAutoBrightnessAdjustment=" + mAutoBrightnessAdjustment); 2228 pw.println(" mBrightnessReason=" + mBrightnessReason); 2229 pw.println(" mTemporaryAutoBrightnessAdjustment=" + mTemporaryAutoBrightnessAdjustment); 2230 pw.println(" mPendingAutoBrightnessAdjustment=" + mPendingAutoBrightnessAdjustment); 2231 pw.println(" mScreenBrightnessForVrFloat=" + mScreenBrightnessForVr); 2232 pw.println(" mAppliedAutoBrightness=" + mAppliedAutoBrightness); 2233 pw.println(" mAppliedDimming=" + mAppliedDimming); 2234 pw.println(" mAppliedLowPower=" + mAppliedLowPower); 2235 pw.println(" mAppliedScreenBrightnessOverride=" + mAppliedScreenBrightnessOverride); 2236 pw.println(" mAppliedTemporaryBrightness=" + mAppliedTemporaryBrightness); 2237 pw.println(" mDozing=" + mDozing); 2238 pw.println(" mSkipRampState=" + skipRampStateToString(mSkipRampState)); 2239 pw.println(" mScreenOnBlockStartRealTime=" + mScreenOnBlockStartRealTime); 2240 pw.println(" mScreenOffBlockStartRealTime=" + mScreenOffBlockStartRealTime); 2241 pw.println(" mPendingScreenOnUnblocker=" + mPendingScreenOnUnblocker); 2242 pw.println(" mPendingScreenOffUnblocker=" + mPendingScreenOffUnblocker); 2243 pw.println(" mPendingScreenOff=" + mPendingScreenOff); 2244 pw.println(" mReportedToPolicy=" + 2245 reportedToPolicyToString(mReportedScreenStateToPolicy)); 2246 2247 if (mScreenBrightnessRampAnimator != null) { 2248 pw.println(" mScreenBrightnessRampAnimator.isAnimating()=" + 2249 mScreenBrightnessRampAnimator.isAnimating()); 2250 } 2251 2252 if (mColorFadeOnAnimator != null) { 2253 pw.println(" mColorFadeOnAnimator.isStarted()=" + 2254 mColorFadeOnAnimator.isStarted()); 2255 } 2256 if (mColorFadeOffAnimator != null) { 2257 pw.println(" mColorFadeOffAnimator.isStarted()=" + 2258 mColorFadeOffAnimator.isStarted()); 2259 } 2260 2261 if (mPowerState != null) { 2262 mPowerState.dump(pw); 2263 } 2264 2265 if (mAutomaticBrightnessController != null) { 2266 mAutomaticBrightnessController.dump(pw); 2267 } 2268 2269 if (mHbmController != null) { 2270 mHbmController.dump(pw); 2271 } 2272 2273 pw.println(); 2274 if (mDisplayWhiteBalanceController != null) { 2275 mDisplayWhiteBalanceController.dump(pw); 2276 mDisplayWhiteBalanceSettings.dump(pw); 2277 } 2278 } 2279 proximityToString(int state)2280 private static String proximityToString(int state) { 2281 switch (state) { 2282 case PROXIMITY_UNKNOWN: 2283 return "Unknown"; 2284 case PROXIMITY_NEGATIVE: 2285 return "Negative"; 2286 case PROXIMITY_POSITIVE: 2287 return "Positive"; 2288 default: 2289 return Integer.toString(state); 2290 } 2291 } 2292 reportedToPolicyToString(int state)2293 private static String reportedToPolicyToString(int state) { 2294 switch (state) { 2295 case REPORTED_TO_POLICY_SCREEN_OFF: 2296 return "REPORTED_TO_POLICY_SCREEN_OFF"; 2297 case REPORTED_TO_POLICY_SCREEN_TURNING_ON: 2298 return "REPORTED_TO_POLICY_SCREEN_TURNING_ON"; 2299 case REPORTED_TO_POLICY_SCREEN_ON: 2300 return "REPORTED_TO_POLICY_SCREEN_ON"; 2301 default: 2302 return Integer.toString(state); 2303 } 2304 } 2305 skipRampStateToString(int state)2306 private static String skipRampStateToString(int state) { 2307 switch (state) { 2308 case RAMP_STATE_SKIP_NONE: 2309 return "RAMP_STATE_SKIP_NONE"; 2310 case RAMP_STATE_SKIP_INITIAL: 2311 return "RAMP_STATE_SKIP_INITIAL"; 2312 case RAMP_STATE_SKIP_AUTOBRIGHT: 2313 return "RAMP_STATE_SKIP_AUTOBRIGHT"; 2314 default: 2315 return Integer.toString(state); 2316 } 2317 } 2318 clampAbsoluteBrightness(float value)2319 private static float clampAbsoluteBrightness(float value) { 2320 return MathUtils.constrain(value, PowerManager.BRIGHTNESS_MIN, 2321 PowerManager.BRIGHTNESS_MAX); 2322 } 2323 clampAutoBrightnessAdjustment(float value)2324 private static float clampAutoBrightnessAdjustment(float value) { 2325 return MathUtils.constrain(value, -1.0f, 1.0f); 2326 } 2327 noteScreenState(int screenState)2328 private void noteScreenState(int screenState) { 2329 if (mBatteryStats != null) { 2330 try { 2331 // TODO(multi-display): make this multi-display 2332 mBatteryStats.noteScreenState(screenState); 2333 } catch (RemoteException e) { 2334 // same process 2335 } 2336 } 2337 } 2338 noteScreenBrightness(float brightness)2339 private void noteScreenBrightness(float brightness) { 2340 if (mBatteryStats != null) { 2341 try { 2342 // TODO(brightnessfloat): change BatteryStats to use float 2343 mBatteryStats.noteScreenBrightness(BrightnessSynchronizer.brightnessFloatToInt( 2344 brightness)); 2345 } catch (RemoteException e) { 2346 // same process 2347 } 2348 } 2349 } 2350 2351 private final class DisplayControllerHandler extends Handler { DisplayControllerHandler(Looper looper)2352 public DisplayControllerHandler(Looper looper) { 2353 super(looper, null, true /*async*/); 2354 } 2355 2356 @Override handleMessage(Message msg)2357 public void handleMessage(Message msg) { 2358 switch (msg.what) { 2359 case MSG_UPDATE_POWER_STATE: 2360 updatePowerState(); 2361 break; 2362 2363 case MSG_PROXIMITY_SENSOR_DEBOUNCED: 2364 debounceProximitySensor(); 2365 break; 2366 2367 case MSG_SCREEN_ON_UNBLOCKED: 2368 if (mPendingScreenOnUnblocker == msg.obj) { 2369 unblockScreenOn(); 2370 updatePowerState(); 2371 } 2372 break; 2373 case MSG_SCREEN_OFF_UNBLOCKED: 2374 if (mPendingScreenOffUnblocker == msg.obj) { 2375 unblockScreenOff(); 2376 updatePowerState(); 2377 } 2378 break; 2379 case MSG_CONFIGURE_BRIGHTNESS: 2380 mBrightnessConfiguration = (BrightnessConfiguration) msg.obj; 2381 updatePowerState(); 2382 break; 2383 2384 case MSG_SET_TEMPORARY_BRIGHTNESS: 2385 // TODO: Should we have a a timeout for the temporary brightness? 2386 mTemporaryScreenBrightness = Float.intBitsToFloat(msg.arg1); 2387 updatePowerState(); 2388 break; 2389 2390 case MSG_SET_TEMPORARY_AUTO_BRIGHTNESS_ADJUSTMENT: 2391 mTemporaryAutoBrightnessAdjustment = Float.intBitsToFloat(msg.arg1); 2392 updatePowerState(); 2393 break; 2394 2395 case MSG_IGNORE_PROXIMITY: 2396 ignoreProximitySensorUntilChangedInternal(); 2397 break; 2398 2399 case MSG_STOP: 2400 cleanupHandlerThreadAfterStop(); 2401 break; 2402 2403 case MSG_UPDATE_BRIGHTNESS: 2404 if (mStopped) { 2405 return; 2406 } 2407 handleSettingsChange(false /*userSwitch*/); 2408 break; 2409 } 2410 } 2411 } 2412 2413 private final SensorEventListener mProximitySensorListener = new SensorEventListener() { 2414 @Override 2415 public void onSensorChanged(SensorEvent event) { 2416 if (mProximitySensorEnabled) { 2417 final long time = SystemClock.uptimeMillis(); 2418 final float distance = event.values[0]; 2419 boolean positive = distance >= 0.0f && distance < mProximityThreshold; 2420 handleProximitySensorEvent(time, positive); 2421 } 2422 } 2423 2424 @Override 2425 public void onAccuracyChanged(Sensor sensor, int accuracy) { 2426 // Not used. 2427 } 2428 }; 2429 2430 2431 private final class SettingsObserver extends ContentObserver { SettingsObserver(Handler handler)2432 public SettingsObserver(Handler handler) { 2433 super(handler); 2434 } 2435 2436 @Override onChange(boolean selfChange, Uri uri)2437 public void onChange(boolean selfChange, Uri uri) { 2438 handleSettingsChange(false /* userSwitch */); 2439 } 2440 } 2441 2442 private final class ScreenOnUnblocker implements WindowManagerPolicy.ScreenOnListener { 2443 @Override onScreenOn()2444 public void onScreenOn() { 2445 Message msg = mHandler.obtainMessage(MSG_SCREEN_ON_UNBLOCKED, this); 2446 mHandler.sendMessage(msg); 2447 } 2448 } 2449 2450 private final class ScreenOffUnblocker implements WindowManagerPolicy.ScreenOffListener { 2451 @Override onScreenOff()2452 public void onScreenOff() { 2453 Message msg = mHandler.obtainMessage(MSG_SCREEN_OFF_UNBLOCKED, this); 2454 mHandler.sendMessage(msg); 2455 } 2456 } 2457 setAutoBrightnessLoggingEnabled(boolean enabled)2458 void setAutoBrightnessLoggingEnabled(boolean enabled) { 2459 if (mAutomaticBrightnessController != null) { 2460 mAutomaticBrightnessController.setLoggingEnabled(enabled); 2461 } 2462 } 2463 2464 @Override // DisplayWhiteBalanceController.Callbacks updateWhiteBalance()2465 public void updateWhiteBalance() { 2466 sendUpdatePowerState(); 2467 } 2468 setDisplayWhiteBalanceLoggingEnabled(boolean enabled)2469 void setDisplayWhiteBalanceLoggingEnabled(boolean enabled) { 2470 if (mDisplayWhiteBalanceController != null) { 2471 mDisplayWhiteBalanceController.setLoggingEnabled(enabled); 2472 mDisplayWhiteBalanceSettings.setLoggingEnabled(enabled); 2473 } 2474 } 2475 setAmbientColorTemperatureOverride(float cct)2476 void setAmbientColorTemperatureOverride(float cct) { 2477 if (mDisplayWhiteBalanceController != null) { 2478 mDisplayWhiteBalanceController.setAmbientColorTemperatureOverride(cct); 2479 // The ambient color temperature override is only applied when the ambient color 2480 // temperature changes or is updated, so it doesn't necessarily change the screen color 2481 // temperature immediately. So, let's make it! 2482 sendUpdatePowerState(); 2483 } 2484 } 2485 2486 /** 2487 * Stores data about why the brightness was changed. Made up of one main 2488 * {@code BrightnessReason.REASON_*} reason and various {@code BrightnessReason.MODIFIER_*} 2489 * modifiers. 2490 */ 2491 private final class BrightnessReason { 2492 static final int REASON_UNKNOWN = 0; 2493 static final int REASON_MANUAL = 1; 2494 static final int REASON_DOZE = 2; 2495 static final int REASON_DOZE_DEFAULT = 3; 2496 static final int REASON_AUTOMATIC = 4; 2497 static final int REASON_SCREEN_OFF = 5; 2498 static final int REASON_VR = 6; 2499 static final int REASON_OVERRIDE = 7; 2500 static final int REASON_TEMPORARY = 8; 2501 static final int REASON_BOOST = 9; 2502 static final int REASON_MAX = REASON_BOOST; 2503 2504 static final int MODIFIER_DIMMED = 0x1; 2505 static final int MODIFIER_LOW_POWER = 0x2; 2506 static final int MODIFIER_HDR = 0x4; 2507 static final int MODIFIER_MASK = MODIFIER_DIMMED | MODIFIER_LOW_POWER | MODIFIER_HDR; 2508 2509 // ADJUSTMENT_* 2510 // These things can happen at any point, even if the main brightness reason doesn't 2511 // fundamentally change, so they're not stored. 2512 2513 // Auto-brightness adjustment factor changed 2514 static final int ADJUSTMENT_AUTO_TEMP = 0x1; 2515 // Temporary adjustment to the auto-brightness adjustment factor. 2516 static final int ADJUSTMENT_AUTO = 0x2; 2517 2518 // One of REASON_* 2519 public int reason; 2520 // Any number of MODIFIER_* 2521 public int modifier; 2522 set(BrightnessReason other)2523 public void set(BrightnessReason other) { 2524 setReason(other == null ? REASON_UNKNOWN : other.reason); 2525 setModifier(other == null ? 0 : other.modifier); 2526 } 2527 setReason(int reason)2528 public void setReason(int reason) { 2529 if (reason < REASON_UNKNOWN || reason > REASON_MAX) { 2530 Slog.w(TAG, "brightness reason out of bounds: " + reason); 2531 } else { 2532 this.reason = reason; 2533 } 2534 } 2535 setModifier(int modifier)2536 public void setModifier(int modifier) { 2537 if ((modifier & ~MODIFIER_MASK) != 0) { 2538 Slog.w(TAG, "brightness modifier out of bounds: 0x" 2539 + Integer.toHexString(modifier)); 2540 } else { 2541 this.modifier = modifier; 2542 } 2543 } 2544 addModifier(int modifier)2545 public void addModifier(int modifier) { 2546 setModifier(modifier | this.modifier); 2547 } 2548 2549 @Override equals(Object obj)2550 public boolean equals(Object obj) { 2551 if (obj == null || !(obj instanceof BrightnessReason)) { 2552 return false; 2553 } 2554 BrightnessReason other = (BrightnessReason) obj; 2555 return other.reason == reason && other.modifier == modifier; 2556 } 2557 2558 @Override toString()2559 public String toString() { 2560 return toString(0); 2561 } 2562 toString(int adjustments)2563 public String toString(int adjustments) { 2564 final StringBuilder sb = new StringBuilder(); 2565 sb.append(reasonToString(reason)); 2566 sb.append(" ["); 2567 if ((adjustments & ADJUSTMENT_AUTO_TEMP) != 0) { 2568 sb.append(" temp_adj"); 2569 } 2570 if ((adjustments & ADJUSTMENT_AUTO) != 0) { 2571 sb.append(" auto_adj"); 2572 } 2573 if ((modifier & MODIFIER_LOW_POWER) != 0) { 2574 sb.append(" low_pwr"); 2575 } 2576 if ((modifier & MODIFIER_DIMMED) != 0) { 2577 sb.append(" dim"); 2578 } 2579 if ((modifier & MODIFIER_HDR) != 0) { 2580 sb.append(" hdr"); 2581 } 2582 int strlen = sb.length(); 2583 if (sb.charAt(strlen - 1) == '[') { 2584 sb.setLength(strlen - 2); 2585 } else { 2586 sb.append(" ]"); 2587 } 2588 return sb.toString(); 2589 } 2590 reasonToString(int reason)2591 private String reasonToString(int reason) { 2592 switch (reason) { 2593 case REASON_MANUAL: return "manual"; 2594 case REASON_DOZE: return "doze"; 2595 case REASON_DOZE_DEFAULT: return "doze_default"; 2596 case REASON_AUTOMATIC: return "automatic"; 2597 case REASON_SCREEN_OFF: return "screen_off"; 2598 case REASON_VR: return "vr"; 2599 case REASON_OVERRIDE: return "override"; 2600 case REASON_TEMPORARY: return "temporary"; 2601 case REASON_BOOST: return "boost"; 2602 default: return Integer.toString(reason); 2603 } 2604 } 2605 } 2606 2607 static class CachedBrightnessInfo { 2608 public float brightness; 2609 public float brightnessMin; 2610 public float brightnessMax; 2611 public int hbmMode; 2612 } 2613 } 2614