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