DisplayPowerController.java revision 6a5cacb8683ddd78fc78f01ef726f410bf4e0479
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2012 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.server.display; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.app.IBatteryStats; 2007481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilsonimport com.android.server.LocalServices; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.server.am.BatteryStatsService; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.server.lights.LightsManager; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2441e2e1f9919c9ae3593610f7e05f0d9cf69ec9b2Joe Malinimport android.animation.Animator; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.animation.ObjectAnimator; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.hardware.Sensor; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.hardware.SensorEvent; 3007481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilsonimport android.hardware.SensorEventListener; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.hardware.SensorManager; 3207481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilsonimport android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks; 3307481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilsonimport android.hardware.display.DisplayManagerInternal.DisplayPowerRequest; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Looper; 36bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackbornimport android.os.Message; 37bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackbornimport android.os.PowerManager; 3807481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilsonimport android.os.RemoteException; 39bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackbornimport android.os.SystemClock; 40bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackbornimport android.text.format.DateUtils; 4107481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilsonimport android.util.MathUtils; 42bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackbornimport android.util.Slog; 43bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackbornimport android.util.Spline; 44bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackbornimport android.util.TimeUtils; 45bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackbornimport android.view.Display; 4607481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilson 47bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackbornimport java.io.PrintWriter; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Controls the power state of the display. 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Handles the proximity sensor, light sensor, and animations between states 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * including the screen off animation. 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This component acts independently of the rest of the power manager service. 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * In particular, it does not share any state and it only communicates 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * via asynchronous callbacks to inform the power manager that something has 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * changed. 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Everything this class does internally is serialized on its handler although 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * it may be accessed by other threads from the outside. 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Note that the power manager service guarantees that it will hold a suspend 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * blocker as long as the display is not ready. So most of the work done here 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * does not need to worry about holding a suspend blocker unless it happens 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * independently of the display ready signal. 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For debugging, you can make the electron beam and brightness animations run 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * slower by changing the "animator duration scale" option in Development Settings. 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectfinal class DisplayPowerController implements AutomaticBrightnessController.Callbacks { 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "DisplayPowerController"; 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 74bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn private static boolean DEBUG = false; 75bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn private static final boolean DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT = false; 76bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn 77bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn // If true, uses the electron beam on animation. 78bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn // We might want to turn this off if we cannot get a guarantee that the screen 79bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn // actually turns on and starts showing new content after the call to set the 80bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn // screen state returns. Playing the animation can also be somewhat slow. 81bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn private static final boolean USE_ELECTRON_BEAM_ON_ANIMATION = false; 82bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn 83bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn 84bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn // The minimum reduction in brightness when dimmed. 85bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn private static final int SCREEN_DIM_MINIMUM_REDUCTION = 10; 86bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn 87bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn private static final int ELECTRON_BEAM_ON_ANIMATION_DURATION_MILLIS = 250; 88bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn private static final int ELECTRON_BEAM_OFF_ANIMATION_DURATION_MILLIS = 400; 89bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn 90bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn private static final int MSG_UPDATE_POWER_STATE = 1; 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int MSG_PROXIMITY_SENSOR_DEBOUNCED = 2; 927351dd113f26580f3bcc7500746f3a26aecc4260Eric Fischer 937351dd113f26580f3bcc7500746f3a26aecc4260Eric Fischer private static final int PROXIMITY_UNKNOWN = -1; 947351dd113f26580f3bcc7500746f3a26aecc4260Eric Fischer private static final int PROXIMITY_NEGATIVE = 0; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int PROXIMITY_POSITIVE = 1; 9607481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilson 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Proximity sensor debounce delay in milliseconds for positive or negative transitions. 98fbf37c79bdedbdd7b82ad7d5862dd82e3c068590Elliott Hughes private static final int PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY = 0; 99fbf37c79bdedbdd7b82ad7d5862dd82e3c068590Elliott Hughes private static final int PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY = 250; 100fbf37c79bdedbdd7b82ad7d5862dd82e3c068590Elliott Hughes 10107481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilson // Trigger proximity if distance is less than 5 cm. 102fbf37c79bdedbdd7b82ad7d5862dd82e3c068590Elliott Hughes private static final float TYPICAL_PROXIMITY_THRESHOLD = 5.0f; 103fbf37c79bdedbdd7b82ad7d5862dd82e3c068590Elliott Hughes 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Brightness animation ramp rate in brightness units per second. 10507481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilson private static final int BRIGHTNESS_RAMP_RATE_FAST = 200; 10607481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilson private static final int BRIGHTNESS_RAMP_RATE_SLOW = 40; 10707481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilson 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Object mLock = new Object(); 109260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn 110260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn // Our handler. 111260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn private final DisplayControllerHandler mHandler; 112260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn 113874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos // Asynchronous callbacks into the power manager service. 114260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn // Only invoked from the handler thread while no locks are held. 115260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn private final DisplayPowerCallbacks mCallbacks; 116260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn 117260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn // Battery stats. 118260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn private final IBatteryStats mBatteryStats; 119260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn 120260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn // The lights service. 121260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn private final LightsManager mLights; 122260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn 123260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn // The sensor manager. 124260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn private final SensorManager mSensorManager; 125260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn 126260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn // The display blanker. 127260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn private final DisplayBlanker mBlanker; 128260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn 129260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn // The proximity sensor, or null if not available or needed. 130260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn private Sensor mProximitySensor; 131260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn 132260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn // The doze screen brightness. 133260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn private final int mScreenBrightnessDozeConfig; 134260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn 135260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn // The dim screen brightness. 136260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn private final int mScreenBrightnessDimConfig; 137260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn 138260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn // The minimum allowed brightness. 139260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn private final int mScreenBrightnessRangeMinimum; 140260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn 141260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn // The maximum allowed brightness. 142260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn private final int mScreenBrightnessRangeMaximum; 143260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn 144260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn // True if auto-brightness should be used. 145260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn private boolean mUseSoftwareAutoBrightnessConfig; 146260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn 147260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn // True if we should fade the screen while turning it off, false if we should play 148260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn // a stylish electron beam animation instead. 149260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn private boolean mElectronBeamFadesConfig; 150260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn 151260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn // The pending power request. 152260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn // Initially null until the first call to requestPowerState. 153260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn // Guarded by mLock. 154260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn private DisplayPowerRequest mPendingRequestLocked; 155260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn 156260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn // True if a request has been made to wait for the proximity sensor to go negative. 157260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn // Guarded by mLock. 158260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn private boolean mPendingWaitForNegativeProximityLocked; 159260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn 160260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn // True if the pending power request or wait for negative proximity flag 161260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn // has been changed since the last update occurred. 162260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn // Guarded by mLock. 163260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn private boolean mPendingRequestChangedLocked; 164260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn 165260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn // Set to true when the important parts of the pending power request have been applied. 166260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn // The important parts are mainly the screen state. Brightness changes may occur 167260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn // concurrently. 168260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn // Guarded by mLock. 169260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn private boolean mDisplayReadyLocked; 170260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn 171260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn // Set to true if a power state update is required. 172260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn // Guarded by mLock. 173260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn private boolean mPendingUpdatePowerStateLocked; 174260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn 175874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos /* The following state must only be accessed by the handler thread. */ 176874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos 177874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos // The currently requested power state. 178874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos // The power controller will progressively update its internal state to match 179874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos // the requested power state. Initially null until the first update. 180874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos private DisplayPowerRequest mPowerRequest; 181874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos 182874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos // The current power state. 183874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos // Must only be accessed on the handler thread. 184874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos private DisplayPowerState mPowerState; 185874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos 186874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos // True if the device should wait for negative proximity sensor before 187874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos // waking up the screen. This is set to false as soon as a negative 188874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos // proximity sensor measurement is observed or when the device is forced to 189874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos // go to sleep by the user. While true, the screen remains off. 190874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos private boolean mWaitingForNegativeProximity; 191874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos 192874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos // The actual proximity sensor threshold value. 193874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos private float mProximityThreshold; 194874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Set to true if the proximity sensor listener has been registered 196 // with the sensor manager. 197 private boolean mProximitySensorEnabled; 198 199 // The debounced proximity sensor state. 200 private int mProximity = PROXIMITY_UNKNOWN; 201 202 // The raw non-debounced proximity sensor state. 203 private int mPendingProximity = PROXIMITY_UNKNOWN; 204 private long mPendingProximityDebounceTime = -1; // -1 if fully debounced 205 206 // True if the screen was turned off because of the proximity sensor. 207 // When the screen turns on again, we report user activity to the power manager. 208 private boolean mScreenOffBecauseOfProximity; 209 210 // True if the screen on is being blocked. 211 private boolean mScreenOnWasBlocked; 212 213 // The elapsed real time when the screen on was blocked. 214 private long mScreenOnBlockStartRealTime; 215 216 // True if the screen auto-brightness value is actually being used to 217 // set the display brightness. 218 private boolean mUsingScreenAutoBrightness; 219 220 // The controller for the automatic brightness level. 221 private AutomaticBrightnessController mAutomaticBrightnessController; 222 223 // Animators. 224 private ObjectAnimator mElectronBeamOnAnimator; 225 private ObjectAnimator mElectronBeamOffAnimator; 226 private RampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator; 227 228 /** 229 * Creates the display power controller. 230 */ 231 public DisplayPowerController(Context context, 232 DisplayPowerCallbacks callbacks, Handler handler, 233 SensorManager sensorManager, DisplayBlanker blanker) { 234 mHandler = new DisplayControllerHandler(handler.getLooper()); 235 mCallbacks = callbacks; 236 237 mBatteryStats = BatteryStatsService.getService(); 238 mLights = LocalServices.getService(LightsManager.class); 239 mSensorManager = sensorManager; 240 mBlanker = blanker; 241 242 final Resources resources = context.getResources(); 243 244 mScreenBrightnessDozeConfig = clampAbsoluteBrightness(resources.getInteger( 245 com.android.internal.R.integer.config_screenBrightnessDoze)); 246 247 mScreenBrightnessDimConfig = clampAbsoluteBrightness(resources.getInteger( 248 com.android.internal.R.integer.config_screenBrightnessDim)); 249 250 int screenBrightnessRangeMinimum = clampAbsoluteBrightness(Math.min(resources.getInteger( 251 com.android.internal.R.integer.config_screenBrightnessSettingMinimum), 252 mScreenBrightnessDimConfig)); 253 254 mScreenBrightnessRangeMaximum = PowerManager.BRIGHTNESS_ON; 255 256 mUseSoftwareAutoBrightnessConfig = resources.getBoolean( 257 com.android.internal.R.bool.config_automatic_brightness_available); 258 if (mUseSoftwareAutoBrightnessConfig) { 259 int[] lux = resources.getIntArray( 260 com.android.internal.R.array.config_autoBrightnessLevels); 261 int[] screenBrightness = resources.getIntArray( 262 com.android.internal.R.array.config_autoBrightnessLcdBacklightValues); 263 int lightSensorWarmUpTimeConfig = resources.getInteger( 264 com.android.internal.R.integer.config_lightSensorWarmupTime); 265 266 Spline screenAutoBrightnessSpline = createAutoBrightnessSpline(lux, screenBrightness); 267 if (screenAutoBrightnessSpline == null) { 268 Slog.e(TAG, "Error in config.xml. config_autoBrightnessLcdBacklightValues " 269 + "(size " + screenBrightness.length + ") " 270 + "must be monotic and have exactly one more entry than " 271 + "config_autoBrightnessLevels (size " + lux.length + ") " 272 + "which must be strictly increasing. " 273 + "Auto-brightness will be disabled."); 274 mUseSoftwareAutoBrightnessConfig = false; 275 } else { 276 if (screenBrightness[0] < screenBrightnessRangeMinimum) { 277 screenBrightnessRangeMinimum = clampAbsoluteBrightness(screenBrightness[0]); 278 } 279 mAutomaticBrightnessController = new AutomaticBrightnessController(this, 280 handler.getLooper(), sensorManager, screenAutoBrightnessSpline, 281 lightSensorWarmUpTimeConfig, screenBrightnessRangeMinimum, 282 mScreenBrightnessRangeMaximum); 283 } 284 } 285 286 mScreenBrightnessRangeMinimum = screenBrightnessRangeMinimum; 287 288 mElectronBeamFadesConfig = resources.getBoolean( 289 com.android.internal.R.bool.config_animateScreenLights); 290 291 if (!DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) { 292 mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); 293 if (mProximitySensor != null) { 294 mProximityThreshold = Math.min(mProximitySensor.getMaximumRange(), 295 TYPICAL_PROXIMITY_THRESHOLD); 296 } 297 } 298 299 } 300 301 /** 302 * Returns true if the proximity sensor screen-off function is available. 303 */ 304 public boolean isProximitySensorAvailable() { 305 return mProximitySensor != null; 306 } 307 308 /** 309 * Requests a new power state. 310 * The controller makes a copy of the provided object and then 311 * begins adjusting the power state to match what was requested. 312 * 313 * @param request The requested power state. 314 * @param waitForNegativeProximity If true, issues a request to wait for 315 * negative proximity before turning the screen back on, assuming the screen 316 * was turned off by the proximity sensor. 317 * @return True if display is ready, false if there are important changes that must 318 * be made asynchronously (such as turning the screen on), in which case the caller 319 * should grab a wake lock, watch for {@link Callbacks#onStateChanged()} then try 320 * the request again later until the state converges. 321 */ 322 public boolean requestPowerState(DisplayPowerRequest request, 323 boolean waitForNegativeProximity) { 324 if (DEBUG) { 325 Slog.d(TAG, "requestPowerState: " 326 + request + ", waitForNegativeProximity=" + waitForNegativeProximity); 327 } 328 329 synchronized (mLock) { 330 boolean changed = false; 331 332 if (waitForNegativeProximity 333 && !mPendingWaitForNegativeProximityLocked) { 334 mPendingWaitForNegativeProximityLocked = true; 335 changed = true; 336 } 337 338 if (mPendingRequestLocked == null) { 339 mPendingRequestLocked = new DisplayPowerRequest(request); 340 changed = true; 341 } else if (!mPendingRequestLocked.equals(request)) { 342 mPendingRequestLocked.copyFrom(request); 343 changed = true; 344 } 345 346 if (changed) { 347 mDisplayReadyLocked = false; 348 } 349 350 if (changed && !mPendingRequestChangedLocked) { 351 mPendingRequestChangedLocked = true; 352 sendUpdatePowerStateLocked(); 353 } 354 355 return mDisplayReadyLocked; 356 } 357 } 358 359 private void sendUpdatePowerState() { 360 synchronized (mLock) { 361 sendUpdatePowerStateLocked(); 362 } 363 } 364 365 private void sendUpdatePowerStateLocked() { 366 if (!mPendingUpdatePowerStateLocked) { 367 mPendingUpdatePowerStateLocked = true; 368 Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE); 369 msg.setAsynchronous(true); 370 mHandler.sendMessage(msg); 371 } 372 } 373 374 private void initialize() { 375 // Initialize the power state object for the default display. 376 // In the future, we might manage multiple displays independently. 377 mPowerState = new DisplayPowerState(mBlanker, 378 mLights.getLight(LightsManager.LIGHT_ID_BACKLIGHT), 379 new ElectronBeam(Display.DEFAULT_DISPLAY)); 380 381 mElectronBeamOnAnimator = ObjectAnimator.ofFloat( 382 mPowerState, DisplayPowerState.ELECTRON_BEAM_LEVEL, 0.0f, 1.0f); 383 mElectronBeamOnAnimator.setDuration(ELECTRON_BEAM_ON_ANIMATION_DURATION_MILLIS); 384 mElectronBeamOnAnimator.addListener(mAnimatorListener); 385 386 mElectronBeamOffAnimator = ObjectAnimator.ofFloat( 387 mPowerState, DisplayPowerState.ELECTRON_BEAM_LEVEL, 1.0f, 0.0f); 388 mElectronBeamOffAnimator.setDuration(ELECTRON_BEAM_OFF_ANIMATION_DURATION_MILLIS); 389 mElectronBeamOffAnimator.addListener(mAnimatorListener); 390 391 mScreenBrightnessRampAnimator = new RampAnimator<DisplayPowerState>( 392 mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS); 393 mScreenBrightnessRampAnimator.setListener(mRampAnimatorListener); 394 395 // Initialize screen state for battery stats. 396 try { 397 mBatteryStats.noteScreenState(mPowerState.getScreenState()); 398 mBatteryStats.noteScreenBrightness(mPowerState.getScreenBrightness()); 399 } catch (RemoteException ex) { 400 // same process 401 } 402 } 403 404 private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() { 405 @Override 406 public void onAnimationStart(Animator animation) { 407 } 408 @Override 409 public void onAnimationEnd(Animator animation) { 410 sendUpdatePowerState(); 411 } 412 @Override 413 public void onAnimationRepeat(Animator animation) { 414 } 415 @Override 416 public void onAnimationCancel(Animator animation) { 417 } 418 }; 419 420 private final RampAnimator.Listener mRampAnimatorListener = new RampAnimator.Listener() { 421 @Override 422 public void onAnimationEnd() { 423 sendUpdatePowerState(); 424 } 425 }; 426 427 private void updatePowerState() { 428 // Update the power state request. 429 final boolean mustNotify; 430 boolean mustInitialize = false; 431 boolean wasDimOrDoze = false; 432 boolean autoBrightnessAdjustmentChanged = false; 433 434 synchronized (mLock) { 435 mPendingUpdatePowerStateLocked = false; 436 if (mPendingRequestLocked == null) { 437 return; // wait until first actual power request 438 } 439 440 if (mPowerRequest == null) { 441 mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked); 442 mWaitingForNegativeProximity = mPendingWaitForNegativeProximityLocked; 443 mPendingWaitForNegativeProximityLocked = false; 444 mPendingRequestChangedLocked = false; 445 mustInitialize = true; 446 } else if (mPendingRequestChangedLocked) { 447 wasDimOrDoze = (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DIM 448 || mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DOZE); 449 autoBrightnessAdjustmentChanged = (mPowerRequest.screenAutoBrightnessAdjustment 450 != mPendingRequestLocked.screenAutoBrightnessAdjustment); 451 mPowerRequest.copyFrom(mPendingRequestLocked); 452 mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked; 453 mPendingWaitForNegativeProximityLocked = false; 454 mPendingRequestChangedLocked = false; 455 mDisplayReadyLocked = false; 456 } 457 458 mustNotify = !mDisplayReadyLocked; 459 } 460 461 // Initialize things the first time the power state is changed. 462 if (mustInitialize) { 463 initialize(); 464 } 465 466 // Apply the proximity sensor. 467 if (mProximitySensor != null) { 468 if (mPowerRequest.useProximitySensor 469 && mPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF) { 470 setProximitySensorEnabled(true); 471 if (!mScreenOffBecauseOfProximity 472 && mProximity == PROXIMITY_POSITIVE) { 473 mScreenOffBecauseOfProximity = true; 474 sendOnProximityPositiveWithWakelock(); 475 } 476 } else if (mWaitingForNegativeProximity 477 && mScreenOffBecauseOfProximity 478 && mProximity == PROXIMITY_POSITIVE 479 && mPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF) { 480 setProximitySensorEnabled(true); 481 } else { 482 setProximitySensorEnabled(false); 483 mWaitingForNegativeProximity = false; 484 } 485 if (mScreenOffBecauseOfProximity 486 && mProximity != PROXIMITY_POSITIVE) { 487 mScreenOffBecauseOfProximity = false; 488 sendOnProximityNegativeWithWakelock(); 489 } 490 } else { 491 mWaitingForNegativeProximity = false; 492 } 493 494 // Turn on the light sensor if needed. 495 if (mAutomaticBrightnessController != null) { 496 mAutomaticBrightnessController.updatePowerState(mPowerRequest); 497 } 498 499 // Set the screen brightness. 500 if (mPowerRequest.wantScreenOnAny()) { 501 int target; 502 boolean slow; 503 int screenAutoBrightness = mAutomaticBrightnessController != null ? 504 mAutomaticBrightnessController.getAutomaticScreenBrightness() : -1; 505 if (screenAutoBrightness >= 0 && mPowerRequest.useAutoBrightness) { 506 // Use current auto-brightness value. 507 target = screenAutoBrightness; 508 slow = mUsingScreenAutoBrightness && !autoBrightnessAdjustmentChanged; 509 mUsingScreenAutoBrightness = true; 510 } else { 511 // Light sensor is disabled or not ready yet. 512 // Use the current brightness setting from the request, which is expected 513 // provide a nominal default value for the case where auto-brightness 514 // is not ready yet. 515 target = mPowerRequest.screenBrightness; 516 slow = false; 517 mUsingScreenAutoBrightness = false; 518 } 519 if (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DOZE) { 520 // Dim quickly to the doze state. 521 target = mScreenBrightnessDozeConfig; 522 slow = false; 523 } else if (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DIM) { 524 // Dim quickly by at least some minimum amount. 525 target = Math.min(target - SCREEN_DIM_MINIMUM_REDUCTION, 526 mScreenBrightnessDimConfig); 527 slow = false; 528 } else if (wasDimOrDoze) { 529 // Brighten quickly. 530 slow = false; 531 } 532 // If low power mode is enabled, brightness level 533 // would be scaled down to half 534 if (mPowerRequest.lowPowerMode) { 535 target = target/2; 536 } 537 animateScreenBrightness(clampScreenBrightness(target), 538 slow ? BRIGHTNESS_RAMP_RATE_SLOW : BRIGHTNESS_RAMP_RATE_FAST); 539 } else { 540 // Screen is off. Don't bother changing the brightness. 541 mUsingScreenAutoBrightness = false; 542 } 543 544 // Animate the screen on or off unless blocked. 545 if (mScreenOffBecauseOfProximity) { 546 // Screen off due to proximity. 547 setScreenState(Display.STATE_OFF); 548 unblockScreenOn(); 549 } else if (mPowerRequest.wantScreenOnAny()) { 550 // Want screen on. 551 // Wait for previous off animation to complete beforehand. 552 // It is relatively short but if we cancel it and switch to the 553 // on animation immediately then the results are pretty ugly. 554 if (!mElectronBeamOffAnimator.isStarted()) { 555 // Turn the screen on. The contents of the screen may not yet 556 // be visible if the electron beam has not been dismissed because 557 // its last frame of animation is solid black. 558 559 if (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DOZE) { 560 if (!mScreenBrightnessRampAnimator.isAnimating()) { 561 setScreenState(Display.STATE_DOZING); 562 } 563 } else { 564 setScreenState(Display.STATE_ON); 565 } 566 567 if (mPowerRequest.blockScreenOn 568 && mPowerState.getElectronBeamLevel() == 0.0f) { 569 blockScreenOn(); 570 } else { 571 unblockScreenOn(); 572 if (USE_ELECTRON_BEAM_ON_ANIMATION) { 573 if (!mElectronBeamOnAnimator.isStarted()) { 574 if (mPowerState.getElectronBeamLevel() == 1.0f) { 575 mPowerState.dismissElectronBeam(); 576 } else if (mPowerState.prepareElectronBeam( 577 mElectronBeamFadesConfig ? 578 ElectronBeam.MODE_FADE : 579 ElectronBeam.MODE_WARM_UP)) { 580 mElectronBeamOnAnimator.start(); 581 } else { 582 mElectronBeamOnAnimator.end(); 583 } 584 } 585 } else { 586 mPowerState.setElectronBeamLevel(1.0f); 587 mPowerState.dismissElectronBeam(); 588 } 589 } 590 } 591 } else { 592 // Want screen off. 593 // Wait for previous on animation to complete beforehand. 594 unblockScreenOn(); 595 if (!mElectronBeamOnAnimator.isStarted()) { 596 if (!mElectronBeamOffAnimator.isStarted()) { 597 if (mPowerState.getElectronBeamLevel() == 0.0f) { 598 setScreenState(Display.STATE_OFF); 599 } else if (mPowerState.prepareElectronBeam( 600 mElectronBeamFadesConfig ? 601 ElectronBeam.MODE_FADE : 602 ElectronBeam.MODE_COOL_DOWN) 603 && mPowerState.getScreenState() != Display.STATE_OFF) { 604 mElectronBeamOffAnimator.start(); 605 } else { 606 mElectronBeamOffAnimator.end(); 607 } 608 } 609 } 610 } 611 612 // Report whether the display is ready for use. 613 // We mostly care about the screen state here, ignoring brightness changes 614 // which will be handled asynchronously. 615 if (mustNotify 616 && !mScreenOnWasBlocked 617 && !mElectronBeamOnAnimator.isStarted() 618 && !mElectronBeamOffAnimator.isStarted() 619 && !mScreenBrightnessRampAnimator.isAnimating() 620 && mPowerState.waitUntilClean(mCleanListener)) { 621 synchronized (mLock) { 622 if (!mPendingRequestChangedLocked) { 623 mDisplayReadyLocked = true; 624 625 if (DEBUG) { 626 Slog.d(TAG, "Display ready!"); 627 } 628 } 629 } 630 sendOnStateChangedWithWakelock(); 631 } 632 } 633 634 @Override 635 public void updateBrightness() { 636 sendUpdatePowerState(); 637 } 638 639 private void blockScreenOn() { 640 if (!mScreenOnWasBlocked) { 641 mScreenOnWasBlocked = true; 642 mScreenOnBlockStartRealTime = SystemClock.elapsedRealtime(); 643 if (DEBUG) { 644 Slog.d(TAG, "Blocked screen on."); 645 } 646 } 647 } 648 649 private void unblockScreenOn() { 650 if (mScreenOnWasBlocked) { 651 mScreenOnWasBlocked = false; 652 long delay = SystemClock.elapsedRealtime() - mScreenOnBlockStartRealTime; 653 if (delay > 1000 || DEBUG) { 654 Slog.d(TAG, "Unblocked screen on after " + delay + " ms"); 655 } 656 } 657 } 658 659 private void setScreenState(int state) { 660 if (mPowerState.getScreenState() != state) { 661 mPowerState.setScreenState(state); 662 try { 663 mBatteryStats.noteScreenState(state); 664 } catch (RemoteException ex) { 665 // same process 666 } 667 } 668 } 669 670 private int clampScreenBrightness(int value) { 671 return MathUtils.constrain( 672 value, mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum); 673 } 674 675 private void animateScreenBrightness(int target, int rate) { 676 if (mScreenBrightnessRampAnimator.animateTo(target, rate)) { 677 try { 678 mBatteryStats.noteScreenBrightness(target); 679 } catch (RemoteException ex) { 680 // same process 681 } 682 } 683 } 684 685 private final Runnable mCleanListener = new Runnable() { 686 @Override 687 public void run() { 688 sendUpdatePowerState(); 689 } 690 }; 691 692 private void setProximitySensorEnabled(boolean enable) { 693 if (enable) { 694 if (!mProximitySensorEnabled) { 695 // Register the listener. 696 // Proximity sensor state already cleared initially. 697 mProximitySensorEnabled = true; 698 mSensorManager.registerListener(mProximitySensorListener, mProximitySensor, 699 SensorManager.SENSOR_DELAY_NORMAL, mHandler); 700 } 701 } else { 702 if (mProximitySensorEnabled) { 703 // Unregister the listener. 704 // Clear the proximity sensor state for next time. 705 mProximitySensorEnabled = false; 706 mProximity = PROXIMITY_UNKNOWN; 707 mPendingProximity = PROXIMITY_UNKNOWN; 708 mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED); 709 mSensorManager.unregisterListener(mProximitySensorListener); 710 clearPendingProximityDebounceTime(); // release wake lock (must be last) 711 } 712 } 713 } 714 715 private void handleProximitySensorEvent(long time, boolean positive) { 716 if (mProximitySensorEnabled) { 717 if (mPendingProximity == PROXIMITY_NEGATIVE && !positive) { 718 return; // no change 719 } 720 if (mPendingProximity == PROXIMITY_POSITIVE && positive) { 721 return; // no change 722 } 723 724 // Only accept a proximity sensor reading if it remains 725 // stable for the entire debounce delay. We hold a wake lock while 726 // debouncing the sensor. 727 mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED); 728 if (positive) { 729 mPendingProximity = PROXIMITY_POSITIVE; 730 setPendingProximityDebounceTime( 731 time + PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY); // acquire wake lock 732 } else { 733 mPendingProximity = PROXIMITY_NEGATIVE; 734 setPendingProximityDebounceTime( 735 time + PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY); // acquire wake lock 736 } 737 738 // Debounce the new sensor reading. 739 debounceProximitySensor(); 740 } 741 } 742 743 private void debounceProximitySensor() { 744 if (mProximitySensorEnabled 745 && mPendingProximity != PROXIMITY_UNKNOWN 746 && mPendingProximityDebounceTime >= 0) { 747 final long now = SystemClock.uptimeMillis(); 748 if (mPendingProximityDebounceTime <= now) { 749 // Sensor reading accepted. Apply the change then release the wake lock. 750 mProximity = mPendingProximity; 751 updatePowerState(); 752 clearPendingProximityDebounceTime(); // release wake lock (must be last) 753 } else { 754 // Need to wait a little longer. 755 // Debounce again later. We continue holding a wake lock while waiting. 756 Message msg = mHandler.obtainMessage(MSG_PROXIMITY_SENSOR_DEBOUNCED); 757 msg.setAsynchronous(true); 758 mHandler.sendMessageAtTime(msg, mPendingProximityDebounceTime); 759 } 760 } 761 } 762 763 private void clearPendingProximityDebounceTime() { 764 if (mPendingProximityDebounceTime >= 0) { 765 mPendingProximityDebounceTime = -1; 766 mCallbacks.releaseSuspendBlocker(); // release wake lock 767 } 768 } 769 770 private void setPendingProximityDebounceTime(long debounceTime) { 771 if (mPendingProximityDebounceTime < 0) { 772 mCallbacks.acquireSuspendBlocker(); // acquire wake lock 773 } 774 mPendingProximityDebounceTime = debounceTime; 775 } 776 777 private void sendOnStateChangedWithWakelock() { 778 mCallbacks.acquireSuspendBlocker(); 779 mHandler.post(mOnStateChangedRunnable); 780 } 781 782 private final Runnable mOnStateChangedRunnable = new Runnable() { 783 @Override 784 public void run() { 785 mCallbacks.onStateChanged(); 786 mCallbacks.releaseSuspendBlocker(); 787 } 788 }; 789 790 private void sendOnProximityPositiveWithWakelock() { 791 mCallbacks.acquireSuspendBlocker(); 792 mHandler.post(mOnProximityPositiveRunnable); 793 } 794 795 private final Runnable mOnProximityPositiveRunnable = new Runnable() { 796 @Override 797 public void run() { 798 mCallbacks.onProximityPositive(); 799 mCallbacks.releaseSuspendBlocker(); 800 } 801 }; 802 803 private void sendOnProximityNegativeWithWakelock() { 804 mCallbacks.acquireSuspendBlocker(); 805 mHandler.post(mOnProximityNegativeRunnable); 806 } 807 808 private final Runnable mOnProximityNegativeRunnable = new Runnable() { 809 @Override 810 public void run() { 811 mCallbacks.onProximityNegative(); 812 mCallbacks.releaseSuspendBlocker(); 813 } 814 }; 815 816 public void dump(final PrintWriter pw) { 817 synchronized (mLock) { 818 pw.println(); 819 pw.println("Display Power Controller Locked State:"); 820 pw.println(" mDisplayReadyLocked=" + mDisplayReadyLocked); 821 pw.println(" mPendingRequestLocked=" + mPendingRequestLocked); 822 pw.println(" mPendingRequestChangedLocked=" + mPendingRequestChangedLocked); 823 pw.println(" mPendingWaitForNegativeProximityLocked=" 824 + mPendingWaitForNegativeProximityLocked); 825 pw.println(" mPendingUpdatePowerStateLocked=" + mPendingUpdatePowerStateLocked); 826 } 827 828 pw.println(); 829 pw.println("Display Power Controller Configuration:"); 830 pw.println(" mScreenBrightnessDozeConfig=" + mScreenBrightnessDozeConfig); 831 pw.println(" mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig); 832 pw.println(" mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum); 833 pw.println(" mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum); 834 pw.println(" mUseSoftwareAutoBrightnessConfig=" 835 + mUseSoftwareAutoBrightnessConfig); 836 837 mHandler.runWithScissors(new Runnable() { 838 @Override 839 public void run() { 840 dumpLocal(pw); 841 } 842 }, 1000); 843 } 844 845 private void dumpLocal(PrintWriter pw) { 846 pw.println(); 847 pw.println("Display Power Controller Thread State:"); 848 pw.println(" mPowerRequest=" + mPowerRequest); 849 pw.println(" mWaitingForNegativeProximity=" + mWaitingForNegativeProximity); 850 851 pw.println(" mProximitySensor=" + mProximitySensor); 852 pw.println(" mProximitySensorEnabled=" + mProximitySensorEnabled); 853 pw.println(" mProximityThreshold=" + mProximityThreshold); 854 pw.println(" mProximity=" + proximityToString(mProximity)); 855 pw.println(" mPendingProximity=" + proximityToString(mPendingProximity)); 856 pw.println(" mPendingProximityDebounceTime=" 857 + TimeUtils.formatUptime(mPendingProximityDebounceTime)); 858 pw.println(" mScreenOffBecauseOfProximity=" + mScreenOffBecauseOfProximity); 859 pw.println(" mUsingScreenAutoBrightness=" + mUsingScreenAutoBrightness); 860 861 pw.println(" mScreenBrightnessRampAnimator.isAnimating()=" + 862 mScreenBrightnessRampAnimator.isAnimating()); 863 864 if (mElectronBeamOnAnimator != null) { 865 pw.println(" mElectronBeamOnAnimator.isStarted()=" + 866 mElectronBeamOnAnimator.isStarted()); 867 } 868 if (mElectronBeamOffAnimator != null) { 869 pw.println(" mElectronBeamOffAnimator.isStarted()=" + 870 mElectronBeamOffAnimator.isStarted()); 871 } 872 873 if (mPowerState != null) { 874 mPowerState.dump(pw); 875 } 876 877 if (mAutomaticBrightnessController != null) { 878 mAutomaticBrightnessController.dump(pw); 879 } 880 881 } 882 883 private static String proximityToString(int state) { 884 switch (state) { 885 case PROXIMITY_UNKNOWN: 886 return "Unknown"; 887 case PROXIMITY_NEGATIVE: 888 return "Negative"; 889 case PROXIMITY_POSITIVE: 890 return "Positive"; 891 default: 892 return Integer.toString(state); 893 } 894 } 895 896 private static Spline createAutoBrightnessSpline(int[] lux, int[] brightness) { 897 try { 898 final int n = brightness.length; 899 float[] x = new float[n]; 900 float[] y = new float[n]; 901 y[0] = normalizeAbsoluteBrightness(brightness[0]); 902 for (int i = 1; i < n; i++) { 903 x[i] = lux[i - 1]; 904 y[i] = normalizeAbsoluteBrightness(brightness[i]); 905 } 906 907 Spline spline = Spline.createMonotoneCubicSpline(x, y); 908 if (DEBUG) { 909 Slog.d(TAG, "Auto-brightness spline: " + spline); 910 for (float v = 1f; v < lux[lux.length - 1] * 1.25f; v *= 1.25f) { 911 Slog.d(TAG, String.format(" %7.1f: %7.1f", v, spline.interpolate(v))); 912 } 913 } 914 return spline; 915 } catch (IllegalArgumentException ex) { 916 Slog.e(TAG, "Could not create auto-brightness spline.", ex); 917 return null; 918 } 919 } 920 921 private static float normalizeAbsoluteBrightness(int value) { 922 return (float)clampAbsoluteBrightness(value) / PowerManager.BRIGHTNESS_ON; 923 } 924 925 private static int clampAbsoluteBrightness(int value) { 926 return MathUtils.constrain(value, PowerManager.BRIGHTNESS_OFF, PowerManager.BRIGHTNESS_ON); 927 } 928 929 private final class DisplayControllerHandler extends Handler { 930 public DisplayControllerHandler(Looper looper) { 931 super(looper, null, true /*async*/); 932 } 933 934 @Override 935 public void handleMessage(Message msg) { 936 switch (msg.what) { 937 case MSG_UPDATE_POWER_STATE: 938 updatePowerState(); 939 break; 940 941 case MSG_PROXIMITY_SENSOR_DEBOUNCED: 942 debounceProximitySensor(); 943 break; 944 } 945 } 946 } 947 948 private final SensorEventListener mProximitySensorListener = new SensorEventListener() { 949 @Override 950 public void onSensorChanged(SensorEvent event) { 951 if (mProximitySensorEnabled) { 952 final long time = SystemClock.uptimeMillis(); 953 final float distance = event.values[0]; 954 boolean positive = distance >= 0.0f && distance < mProximityThreshold; 955 handleProximitySensorEvent(time, positive); 956 } 957 } 958 959 @Override 960 public void onAccuracyChanged(Sensor sensor, int accuracy) { 961 // Not used. 962 } 963 }; 964} 965