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