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