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.power; 18 19 import com.android.server.LightsService; 20 import com.android.server.TwilightService; 21 import com.android.server.TwilightService.TwilightState; 22 import com.android.server.display.DisplayManagerService; 23 24 import android.animation.Animator; 25 import android.animation.ObjectAnimator; 26 import android.content.Context; 27 import android.content.res.Resources; 28 import android.hardware.Sensor; 29 import android.hardware.SensorEvent; 30 import android.hardware.SensorEventListener; 31 import android.hardware.SensorManager; 32 import android.hardware.SystemSensorManager; 33 import android.os.Handler; 34 import android.os.Looper; 35 import android.os.Message; 36 import android.os.PowerManager; 37 import android.os.SystemClock; 38 import android.text.format.DateUtils; 39 import android.util.FloatMath; 40 import android.util.Slog; 41 import android.util.Spline; 42 import android.util.TimeUtils; 43 44 import java.io.PrintWriter; 45 46 /** 47 * Controls the power state of the display. 48 * 49 * Handles the proximity sensor, light sensor, and animations between states 50 * including the screen off animation. 51 * 52 * This component acts independently of the rest of the power manager service. 53 * In particular, it does not share any state and it only communicates 54 * via asynchronous callbacks to inform the power manager that something has 55 * changed. 56 * 57 * Everything this class does internally is serialized on its handler although 58 * it may be accessed by other threads from the outside. 59 * 60 * Note that the power manager service guarantees that it will hold a suspend 61 * blocker as long as the display is not ready. So most of the work done here 62 * does not need to worry about holding a suspend blocker unless it happens 63 * independently of the display ready signal. 64 * 65 * For debugging, you can make the electron beam and brightness animations run 66 * slower by changing the "animator duration scale" option in Development Settings. 67 */ 68 final class DisplayPowerController { 69 private static final String TAG = "DisplayPowerController"; 70 71 private static boolean DEBUG = false; 72 private static final boolean DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT = false; 73 private static final boolean DEBUG_PRETEND_LIGHT_SENSOR_ABSENT = false; 74 75 // If true, uses the electron beam on animation. 76 // We might want to turn this off if we cannot get a guarantee that the screen 77 // actually turns on and starts showing new content after the call to set the 78 // screen state returns. Playing the animation can also be somewhat slow. 79 private static final boolean USE_ELECTRON_BEAM_ON_ANIMATION = false; 80 81 // If true, enables the use of the screen auto-brightness adjustment setting. 82 private static final boolean USE_SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT = 83 PowerManager.useScreenAutoBrightnessAdjustmentFeature(); 84 85 // The maximum range of gamma adjustment possible using the screen 86 // auto-brightness adjustment setting. 87 private static final float SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT_MAX_GAMMA = 3.0f; 88 89 // The minimum reduction in brightness when dimmed. 90 private static final int SCREEN_DIM_MINIMUM_REDUCTION = 10; 91 92 // If true, enables the use of the current time as an auto-brightness adjustment. 93 // The basic idea here is to expand the dynamic range of auto-brightness 94 // when it is especially dark outside. The light sensor tends to perform 95 // poorly at low light levels so we compensate for it by making an 96 // assumption about the environment. 97 private static final boolean USE_TWILIGHT_ADJUSTMENT = 98 PowerManager.useTwilightAdjustmentFeature(); 99 100 // Specifies the maximum magnitude of the time of day adjustment. 101 private static final float TWILIGHT_ADJUSTMENT_MAX_GAMMA = 1.5f; 102 103 // The amount of time after or before sunrise over which to start adjusting 104 // the gamma. We want the change to happen gradually so that it is below the 105 // threshold of perceptibility and so that the adjustment has maximum effect 106 // well after dusk. 107 private static final long TWILIGHT_ADJUSTMENT_TIME = DateUtils.HOUR_IN_MILLIS * 2; 108 109 private static final int ELECTRON_BEAM_ON_ANIMATION_DURATION_MILLIS = 250; 110 private static final int ELECTRON_BEAM_OFF_ANIMATION_DURATION_MILLIS = 400; 111 112 private static final int MSG_UPDATE_POWER_STATE = 1; 113 private static final int MSG_PROXIMITY_SENSOR_DEBOUNCED = 2; 114 private static final int MSG_LIGHT_SENSOR_DEBOUNCED = 3; 115 116 private static final int PROXIMITY_UNKNOWN = -1; 117 private static final int PROXIMITY_NEGATIVE = 0; 118 private static final int PROXIMITY_POSITIVE = 1; 119 120 // Proximity sensor debounce delay in milliseconds for positive or negative transitions. 121 private static final int PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY = 0; 122 private static final int PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY = 500; 123 124 // Trigger proximity if distance is less than 5 cm. 125 private static final float TYPICAL_PROXIMITY_THRESHOLD = 5.0f; 126 127 // Light sensor event rate in milliseconds. 128 private static final int LIGHT_SENSOR_RATE_MILLIS = 1000; 129 130 // A rate for generating synthetic light sensor events in the case where the light 131 // sensor hasn't reported any new data in a while and we need it to update the 132 // debounce filter. We only synthesize light sensor measurements when needed. 133 private static final int SYNTHETIC_LIGHT_SENSOR_RATE_MILLIS = 134 LIGHT_SENSOR_RATE_MILLIS * 2; 135 136 // Brightness animation ramp rate in brightness units per second. 137 private static final int BRIGHTNESS_RAMP_RATE_FAST = 200; 138 private static final int BRIGHTNESS_RAMP_RATE_SLOW = 40; 139 140 // IIR filter time constants in milliseconds for computing two moving averages of 141 // the light samples. One is a long-term average and the other is a short-term average. 142 // We can use these filters to assess trends in ambient brightness. 143 // The short term average gives us a filtered but relatively low latency measurement. 144 // The long term average informs us about the overall trend. 145 private static final long SHORT_TERM_AVERAGE_LIGHT_TIME_CONSTANT = 1000; 146 private static final long LONG_TERM_AVERAGE_LIGHT_TIME_CONSTANT = 5000; 147 148 // Stability requirements in milliseconds for accepting a new brightness 149 // level. This is used for debouncing the light sensor. Different constants 150 // are used to debounce the light sensor when adapting to brighter or darker environments. 151 // This parameter controls how quickly brightness changes occur in response to 152 // an observed change in light level that exceeds the hysteresis threshold. 153 private static final long BRIGHTENING_LIGHT_DEBOUNCE = 4000; 154 private static final long DARKENING_LIGHT_DEBOUNCE = 8000; 155 156 // Hysteresis constraints for brightening or darkening. 157 // The recent lux must have changed by at least this fraction relative to the 158 // current ambient lux before a change will be considered. 159 private static final float BRIGHTENING_LIGHT_HYSTERESIS = 0.10f; 160 private static final float DARKENING_LIGHT_HYSTERESIS = 0.20f; 161 162 private final Object mLock = new Object(); 163 164 // Notifier for sending asynchronous notifications. 165 private final Notifier mNotifier; 166 167 // The display blanker. 168 private final DisplayBlanker mDisplayBlanker; 169 170 // Our handler. 171 private final DisplayControllerHandler mHandler; 172 173 // Asynchronous callbacks into the power manager service. 174 // Only invoked from the handler thread while no locks are held. 175 private final Callbacks mCallbacks; 176 private Handler mCallbackHandler; 177 178 // The lights service. 179 private final LightsService mLights; 180 181 // The twilight service. 182 private final TwilightService mTwilight; 183 184 // The display manager. 185 private final DisplayManagerService mDisplayManager; 186 187 // The sensor manager. 188 private final SensorManager mSensorManager; 189 190 // The proximity sensor, or null if not available or needed. 191 private Sensor mProximitySensor; 192 193 // The light sensor, or null if not available or needed. 194 private Sensor mLightSensor; 195 196 // The dim screen brightness. 197 private final int mScreenBrightnessDimConfig; 198 199 // The minimum allowed brightness. 200 private final int mScreenBrightnessRangeMinimum; 201 202 // The maximum allowed brightness. 203 private final int mScreenBrightnessRangeMaximum; 204 205 // True if auto-brightness should be used. 206 private boolean mUseSoftwareAutoBrightnessConfig; 207 208 // The auto-brightness spline adjustment. 209 // The brightness values have been scaled to a range of 0..1. 210 private Spline mScreenAutoBrightnessSpline; 211 212 // Amount of time to delay auto-brightness after screen on while waiting for 213 // the light sensor to warm-up in milliseconds. 214 // May be 0 if no warm-up is required. 215 private int mLightSensorWarmUpTimeConfig; 216 217 // True if we should fade the screen while turning it off, false if we should play 218 // a stylish electron beam animation instead. 219 private boolean mElectronBeamFadesConfig; 220 221 // The pending power request. 222 // Initially null until the first call to requestPowerState. 223 // Guarded by mLock. 224 private DisplayPowerRequest mPendingRequestLocked; 225 226 // True if a request has been made to wait for the proximity sensor to go negative. 227 // Guarded by mLock. 228 private boolean mPendingWaitForNegativeProximityLocked; 229 230 // True if the pending power request or wait for negative proximity flag 231 // has been changed since the last update occurred. 232 // Guarded by mLock. 233 private boolean mPendingRequestChangedLocked; 234 235 // Set to true when the important parts of the pending power request have been applied. 236 // The important parts are mainly the screen state. Brightness changes may occur 237 // concurrently. 238 // Guarded by mLock. 239 private boolean mDisplayReadyLocked; 240 241 // Set to true if a power state update is required. 242 // Guarded by mLock. 243 private boolean mPendingUpdatePowerStateLocked; 244 245 /* The following state must only be accessed by the handler thread. */ 246 247 // The currently requested power state. 248 // The power controller will progressively update its internal state to match 249 // the requested power state. Initially null until the first update. 250 private DisplayPowerRequest mPowerRequest; 251 252 // The current power state. 253 // Must only be accessed on the handler thread. 254 private DisplayPowerState mPowerState; 255 256 // True if the device should wait for negative proximity sensor before 257 // waking up the screen. This is set to false as soon as a negative 258 // proximity sensor measurement is observed or when the device is forced to 259 // go to sleep by the user. While true, the screen remains off. 260 private boolean mWaitingForNegativeProximity; 261 262 // The actual proximity sensor threshold value. 263 private float mProximityThreshold; 264 265 // Set to true if the proximity sensor listener has been registered 266 // with the sensor manager. 267 private boolean mProximitySensorEnabled; 268 269 // The debounced proximity sensor state. 270 private int mProximity = PROXIMITY_UNKNOWN; 271 272 // The raw non-debounced proximity sensor state. 273 private int mPendingProximity = PROXIMITY_UNKNOWN; 274 private long mPendingProximityDebounceTime; 275 276 // True if the screen was turned off because of the proximity sensor. 277 // When the screen turns on again, we report user activity to the power manager. 278 private boolean mScreenOffBecauseOfProximity; 279 280 // True if the screen on is being blocked. 281 private boolean mScreenOnWasBlocked; 282 283 // The elapsed real time when the screen on was blocked. 284 private long mScreenOnBlockStartRealTime; 285 286 // Set to true if the light sensor is enabled. 287 private boolean mLightSensorEnabled; 288 289 // The time when the light sensor was enabled. 290 private long mLightSensorEnableTime; 291 292 // The currently accepted nominal ambient light level. 293 private float mAmbientLux; 294 295 // True if mAmbientLux holds a valid value. 296 private boolean mAmbientLuxValid; 297 298 // The most recent light sample. 299 private float mLastObservedLux; 300 301 // The time of the most light recent sample. 302 private long mLastObservedLuxTime; 303 304 // The number of light samples collected since the light sensor was enabled. 305 private int mRecentLightSamples; 306 307 // The long-term and short-term filtered light measurements. 308 private float mRecentShortTermAverageLux; 309 private float mRecentLongTermAverageLux; 310 311 // The direction in which the average lux is moving relative to the current ambient lux. 312 // 0 if not changing or within hysteresis threshold. 313 // 1 if brightening beyond hysteresis threshold. 314 // -1 if darkening beyond hysteresis threshold. 315 private int mDebounceLuxDirection; 316 317 // The time when the average lux last changed direction. 318 private long mDebounceLuxTime; 319 320 // The screen brightness level that has been chosen by the auto-brightness 321 // algorithm. The actual brightness should ramp towards this value. 322 // We preserve this value even when we stop using the light sensor so 323 // that we can quickly revert to the previous auto-brightness level 324 // while the light sensor warms up. 325 // Use -1 if there is no current auto-brightness value available. 326 private int mScreenAutoBrightness = -1; 327 328 // The last screen auto-brightness gamma. (For printing in dump() only.) 329 private float mLastScreenAutoBrightnessGamma = 1.0f; 330 331 // True if the screen auto-brightness value is actually being used to 332 // set the display brightness. 333 private boolean mUsingScreenAutoBrightness; 334 335 // Animators. 336 private ObjectAnimator mElectronBeamOnAnimator; 337 private ObjectAnimator mElectronBeamOffAnimator; 338 private RampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator; 339 340 // Twilight changed. We might recalculate auto-brightness values. 341 private boolean mTwilightChanged; 342 343 /** 344 * Creates the display power controller. 345 */ DisplayPowerController(Looper looper, Context context, Notifier notifier, LightsService lights, TwilightService twilight, SensorManager sensorManager, DisplayManagerService displayManager, DisplayBlanker displayBlanker, Callbacks callbacks, Handler callbackHandler)346 public DisplayPowerController(Looper looper, Context context, Notifier notifier, 347 LightsService lights, TwilightService twilight, SensorManager sensorManager, 348 DisplayManagerService displayManager, 349 DisplayBlanker displayBlanker, 350 Callbacks callbacks, Handler callbackHandler) { 351 mHandler = new DisplayControllerHandler(looper); 352 mNotifier = notifier; 353 mDisplayBlanker = displayBlanker; 354 mCallbacks = callbacks; 355 mCallbackHandler = callbackHandler; 356 357 mLights = lights; 358 mTwilight = twilight; 359 mSensorManager = sensorManager; 360 mDisplayManager = displayManager; 361 362 final Resources resources = context.getResources(); 363 364 mScreenBrightnessDimConfig = clampAbsoluteBrightness(resources.getInteger( 365 com.android.internal.R.integer.config_screenBrightnessDim)); 366 367 int screenBrightnessMinimum = Math.min(resources.getInteger( 368 com.android.internal.R.integer.config_screenBrightnessSettingMinimum), 369 mScreenBrightnessDimConfig); 370 371 mUseSoftwareAutoBrightnessConfig = resources.getBoolean( 372 com.android.internal.R.bool.config_automatic_brightness_available); 373 if (mUseSoftwareAutoBrightnessConfig) { 374 int[] lux = resources.getIntArray( 375 com.android.internal.R.array.config_autoBrightnessLevels); 376 int[] screenBrightness = resources.getIntArray( 377 com.android.internal.R.array.config_autoBrightnessLcdBacklightValues); 378 379 mScreenAutoBrightnessSpline = createAutoBrightnessSpline(lux, screenBrightness); 380 if (mScreenAutoBrightnessSpline == null) { 381 Slog.e(TAG, "Error in config.xml. config_autoBrightnessLcdBacklightValues " 382 + "(size " + screenBrightness.length + ") " 383 + "must be monotic and have exactly one more entry than " 384 + "config_autoBrightnessLevels (size " + lux.length + ") " 385 + "which must be strictly increasing. " 386 + "Auto-brightness will be disabled."); 387 mUseSoftwareAutoBrightnessConfig = false; 388 } else { 389 if (screenBrightness[0] < screenBrightnessMinimum) { 390 screenBrightnessMinimum = screenBrightness[0]; 391 } 392 } 393 394 mLightSensorWarmUpTimeConfig = resources.getInteger( 395 com.android.internal.R.integer.config_lightSensorWarmupTime); 396 } 397 398 mScreenBrightnessRangeMinimum = clampAbsoluteBrightness(screenBrightnessMinimum); 399 mScreenBrightnessRangeMaximum = PowerManager.BRIGHTNESS_ON; 400 401 mElectronBeamFadesConfig = resources.getBoolean( 402 com.android.internal.R.bool.config_animateScreenLights); 403 404 if (!DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) { 405 mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); 406 if (mProximitySensor != null) { 407 mProximityThreshold = Math.min(mProximitySensor.getMaximumRange(), 408 TYPICAL_PROXIMITY_THRESHOLD); 409 } 410 } 411 412 if (mUseSoftwareAutoBrightnessConfig 413 && !DEBUG_PRETEND_LIGHT_SENSOR_ABSENT) { 414 mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); 415 } 416 417 if (mUseSoftwareAutoBrightnessConfig && USE_TWILIGHT_ADJUSTMENT) { 418 mTwilight.registerListener(mTwilightListener, mHandler); 419 } 420 } 421 createAutoBrightnessSpline(int[] lux, int[] brightness)422 private static Spline createAutoBrightnessSpline(int[] lux, int[] brightness) { 423 try { 424 final int n = brightness.length; 425 float[] x = new float[n]; 426 float[] y = new float[n]; 427 y[0] = normalizeAbsoluteBrightness(brightness[0]); 428 for (int i = 1; i < n; i++) { 429 x[i] = lux[i - 1]; 430 y[i] = normalizeAbsoluteBrightness(brightness[i]); 431 } 432 433 Spline spline = Spline.createMonotoneCubicSpline(x, y); 434 if (DEBUG) { 435 Slog.d(TAG, "Auto-brightness spline: " + spline); 436 for (float v = 1f; v < lux[lux.length - 1] * 1.25f; v *= 1.25f) { 437 Slog.d(TAG, String.format(" %7.1f: %7.1f", v, spline.interpolate(v))); 438 } 439 } 440 return spline; 441 } catch (IllegalArgumentException ex) { 442 Slog.e(TAG, "Could not create auto-brightness spline.", ex); 443 return null; 444 } 445 } 446 447 /** 448 * Returns true if the proximity sensor screen-off function is available. 449 */ isProximitySensorAvailable()450 public boolean isProximitySensorAvailable() { 451 return mProximitySensor != null; 452 } 453 454 /** 455 * Requests a new power state. 456 * The controller makes a copy of the provided object and then 457 * begins adjusting the power state to match what was requested. 458 * 459 * @param request The requested power state. 460 * @param waitForNegativeProximity If true, issues a request to wait for 461 * negative proximity before turning the screen back on, assuming the screen 462 * was turned off by the proximity sensor. 463 * @return True if display is ready, false if there are important changes that must 464 * be made asynchronously (such as turning the screen on), in which case the caller 465 * should grab a wake lock, watch for {@link Callbacks#onStateChanged()} then try 466 * the request again later until the state converges. 467 */ requestPowerState(DisplayPowerRequest request, boolean waitForNegativeProximity)468 public boolean requestPowerState(DisplayPowerRequest request, 469 boolean waitForNegativeProximity) { 470 if (DEBUG) { 471 Slog.d(TAG, "requestPowerState: " 472 + request + ", waitForNegativeProximity=" + waitForNegativeProximity); 473 } 474 475 synchronized (mLock) { 476 boolean changed = false; 477 478 if (waitForNegativeProximity 479 && !mPendingWaitForNegativeProximityLocked) { 480 mPendingWaitForNegativeProximityLocked = true; 481 changed = true; 482 } 483 484 if (mPendingRequestLocked == null) { 485 mPendingRequestLocked = new DisplayPowerRequest(request); 486 changed = true; 487 } else if (!mPendingRequestLocked.equals(request)) { 488 mPendingRequestLocked.copyFrom(request); 489 changed = true; 490 } 491 492 if (changed) { 493 mDisplayReadyLocked = false; 494 } 495 496 if (changed && !mPendingRequestChangedLocked) { 497 mPendingRequestChangedLocked = true; 498 sendUpdatePowerStateLocked(); 499 } 500 501 return mDisplayReadyLocked; 502 } 503 } 504 sendUpdatePowerState()505 private void sendUpdatePowerState() { 506 synchronized (mLock) { 507 sendUpdatePowerStateLocked(); 508 } 509 } 510 sendUpdatePowerStateLocked()511 private void sendUpdatePowerStateLocked() { 512 if (!mPendingUpdatePowerStateLocked) { 513 mPendingUpdatePowerStateLocked = true; 514 Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE); 515 msg.setAsynchronous(true); 516 mHandler.sendMessage(msg); 517 } 518 } 519 initialize()520 private void initialize() { 521 mPowerState = new DisplayPowerState( 522 new ElectronBeam(mDisplayManager), mDisplayBlanker, 523 mLights.getLight(LightsService.LIGHT_ID_BACKLIGHT)); 524 525 mElectronBeamOnAnimator = ObjectAnimator.ofFloat( 526 mPowerState, DisplayPowerState.ELECTRON_BEAM_LEVEL, 0.0f, 1.0f); 527 mElectronBeamOnAnimator.setDuration(ELECTRON_BEAM_ON_ANIMATION_DURATION_MILLIS); 528 mElectronBeamOnAnimator.addListener(mAnimatorListener); 529 530 mElectronBeamOffAnimator = ObjectAnimator.ofFloat( 531 mPowerState, DisplayPowerState.ELECTRON_BEAM_LEVEL, 1.0f, 0.0f); 532 mElectronBeamOffAnimator.setDuration(ELECTRON_BEAM_OFF_ANIMATION_DURATION_MILLIS); 533 mElectronBeamOffAnimator.addListener(mAnimatorListener); 534 535 mScreenBrightnessRampAnimator = new RampAnimator<DisplayPowerState>( 536 mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS); 537 } 538 539 private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() { 540 @Override 541 public void onAnimationStart(Animator animation) { 542 } 543 @Override 544 public void onAnimationEnd(Animator animation) { 545 sendUpdatePowerState(); 546 } 547 @Override 548 public void onAnimationRepeat(Animator animation) { 549 } 550 @Override 551 public void onAnimationCancel(Animator animation) { 552 } 553 }; 554 updatePowerState()555 private void updatePowerState() { 556 // Update the power state request. 557 final boolean mustNotify; 558 boolean mustInitialize = false; 559 boolean updateAutoBrightness = mTwilightChanged; 560 boolean wasDim = false; 561 mTwilightChanged = false; 562 563 synchronized (mLock) { 564 mPendingUpdatePowerStateLocked = false; 565 if (mPendingRequestLocked == null) { 566 return; // wait until first actual power request 567 } 568 569 if (mPowerRequest == null) { 570 mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked); 571 mWaitingForNegativeProximity = mPendingWaitForNegativeProximityLocked; 572 mPendingWaitForNegativeProximityLocked = false; 573 mPendingRequestChangedLocked = false; 574 mustInitialize = true; 575 } else if (mPendingRequestChangedLocked) { 576 if (mPowerRequest.screenAutoBrightnessAdjustment 577 != mPendingRequestLocked.screenAutoBrightnessAdjustment) { 578 updateAutoBrightness = true; 579 } 580 wasDim = (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DIM); 581 mPowerRequest.copyFrom(mPendingRequestLocked); 582 mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked; 583 mPendingWaitForNegativeProximityLocked = false; 584 mPendingRequestChangedLocked = false; 585 mDisplayReadyLocked = false; 586 } 587 588 mustNotify = !mDisplayReadyLocked; 589 } 590 591 // Initialize things the first time the power state is changed. 592 if (mustInitialize) { 593 initialize(); 594 } 595 596 // Apply the proximity sensor. 597 if (mProximitySensor != null) { 598 if (mPowerRequest.useProximitySensor 599 && mPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF) { 600 setProximitySensorEnabled(true); 601 if (!mScreenOffBecauseOfProximity 602 && mProximity == PROXIMITY_POSITIVE) { 603 mScreenOffBecauseOfProximity = true; 604 sendOnProximityPositive(); 605 setScreenOn(false); 606 } 607 } else if (mWaitingForNegativeProximity 608 && mScreenOffBecauseOfProximity 609 && mProximity == PROXIMITY_POSITIVE 610 && mPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF) { 611 setProximitySensorEnabled(true); 612 } else { 613 setProximitySensorEnabled(false); 614 mWaitingForNegativeProximity = false; 615 } 616 if (mScreenOffBecauseOfProximity 617 && mProximity != PROXIMITY_POSITIVE) { 618 mScreenOffBecauseOfProximity = false; 619 sendOnProximityNegative(); 620 } 621 } else { 622 mWaitingForNegativeProximity = false; 623 } 624 625 // Turn on the light sensor if needed. 626 if (mLightSensor != null) { 627 setLightSensorEnabled(mPowerRequest.useAutoBrightness 628 && wantScreenOn(mPowerRequest.screenState), updateAutoBrightness); 629 } 630 631 // Set the screen brightness. 632 if (wantScreenOn(mPowerRequest.screenState)) { 633 int target; 634 boolean slow; 635 if (mScreenAutoBrightness >= 0 && mLightSensorEnabled) { 636 // Use current auto-brightness value. 637 target = mScreenAutoBrightness; 638 slow = mUsingScreenAutoBrightness; 639 mUsingScreenAutoBrightness = true; 640 } else { 641 // Light sensor is disabled or not ready yet. 642 // Use the current brightness setting from the request, which is expected 643 // provide a nominal default value for the case where auto-brightness 644 // is not ready yet. 645 target = mPowerRequest.screenBrightness; 646 slow = false; 647 mUsingScreenAutoBrightness = false; 648 } 649 if (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DIM) { 650 // Dim quickly by at least some minimum amount. 651 target = Math.min(target - SCREEN_DIM_MINIMUM_REDUCTION, 652 mScreenBrightnessDimConfig); 653 slow = false; 654 } else if (wasDim) { 655 // Brighten quickly. 656 slow = false; 657 } 658 animateScreenBrightness(clampScreenBrightness(target), 659 slow ? BRIGHTNESS_RAMP_RATE_SLOW : BRIGHTNESS_RAMP_RATE_FAST); 660 } else { 661 // Screen is off. Don't bother changing the brightness. 662 mUsingScreenAutoBrightness = false; 663 } 664 665 // Animate the screen on or off. 666 if (!mScreenOffBecauseOfProximity) { 667 if (wantScreenOn(mPowerRequest.screenState)) { 668 // Want screen on. 669 // Wait for previous off animation to complete beforehand. 670 // It is relatively short but if we cancel it and switch to the 671 // on animation immediately then the results are pretty ugly. 672 if (!mElectronBeamOffAnimator.isStarted()) { 673 // Turn the screen on. The contents of the screen may not yet 674 // be visible if the electron beam has not been dismissed because 675 // its last frame of animation is solid black. 676 setScreenOn(true); 677 678 if (mPowerRequest.blockScreenOn 679 && mPowerState.getElectronBeamLevel() == 0.0f) { 680 blockScreenOn(); 681 } else { 682 unblockScreenOn(); 683 if (USE_ELECTRON_BEAM_ON_ANIMATION) { 684 if (!mElectronBeamOnAnimator.isStarted()) { 685 if (mPowerState.getElectronBeamLevel() == 1.0f) { 686 mPowerState.dismissElectronBeam(); 687 } else if (mPowerState.prepareElectronBeam( 688 mElectronBeamFadesConfig ? 689 ElectronBeam.MODE_FADE : 690 ElectronBeam.MODE_WARM_UP)) { 691 mElectronBeamOnAnimator.start(); 692 } else { 693 mElectronBeamOnAnimator.end(); 694 } 695 } 696 } else { 697 mPowerState.setElectronBeamLevel(1.0f); 698 mPowerState.dismissElectronBeam(); 699 } 700 } 701 } 702 } else { 703 // Want screen off. 704 // Wait for previous on animation to complete beforehand. 705 if (!mElectronBeamOnAnimator.isStarted()) { 706 if (!mElectronBeamOffAnimator.isStarted()) { 707 if (mPowerState.getElectronBeamLevel() == 0.0f) { 708 setScreenOn(false); 709 } else if (mPowerState.prepareElectronBeam( 710 mElectronBeamFadesConfig ? 711 ElectronBeam.MODE_FADE : 712 ElectronBeam.MODE_COOL_DOWN) 713 && mPowerState.isScreenOn()) { 714 mElectronBeamOffAnimator.start(); 715 } else { 716 mElectronBeamOffAnimator.end(); 717 } 718 } 719 } 720 } 721 } 722 723 // Report whether the display is ready for use. 724 // We mostly care about the screen state here, ignoring brightness changes 725 // which will be handled asynchronously. 726 if (mustNotify 727 && !mScreenOnWasBlocked 728 && !mElectronBeamOnAnimator.isStarted() 729 && !mElectronBeamOffAnimator.isStarted() 730 && mPowerState.waitUntilClean(mCleanListener)) { 731 synchronized (mLock) { 732 if (!mPendingRequestChangedLocked) { 733 mDisplayReadyLocked = true; 734 735 if (DEBUG) { 736 Slog.d(TAG, "Display ready!"); 737 } 738 } 739 } 740 sendOnStateChanged(); 741 } 742 } 743 blockScreenOn()744 private void blockScreenOn() { 745 if (!mScreenOnWasBlocked) { 746 mScreenOnWasBlocked = true; 747 if (DEBUG) { 748 Slog.d(TAG, "Blocked screen on."); 749 mScreenOnBlockStartRealTime = SystemClock.elapsedRealtime(); 750 } 751 } 752 } 753 unblockScreenOn()754 private void unblockScreenOn() { 755 if (mScreenOnWasBlocked) { 756 mScreenOnWasBlocked = false; 757 if (DEBUG) { 758 Slog.d(TAG, "Unblocked screen on after " + 759 (SystemClock.elapsedRealtime() - mScreenOnBlockStartRealTime) + " ms"); 760 } 761 } 762 } 763 setScreenOn(boolean on)764 private void setScreenOn(boolean on) { 765 if (!mPowerState.isScreenOn() == on) { 766 mPowerState.setScreenOn(on); 767 if (on) { 768 mNotifier.onScreenOn(); 769 } else { 770 mNotifier.onScreenOff(); 771 } 772 } 773 } 774 clampScreenBrightness(int value)775 private int clampScreenBrightness(int value) { 776 return clamp(value, mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum); 777 } 778 clampAbsoluteBrightness(int value)779 private static int clampAbsoluteBrightness(int value) { 780 return clamp(value, PowerManager.BRIGHTNESS_OFF, PowerManager.BRIGHTNESS_ON); 781 } 782 clamp(int value, int min, int max)783 private static int clamp(int value, int min, int max) { 784 if (value <= min) { 785 return min; 786 } 787 if (value >= max) { 788 return max; 789 } 790 return value; 791 } 792 normalizeAbsoluteBrightness(int value)793 private static float normalizeAbsoluteBrightness(int value) { 794 return (float)clampAbsoluteBrightness(value) / PowerManager.BRIGHTNESS_ON; 795 } 796 animateScreenBrightness(int target, int rate)797 private void animateScreenBrightness(int target, int rate) { 798 if (mScreenBrightnessRampAnimator.animateTo(target, rate)) { 799 mNotifier.onScreenBrightness(target); 800 } 801 } 802 803 private final Runnable mCleanListener = new Runnable() { 804 @Override 805 public void run() { 806 sendUpdatePowerState(); 807 } 808 }; 809 setProximitySensorEnabled(boolean enable)810 private void setProximitySensorEnabled(boolean enable) { 811 if (enable) { 812 if (!mProximitySensorEnabled) { 813 mProximitySensorEnabled = true; 814 mPendingProximity = PROXIMITY_UNKNOWN; 815 mSensorManager.registerListener(mProximitySensorListener, mProximitySensor, 816 SensorManager.SENSOR_DELAY_NORMAL, mHandler); 817 } 818 } else { 819 if (mProximitySensorEnabled) { 820 mProximitySensorEnabled = false; 821 mProximity = PROXIMITY_UNKNOWN; 822 mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED); 823 mSensorManager.unregisterListener(mProximitySensorListener); 824 } 825 } 826 } 827 handleProximitySensorEvent(long time, boolean positive)828 private void handleProximitySensorEvent(long time, boolean positive) { 829 if (mPendingProximity == PROXIMITY_NEGATIVE && !positive) { 830 return; // no change 831 } 832 if (mPendingProximity == PROXIMITY_POSITIVE && positive) { 833 return; // no change 834 } 835 836 // Only accept a proximity sensor reading if it remains 837 // stable for the entire debounce delay. 838 mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED); 839 if (positive) { 840 mPendingProximity = PROXIMITY_POSITIVE; 841 mPendingProximityDebounceTime = time + PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY; 842 } else { 843 mPendingProximity = PROXIMITY_NEGATIVE; 844 mPendingProximityDebounceTime = time + PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY; 845 } 846 debounceProximitySensor(); 847 } 848 debounceProximitySensor()849 private void debounceProximitySensor() { 850 if (mPendingProximity != PROXIMITY_UNKNOWN) { 851 final long now = SystemClock.uptimeMillis(); 852 if (mPendingProximityDebounceTime <= now) { 853 mProximity = mPendingProximity; 854 sendUpdatePowerState(); 855 } else { 856 Message msg = mHandler.obtainMessage(MSG_PROXIMITY_SENSOR_DEBOUNCED); 857 msg.setAsynchronous(true); 858 mHandler.sendMessageAtTime(msg, mPendingProximityDebounceTime); 859 } 860 } 861 } 862 setLightSensorEnabled(boolean enable, boolean updateAutoBrightness)863 private void setLightSensorEnabled(boolean enable, boolean updateAutoBrightness) { 864 if (enable) { 865 if (!mLightSensorEnabled) { 866 updateAutoBrightness = true; 867 mLightSensorEnabled = true; 868 mLightSensorEnableTime = SystemClock.uptimeMillis(); 869 mSensorManager.registerListener(mLightSensorListener, mLightSensor, 870 LIGHT_SENSOR_RATE_MILLIS * 1000, mHandler); 871 } 872 } else { 873 if (mLightSensorEnabled) { 874 mLightSensorEnabled = false; 875 mAmbientLuxValid = false; 876 mRecentLightSamples = 0; 877 mHandler.removeMessages(MSG_LIGHT_SENSOR_DEBOUNCED); 878 mSensorManager.unregisterListener(mLightSensorListener); 879 } 880 } 881 if (updateAutoBrightness) { 882 updateAutoBrightness(false); 883 } 884 } 885 handleLightSensorEvent(long time, float lux)886 private void handleLightSensorEvent(long time, float lux) { 887 mHandler.removeMessages(MSG_LIGHT_SENSOR_DEBOUNCED); 888 889 applyLightSensorMeasurement(time, lux); 890 updateAmbientLux(time); 891 } 892 applyLightSensorMeasurement(long time, float lux)893 private void applyLightSensorMeasurement(long time, float lux) { 894 // Update our filters. 895 mRecentLightSamples += 1; 896 if (mRecentLightSamples == 1) { 897 mRecentShortTermAverageLux = lux; 898 mRecentLongTermAverageLux = lux; 899 } else { 900 final long timeDelta = time - mLastObservedLuxTime; 901 mRecentShortTermAverageLux += (lux - mRecentShortTermAverageLux) 902 * timeDelta / (SHORT_TERM_AVERAGE_LIGHT_TIME_CONSTANT + timeDelta); 903 mRecentLongTermAverageLux += (lux - mRecentLongTermAverageLux) 904 * timeDelta / (LONG_TERM_AVERAGE_LIGHT_TIME_CONSTANT + timeDelta); 905 } 906 907 // Remember this sample value. 908 mLastObservedLux = lux; 909 mLastObservedLuxTime = time; 910 } 911 updateAmbientLux(long time)912 private void updateAmbientLux(long time) { 913 // If the light sensor was just turned on then immediately update our initial 914 // estimate of the current ambient light level. 915 if (!mAmbientLuxValid 916 || (time - mLightSensorEnableTime) < mLightSensorWarmUpTimeConfig) { 917 mAmbientLux = mRecentShortTermAverageLux; 918 mAmbientLuxValid = true; 919 mDebounceLuxDirection = 0; 920 mDebounceLuxTime = time; 921 if (DEBUG) { 922 Slog.d(TAG, "updateAmbientLux: Initializing: " 923 + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux 924 + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux 925 + ", mAmbientLux=" + mAmbientLux); 926 } 927 updateAutoBrightness(true); 928 return; 929 } 930 931 // Determine whether the ambient environment appears to be brightening. 932 float brighteningLuxThreshold = mAmbientLux * (1.0f + BRIGHTENING_LIGHT_HYSTERESIS); 933 if (mRecentShortTermAverageLux > brighteningLuxThreshold 934 && mRecentLongTermAverageLux > brighteningLuxThreshold) { 935 if (mDebounceLuxDirection <= 0) { 936 mDebounceLuxDirection = 1; 937 mDebounceLuxTime = time; 938 if (DEBUG) { 939 Slog.d(TAG, "updateAmbientLux: Possibly brightened, waiting for " 940 + BRIGHTENING_LIGHT_DEBOUNCE + " ms: " 941 + "brighteningLuxThreshold=" + brighteningLuxThreshold 942 + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux 943 + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux 944 + ", mAmbientLux=" + mAmbientLux); 945 } 946 } 947 long debounceTime = mDebounceLuxTime + BRIGHTENING_LIGHT_DEBOUNCE; 948 if (time >= debounceTime) { 949 mAmbientLux = mRecentShortTermAverageLux; 950 if (DEBUG) { 951 Slog.d(TAG, "updateAmbientLux: Brightened: " 952 + "brighteningLuxThreshold=" + brighteningLuxThreshold 953 + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux 954 + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux 955 + ", mAmbientLux=" + mAmbientLux); 956 } 957 updateAutoBrightness(true); 958 } else { 959 mHandler.sendEmptyMessageAtTime(MSG_LIGHT_SENSOR_DEBOUNCED, debounceTime); 960 } 961 return; 962 } 963 964 // Determine whether the ambient environment appears to be darkening. 965 float darkeningLuxThreshold = mAmbientLux * (1.0f - DARKENING_LIGHT_HYSTERESIS); 966 if (mRecentShortTermAverageLux < darkeningLuxThreshold 967 && mRecentLongTermAverageLux < darkeningLuxThreshold) { 968 if (mDebounceLuxDirection >= 0) { 969 mDebounceLuxDirection = -1; 970 mDebounceLuxTime = time; 971 if (DEBUG) { 972 Slog.d(TAG, "updateAmbientLux: Possibly darkened, waiting for " 973 + DARKENING_LIGHT_DEBOUNCE + " ms: " 974 + "darkeningLuxThreshold=" + darkeningLuxThreshold 975 + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux 976 + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux 977 + ", mAmbientLux=" + mAmbientLux); 978 } 979 } 980 long debounceTime = mDebounceLuxTime + DARKENING_LIGHT_DEBOUNCE; 981 if (time >= debounceTime) { 982 // Be conservative about reducing the brightness, only reduce it a little bit 983 // at a time to avoid having to bump it up again soon. 984 mAmbientLux = Math.max(mRecentShortTermAverageLux, mRecentLongTermAverageLux); 985 if (DEBUG) { 986 Slog.d(TAG, "updateAmbientLux: Darkened: " 987 + "darkeningLuxThreshold=" + darkeningLuxThreshold 988 + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux 989 + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux 990 + ", mAmbientLux=" + mAmbientLux); 991 } 992 updateAutoBrightness(true); 993 } else { 994 mHandler.sendEmptyMessageAtTime(MSG_LIGHT_SENSOR_DEBOUNCED, debounceTime); 995 } 996 return; 997 } 998 999 // No change or change is within the hysteresis thresholds. 1000 if (mDebounceLuxDirection != 0) { 1001 mDebounceLuxDirection = 0; 1002 mDebounceLuxTime = time; 1003 if (DEBUG) { 1004 Slog.d(TAG, "updateAmbientLux: Canceled debounce: " 1005 + "brighteningLuxThreshold=" + brighteningLuxThreshold 1006 + ", darkeningLuxThreshold=" + darkeningLuxThreshold 1007 + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux 1008 + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux 1009 + ", mAmbientLux=" + mAmbientLux); 1010 } 1011 } 1012 1013 // If the light level does not change, then the sensor may not report 1014 // a new value. This can cause problems for the auto-brightness algorithm 1015 // because the filters might not be updated. To work around it, we want to 1016 // make sure to update the filters whenever the observed light level could 1017 // possibly exceed one of the hysteresis thresholds. 1018 if (mLastObservedLux > brighteningLuxThreshold 1019 || mLastObservedLux < darkeningLuxThreshold) { 1020 mHandler.sendEmptyMessageAtTime(MSG_LIGHT_SENSOR_DEBOUNCED, 1021 time + SYNTHETIC_LIGHT_SENSOR_RATE_MILLIS); 1022 } 1023 } 1024 debounceLightSensor()1025 private void debounceLightSensor() { 1026 if (mLightSensorEnabled) { 1027 long time = SystemClock.uptimeMillis(); 1028 if (time >= mLastObservedLuxTime + SYNTHETIC_LIGHT_SENSOR_RATE_MILLIS) { 1029 if (DEBUG) { 1030 Slog.d(TAG, "debounceLightSensor: Synthesizing light sensor measurement " 1031 + "after " + (time - mLastObservedLuxTime) + " ms."); 1032 } 1033 applyLightSensorMeasurement(time, mLastObservedLux); 1034 } 1035 updateAmbientLux(time); 1036 } 1037 } 1038 updateAutoBrightness(boolean sendUpdate)1039 private void updateAutoBrightness(boolean sendUpdate) { 1040 if (!mAmbientLuxValid) { 1041 return; 1042 } 1043 1044 float value = mScreenAutoBrightnessSpline.interpolate(mAmbientLux); 1045 float gamma = 1.0f; 1046 1047 if (USE_SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT 1048 && mPowerRequest.screenAutoBrightnessAdjustment != 0.0f) { 1049 final float adjGamma = FloatMath.pow(SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT_MAX_GAMMA, 1050 Math.min(1.0f, Math.max(-1.0f, 1051 -mPowerRequest.screenAutoBrightnessAdjustment))); 1052 gamma *= adjGamma; 1053 if (DEBUG) { 1054 Slog.d(TAG, "updateAutoBrightness: adjGamma=" + adjGamma); 1055 } 1056 } 1057 1058 if (USE_TWILIGHT_ADJUSTMENT) { 1059 TwilightState state = mTwilight.getCurrentState(); 1060 if (state != null && state.isNight()) { 1061 final long now = System.currentTimeMillis(); 1062 final float earlyGamma = 1063 getTwilightGamma(now, state.getYesterdaySunset(), state.getTodaySunrise()); 1064 final float lateGamma = 1065 getTwilightGamma(now, state.getTodaySunset(), state.getTomorrowSunrise()); 1066 gamma *= earlyGamma * lateGamma; 1067 if (DEBUG) { 1068 Slog.d(TAG, "updateAutoBrightness: earlyGamma=" + earlyGamma 1069 + ", lateGamma=" + lateGamma); 1070 } 1071 } 1072 } 1073 1074 if (gamma != 1.0f) { 1075 final float in = value; 1076 value = FloatMath.pow(value, gamma); 1077 if (DEBUG) { 1078 Slog.d(TAG, "updateAutoBrightness: gamma=" + gamma 1079 + ", in=" + in + ", out=" + value); 1080 } 1081 } 1082 1083 int newScreenAutoBrightness = clampScreenBrightness( 1084 Math.round(value * PowerManager.BRIGHTNESS_ON)); 1085 if (mScreenAutoBrightness != newScreenAutoBrightness) { 1086 if (DEBUG) { 1087 Slog.d(TAG, "updateAutoBrightness: mScreenAutoBrightness=" 1088 + mScreenAutoBrightness + ", newScreenAutoBrightness=" 1089 + newScreenAutoBrightness); 1090 } 1091 1092 mScreenAutoBrightness = newScreenAutoBrightness; 1093 mLastScreenAutoBrightnessGamma = gamma; 1094 if (sendUpdate) { 1095 sendUpdatePowerState(); 1096 } 1097 } 1098 } 1099 getTwilightGamma(long now, long lastSunset, long nextSunrise)1100 private static float getTwilightGamma(long now, long lastSunset, long nextSunrise) { 1101 if (lastSunset < 0 || nextSunrise < 0 1102 || now < lastSunset || now > nextSunrise) { 1103 return 1.0f; 1104 } 1105 1106 if (now < lastSunset + TWILIGHT_ADJUSTMENT_TIME) { 1107 return lerp(1.0f, TWILIGHT_ADJUSTMENT_MAX_GAMMA, 1108 (float)(now - lastSunset) / TWILIGHT_ADJUSTMENT_TIME); 1109 } 1110 1111 if (now > nextSunrise - TWILIGHT_ADJUSTMENT_TIME) { 1112 return lerp(1.0f, TWILIGHT_ADJUSTMENT_MAX_GAMMA, 1113 (float)(nextSunrise - now) / TWILIGHT_ADJUSTMENT_TIME); 1114 } 1115 1116 return TWILIGHT_ADJUSTMENT_MAX_GAMMA; 1117 } 1118 lerp(float x, float y, float alpha)1119 private static float lerp(float x, float y, float alpha) { 1120 return x + (y - x) * alpha; 1121 } 1122 sendOnStateChanged()1123 private void sendOnStateChanged() { 1124 mCallbackHandler.post(mOnStateChangedRunnable); 1125 } 1126 1127 private final Runnable mOnStateChangedRunnable = new Runnable() { 1128 @Override 1129 public void run() { 1130 mCallbacks.onStateChanged(); 1131 } 1132 }; 1133 sendOnProximityPositive()1134 private void sendOnProximityPositive() { 1135 mCallbackHandler.post(mOnProximityPositiveRunnable); 1136 } 1137 1138 private final Runnable mOnProximityPositiveRunnable = new Runnable() { 1139 @Override 1140 public void run() { 1141 mCallbacks.onProximityPositive(); 1142 } 1143 }; 1144 sendOnProximityNegative()1145 private void sendOnProximityNegative() { 1146 mCallbackHandler.post(mOnProximityNegativeRunnable); 1147 } 1148 1149 private final Runnable mOnProximityNegativeRunnable = new Runnable() { 1150 @Override 1151 public void run() { 1152 mCallbacks.onProximityNegative(); 1153 } 1154 }; 1155 dump(final PrintWriter pw)1156 public void dump(final PrintWriter pw) { 1157 synchronized (mLock) { 1158 pw.println(); 1159 pw.println("Display Controller Locked State:"); 1160 pw.println(" mDisplayReadyLocked=" + mDisplayReadyLocked); 1161 pw.println(" mPendingRequestLocked=" + mPendingRequestLocked); 1162 pw.println(" mPendingRequestChangedLocked=" + mPendingRequestChangedLocked); 1163 pw.println(" mPendingWaitForNegativeProximityLocked=" 1164 + mPendingWaitForNegativeProximityLocked); 1165 pw.println(" mPendingUpdatePowerStateLocked=" + mPendingUpdatePowerStateLocked); 1166 } 1167 1168 pw.println(); 1169 pw.println("Display Controller Configuration:"); 1170 pw.println(" mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig); 1171 pw.println(" mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum); 1172 pw.println(" mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum); 1173 pw.println(" mUseSoftwareAutoBrightnessConfig=" 1174 + mUseSoftwareAutoBrightnessConfig); 1175 pw.println(" mScreenAutoBrightnessSpline=" + mScreenAutoBrightnessSpline); 1176 pw.println(" mLightSensorWarmUpTimeConfig=" + mLightSensorWarmUpTimeConfig); 1177 1178 mHandler.runWithScissors(new Runnable() { 1179 @Override 1180 public void run() { 1181 dumpLocal(pw); 1182 } 1183 }, 1000); 1184 } 1185 dumpLocal(PrintWriter pw)1186 private void dumpLocal(PrintWriter pw) { 1187 pw.println(); 1188 pw.println("Display Controller Thread State:"); 1189 pw.println(" mPowerRequest=" + mPowerRequest); 1190 pw.println(" mWaitingForNegativeProximity=" + mWaitingForNegativeProximity); 1191 1192 pw.println(" mProximitySensor=" + mProximitySensor); 1193 pw.println(" mProximitySensorEnabled=" + mProximitySensorEnabled); 1194 pw.println(" mProximityThreshold=" + mProximityThreshold); 1195 pw.println(" mProximity=" + proximityToString(mProximity)); 1196 pw.println(" mPendingProximity=" + proximityToString(mPendingProximity)); 1197 pw.println(" mPendingProximityDebounceTime=" 1198 + TimeUtils.formatUptime(mPendingProximityDebounceTime)); 1199 pw.println(" mScreenOffBecauseOfProximity=" + mScreenOffBecauseOfProximity); 1200 1201 pw.println(" mLightSensor=" + mLightSensor); 1202 pw.println(" mLightSensorEnabled=" + mLightSensorEnabled); 1203 pw.println(" mLightSensorEnableTime=" 1204 + TimeUtils.formatUptime(mLightSensorEnableTime)); 1205 pw.println(" mAmbientLux=" + mAmbientLux); 1206 pw.println(" mAmbientLuxValid=" + mAmbientLuxValid); 1207 pw.println(" mLastObservedLux=" + mLastObservedLux); 1208 pw.println(" mLastObservedLuxTime=" 1209 + TimeUtils.formatUptime(mLastObservedLuxTime)); 1210 pw.println(" mRecentLightSamples=" + mRecentLightSamples); 1211 pw.println(" mRecentShortTermAverageLux=" + mRecentShortTermAverageLux); 1212 pw.println(" mRecentLongTermAverageLux=" + mRecentLongTermAverageLux); 1213 pw.println(" mDebounceLuxDirection=" + mDebounceLuxDirection); 1214 pw.println(" mDebounceLuxTime=" + TimeUtils.formatUptime(mDebounceLuxTime)); 1215 pw.println(" mScreenAutoBrightness=" + mScreenAutoBrightness); 1216 pw.println(" mUsingScreenAutoBrightness=" + mUsingScreenAutoBrightness); 1217 pw.println(" mLastScreenAutoBrightnessGamma=" + mLastScreenAutoBrightnessGamma); 1218 pw.println(" mTwilight.getCurrentState()=" + mTwilight.getCurrentState()); 1219 1220 if (mElectronBeamOnAnimator != null) { 1221 pw.println(" mElectronBeamOnAnimator.isStarted()=" + 1222 mElectronBeamOnAnimator.isStarted()); 1223 } 1224 if (mElectronBeamOffAnimator != null) { 1225 pw.println(" mElectronBeamOffAnimator.isStarted()=" + 1226 mElectronBeamOffAnimator.isStarted()); 1227 } 1228 1229 if (mPowerState != null) { 1230 mPowerState.dump(pw); 1231 } 1232 } 1233 proximityToString(int state)1234 private static String proximityToString(int state) { 1235 switch (state) { 1236 case PROXIMITY_UNKNOWN: 1237 return "Unknown"; 1238 case PROXIMITY_NEGATIVE: 1239 return "Negative"; 1240 case PROXIMITY_POSITIVE: 1241 return "Positive"; 1242 default: 1243 return Integer.toString(state); 1244 } 1245 } 1246 wantScreenOn(int state)1247 private static boolean wantScreenOn(int state) { 1248 switch (state) { 1249 case DisplayPowerRequest.SCREEN_STATE_BRIGHT: 1250 case DisplayPowerRequest.SCREEN_STATE_DIM: 1251 return true; 1252 } 1253 return false; 1254 } 1255 1256 /** 1257 * Asynchronous callbacks from the power controller to the power manager service. 1258 */ 1259 public interface Callbacks { onStateChanged()1260 void onStateChanged(); onProximityPositive()1261 void onProximityPositive(); onProximityNegative()1262 void onProximityNegative(); 1263 } 1264 1265 private final class DisplayControllerHandler extends Handler { DisplayControllerHandler(Looper looper)1266 public DisplayControllerHandler(Looper looper) { 1267 super(looper, null, true /*async*/); 1268 } 1269 1270 @Override handleMessage(Message msg)1271 public void handleMessage(Message msg) { 1272 switch (msg.what) { 1273 case MSG_UPDATE_POWER_STATE: 1274 updatePowerState(); 1275 break; 1276 1277 case MSG_PROXIMITY_SENSOR_DEBOUNCED: 1278 debounceProximitySensor(); 1279 break; 1280 1281 case MSG_LIGHT_SENSOR_DEBOUNCED: 1282 debounceLightSensor(); 1283 break; 1284 } 1285 } 1286 } 1287 1288 private final SensorEventListener mProximitySensorListener = new SensorEventListener() { 1289 @Override 1290 public void onSensorChanged(SensorEvent event) { 1291 if (mProximitySensorEnabled) { 1292 final long time = SystemClock.uptimeMillis(); 1293 final float distance = event.values[0]; 1294 boolean positive = distance >= 0.0f && distance < mProximityThreshold; 1295 handleProximitySensorEvent(time, positive); 1296 } 1297 } 1298 1299 @Override 1300 public void onAccuracyChanged(Sensor sensor, int accuracy) { 1301 // Not used. 1302 } 1303 }; 1304 1305 private final SensorEventListener mLightSensorListener = new SensorEventListener() { 1306 @Override 1307 public void onSensorChanged(SensorEvent event) { 1308 if (mLightSensorEnabled) { 1309 final long time = SystemClock.uptimeMillis(); 1310 final float lux = event.values[0]; 1311 handleLightSensorEvent(time, lux); 1312 } 1313 } 1314 1315 @Override 1316 public void onAccuracyChanged(Sensor sensor, int accuracy) { 1317 // Not used. 1318 } 1319 }; 1320 1321 private final TwilightService.TwilightListener mTwilightListener = 1322 new TwilightService.TwilightListener() { 1323 @Override 1324 public void onTwilightStateChanged() { 1325 mTwilightChanged = true; 1326 updatePowerState(); 1327 } 1328 }; 1329 } 1330