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 com.android.internal.app.IBatteryStats; 20 import com.android.server.LocalServices; 21 import com.android.server.am.BatteryStatsService; 22 23 import android.animation.Animator; 24 import android.animation.ObjectAnimator; 25 import android.content.Context; 26 import android.content.res.Resources; 27 import android.hardware.Sensor; 28 import android.hardware.SensorEvent; 29 import android.hardware.SensorEventListener; 30 import android.hardware.SensorManager; 31 import android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks; 32 import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest; 33 import android.os.Handler; 34 import android.os.Looper; 35 import android.os.Message; 36 import android.os.PowerManager; 37 import android.os.RemoteException; 38 import android.os.SystemClock; 39 import android.os.Trace; 40 import android.util.MathUtils; 41 import android.util.Slog; 42 import android.util.Spline; 43 import android.util.TimeUtils; 44 import android.view.Display; 45 import android.view.WindowManagerPolicy; 46 47 import java.io.PrintWriter; 48 49 /** 50 * Controls the power state of the display. 51 * 52 * Handles the proximity sensor, light sensor, and animations between states 53 * including the screen off animation. 54 * 55 * This component acts independently of the rest of the power manager service. 56 * In particular, it does not share any state and it only communicates 57 * via asynchronous callbacks to inform the power manager that something has 58 * changed. 59 * 60 * Everything this class does internally is serialized on its handler although 61 * it may be accessed by other threads from the outside. 62 * 63 * Note that the power manager service guarantees that it will hold a suspend 64 * blocker as long as the display is not ready. So most of the work done here 65 * does not need to worry about holding a suspend blocker unless it happens 66 * independently of the display ready signal. 67 * 68 * For debugging, you can make the color fade and brightness animations run 69 * slower by changing the "animator duration scale" option in Development Settings. 70 */ 71 final class DisplayPowerController implements AutomaticBrightnessController.Callbacks { 72 private static final String TAG = "DisplayPowerController"; 73 private static final String SCREEN_ON_BLOCKED_TRACE_NAME = "Screen on blocked"; 74 private static final String SCREEN_OFF_BLOCKED_TRACE_NAME = "Screen off blocked"; 75 76 private static final boolean DEBUG = false; 77 private static final boolean DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT = false; 78 79 // If true, uses the color fade on animation. 80 // We might want to turn this off if we cannot get a guarantee that the screen 81 // actually turns on and starts showing new content after the call to set the 82 // screen state returns. Playing the animation can also be somewhat slow. 83 private static final boolean USE_COLOR_FADE_ON_ANIMATION = false; 84 85 // The minimum reduction in brightness when dimmed. 86 private static final int SCREEN_DIM_MINIMUM_REDUCTION = 10; 87 88 private static final int COLOR_FADE_ON_ANIMATION_DURATION_MILLIS = 250; 89 private static final int COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS = 400; 90 91 private static final int MSG_UPDATE_POWER_STATE = 1; 92 private static final int MSG_PROXIMITY_SENSOR_DEBOUNCED = 2; 93 private static final int MSG_SCREEN_ON_UNBLOCKED = 3; 94 private static final int MSG_SCREEN_OFF_UNBLOCKED = 4; 95 96 private static final int PROXIMITY_UNKNOWN = -1; 97 private static final int PROXIMITY_NEGATIVE = 0; 98 private static final int PROXIMITY_POSITIVE = 1; 99 100 // Proximity sensor debounce delay in milliseconds for positive or negative transitions. 101 private static final int PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY = 0; 102 private static final int PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY = 250; 103 104 // Trigger proximity if distance is less than 5 cm. 105 private static final float TYPICAL_PROXIMITY_THRESHOLD = 5.0f; 106 107 // State machine constants for tracking initial brightness ramp skipping when enabled. 108 private static final int RAMP_STATE_SKIP_NONE = 0; 109 private static final int RAMP_STATE_SKIP_INITIAL = 1; 110 private static final int RAMP_STATE_SKIP_AUTOBRIGHT = 2; 111 112 private static final int REPORTED_TO_POLICY_SCREEN_OFF = 0; 113 private static final int REPORTED_TO_POLICY_SCREEN_TURNING_ON = 1; 114 private static final int REPORTED_TO_POLICY_SCREEN_ON = 2; 115 private static final int REPORTED_TO_POLICY_SCREEN_TURNING_OFF = 3; 116 117 private final Object mLock = new Object(); 118 119 private final Context mContext; 120 121 // Our handler. 122 private final DisplayControllerHandler mHandler; 123 124 // Asynchronous callbacks into the power manager service. 125 // Only invoked from the handler thread while no locks are held. 126 private final DisplayPowerCallbacks mCallbacks; 127 128 // Battery stats. 129 private final IBatteryStats mBatteryStats; 130 131 // The sensor manager. 132 private final SensorManager mSensorManager; 133 134 // The window manager policy. 135 private final WindowManagerPolicy mWindowManagerPolicy; 136 137 // The display blanker. 138 private final DisplayBlanker mBlanker; 139 140 // The proximity sensor, or null if not available or needed. 141 private Sensor mProximitySensor; 142 143 // The doze screen brightness. 144 private final int mScreenBrightnessDozeConfig; 145 146 // The dim screen brightness. 147 private final int mScreenBrightnessDimConfig; 148 149 // The minimum screen brightness to use in a very dark room. 150 private final int mScreenBrightnessDarkConfig; 151 152 // The minimum allowed brightness. 153 private final int mScreenBrightnessRangeMinimum; 154 155 // The maximum allowed brightness. 156 private final int mScreenBrightnessRangeMaximum; 157 158 // True if auto-brightness should be used. 159 private boolean mUseSoftwareAutoBrightnessConfig; 160 161 // True if should use light sensor to automatically determine doze screen brightness. 162 private final boolean mAllowAutoBrightnessWhileDozingConfig; 163 164 // True if we should fade the screen while turning it off, false if we should play 165 // a stylish color fade animation instead. 166 private boolean mColorFadeFadesConfig; 167 168 // The pending power request. 169 // Initially null until the first call to requestPowerState. 170 // Guarded by mLock. 171 private DisplayPowerRequest mPendingRequestLocked; 172 173 // True if a request has been made to wait for the proximity sensor to go negative. 174 // Guarded by mLock. 175 private boolean mPendingWaitForNegativeProximityLocked; 176 177 // True if the pending power request or wait for negative proximity flag 178 // has been changed since the last update occurred. 179 // Guarded by mLock. 180 private boolean mPendingRequestChangedLocked; 181 182 // Set to true when the important parts of the pending power request have been applied. 183 // The important parts are mainly the screen state. Brightness changes may occur 184 // concurrently. 185 // Guarded by mLock. 186 private boolean mDisplayReadyLocked; 187 188 // Set to true if a power state update is required. 189 // Guarded by mLock. 190 private boolean mPendingUpdatePowerStateLocked; 191 192 /* The following state must only be accessed by the handler thread. */ 193 194 // The currently requested power state. 195 // The power controller will progressively update its internal state to match 196 // the requested power state. Initially null until the first update. 197 private DisplayPowerRequest mPowerRequest; 198 199 // The current power state. 200 // Must only be accessed on the handler thread. 201 private DisplayPowerState mPowerState; 202 203 // True if the device should wait for negative proximity sensor before 204 // waking up the screen. This is set to false as soon as a negative 205 // proximity sensor measurement is observed or when the device is forced to 206 // go to sleep by the user. While true, the screen remains off. 207 private boolean mWaitingForNegativeProximity; 208 209 // The actual proximity sensor threshold value. 210 private float mProximityThreshold; 211 212 // Set to true if the proximity sensor listener has been registered 213 // with the sensor manager. 214 private boolean mProximitySensorEnabled; 215 216 // The debounced proximity sensor state. 217 private int mProximity = PROXIMITY_UNKNOWN; 218 219 // The raw non-debounced proximity sensor state. 220 private int mPendingProximity = PROXIMITY_UNKNOWN; 221 private long mPendingProximityDebounceTime = -1; // -1 if fully debounced 222 223 // True if the screen was turned off because of the proximity sensor. 224 // When the screen turns on again, we report user activity to the power manager. 225 private boolean mScreenOffBecauseOfProximity; 226 227 // The currently active screen on unblocker. This field is non-null whenever 228 // we are waiting for a callback to release it and unblock the screen. 229 private ScreenOnUnblocker mPendingScreenOnUnblocker; 230 private ScreenOffUnblocker mPendingScreenOffUnblocker; 231 232 // True if we were in the process of turning off the screen. 233 // This allows us to recover more gracefully from situations where we abort 234 // turning off the screen. 235 private boolean mPendingScreenOff; 236 237 // True if we have unfinished business and are holding a suspend blocker. 238 private boolean mUnfinishedBusiness; 239 240 // The elapsed real time when the screen on was blocked. 241 private long mScreenOnBlockStartRealTime; 242 private long mScreenOffBlockStartRealTime; 243 244 // Screen state we reported to policy. Must be one of REPORTED_TO_POLICY_SCREEN_* fields. 245 private int mReportedScreenStateToPolicy; 246 247 // If the last recorded screen state was dozing or not. 248 private boolean mDozing; 249 250 // Remembers whether certain kinds of brightness adjustments 251 // were recently applied so that we can decide how to transition. 252 private boolean mAppliedAutoBrightness; 253 private boolean mAppliedDimming; 254 private boolean mAppliedLowPower; 255 256 // Brightness animation ramp rates in brightness units per second 257 private final int mBrightnessRampRateFast; 258 private final int mBrightnessRampRateSlow; 259 260 // Whether or not to skip the initial brightness ramps into STATE_ON. 261 private final boolean mSkipScreenOnBrightnessRamp; 262 263 // A record of state for skipping brightness ramps. 264 private int mSkipRampState = RAMP_STATE_SKIP_NONE; 265 266 // The first autobrightness value set when entering RAMP_STATE_SKIP_INITIAL. 267 private int mInitialAutoBrightness; 268 269 // The controller for the automatic brightness level. 270 private AutomaticBrightnessController mAutomaticBrightnessController; 271 272 // Animators. 273 private ObjectAnimator mColorFadeOnAnimator; 274 private ObjectAnimator mColorFadeOffAnimator; 275 private RampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator; 276 277 /** 278 * Creates the display power controller. 279 */ 280 public DisplayPowerController(Context context, 281 DisplayPowerCallbacks callbacks, Handler handler, 282 SensorManager sensorManager, DisplayBlanker blanker) { 283 mHandler = new DisplayControllerHandler(handler.getLooper()); 284 mCallbacks = callbacks; 285 286 mBatteryStats = BatteryStatsService.getService(); 287 mSensorManager = sensorManager; 288 mWindowManagerPolicy = LocalServices.getService(WindowManagerPolicy.class); 289 mBlanker = blanker; 290 mContext = context; 291 292 final Resources resources = context.getResources(); 293 final int screenBrightnessSettingMinimum = clampAbsoluteBrightness(resources.getInteger( 294 com.android.internal.R.integer.config_screenBrightnessSettingMinimum)); 295 296 mScreenBrightnessDozeConfig = clampAbsoluteBrightness(resources.getInteger( 297 com.android.internal.R.integer.config_screenBrightnessDoze)); 298 299 mScreenBrightnessDimConfig = clampAbsoluteBrightness(resources.getInteger( 300 com.android.internal.R.integer.config_screenBrightnessDim)); 301 302 mScreenBrightnessDarkConfig = clampAbsoluteBrightness(resources.getInteger( 303 com.android.internal.R.integer.config_screenBrightnessDark)); 304 if (mScreenBrightnessDarkConfig > mScreenBrightnessDimConfig) { 305 Slog.w(TAG, "Expected config_screenBrightnessDark (" 306 + mScreenBrightnessDarkConfig + ") to be less than or equal to " 307 + "config_screenBrightnessDim (" + mScreenBrightnessDimConfig + ")."); 308 } 309 if (mScreenBrightnessDarkConfig > screenBrightnessSettingMinimum) { 310 Slog.w(TAG, "Expected config_screenBrightnessDark (" 311 + mScreenBrightnessDarkConfig + ") to be less than or equal to " 312 + "config_screenBrightnessSettingMinimum (" 313 + screenBrightnessSettingMinimum + ")."); 314 } 315 316 int screenBrightnessRangeMinimum = Math.min(Math.min( 317 screenBrightnessSettingMinimum, mScreenBrightnessDimConfig), 318 mScreenBrightnessDarkConfig); 319 320 mScreenBrightnessRangeMaximum = PowerManager.BRIGHTNESS_ON; 321 322 mUseSoftwareAutoBrightnessConfig = resources.getBoolean( 323 com.android.internal.R.bool.config_automatic_brightness_available); 324 325 mAllowAutoBrightnessWhileDozingConfig = resources.getBoolean( 326 com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing); 327 328 mBrightnessRampRateFast = resources.getInteger( 329 com.android.internal.R.integer.config_brightness_ramp_rate_fast); 330 mBrightnessRampRateSlow = resources.getInteger( 331 com.android.internal.R.integer.config_brightness_ramp_rate_slow); 332 mSkipScreenOnBrightnessRamp = resources.getBoolean( 333 com.android.internal.R.bool.config_skipScreenOnBrightnessRamp); 334 335 int lightSensorRate = resources.getInteger( 336 com.android.internal.R.integer.config_autoBrightnessLightSensorRate); 337 int initialLightSensorRate = resources.getInteger( 338 com.android.internal.R.integer.config_autoBrightnessInitialLightSensorRate); 339 if (initialLightSensorRate == -1) { 340 initialLightSensorRate = lightSensorRate; 341 } else if (initialLightSensorRate > lightSensorRate) { 342 Slog.w(TAG, "Expected config_autoBrightnessInitialLightSensorRate (" 343 + initialLightSensorRate + ") to be less than or equal to " 344 + "config_autoBrightnessLightSensorRate (" + lightSensorRate + ")."); 345 } 346 long brighteningLightDebounce = resources.getInteger( 347 com.android.internal.R.integer.config_autoBrightnessBrighteningLightDebounce); 348 long darkeningLightDebounce = resources.getInteger( 349 com.android.internal.R.integer.config_autoBrightnessDarkeningLightDebounce); 350 boolean autoBrightnessResetAmbientLuxAfterWarmUp = resources.getBoolean( 351 com.android.internal.R.bool.config_autoBrightnessResetAmbientLuxAfterWarmUp); 352 int ambientLightHorizon = resources.getInteger( 353 com.android.internal.R.integer.config_autoBrightnessAmbientLightHorizon); 354 float autoBrightnessAdjustmentMaxGamma = resources.getFraction( 355 com.android.internal.R.fraction.config_autoBrightnessAdjustmentMaxGamma, 356 1, 1); 357 358 int[] brightLevels = resources.getIntArray( 359 com.android.internal.R.array.config_dynamicHysteresisBrightLevels); 360 int[] darkLevels = resources.getIntArray( 361 com.android.internal.R.array.config_dynamicHysteresisDarkLevels); 362 int[] luxLevels = resources.getIntArray( 363 com.android.internal.R.array.config_dynamicHysteresisLuxLevels); 364 HysteresisLevels dynamicHysteresis = new HysteresisLevels( 365 brightLevels, darkLevels, luxLevels); 366 367 if (mUseSoftwareAutoBrightnessConfig) { 368 int[] lux = resources.getIntArray( 369 com.android.internal.R.array.config_autoBrightnessLevels); 370 int[] screenBrightness = resources.getIntArray( 371 com.android.internal.R.array.config_autoBrightnessLcdBacklightValues); 372 int lightSensorWarmUpTimeConfig = resources.getInteger( 373 com.android.internal.R.integer.config_lightSensorWarmupTime); 374 final float dozeScaleFactor = resources.getFraction( 375 com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor, 376 1, 1); 377 378 Spline screenAutoBrightnessSpline = createAutoBrightnessSpline(lux, screenBrightness); 379 if (screenAutoBrightnessSpline == null) { 380 Slog.e(TAG, "Error in config.xml. config_autoBrightnessLcdBacklightValues " 381 + "(size " + screenBrightness.length + ") " 382 + "must be monotic and have exactly one more entry than " 383 + "config_autoBrightnessLevels (size " + lux.length + ") " 384 + "which must be strictly increasing. " 385 + "Auto-brightness will be disabled."); 386 mUseSoftwareAutoBrightnessConfig = false; 387 } else { 388 int bottom = clampAbsoluteBrightness(screenBrightness[0]); 389 if (mScreenBrightnessDarkConfig > bottom) { 390 Slog.w(TAG, "config_screenBrightnessDark (" + mScreenBrightnessDarkConfig 391 + ") should be less than or equal to the first value of " 392 + "config_autoBrightnessLcdBacklightValues (" 393 + bottom + ")."); 394 } 395 if (bottom < screenBrightnessRangeMinimum) { 396 screenBrightnessRangeMinimum = bottom; 397 } 398 mAutomaticBrightnessController = new AutomaticBrightnessController(this, 399 handler.getLooper(), sensorManager, screenAutoBrightnessSpline, 400 lightSensorWarmUpTimeConfig, screenBrightnessRangeMinimum, 401 mScreenBrightnessRangeMaximum, dozeScaleFactor, lightSensorRate, 402 initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce, 403 autoBrightnessResetAmbientLuxAfterWarmUp, ambientLightHorizon, 404 autoBrightnessAdjustmentMaxGamma, dynamicHysteresis); 405 } 406 } 407 408 mScreenBrightnessRangeMinimum = screenBrightnessRangeMinimum; 409 410 mColorFadeFadesConfig = resources.getBoolean( 411 com.android.internal.R.bool.config_animateScreenLights); 412 413 if (!DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) { 414 mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); 415 if (mProximitySensor != null) { 416 mProximityThreshold = Math.min(mProximitySensor.getMaximumRange(), 417 TYPICAL_PROXIMITY_THRESHOLD); 418 } 419 } 420 421 } 422 423 /** 424 * Returns true if the proximity sensor screen-off function is available. 425 */ 426 public boolean isProximitySensorAvailable() { 427 return mProximitySensor != null; 428 } 429 430 /** 431 * Requests a new power state. 432 * The controller makes a copy of the provided object and then 433 * begins adjusting the power state to match what was requested. 434 * 435 * @param request The requested power state. 436 * @param waitForNegativeProximity If true, issues a request to wait for 437 * negative proximity before turning the screen back on, assuming the screen 438 * was turned off by the proximity sensor. 439 * @return True if display is ready, false if there are important changes that must 440 * be made asynchronously (such as turning the screen on), in which case the caller 441 * should grab a wake lock, watch for {@link DisplayPowerCallbacks#onStateChanged()} 442 * then try the request again later until the state converges. 443 */ 444 public boolean requestPowerState(DisplayPowerRequest request, 445 boolean waitForNegativeProximity) { 446 if (DEBUG) { 447 Slog.d(TAG, "requestPowerState: " 448 + request + ", waitForNegativeProximity=" + waitForNegativeProximity); 449 } 450 451 synchronized (mLock) { 452 boolean changed = false; 453 454 if (waitForNegativeProximity 455 && !mPendingWaitForNegativeProximityLocked) { 456 mPendingWaitForNegativeProximityLocked = true; 457 changed = true; 458 } 459 460 if (mPendingRequestLocked == null) { 461 mPendingRequestLocked = new DisplayPowerRequest(request); 462 changed = true; 463 } else if (!mPendingRequestLocked.equals(request)) { 464 mPendingRequestLocked.copyFrom(request); 465 changed = true; 466 } 467 468 if (changed) { 469 mDisplayReadyLocked = false; 470 } 471 472 if (changed && !mPendingRequestChangedLocked) { 473 mPendingRequestChangedLocked = true; 474 sendUpdatePowerStateLocked(); 475 } 476 477 return mDisplayReadyLocked; 478 } 479 } 480 481 private void sendUpdatePowerState() { 482 synchronized (mLock) { 483 sendUpdatePowerStateLocked(); 484 } 485 } 486 487 private void sendUpdatePowerStateLocked() { 488 if (!mPendingUpdatePowerStateLocked) { 489 mPendingUpdatePowerStateLocked = true; 490 Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE); 491 msg.setAsynchronous(true); 492 mHandler.sendMessage(msg); 493 } 494 } 495 496 private void initialize() { 497 // Initialize the power state object for the default display. 498 // In the future, we might manage multiple displays independently. 499 mPowerState = new DisplayPowerState(mBlanker, 500 new ColorFade(Display.DEFAULT_DISPLAY)); 501 502 mColorFadeOnAnimator = ObjectAnimator.ofFloat( 503 mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 0.0f, 1.0f); 504 mColorFadeOnAnimator.setDuration(COLOR_FADE_ON_ANIMATION_DURATION_MILLIS); 505 mColorFadeOnAnimator.addListener(mAnimatorListener); 506 507 mColorFadeOffAnimator = ObjectAnimator.ofFloat( 508 mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 1.0f, 0.0f); 509 mColorFadeOffAnimator.setDuration(COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS); 510 mColorFadeOffAnimator.addListener(mAnimatorListener); 511 512 mScreenBrightnessRampAnimator = new RampAnimator<DisplayPowerState>( 513 mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS); 514 mScreenBrightnessRampAnimator.setListener(mRampAnimatorListener); 515 516 // Initialize screen state for battery stats. 517 try { 518 mBatteryStats.noteScreenState(mPowerState.getScreenState()); 519 mBatteryStats.noteScreenBrightness(mPowerState.getScreenBrightness()); 520 } catch (RemoteException ex) { 521 // same process 522 } 523 } 524 525 private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() { 526 @Override 527 public void onAnimationStart(Animator animation) { 528 } 529 @Override 530 public void onAnimationEnd(Animator animation) { 531 sendUpdatePowerState(); 532 } 533 @Override 534 public void onAnimationRepeat(Animator animation) { 535 } 536 @Override 537 public void onAnimationCancel(Animator animation) { 538 } 539 }; 540 541 private final RampAnimator.Listener mRampAnimatorListener = new RampAnimator.Listener() { 542 @Override 543 public void onAnimationEnd() { 544 sendUpdatePowerState(); 545 } 546 }; 547 548 private void updatePowerState() { 549 // Update the power state request. 550 final boolean mustNotify; 551 boolean mustInitialize = false; 552 boolean autoBrightnessAdjustmentChanged = false; 553 554 synchronized (mLock) { 555 mPendingUpdatePowerStateLocked = false; 556 if (mPendingRequestLocked == null) { 557 return; // wait until first actual power request 558 } 559 560 if (mPowerRequest == null) { 561 mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked); 562 mWaitingForNegativeProximity = mPendingWaitForNegativeProximityLocked; 563 mPendingWaitForNegativeProximityLocked = false; 564 mPendingRequestChangedLocked = false; 565 mustInitialize = true; 566 } else if (mPendingRequestChangedLocked) { 567 autoBrightnessAdjustmentChanged = (mPowerRequest.screenAutoBrightnessAdjustment 568 != mPendingRequestLocked.screenAutoBrightnessAdjustment); 569 mPowerRequest.copyFrom(mPendingRequestLocked); 570 mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked; 571 mPendingWaitForNegativeProximityLocked = false; 572 mPendingRequestChangedLocked = false; 573 mDisplayReadyLocked = false; 574 } 575 576 mustNotify = !mDisplayReadyLocked; 577 } 578 579 // Initialize things the first time the power state is changed. 580 if (mustInitialize) { 581 initialize(); 582 } 583 584 // Compute the basic display state using the policy. 585 // We might override this below based on other factors. 586 int state; 587 int brightness = PowerManager.BRIGHTNESS_DEFAULT; 588 boolean performScreenOffTransition = false; 589 switch (mPowerRequest.policy) { 590 case DisplayPowerRequest.POLICY_OFF: 591 state = Display.STATE_OFF; 592 performScreenOffTransition = true; 593 break; 594 case DisplayPowerRequest.POLICY_DOZE: 595 if (mPowerRequest.dozeScreenState != Display.STATE_UNKNOWN) { 596 state = mPowerRequest.dozeScreenState; 597 } else { 598 state = Display.STATE_DOZE; 599 } 600 if (!mAllowAutoBrightnessWhileDozingConfig) { 601 brightness = mPowerRequest.dozeScreenBrightness; 602 } 603 break; 604 case DisplayPowerRequest.POLICY_VR: 605 state = Display.STATE_VR; 606 break; 607 case DisplayPowerRequest.POLICY_DIM: 608 case DisplayPowerRequest.POLICY_BRIGHT: 609 default: 610 state = Display.STATE_ON; 611 break; 612 } 613 assert(state != Display.STATE_UNKNOWN); 614 615 // Apply the proximity sensor. 616 if (mProximitySensor != null) { 617 if (mPowerRequest.useProximitySensor && state != Display.STATE_OFF) { 618 setProximitySensorEnabled(true); 619 if (!mScreenOffBecauseOfProximity 620 && mProximity == PROXIMITY_POSITIVE) { 621 mScreenOffBecauseOfProximity = true; 622 sendOnProximityPositiveWithWakelock(); 623 } 624 } else if (mWaitingForNegativeProximity 625 && mScreenOffBecauseOfProximity 626 && mProximity == PROXIMITY_POSITIVE 627 && state != Display.STATE_OFF) { 628 setProximitySensorEnabled(true); 629 } else { 630 setProximitySensorEnabled(false); 631 mWaitingForNegativeProximity = false; 632 } 633 if (mScreenOffBecauseOfProximity 634 && mProximity != PROXIMITY_POSITIVE) { 635 mScreenOffBecauseOfProximity = false; 636 sendOnProximityNegativeWithWakelock(); 637 } 638 } else { 639 mWaitingForNegativeProximity = false; 640 } 641 if (mScreenOffBecauseOfProximity) { 642 state = Display.STATE_OFF; 643 } 644 645 // Animate the screen state change unless already animating. 646 // The transition may be deferred, so after this point we will use the 647 // actual state instead of the desired one. 648 final int oldState = mPowerState.getScreenState(); 649 animateScreenStateChange(state, performScreenOffTransition); 650 state = mPowerState.getScreenState(); 651 652 // Use zero brightness when screen is off. 653 if (state == Display.STATE_OFF) { 654 brightness = PowerManager.BRIGHTNESS_OFF; 655 } 656 657 // Configure auto-brightness. 658 boolean autoBrightnessEnabled = false; 659 if (mAutomaticBrightnessController != null) { 660 final boolean autoBrightnessEnabledInDoze = mAllowAutoBrightnessWhileDozingConfig 661 && (state == Display.STATE_DOZE || state == Display.STATE_DOZE_SUSPEND); 662 autoBrightnessEnabled = mPowerRequest.useAutoBrightness 663 && (state == Display.STATE_ON || autoBrightnessEnabledInDoze) 664 && brightness < 0; 665 final boolean userInitiatedChange = autoBrightnessAdjustmentChanged 666 && mPowerRequest.brightnessSetByUser; 667 mAutomaticBrightnessController.configure(autoBrightnessEnabled, 668 mPowerRequest.screenAutoBrightnessAdjustment, state != Display.STATE_ON, 669 userInitiatedChange); 670 } 671 672 // Apply brightness boost. 673 // We do this here after configuring auto-brightness so that we don't 674 // disable the light sensor during this temporary state. That way when 675 // boost ends we will be able to resume normal auto-brightness behavior 676 // without any delay. 677 if (mPowerRequest.boostScreenBrightness 678 && brightness != PowerManager.BRIGHTNESS_OFF) { 679 brightness = PowerManager.BRIGHTNESS_ON; 680 } 681 682 // Apply auto-brightness. 683 boolean slowChange = false; 684 if (brightness < 0) { 685 if (autoBrightnessEnabled) { 686 brightness = mAutomaticBrightnessController.getAutomaticScreenBrightness(); 687 } 688 if (brightness >= 0) { 689 // Use current auto-brightness value and slowly adjust to changes. 690 brightness = clampScreenBrightness(brightness); 691 if (mAppliedAutoBrightness && !autoBrightnessAdjustmentChanged) { 692 slowChange = true; // slowly adapt to auto-brightness 693 } 694 mAppliedAutoBrightness = true; 695 } else { 696 mAppliedAutoBrightness = false; 697 } 698 } else { 699 mAppliedAutoBrightness = false; 700 } 701 702 // Use default brightness when dozing unless overridden. 703 if (brightness < 0 && (state == Display.STATE_DOZE 704 || state == Display.STATE_DOZE_SUSPEND)) { 705 brightness = mScreenBrightnessDozeConfig; 706 } 707 708 // Apply manual brightness. 709 // Use the current brightness setting from the request, which is expected 710 // provide a nominal default value for the case where auto-brightness 711 // is not ready yet. 712 if (brightness < 0) { 713 brightness = clampScreenBrightness(mPowerRequest.screenBrightness); 714 } 715 716 // Apply dimming by at least some minimum amount when user activity 717 // timeout is about to expire. 718 if (mPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) { 719 if (brightness > mScreenBrightnessRangeMinimum) { 720 brightness = Math.max(Math.min(brightness - SCREEN_DIM_MINIMUM_REDUCTION, 721 mScreenBrightnessDimConfig), mScreenBrightnessRangeMinimum); 722 } 723 if (!mAppliedDimming) { 724 slowChange = false; 725 } 726 mAppliedDimming = true; 727 } else if (mAppliedDimming) { 728 slowChange = false; 729 mAppliedDimming = false; 730 } 731 732 // If low power mode is enabled, scale brightness by screenLowPowerBrightnessFactor 733 // as long as it is above the minimum threshold. 734 if (mPowerRequest.lowPowerMode) { 735 if (brightness > mScreenBrightnessRangeMinimum) { 736 final float brightnessFactor = 737 Math.min(mPowerRequest.screenLowPowerBrightnessFactor, 1); 738 final int lowPowerBrightness = (int) (brightness * brightnessFactor); 739 brightness = Math.max(lowPowerBrightness, mScreenBrightnessRangeMinimum); 740 } 741 if (!mAppliedLowPower) { 742 slowChange = false; 743 } 744 mAppliedLowPower = true; 745 } else if (mAppliedLowPower) { 746 slowChange = false; 747 mAppliedLowPower = false; 748 } 749 750 // Animate the screen brightness when the screen is on or dozing. 751 // Skip the animation when the screen is off or suspended or transition to/from VR. 752 if (!mPendingScreenOff) { 753 if (mSkipScreenOnBrightnessRamp) { 754 755 if (state == Display.STATE_ON) { 756 if (mSkipRampState == RAMP_STATE_SKIP_NONE && mDozing) { 757 mInitialAutoBrightness = brightness; 758 mSkipRampState = RAMP_STATE_SKIP_INITIAL; 759 } else if (mSkipRampState == RAMP_STATE_SKIP_INITIAL 760 && mUseSoftwareAutoBrightnessConfig 761 && brightness != mInitialAutoBrightness) { 762 mSkipRampState = RAMP_STATE_SKIP_AUTOBRIGHT; 763 } else if (mSkipRampState == RAMP_STATE_SKIP_AUTOBRIGHT) { 764 mSkipRampState = RAMP_STATE_SKIP_NONE; 765 } 766 } else { 767 mSkipRampState = RAMP_STATE_SKIP_NONE; 768 } 769 } 770 771 boolean wasOrWillBeInVr = (state == Display.STATE_VR || oldState == Display.STATE_VR); 772 if ((state == Display.STATE_ON 773 && mSkipRampState == RAMP_STATE_SKIP_NONE 774 || state == Display.STATE_DOZE) 775 && !wasOrWillBeInVr) { 776 animateScreenBrightness(brightness, 777 slowChange ? mBrightnessRampRateSlow : mBrightnessRampRateFast); 778 } else { 779 animateScreenBrightness(brightness, 0); 780 } 781 } 782 783 // Determine whether the display is ready for use in the newly requested state. 784 // Note that we do not wait for the brightness ramp animation to complete before 785 // reporting the display is ready because we only need to ensure the screen is in the 786 // right power state even as it continues to converge on the desired brightness. 787 final boolean ready = mPendingScreenOnUnblocker == null 788 && !mColorFadeOnAnimator.isStarted() 789 && !mColorFadeOffAnimator.isStarted() 790 && mPowerState.waitUntilClean(mCleanListener); 791 final boolean finished = ready 792 && !mScreenBrightnessRampAnimator.isAnimating(); 793 794 // Notify policy about screen turned on. 795 if (ready && state != Display.STATE_OFF 796 && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_ON) { 797 mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_ON; 798 mWindowManagerPolicy.screenTurnedOn(); 799 } 800 801 // Grab a wake lock if we have unfinished business. 802 if (!finished && !mUnfinishedBusiness) { 803 if (DEBUG) { 804 Slog.d(TAG, "Unfinished business..."); 805 } 806 mCallbacks.acquireSuspendBlocker(); 807 mUnfinishedBusiness = true; 808 } 809 810 // Notify the power manager when ready. 811 if (ready && mustNotify) { 812 // Send state change. 813 synchronized (mLock) { 814 if (!mPendingRequestChangedLocked) { 815 mDisplayReadyLocked = true; 816 817 if (DEBUG) { 818 Slog.d(TAG, "Display ready!"); 819 } 820 } 821 } 822 sendOnStateChangedWithWakelock(); 823 } 824 825 // Release the wake lock when we have no unfinished business. 826 if (finished && mUnfinishedBusiness) { 827 if (DEBUG) { 828 Slog.d(TAG, "Finished business..."); 829 } 830 mUnfinishedBusiness = false; 831 mCallbacks.releaseSuspendBlocker(); 832 } 833 834 // Record if dozing for future comparison. 835 mDozing = state != Display.STATE_ON; 836 } 837 838 @Override 839 public void updateBrightness() { 840 sendUpdatePowerState(); 841 } 842 843 private void blockScreenOn() { 844 if (mPendingScreenOnUnblocker == null) { 845 Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0); 846 mPendingScreenOnUnblocker = new ScreenOnUnblocker(); 847 mScreenOnBlockStartRealTime = SystemClock.elapsedRealtime(); 848 Slog.i(TAG, "Blocking screen on until initial contents have been drawn."); 849 } 850 } 851 852 private void unblockScreenOn() { 853 if (mPendingScreenOnUnblocker != null) { 854 mPendingScreenOnUnblocker = null; 855 long delay = SystemClock.elapsedRealtime() - mScreenOnBlockStartRealTime; 856 Slog.i(TAG, "Unblocked screen on after " + delay + " ms"); 857 Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0); 858 } 859 } 860 861 private void blockScreenOff() { 862 if (mPendingScreenOffUnblocker == null) { 863 Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, SCREEN_OFF_BLOCKED_TRACE_NAME, 0); 864 mPendingScreenOffUnblocker = new ScreenOffUnblocker(); 865 mScreenOffBlockStartRealTime = SystemClock.elapsedRealtime(); 866 Slog.i(TAG, "Blocking screen off"); 867 } 868 } 869 870 private void unblockScreenOff() { 871 if (mPendingScreenOffUnblocker != null) { 872 mPendingScreenOffUnblocker = null; 873 long delay = SystemClock.elapsedRealtime() - mScreenOffBlockStartRealTime; 874 Slog.i(TAG, "Unblocked screen off after " + delay + " ms"); 875 Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, SCREEN_OFF_BLOCKED_TRACE_NAME, 0); 876 } 877 } 878 879 private boolean setScreenState(int state) { 880 final boolean isOff = (state == Display.STATE_OFF); 881 if (mPowerState.getScreenState() != state) { 882 883 // If we are trying to turn screen off, give policy a chance to do something before we 884 // actually turn the screen off. 885 if (isOff && !mScreenOffBecauseOfProximity) { 886 if (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_ON) { 887 mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_TURNING_OFF; 888 blockScreenOff(); 889 mWindowManagerPolicy.screenTurningOff(mPendingScreenOffUnblocker); 890 return false; 891 } else if (mPendingScreenOffUnblocker != null) { 892 893 // Abort doing the state change until screen off is unblocked. 894 return false; 895 } 896 } 897 898 mPowerState.setScreenState(state); 899 900 // Tell battery stats about the transition. 901 try { 902 mBatteryStats.noteScreenState(state); 903 } catch (RemoteException ex) { 904 // same process 905 } 906 } 907 908 // Tell the window manager policy when the screen is turned off or on unless it's due 909 // to the proximity sensor. We temporarily block turning the screen on until the 910 // window manager is ready by leaving a black surface covering the screen. 911 // This surface is essentially the final state of the color fade animation and 912 // it is only removed once the window manager tells us that the activity has 913 // finished drawing underneath. 914 if (isOff && mReportedScreenStateToPolicy != REPORTED_TO_POLICY_SCREEN_OFF 915 && !mScreenOffBecauseOfProximity) { 916 mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_OFF; 917 unblockScreenOn(); 918 mWindowManagerPolicy.screenTurnedOff(); 919 } else if (!isOff 920 && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_OFF) { 921 922 // We told policy already that screen was turning off, but now we changed our minds. 923 // Complete the full state transition on -> turningOff -> off. 924 unblockScreenOff(); 925 mWindowManagerPolicy.screenTurnedOff(); 926 mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_OFF; 927 } 928 if (!isOff && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF) { 929 mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_TURNING_ON; 930 if (mPowerState.getColorFadeLevel() == 0.0f) { 931 blockScreenOn(); 932 } else { 933 unblockScreenOn(); 934 } 935 mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker); 936 } 937 938 // Return true if the screen isn't blocked. 939 return mPendingScreenOnUnblocker == null; 940 } 941 942 private int clampScreenBrightness(int value) { 943 return MathUtils.constrain( 944 value, mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum); 945 } 946 947 private void animateScreenBrightness(int target, int rate) { 948 if (DEBUG) { 949 Slog.d(TAG, "Animating brightness: target=" + target +", rate=" + rate); 950 } 951 if (mScreenBrightnessRampAnimator.animateTo(target, rate)) { 952 try { 953 mBatteryStats.noteScreenBrightness(target); 954 } catch (RemoteException ex) { 955 // same process 956 } 957 } 958 } 959 960 private void animateScreenStateChange(int target, boolean performScreenOffTransition) { 961 // If there is already an animation in progress, don't interfere with it. 962 if (mColorFadeOnAnimator.isStarted() 963 || mColorFadeOffAnimator.isStarted()) { 964 if (target != Display.STATE_ON) { 965 return; 966 } 967 // If display state changed to on, proceed and stop the color fade and turn screen on. 968 mPendingScreenOff = false; 969 } 970 971 // If we were in the process of turning off the screen but didn't quite 972 // finish. Then finish up now to prevent a jarring transition back 973 // to screen on if we skipped blocking screen on as usual. 974 if (mPendingScreenOff && target != Display.STATE_OFF) { 975 setScreenState(Display.STATE_OFF); 976 mPendingScreenOff = false; 977 mPowerState.dismissColorFadeResources(); 978 } 979 980 if (target == Display.STATE_ON) { 981 // Want screen on. The contents of the screen may not yet 982 // be visible if the color fade has not been dismissed because 983 // its last frame of animation is solid black. 984 if (!setScreenState(Display.STATE_ON)) { 985 return; // screen on blocked 986 } 987 if (USE_COLOR_FADE_ON_ANIMATION && mPowerRequest.isBrightOrDim()) { 988 // Perform screen on animation. 989 if (mPowerState.getColorFadeLevel() == 1.0f) { 990 mPowerState.dismissColorFade(); 991 } else if (mPowerState.prepareColorFade(mContext, 992 mColorFadeFadesConfig ? 993 ColorFade.MODE_FADE : 994 ColorFade.MODE_WARM_UP)) { 995 mColorFadeOnAnimator.start(); 996 } else { 997 mColorFadeOnAnimator.end(); 998 } 999 } else { 1000 // Skip screen on animation. 1001 mPowerState.setColorFadeLevel(1.0f); 1002 mPowerState.dismissColorFade(); 1003 } 1004 } else if (target == Display.STATE_VR) { 1005 // Wait for brightness animation to complete beforehand when entering VR 1006 // from screen on to prevent a perceptible jump because brightness may operate 1007 // differently when the display is configured for dozing. 1008 if (mScreenBrightnessRampAnimator.isAnimating() 1009 && mPowerState.getScreenState() == Display.STATE_ON) { 1010 return; 1011 } 1012 1013 // Set screen state. 1014 if (!setScreenState(Display.STATE_VR)) { 1015 return; // screen on blocked 1016 } 1017 1018 // Dismiss the black surface without fanfare. 1019 mPowerState.setColorFadeLevel(1.0f); 1020 mPowerState.dismissColorFade(); 1021 } else if (target == Display.STATE_DOZE) { 1022 // Want screen dozing. 1023 // Wait for brightness animation to complete beforehand when entering doze 1024 // from screen on to prevent a perceptible jump because brightness may operate 1025 // differently when the display is configured for dozing. 1026 if (mScreenBrightnessRampAnimator.isAnimating() 1027 && mPowerState.getScreenState() == Display.STATE_ON) { 1028 return; 1029 } 1030 1031 // Set screen state. 1032 if (!setScreenState(Display.STATE_DOZE)) { 1033 return; // screen on blocked 1034 } 1035 1036 // Dismiss the black surface without fanfare. 1037 mPowerState.setColorFadeLevel(1.0f); 1038 mPowerState.dismissColorFade(); 1039 } else if (target == Display.STATE_DOZE_SUSPEND) { 1040 // Want screen dozing and suspended. 1041 // Wait for brightness animation to complete beforehand unless already 1042 // suspended because we may not be able to change it after suspension. 1043 if (mScreenBrightnessRampAnimator.isAnimating() 1044 && mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) { 1045 return; 1046 } 1047 1048 // If not already suspending, temporarily set the state to doze until the 1049 // screen on is unblocked, then suspend. 1050 if (mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) { 1051 if (!setScreenState(Display.STATE_DOZE)) { 1052 return; // screen on blocked 1053 } 1054 setScreenState(Display.STATE_DOZE_SUSPEND); // already on so can't block 1055 } 1056 1057 // Dismiss the black surface without fanfare. 1058 mPowerState.setColorFadeLevel(1.0f); 1059 mPowerState.dismissColorFade(); 1060 } else { 1061 // Want screen off. 1062 mPendingScreenOff = true; 1063 if (mPowerState.getColorFadeLevel() == 0.0f) { 1064 // Turn the screen off. 1065 // A black surface is already hiding the contents of the screen. 1066 setScreenState(Display.STATE_OFF); 1067 mPendingScreenOff = false; 1068 mPowerState.dismissColorFadeResources(); 1069 } else if (performScreenOffTransition 1070 && mPowerState.prepareColorFade(mContext, 1071 mColorFadeFadesConfig ? 1072 ColorFade.MODE_FADE : ColorFade.MODE_COOL_DOWN) 1073 && mPowerState.getScreenState() != Display.STATE_OFF) { 1074 // Perform the screen off animation. 1075 mColorFadeOffAnimator.start(); 1076 } else { 1077 // Skip the screen off animation and add a black surface to hide the 1078 // contents of the screen. 1079 mColorFadeOffAnimator.end(); 1080 } 1081 } 1082 } 1083 1084 private final Runnable mCleanListener = new Runnable() { 1085 @Override 1086 public void run() { 1087 sendUpdatePowerState(); 1088 } 1089 }; 1090 1091 private void setProximitySensorEnabled(boolean enable) { 1092 if (enable) { 1093 if (!mProximitySensorEnabled) { 1094 // Register the listener. 1095 // Proximity sensor state already cleared initially. 1096 mProximitySensorEnabled = true; 1097 mSensorManager.registerListener(mProximitySensorListener, mProximitySensor, 1098 SensorManager.SENSOR_DELAY_NORMAL, mHandler); 1099 } 1100 } else { 1101 if (mProximitySensorEnabled) { 1102 // Unregister the listener. 1103 // Clear the proximity sensor state for next time. 1104 mProximitySensorEnabled = false; 1105 mProximity = PROXIMITY_UNKNOWN; 1106 mPendingProximity = PROXIMITY_UNKNOWN; 1107 mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED); 1108 mSensorManager.unregisterListener(mProximitySensorListener); 1109 clearPendingProximityDebounceTime(); // release wake lock (must be last) 1110 } 1111 } 1112 } 1113 1114 private void handleProximitySensorEvent(long time, boolean positive) { 1115 if (mProximitySensorEnabled) { 1116 if (mPendingProximity == PROXIMITY_NEGATIVE && !positive) { 1117 return; // no change 1118 } 1119 if (mPendingProximity == PROXIMITY_POSITIVE && positive) { 1120 return; // no change 1121 } 1122 1123 // Only accept a proximity sensor reading if it remains 1124 // stable for the entire debounce delay. We hold a wake lock while 1125 // debouncing the sensor. 1126 mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED); 1127 if (positive) { 1128 mPendingProximity = PROXIMITY_POSITIVE; 1129 setPendingProximityDebounceTime( 1130 time + PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY); // acquire wake lock 1131 } else { 1132 mPendingProximity = PROXIMITY_NEGATIVE; 1133 setPendingProximityDebounceTime( 1134 time + PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY); // acquire wake lock 1135 } 1136 1137 // Debounce the new sensor reading. 1138 debounceProximitySensor(); 1139 } 1140 } 1141 1142 private void debounceProximitySensor() { 1143 if (mProximitySensorEnabled 1144 && mPendingProximity != PROXIMITY_UNKNOWN 1145 && mPendingProximityDebounceTime >= 0) { 1146 final long now = SystemClock.uptimeMillis(); 1147 if (mPendingProximityDebounceTime <= now) { 1148 // Sensor reading accepted. Apply the change then release the wake lock. 1149 mProximity = mPendingProximity; 1150 updatePowerState(); 1151 clearPendingProximityDebounceTime(); // release wake lock (must be last) 1152 } else { 1153 // Need to wait a little longer. 1154 // Debounce again later. We continue holding a wake lock while waiting. 1155 Message msg = mHandler.obtainMessage(MSG_PROXIMITY_SENSOR_DEBOUNCED); 1156 msg.setAsynchronous(true); 1157 mHandler.sendMessageAtTime(msg, mPendingProximityDebounceTime); 1158 } 1159 } 1160 } 1161 1162 private void clearPendingProximityDebounceTime() { 1163 if (mPendingProximityDebounceTime >= 0) { 1164 mPendingProximityDebounceTime = -1; 1165 mCallbacks.releaseSuspendBlocker(); // release wake lock 1166 } 1167 } 1168 1169 private void setPendingProximityDebounceTime(long debounceTime) { 1170 if (mPendingProximityDebounceTime < 0) { 1171 mCallbacks.acquireSuspendBlocker(); // acquire wake lock 1172 } 1173 mPendingProximityDebounceTime = debounceTime; 1174 } 1175 1176 private void sendOnStateChangedWithWakelock() { 1177 mCallbacks.acquireSuspendBlocker(); 1178 mHandler.post(mOnStateChangedRunnable); 1179 } 1180 1181 private final Runnable mOnStateChangedRunnable = new Runnable() { 1182 @Override 1183 public void run() { 1184 mCallbacks.onStateChanged(); 1185 mCallbacks.releaseSuspendBlocker(); 1186 } 1187 }; 1188 1189 private void sendOnProximityPositiveWithWakelock() { 1190 mCallbacks.acquireSuspendBlocker(); 1191 mHandler.post(mOnProximityPositiveRunnable); 1192 } 1193 1194 private final Runnable mOnProximityPositiveRunnable = new Runnable() { 1195 @Override 1196 public void run() { 1197 mCallbacks.onProximityPositive(); 1198 mCallbacks.releaseSuspendBlocker(); 1199 } 1200 }; 1201 1202 private void sendOnProximityNegativeWithWakelock() { 1203 mCallbacks.acquireSuspendBlocker(); 1204 mHandler.post(mOnProximityNegativeRunnable); 1205 } 1206 1207 private final Runnable mOnProximityNegativeRunnable = new Runnable() { 1208 @Override 1209 public void run() { 1210 mCallbacks.onProximityNegative(); 1211 mCallbacks.releaseSuspendBlocker(); 1212 } 1213 }; 1214 1215 public void dump(final PrintWriter pw) { 1216 synchronized (mLock) { 1217 pw.println(); 1218 pw.println("Display Power Controller Locked State:"); 1219 pw.println(" mDisplayReadyLocked=" + mDisplayReadyLocked); 1220 pw.println(" mPendingRequestLocked=" + mPendingRequestLocked); 1221 pw.println(" mPendingRequestChangedLocked=" + mPendingRequestChangedLocked); 1222 pw.println(" mPendingWaitForNegativeProximityLocked=" 1223 + mPendingWaitForNegativeProximityLocked); 1224 pw.println(" mPendingUpdatePowerStateLocked=" + mPendingUpdatePowerStateLocked); 1225 } 1226 1227 pw.println(); 1228 pw.println("Display Power Controller Configuration:"); 1229 pw.println(" mScreenBrightnessDozeConfig=" + mScreenBrightnessDozeConfig); 1230 pw.println(" mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig); 1231 pw.println(" mScreenBrightnessDarkConfig=" + mScreenBrightnessDarkConfig); 1232 pw.println(" mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum); 1233 pw.println(" mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum); 1234 pw.println(" mUseSoftwareAutoBrightnessConfig=" + mUseSoftwareAutoBrightnessConfig); 1235 pw.println(" mAllowAutoBrightnessWhileDozingConfig=" + 1236 mAllowAutoBrightnessWhileDozingConfig); 1237 pw.println(" mColorFadeFadesConfig=" + mColorFadeFadesConfig); 1238 1239 mHandler.runWithScissors(new Runnable() { 1240 @Override 1241 public void run() { 1242 dumpLocal(pw); 1243 } 1244 }, 1000); 1245 } 1246 1247 private void dumpLocal(PrintWriter pw) { 1248 pw.println(); 1249 pw.println("Display Power Controller Thread State:"); 1250 pw.println(" mPowerRequest=" + mPowerRequest); 1251 pw.println(" mWaitingForNegativeProximity=" + mWaitingForNegativeProximity); 1252 1253 pw.println(" mProximitySensor=" + mProximitySensor); 1254 pw.println(" mProximitySensorEnabled=" + mProximitySensorEnabled); 1255 pw.println(" mProximityThreshold=" + mProximityThreshold); 1256 pw.println(" mProximity=" + proximityToString(mProximity)); 1257 pw.println(" mPendingProximity=" + proximityToString(mPendingProximity)); 1258 pw.println(" mPendingProximityDebounceTime=" 1259 + TimeUtils.formatUptime(mPendingProximityDebounceTime)); 1260 pw.println(" mScreenOffBecauseOfProximity=" + mScreenOffBecauseOfProximity); 1261 pw.println(" mAppliedAutoBrightness=" + mAppliedAutoBrightness); 1262 pw.println(" mAppliedDimming=" + mAppliedDimming); 1263 pw.println(" mAppliedLowPower=" + mAppliedLowPower); 1264 pw.println(" mPendingScreenOnUnblocker=" + mPendingScreenOnUnblocker); 1265 pw.println(" mPendingScreenOff=" + mPendingScreenOff); 1266 pw.println(" mReportedToPolicy=" + reportedToPolicyToString(mReportedScreenStateToPolicy)); 1267 1268 pw.println(" mScreenBrightnessRampAnimator.isAnimating()=" + 1269 mScreenBrightnessRampAnimator.isAnimating()); 1270 1271 if (mColorFadeOnAnimator != null) { 1272 pw.println(" mColorFadeOnAnimator.isStarted()=" + 1273 mColorFadeOnAnimator.isStarted()); 1274 } 1275 if (mColorFadeOffAnimator != null) { 1276 pw.println(" mColorFadeOffAnimator.isStarted()=" + 1277 mColorFadeOffAnimator.isStarted()); 1278 } 1279 1280 if (mPowerState != null) { 1281 mPowerState.dump(pw); 1282 } 1283 1284 if (mAutomaticBrightnessController != null) { 1285 mAutomaticBrightnessController.dump(pw); 1286 } 1287 1288 } 1289 1290 private static String proximityToString(int state) { 1291 switch (state) { 1292 case PROXIMITY_UNKNOWN: 1293 return "Unknown"; 1294 case PROXIMITY_NEGATIVE: 1295 return "Negative"; 1296 case PROXIMITY_POSITIVE: 1297 return "Positive"; 1298 default: 1299 return Integer.toString(state); 1300 } 1301 } 1302 1303 private static String reportedToPolicyToString(int state) { 1304 switch (state) { 1305 case REPORTED_TO_POLICY_SCREEN_OFF: 1306 return "REPORTED_TO_POLICY_SCREEN_OFF"; 1307 case REPORTED_TO_POLICY_SCREEN_TURNING_ON: 1308 return "REPORTED_TO_POLICY_SCREEN_TURNING_ON"; 1309 case REPORTED_TO_POLICY_SCREEN_ON: 1310 return "REPORTED_TO_POLICY_SCREEN_ON"; 1311 default: 1312 return Integer.toString(state); 1313 } 1314 } 1315 1316 private static Spline createAutoBrightnessSpline(int[] lux, int[] brightness) { 1317 if (lux == null || lux.length == 0 || brightness == null || brightness.length == 0) { 1318 Slog.e(TAG, "Could not create auto-brightness spline."); 1319 return null; 1320 } 1321 try { 1322 final int n = brightness.length; 1323 float[] x = new float[n]; 1324 float[] y = new float[n]; 1325 y[0] = normalizeAbsoluteBrightness(brightness[0]); 1326 for (int i = 1; i < n; i++) { 1327 x[i] = lux[i - 1]; 1328 y[i] = normalizeAbsoluteBrightness(brightness[i]); 1329 } 1330 1331 Spline spline = Spline.createSpline(x, y); 1332 if (DEBUG) { 1333 Slog.d(TAG, "Auto-brightness spline: " + spline); 1334 for (float v = 1f; v < lux[lux.length - 1] * 1.25f; v *= 1.25f) { 1335 Slog.d(TAG, String.format(" %7.1f: %7.1f", v, spline.interpolate(v))); 1336 } 1337 } 1338 return spline; 1339 } catch (IllegalArgumentException ex) { 1340 Slog.e(TAG, "Could not create auto-brightness spline.", ex); 1341 return null; 1342 } 1343 } 1344 1345 private static float normalizeAbsoluteBrightness(int value) { 1346 return (float)clampAbsoluteBrightness(value) / PowerManager.BRIGHTNESS_ON; 1347 } 1348 1349 private static int clampAbsoluteBrightness(int value) { 1350 return MathUtils.constrain(value, PowerManager.BRIGHTNESS_OFF, PowerManager.BRIGHTNESS_ON); 1351 } 1352 1353 private final class DisplayControllerHandler extends Handler { 1354 public DisplayControllerHandler(Looper looper) { 1355 super(looper, null, true /*async*/); 1356 } 1357 1358 @Override 1359 public void handleMessage(Message msg) { 1360 switch (msg.what) { 1361 case MSG_UPDATE_POWER_STATE: 1362 updatePowerState(); 1363 break; 1364 1365 case MSG_PROXIMITY_SENSOR_DEBOUNCED: 1366 debounceProximitySensor(); 1367 break; 1368 1369 case MSG_SCREEN_ON_UNBLOCKED: 1370 if (mPendingScreenOnUnblocker == msg.obj) { 1371 unblockScreenOn(); 1372 updatePowerState(); 1373 } 1374 break; 1375 case MSG_SCREEN_OFF_UNBLOCKED: 1376 if (mPendingScreenOffUnblocker == msg.obj) { 1377 unblockScreenOff(); 1378 updatePowerState(); 1379 } 1380 break; 1381 } 1382 } 1383 } 1384 1385 private final SensorEventListener mProximitySensorListener = new SensorEventListener() { 1386 @Override 1387 public void onSensorChanged(SensorEvent event) { 1388 if (mProximitySensorEnabled) { 1389 final long time = SystemClock.uptimeMillis(); 1390 final float distance = event.values[0]; 1391 boolean positive = distance >= 0.0f && distance < mProximityThreshold; 1392 handleProximitySensorEvent(time, positive); 1393 } 1394 } 1395 1396 @Override 1397 public void onAccuracyChanged(Sensor sensor, int accuracy) { 1398 // Not used. 1399 } 1400 }; 1401 1402 private final class ScreenOnUnblocker implements WindowManagerPolicy.ScreenOnListener { 1403 @Override 1404 public void onScreenOn() { 1405 Message msg = mHandler.obtainMessage(MSG_SCREEN_ON_UNBLOCKED, this); 1406 msg.setAsynchronous(true); 1407 mHandler.sendMessage(msg); 1408 } 1409 } 1410 1411 private final class ScreenOffUnblocker implements WindowManagerPolicy.ScreenOffListener { 1412 1413 @Override 1414 public void onScreenOff() { 1415 Message msg = mHandler.obtainMessage(MSG_SCREEN_OFF_UNBLOCKED, this); 1416 msg.setAsynchronous(true); 1417 mHandler.sendMessage(msg); 1418 } 1419 } 1420 } 1421