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