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