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