Home | History | Annotate | Download | only in server
      1 /*
      2  * Copyright (C) 2007 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;
     18 
     19 import com.android.internal.app.IBatteryStats;
     20 import com.android.server.am.BatteryStatsService;
     21 import com.android.server.pm.ShutdownThread;
     22 
     23 import android.app.ActivityManagerNative;
     24 import android.app.IActivityManager;
     25 import android.content.BroadcastReceiver;
     26 import android.content.ContentQueryMap;
     27 import android.content.ContentResolver;
     28 import android.content.ContentValues;
     29 import android.content.Context;
     30 import android.content.Intent;
     31 import android.content.IntentFilter;
     32 import android.content.pm.PackageManager;
     33 import android.content.res.Resources;
     34 import android.database.ContentObserver;
     35 import android.database.Cursor;
     36 import android.hardware.Sensor;
     37 import android.hardware.SensorEvent;
     38 import android.hardware.SensorEventListener;
     39 import android.hardware.SensorManager;
     40 import android.hardware.SystemSensorManager;
     41 import android.os.BatteryManager;
     42 import android.os.BatteryStats;
     43 import android.os.Binder;
     44 import android.os.Handler;
     45 import android.os.HandlerThread;
     46 import android.os.IBinder;
     47 import android.os.IPowerManager;
     48 import android.os.LocalPowerManager;
     49 import android.os.Message;
     50 import android.os.PowerManager;
     51 import android.os.Process;
     52 import android.os.RemoteException;
     53 import android.os.SystemClock;
     54 import android.os.SystemProperties;
     55 import android.os.WorkSource;
     56 import android.provider.Settings;
     57 import android.util.EventLog;
     58 import android.util.Log;
     59 import android.util.Slog;
     60 import android.view.WindowManagerPolicy;
     61 import static android.view.WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR;
     62 import static android.provider.Settings.System.DIM_SCREEN;
     63 import static android.provider.Settings.System.SCREEN_BRIGHTNESS;
     64 import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE;
     65 import static android.provider.Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ;
     66 import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
     67 import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
     68 import static android.provider.Settings.System.STAY_ON_WHILE_PLUGGED_IN;
     69 import static android.provider.Settings.System.WINDOW_ANIMATION_SCALE;
     70 import static android.provider.Settings.System.TRANSITION_ANIMATION_SCALE;
     71 
     72 import java.io.FileDescriptor;
     73 import java.io.IOException;
     74 import java.io.PrintWriter;
     75 import java.util.ArrayList;
     76 import java.util.HashMap;
     77 import java.util.Observable;
     78 import java.util.Observer;
     79 
     80 public class PowerManagerService extends IPowerManager.Stub
     81         implements LocalPowerManager, Watchdog.Monitor {
     82     private static final int NOMINAL_FRAME_TIME_MS = 1000/60;
     83 
     84     private static final String TAG = "PowerManagerService";
     85     static final String PARTIAL_NAME = "PowerManagerService";
     86 
     87     // Wake lock that ensures that the CPU is running.  The screen might not be on.
     88     private static final int PARTIAL_WAKE_LOCK_ID = 1;
     89 
     90     // Wake lock that ensures that the screen is on.
     91     private static final int FULL_WAKE_LOCK_ID = 2;
     92 
     93     static final boolean DEBUG_SCREEN_ON = false;
     94 
     95     private static final boolean LOG_PARTIAL_WL = false;
     96 
     97     // Indicates whether touch-down cycles should be logged as part of the
     98     // LOG_POWER_SCREEN_STATE log events
     99     private static final boolean LOG_TOUCH_DOWNS = true;
    100 
    101     private static final int LOCK_MASK = PowerManager.PARTIAL_WAKE_LOCK
    102                                         | PowerManager.SCREEN_DIM_WAKE_LOCK
    103                                         | PowerManager.SCREEN_BRIGHT_WAKE_LOCK
    104                                         | PowerManager.FULL_WAKE_LOCK
    105                                         | PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK;
    106 
    107     //                       time since last state:               time since last event:
    108     // The short keylight delay comes from secure settings; this is the default.
    109     private static final int SHORT_KEYLIGHT_DELAY_DEFAULT = 6000; // t+6 sec
    110     private static final int MEDIUM_KEYLIGHT_DELAY = 15000;       // t+15 sec
    111     private static final int LONG_KEYLIGHT_DELAY = 6000;        // t+6 sec
    112     private static final int LONG_DIM_TIME = 7000;              // t+N-5 sec
    113 
    114     // How long to wait to debounce light sensor changes in milliseconds
    115     private static final int LIGHT_SENSOR_DELAY = 2000;
    116 
    117     // light sensor events rate in microseconds
    118     private static final int LIGHT_SENSOR_RATE = 1000000;
    119 
    120     // Expansion of range of light values when applying scale from light
    121     // sensor brightness setting, in the [0..255] brightness range.
    122     private static final int LIGHT_SENSOR_RANGE_EXPANSION = 20;
    123 
    124     // Scaling factor of the light sensor brightness setting when applying
    125     // it to the final brightness.
    126     private static final int LIGHT_SENSOR_OFFSET_SCALE = 8;
    127 
    128     // For debouncing the proximity sensor in milliseconds
    129     private static final int PROXIMITY_SENSOR_DELAY = 1000;
    130 
    131     // trigger proximity if distance is less than 5 cm
    132     private static final float PROXIMITY_THRESHOLD = 5.0f;
    133 
    134     // Cached secure settings; see updateSettingsValues()
    135     private int mShortKeylightDelay = SHORT_KEYLIGHT_DELAY_DEFAULT;
    136 
    137     // Default timeout for screen off, if not found in settings database = 15 seconds.
    138     private static final int DEFAULT_SCREEN_OFF_TIMEOUT = 15000;
    139 
    140     // Screen brightness should always have a value, but just in case...
    141     private static final int DEFAULT_SCREEN_BRIGHTNESS = 192;
    142 
    143     // Threshold for BRIGHTNESS_LOW_BATTERY (percentage)
    144     // Screen will stay dim if battery level is <= LOW_BATTERY_THRESHOLD
    145     private static final int LOW_BATTERY_THRESHOLD = 10;
    146 
    147     // flags for setPowerState
    148     private static final int ALL_LIGHTS_OFF         = 0x00000000;
    149     private static final int SCREEN_ON_BIT          = 0x00000001;
    150     private static final int SCREEN_BRIGHT_BIT      = 0x00000002;
    151     private static final int BUTTON_BRIGHT_BIT      = 0x00000004;
    152     private static final int KEYBOARD_BRIGHT_BIT    = 0x00000008;
    153     private static final int BATTERY_LOW_BIT        = 0x00000010;
    154 
    155     // values for setPowerState
    156 
    157     // SCREEN_OFF == everything off
    158     private static final int SCREEN_OFF         = 0x00000000;
    159 
    160     // SCREEN_DIM == screen on, screen backlight dim
    161     private static final int SCREEN_DIM         = SCREEN_ON_BIT;
    162 
    163     // SCREEN_BRIGHT == screen on, screen backlight bright
    164     private static final int SCREEN_BRIGHT      = SCREEN_ON_BIT | SCREEN_BRIGHT_BIT;
    165 
    166     // SCREEN_BUTTON_BRIGHT == screen on, screen and button backlights bright
    167     private static final int SCREEN_BUTTON_BRIGHT  = SCREEN_BRIGHT | BUTTON_BRIGHT_BIT;
    168 
    169     // SCREEN_BUTTON_BRIGHT == screen on, screen, button and keyboard backlights bright
    170     private static final int ALL_BRIGHT         = SCREEN_BUTTON_BRIGHT | KEYBOARD_BRIGHT_BIT;
    171 
    172     // used for noChangeLights in setPowerState()
    173     private static final int LIGHTS_MASK        = SCREEN_BRIGHT_BIT | BUTTON_BRIGHT_BIT | KEYBOARD_BRIGHT_BIT;
    174 
    175     // animate screen lights in PowerManager (as opposed to SurfaceFlinger)
    176     boolean mAnimateScreenLights = true;
    177 
    178     static final int ANIM_STEPS = 60; // nominal # of frames at 60Hz
    179     // Slower animation for autobrightness changes
    180     static final int AUTOBRIGHTNESS_ANIM_STEPS = 2 * ANIM_STEPS;
    181     // Even slower animation for autodimness changes. Set to max to effectively disable dimming.
    182     // Note 100 is used to keep the mWindowScaleAnimation scaling below from overflowing an int.
    183     static final int AUTODIMNESS_ANIM_STEPS = Integer.MAX_VALUE / (NOMINAL_FRAME_TIME_MS * 100);
    184     // Number of steps when performing a more immediate brightness change.
    185     static final int IMMEDIATE_ANIM_STEPS = 4;
    186 
    187     // These magic numbers are the initial state of the LEDs at boot.  Ideally
    188     // we should read them from the driver, but our current hardware returns 0
    189     // for the initial value.  Oops!
    190     static final int INITIAL_SCREEN_BRIGHTNESS = 255;
    191     static final int INITIAL_BUTTON_BRIGHTNESS = PowerManager.BRIGHTNESS_OFF;
    192     static final int INITIAL_KEYBOARD_BRIGHTNESS = PowerManager.BRIGHTNESS_OFF;
    193 
    194     private final int MY_UID;
    195     private final int MY_PID;
    196 
    197     private boolean mDoneBooting = false;
    198     private boolean mBootCompleted = false;
    199     private boolean mHeadless = false;
    200     private int mStayOnConditions = 0;
    201     private final int[] mBroadcastQueue = new int[] { -1, -1, -1 };
    202     private final int[] mBroadcastWhy = new int[3];
    203     private boolean mPreparingForScreenOn = false;
    204     private boolean mSkippedScreenOn = false;
    205     private boolean mInitialized = false;
    206     private int mPartialCount = 0;
    207     private int mPowerState;
    208     // mScreenOffReason can be WindowManagerPolicy.OFF_BECAUSE_OF_USER,
    209     // WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT or WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR
    210     private int mScreenOffReason;
    211     private int mUserState;
    212     private boolean mKeyboardVisible = false;
    213     private boolean mUserActivityAllowed = true;
    214     private int mProximityWakeLockCount = 0;
    215     private boolean mProximitySensorEnabled = false;
    216     private boolean mProximitySensorActive = false;
    217     private int mProximityPendingValue = -1; // -1 == nothing, 0 == inactive, 1 == active
    218     private long mLastProximityEventTime;
    219     private int mScreenOffTimeoutSetting;
    220     private int mMaximumScreenOffTimeout = Integer.MAX_VALUE;
    221     private int mKeylightDelay;
    222     private int mDimDelay;
    223     private int mScreenOffDelay;
    224     private int mWakeLockState;
    225     private long mLastEventTime = 0;
    226     private long mScreenOffTime;
    227     private volatile WindowManagerPolicy mPolicy;
    228     private final LockList mLocks = new LockList();
    229     private Intent mScreenOffIntent;
    230     private Intent mScreenOnIntent;
    231     private LightsService mLightsService;
    232     private Context mContext;
    233     private LightsService.Light mLcdLight;
    234     private LightsService.Light mButtonLight;
    235     private LightsService.Light mKeyboardLight;
    236     private LightsService.Light mAttentionLight;
    237     private UnsynchronizedWakeLock mBroadcastWakeLock;
    238     private UnsynchronizedWakeLock mStayOnWhilePluggedInScreenDimLock;
    239     private UnsynchronizedWakeLock mStayOnWhilePluggedInPartialLock;
    240     private UnsynchronizedWakeLock mPreventScreenOnPartialLock;
    241     private UnsynchronizedWakeLock mProximityPartialLock;
    242     private HandlerThread mHandlerThread;
    243     private Handler mScreenOffHandler;
    244     private Handler mScreenBrightnessHandler;
    245     private Handler mHandler;
    246     private final TimeoutTask mTimeoutTask = new TimeoutTask();
    247     private ScreenBrightnessAnimator mScreenBrightnessAnimator;
    248     private boolean mWaitingForFirstLightSensor = false;
    249     private boolean mStillNeedSleepNotification;
    250     private boolean mIsPowered = false;
    251     private IActivityManager mActivityService;
    252     private IBatteryStats mBatteryStats;
    253     private BatteryService mBatteryService;
    254     private SensorManager mSensorManager;
    255     private Sensor mProximitySensor;
    256     private Sensor mLightSensor;
    257     private boolean mLightSensorEnabled;
    258     private float mLightSensorValue = -1;
    259     private boolean mProxIgnoredBecauseScreenTurnedOff = false;
    260     private int mHighestLightSensorValue = -1;
    261     private boolean mLightSensorPendingDecrease = false;
    262     private boolean mLightSensorPendingIncrease = false;
    263     private float mLightSensorPendingValue = -1;
    264     private float mLightSensorAdjustSetting = 0;
    265     private int mLightSensorScreenBrightness = -1;
    266     private int mLightSensorButtonBrightness = -1;
    267     private int mLightSensorKeyboardBrightness = -1;
    268     private boolean mDimScreen = true;
    269     private boolean mIsDocked = false;
    270     private long mNextTimeout;
    271     private volatile int mPokey = 0;
    272     private volatile boolean mPokeAwakeOnSet = false;
    273     private volatile boolean mInitComplete = false;
    274     private final HashMap<IBinder,PokeLock> mPokeLocks = new HashMap<IBinder,PokeLock>();
    275     // mLastScreenOnTime is the time the screen was last turned on
    276     private long mLastScreenOnTime;
    277     private boolean mPreventScreenOn;
    278     private int mScreenBrightnessSetting = DEFAULT_SCREEN_BRIGHTNESS;
    279     private int mScreenBrightnessOverride = -1;
    280     private int mButtonBrightnessOverride = -1;
    281     private int mScreenBrightnessDim;
    282     private boolean mUseSoftwareAutoBrightness;
    283     private boolean mAutoBrightessEnabled;
    284     private int[] mAutoBrightnessLevels;
    285     private int[] mLcdBacklightValues;
    286     private int[] mButtonBacklightValues;
    287     private int[] mKeyboardBacklightValues;
    288     private int mLightSensorWarmupTime;
    289     boolean mUnplugTurnsOnScreen;
    290     private int mWarningSpewThrottleCount;
    291     private long mWarningSpewThrottleTime;
    292     private int mAnimationSetting = ANIM_SETTING_OFF;
    293     private float mWindowScaleAnimation;
    294 
    295     // Must match with the ISurfaceComposer constants in C++.
    296     private static final int ANIM_SETTING_ON = 0x01;
    297     private static final int ANIM_SETTING_OFF = 0x10;
    298 
    299     // Used when logging number and duration of touch-down cycles
    300     private long mTotalTouchDownTime;
    301     private long mLastTouchDown;
    302     private int mTouchCycles;
    303 
    304     // could be either static or controllable at runtime
    305     private static final boolean mSpew = false;
    306     private static final boolean mDebugProximitySensor = (false || mSpew);
    307     private static final boolean mDebugLightSensor = (false || mSpew);
    308     private static final boolean mDebugLightAnimation = (false || mSpew);
    309 
    310     private native void nativeInit();
    311     private native void nativeSetPowerState(boolean screenOn, boolean screenBright);
    312     private native void nativeStartSurfaceFlingerAnimation(int mode);
    313     private static native void nativeAcquireWakeLock(int lock, String id);
    314     private static native void nativeReleaseWakeLock(String id);
    315     private static native int nativeSetScreenState(boolean on);
    316     private static native void nativeShutdown();
    317     private static native void nativeReboot(String reason) throws IOException;
    318 
    319     /*
    320     static PrintStream mLog;
    321     static {
    322         try {
    323             mLog = new PrintStream("/data/power.log");
    324         }
    325         catch (FileNotFoundException e) {
    326             android.util.Slog.e(TAG, "Life is hard", e);
    327         }
    328     }
    329     static class Log {
    330         static void d(String tag, String s) {
    331             mLog.println(s);
    332             android.util.Slog.d(tag, s);
    333         }
    334         static void i(String tag, String s) {
    335             mLog.println(s);
    336             android.util.Slog.i(tag, s);
    337         }
    338         static void w(String tag, String s) {
    339             mLog.println(s);
    340             android.util.Slog.w(tag, s);
    341         }
    342         static void e(String tag, String s) {
    343             mLog.println(s);
    344             android.util.Slog.e(tag, s);
    345         }
    346     }
    347     */
    348 
    349     /**
    350      * This class works around a deadlock between the lock in PowerManager.WakeLock
    351      * and our synchronizing on mLocks.  PowerManager.WakeLock synchronizes on its
    352      * mToken object so it can be accessed from any thread, but it calls into here
    353      * with its lock held.  This class is essentially a reimplementation of
    354      * PowerManager.WakeLock, but without that extra synchronized block, because we'll
    355      * only call it with our own locks held.
    356      */
    357     private class UnsynchronizedWakeLock {
    358         int mFlags;
    359         String mTag;
    360         IBinder mToken;
    361         int mCount = 0;
    362         boolean mRefCounted;
    363         boolean mHeld;
    364 
    365         UnsynchronizedWakeLock(int flags, String tag, boolean refCounted) {
    366             mFlags = flags;
    367             mTag = tag;
    368             mToken = new Binder();
    369             mRefCounted = refCounted;
    370         }
    371 
    372         public void acquire() {
    373             if (!mRefCounted || mCount++ == 0) {
    374                 long ident = Binder.clearCallingIdentity();
    375                 try {
    376                     PowerManagerService.this.acquireWakeLockLocked(mFlags, mToken,
    377                             MY_UID, MY_PID, mTag, null);
    378                     mHeld = true;
    379                 } finally {
    380                     Binder.restoreCallingIdentity(ident);
    381                 }
    382             }
    383         }
    384 
    385         public void release() {
    386             if (!mRefCounted || --mCount == 0) {
    387                 PowerManagerService.this.releaseWakeLockLocked(mToken, 0, false);
    388                 mHeld = false;
    389             }
    390             if (mCount < 0) {
    391                 throw new RuntimeException("WakeLock under-locked " + mTag);
    392             }
    393         }
    394 
    395         public boolean isHeld()
    396         {
    397             return mHeld;
    398         }
    399 
    400         public String toString() {
    401             return "UnsynchronizedWakeLock(mFlags=0x" + Integer.toHexString(mFlags)
    402                     + " mCount=" + mCount + " mHeld=" + mHeld + ")";
    403         }
    404     }
    405 
    406     private final class BatteryReceiver extends BroadcastReceiver {
    407         @Override
    408         public void onReceive(Context context, Intent intent) {
    409             synchronized (mLocks) {
    410                 boolean wasPowered = mIsPowered;
    411                 mIsPowered = mBatteryService.isPowered();
    412 
    413                 if (mIsPowered != wasPowered) {
    414                     // update mStayOnWhilePluggedIn wake lock
    415                     updateWakeLockLocked();
    416 
    417                     // treat plugging and unplugging the devices as a user activity.
    418                     // users find it disconcerting when they unplug the device
    419                     // and it shuts off right away.
    420                     // to avoid turning on the screen when unplugging, we only trigger
    421                     // user activity when screen was already on.
    422                     // temporarily set mUserActivityAllowed to true so this will work
    423                     // even when the keyguard is on.
    424                     // However, you can also set config_unplugTurnsOnScreen to have it
    425                     // turn on.  Some devices want this because they don't have a
    426                     // charging LED.
    427                     synchronized (mLocks) {
    428                         if (!wasPowered || (mPowerState & SCREEN_ON_BIT) != 0 ||
    429                                 mUnplugTurnsOnScreen) {
    430                             forceUserActivityLocked();
    431                         }
    432                     }
    433                 }
    434             }
    435         }
    436     }
    437 
    438     private final class BootCompletedReceiver extends BroadcastReceiver {
    439         @Override
    440         public void onReceive(Context context, Intent intent) {
    441             bootCompleted();
    442         }
    443     }
    444 
    445     private final class DockReceiver extends BroadcastReceiver {
    446         @Override
    447         public void onReceive(Context context, Intent intent) {
    448             int state = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
    449                     Intent.EXTRA_DOCK_STATE_UNDOCKED);
    450             dockStateChanged(state);
    451         }
    452     }
    453 
    454     /**
    455      * Set the setting that determines whether the device stays on when plugged in.
    456      * The argument is a bit string, with each bit specifying a power source that,
    457      * when the device is connected to that source, causes the device to stay on.
    458      * See {@link android.os.BatteryManager} for the list of power sources that
    459      * can be specified. Current values include {@link android.os.BatteryManager#BATTERY_PLUGGED_AC}
    460      * and {@link android.os.BatteryManager#BATTERY_PLUGGED_USB}
    461      * @param val an {@code int} containing the bits that specify which power sources
    462      * should cause the device to stay on.
    463      */
    464     public void setStayOnSetting(int val) {
    465         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS, null);
    466         Settings.System.putInt(mContext.getContentResolver(),
    467                 Settings.System.STAY_ON_WHILE_PLUGGED_IN, val);
    468     }
    469 
    470     public void setMaximumScreenOffTimeount(int timeMs) {
    471         mContext.enforceCallingOrSelfPermission(
    472                 android.Manifest.permission.WRITE_SECURE_SETTINGS, null);
    473         synchronized (mLocks) {
    474             mMaximumScreenOffTimeout = timeMs;
    475             // recalculate everything
    476             setScreenOffTimeoutsLocked();
    477         }
    478     }
    479 
    480     int getStayOnConditionsLocked() {
    481         return mMaximumScreenOffTimeout <= 0 || mMaximumScreenOffTimeout == Integer.MAX_VALUE
    482                 ? mStayOnConditions : 0;
    483     }
    484 
    485     private class SettingsObserver implements Observer {
    486         private int getInt(String name, int defValue) {
    487             ContentValues values = mSettings.getValues(name);
    488             Integer iVal = values != null ? values.getAsInteger(Settings.System.VALUE) : null;
    489             return iVal != null ? iVal : defValue;
    490         }
    491 
    492         private float getFloat(String name, float defValue) {
    493             ContentValues values = mSettings.getValues(name);
    494             Float fVal = values != null ? values.getAsFloat(Settings.System.VALUE) : null;
    495             return fVal != null ? fVal : defValue;
    496         }
    497 
    498         public void update(Observable o, Object arg) {
    499             synchronized (mLocks) {
    500                 // STAY_ON_WHILE_PLUGGED_IN, default to when plugged into AC
    501                 mStayOnConditions = getInt(STAY_ON_WHILE_PLUGGED_IN,
    502                         BatteryManager.BATTERY_PLUGGED_AC);
    503                 updateWakeLockLocked();
    504 
    505                 // SCREEN_OFF_TIMEOUT, default to 15 seconds
    506                 mScreenOffTimeoutSetting = getInt(SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT);
    507 
    508                 // DIM_SCREEN
    509                 //mDimScreen = getInt(DIM_SCREEN) != 0;
    510 
    511                 mScreenBrightnessSetting = getInt(SCREEN_BRIGHTNESS, DEFAULT_SCREEN_BRIGHTNESS);
    512                 mLightSensorAdjustSetting = 0; //getFloat(SCREEN_AUTO_BRIGHTNESS_ADJ, 0);
    513 
    514                 // SCREEN_BRIGHTNESS_MODE, default to manual
    515                 setScreenBrightnessMode(getInt(SCREEN_BRIGHTNESS_MODE,
    516                         Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL));
    517 
    518                 // recalculate everything
    519                 setScreenOffTimeoutsLocked();
    520 
    521                 mWindowScaleAnimation = getFloat(WINDOW_ANIMATION_SCALE, 1.0f);
    522                 final float transitionScale = getFloat(TRANSITION_ANIMATION_SCALE, 1.0f);
    523                 mAnimationSetting = 0;
    524                 if (mWindowScaleAnimation > 0.5f) {
    525                     mAnimationSetting |= ANIM_SETTING_OFF;
    526                 }
    527                 if (transitionScale > 0.5f) {
    528                     // Uncomment this if you want the screen-on animation.
    529                     // mAnimationSetting |= ANIM_SETTING_ON;
    530                 }
    531             }
    532         }
    533     }
    534 
    535     PowerManagerService() {
    536         // Hack to get our uid...  should have a func for this.
    537         long token = Binder.clearCallingIdentity();
    538         MY_UID = Process.myUid();
    539         MY_PID = Process.myPid();
    540         Binder.restoreCallingIdentity(token);
    541 
    542         // assume nothing is on yet
    543         mUserState = mPowerState = 0;
    544 
    545         // Add ourself to the Watchdog monitors.
    546         Watchdog.getInstance().addMonitor(this);
    547 
    548         nativeInit();
    549     }
    550 
    551     private ContentQueryMap mSettings;
    552 
    553     void init(Context context, LightsService lights, IActivityManager activity,
    554             BatteryService battery) {
    555         mLightsService = lights;
    556         mContext = context;
    557         mActivityService = activity;
    558         mBatteryStats = BatteryStatsService.getService();
    559         mBatteryService = battery;
    560 
    561         mLcdLight = lights.getLight(LightsService.LIGHT_ID_BACKLIGHT);
    562         mButtonLight = lights.getLight(LightsService.LIGHT_ID_BUTTONS);
    563         mKeyboardLight = lights.getLight(LightsService.LIGHT_ID_KEYBOARD);
    564         mAttentionLight = lights.getLight(LightsService.LIGHT_ID_ATTENTION);
    565         mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
    566 
    567         mInitComplete = false;
    568         mScreenBrightnessAnimator = new ScreenBrightnessAnimator("mScreenBrightnessUpdaterThread",
    569                 Process.THREAD_PRIORITY_DISPLAY);
    570         mScreenBrightnessAnimator.start();
    571 
    572         synchronized (mScreenBrightnessAnimator) {
    573             while (!mInitComplete) {
    574                 try {
    575                     mScreenBrightnessAnimator.wait();
    576                 } catch (InterruptedException e) {
    577                     // Ignore
    578                 }
    579             }
    580         }
    581 
    582         mInitComplete = false;
    583         mHandlerThread = new HandlerThread("PowerManagerService") {
    584             @Override
    585             protected void onLooperPrepared() {
    586                 super.onLooperPrepared();
    587                 initInThread();
    588             }
    589         };
    590         mHandlerThread.start();
    591 
    592         synchronized (mHandlerThread) {
    593             while (!mInitComplete) {
    594                 try {
    595                     mHandlerThread.wait();
    596                 } catch (InterruptedException e) {
    597                     // Ignore
    598                 }
    599             }
    600         }
    601 
    602         synchronized (mLocks) {
    603             updateNativePowerStateLocked();
    604             // We make sure to start out with the screen on due to user activity.
    605             // (They did just boot their device, after all.)
    606             forceUserActivityLocked();
    607             mInitialized = true;
    608         }
    609     }
    610 
    611     void initInThread() {
    612         mHandler = new Handler();
    613 
    614         mBroadcastWakeLock = new UnsynchronizedWakeLock(
    615                                 PowerManager.PARTIAL_WAKE_LOCK, "sleep_broadcast", true);
    616         mStayOnWhilePluggedInScreenDimLock = new UnsynchronizedWakeLock(
    617                                 PowerManager.SCREEN_DIM_WAKE_LOCK, "StayOnWhilePluggedIn Screen Dim", false);
    618         mStayOnWhilePluggedInPartialLock = new UnsynchronizedWakeLock(
    619                                 PowerManager.PARTIAL_WAKE_LOCK, "StayOnWhilePluggedIn Partial", false);
    620         mPreventScreenOnPartialLock = new UnsynchronizedWakeLock(
    621                                 PowerManager.PARTIAL_WAKE_LOCK, "PreventScreenOn Partial", false);
    622         mProximityPartialLock = new UnsynchronizedWakeLock(
    623                                 PowerManager.PARTIAL_WAKE_LOCK, "Proximity Partial", false);
    624 
    625         mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
    626         mScreenOnIntent.addFlags(
    627                 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
    628         mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF);
    629         mScreenOffIntent.addFlags(
    630                 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
    631 
    632         Resources resources = mContext.getResources();
    633 
    634         mAnimateScreenLights = resources.getBoolean(
    635                 com.android.internal.R.bool.config_animateScreenLights);
    636 
    637         mUnplugTurnsOnScreen = resources.getBoolean(
    638                 com.android.internal.R.bool.config_unplugTurnsOnScreen);
    639 
    640         mScreenBrightnessDim = resources.getInteger(
    641                 com.android.internal.R.integer.config_screenBrightnessDim);
    642 
    643         // read settings for auto-brightness
    644         mUseSoftwareAutoBrightness = resources.getBoolean(
    645                 com.android.internal.R.bool.config_automatic_brightness_available);
    646         if (mUseSoftwareAutoBrightness) {
    647             mAutoBrightnessLevels = resources.getIntArray(
    648                     com.android.internal.R.array.config_autoBrightnessLevels);
    649             mLcdBacklightValues = resources.getIntArray(
    650                     com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
    651             mButtonBacklightValues = resources.getIntArray(
    652                     com.android.internal.R.array.config_autoBrightnessButtonBacklightValues);
    653             mKeyboardBacklightValues = resources.getIntArray(
    654                     com.android.internal.R.array.config_autoBrightnessKeyboardBacklightValues);
    655             mLightSensorWarmupTime = resources.getInteger(
    656                     com.android.internal.R.integer.config_lightSensorWarmupTime);
    657         }
    658 
    659        ContentResolver resolver = mContext.getContentResolver();
    660         Cursor settingsCursor = resolver.query(Settings.System.CONTENT_URI, null,
    661                 "(" + Settings.System.NAME + "=?) or ("
    662                         + Settings.System.NAME + "=?) or ("
    663                         + Settings.System.NAME + "=?) or ("
    664                         + Settings.System.NAME + "=?) or ("
    665                         + Settings.System.NAME + "=?) or ("
    666                         + Settings.System.NAME + "=?) or ("
    667                         + Settings.System.NAME + "=?) or ("
    668                         + Settings.System.NAME + "=?)",
    669                 new String[]{STAY_ON_WHILE_PLUGGED_IN, SCREEN_OFF_TIMEOUT, DIM_SCREEN, SCREEN_BRIGHTNESS,
    670                         SCREEN_BRIGHTNESS_MODE, /*SCREEN_AUTO_BRIGHTNESS_ADJ,*/
    671                         WINDOW_ANIMATION_SCALE, TRANSITION_ANIMATION_SCALE},
    672                 null);
    673         mSettings = new ContentQueryMap(settingsCursor, Settings.System.NAME, true, mHandler);
    674         SettingsObserver settingsObserver = new SettingsObserver();
    675         mSettings.addObserver(settingsObserver);
    676 
    677         // pretend that the settings changed so we will get their initial state
    678         settingsObserver.update(mSettings, null);
    679 
    680         // register for the battery changed notifications
    681         IntentFilter filter = new IntentFilter();
    682         filter.addAction(Intent.ACTION_BATTERY_CHANGED);
    683         mContext.registerReceiver(new BatteryReceiver(), filter);
    684         filter = new IntentFilter();
    685         filter.addAction(Intent.ACTION_BOOT_COMPLETED);
    686         mContext.registerReceiver(new BootCompletedReceiver(), filter);
    687         filter = new IntentFilter();
    688         filter.addAction(Intent.ACTION_DOCK_EVENT);
    689         mContext.registerReceiver(new DockReceiver(), filter);
    690 
    691         // Listen for secure settings changes
    692         mContext.getContentResolver().registerContentObserver(
    693             Settings.Secure.CONTENT_URI, true,
    694             new ContentObserver(new Handler()) {
    695                 public void onChange(boolean selfChange) {
    696                     updateSettingsValues();
    697                 }
    698             });
    699         updateSettingsValues();
    700 
    701         synchronized (mHandlerThread) {
    702             mInitComplete = true;
    703             mHandlerThread.notifyAll();
    704         }
    705     }
    706 
    707     /**
    708      * Low-level function turn the device off immediately, without trying
    709      * to be clean.  Most people should use
    710      * {@link com.android.server.pm.internal.app.ShutdownThread} for a clean shutdown.
    711      */
    712     public static void lowLevelShutdown() {
    713         nativeShutdown();
    714     }
    715 
    716     /**
    717      * Low-level function to reboot the device.
    718      *
    719      * @param reason code to pass to the kernel (e.g. "recovery"), or null.
    720      * @throws IOException if reboot fails for some reason (eg, lack of
    721      *         permission)
    722      */
    723     public static void lowLevelReboot(String reason) throws IOException {
    724         nativeReboot(reason);
    725     }
    726 
    727     private class WakeLock implements IBinder.DeathRecipient
    728     {
    729         WakeLock(int f, IBinder b, String t, int u, int p) {
    730             super();
    731             flags = f;
    732             binder = b;
    733             tag = t;
    734             uid = u == MY_UID ? Process.SYSTEM_UID : u;
    735             pid = p;
    736             if (u != MY_UID || (
    737                     !"KEEP_SCREEN_ON_FLAG".equals(tag)
    738                     && !"KeyInputQueue".equals(tag))) {
    739                 monitorType = (f & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK
    740                         ? BatteryStats.WAKE_TYPE_PARTIAL
    741                         : BatteryStats.WAKE_TYPE_FULL;
    742             } else {
    743                 monitorType = -1;
    744             }
    745             try {
    746                 b.linkToDeath(this, 0);
    747             } catch (RemoteException e) {
    748                 binderDied();
    749             }
    750         }
    751         public void binderDied() {
    752             synchronized (mLocks) {
    753                 releaseWakeLockLocked(this.binder, 0, true);
    754             }
    755         }
    756         final int flags;
    757         final IBinder binder;
    758         final String tag;
    759         final int uid;
    760         final int pid;
    761         final int monitorType;
    762         WorkSource ws;
    763         boolean activated = true;
    764         int minState;
    765     }
    766 
    767     private void updateWakeLockLocked() {
    768         final int stayOnConditions = getStayOnConditionsLocked();
    769         if (stayOnConditions != 0 && mBatteryService.isPowered(stayOnConditions)) {
    770             // keep the device on if we're plugged in and mStayOnWhilePluggedIn is set.
    771             mStayOnWhilePluggedInScreenDimLock.acquire();
    772             mStayOnWhilePluggedInPartialLock.acquire();
    773         } else {
    774             mStayOnWhilePluggedInScreenDimLock.release();
    775             mStayOnWhilePluggedInPartialLock.release();
    776         }
    777     }
    778 
    779     private boolean isScreenLock(int flags)
    780     {
    781         int n = flags & LOCK_MASK;
    782         return n == PowerManager.FULL_WAKE_LOCK
    783                 || n == PowerManager.SCREEN_BRIGHT_WAKE_LOCK
    784                 || n == PowerManager.SCREEN_DIM_WAKE_LOCK
    785                 || n == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK;
    786     }
    787 
    788     void enforceWakeSourcePermission(int uid, int pid) {
    789         if (uid == Process.myUid()) {
    790             return;
    791         }
    792         mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
    793                 pid, uid, null);
    794     }
    795 
    796     public void acquireWakeLock(int flags, IBinder lock, String tag, WorkSource ws) {
    797         int uid = Binder.getCallingUid();
    798         int pid = Binder.getCallingPid();
    799         if (uid != Process.myUid()) {
    800             mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
    801         }
    802         if (ws != null) {
    803             enforceWakeSourcePermission(uid, pid);
    804         }
    805         long ident = Binder.clearCallingIdentity();
    806         try {
    807             synchronized (mLocks) {
    808                 acquireWakeLockLocked(flags, lock, uid, pid, tag, ws);
    809             }
    810         } finally {
    811             Binder.restoreCallingIdentity(ident);
    812         }
    813     }
    814 
    815     void noteStartWakeLocked(WakeLock wl, WorkSource ws) {
    816         if (wl.monitorType >= 0) {
    817             long origId = Binder.clearCallingIdentity();
    818             try {
    819                 if (ws != null) {
    820                     mBatteryStats.noteStartWakelockFromSource(ws, wl.pid, wl.tag,
    821                             wl.monitorType);
    822                 } else {
    823                     mBatteryStats.noteStartWakelock(wl.uid, wl.pid, wl.tag, wl.monitorType);
    824                 }
    825             } catch (RemoteException e) {
    826                 // Ignore
    827             } finally {
    828                 Binder.restoreCallingIdentity(origId);
    829             }
    830         }
    831     }
    832 
    833     void noteStopWakeLocked(WakeLock wl, WorkSource ws) {
    834         if (wl.monitorType >= 0) {
    835             long origId = Binder.clearCallingIdentity();
    836             try {
    837                 if (ws != null) {
    838                     mBatteryStats.noteStopWakelockFromSource(ws, wl.pid, wl.tag,
    839                             wl.monitorType);
    840                 } else {
    841                     mBatteryStats.noteStopWakelock(wl.uid, wl.pid, wl.tag, wl.monitorType);
    842                 }
    843             } catch (RemoteException e) {
    844                 // Ignore
    845             } finally {
    846                 Binder.restoreCallingIdentity(origId);
    847             }
    848         }
    849     }
    850 
    851     public void acquireWakeLockLocked(int flags, IBinder lock, int uid, int pid, String tag,
    852             WorkSource ws) {
    853         if (mSpew) {
    854             Slog.d(TAG, "acquireWakeLock flags=0x" + Integer.toHexString(flags) + " tag=" + tag);
    855         }
    856 
    857         if (ws != null && ws.size() == 0) {
    858             ws = null;
    859         }
    860 
    861         int index = mLocks.getIndex(lock);
    862         WakeLock wl;
    863         boolean newlock;
    864         boolean diffsource;
    865         WorkSource oldsource;
    866         if (index < 0) {
    867             wl = new WakeLock(flags, lock, tag, uid, pid);
    868             switch (wl.flags & LOCK_MASK)
    869             {
    870                 case PowerManager.FULL_WAKE_LOCK:
    871                     if (mUseSoftwareAutoBrightness) {
    872                         wl.minState = SCREEN_BRIGHT;
    873                     } else {
    874                         wl.minState = (mKeyboardVisible ? ALL_BRIGHT : SCREEN_BUTTON_BRIGHT);
    875                     }
    876                     break;
    877                 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
    878                     wl.minState = SCREEN_BRIGHT;
    879                     break;
    880                 case PowerManager.SCREEN_DIM_WAKE_LOCK:
    881                     wl.minState = SCREEN_DIM;
    882                     break;
    883                 case PowerManager.PARTIAL_WAKE_LOCK:
    884                 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
    885                     break;
    886                 default:
    887                     // just log and bail.  we're in the server, so don't
    888                     // throw an exception.
    889                     Slog.e(TAG, "bad wakelock type for lock '" + tag + "' "
    890                             + " flags=" + flags);
    891                     return;
    892             }
    893             mLocks.addLock(wl);
    894             if (ws != null) {
    895                 wl.ws = new WorkSource(ws);
    896             }
    897             newlock = true;
    898             diffsource = false;
    899             oldsource = null;
    900         } else {
    901             wl = mLocks.get(index);
    902             newlock = false;
    903             oldsource = wl.ws;
    904             if (oldsource != null) {
    905                 if (ws == null) {
    906                     wl.ws = null;
    907                     diffsource = true;
    908                 } else {
    909                     diffsource = oldsource.diff(ws);
    910                 }
    911             } else if (ws != null) {
    912                 diffsource = true;
    913             } else {
    914                 diffsource = false;
    915             }
    916             if (diffsource) {
    917                 wl.ws = new WorkSource(ws);
    918             }
    919         }
    920         if (isScreenLock(flags)) {
    921             // if this causes a wakeup, we reactivate all of the locks and
    922             // set it to whatever they want.  otherwise, we modulate that
    923             // by the current state so we never turn it more on than
    924             // it already is.
    925             if ((flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) {
    926                 mProximityWakeLockCount++;
    927                 if (mProximityWakeLockCount == 1) {
    928                     enableProximityLockLocked();
    929                 }
    930             } else {
    931                 if ((wl.flags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {
    932                     int oldWakeLockState = mWakeLockState;
    933                     mWakeLockState = mLocks.reactivateScreenLocksLocked();
    934 
    935                     // Disable proximity sensor if if user presses power key while we are in the
    936                     // "waiting for proximity sensor to go negative" state.
    937                     if ((mWakeLockState & SCREEN_ON_BIT) != 0
    938                             && mProximitySensorActive && mProximityWakeLockCount == 0) {
    939                         mProximitySensorActive = false;
    940                     }
    941 
    942                     if (mSpew) {
    943                         Slog.d(TAG, "wakeup here mUserState=0x" + Integer.toHexString(mUserState)
    944                                 + " mWakeLockState=0x"
    945                                 + Integer.toHexString(mWakeLockState)
    946                                 + " previous wakeLockState=0x"
    947                                 + Integer.toHexString(oldWakeLockState));
    948                     }
    949                 } else {
    950                     if (mSpew) {
    951                         Slog.d(TAG, "here mUserState=0x" + Integer.toHexString(mUserState)
    952                                 + " mLocks.gatherState()=0x"
    953                                 + Integer.toHexString(mLocks.gatherState())
    954                                 + " mWakeLockState=0x" + Integer.toHexString(mWakeLockState));
    955                     }
    956                     mWakeLockState = (mUserState | mWakeLockState) & mLocks.gatherState();
    957                 }
    958                 setPowerState(mWakeLockState | mUserState);
    959             }
    960         }
    961         else if ((flags & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK) {
    962             if (newlock) {
    963                 mPartialCount++;
    964                 if (mPartialCount == 1) {
    965                     if (LOG_PARTIAL_WL) EventLog.writeEvent(EventLogTags.POWER_PARTIAL_WAKE_STATE, 1, tag);
    966                 }
    967             }
    968             nativeAcquireWakeLock(PARTIAL_WAKE_LOCK_ID, PARTIAL_NAME);
    969         }
    970 
    971         if (diffsource) {
    972             // If the lock sources have changed, need to first release the
    973             // old ones.
    974             noteStopWakeLocked(wl, oldsource);
    975         }
    976         if (newlock || diffsource) {
    977             noteStartWakeLocked(wl, ws);
    978         }
    979     }
    980 
    981     public void updateWakeLockWorkSource(IBinder lock, WorkSource ws) {
    982         int uid = Binder.getCallingUid();
    983         int pid = Binder.getCallingPid();
    984         if (ws != null && ws.size() == 0) {
    985             ws = null;
    986         }
    987         if (ws != null) {
    988             enforceWakeSourcePermission(uid, pid);
    989         }
    990         synchronized (mLocks) {
    991             int index = mLocks.getIndex(lock);
    992             if (index < 0) {
    993                 throw new IllegalArgumentException("Wake lock not active");
    994             }
    995             WakeLock wl = mLocks.get(index);
    996             WorkSource oldsource = wl.ws;
    997             wl.ws = ws != null ? new WorkSource(ws) : null;
    998             noteStopWakeLocked(wl, oldsource);
    999             noteStartWakeLocked(wl, ws);
   1000         }
   1001     }
   1002 
   1003     public void releaseWakeLock(IBinder lock, int flags) {
   1004         int uid = Binder.getCallingUid();
   1005         if (uid != Process.myUid()) {
   1006             mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
   1007         }
   1008 
   1009         synchronized (mLocks) {
   1010             releaseWakeLockLocked(lock, flags, false);
   1011         }
   1012     }
   1013 
   1014     private void releaseWakeLockLocked(IBinder lock, int flags, boolean death) {
   1015         WakeLock wl = mLocks.removeLock(lock);
   1016         if (wl == null) {
   1017             return;
   1018         }
   1019 
   1020         if (mSpew) {
   1021             Slog.d(TAG, "releaseWakeLock flags=0x"
   1022                     + Integer.toHexString(wl.flags) + " tag=" + wl.tag);
   1023         }
   1024 
   1025         if (isScreenLock(wl.flags)) {
   1026             if ((wl.flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) {
   1027                 mProximityWakeLockCount--;
   1028                 if (mProximityWakeLockCount == 0) {
   1029                     if (mProximitySensorActive &&
   1030                             ((flags & PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE) != 0)) {
   1031                         // wait for proximity sensor to go negative before disabling sensor
   1032                         if (mDebugProximitySensor) {
   1033                             Slog.d(TAG, "waiting for proximity sensor to go negative");
   1034                         }
   1035                     } else {
   1036                         disableProximityLockLocked();
   1037                     }
   1038                 }
   1039             } else {
   1040                 mWakeLockState = mLocks.gatherState();
   1041                 // goes in the middle to reduce flicker
   1042                 if ((wl.flags & PowerManager.ON_AFTER_RELEASE) != 0) {
   1043                     userActivity(SystemClock.uptimeMillis(), -1, false, OTHER_EVENT, false, true);
   1044                 }
   1045                 setPowerState(mWakeLockState | mUserState);
   1046             }
   1047         }
   1048         else if ((wl.flags & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK) {
   1049             mPartialCount--;
   1050             if (mPartialCount == 0) {
   1051                 if (LOG_PARTIAL_WL) EventLog.writeEvent(EventLogTags.POWER_PARTIAL_WAKE_STATE, 0, wl.tag);
   1052                 nativeReleaseWakeLock(PARTIAL_NAME);
   1053             }
   1054         }
   1055         // Unlink the lock from the binder.
   1056         wl.binder.unlinkToDeath(wl, 0);
   1057 
   1058         noteStopWakeLocked(wl, wl.ws);
   1059     }
   1060 
   1061     private class PokeLock implements IBinder.DeathRecipient
   1062     {
   1063         PokeLock(int p, IBinder b, String t) {
   1064             super();
   1065             this.pokey = p;
   1066             this.binder = b;
   1067             this.tag = t;
   1068             try {
   1069                 b.linkToDeath(this, 0);
   1070             } catch (RemoteException e) {
   1071                 binderDied();
   1072             }
   1073         }
   1074         public void binderDied() {
   1075             setPokeLock(0, this.binder, this.tag);
   1076         }
   1077         int pokey;
   1078         IBinder binder;
   1079         String tag;
   1080         boolean awakeOnSet;
   1081     }
   1082 
   1083     public void setPokeLock(int pokey, IBinder token, String tag) {
   1084         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
   1085         if (token == null) {
   1086             Slog.e(TAG, "setPokeLock got null token for tag='" + tag + "'");
   1087             return;
   1088         }
   1089 
   1090         if ((pokey & POKE_LOCK_TIMEOUT_MASK) == POKE_LOCK_TIMEOUT_MASK) {
   1091             throw new IllegalArgumentException("setPokeLock can't have both POKE_LOCK_SHORT_TIMEOUT"
   1092                     + " and POKE_LOCK_MEDIUM_TIMEOUT");
   1093         }
   1094 
   1095         synchronized (mLocks) {
   1096             if (pokey != 0) {
   1097                 PokeLock p = mPokeLocks.get(token);
   1098                 int oldPokey = 0;
   1099                 if (p != null) {
   1100                     oldPokey = p.pokey;
   1101                     p.pokey = pokey;
   1102                 } else {
   1103                     p = new PokeLock(pokey, token, tag);
   1104                     mPokeLocks.put(token, p);
   1105                 }
   1106                 int oldTimeout = oldPokey & POKE_LOCK_TIMEOUT_MASK;
   1107                 int newTimeout = pokey & POKE_LOCK_TIMEOUT_MASK;
   1108                 if (((mPowerState & SCREEN_ON_BIT) == 0) && (oldTimeout != newTimeout)) {
   1109                     p.awakeOnSet = true;
   1110                 }
   1111             } else {
   1112                 PokeLock rLock = mPokeLocks.remove(token);
   1113                 if (rLock != null) {
   1114                     token.unlinkToDeath(rLock, 0);
   1115                 }
   1116             }
   1117 
   1118             int oldPokey = mPokey;
   1119             int cumulative = 0;
   1120             boolean awakeOnSet = false;
   1121             for (PokeLock p: mPokeLocks.values()) {
   1122                 cumulative |= p.pokey;
   1123                 if (p.awakeOnSet) {
   1124                     awakeOnSet = true;
   1125                 }
   1126             }
   1127             mPokey = cumulative;
   1128             mPokeAwakeOnSet = awakeOnSet;
   1129 
   1130             int oldCumulativeTimeout = oldPokey & POKE_LOCK_TIMEOUT_MASK;
   1131             int newCumulativeTimeout = pokey & POKE_LOCK_TIMEOUT_MASK;
   1132 
   1133             if (oldCumulativeTimeout != newCumulativeTimeout) {
   1134                 setScreenOffTimeoutsLocked();
   1135                 // reset the countdown timer, but use the existing nextState so it doesn't
   1136                 // change anything
   1137                 setTimeoutLocked(SystemClock.uptimeMillis(), mTimeoutTask.nextState);
   1138             }
   1139         }
   1140     }
   1141 
   1142     private static String lockType(int type)
   1143     {
   1144         switch (type)
   1145         {
   1146             case PowerManager.FULL_WAKE_LOCK:
   1147                 return "FULL_WAKE_LOCK                ";
   1148             case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
   1149                 return "SCREEN_BRIGHT_WAKE_LOCK       ";
   1150             case PowerManager.SCREEN_DIM_WAKE_LOCK:
   1151                 return "SCREEN_DIM_WAKE_LOCK          ";
   1152             case PowerManager.PARTIAL_WAKE_LOCK:
   1153                 return "PARTIAL_WAKE_LOCK             ";
   1154             case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
   1155                 return "PROXIMITY_SCREEN_OFF_WAKE_LOCK";
   1156             default:
   1157                 return "???                           ";
   1158         }
   1159     }
   1160 
   1161     private static String dumpPowerState(int state) {
   1162         return (((state & KEYBOARD_BRIGHT_BIT) != 0)
   1163                         ? "KEYBOARD_BRIGHT_BIT " : "")
   1164                 + (((state & SCREEN_BRIGHT_BIT) != 0)
   1165                         ? "SCREEN_BRIGHT_BIT " : "")
   1166                 + (((state & SCREEN_ON_BIT) != 0)
   1167                         ? "SCREEN_ON_BIT " : "")
   1168                 + (((state & BATTERY_LOW_BIT) != 0)
   1169                         ? "BATTERY_LOW_BIT " : "");
   1170     }
   1171 
   1172     @Override
   1173     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1174         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
   1175                 != PackageManager.PERMISSION_GRANTED) {
   1176             pw.println("Permission Denial: can't dump PowerManager from from pid="
   1177                     + Binder.getCallingPid()
   1178                     + ", uid=" + Binder.getCallingUid());
   1179             return;
   1180         }
   1181 
   1182         long now = SystemClock.uptimeMillis();
   1183 
   1184         synchronized (mLocks) {
   1185             pw.println("Power Manager State:");
   1186             pw.println("  mIsPowered=" + mIsPowered
   1187                     + " mPowerState=" + mPowerState
   1188                     + " mScreenOffTime=" + (SystemClock.elapsedRealtime()-mScreenOffTime)
   1189                     + " ms");
   1190             pw.println("  mPartialCount=" + mPartialCount);
   1191             pw.println("  mWakeLockState=" + dumpPowerState(mWakeLockState));
   1192             pw.println("  mUserState=" + dumpPowerState(mUserState));
   1193             pw.println("  mPowerState=" + dumpPowerState(mPowerState));
   1194             pw.println("  mLocks.gather=" + dumpPowerState(mLocks.gatherState()));
   1195             pw.println("  mNextTimeout=" + mNextTimeout + " now=" + now
   1196                     + " " + ((mNextTimeout-now)/1000) + "s from now");
   1197             pw.println("  mDimScreen=" + mDimScreen
   1198                     + " mStayOnConditions=" + mStayOnConditions
   1199                     + " mPreparingForScreenOn=" + mPreparingForScreenOn
   1200                     + " mSkippedScreenOn=" + mSkippedScreenOn);
   1201             pw.println("  mScreenOffReason=" + mScreenOffReason
   1202                     + " mUserState=" + mUserState);
   1203             pw.println("  mBroadcastQueue={" + mBroadcastQueue[0] + ',' + mBroadcastQueue[1]
   1204                     + ',' + mBroadcastQueue[2] + "}");
   1205             pw.println("  mBroadcastWhy={" + mBroadcastWhy[0] + ',' + mBroadcastWhy[1]
   1206                     + ',' + mBroadcastWhy[2] + "}");
   1207             pw.println("  mPokey=" + mPokey + " mPokeAwakeonSet=" + mPokeAwakeOnSet);
   1208             pw.println("  mKeyboardVisible=" + mKeyboardVisible
   1209                     + " mUserActivityAllowed=" + mUserActivityAllowed);
   1210             pw.println("  mKeylightDelay=" + mKeylightDelay + " mDimDelay=" + mDimDelay
   1211                     + " mScreenOffDelay=" + mScreenOffDelay);
   1212             pw.println("  mPreventScreenOn=" + mPreventScreenOn
   1213                     + "  mScreenBrightnessOverride=" + mScreenBrightnessOverride
   1214                     + "  mButtonBrightnessOverride=" + mButtonBrightnessOverride);
   1215             pw.println("  mScreenOffTimeoutSetting=" + mScreenOffTimeoutSetting
   1216                     + " mMaximumScreenOffTimeout=" + mMaximumScreenOffTimeout);
   1217             pw.println("  mLastScreenOnTime=" + mLastScreenOnTime);
   1218             pw.println("  mBroadcastWakeLock=" + mBroadcastWakeLock);
   1219             pw.println("  mStayOnWhilePluggedInScreenDimLock=" + mStayOnWhilePluggedInScreenDimLock);
   1220             pw.println("  mStayOnWhilePluggedInPartialLock=" + mStayOnWhilePluggedInPartialLock);
   1221             pw.println("  mPreventScreenOnPartialLock=" + mPreventScreenOnPartialLock);
   1222             pw.println("  mProximityPartialLock=" + mProximityPartialLock);
   1223             pw.println("  mProximityWakeLockCount=" + mProximityWakeLockCount);
   1224             pw.println("  mProximitySensorEnabled=" + mProximitySensorEnabled);
   1225             pw.println("  mProximitySensorActive=" + mProximitySensorActive);
   1226             pw.println("  mProximityPendingValue=" + mProximityPendingValue);
   1227             pw.println("  mLastProximityEventTime=" + mLastProximityEventTime);
   1228             pw.println("  mLightSensorEnabled=" + mLightSensorEnabled
   1229                     + " mLightSensorAdjustSetting=" + mLightSensorAdjustSetting);
   1230             pw.println("  mLightSensorValue=" + mLightSensorValue
   1231                     + " mLightSensorPendingValue=" + mLightSensorPendingValue);
   1232             pw.println("  mHighestLightSensorValue=" + mHighestLightSensorValue
   1233                     + " mWaitingForFirstLightSensor=" + mWaitingForFirstLightSensor);
   1234             pw.println("  mLightSensorPendingDecrease=" + mLightSensorPendingDecrease
   1235                     + " mLightSensorPendingIncrease=" + mLightSensorPendingIncrease);
   1236             pw.println("  mLightSensorScreenBrightness=" + mLightSensorScreenBrightness
   1237                     + " mLightSensorButtonBrightness=" + mLightSensorButtonBrightness
   1238                     + " mLightSensorKeyboardBrightness=" + mLightSensorKeyboardBrightness);
   1239             pw.println("  mUseSoftwareAutoBrightness=" + mUseSoftwareAutoBrightness);
   1240             pw.println("  mAutoBrightessEnabled=" + mAutoBrightessEnabled);
   1241             mScreenBrightnessAnimator.dump(pw, "mScreenBrightnessAnimator: ");
   1242 
   1243             int N = mLocks.size();
   1244             pw.println();
   1245             pw.println("mLocks.size=" + N + ":");
   1246             for (int i=0; i<N; i++) {
   1247                 WakeLock wl = mLocks.get(i);
   1248                 String type = lockType(wl.flags & LOCK_MASK);
   1249                 String acquireCausesWakeup = "";
   1250                 if ((wl.flags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {
   1251                     acquireCausesWakeup = "ACQUIRE_CAUSES_WAKEUP ";
   1252                 }
   1253                 String activated = "";
   1254                 if (wl.activated) {
   1255                    activated = " activated";
   1256                 }
   1257                 pw.println("  " + type + " '" + wl.tag + "'" + acquireCausesWakeup
   1258                         + activated + " (minState=" + wl.minState + ", uid=" + wl.uid
   1259                         + ", pid=" + wl.pid + ")");
   1260             }
   1261 
   1262             pw.println();
   1263             pw.println("mPokeLocks.size=" + mPokeLocks.size() + ":");
   1264             for (PokeLock p: mPokeLocks.values()) {
   1265                 pw.println("    poke lock '" + p.tag + "':"
   1266                         + ((p.pokey & POKE_LOCK_IGNORE_TOUCH_EVENTS) != 0
   1267                                 ? " POKE_LOCK_IGNORE_TOUCH_EVENTS" : "")
   1268                         + ((p.pokey & POKE_LOCK_SHORT_TIMEOUT) != 0
   1269                                 ? " POKE_LOCK_SHORT_TIMEOUT" : "")
   1270                         + ((p.pokey & POKE_LOCK_MEDIUM_TIMEOUT) != 0
   1271                                 ? " POKE_LOCK_MEDIUM_TIMEOUT" : ""));
   1272             }
   1273 
   1274             pw.println();
   1275         }
   1276     }
   1277 
   1278     private void setTimeoutLocked(long now, int nextState) {
   1279         setTimeoutLocked(now, -1, nextState);
   1280     }
   1281 
   1282     // If they gave a timeoutOverride it is the number of seconds
   1283     // to screen-off.  Figure out where in the countdown cycle we
   1284     // should jump to.
   1285     private void setTimeoutLocked(long now, final long originalTimeoutOverride, int nextState) {
   1286         long timeoutOverride = originalTimeoutOverride;
   1287         if (mBootCompleted) {
   1288             synchronized (mLocks) {
   1289                 long when = 0;
   1290                 if (timeoutOverride <= 0) {
   1291                     switch (nextState)
   1292                     {
   1293                         case SCREEN_BRIGHT:
   1294                             when = now + mKeylightDelay;
   1295                             break;
   1296                         case SCREEN_DIM:
   1297                             if (mDimDelay >= 0) {
   1298                                 when = now + mDimDelay;
   1299                                 break;
   1300                             } else {
   1301                                 Slog.w(TAG, "mDimDelay=" + mDimDelay + " while trying to dim");
   1302                             }
   1303                        case SCREEN_OFF:
   1304                             synchronized (mLocks) {
   1305                                 when = now + mScreenOffDelay;
   1306                             }
   1307                             break;
   1308                         default:
   1309                             when = now;
   1310                             break;
   1311                     }
   1312                 } else {
   1313                     override: {
   1314                         if (timeoutOverride <= mScreenOffDelay) {
   1315                             when = now + timeoutOverride;
   1316                             nextState = SCREEN_OFF;
   1317                             break override;
   1318                         }
   1319                         timeoutOverride -= mScreenOffDelay;
   1320 
   1321                         if (mDimDelay >= 0) {
   1322                              if (timeoutOverride <= mDimDelay) {
   1323                                 when = now + timeoutOverride;
   1324                                 nextState = SCREEN_DIM;
   1325                                 break override;
   1326                             }
   1327                             timeoutOverride -= mDimDelay;
   1328                         }
   1329 
   1330                         when = now + timeoutOverride;
   1331                         nextState = SCREEN_BRIGHT;
   1332                     }
   1333                 }
   1334                 if (mSpew) {
   1335                     Slog.d(TAG, "setTimeoutLocked now=" + now
   1336                             + " timeoutOverride=" + timeoutOverride
   1337                             + " nextState=" + nextState + " when=" + when);
   1338                 }
   1339 
   1340                 mHandler.removeCallbacks(mTimeoutTask);
   1341                 mTimeoutTask.nextState = nextState;
   1342                 mTimeoutTask.remainingTimeoutOverride = timeoutOverride > 0
   1343                         ? (originalTimeoutOverride - timeoutOverride)
   1344                         : -1;
   1345                 mHandler.postAtTime(mTimeoutTask, when);
   1346                 mNextTimeout = when; // for debugging
   1347             }
   1348         }
   1349     }
   1350 
   1351     private void cancelTimerLocked()
   1352     {
   1353         mHandler.removeCallbacks(mTimeoutTask);
   1354         mTimeoutTask.nextState = -1;
   1355     }
   1356 
   1357     private class TimeoutTask implements Runnable
   1358     {
   1359         int nextState; // access should be synchronized on mLocks
   1360         long remainingTimeoutOverride;
   1361         public void run()
   1362         {
   1363             synchronized (mLocks) {
   1364                 if (mSpew) {
   1365                     Slog.d(TAG, "user activity timeout timed out nextState=" + this.nextState);
   1366                 }
   1367 
   1368                 if (nextState == -1) {
   1369                     return;
   1370                 }
   1371 
   1372                 mUserState = this.nextState;
   1373                 setPowerState(this.nextState | mWakeLockState);
   1374 
   1375                 long now = SystemClock.uptimeMillis();
   1376 
   1377                 switch (this.nextState)
   1378                 {
   1379                     case SCREEN_BRIGHT:
   1380                         if (mDimDelay >= 0) {
   1381                             setTimeoutLocked(now, remainingTimeoutOverride, SCREEN_DIM);
   1382                             break;
   1383                         }
   1384                     case SCREEN_DIM:
   1385                         setTimeoutLocked(now, remainingTimeoutOverride, SCREEN_OFF);
   1386                         break;
   1387                 }
   1388             }
   1389         }
   1390     }
   1391 
   1392     private void sendNotificationLocked(boolean on, int why) {
   1393         if (!mInitialized) {
   1394             // No notifications sent until first initialization is done.
   1395             // This is so that when we are moving from our initial state
   1396             // which looks like the screen was off to it being on, we do not
   1397             // go through the process of waiting for the higher-level user
   1398             // space to be ready before turning up the display brightness.
   1399             // (And also do not send needless broadcasts about the screen.)
   1400             return;
   1401         }
   1402 
   1403         if (DEBUG_SCREEN_ON) {
   1404             RuntimeException here = new RuntimeException("here");
   1405             here.fillInStackTrace();
   1406             Slog.i(TAG, "sendNotificationLocked: " + on, here);
   1407         }
   1408 
   1409         if (!on) {
   1410             mStillNeedSleepNotification = false;
   1411         }
   1412 
   1413         // Add to the queue.
   1414         int index = 0;
   1415         while (mBroadcastQueue[index] != -1) {
   1416             index++;
   1417         }
   1418         mBroadcastQueue[index] = on ? 1 : 0;
   1419         mBroadcastWhy[index] = why;
   1420 
   1421         // If we added it position 2, then there is a pair that can be stripped.
   1422         // If we added it position 1 and we're turning the screen off, we can strip
   1423         // the pair and do nothing, because the screen is already off, and therefore
   1424         // keyguard has already been enabled.
   1425         // However, if we added it at position 1 and we're turning it on, then position
   1426         // 0 was to turn it off, and we can't strip that, because keyguard needs to come
   1427         // on, so have to run the queue then.
   1428         if (index == 2) {
   1429             // While we're collapsing them, if it's going off, and the new reason
   1430             // is more significant than the first, then use the new one.
   1431             if (!on && mBroadcastWhy[0] > why) {
   1432                 mBroadcastWhy[0] = why;
   1433             }
   1434             mBroadcastQueue[0] = on ? 1 : 0;
   1435             mBroadcastQueue[1] = -1;
   1436             mBroadcastQueue[2] = -1;
   1437             EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount);
   1438             mBroadcastWakeLock.release();
   1439             EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount);
   1440             mBroadcastWakeLock.release();
   1441             index = 0;
   1442         }
   1443         if (index == 1 && !on) {
   1444             mBroadcastQueue[0] = -1;
   1445             mBroadcastQueue[1] = -1;
   1446             index = -1;
   1447             // The wake lock was being held, but we're not actually going to do any
   1448             // broadcasts, so release the wake lock.
   1449             EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount);
   1450             mBroadcastWakeLock.release();
   1451         }
   1452 
   1453         // The broadcast queue has changed; make sure the screen is on if it
   1454         // is now possible for it to be.
   1455         if (mSkippedScreenOn) {
   1456             updateLightsLocked(mPowerState, SCREEN_ON_BIT);
   1457         }
   1458 
   1459         // Now send the message.
   1460         if (index >= 0) {
   1461             // Acquire the broadcast wake lock before changing the power
   1462             // state. It will be release after the broadcast is sent.
   1463             // We always increment the ref count for each notification in the queue
   1464             // and always decrement when that notification is handled.
   1465             mBroadcastWakeLock.acquire();
   1466             EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND, mBroadcastWakeLock.mCount);
   1467             mHandler.post(mNotificationTask);
   1468         }
   1469     }
   1470 
   1471     private WindowManagerPolicy.ScreenOnListener mScreenOnListener =
   1472             new WindowManagerPolicy.ScreenOnListener() {
   1473                 public void onScreenOn() {
   1474                     synchronized (mLocks) {
   1475                         if (mPreparingForScreenOn) {
   1476                             mPreparingForScreenOn = false;
   1477                             updateLightsLocked(mPowerState, SCREEN_ON_BIT);
   1478                             EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP,
   1479                                     4, mBroadcastWakeLock.mCount);
   1480                             mBroadcastWakeLock.release();
   1481                         }
   1482                     }
   1483                 }
   1484     };
   1485 
   1486     private Runnable mNotificationTask = new Runnable()
   1487     {
   1488         public void run()
   1489         {
   1490             while (true) {
   1491                 int value;
   1492                 int why;
   1493                 WindowManagerPolicy policy;
   1494                 synchronized (mLocks) {
   1495                     value = mBroadcastQueue[0];
   1496                     why = mBroadcastWhy[0];
   1497                     for (int i=0; i<2; i++) {
   1498                         mBroadcastQueue[i] = mBroadcastQueue[i+1];
   1499                         mBroadcastWhy[i] = mBroadcastWhy[i+1];
   1500                     }
   1501                     policy = getPolicyLocked();
   1502                     if (value == 1 && !mPreparingForScreenOn) {
   1503                         mPreparingForScreenOn = true;
   1504                         mBroadcastWakeLock.acquire();
   1505                         EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND,
   1506                                 mBroadcastWakeLock.mCount);
   1507                     }
   1508                 }
   1509                 if (value == 1) {
   1510                     mScreenOnStart = SystemClock.uptimeMillis();
   1511 
   1512                     policy.screenTurningOn(mScreenOnListener);
   1513                     try {
   1514                         ActivityManagerNative.getDefault().wakingUp();
   1515                     } catch (RemoteException e) {
   1516                         // ignore it
   1517                     }
   1518 
   1519                     if (mSpew) {
   1520                         Slog.d(TAG, "mBroadcastWakeLock=" + mBroadcastWakeLock);
   1521                     }
   1522                     if (mContext != null && ActivityManagerNative.isSystemReady()) {
   1523                         mContext.sendOrderedBroadcast(mScreenOnIntent, null,
   1524                                 mScreenOnBroadcastDone, mHandler, 0, null, null);
   1525                     } else {
   1526                         synchronized (mLocks) {
   1527                             EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 2,
   1528                                     mBroadcastWakeLock.mCount);
   1529                             mBroadcastWakeLock.release();
   1530                         }
   1531                     }
   1532                 }
   1533                 else if (value == 0) {
   1534                     mScreenOffStart = SystemClock.uptimeMillis();
   1535 
   1536                     policy.screenTurnedOff(why);
   1537                     try {
   1538                         ActivityManagerNative.getDefault().goingToSleep();
   1539                     } catch (RemoteException e) {
   1540                         // ignore it.
   1541                     }
   1542 
   1543                     if (mContext != null && ActivityManagerNative.isSystemReady()) {
   1544                         mContext.sendOrderedBroadcast(mScreenOffIntent, null,
   1545                                 mScreenOffBroadcastDone, mHandler, 0, null, null);
   1546                     } else {
   1547                         synchronized (mLocks) {
   1548                             EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 3,
   1549                                     mBroadcastWakeLock.mCount);
   1550                             updateLightsLocked(mPowerState, SCREEN_ON_BIT);
   1551                             mBroadcastWakeLock.release();
   1552                         }
   1553                     }
   1554                 }
   1555                 else {
   1556                     // If we're in this case, then this handler is running for a previous
   1557                     // paired transaction.  mBroadcastWakeLock will already have been released.
   1558                     break;
   1559                 }
   1560             }
   1561         }
   1562     };
   1563 
   1564     long mScreenOnStart;
   1565     private BroadcastReceiver mScreenOnBroadcastDone = new BroadcastReceiver() {
   1566         public void onReceive(Context context, Intent intent) {
   1567             synchronized (mLocks) {
   1568                 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 1,
   1569                         SystemClock.uptimeMillis() - mScreenOnStart, mBroadcastWakeLock.mCount);
   1570                 mBroadcastWakeLock.release();
   1571             }
   1572         }
   1573     };
   1574 
   1575     long mScreenOffStart;
   1576     private BroadcastReceiver mScreenOffBroadcastDone = new BroadcastReceiver() {
   1577         public void onReceive(Context context, Intent intent) {
   1578             synchronized (mLocks) {
   1579                 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 0,
   1580                         SystemClock.uptimeMillis() - mScreenOffStart, mBroadcastWakeLock.mCount);
   1581                 mBroadcastWakeLock.release();
   1582             }
   1583         }
   1584     };
   1585 
   1586     void logPointerUpEvent() {
   1587         if (LOG_TOUCH_DOWNS) {
   1588             mTotalTouchDownTime += SystemClock.elapsedRealtime() - mLastTouchDown;
   1589             mLastTouchDown = 0;
   1590         }
   1591     }
   1592 
   1593     void logPointerDownEvent() {
   1594         if (LOG_TOUCH_DOWNS) {
   1595             // If we are not already timing a down/up sequence
   1596             if (mLastTouchDown == 0) {
   1597                 mLastTouchDown = SystemClock.elapsedRealtime();
   1598                 mTouchCycles++;
   1599             }
   1600         }
   1601     }
   1602 
   1603     /**
   1604      * Prevents the screen from turning on even if it *should* turn on due
   1605      * to a subsequent full wake lock being acquired.
   1606      * <p>
   1607      * This is a temporary hack that allows an activity to "cover up" any
   1608      * display glitches that happen during the activity's startup
   1609      * sequence.  (Specifically, this API was added to work around a
   1610      * cosmetic bug in the "incoming call" sequence, where the lock screen
   1611      * would flicker briefly before the incoming call UI became visible.)
   1612      * TODO: There ought to be a more elegant way of doing this,
   1613      * probably by having the PowerManager and ActivityManager
   1614      * work together to let apps specify that the screen on/off
   1615      * state should be synchronized with the Activity lifecycle.
   1616      * <p>
   1617      * Note that calling preventScreenOn(true) will NOT turn the screen
   1618      * off if it's currently on.  (This API only affects *future*
   1619      * acquisitions of full wake locks.)
   1620      * But calling preventScreenOn(false) WILL turn the screen on if
   1621      * it's currently off because of a prior preventScreenOn(true) call.
   1622      * <p>
   1623      * Any call to preventScreenOn(true) MUST be followed promptly by a call
   1624      * to preventScreenOn(false).  In fact, if the preventScreenOn(false)
   1625      * call doesn't occur within 5 seconds, we'll turn the screen back on
   1626      * ourselves (and log a warning about it); this prevents a buggy app
   1627      * from disabling the screen forever.)
   1628      * <p>
   1629      * TODO: this feature should really be controlled by a new type of poke
   1630      * lock (rather than an IPowerManager call).
   1631      */
   1632     public void preventScreenOn(boolean prevent) {
   1633         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
   1634 
   1635         synchronized (mLocks) {
   1636             if (prevent) {
   1637                 // First of all, grab a partial wake lock to
   1638                 // make sure the CPU stays on during the entire
   1639                 // preventScreenOn(true) -> preventScreenOn(false) sequence.
   1640                 mPreventScreenOnPartialLock.acquire();
   1641 
   1642                 // Post a forceReenableScreen() call (for 5 seconds in the
   1643                 // future) to make sure the matching preventScreenOn(false) call
   1644                 // has happened by then.
   1645                 mHandler.removeCallbacks(mForceReenableScreenTask);
   1646                 mHandler.postDelayed(mForceReenableScreenTask, 5000);
   1647 
   1648                 // Finally, set the flag that prevents the screen from turning on.
   1649                 // (Below, in setPowerState(), we'll check mPreventScreenOn and
   1650                 // we *won't* call setScreenStateLocked(true) if it's set.)
   1651                 mPreventScreenOn = true;
   1652             } else {
   1653                 // (Re)enable the screen.
   1654                 mPreventScreenOn = false;
   1655 
   1656                 // We're "undoing" a the prior preventScreenOn(true) call, so we
   1657                 // no longer need the 5-second safeguard.
   1658                 mHandler.removeCallbacks(mForceReenableScreenTask);
   1659 
   1660                 // Forcibly turn on the screen if it's supposed to be on.  (This
   1661                 // handles the case where the screen is currently off because of
   1662                 // a prior preventScreenOn(true) call.)
   1663                 if (!mProximitySensorActive && (mPowerState & SCREEN_ON_BIT) != 0) {
   1664                     if (mSpew) {
   1665                         Slog.d(TAG,
   1666                               "preventScreenOn: turning on after a prior preventScreenOn(true)!");
   1667                     }
   1668                     int err = setScreenStateLocked(true);
   1669                     if (err != 0) {
   1670                         Slog.w(TAG, "preventScreenOn: error from setScreenStateLocked(): " + err);
   1671                     }
   1672                 }
   1673 
   1674                 // Release the partial wake lock that we held during the
   1675                 // preventScreenOn(true) -> preventScreenOn(false) sequence.
   1676                 mPreventScreenOnPartialLock.release();
   1677             }
   1678         }
   1679     }
   1680 
   1681     public void setScreenBrightnessOverride(int brightness) {
   1682         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
   1683 
   1684         if (mSpew) Slog.d(TAG, "setScreenBrightnessOverride " + brightness);
   1685         synchronized (mLocks) {
   1686             if (mScreenBrightnessOverride != brightness) {
   1687                 mScreenBrightnessOverride = brightness;
   1688                 if (isScreenOn()) {
   1689                     updateLightsLocked(mPowerState, SCREEN_ON_BIT);
   1690                 }
   1691             }
   1692         }
   1693     }
   1694 
   1695     public void setButtonBrightnessOverride(int brightness) {
   1696         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
   1697 
   1698         if (mSpew) Slog.d(TAG, "setButtonBrightnessOverride " + brightness);
   1699          synchronized (mLocks) {
   1700            if (mButtonBrightnessOverride != brightness) {
   1701                 mButtonBrightnessOverride = brightness;
   1702                 if (isScreenOn()) {
   1703                     updateLightsLocked(mPowerState, BUTTON_BRIGHT_BIT | KEYBOARD_BRIGHT_BIT);
   1704                 }
   1705             }
   1706         }
   1707     }
   1708 
   1709     /**
   1710      * Sanity-check that gets called 5 seconds after any call to
   1711      * preventScreenOn(true).  This ensures that the original call
   1712      * is followed promptly by a call to preventScreenOn(false).
   1713      */
   1714     private void forceReenableScreen() {
   1715         // We shouldn't get here at all if mPreventScreenOn is false, since
   1716         // we should have already removed any existing
   1717         // mForceReenableScreenTask messages...
   1718         if (!mPreventScreenOn) {
   1719             Slog.w(TAG, "forceReenableScreen: mPreventScreenOn is false, nothing to do");
   1720             return;
   1721         }
   1722 
   1723         // Uh oh.  It's been 5 seconds since a call to
   1724         // preventScreenOn(true) and we haven't re-enabled the screen yet.
   1725         // This means the app that called preventScreenOn(true) is either
   1726         // slow (i.e. it took more than 5 seconds to call preventScreenOn(false)),
   1727         // or buggy (i.e. it forgot to call preventScreenOn(false), or
   1728         // crashed before doing so.)
   1729 
   1730         // Log a warning, and forcibly turn the screen back on.
   1731         Slog.w(TAG, "App called preventScreenOn(true) but didn't promptly reenable the screen! "
   1732               + "Forcing the screen back on...");
   1733         preventScreenOn(false);
   1734     }
   1735 
   1736     private Runnable mForceReenableScreenTask = new Runnable() {
   1737             public void run() {
   1738                 forceReenableScreen();
   1739             }
   1740         };
   1741 
   1742     private int setScreenStateLocked(boolean on) {
   1743         if (DEBUG_SCREEN_ON) {
   1744             RuntimeException e = new RuntimeException("here");
   1745             e.fillInStackTrace();
   1746             Slog.i(TAG, "Set screen state: " + on, e);
   1747         }
   1748         if (on) {
   1749             if (mInitialized && ((mPowerState & SCREEN_ON_BIT) == 0 || mSkippedScreenOn)) {
   1750                 // If we are turning the screen state on, but the screen
   1751                 // light is currently off, then make sure that we set the
   1752                 // light at this point to 0.  This is the case where we are
   1753                 // turning on the screen and waiting for the UI to be drawn
   1754                 // before showing it to the user.  We want the light off
   1755                 // until it is ready to be shown to the user, not it using
   1756                 // whatever the last value it had.
   1757                 // Skip this if the screen is being turned on for the first time
   1758                 // after boot (mInitialized is false).
   1759                 if (DEBUG_SCREEN_ON) {
   1760                     Slog.i(TAG, "Forcing brightness 0: mPowerState=0x"
   1761                             + Integer.toHexString(mPowerState)
   1762                             + " mSkippedScreenOn=" + mSkippedScreenOn);
   1763                 }
   1764                 mScreenBrightnessAnimator.animateTo(PowerManager.BRIGHTNESS_OFF, SCREEN_BRIGHT_BIT, 0);
   1765             }
   1766         }
   1767         int err = nativeSetScreenState(on);
   1768         if (err == 0) {
   1769             mLastScreenOnTime = (on ? SystemClock.elapsedRealtime() : 0);
   1770             if (mUseSoftwareAutoBrightness) {
   1771                 enableLightSensorLocked(on);
   1772                 if (on) {
   1773                     // If AutoBrightness is enabled, set the brightness immediately after the
   1774                     // next sensor value is received.
   1775                     mWaitingForFirstLightSensor = mAutoBrightessEnabled;
   1776                 } else {
   1777                     // make sure button and key backlights are off too
   1778                     mButtonLight.turnOff();
   1779                     mKeyboardLight.turnOff();
   1780                 }
   1781             }
   1782         }
   1783         return err;
   1784     }
   1785 
   1786     private void setPowerState(int state)
   1787     {
   1788         setPowerState(state, false, WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT);
   1789     }
   1790 
   1791     private void setPowerState(int newState, boolean noChangeLights, int reason)
   1792     {
   1793         synchronized (mLocks) {
   1794             int err;
   1795 
   1796             if (mSpew) {
   1797                 Slog.d(TAG, "setPowerState: mPowerState=0x" + Integer.toHexString(mPowerState)
   1798                         + " newState=0x" + Integer.toHexString(newState)
   1799                         + " noChangeLights=" + noChangeLights
   1800                         + " reason=" + reason);
   1801             }
   1802 
   1803             if (noChangeLights) {
   1804                 newState = (newState & ~LIGHTS_MASK) | (mPowerState & LIGHTS_MASK);
   1805             }
   1806             if (mProximitySensorActive) {
   1807                 // don't turn on the screen when the proximity sensor lock is held
   1808                 newState = (newState & ~SCREEN_BRIGHT);
   1809             }
   1810 
   1811             if (batteryIsLow()) {
   1812                 newState |= BATTERY_LOW_BIT;
   1813             } else {
   1814                 newState &= ~BATTERY_LOW_BIT;
   1815             }
   1816             if (newState == mPowerState && mInitialized) {
   1817                 return;
   1818             }
   1819 
   1820             if (!mBootCompleted && !mUseSoftwareAutoBrightness) {
   1821                 newState |= ALL_BRIGHT;
   1822             }
   1823 
   1824             boolean oldScreenOn = (mPowerState & SCREEN_ON_BIT) != 0;
   1825             boolean newScreenOn = (newState & SCREEN_ON_BIT) != 0;
   1826 
   1827             if (mSpew) {
   1828                 Slog.d(TAG, "setPowerState: mPowerState=" + mPowerState
   1829                         + " newState=" + newState + " noChangeLights=" + noChangeLights);
   1830                 Slog.d(TAG, "  oldKeyboardBright=" + ((mPowerState & KEYBOARD_BRIGHT_BIT) != 0)
   1831                          + " newKeyboardBright=" + ((newState & KEYBOARD_BRIGHT_BIT) != 0));
   1832                 Slog.d(TAG, "  oldScreenBright=" + ((mPowerState & SCREEN_BRIGHT_BIT) != 0)
   1833                          + " newScreenBright=" + ((newState & SCREEN_BRIGHT_BIT) != 0));
   1834                 Slog.d(TAG, "  oldButtonBright=" + ((mPowerState & BUTTON_BRIGHT_BIT) != 0)
   1835                          + " newButtonBright=" + ((newState & BUTTON_BRIGHT_BIT) != 0));
   1836                 Slog.d(TAG, "  oldScreenOn=" + oldScreenOn
   1837                          + " newScreenOn=" + newScreenOn);
   1838                 Slog.d(TAG, "  oldBatteryLow=" + ((mPowerState & BATTERY_LOW_BIT) != 0)
   1839                          + " newBatteryLow=" + ((newState & BATTERY_LOW_BIT) != 0));
   1840             }
   1841 
   1842             final boolean stateChanged = mPowerState != newState;
   1843 
   1844             if (stateChanged && reason == WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT) {
   1845                 if (mPolicy != null && mPolicy.isScreenSaverEnabled()) {
   1846                     if (mSpew) {
   1847                         Slog.d(TAG, "setPowerState: running screen saver instead of turning off screen");
   1848                     }
   1849                     if (mPolicy.startScreenSaver()) {
   1850                         // was successful
   1851                         return;
   1852                     }
   1853                 }
   1854             }
   1855 
   1856 
   1857             if (oldScreenOn != newScreenOn) {
   1858                 if (newScreenOn) {
   1859                     // When the user presses the power button, we need to always send out the
   1860                     // notification that it's going to sleep so the keyguard goes on.  But
   1861                     // we can't do that until the screen fades out, so we don't show the keyguard
   1862                     // too early.
   1863                     if (mStillNeedSleepNotification) {
   1864                         sendNotificationLocked(false, WindowManagerPolicy.OFF_BECAUSE_OF_USER);
   1865                     }
   1866 
   1867                     // Turn on the screen UNLESS there was a prior
   1868                     // preventScreenOn(true) request.  (Note that the lifetime
   1869                     // of a single preventScreenOn() request is limited to 5
   1870                     // seconds to prevent a buggy app from disabling the
   1871                     // screen forever; see forceReenableScreen().)
   1872                     boolean reallyTurnScreenOn = true;
   1873                     if (mSpew) {
   1874                         Slog.d(TAG, "- turning screen on...  mPreventScreenOn = "
   1875                               + mPreventScreenOn);
   1876                     }
   1877 
   1878                     if (mPreventScreenOn) {
   1879                         if (mSpew) {
   1880                             Slog.d(TAG, "- PREVENTING screen from really turning on!");
   1881                         }
   1882                         reallyTurnScreenOn = false;
   1883                     }
   1884                     if (reallyTurnScreenOn) {
   1885                         err = setScreenStateLocked(true);
   1886                         long identity = Binder.clearCallingIdentity();
   1887                         try {
   1888                             mBatteryStats.noteScreenBrightness(getPreferredBrightness());
   1889                             mBatteryStats.noteScreenOn();
   1890                         } catch (RemoteException e) {
   1891                             Slog.w(TAG, "RemoteException calling noteScreenOn on BatteryStatsService", e);
   1892                         } finally {
   1893                             Binder.restoreCallingIdentity(identity);
   1894                         }
   1895                     } else {
   1896                         setScreenStateLocked(false);
   1897                         // But continue as if we really did turn the screen on...
   1898                         err = 0;
   1899                     }
   1900 
   1901                     mLastTouchDown = 0;
   1902                     mTotalTouchDownTime = 0;
   1903                     mTouchCycles = 0;
   1904                     EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, reason,
   1905                             mTotalTouchDownTime, mTouchCycles);
   1906                     if (err == 0) {
   1907                         sendNotificationLocked(true, -1);
   1908                         // Update the lights *after* taking care of turning the
   1909                         // screen on, so we do this after our notifications are
   1910                         // enqueued and thus will delay turning on the screen light
   1911                         // until the windows are correctly displayed.
   1912                         if (stateChanged) {
   1913                             updateLightsLocked(newState, 0);
   1914                         }
   1915                         mPowerState |= SCREEN_ON_BIT;
   1916                     }
   1917 
   1918                 } else {
   1919                     // Update the lights *before* taking care of turning the
   1920                     // screen off, so we can initiate any animations that are desired.
   1921                     mScreenOffReason = reason;
   1922                     if (stateChanged) {
   1923                         updateLightsLocked(newState, 0);
   1924                     }
   1925 
   1926                     // cancel light sensor task
   1927                     mHandler.removeCallbacks(mAutoBrightnessTask);
   1928                     mLightSensorPendingDecrease = false;
   1929                     mLightSensorPendingIncrease = false;
   1930                     mScreenOffTime = SystemClock.elapsedRealtime();
   1931                     long identity = Binder.clearCallingIdentity();
   1932                     try {
   1933                         mBatteryStats.noteScreenOff();
   1934                     } catch (RemoteException e) {
   1935                         Slog.w(TAG, "RemoteException calling noteScreenOff on BatteryStatsService", e);
   1936                     } finally {
   1937                         Binder.restoreCallingIdentity(identity);
   1938                     }
   1939                     mPowerState &= ~SCREEN_ON_BIT;
   1940                     if (!mScreenBrightnessAnimator.isAnimating()) {
   1941                         err = screenOffFinishedAnimatingLocked(reason);
   1942                     } else {
   1943                         err = 0;
   1944                         mLastTouchDown = 0;
   1945                     }
   1946                 }
   1947             } else if (stateChanged) {
   1948                 // Screen on/off didn't change, but lights may have.
   1949                 updateLightsLocked(newState, 0);
   1950             }
   1951 
   1952             mPowerState = (mPowerState & ~LIGHTS_MASK) | (newState & LIGHTS_MASK);
   1953 
   1954             updateNativePowerStateLocked();
   1955         }
   1956     }
   1957 
   1958     private void updateNativePowerStateLocked() {
   1959         if (!mHeadless) {
   1960             nativeSetPowerState(
   1961                     (mPowerState & SCREEN_ON_BIT) != 0,
   1962                     (mPowerState & SCREEN_BRIGHT) == SCREEN_BRIGHT);
   1963         }
   1964     }
   1965 
   1966     private int screenOffFinishedAnimatingLocked(int reason) {
   1967         // I don't think we need to check the current state here because all of these
   1968         // Power.setScreenState and sendNotificationLocked can both handle being
   1969         // called multiple times in the same state. -joeo
   1970         EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, reason, mTotalTouchDownTime,
   1971                 mTouchCycles);
   1972         mLastTouchDown = 0;
   1973         int err = setScreenStateLocked(false);
   1974         if (err == 0) {
   1975             mScreenOffReason = reason;
   1976             sendNotificationLocked(false, reason);
   1977         }
   1978         return err;
   1979     }
   1980 
   1981     private boolean batteryIsLow() {
   1982         return (!mIsPowered &&
   1983                 mBatteryService.getBatteryLevel() <= LOW_BATTERY_THRESHOLD);
   1984     }
   1985 
   1986     private boolean shouldDeferScreenOnLocked() {
   1987         if (mPreparingForScreenOn) {
   1988             // Currently waiting for confirmation from the policy that it
   1989             // is okay to turn on the screen.  Don't allow the screen to go
   1990             // on until that is done.
   1991             if (DEBUG_SCREEN_ON) Slog.i(TAG,
   1992                     "updateLights: delaying screen on due to mPreparingForScreenOn");
   1993             return true;
   1994         } else {
   1995             // If there is a screen-on command in the notification queue, we
   1996             // can't turn the screen on until it has been processed (and we
   1997             // have set mPreparingForScreenOn) or it has been dropped.
   1998             for (int i=0; i<mBroadcastQueue.length; i++) {
   1999                 if (mBroadcastQueue[i] == 1) {
   2000                     if (DEBUG_SCREEN_ON) Slog.i(TAG,
   2001                             "updateLights: delaying screen on due to notification queue");
   2002                     return true;
   2003                 }
   2004             }
   2005         }
   2006         return false;
   2007     }
   2008 
   2009     private void updateLightsLocked(int newState, int forceState) {
   2010         final int oldState = mPowerState;
   2011 
   2012         // If the screen is not currently on, we will want to delay actually
   2013         // turning the lights on if we are still getting the UI put up.
   2014         if ((oldState & SCREEN_ON_BIT) == 0 || mSkippedScreenOn) {
   2015             // Don't turn screen on until we know we are really ready to.
   2016             // This is to avoid letting the screen go on before things like the
   2017             // lock screen have been displayed.
   2018             if ((mSkippedScreenOn = shouldDeferScreenOnLocked())) {
   2019                 newState &= ~(SCREEN_ON_BIT|SCREEN_BRIGHT_BIT);
   2020             }
   2021         }
   2022 
   2023         if ((newState & SCREEN_ON_BIT) != 0) {
   2024             // Only turn on the buttons or keyboard if the screen is also on.
   2025             // We should never see the buttons on but not the screen.
   2026             newState = applyButtonState(newState);
   2027             newState = applyKeyboardState(newState);
   2028         }
   2029         final int realDifference = (newState ^ oldState);
   2030         final int difference = realDifference | forceState;
   2031         if (difference == 0) {
   2032             return;
   2033         }
   2034 
   2035         int offMask = 0;
   2036         int dimMask = 0;
   2037         int onMask = 0;
   2038 
   2039         int preferredBrightness = getPreferredBrightness();
   2040 
   2041         if ((difference & KEYBOARD_BRIGHT_BIT) != 0) {
   2042             if ((newState & KEYBOARD_BRIGHT_BIT) == 0) {
   2043                 offMask |= KEYBOARD_BRIGHT_BIT;
   2044             } else {
   2045                 onMask |= KEYBOARD_BRIGHT_BIT;
   2046             }
   2047         }
   2048 
   2049         if ((difference & BUTTON_BRIGHT_BIT) != 0) {
   2050             if ((newState & BUTTON_BRIGHT_BIT) == 0) {
   2051                 offMask |= BUTTON_BRIGHT_BIT;
   2052             } else {
   2053                 onMask |= BUTTON_BRIGHT_BIT;
   2054             }
   2055         }
   2056 
   2057         if ((difference & (SCREEN_ON_BIT | SCREEN_BRIGHT_BIT)) != 0) {
   2058             int nominalCurrentValue = -1;
   2059             // If there was an actual difference in the light state, then
   2060             // figure out the "ideal" current value based on the previous
   2061             // state.  Otherwise, this is a change due to the brightness
   2062             // override, so we want to animate from whatever the current
   2063             // value is.
   2064             if ((realDifference & (SCREEN_ON_BIT | SCREEN_BRIGHT_BIT)) != 0) {
   2065                 switch (oldState & (SCREEN_BRIGHT_BIT|SCREEN_ON_BIT)) {
   2066                     case SCREEN_BRIGHT_BIT | SCREEN_ON_BIT:
   2067                         nominalCurrentValue = preferredBrightness;
   2068                         break;
   2069                     case SCREEN_ON_BIT:
   2070                         nominalCurrentValue = mScreenBrightnessDim;
   2071                         break;
   2072                     case 0:
   2073                         nominalCurrentValue = PowerManager.BRIGHTNESS_OFF;
   2074                         break;
   2075                     case SCREEN_BRIGHT_BIT:
   2076                     default:
   2077                         // not possible
   2078                         nominalCurrentValue = (int)mScreenBrightnessAnimator.getCurrentBrightness();
   2079                         break;
   2080                 }
   2081             }
   2082             int brightness = preferredBrightness;
   2083             int steps = ANIM_STEPS;
   2084             if ((newState & SCREEN_BRIGHT_BIT) == 0) {
   2085                 // dim or turn off backlight, depending on if the screen is on
   2086                 // the scale is because the brightness ramp isn't linear and this biases
   2087                 // it so the later parts take longer.
   2088                 final float scale = 1.5f;
   2089                 float ratio = (((float)mScreenBrightnessDim)/preferredBrightness);
   2090                 if (ratio > 1.0f) ratio = 1.0f;
   2091                 if ((newState & SCREEN_ON_BIT) == 0) {
   2092                     if ((oldState & SCREEN_BRIGHT_BIT) != 0) {
   2093                         // was bright
   2094                         steps = ANIM_STEPS;
   2095                     } else {
   2096                         // was dim
   2097                         steps = (int)(ANIM_STEPS*ratio*scale);
   2098                     }
   2099                     brightness = PowerManager.BRIGHTNESS_OFF;
   2100                 } else {
   2101                     if ((oldState & SCREEN_ON_BIT) != 0) {
   2102                         // was bright
   2103                         steps = (int)(ANIM_STEPS*(1.0f-ratio)*scale);
   2104                     } else {
   2105                         // was dim
   2106                         steps = (int)(ANIM_STEPS*ratio);
   2107                     }
   2108                     final int stayOnConditions = getStayOnConditionsLocked();
   2109                     if (stayOnConditions != 0 && mBatteryService.isPowered(stayOnConditions)) {
   2110                         // If the "stay on while plugged in" option is
   2111                         // turned on, then the screen will often not
   2112                         // automatically turn off while plugged in.  To
   2113                         // still have a sense of when it is inactive, we
   2114                         // will then count going dim as turning off.
   2115                         mScreenOffTime = SystemClock.elapsedRealtime();
   2116                     }
   2117                     brightness = mScreenBrightnessDim;
   2118                 }
   2119             }
   2120             if (mWaitingForFirstLightSensor && (newState & SCREEN_ON_BIT) != 0) {
   2121                 steps = IMMEDIATE_ANIM_STEPS;
   2122             }
   2123 
   2124             long identity = Binder.clearCallingIdentity();
   2125             try {
   2126                 mBatteryStats.noteScreenBrightness(brightness);
   2127             } catch (RemoteException e) {
   2128                 // Nothing interesting to do.
   2129             } finally {
   2130                 Binder.restoreCallingIdentity(identity);
   2131             }
   2132             if (!mSkippedScreenOn) {
   2133                 int dt = steps * NOMINAL_FRAME_TIME_MS;
   2134                 mScreenBrightnessAnimator.animateTo(brightness, SCREEN_BRIGHT_BIT, dt);
   2135                 if (DEBUG_SCREEN_ON) {
   2136                     RuntimeException e = new RuntimeException("here");
   2137                     e.fillInStackTrace();
   2138                     Slog.i(TAG, "Setting screen brightness: " + brightness, e);
   2139                 }
   2140             }
   2141         }
   2142 
   2143         if (mSpew) {
   2144             Slog.d(TAG, "offMask=0x" + Integer.toHexString(offMask)
   2145                     + " dimMask=0x" + Integer.toHexString(dimMask)
   2146                     + " onMask=0x" + Integer.toHexString(onMask)
   2147                     + " difference=0x" + Integer.toHexString(difference)
   2148                     + " realDifference=0x" + Integer.toHexString(realDifference)
   2149                     + " forceState=0x" + Integer.toHexString(forceState)
   2150                     );
   2151         }
   2152 
   2153         if (offMask != 0) {
   2154             if (mSpew) Slog.i(TAG, "Setting brightess off: " + offMask);
   2155             setLightBrightness(offMask, PowerManager.BRIGHTNESS_OFF);
   2156         }
   2157         if (dimMask != 0) {
   2158             int brightness = mScreenBrightnessDim;
   2159             if ((newState & BATTERY_LOW_BIT) != 0 &&
   2160                     brightness > PowerManager.BRIGHTNESS_LOW_BATTERY) {
   2161                 brightness = PowerManager.BRIGHTNESS_LOW_BATTERY;
   2162             }
   2163             if (mSpew) Slog.i(TAG, "Setting brightess dim " + brightness + ": " + dimMask);
   2164             setLightBrightness(dimMask, brightness);
   2165         }
   2166         if (onMask != 0) {
   2167             int brightness = getPreferredBrightness();
   2168             if ((newState & BATTERY_LOW_BIT) != 0 &&
   2169                     brightness > PowerManager.BRIGHTNESS_LOW_BATTERY) {
   2170                 brightness = PowerManager.BRIGHTNESS_LOW_BATTERY;
   2171             }
   2172             if (mSpew) Slog.i(TAG, "Setting brightess on " + brightness + ": " + onMask);
   2173             setLightBrightness(onMask, brightness);
   2174         }
   2175     }
   2176 
   2177     /**
   2178      * Note: by design this class does not hold mLocks while calling native methods.
   2179      * Nor should it. Ever.
   2180      */
   2181     class ScreenBrightnessAnimator extends HandlerThread {
   2182         static final int ANIMATE_LIGHTS = 10;
   2183         static final int ANIMATE_POWER_OFF = 11;
   2184         volatile int startValue;
   2185         volatile int endValue;
   2186         volatile int startSensorValue;
   2187         volatile int endSensorValue;
   2188         volatile int currentValue;
   2189         private int currentMask;
   2190         private int duration;
   2191         private long startTimeMillis;
   2192         private final String prefix;
   2193 
   2194         public ScreenBrightnessAnimator(String name, int priority) {
   2195             super(name, priority);
   2196             prefix = name;
   2197         }
   2198 
   2199         @Override
   2200         protected void onLooperPrepared() {
   2201             mScreenBrightnessHandler = new Handler() {
   2202                 public void handleMessage(Message msg) {
   2203                     int brightnessMode = (mAutoBrightessEnabled && !mInitialAnimation
   2204                             ? LightsService.BRIGHTNESS_MODE_SENSOR
   2205                             : LightsService.BRIGHTNESS_MODE_USER);
   2206                     if (msg.what == ANIMATE_LIGHTS) {
   2207                         final int mask = msg.arg1;
   2208                         int value = msg.arg2;
   2209                         long tStart = SystemClock.uptimeMillis();
   2210                         if ((mask & SCREEN_BRIGHT_BIT) != 0) {
   2211                             if (mDebugLightAnimation) Slog.v(TAG, "Set brightness: " + value);
   2212                             mLcdLight.setBrightness(value, brightnessMode);
   2213                         }
   2214                         long elapsed = SystemClock.uptimeMillis() - tStart;
   2215                         if ((mask & BUTTON_BRIGHT_BIT) != 0) {
   2216                             mButtonLight.setBrightness(value);
   2217                         }
   2218                         if ((mask & KEYBOARD_BRIGHT_BIT) != 0) {
   2219                             mKeyboardLight.setBrightness(value);
   2220                         }
   2221 
   2222                         if (elapsed > 100) {
   2223                             Slog.e(TAG, "Excessive delay setting brightness: " + elapsed
   2224                                     + "ms, mask=" + mask);
   2225                         }
   2226 
   2227                         // Throttle brightness updates to frame refresh rate
   2228                         int delay = elapsed < NOMINAL_FRAME_TIME_MS ? NOMINAL_FRAME_TIME_MS : 1;
   2229                         synchronized(this) {
   2230                             currentValue = value;
   2231                         }
   2232                         animateInternal(mask, false, delay);
   2233                     } else if (msg.what == ANIMATE_POWER_OFF) {
   2234                         int mode = msg.arg1;
   2235                         nativeStartSurfaceFlingerAnimation(mode);
   2236                     }
   2237                 }
   2238             };
   2239             synchronized (this) {
   2240                 mInitComplete = true;
   2241                 notifyAll();
   2242             }
   2243         }
   2244 
   2245         private void animateInternal(int mask, boolean turningOff, int delay) {
   2246             synchronized (this) {
   2247                 if (currentValue != endValue) {
   2248                     final long now = SystemClock.elapsedRealtime();
   2249                     final int elapsed = (int) (now - startTimeMillis);
   2250                     int newValue;
   2251                     if (elapsed < duration) {
   2252                         int delta = endValue - startValue;
   2253                         newValue = startValue + delta * elapsed / duration;
   2254                         newValue = Math.max(PowerManager.BRIGHTNESS_OFF, newValue);
   2255                         newValue = Math.min(PowerManager.BRIGHTNESS_ON, newValue);
   2256                         // Optimization to delay next step until a change will occur.
   2257                         if (delay > 0 && newValue == currentValue) {
   2258                             final int timePerStep = duration / Math.abs(delta);
   2259                             delay = Math.min(duration - elapsed, timePerStep);
   2260                             newValue += delta < 0 ? -1 : 1;
   2261                         }
   2262                         // adjust the peak sensor value until we get to the target sensor value
   2263                         delta = endSensorValue - startSensorValue;
   2264                         mHighestLightSensorValue = startSensorValue + delta * elapsed / duration;
   2265                     } else {
   2266                         newValue = endValue;
   2267                         mHighestLightSensorValue = endSensorValue;
   2268                         if (endValue > 0) {
   2269                             mInitialAnimation = false;
   2270                         }
   2271                     }
   2272 
   2273                     if (mDebugLightAnimation) {
   2274                         Slog.v(TAG, "Animating light: " + "start:" + startValue
   2275                                 + ", end:" + endValue + ", elapsed:" + elapsed
   2276                                 + ", duration:" + duration + ", current:" + currentValue
   2277                                 + ", newValue:" + newValue
   2278                                 + ", delay:" + delay
   2279                                 + ", highestSensor:" + mHighestLightSensorValue);
   2280                     }
   2281 
   2282                     if (turningOff && !mHeadless && !mAnimateScreenLights) {
   2283                         int mode = mScreenOffReason == OFF_BECAUSE_OF_PROX_SENSOR
   2284                                 ? 0 : mAnimationSetting;
   2285                         if (mDebugLightAnimation) {
   2286                             Slog.v(TAG, "Doing power-off anim, mode=" + mode);
   2287                         }
   2288                         mScreenBrightnessHandler.obtainMessage(ANIMATE_POWER_OFF, mode, 0)
   2289                                 .sendToTarget();
   2290                     }
   2291                     mScreenBrightnessHandler.removeMessages(
   2292                             ScreenBrightnessAnimator.ANIMATE_LIGHTS);
   2293                     Message msg = mScreenBrightnessHandler
   2294                             .obtainMessage(ANIMATE_LIGHTS, mask, newValue);
   2295                     mScreenBrightnessHandler.sendMessageDelayed(msg, delay);
   2296                 }
   2297             }
   2298         }
   2299 
   2300         public void dump(PrintWriter pw, String string) {
   2301             pw.println(string);
   2302             pw.println("  animating: " + "start:" + startValue + ", end:" + endValue
   2303                     + ", duration:" + duration + ", current:" + currentValue);
   2304             pw.println("  startSensorValue:" + startSensorValue
   2305                     + " endSensorValue:" + endSensorValue);
   2306             pw.println("  startTimeMillis:" + startTimeMillis
   2307                     + " now:" + SystemClock.elapsedRealtime());
   2308             pw.println("  currentMask:" + dumpPowerState(currentMask));
   2309         }
   2310 
   2311         public void animateTo(int target, int mask, int animationDuration) {
   2312             animateTo(target, mHighestLightSensorValue, mask, animationDuration);
   2313         }
   2314 
   2315         public void animateTo(int target, int sensorTarget, int mask, int animationDuration) {
   2316             synchronized(this) {
   2317                 if ((mask & SCREEN_BRIGHT_BIT) == 0) {
   2318                     // We only animate keyboard and button when passed in with SCREEN_BRIGHT_BIT.
   2319                     if ((mask & BUTTON_BRIGHT_BIT) != 0) {
   2320                         mButtonLight.setBrightness(target);
   2321                     }
   2322                     if ((mask & KEYBOARD_BRIGHT_BIT) != 0) {
   2323                         mKeyboardLight.setBrightness(target);
   2324                     }
   2325                     return;
   2326                 }
   2327                 if (isAnimating() && (mask ^ currentMask) != 0) {
   2328                     // current animation is unrelated to new animation, jump to final values
   2329                     cancelAnimation();
   2330                 }
   2331                 if (mInitialAnimation) {
   2332                     // jump to final value in one step the first time the brightness is set
   2333                     animationDuration = 0;
   2334                     if (target > 0) {
   2335                         mInitialAnimation = false;
   2336                     }
   2337                 }
   2338                 startValue = currentValue;
   2339                 endValue = target;
   2340                 startSensorValue = mHighestLightSensorValue;
   2341                 endSensorValue = sensorTarget;
   2342                 currentMask = mask;
   2343                 duration = (int) (mWindowScaleAnimation * animationDuration);
   2344                 startTimeMillis = SystemClock.elapsedRealtime();
   2345 
   2346                 if (mDebugLightAnimation) {
   2347                     Slog.v(TAG, "animateTo(target=" + target
   2348                             + ", sensor=" + sensorTarget
   2349                             + ", mask=" + mask
   2350                             + ", duration=" + animationDuration +")"
   2351                             + ", currentValue=" + currentValue
   2352                             + ", startTime=" + startTimeMillis);
   2353                 }
   2354 
   2355                 if (target != currentValue) {
   2356                     final boolean doScreenAnim = (mask & (SCREEN_BRIGHT_BIT | SCREEN_ON_BIT)) != 0;
   2357                     final boolean turningOff = endValue == PowerManager.BRIGHTNESS_OFF;
   2358                     if (turningOff && doScreenAnim) {
   2359                         // Cancel all pending animations since we're turning off
   2360                         mScreenBrightnessHandler.removeCallbacksAndMessages(null);
   2361                         screenOffFinishedAnimatingLocked(mScreenOffReason);
   2362                         duration = 200; // TODO: how long should this be?
   2363                     }
   2364                     if (doScreenAnim) {
   2365                         animateInternal(mask, turningOff, 0);
   2366                     }
   2367                     // TODO: Handle keyboard light animation when we have devices that support it
   2368                 }
   2369             }
   2370         }
   2371 
   2372         public int getCurrentBrightness() {
   2373             synchronized (this) {
   2374                 return currentValue;
   2375             }
   2376         }
   2377 
   2378         public boolean isAnimating() {
   2379             synchronized (this) {
   2380                 return currentValue != endValue;
   2381             }
   2382         }
   2383 
   2384         public void cancelAnimation() {
   2385             animateTo(endValue, currentMask, 0);
   2386         }
   2387     }
   2388 
   2389     private void setLightBrightness(int mask, int value) {
   2390         mScreenBrightnessAnimator.animateTo(value, mask, 0);
   2391     }
   2392 
   2393     private int getPreferredBrightness() {
   2394         if (mScreenBrightnessOverride >= 0) {
   2395             return mScreenBrightnessOverride;
   2396         } else if (mLightSensorScreenBrightness >= 0 && mUseSoftwareAutoBrightness
   2397                 && mAutoBrightessEnabled) {
   2398             return mLightSensorScreenBrightness;
   2399         }
   2400         final int brightness = mScreenBrightnessSetting;
   2401          // Don't let applications turn the screen all the way off
   2402         return Math.max(brightness, mScreenBrightnessDim);
   2403     }
   2404 
   2405     private int applyButtonState(int state) {
   2406         int brightness = -1;
   2407         if ((state & BATTERY_LOW_BIT) != 0) {
   2408             // do not override brightness if the battery is low
   2409             return state;
   2410         }
   2411         if (mButtonBrightnessOverride >= 0) {
   2412             brightness = mButtonBrightnessOverride;
   2413         } else if (mLightSensorButtonBrightness >= 0 && mUseSoftwareAutoBrightness) {
   2414             brightness = mLightSensorButtonBrightness;
   2415         }
   2416         if (brightness > 0) {
   2417             return state | BUTTON_BRIGHT_BIT;
   2418         } else if (brightness == 0) {
   2419             return state & ~BUTTON_BRIGHT_BIT;
   2420         } else {
   2421             return state;
   2422         }
   2423     }
   2424 
   2425     private int applyKeyboardState(int state) {
   2426         int brightness = -1;
   2427         if ((state & BATTERY_LOW_BIT) != 0) {
   2428             // do not override brightness if the battery is low
   2429             return state;
   2430         }
   2431         if (!mKeyboardVisible) {
   2432             brightness = 0;
   2433         } else if (mButtonBrightnessOverride >= 0) {
   2434             brightness = mButtonBrightnessOverride;
   2435         } else if (mLightSensorKeyboardBrightness >= 0 && mUseSoftwareAutoBrightness) {
   2436             brightness =  mLightSensorKeyboardBrightness;
   2437         }
   2438         if (brightness > 0) {
   2439             return state | KEYBOARD_BRIGHT_BIT;
   2440         } else if (brightness == 0) {
   2441             return state & ~KEYBOARD_BRIGHT_BIT;
   2442         } else {
   2443             return state;
   2444         }
   2445     }
   2446 
   2447     public boolean isScreenOn() {
   2448         synchronized (mLocks) {
   2449             return (mPowerState & SCREEN_ON_BIT) != 0;
   2450         }
   2451     }
   2452 
   2453     boolean isScreenBright() {
   2454         synchronized (mLocks) {
   2455             return (mPowerState & SCREEN_BRIGHT) == SCREEN_BRIGHT;
   2456         }
   2457     }
   2458 
   2459     private boolean isScreenTurningOffLocked() {
   2460         return (mScreenBrightnessAnimator.isAnimating()
   2461                 && mScreenBrightnessAnimator.endValue == PowerManager.BRIGHTNESS_OFF
   2462                 && (mScreenBrightnessAnimator.currentMask & SCREEN_BRIGHT_BIT) != 0);
   2463     }
   2464 
   2465     private boolean shouldLog(long time) {
   2466         synchronized (mLocks) {
   2467             if (time > (mWarningSpewThrottleTime + (60*60*1000))) {
   2468                 mWarningSpewThrottleTime = time;
   2469                 mWarningSpewThrottleCount = 0;
   2470                 return true;
   2471             } else if (mWarningSpewThrottleCount < 30) {
   2472                 mWarningSpewThrottleCount++;
   2473                 return true;
   2474             } else {
   2475                 return false;
   2476             }
   2477         }
   2478     }
   2479 
   2480     private void forceUserActivityLocked() {
   2481         if (isScreenTurningOffLocked()) {
   2482             // cancel animation so userActivity will succeed
   2483             mScreenBrightnessAnimator.cancelAnimation();
   2484         }
   2485         boolean savedActivityAllowed = mUserActivityAllowed;
   2486         mUserActivityAllowed = true;
   2487         userActivity(SystemClock.uptimeMillis(), false);
   2488         mUserActivityAllowed = savedActivityAllowed;
   2489     }
   2490 
   2491     public void userActivityWithForce(long time, boolean noChangeLights, boolean force) {
   2492         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
   2493         userActivity(time, -1, noChangeLights, OTHER_EVENT, force, false);
   2494     }
   2495 
   2496     public void userActivity(long time, boolean noChangeLights) {
   2497         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER)
   2498                 != PackageManager.PERMISSION_GRANTED) {
   2499             if (shouldLog(time)) {
   2500                 Slog.w(TAG, "Caller does not have DEVICE_POWER permission.  pid="
   2501                         + Binder.getCallingPid() + " uid=" + Binder.getCallingUid());
   2502             }
   2503             return;
   2504         }
   2505 
   2506         userActivity(time, -1, noChangeLights, OTHER_EVENT, false, false);
   2507     }
   2508 
   2509     public void userActivity(long time, boolean noChangeLights, int eventType) {
   2510         userActivity(time, -1, noChangeLights, eventType, false, false);
   2511     }
   2512 
   2513     public void userActivity(long time, boolean noChangeLights, int eventType, boolean force) {
   2514         userActivity(time, -1, noChangeLights, eventType, force, false);
   2515     }
   2516 
   2517     /*
   2518      * Reset the user activity timeout to now + timeout.  This overrides whatever else is going
   2519      * on with user activity.  Don't use this function.
   2520      */
   2521     public void clearUserActivityTimeout(long now, long timeout) {
   2522         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
   2523         Slog.i(TAG, "clearUserActivity for " + timeout + "ms from now");
   2524         userActivity(now, timeout, false, OTHER_EVENT, false, false);
   2525     }
   2526 
   2527     private void userActivity(long time, long timeoutOverride, boolean noChangeLights,
   2528             int eventType, boolean force, boolean ignoreIfScreenOff) {
   2529 
   2530         if (((mPokey & POKE_LOCK_IGNORE_TOUCH_EVENTS) != 0) && (eventType == TOUCH_EVENT)) {
   2531             if (false) {
   2532                 Slog.d(TAG, "dropping touch mPokey=0x" + Integer.toHexString(mPokey));
   2533             }
   2534             return;
   2535         }
   2536 
   2537         synchronized (mLocks) {
   2538             if (mSpew) {
   2539                 Slog.d(TAG, "userActivity mLastEventTime=" + mLastEventTime + " time=" + time
   2540                         + " mUserActivityAllowed=" + mUserActivityAllowed
   2541                         + " mUserState=0x" + Integer.toHexString(mUserState)
   2542                         + " mWakeLockState=0x" + Integer.toHexString(mWakeLockState)
   2543                         + " mProximitySensorActive=" + mProximitySensorActive
   2544                         + " timeoutOverride=" + timeoutOverride
   2545                         + " force=" + force);
   2546             }
   2547             // ignore user activity if we are in the process of turning off the screen
   2548             if (isScreenTurningOffLocked()) {
   2549                 Slog.d(TAG, "ignoring user activity while turning off screen");
   2550                 return;
   2551             }
   2552             // ignore if the caller doesn't want this to allow the screen to turn
   2553             // on, and the screen is currently off.
   2554             if (ignoreIfScreenOff && (mPowerState & SCREEN_ON_BIT) == 0) {
   2555                 return;
   2556             }
   2557             // Disable proximity sensor if if user presses power key while we are in the
   2558             // "waiting for proximity sensor to go negative" state.
   2559             if (mProximitySensorActive && mProximityWakeLockCount == 0) {
   2560                 mProximitySensorActive = false;
   2561             }
   2562             if (mLastEventTime <= time || force) {
   2563                 mLastEventTime = time;
   2564                 if ((mUserActivityAllowed && !mProximitySensorActive) || force) {
   2565                     // Only turn on button backlights if a button was pressed
   2566                     // and auto brightness is disabled
   2567                     if (eventType == BUTTON_EVENT && !mUseSoftwareAutoBrightness) {
   2568                         mUserState = (mKeyboardVisible ? ALL_BRIGHT : SCREEN_BUTTON_BRIGHT);
   2569                     } else {
   2570                         // don't clear button/keyboard backlights when the screen is touched.
   2571                         mUserState |= SCREEN_BRIGHT;
   2572                     }
   2573 
   2574                     int uid = Binder.getCallingUid();
   2575                     long ident = Binder.clearCallingIdentity();
   2576                     try {
   2577                         mBatteryStats.noteUserActivity(uid, eventType);
   2578                     } catch (RemoteException e) {
   2579                         // Ignore
   2580                     } finally {
   2581                         Binder.restoreCallingIdentity(ident);
   2582                     }
   2583 
   2584                     mWakeLockState = mLocks.reactivateScreenLocksLocked();
   2585                     setPowerState(mUserState | mWakeLockState, noChangeLights,
   2586                             WindowManagerPolicy.OFF_BECAUSE_OF_USER);
   2587                     setTimeoutLocked(time, timeoutOverride, SCREEN_BRIGHT);
   2588                 }
   2589             }
   2590         }
   2591 
   2592         if (mPolicy != null) {
   2593             mPolicy.userActivity();
   2594         }
   2595     }
   2596 
   2597     private int getAutoBrightnessValue(int sensorValue, int[] values) {
   2598         try {
   2599             int i;
   2600             for (i = 0; i < mAutoBrightnessLevels.length; i++) {
   2601                 if (sensorValue < mAutoBrightnessLevels[i]) {
   2602                     break;
   2603                 }
   2604             }
   2605             // This is the range of brightness values that we can use.
   2606             final int minval = values[0];
   2607             final int maxval = values[mAutoBrightnessLevels.length];
   2608             // This is the range we will be scaling.  We put some padding
   2609             // at the low and high end to give the adjustment a little better
   2610             // impact on the actual observed value.
   2611             final int range = (maxval-minval) + LIGHT_SENSOR_RANGE_EXPANSION;
   2612             // This is the desired brightness value from 0.0 to 1.0.
   2613             float valf = ((values[i]-minval+(LIGHT_SENSOR_RANGE_EXPANSION/2))/(float)range);
   2614             // Apply a scaling to the value based on the adjustment.
   2615             if (mLightSensorAdjustSetting > 0 && mLightSensorAdjustSetting <= 1) {
   2616                 float adj = (float)Math.sqrt(1.0f-mLightSensorAdjustSetting);
   2617                 if (adj <= .00001) {
   2618                     valf = 1;
   2619                 } else {
   2620                     valf /= adj;
   2621                 }
   2622             } else if (mLightSensorAdjustSetting < 0 && mLightSensorAdjustSetting >= -1) {
   2623                 float adj = (float)Math.sqrt(1.0f+mLightSensorAdjustSetting);
   2624                 valf *= adj;
   2625             }
   2626             // Apply an additional offset to the value based on the adjustment.
   2627             valf += mLightSensorAdjustSetting/LIGHT_SENSOR_OFFSET_SCALE;
   2628             // Convert the 0.0-1.0 value back to a brightness integer.
   2629             int val = (int)((valf*range)+minval) - (LIGHT_SENSOR_RANGE_EXPANSION/2);
   2630             if (val < minval) val = minval;
   2631             else if (val > maxval) val = maxval;
   2632             return val;
   2633         } catch (Exception e) {
   2634             // guard against null pointer or index out of bounds errors
   2635             Slog.e(TAG, "Values array must be non-empty and must be one element longer than "
   2636                     + "the auto-brightness levels array.  Check config.xml.", e);
   2637             return 255;
   2638         }
   2639     }
   2640 
   2641     private Runnable mProximityTask = new Runnable() {
   2642         public void run() {
   2643             synchronized (mLocks) {
   2644                 if (mProximityPendingValue != -1) {
   2645                     proximityChangedLocked(mProximityPendingValue == 1);
   2646                     mProximityPendingValue = -1;
   2647                 }
   2648                 if (mProximityPartialLock.isHeld()) {
   2649                     mProximityPartialLock.release();
   2650                 }
   2651             }
   2652         }
   2653     };
   2654 
   2655     private Runnable mAutoBrightnessTask = new Runnable() {
   2656         public void run() {
   2657             synchronized (mLocks) {
   2658                 if (mLightSensorPendingDecrease || mLightSensorPendingIncrease) {
   2659                     int value = (int)mLightSensorPendingValue;
   2660                     mLightSensorPendingDecrease = false;
   2661                     mLightSensorPendingIncrease = false;
   2662                     lightSensorChangedLocked(value, false);
   2663                 }
   2664             }
   2665         }
   2666     };
   2667 
   2668     /** used to prevent lightsensor changes while turning on. */
   2669     private boolean mInitialAnimation = true;
   2670 
   2671     private void dockStateChanged(int state) {
   2672         synchronized (mLocks) {
   2673             mIsDocked = (state != Intent.EXTRA_DOCK_STATE_UNDOCKED);
   2674             if (mIsDocked) {
   2675                 // allow brightness to decrease when docked
   2676                 mHighestLightSensorValue = -1;
   2677             }
   2678             if ((mPowerState & SCREEN_ON_BIT) != 0) {
   2679                 // force lights recalculation
   2680                 int value = (int)mLightSensorValue;
   2681                 mLightSensorValue = -1;
   2682                 lightSensorChangedLocked(value, false);
   2683             }
   2684         }
   2685     }
   2686 
   2687     private void lightSensorChangedLocked(int value, boolean immediate) {
   2688         if (mDebugLightSensor) {
   2689             Slog.d(TAG, "lightSensorChangedLocked value=" + value + " immediate=" + immediate);
   2690         }
   2691 
   2692         // Don't do anything if the screen is off.
   2693         if ((mPowerState & SCREEN_ON_BIT) == 0) {
   2694             if (mDebugLightSensor) {
   2695                 Slog.d(TAG, "dropping lightSensorChangedLocked because screen is off");
   2696             }
   2697             return;
   2698         }
   2699 
   2700         if (mLightSensorValue != value) {
   2701             mLightSensorValue = value;
   2702             if ((mPowerState & BATTERY_LOW_BIT) == 0) {
   2703                 // use maximum light sensor value seen since screen went on for LCD to avoid flicker
   2704                 // we only do this if we are undocked, since lighting should be stable when
   2705                 // stationary in a dock.
   2706                 int lcdValue = getAutoBrightnessValue(value, mLcdBacklightValues);
   2707                 int buttonValue = getAutoBrightnessValue(value, mButtonBacklightValues);
   2708                 int keyboardValue;
   2709                 if (mKeyboardVisible) {
   2710                     keyboardValue = getAutoBrightnessValue(value, mKeyboardBacklightValues);
   2711                 } else {
   2712                     keyboardValue = 0;
   2713                 }
   2714                 mLightSensorScreenBrightness = lcdValue;
   2715                 mLightSensorButtonBrightness = buttonValue;
   2716                 mLightSensorKeyboardBrightness = keyboardValue;
   2717 
   2718                 if (mDebugLightSensor) {
   2719                     Slog.d(TAG, "lcdValue " + lcdValue);
   2720                     Slog.d(TAG, "buttonValue " + buttonValue);
   2721                     Slog.d(TAG, "keyboardValue " + keyboardValue);
   2722                 }
   2723 
   2724                 if (mAutoBrightessEnabled && mScreenBrightnessOverride < 0) {
   2725                     if (!mSkippedScreenOn && !mInitialAnimation) {
   2726                         final int steps;
   2727                         if (immediate) {
   2728                             steps = IMMEDIATE_ANIM_STEPS;
   2729                         } else {
   2730                             synchronized (mScreenBrightnessAnimator) {
   2731                                 if (mScreenBrightnessAnimator.currentValue <= lcdValue) {
   2732                                     steps = AUTOBRIGHTNESS_ANIM_STEPS;
   2733                                 } else {
   2734                                     steps = AUTODIMNESS_ANIM_STEPS;
   2735                                 }
   2736                             }
   2737                         }
   2738                         mScreenBrightnessAnimator.animateTo(lcdValue, value,
   2739                                 SCREEN_BRIGHT_BIT, steps * NOMINAL_FRAME_TIME_MS);
   2740                     }
   2741                 }
   2742                 if (mButtonBrightnessOverride < 0) {
   2743                     mButtonLight.setBrightness(buttonValue);
   2744                 }
   2745                 if (mButtonBrightnessOverride < 0 || !mKeyboardVisible) {
   2746                     mKeyboardLight.setBrightness(keyboardValue);
   2747                 }
   2748             }
   2749         }
   2750     }
   2751 
   2752     /**
   2753      * The user requested that we go to sleep (probably with the power button).
   2754      * This overrides all wake locks that are held.
   2755      */
   2756     public void goToSleep(long time)
   2757     {
   2758         goToSleepWithReason(time, WindowManagerPolicy.OFF_BECAUSE_OF_USER);
   2759     }
   2760 
   2761     /**
   2762      * The user requested that we go to sleep (probably with the power button).
   2763      * This overrides all wake locks that are held.
   2764      */
   2765     public void goToSleepWithReason(long time, int reason)
   2766     {
   2767         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
   2768         synchronized (mLocks) {
   2769             goToSleepLocked(time, reason);
   2770         }
   2771     }
   2772 
   2773     /**
   2774      * Reboot the device immediately, passing 'reason' (may be null)
   2775      * to the underlying __reboot system call.  Should not return.
   2776      */
   2777     public void reboot(String reason)
   2778     {
   2779         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
   2780 
   2781         if (mHandler == null || !ActivityManagerNative.isSystemReady()) {
   2782             throw new IllegalStateException("Too early to call reboot()");
   2783         }
   2784 
   2785         final String finalReason = reason;
   2786         Runnable runnable = new Runnable() {
   2787             public void run() {
   2788                 synchronized (this) {
   2789                     ShutdownThread.reboot(mContext, finalReason, false);
   2790                 }
   2791 
   2792             }
   2793         };
   2794         // ShutdownThread must run on a looper capable of displaying the UI.
   2795         mHandler.post(runnable);
   2796 
   2797         // PowerManager.reboot() is documented not to return so just wait for the inevitable.
   2798         synchronized (runnable) {
   2799             while (true) {
   2800                 try {
   2801                     runnable.wait();
   2802                 } catch (InterruptedException e) {
   2803                 }
   2804             }
   2805         }
   2806     }
   2807 
   2808     /**
   2809      * Crash the runtime (causing a complete restart of the Android framework).
   2810      * Requires REBOOT permission.  Mostly for testing.  Should not return.
   2811      */
   2812     public void crash(final String message)
   2813     {
   2814         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
   2815         Thread t = new Thread("PowerManagerService.crash()") {
   2816             public void run() { throw new RuntimeException(message); }
   2817         };
   2818         try {
   2819             t.start();
   2820             t.join();
   2821         } catch (InterruptedException e) {
   2822             Log.wtf(TAG, e);
   2823         }
   2824     }
   2825 
   2826     private void goToSleepLocked(long time, int reason) {
   2827         if (mSpew) {
   2828             Exception ex = new Exception();
   2829             ex.fillInStackTrace();
   2830             Slog.d(TAG, "goToSleep mLastEventTime=" + mLastEventTime + " time=" + time
   2831                     + " reason=" + reason, ex);
   2832         }
   2833 
   2834         if (mLastEventTime <= time) {
   2835             mLastEventTime = time;
   2836             // cancel all of the wake locks
   2837             mWakeLockState = SCREEN_OFF;
   2838             int N = mLocks.size();
   2839             int numCleared = 0;
   2840             boolean proxLock = false;
   2841             for (int i=0; i<N; i++) {
   2842                 WakeLock wl = mLocks.get(i);
   2843                 if (isScreenLock(wl.flags)) {
   2844                     if (((wl.flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)
   2845                             && reason == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR) {
   2846                         proxLock = true;
   2847                     } else {
   2848                         mLocks.get(i).activated = false;
   2849                         numCleared++;
   2850                     }
   2851                 }
   2852             }
   2853             if (!proxLock) {
   2854                 mProxIgnoredBecauseScreenTurnedOff = true;
   2855                 if (mDebugProximitySensor) {
   2856                     Slog.d(TAG, "setting mProxIgnoredBecauseScreenTurnedOff");
   2857                 }
   2858             }
   2859             EventLog.writeEvent(EventLogTags.POWER_SLEEP_REQUESTED, numCleared);
   2860             mStillNeedSleepNotification = true;
   2861             mUserState = SCREEN_OFF;
   2862             setPowerState(SCREEN_OFF, false, reason);
   2863             cancelTimerLocked();
   2864         }
   2865     }
   2866 
   2867     public long timeSinceScreenOn() {
   2868         synchronized (mLocks) {
   2869             if ((mPowerState & SCREEN_ON_BIT) != 0) {
   2870                 return 0;
   2871             }
   2872             return SystemClock.elapsedRealtime() - mScreenOffTime;
   2873         }
   2874     }
   2875 
   2876     public void setKeyboardVisibility(boolean visible) {
   2877         synchronized (mLocks) {
   2878             if (mSpew) {
   2879                 Slog.d(TAG, "setKeyboardVisibility: " + visible);
   2880             }
   2881             if (mKeyboardVisible != visible) {
   2882                 mKeyboardVisible = visible;
   2883                 // don't signal user activity if the screen is off; other code
   2884                 // will take care of turning on due to a true change to the lid
   2885                 // switch and synchronized with the lock screen.
   2886                 if ((mPowerState & SCREEN_ON_BIT) != 0) {
   2887                     if (mUseSoftwareAutoBrightness) {
   2888                         // force recompute of backlight values
   2889                         if (mLightSensorValue >= 0) {
   2890                             int value = (int)mLightSensorValue;
   2891                             mLightSensorValue = -1;
   2892                             lightSensorChangedLocked(value, false);
   2893                         }
   2894                     }
   2895                     userActivity(SystemClock.uptimeMillis(), false, BUTTON_EVENT, true);
   2896                 }
   2897             }
   2898         }
   2899     }
   2900 
   2901     /**
   2902      * When the keyguard is up, it manages the power state, and userActivity doesn't do anything.
   2903      * When disabling user activity we also reset user power state so the keyguard can reset its
   2904      * short screen timeout when keyguard is unhidden.
   2905      */
   2906     public void enableUserActivity(boolean enabled) {
   2907         if (mSpew) {
   2908             Slog.d(TAG, "enableUserActivity " + enabled);
   2909         }
   2910         synchronized (mLocks) {
   2911             mUserActivityAllowed = enabled;
   2912             if (!enabled) {
   2913                 // cancel timeout and clear mUserState so the keyguard can set a short timeout
   2914                 setTimeoutLocked(SystemClock.uptimeMillis(), 0);
   2915             }
   2916         }
   2917     }
   2918 
   2919     private void setScreenBrightnessMode(int mode) {
   2920         synchronized (mLocks) {
   2921             boolean enabled = (mode == SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
   2922             if (mUseSoftwareAutoBrightness && mAutoBrightessEnabled != enabled) {
   2923                 mAutoBrightessEnabled = enabled;
   2924                 // This will get us a new value
   2925                 enableLightSensorLocked(mAutoBrightessEnabled && isScreenOn());
   2926             }
   2927         }
   2928     }
   2929 
   2930     /** Sets the screen off timeouts:
   2931      *      mKeylightDelay
   2932      *      mDimDelay
   2933      *      mScreenOffDelay
   2934      * */
   2935     private void setScreenOffTimeoutsLocked() {
   2936         if ((mPokey & POKE_LOCK_SHORT_TIMEOUT) != 0) {
   2937             mKeylightDelay = mShortKeylightDelay;  // Configurable via secure settings
   2938             mDimDelay = -1;
   2939             mScreenOffDelay = 0;
   2940         } else if ((mPokey & POKE_LOCK_MEDIUM_TIMEOUT) != 0) {
   2941             mKeylightDelay = MEDIUM_KEYLIGHT_DELAY;
   2942             mDimDelay = -1;
   2943             mScreenOffDelay = 0;
   2944         } else {
   2945             int totalDelay = mScreenOffTimeoutSetting;
   2946             if (totalDelay > mMaximumScreenOffTimeout) {
   2947                 totalDelay = mMaximumScreenOffTimeout;
   2948             }
   2949             mKeylightDelay = LONG_KEYLIGHT_DELAY;
   2950             if (totalDelay < 0) {
   2951                 // negative number means stay on as long as possible.
   2952                 mScreenOffDelay = mMaximumScreenOffTimeout;
   2953             } else if (mKeylightDelay < totalDelay) {
   2954                 // subtract the time that the keylight delay. This will give us the
   2955                 // remainder of the time that we need to sleep to get the accurate
   2956                 // screen off timeout.
   2957                 mScreenOffDelay = totalDelay - mKeylightDelay;
   2958             } else {
   2959                 mScreenOffDelay = 0;
   2960             }
   2961             if (mDimScreen && totalDelay >= (LONG_KEYLIGHT_DELAY + LONG_DIM_TIME)) {
   2962                 mDimDelay = mScreenOffDelay - LONG_DIM_TIME;
   2963                 mScreenOffDelay = LONG_DIM_TIME;
   2964             } else {
   2965                 mDimDelay = -1;
   2966             }
   2967         }
   2968         if (mSpew) {
   2969             Slog.d(TAG, "setScreenOffTimeouts mKeylightDelay=" + mKeylightDelay
   2970                     + " mDimDelay=" + mDimDelay + " mScreenOffDelay=" + mScreenOffDelay
   2971                     + " mDimScreen=" + mDimScreen);
   2972         }
   2973     }
   2974 
   2975     /**
   2976      * Refreshes cached secure settings.  Called once on startup, and
   2977      * on subsequent changes to secure settings.
   2978      */
   2979     private void updateSettingsValues() {
   2980         mShortKeylightDelay = Settings.Secure.getInt(
   2981                 mContext.getContentResolver(),
   2982                 Settings.Secure.SHORT_KEYLIGHT_DELAY_MS,
   2983                 SHORT_KEYLIGHT_DELAY_DEFAULT);
   2984         // Slog.i(TAG, "updateSettingsValues(): mShortKeylightDelay now " + mShortKeylightDelay);
   2985     }
   2986 
   2987     private class LockList extends ArrayList<WakeLock>
   2988     {
   2989         void addLock(WakeLock wl)
   2990         {
   2991             int index = getIndex(wl.binder);
   2992             if (index < 0) {
   2993                 this.add(wl);
   2994             }
   2995         }
   2996 
   2997         WakeLock removeLock(IBinder binder)
   2998         {
   2999             int index = getIndex(binder);
   3000             if (index >= 0) {
   3001                 return this.remove(index);
   3002             } else {
   3003                 return null;
   3004             }
   3005         }
   3006 
   3007         int getIndex(IBinder binder)
   3008         {
   3009             int N = this.size();
   3010             for (int i=0; i<N; i++) {
   3011                 if (this.get(i).binder == binder) {
   3012                     return i;
   3013                 }
   3014             }
   3015             return -1;
   3016         }
   3017 
   3018         int gatherState()
   3019         {
   3020             int result = 0;
   3021             int N = this.size();
   3022             for (int i=0; i<N; i++) {
   3023                 WakeLock wl = this.get(i);
   3024                 if (wl.activated) {
   3025                     if (isScreenLock(wl.flags)) {
   3026                         result |= wl.minState;
   3027                     }
   3028                 }
   3029             }
   3030             return result;
   3031         }
   3032 
   3033         int reactivateScreenLocksLocked()
   3034         {
   3035             int result = 0;
   3036             int N = this.size();
   3037             for (int i=0; i<N; i++) {
   3038                 WakeLock wl = this.get(i);
   3039                 if (isScreenLock(wl.flags)) {
   3040                     wl.activated = true;
   3041                     result |= wl.minState;
   3042                 }
   3043             }
   3044             if (mDebugProximitySensor) {
   3045                 Slog.d(TAG, "reactivateScreenLocksLocked mProxIgnoredBecauseScreenTurnedOff="
   3046                         + mProxIgnoredBecauseScreenTurnedOff);
   3047             }
   3048             mProxIgnoredBecauseScreenTurnedOff = false;
   3049             return result;
   3050         }
   3051     }
   3052 
   3053     public void setPolicy(WindowManagerPolicy p) {
   3054         synchronized (mLocks) {
   3055             mPolicy = p;
   3056             mLocks.notifyAll();
   3057         }
   3058     }
   3059 
   3060     WindowManagerPolicy getPolicyLocked() {
   3061         while (mPolicy == null || !mDoneBooting) {
   3062             try {
   3063                 mLocks.wait();
   3064             } catch (InterruptedException e) {
   3065                 // Ignore
   3066             }
   3067         }
   3068         return mPolicy;
   3069     }
   3070 
   3071     void systemReady() {
   3072         mSensorManager = new SystemSensorManager(mHandlerThread.getLooper());
   3073         mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
   3074         // don't bother with the light sensor if auto brightness is handled in hardware
   3075         if (mUseSoftwareAutoBrightness) {
   3076             mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
   3077         }
   3078 
   3079         // wait until sensors are enabled before turning on screen.
   3080         // some devices will not activate the light sensor properly on boot
   3081         // unless we do this.
   3082         if (mUseSoftwareAutoBrightness) {
   3083             // turn the screen on
   3084             setPowerState(SCREEN_BRIGHT);
   3085         } else {
   3086             // turn everything on
   3087             setPowerState(ALL_BRIGHT);
   3088         }
   3089 
   3090         synchronized (mLocks) {
   3091             Slog.d(TAG, "system ready!");
   3092             mDoneBooting = true;
   3093 
   3094             enableLightSensorLocked(mUseSoftwareAutoBrightness && mAutoBrightessEnabled);
   3095 
   3096             long identity = Binder.clearCallingIdentity();
   3097             try {
   3098                 mBatteryStats.noteScreenBrightness(getPreferredBrightness());
   3099                 mBatteryStats.noteScreenOn();
   3100             } catch (RemoteException e) {
   3101                 // Nothing interesting to do.
   3102             } finally {
   3103                 Binder.restoreCallingIdentity(identity);
   3104             }
   3105         }
   3106     }
   3107 
   3108     void bootCompleted() {
   3109         Slog.d(TAG, "bootCompleted");
   3110         synchronized (mLocks) {
   3111             mBootCompleted = true;
   3112             userActivity(SystemClock.uptimeMillis(), false, BUTTON_EVENT, true);
   3113             updateWakeLockLocked();
   3114             mLocks.notifyAll();
   3115         }
   3116     }
   3117 
   3118     // for watchdog
   3119     public void monitor() {
   3120         synchronized (mLocks) { }
   3121     }
   3122 
   3123     public int getSupportedWakeLockFlags() {
   3124         int result = PowerManager.PARTIAL_WAKE_LOCK
   3125                    | PowerManager.FULL_WAKE_LOCK
   3126                    | PowerManager.SCREEN_DIM_WAKE_LOCK;
   3127 
   3128         if (mProximitySensor != null) {
   3129             result |= PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK;
   3130         }
   3131 
   3132         return result;
   3133     }
   3134 
   3135     public void setBacklightBrightness(int brightness) {
   3136         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
   3137         // Don't let applications turn the screen all the way off
   3138         synchronized (mLocks) {
   3139             brightness = Math.max(brightness, mScreenBrightnessDim);
   3140             mLcdLight.setBrightness(brightness);
   3141             mKeyboardLight.setBrightness(mKeyboardVisible ? brightness : 0);
   3142             mButtonLight.setBrightness(brightness);
   3143             long identity = Binder.clearCallingIdentity();
   3144             try {
   3145                 mBatteryStats.noteScreenBrightness(brightness);
   3146             } catch (RemoteException e) {
   3147                 Slog.w(TAG, "RemoteException calling noteScreenBrightness on BatteryStatsService", e);
   3148             } finally {
   3149                 Binder.restoreCallingIdentity(identity);
   3150             }
   3151             mScreenBrightnessAnimator.animateTo(brightness, SCREEN_BRIGHT_BIT, 0);
   3152         }
   3153     }
   3154 
   3155     public void setAutoBrightnessAdjustment(float adj) {
   3156         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
   3157         synchronized (mLocks) {
   3158             mLightSensorAdjustSetting = adj;
   3159             if (mSensorManager != null && mLightSensorEnabled) {
   3160                 // clear calling identity so sensor manager battery stats are accurate
   3161                 long identity = Binder.clearCallingIdentity();
   3162                 try {
   3163                     // force recompute of backlight values
   3164                     if (mLightSensorValue >= 0) {
   3165                         int value = (int)mLightSensorValue;
   3166                         mLightSensorValue = -1;
   3167                         handleLightSensorValue(value, true);
   3168                     }
   3169                 } finally {
   3170                     Binder.restoreCallingIdentity(identity);
   3171                 }
   3172             }
   3173         }
   3174     }
   3175 
   3176     public void setAttentionLight(boolean on, int color) {
   3177         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
   3178         mAttentionLight.setFlashing(color, LightsService.LIGHT_FLASH_HARDWARE, (on ? 3 : 0), 0);
   3179     }
   3180 
   3181     private void enableProximityLockLocked() {
   3182         if (mDebugProximitySensor) {
   3183             Slog.d(TAG, "enableProximityLockLocked");
   3184         }
   3185         if (!mProximitySensorEnabled) {
   3186             // clear calling identity so sensor manager battery stats are accurate
   3187             long identity = Binder.clearCallingIdentity();
   3188             try {
   3189                 mSensorManager.registerListener(mProximityListener, mProximitySensor,
   3190                         SensorManager.SENSOR_DELAY_NORMAL);
   3191                 mProximitySensorEnabled = true;
   3192             } finally {
   3193                 Binder.restoreCallingIdentity(identity);
   3194             }
   3195         }
   3196     }
   3197 
   3198     private void disableProximityLockLocked() {
   3199         if (mDebugProximitySensor) {
   3200             Slog.d(TAG, "disableProximityLockLocked");
   3201         }
   3202         if (mProximitySensorEnabled) {
   3203             // clear calling identity so sensor manager battery stats are accurate
   3204             long identity = Binder.clearCallingIdentity();
   3205             try {
   3206                 mSensorManager.unregisterListener(mProximityListener);
   3207                 mHandler.removeCallbacks(mProximityTask);
   3208                 if (mProximityPartialLock.isHeld()) {
   3209                     mProximityPartialLock.release();
   3210                 }
   3211                 mProximitySensorEnabled = false;
   3212             } finally {
   3213                 Binder.restoreCallingIdentity(identity);
   3214             }
   3215             if (mProximitySensorActive) {
   3216                 mProximitySensorActive = false;
   3217                 if (mDebugProximitySensor) {
   3218                     Slog.d(TAG, "disableProximityLockLocked mProxIgnoredBecauseScreenTurnedOff="
   3219                             + mProxIgnoredBecauseScreenTurnedOff);
   3220                 }
   3221                 if (!mProxIgnoredBecauseScreenTurnedOff) {
   3222                     forceUserActivityLocked();
   3223                 }
   3224             }
   3225         }
   3226     }
   3227 
   3228     private void proximityChangedLocked(boolean active) {
   3229         if (mDebugProximitySensor) {
   3230             Slog.d(TAG, "proximityChangedLocked, active: " + active);
   3231         }
   3232         if (!mProximitySensorEnabled) {
   3233             Slog.d(TAG, "Ignoring proximity change after sensor is disabled");
   3234             return;
   3235         }
   3236         if (active) {
   3237             if (mDebugProximitySensor) {
   3238                 Slog.d(TAG, "b mProxIgnoredBecauseScreenTurnedOff="
   3239                         + mProxIgnoredBecauseScreenTurnedOff);
   3240             }
   3241             if (!mProxIgnoredBecauseScreenTurnedOff) {
   3242                 goToSleepLocked(SystemClock.uptimeMillis(),
   3243                         WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR);
   3244             }
   3245             mProximitySensorActive = true;
   3246         } else {
   3247             // proximity sensor negative events trigger as user activity.
   3248             // temporarily set mUserActivityAllowed to true so this will work
   3249             // even when the keyguard is on.
   3250             mProximitySensorActive = false;
   3251             if (mDebugProximitySensor) {
   3252                 Slog.d(TAG, "b mProxIgnoredBecauseScreenTurnedOff="
   3253                         + mProxIgnoredBecauseScreenTurnedOff);
   3254             }
   3255             if (!mProxIgnoredBecauseScreenTurnedOff) {
   3256                 forceUserActivityLocked();
   3257             }
   3258 
   3259             if (mProximityWakeLockCount == 0) {
   3260                 // disable sensor if we have no listeners left after proximity negative
   3261                 disableProximityLockLocked();
   3262             }
   3263         }
   3264     }
   3265 
   3266     private void enableLightSensorLocked(boolean enable) {
   3267         if (mDebugLightSensor) {
   3268             Slog.d(TAG, "enableLightSensorLocked enable=" + enable
   3269                     + " mLightSensorEnabled=" + mLightSensorEnabled
   3270                     + " mAutoBrightessEnabled=" + mAutoBrightessEnabled
   3271                     + " mWaitingForFirstLightSensor=" + mWaitingForFirstLightSensor);
   3272         }
   3273         if (!mAutoBrightessEnabled) {
   3274             enable = false;
   3275         }
   3276         if (mSensorManager != null && mLightSensorEnabled != enable) {
   3277             mLightSensorEnabled = enable;
   3278             // clear calling identity so sensor manager battery stats are accurate
   3279             long identity = Binder.clearCallingIdentity();
   3280             try {
   3281                 if (enable) {
   3282                     // reset our highest value when reenabling
   3283                     mHighestLightSensorValue = -1;
   3284                     // force recompute of backlight values
   3285                     final int value = (int)mLightSensorValue;
   3286                     if (value >= 0) {
   3287                         mLightSensorValue = -1;
   3288                         handleLightSensorValue(value, true);
   3289                     }
   3290                     mSensorManager.registerListener(mLightListener, mLightSensor,
   3291                             LIGHT_SENSOR_RATE);
   3292                 } else {
   3293                     mSensorManager.unregisterListener(mLightListener);
   3294                     mHandler.removeCallbacks(mAutoBrightnessTask);
   3295                     mLightSensorPendingDecrease = false;
   3296                     mLightSensorPendingIncrease = false;
   3297                 }
   3298             } finally {
   3299                 Binder.restoreCallingIdentity(identity);
   3300             }
   3301         }
   3302     }
   3303 
   3304     SensorEventListener mProximityListener = new SensorEventListener() {
   3305         public void onSensorChanged(SensorEvent event) {
   3306             long milliseconds = SystemClock.elapsedRealtime();
   3307             synchronized (mLocks) {
   3308                 float distance = event.values[0];
   3309                 long timeSinceLastEvent = milliseconds - mLastProximityEventTime;
   3310                 mLastProximityEventTime = milliseconds;
   3311                 mHandler.removeCallbacks(mProximityTask);
   3312                 boolean proximityTaskQueued = false;
   3313 
   3314                 // compare against getMaximumRange to support sensors that only return 0 or 1
   3315                 boolean active = (distance >= 0.0 && distance < PROXIMITY_THRESHOLD &&
   3316                         distance < mProximitySensor.getMaximumRange());
   3317 
   3318                 if (mDebugProximitySensor) {
   3319                     Slog.d(TAG, "mProximityListener.onSensorChanged active: " + active);
   3320                 }
   3321                 if (timeSinceLastEvent < PROXIMITY_SENSOR_DELAY) {
   3322                     // enforce delaying atleast PROXIMITY_SENSOR_DELAY before processing
   3323                     mProximityPendingValue = (active ? 1 : 0);
   3324                     mHandler.postDelayed(mProximityTask, PROXIMITY_SENSOR_DELAY - timeSinceLastEvent);
   3325                     proximityTaskQueued = true;
   3326                 } else {
   3327                     // process the value immediately
   3328                     mProximityPendingValue = -1;
   3329                     proximityChangedLocked(active);
   3330                 }
   3331 
   3332                 // update mProximityPartialLock state
   3333                 boolean held = mProximityPartialLock.isHeld();
   3334                 if (!held && proximityTaskQueued) {
   3335                     // hold wakelock until mProximityTask runs
   3336                     mProximityPartialLock.acquire();
   3337                 } else if (held && !proximityTaskQueued) {
   3338                     mProximityPartialLock.release();
   3339                 }
   3340             }
   3341         }
   3342 
   3343         public void onAccuracyChanged(Sensor sensor, int accuracy) {
   3344             // ignore
   3345         }
   3346     };
   3347 
   3348     private void handleLightSensorValue(int value, boolean immediate) {
   3349         long milliseconds = SystemClock.elapsedRealtime();
   3350         if (mLightSensorValue == -1
   3351                 || milliseconds < mLastScreenOnTime + mLightSensorWarmupTime
   3352                 || mWaitingForFirstLightSensor) {
   3353             // process the value immediately if screen has just turned on
   3354             mHandler.removeCallbacks(mAutoBrightnessTask);
   3355             mLightSensorPendingDecrease = false;
   3356             mLightSensorPendingIncrease = false;
   3357             lightSensorChangedLocked(value, immediate);
   3358         } else {
   3359             if ((value > mLightSensorValue && mLightSensorPendingDecrease) ||
   3360                     (value < mLightSensorValue && mLightSensorPendingIncrease) ||
   3361                     (value == mLightSensorValue) ||
   3362                     (!mLightSensorPendingDecrease && !mLightSensorPendingIncrease)) {
   3363                 // delay processing to debounce the sensor
   3364                 mHandler.removeCallbacks(mAutoBrightnessTask);
   3365                 mLightSensorPendingDecrease = (value < mLightSensorValue);
   3366                 mLightSensorPendingIncrease = (value > mLightSensorValue);
   3367                 if (mLightSensorPendingDecrease || mLightSensorPendingIncrease) {
   3368                     mLightSensorPendingValue = value;
   3369                     mHandler.postDelayed(mAutoBrightnessTask, LIGHT_SENSOR_DELAY);
   3370                 }
   3371             } else {
   3372                 mLightSensorPendingValue = value;
   3373             }
   3374         }
   3375     }
   3376 
   3377     SensorEventListener mLightListener = new SensorEventListener() {
   3378         @Override
   3379         public void onSensorChanged(SensorEvent event) {
   3380             if (mDebugLightSensor) {
   3381                 Slog.d(TAG, "onSensorChanged: light value: " + event.values[0]);
   3382             }
   3383             synchronized (mLocks) {
   3384                 // ignore light sensor while screen is turning off
   3385                 if (isScreenTurningOffLocked()) {
   3386                     return;
   3387                 }
   3388                 handleLightSensorValue((int)event.values[0], mWaitingForFirstLightSensor);
   3389                 if (mWaitingForFirstLightSensor && !mPreparingForScreenOn) {
   3390                     if (mDebugLightAnimation) {
   3391                         Slog.d(TAG, "onSensorChanged: Clearing mWaitingForFirstLightSensor.");
   3392                     }
   3393                     mWaitingForFirstLightSensor = false;
   3394                 }
   3395             }
   3396         }
   3397 
   3398         @Override
   3399         public void onAccuracyChanged(Sensor sensor, int accuracy) {
   3400             // ignore
   3401         }
   3402     };
   3403 }
   3404