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