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