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