PowerManagerService.java revision 9fca9e96989bb70c3a5fa9de37681c9228c88ae6
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
17package com.android.server.power;
18
19import com.android.internal.app.IBatteryStats;
20import com.android.server.BatteryService;
21import com.android.server.EventLogTags;
22import com.android.server.LightsService;
23import com.android.server.TwilightService;
24import com.android.server.Watchdog;
25import com.android.server.am.ActivityManagerService;
26import com.android.server.display.DisplayManagerService;
27import com.android.server.dreams.DreamManagerService;
28
29import android.Manifest;
30import android.content.BroadcastReceiver;
31import android.content.ContentResolver;
32import android.content.Context;
33import android.content.Intent;
34import android.content.IntentFilter;
35import android.content.pm.PackageManager;
36import android.content.res.Resources;
37import android.database.ContentObserver;
38import android.net.Uri;
39import android.os.BatteryManager;
40import android.os.Binder;
41import android.os.Handler;
42import android.os.HandlerThread;
43import android.os.IBinder;
44import android.os.IPowerManager;
45import android.os.Looper;
46import android.os.Message;
47import android.os.PowerManager;
48import android.os.Process;
49import android.os.RemoteException;
50import android.os.SystemClock;
51import android.os.UserHandle;
52import android.os.WorkSource;
53import android.provider.Settings;
54import android.util.EventLog;
55import android.util.Log;
56import android.util.Slog;
57import android.util.TimeUtils;
58import android.view.WindowManagerPolicy;
59
60import java.io.FileDescriptor;
61import java.io.IOException;
62import java.io.PrintWriter;
63import java.util.ArrayList;
64
65import libcore.util.Objects;
66
67/**
68 * The power manager service is responsible for coordinating power management
69 * functions on the device.
70 */
71public final class PowerManagerService extends IPowerManager.Stub
72        implements Watchdog.Monitor {
73    private static final String TAG = "PowerManagerService";
74
75    private static final boolean DEBUG = false;
76    private static final boolean DEBUG_SPEW = DEBUG && true;
77
78    // Message: Sent when a user activity timeout occurs to update the power state.
79    private static final int MSG_USER_ACTIVITY_TIMEOUT = 1;
80    // Message: Sent when the device enters or exits a napping or dreaming state.
81    private static final int MSG_SANDMAN = 2;
82    // Message: Sent when the screen on blocker is released.
83    private static final int MSG_SCREEN_ON_BLOCKER_RELEASED = 3;
84
85    // Dirty bit: mWakeLocks changed
86    private static final int DIRTY_WAKE_LOCKS = 1 << 0;
87    // Dirty bit: mWakefulness changed
88    private static final int DIRTY_WAKEFULNESS = 1 << 1;
89    // Dirty bit: user activity was poked or may have timed out
90    private static final int DIRTY_USER_ACTIVITY = 1 << 2;
91    // Dirty bit: actual display power state was updated asynchronously
92    private static final int DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED = 1 << 3;
93    // Dirty bit: mBootCompleted changed
94    private static final int DIRTY_BOOT_COMPLETED = 1 << 4;
95    // Dirty bit: settings changed
96    private static final int DIRTY_SETTINGS = 1 << 5;
97    // Dirty bit: mIsPowered changed
98    private static final int DIRTY_IS_POWERED = 1 << 6;
99    // Dirty bit: mStayOn changed
100    private static final int DIRTY_STAY_ON = 1 << 7;
101    // Dirty bit: battery state changed
102    private static final int DIRTY_BATTERY_STATE = 1 << 8;
103    // Dirty bit: proximity state changed
104    private static final int DIRTY_PROXIMITY_POSITIVE = 1 << 9;
105    // Dirty bit: screen on blocker state became held or unheld
106    private static final int DIRTY_SCREEN_ON_BLOCKER_RELEASED = 1 << 10;
107
108    // Wakefulness: The device is asleep and can only be awoken by a call to wakeUp().
109    // The screen should be off or in the process of being turned off by the display controller.
110    private static final int WAKEFULNESS_ASLEEP = 0;
111    // Wakefulness: The device is fully awake.  It can be put to sleep by a call to goToSleep().
112    // When the user activity timeout expires, the device may start napping or go to sleep.
113    private static final int WAKEFULNESS_AWAKE = 1;
114    // Wakefulness: The device is napping.  It is deciding whether to dream or go to sleep
115    // but hasn't gotten around to it yet.  It can be awoken by a call to wakeUp(), which
116    // ends the nap. User activity may brighten the screen but does not end the nap.
117    private static final int WAKEFULNESS_NAPPING = 2;
118    // Wakefulness: The device is dreaming.  It can be awoken by a call to wakeUp(),
119    // which ends the dream.  The device goes to sleep when goToSleep() is called, when
120    // the dream ends or when unplugged.
121    // User activity may brighten the screen but does not end the dream.
122    private static final int WAKEFULNESS_DREAMING = 3;
123
124    // Summarizes the state of all active wakelocks.
125    private static final int WAKE_LOCK_CPU = 1 << 0;
126    private static final int WAKE_LOCK_SCREEN_BRIGHT = 1 << 1;
127    private static final int WAKE_LOCK_SCREEN_DIM = 1 << 2;
128    private static final int WAKE_LOCK_BUTTON_BRIGHT = 1 << 3;
129    private static final int WAKE_LOCK_PROXIMITY_SCREEN_OFF = 1 << 4;
130
131    // Summarizes the user activity state.
132    private static final int USER_ACTIVITY_SCREEN_BRIGHT = 1 << 0;
133    private static final int USER_ACTIVITY_SCREEN_DIM = 1 << 1;
134
135    // Default and minimum screen off timeout in milliseconds.
136    private static final int DEFAULT_SCREEN_OFF_TIMEOUT = 15 * 1000;
137    private static final int MINIMUM_SCREEN_OFF_TIMEOUT = 10 * 1000;
138
139    // The screen dim duration, in milliseconds.
140    // This is subtracted from the end of the screen off timeout so the
141    // minimum screen off timeout should be longer than this.
142    private static final int SCREEN_DIM_DURATION = 7 * 1000;
143
144    // The maximum screen dim time expressed as a ratio relative to the screen
145    // off timeout.  If the screen off timeout is very short then we want the
146    // dim timeout to also be quite short so that most of the time is spent on.
147    // Otherwise the user won't get much screen on time before dimming occurs.
148    private static final float MAXIMUM_SCREEN_DIM_RATIO = 0.2f;
149
150    // Upper bound on the battery charge percentage in order to consider turning
151    // the screen on when the device starts charging wirelessly.
152    // See point of use for more details.
153    private static final int WIRELESS_CHARGER_TURN_ON_BATTERY_LEVEL_LIMIT = 95;
154
155    private Context mContext;
156    private LightsService mLightsService;
157    private BatteryService mBatteryService;
158    private IBatteryStats mBatteryStats;
159    private HandlerThread mHandlerThread;
160    private PowerManagerHandler mHandler;
161    private WindowManagerPolicy mPolicy;
162    private Notifier mNotifier;
163    private DisplayPowerController mDisplayPowerController;
164    private SettingsObserver mSettingsObserver;
165    private DreamManagerService mDreamManager;
166    private LightsService.Light mAttentionLight;
167
168    private final Object mLock = new Object();
169
170    // A bitfield that indicates what parts of the power state have
171    // changed and need to be recalculated.
172    private int mDirty;
173
174    // Indicates whether the device is awake or asleep or somewhere in between.
175    // This is distinct from the screen power state, which is managed separately.
176    private int mWakefulness;
177
178    // True if MSG_SANDMAN has been scheduled.
179    private boolean mSandmanScheduled;
180
181    // Table of all suspend blockers.
182    // There should only be a few of these.
183    private final ArrayList<SuspendBlocker> mSuspendBlockers = new ArrayList<SuspendBlocker>();
184
185    // Table of all wake locks acquired by applications.
186    private final ArrayList<WakeLock> mWakeLocks = new ArrayList<WakeLock>();
187
188    // A bitfield that summarizes the state of all active wakelocks.
189    private int mWakeLockSummary;
190
191    // If true, instructs the display controller to wait for the proximity sensor to
192    // go negative before turning the screen on.
193    private boolean mRequestWaitForNegativeProximity;
194
195    // Timestamp of the last time the device was awoken or put to sleep.
196    private long mLastWakeTime;
197    private long mLastSleepTime;
198
199    // True if we need to send a wake up or go to sleep finished notification
200    // when the display is ready.
201    private boolean mSendWakeUpFinishedNotificationWhenReady;
202    private boolean mSendGoToSleepFinishedNotificationWhenReady;
203
204    // Timestamp of the last call to user activity.
205    private long mLastUserActivityTime;
206    private long mLastUserActivityTimeNoChangeLights;
207
208    // A bitfield that summarizes the effect of the user activity timer.
209    // A zero value indicates that the user activity timer has expired.
210    private int mUserActivitySummary;
211
212    // The desired display power state.  The actual state may lag behind the
213    // requested because it is updated asynchronously by the display power controller.
214    private final DisplayPowerRequest mDisplayPowerRequest = new DisplayPowerRequest();
215
216    // The time the screen was last turned off, in elapsedRealtime() timebase.
217    private long mLastScreenOffEventElapsedRealTime;
218
219    // True if the display power state has been fully applied, which means the display
220    // is actually on or actually off or whatever was requested.
221    private boolean mDisplayReady;
222
223    // True if holding a wake-lock to block suspend of the CPU.
224    private boolean mHoldingWakeLockSuspendBlocker;
225
226    // The suspend blocker used to keep the CPU alive when wake locks have been acquired.
227    private final SuspendBlocker mWakeLockSuspendBlocker;
228
229    // The screen on blocker used to keep the screen from turning on while the lock
230    // screen is coming up.
231    private final ScreenOnBlockerImpl mScreenOnBlocker;
232
233    // True if systemReady() has been called.
234    private boolean mSystemReady;
235
236    // True if boot completed occurred.  We keep the screen on until this happens.
237    private boolean mBootCompleted;
238
239    // True if the device is plugged into a power source.
240    private boolean mIsPowered;
241
242    // The current plug type, such as BatteryManager.BATTERY_PLUGGED_WIRELESS.
243    private int mPlugType;
244
245    // True if the device should wake up when plugged or unplugged.
246    private boolean mWakeUpWhenPluggedOrUnpluggedConfig;
247
248    // True if dreams are supported on this device.
249    private boolean mDreamsSupportedConfig;
250
251    // True if dreams are enabled by the user.
252    private boolean mDreamsEnabledSetting;
253
254    // True if dreams should be activated on sleep.
255    private boolean mDreamsActivateOnSleepSetting;
256
257    // The screen off timeout setting value in milliseconds.
258    private int mScreenOffTimeoutSetting;
259
260    // The maximum allowable screen off timeout according to the device
261    // administration policy.  Overrides other settings.
262    private int mMaximumScreenOffTimeoutFromDeviceAdmin = Integer.MAX_VALUE;
263
264    // The stay on while plugged in setting.
265    // A bitfield of battery conditions under which to make the screen stay on.
266    private int mStayOnWhilePluggedInSetting;
267
268    // True if the device should stay on.
269    private boolean mStayOn;
270
271    // True if the proximity sensor reads a positive result.
272    private boolean mProximityPositive;
273
274    // Screen brightness setting limits.
275    private int mScreenBrightnessSettingMinimum;
276    private int mScreenBrightnessSettingMaximum;
277    private int mScreenBrightnessSettingDefault;
278
279    // The screen brightness setting, from 0 to 255.
280    // Use -1 if no value has been set.
281    private int mScreenBrightnessSetting;
282
283    // The screen auto-brightness adjustment setting, from -1 to 1.
284    // Use 0 if there is no adjustment.
285    private float mScreenAutoBrightnessAdjustmentSetting;
286
287    // The screen brightness mode.
288    // One of the Settings.System.SCREEN_BRIGHTNESS_MODE_* constants.
289    private int mScreenBrightnessModeSetting;
290
291    // The screen brightness setting override from the window manager
292    // to allow the current foreground activity to override the brightness.
293    // Use -1 to disable.
294    private int mScreenBrightnessOverrideFromWindowManager = -1;
295
296    // The user activity timeout override from the window manager
297    // to allow the current foreground activity to override the user activity timeout.
298    // Use -1 to disable.
299    private long mUserActivityTimeoutOverrideFromWindowManager = -1;
300
301    // The screen brightness setting override from the settings application
302    // to temporarily adjust the brightness until next updated,
303    // Use -1 to disable.
304    private int mTemporaryScreenBrightnessSettingOverride = -1;
305
306    // The screen brightness adjustment setting override from the settings
307    // application to temporarily adjust the auto-brightness adjustment factor
308    // until next updated, in the range -1..1.
309    // Use NaN to disable.
310    private float mTemporaryScreenAutoBrightnessAdjustmentSettingOverride = Float.NaN;
311
312    // Time when we last logged a warning about calling userActivity() without permission.
313    private long mLastWarningAboutUserActivityPermission = Long.MIN_VALUE;
314
315    private native void nativeInit();
316    private static native void nativeShutdown();
317    private static native void nativeReboot(String reason) throws IOException;
318
319    private static native void nativeSetPowerState(boolean screenOn, boolean screenBright);
320    private static native void nativeAcquireSuspendBlocker(String name);
321    private static native void nativeReleaseSuspendBlocker(String name);
322
323    static native void nativeSetScreenState(boolean on);
324
325    public PowerManagerService() {
326        synchronized (mLock) {
327            mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService");
328            mWakeLockSuspendBlocker.acquire();
329            mScreenOnBlocker = new ScreenOnBlockerImpl();
330            mHoldingWakeLockSuspendBlocker = true;
331            mWakefulness = WAKEFULNESS_AWAKE;
332        }
333
334        nativeInit();
335        nativeSetPowerState(true, true);
336    }
337
338    /**
339     * Initialize the power manager.
340     * Must be called before any other functions within the power manager are called.
341     */
342    public void init(Context context, LightsService ls,
343            ActivityManagerService am, BatteryService bs, IBatteryStats bss,
344            DisplayManagerService dm) {
345        // Forcibly turn the screen on at boot so that it is in a known power state.
346        // We do this in init() rather than in the constructor because setting the
347        // screen state requires a call into surface flinger which then needs to call back
348        // into the activity manager to check permissions.  Unfortunately the
349        // activity manager is not running when the constructor is called, so we
350        // have to defer setting the screen state until this point.
351        nativeSetScreenState(true);
352
353        mContext = context;
354        mLightsService = ls;
355        mBatteryService = bs;
356        mBatteryStats = bss;
357        mHandlerThread = new HandlerThread(TAG);
358        mHandlerThread.start();
359        mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
360
361        Watchdog.getInstance().addMonitor(this);
362    }
363
364    public void setPolicy(WindowManagerPolicy policy) {
365        synchronized (mLock) {
366            mPolicy = policy;
367        }
368    }
369
370    public void systemReady(TwilightService twilight, DreamManagerService dreamManager) {
371        synchronized (mLock) {
372            mSystemReady = true;
373            mDreamManager = dreamManager;
374
375            PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
376            mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting();
377            mScreenBrightnessSettingMaximum = pm.getMaximumScreenBrightnessSetting();
378            mScreenBrightnessSettingDefault = pm.getDefaultScreenBrightnessSetting();
379
380            // The notifier runs on the system server's main looper so as not to interfere
381            // with the animations and other critical functions of the power manager.
382            mNotifier = new Notifier(Looper.getMainLooper(), mContext, mBatteryStats,
383                    createSuspendBlockerLocked("PowerManagerService.Broadcasts"),
384                    mScreenOnBlocker, mPolicy);
385
386            // The display power controller runs on the power manager service's
387            // own handler thread.
388            mDisplayPowerController = new DisplayPowerController(mHandler.getLooper(),
389                    mContext, mNotifier, mLightsService, twilight,
390                    createSuspendBlockerLocked("PowerManagerService.Display"),
391                    mDisplayPowerControllerCallbacks, mHandler);
392
393            mSettingsObserver = new SettingsObserver(mHandler);
394            mAttentionLight = mLightsService.getLight(LightsService.LIGHT_ID_ATTENTION);
395
396            // Register for broadcasts from other components of the system.
397            IntentFilter filter = new IntentFilter();
398            filter.addAction(Intent.ACTION_BATTERY_CHANGED);
399            mContext.registerReceiver(new BatteryReceiver(), filter, null, mHandler);
400
401            filter = new IntentFilter();
402            filter.addAction(Intent.ACTION_BOOT_COMPLETED);
403            mContext.registerReceiver(new BootCompletedReceiver(), filter, null, mHandler);
404
405            filter = new IntentFilter();
406            filter.addAction(Intent.ACTION_DREAMING_STARTED);
407            filter.addAction(Intent.ACTION_DREAMING_STOPPED);
408            mContext.registerReceiver(new DreamReceiver(), filter, null, mHandler);
409
410            filter = new IntentFilter();
411            filter.addAction(Intent.ACTION_USER_SWITCHED);
412            mContext.registerReceiver(new UserSwitchedReceiver(), filter, null, mHandler);
413
414            // Register for settings changes.
415            final ContentResolver resolver = mContext.getContentResolver();
416            resolver.registerContentObserver(Settings.Secure.getUriFor(
417                    Settings.Secure.SCREENSAVER_ENABLED),
418                    false, mSettingsObserver, UserHandle.USER_ALL);
419            resolver.registerContentObserver(Settings.Secure.getUriFor(
420                    Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP),
421                    false, mSettingsObserver, UserHandle.USER_ALL);
422            resolver.registerContentObserver(Settings.System.getUriFor(
423                    Settings.System.SCREEN_OFF_TIMEOUT),
424                    false, mSettingsObserver, UserHandle.USER_ALL);
425            resolver.registerContentObserver(Settings.Global.getUriFor(
426                    Settings.Global.STAY_ON_WHILE_PLUGGED_IN),
427                    false, mSettingsObserver, UserHandle.USER_ALL);
428            resolver.registerContentObserver(Settings.System.getUriFor(
429                    Settings.System.SCREEN_BRIGHTNESS),
430                    false, mSettingsObserver, UserHandle.USER_ALL);
431            resolver.registerContentObserver(Settings.System.getUriFor(
432                    Settings.System.SCREEN_BRIGHTNESS_MODE),
433                    false, mSettingsObserver, UserHandle.USER_ALL);
434
435            // Go.
436            readConfigurationLocked();
437            updateSettingsLocked();
438            mDirty |= DIRTY_BATTERY_STATE;
439            updatePowerStateLocked();
440        }
441    }
442
443    private void readConfigurationLocked() {
444        final Resources resources = mContext.getResources();
445
446        mWakeUpWhenPluggedOrUnpluggedConfig = resources.getBoolean(
447                com.android.internal.R.bool.config_unplugTurnsOnScreen);
448        mDreamsSupportedConfig = resources.getBoolean(
449                com.android.internal.R.bool.config_enableDreams);
450    }
451
452    private void updateSettingsLocked() {
453        final ContentResolver resolver = mContext.getContentResolver();
454
455        mDreamsEnabledSetting = (Settings.Secure.getIntForUser(resolver,
456                Settings.Secure.SCREENSAVER_ENABLED, 0,
457                UserHandle.USER_CURRENT) != 0);
458        mDreamsActivateOnSleepSetting = (Settings.Secure.getIntForUser(resolver,
459                Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, 0,
460                UserHandle.USER_CURRENT) != 0);
461        mScreenOffTimeoutSetting = Settings.System.getIntForUser(resolver,
462                Settings.System.SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT,
463                UserHandle.USER_CURRENT);
464        mStayOnWhilePluggedInSetting = Settings.Global.getInt(resolver,
465                Settings.Global.STAY_ON_WHILE_PLUGGED_IN, BatteryManager.BATTERY_PLUGGED_AC);
466
467        final int oldScreenBrightnessSetting = mScreenBrightnessSetting;
468        mScreenBrightnessSetting = Settings.System.getIntForUser(resolver,
469                Settings.System.SCREEN_BRIGHTNESS, mScreenBrightnessSettingDefault,
470                UserHandle.USER_CURRENT);
471        if (oldScreenBrightnessSetting != mScreenBrightnessSetting) {
472            mTemporaryScreenBrightnessSettingOverride = -1;
473        }
474
475        final float oldScreenAutoBrightnessAdjustmentSetting =
476                mScreenAutoBrightnessAdjustmentSetting;
477        mScreenAutoBrightnessAdjustmentSetting = Settings.System.getFloatForUser(resolver,
478                Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f,
479                UserHandle.USER_CURRENT);
480        if (oldScreenAutoBrightnessAdjustmentSetting != mScreenAutoBrightnessAdjustmentSetting) {
481            mTemporaryScreenAutoBrightnessAdjustmentSettingOverride = Float.NaN;
482        }
483
484        mScreenBrightnessModeSetting = Settings.System.getIntForUser(resolver,
485                Settings.System.SCREEN_BRIGHTNESS_MODE,
486                Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, UserHandle.USER_CURRENT);
487
488        mDirty |= DIRTY_SETTINGS;
489    }
490
491    private void handleSettingsChangedLocked() {
492        updateSettingsLocked();
493        updatePowerStateLocked();
494    }
495
496    @Override // Binder call
497    public void acquireWakeLock(IBinder lock, int flags, String tag, WorkSource ws) {
498        if (lock == null) {
499            throw new IllegalArgumentException("lock must not be null");
500        }
501        PowerManager.validateWakeLockParameters(flags, tag);
502
503        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
504        if (ws != null && ws.size() != 0) {
505            mContext.enforceCallingOrSelfPermission(
506                    android.Manifest.permission.UPDATE_DEVICE_STATS, null);
507        } else {
508            ws = null;
509        }
510
511        final int uid = Binder.getCallingUid();
512        final int pid = Binder.getCallingPid();
513        final long ident = Binder.clearCallingIdentity();
514        try {
515            acquireWakeLockInternal(lock, flags, tag, ws, uid, pid);
516        } finally {
517            Binder.restoreCallingIdentity(ident);
518        }
519    }
520
521    private void acquireWakeLockInternal(IBinder lock, int flags, String tag, WorkSource ws,
522            int uid, int pid) {
523        synchronized (mLock) {
524            if (DEBUG_SPEW) {
525                Slog.d(TAG, "acquireWakeLockInternal: lock=" + Objects.hashCode(lock)
526                        + ", flags=0x" + Integer.toHexString(flags)
527                        + ", tag=\"" + tag + "\", ws=" + ws + ", uid=" + uid + ", pid=" + pid);
528            }
529
530            WakeLock wakeLock;
531            int index = findWakeLockIndexLocked(lock);
532            if (index >= 0) {
533                wakeLock = mWakeLocks.get(index);
534                if (!wakeLock.hasSameProperties(flags, tag, ws, uid, pid)) {
535                    // Update existing wake lock.  This shouldn't happen but is harmless.
536                    notifyWakeLockReleasedLocked(wakeLock);
537                    wakeLock.updateProperties(flags, tag, ws, uid, pid);
538                    notifyWakeLockAcquiredLocked(wakeLock);
539                }
540            } else {
541                wakeLock = new WakeLock(lock, flags, tag, ws, uid, pid);
542                try {
543                    lock.linkToDeath(wakeLock, 0);
544                } catch (RemoteException ex) {
545                    throw new IllegalArgumentException("Wake lock is already dead.");
546                }
547                notifyWakeLockAcquiredLocked(wakeLock);
548                mWakeLocks.add(wakeLock);
549            }
550
551            applyWakeLockFlagsOnAcquireLocked(wakeLock);
552            mDirty |= DIRTY_WAKE_LOCKS;
553            updatePowerStateLocked();
554        }
555    }
556
557    private void applyWakeLockFlagsOnAcquireLocked(WakeLock wakeLock) {
558        if ((wakeLock.mFlags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {
559            wakeUpNoUpdateLocked(SystemClock.uptimeMillis());
560        }
561    }
562
563    @Override // Binder call
564    public void releaseWakeLock(IBinder lock, int flags) {
565        if (lock == null) {
566            throw new IllegalArgumentException("lock must not be null");
567        }
568
569        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
570
571        final long ident = Binder.clearCallingIdentity();
572        try {
573            releaseWakeLockInternal(lock, flags);
574        } finally {
575            Binder.restoreCallingIdentity(ident);
576        }
577    }
578
579    private void releaseWakeLockInternal(IBinder lock, int flags) {
580        synchronized (mLock) {
581            if (DEBUG_SPEW) {
582                Slog.d(TAG, "releaseWakeLockInternal: lock=" + Objects.hashCode(lock)
583                        + ", flags=0x" + Integer.toHexString(flags));
584            }
585
586            int index = findWakeLockIndexLocked(lock);
587            if (index < 0) {
588                return;
589            }
590
591            WakeLock wakeLock = mWakeLocks.get(index);
592            mWakeLocks.remove(index);
593            notifyWakeLockReleasedLocked(wakeLock);
594            wakeLock.mLock.unlinkToDeath(wakeLock, 0);
595
596            if ((flags & PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE) != 0) {
597                mRequestWaitForNegativeProximity = true;
598            }
599
600            applyWakeLockFlagsOnReleaseLocked(wakeLock);
601            mDirty |= DIRTY_WAKE_LOCKS;
602            updatePowerStateLocked();
603        }
604    }
605
606    private void handleWakeLockDeath(WakeLock wakeLock) {
607        synchronized (mLock) {
608            if (DEBUG_SPEW) {
609                Slog.d(TAG, "handleWakeLockDeath: lock=" + Objects.hashCode(wakeLock.mLock));
610            }
611
612            int index = mWakeLocks.indexOf(wakeLock);
613            if (index < 0) {
614                return;
615            }
616
617            mWakeLocks.remove(index);
618            notifyWakeLockReleasedLocked(wakeLock);
619
620            applyWakeLockFlagsOnReleaseLocked(wakeLock);
621            mDirty |= DIRTY_WAKE_LOCKS;
622            updatePowerStateLocked();
623        }
624    }
625
626    private void applyWakeLockFlagsOnReleaseLocked(WakeLock wakeLock) {
627        if ((wakeLock.mFlags & PowerManager.ON_AFTER_RELEASE) != 0) {
628            userActivityNoUpdateLocked(SystemClock.uptimeMillis(),
629                    PowerManager.USER_ACTIVITY_EVENT_OTHER,
630                    PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS,
631                    wakeLock.mOwnerUid);
632        }
633    }
634
635    @Override // Binder call
636    public void updateWakeLockWorkSource(IBinder lock, WorkSource ws) {
637        if (lock == null) {
638            throw new IllegalArgumentException("lock must not be null");
639        }
640
641        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
642        if (ws != null && ws.size() != 0) {
643            mContext.enforceCallingOrSelfPermission(
644                    android.Manifest.permission.UPDATE_DEVICE_STATS, null);
645        } else {
646            ws = null;
647        }
648
649        final long ident = Binder.clearCallingIdentity();
650        try {
651            updateWakeLockWorkSourceInternal(lock, ws);
652        } finally {
653            Binder.restoreCallingIdentity(ident);
654        }
655    }
656
657    private void updateWakeLockWorkSourceInternal(IBinder lock, WorkSource ws) {
658        synchronized (mLock) {
659            int index = findWakeLockIndexLocked(lock);
660            if (index < 0) {
661                throw new IllegalArgumentException("Wake lock not active");
662            }
663
664            WakeLock wakeLock = mWakeLocks.get(index);
665            if (!wakeLock.hasSameWorkSource(ws)) {
666                notifyWakeLockReleasedLocked(wakeLock);
667                wakeLock.updateWorkSource(ws);
668                notifyWakeLockAcquiredLocked(wakeLock);
669            }
670        }
671    }
672
673    private int findWakeLockIndexLocked(IBinder lock) {
674        final int count = mWakeLocks.size();
675        for (int i = 0; i < count; i++) {
676            if (mWakeLocks.get(i).mLock == lock) {
677                return i;
678            }
679        }
680        return -1;
681    }
682
683    private void notifyWakeLockAcquiredLocked(WakeLock wakeLock) {
684        if (mSystemReady) {
685            mNotifier.onWakeLockAcquired(wakeLock.mFlags, wakeLock.mTag,
686                    wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource);
687        }
688    }
689
690    private void notifyWakeLockReleasedLocked(WakeLock wakeLock) {
691        if (mSystemReady) {
692            mNotifier.onWakeLockReleased(wakeLock.mFlags, wakeLock.mTag,
693                    wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource);
694        }
695    }
696
697    @Override // Binder call
698    public boolean isWakeLockLevelSupported(int level) {
699        final long ident = Binder.clearCallingIdentity();
700        try {
701            return isWakeLockLevelSupportedInternal(level);
702        } finally {
703            Binder.restoreCallingIdentity(ident);
704        }
705    }
706
707    private boolean isWakeLockLevelSupportedInternal(int level) {
708        synchronized (mLock) {
709            switch (level) {
710                case PowerManager.PARTIAL_WAKE_LOCK:
711                case PowerManager.SCREEN_DIM_WAKE_LOCK:
712                case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
713                case PowerManager.FULL_WAKE_LOCK:
714                    return true;
715
716                case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
717                    return mSystemReady && mDisplayPowerController.isProximitySensorAvailable();
718
719                default:
720                    return false;
721            }
722        }
723    }
724
725    @Override // Binder call
726    public void userActivity(long eventTime, int event, int flags) {
727        final long now = SystemClock.uptimeMillis();
728        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER)
729                != PackageManager.PERMISSION_GRANTED) {
730            // Once upon a time applications could call userActivity().
731            // Now we require the DEVICE_POWER permission.  Log a warning and ignore the
732            // request instead of throwing a SecurityException so we don't break old apps.
733            synchronized (mLock) {
734                if (now >= mLastWarningAboutUserActivityPermission + (5 * 60 * 1000)) {
735                    mLastWarningAboutUserActivityPermission = now;
736                    Slog.w(TAG, "Ignoring call to PowerManager.userActivity() because the "
737                            + "caller does not have DEVICE_POWER permission.  "
738                            + "Please fix your app!  "
739                            + " pid=" + Binder.getCallingPid()
740                            + " uid=" + Binder.getCallingUid());
741                }
742            }
743            return;
744        }
745
746        if (eventTime > SystemClock.uptimeMillis()) {
747            throw new IllegalArgumentException("event time must not be in the future");
748        }
749
750        final int uid = Binder.getCallingUid();
751        final long ident = Binder.clearCallingIdentity();
752        try {
753            userActivityInternal(eventTime, event, flags, uid);
754        } finally {
755            Binder.restoreCallingIdentity(ident);
756        }
757    }
758
759    // Called from native code.
760    private void userActivityFromNative(long eventTime, int event, int flags) {
761        userActivityInternal(eventTime, event, flags, Process.SYSTEM_UID);
762    }
763
764    private void userActivityInternal(long eventTime, int event, int flags, int uid) {
765        synchronized (mLock) {
766            if (userActivityNoUpdateLocked(eventTime, event, flags, uid)) {
767                updatePowerStateLocked();
768            }
769        }
770    }
771
772    private boolean userActivityNoUpdateLocked(long eventTime, int event, int flags, int uid) {
773        if (DEBUG_SPEW) {
774            Slog.d(TAG, "userActivityNoUpdateLocked: eventTime=" + eventTime
775                    + ", event=" + event + ", flags=0x" + Integer.toHexString(flags)
776                    + ", uid=" + uid);
777        }
778
779        if (eventTime < mLastSleepTime || eventTime < mLastWakeTime
780                || mWakefulness == WAKEFULNESS_ASLEEP || !mBootCompleted || !mSystemReady) {
781            return false;
782        }
783
784        mNotifier.onUserActivity(event, uid);
785
786        if ((flags & PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS) != 0) {
787            if (eventTime > mLastUserActivityTimeNoChangeLights
788                    && eventTime > mLastUserActivityTime) {
789                mLastUserActivityTimeNoChangeLights = eventTime;
790                mDirty |= DIRTY_USER_ACTIVITY;
791                return true;
792            }
793        } else {
794            if (eventTime > mLastUserActivityTime) {
795                mLastUserActivityTime = eventTime;
796                mDirty |= DIRTY_USER_ACTIVITY;
797                return true;
798            }
799        }
800        return false;
801    }
802
803    @Override // Binder call
804    public void wakeUp(long eventTime) {
805        if (eventTime > SystemClock.uptimeMillis()) {
806            throw new IllegalArgumentException("event time must not be in the future");
807        }
808
809        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
810
811        final long ident = Binder.clearCallingIdentity();
812        try {
813            wakeUpInternal(eventTime);
814        } finally {
815            Binder.restoreCallingIdentity(ident);
816        }
817    }
818
819    // Called from native code.
820    private void wakeUpFromNative(long eventTime) {
821        wakeUpInternal(eventTime);
822    }
823
824    private void wakeUpInternal(long eventTime) {
825        synchronized (mLock) {
826            if (wakeUpNoUpdateLocked(eventTime)) {
827                updatePowerStateLocked();
828            }
829        }
830    }
831
832    private boolean wakeUpNoUpdateLocked(long eventTime) {
833        if (DEBUG_SPEW) {
834            Slog.d(TAG, "wakeUpNoUpdateLocked: eventTime=" + eventTime);
835        }
836
837        if (eventTime < mLastSleepTime || mWakefulness == WAKEFULNESS_AWAKE
838                || !mBootCompleted || !mSystemReady) {
839            return false;
840        }
841
842        switch (mWakefulness) {
843            case WAKEFULNESS_ASLEEP:
844                Slog.i(TAG, "Waking up from sleep...");
845                sendPendingNotificationsLocked();
846                mNotifier.onWakeUpStarted();
847                mSendWakeUpFinishedNotificationWhenReady = true;
848                break;
849            case WAKEFULNESS_DREAMING:
850                Slog.i(TAG, "Waking up from dream...");
851                break;
852            case WAKEFULNESS_NAPPING:
853                Slog.i(TAG, "Waking up from nap...");
854                break;
855        }
856
857        mLastWakeTime = eventTime;
858        mWakefulness = WAKEFULNESS_AWAKE;
859        mDirty |= DIRTY_WAKEFULNESS;
860
861        userActivityNoUpdateLocked(
862                eventTime, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
863        return true;
864    }
865
866    @Override // Binder call
867    public void goToSleep(long eventTime, int reason) {
868        if (eventTime > SystemClock.uptimeMillis()) {
869            throw new IllegalArgumentException("event time must not be in the future");
870        }
871
872        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
873
874        final long ident = Binder.clearCallingIdentity();
875        try {
876            goToSleepInternal(eventTime, reason);
877        } finally {
878            Binder.restoreCallingIdentity(ident);
879        }
880    }
881
882    // Called from native code.
883    private void goToSleepFromNative(long eventTime, int reason) {
884        goToSleepInternal(eventTime, reason);
885    }
886
887    private void goToSleepInternal(long eventTime, int reason) {
888        synchronized (mLock) {
889            if (goToSleepNoUpdateLocked(eventTime, reason)) {
890                updatePowerStateLocked();
891            }
892        }
893    }
894
895    private boolean goToSleepNoUpdateLocked(long eventTime, int reason) {
896        if (DEBUG_SPEW) {
897            Slog.d(TAG, "goToSleepNoUpdateLocked: eventTime=" + eventTime + ", reason=" + reason);
898        }
899
900        if (eventTime < mLastWakeTime || mWakefulness == WAKEFULNESS_ASLEEP
901                || !mBootCompleted || !mSystemReady) {
902            return false;
903        }
904
905        switch (reason) {
906            case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN:
907                Slog.i(TAG, "Going to sleep due to device administration policy...");
908                break;
909            case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT:
910                Slog.i(TAG, "Going to sleep due to screen timeout...");
911                break;
912            default:
913                Slog.i(TAG, "Going to sleep by user request...");
914                reason = PowerManager.GO_TO_SLEEP_REASON_USER;
915                break;
916        }
917
918        sendPendingNotificationsLocked();
919        mNotifier.onGoToSleepStarted(reason);
920        mSendGoToSleepFinishedNotificationWhenReady = true;
921
922        mLastSleepTime = eventTime;
923        mDirty |= DIRTY_WAKEFULNESS;
924        mWakefulness = WAKEFULNESS_ASLEEP;
925
926        // Report the number of wake locks that will be cleared by going to sleep.
927        int numWakeLocksCleared = 0;
928        final int numWakeLocks = mWakeLocks.size();
929        for (int i = 0; i < numWakeLocks; i++) {
930            final WakeLock wakeLock = mWakeLocks.get(i);
931            switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
932                case PowerManager.FULL_WAKE_LOCK:
933                case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
934                case PowerManager.SCREEN_DIM_WAKE_LOCK:
935                    numWakeLocksCleared += 1;
936                    break;
937            }
938        }
939        EventLog.writeEvent(EventLogTags.POWER_SLEEP_REQUESTED, numWakeLocksCleared);
940        return true;
941    }
942
943    @Override // Binder call
944    public void nap(long eventTime) {
945        if (eventTime > SystemClock.uptimeMillis()) {
946            throw new IllegalArgumentException("event time must not be in the future");
947        }
948
949        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
950
951        final long ident = Binder.clearCallingIdentity();
952        try {
953            napInternal(eventTime);
954        } finally {
955            Binder.restoreCallingIdentity(ident);
956        }
957    }
958
959    private void napInternal(long eventTime) {
960        synchronized (mLock) {
961            if (napNoUpdateLocked(eventTime)) {
962                updatePowerStateLocked();
963            }
964        }
965    }
966
967    private boolean napNoUpdateLocked(long eventTime) {
968        if (DEBUG_SPEW) {
969            Slog.d(TAG, "napNoUpdateLocked: eventTime=" + eventTime);
970        }
971
972        if (eventTime < mLastWakeTime || mWakefulness != WAKEFULNESS_AWAKE
973                || !mBootCompleted || !mSystemReady) {
974            return false;
975        }
976
977        Slog.i(TAG, "Nap time...");
978
979        mDirty |= DIRTY_WAKEFULNESS;
980        mWakefulness = WAKEFULNESS_NAPPING;
981        return true;
982    }
983
984    /**
985     * Updates the global power state based on dirty bits recorded in mDirty.
986     *
987     * This is the main function that performs power state transitions.
988     * We centralize them here so that we can recompute the power state completely
989     * each time something important changes, and ensure that we do it the same
990     * way each time.  The point is to gather all of the transition logic here.
991     */
992    private void updatePowerStateLocked() {
993        if (!mSystemReady || mDirty == 0) {
994            return;
995        }
996
997        // Phase 0: Basic state updates.
998        updateIsPoweredLocked(mDirty);
999        updateStayOnLocked(mDirty);
1000
1001        // Phase 1: Update wakefulness.
1002        // Loop because the wake lock and user activity computations are influenced
1003        // by changes in wakefulness.
1004        final long now = SystemClock.uptimeMillis();
1005        int dirtyPhase2 = 0;
1006        for (;;) {
1007            int dirtyPhase1 = mDirty;
1008            dirtyPhase2 |= dirtyPhase1;
1009            mDirty = 0;
1010
1011            updateWakeLockSummaryLocked(dirtyPhase1);
1012            updateUserActivitySummaryLocked(now, dirtyPhase1);
1013            if (!updateWakefulnessLocked(dirtyPhase1)) {
1014                break;
1015            }
1016        }
1017
1018        // Phase 2: Update dreams and display power state.
1019        updateDreamLocked(dirtyPhase2);
1020        updateDisplayPowerStateLocked(dirtyPhase2);
1021
1022        // Phase 3: Send notifications, if needed.
1023        if (mDisplayReady) {
1024            sendPendingNotificationsLocked();
1025        }
1026
1027        // Phase 4: Update suspend blocker.
1028        // Because we might release the last suspend blocker here, we need to make sure
1029        // we finished everything else first!
1030        updateSuspendBlockerLocked();
1031    }
1032
1033    private void sendPendingNotificationsLocked() {
1034        if (mSendWakeUpFinishedNotificationWhenReady) {
1035            mSendWakeUpFinishedNotificationWhenReady = false;
1036            mNotifier.onWakeUpFinished();
1037        }
1038        if (mSendGoToSleepFinishedNotificationWhenReady) {
1039            mSendGoToSleepFinishedNotificationWhenReady = false;
1040            mNotifier.onGoToSleepFinished();
1041        }
1042    }
1043
1044    /**
1045     * Updates the value of mIsPowered.
1046     * Sets DIRTY_IS_POWERED if a change occurred.
1047     */
1048    private void updateIsPoweredLocked(int dirty) {
1049        if ((dirty & DIRTY_BATTERY_STATE) != 0) {
1050            final boolean wasPowered = mIsPowered;
1051            final int oldPlugType = mPlugType;
1052            mIsPowered = mBatteryService.isPowered(BatteryManager.BATTERY_PLUGGED_ANY);
1053            mPlugType = mBatteryService.getPlugType();
1054
1055            if (DEBUG) {
1056                Slog.d(TAG, "updateIsPoweredLocked: wasPowered=" + wasPowered
1057                        + ", mIsPowered=" + mIsPowered
1058                        + ", oldPlugType=" + oldPlugType
1059                        + ", mPlugType=" + mPlugType);
1060            }
1061
1062            if (wasPowered != mIsPowered || oldPlugType != mPlugType) {
1063                mDirty |= DIRTY_IS_POWERED;
1064
1065                // Treat plugging and unplugging the devices as a user activity.
1066                // Users find it disconcerting when they plug or unplug the device
1067                // and it shuts off right away.
1068                // Some devices also wake the device when plugged or unplugged because
1069                // they don't have a charging LED.
1070                final long now = SystemClock.uptimeMillis();
1071                if (shouldWakeUpWhenPluggedOrUnpluggedLocked(wasPowered, oldPlugType)) {
1072                    wakeUpNoUpdateLocked(now);
1073                }
1074                userActivityNoUpdateLocked(
1075                        now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
1076            }
1077        }
1078    }
1079
1080    private boolean shouldWakeUpWhenPluggedOrUnpluggedLocked(boolean wasPowered, int oldPlugType) {
1081        // Don't wake when powered unless configured to do so.
1082        if (!mWakeUpWhenPluggedOrUnpluggedConfig) {
1083            return false;
1084        }
1085
1086        // FIXME: Need more accurate detection of wireless chargers.
1087        //
1088        // We are unable to accurately detect whether the device is resting on the
1089        // charger unless it is actually receiving power.  This causes us some grief
1090        // because the device might not appear to be plugged into the wireless charger
1091        // unless it actually charging.
1092        //
1093        // To avoid spuriously waking the screen, we apply a special policy to
1094        // wireless chargers.
1095        //
1096        // 1. Don't wake the device when unplugged from wireless charger because
1097        //    it might be that the device is still resting on the wireless charger
1098        //    but is not receiving power anymore because the battery is full.
1099        //
1100        // 2. Don't wake the device when plugged into a wireless charger if the
1101        //    battery already appears to be mostly full.  This situation may indicate
1102        //    that the device was resting on the charger the whole time and simply
1103        //    wasn't receiving power because the battery was full.  We can't tell
1104        //    whether the device was just placed on the charger or whether it has
1105        //    been there for half of the night slowly discharging until it hit
1106        //    the point where it needed to start charging again.
1107        if (wasPowered && !mIsPowered
1108                && oldPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS) {
1109            return false;
1110        }
1111        if (!wasPowered && mIsPowered
1112                && mPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS
1113                && mBatteryService.getBatteryLevel() >=
1114                        WIRELESS_CHARGER_TURN_ON_BATTERY_LEVEL_LIMIT) {
1115            return false;
1116        }
1117
1118        // If already dreaming and becoming powered, then don't wake.
1119        if (mIsPowered && (mWakefulness == WAKEFULNESS_NAPPING
1120                || mWakefulness == WAKEFULNESS_DREAMING)) {
1121            return false;
1122        }
1123
1124        // Otherwise wake up!
1125        return true;
1126    }
1127
1128    /**
1129     * Updates the value of mStayOn.
1130     * Sets DIRTY_STAY_ON if a change occurred.
1131     */
1132    private void updateStayOnLocked(int dirty) {
1133        if ((dirty & (DIRTY_BATTERY_STATE | DIRTY_SETTINGS)) != 0) {
1134            final boolean wasStayOn = mStayOn;
1135            if (mStayOnWhilePluggedInSetting != 0
1136                    && !isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
1137                mStayOn = mBatteryService.isPowered(mStayOnWhilePluggedInSetting);
1138            } else {
1139                mStayOn = false;
1140            }
1141
1142            if (mStayOn != wasStayOn) {
1143                mDirty |= DIRTY_STAY_ON;
1144            }
1145        }
1146    }
1147
1148    /**
1149     * Updates the value of mWakeLockSummary to summarize the state of all active wake locks.
1150     * Note that most wake-locks are ignored when the system is asleep.
1151     *
1152     * This function must have no other side-effects.
1153     */
1154    private void updateWakeLockSummaryLocked(int dirty) {
1155        if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_WAKEFULNESS)) != 0) {
1156            mWakeLockSummary = 0;
1157
1158            final int numWakeLocks = mWakeLocks.size();
1159            for (int i = 0; i < numWakeLocks; i++) {
1160                final WakeLock wakeLock = mWakeLocks.get(i);
1161                switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
1162                    case PowerManager.PARTIAL_WAKE_LOCK:
1163                        mWakeLockSummary |= WAKE_LOCK_CPU;
1164                        break;
1165                    case PowerManager.FULL_WAKE_LOCK:
1166                        if (mWakefulness != WAKEFULNESS_ASLEEP) {
1167                            mWakeLockSummary |= WAKE_LOCK_CPU
1168                                    | WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_BUTTON_BRIGHT;
1169                        }
1170                        break;
1171                    case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
1172                        if (mWakefulness != WAKEFULNESS_ASLEEP) {
1173                            mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_SCREEN_BRIGHT;
1174                        }
1175                        break;
1176                    case PowerManager.SCREEN_DIM_WAKE_LOCK:
1177                        if (mWakefulness != WAKEFULNESS_ASLEEP) {
1178                            mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_SCREEN_DIM;
1179                        }
1180                        break;
1181                    case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
1182                        if (mWakefulness != WAKEFULNESS_ASLEEP) {
1183                            mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_PROXIMITY_SCREEN_OFF;
1184                        }
1185                        break;
1186                }
1187            }
1188
1189            if (DEBUG_SPEW) {
1190                Slog.d(TAG, "updateWakeLockSummaryLocked: mWakefulness="
1191                        + wakefulnessToString(mWakefulness)
1192                        + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary));
1193            }
1194        }
1195    }
1196
1197    /**
1198     * Updates the value of mUserActivitySummary to summarize the user requested
1199     * state of the system such as whether the screen should be bright or dim.
1200     * Note that user activity is ignored when the system is asleep.
1201     *
1202     * This function must have no other side-effects.
1203     */
1204    private void updateUserActivitySummaryLocked(long now, int dirty) {
1205        // Update the status of the user activity timeout timer.
1206        if ((dirty & (DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS | DIRTY_SETTINGS)) != 0) {
1207            mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT);
1208
1209            long nextTimeout = 0;
1210            if (mWakefulness != WAKEFULNESS_ASLEEP) {
1211                final int screenOffTimeout = getScreenOffTimeoutLocked();
1212                final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
1213
1214                mUserActivitySummary = 0;
1215                if (mLastUserActivityTime >= mLastWakeTime) {
1216                    nextTimeout = mLastUserActivityTime
1217                            + screenOffTimeout - screenDimDuration;
1218                    if (now < nextTimeout) {
1219                        mUserActivitySummary |= USER_ACTIVITY_SCREEN_BRIGHT;
1220                    } else {
1221                        nextTimeout = mLastUserActivityTime + screenOffTimeout;
1222                        if (now < nextTimeout) {
1223                            mUserActivitySummary |= USER_ACTIVITY_SCREEN_DIM;
1224                        }
1225                    }
1226                }
1227                if (mUserActivitySummary == 0
1228                        && mLastUserActivityTimeNoChangeLights >= mLastWakeTime) {
1229                    nextTimeout = mLastUserActivityTimeNoChangeLights + screenOffTimeout;
1230                    if (now < nextTimeout
1231                            && mDisplayPowerRequest.screenState
1232                                    != DisplayPowerRequest.SCREEN_STATE_OFF) {
1233                        mUserActivitySummary = mDisplayPowerRequest.screenState
1234                                == DisplayPowerRequest.SCREEN_STATE_BRIGHT ?
1235                                USER_ACTIVITY_SCREEN_BRIGHT : USER_ACTIVITY_SCREEN_DIM;
1236                    }
1237                }
1238                if (mUserActivitySummary != 0) {
1239                    Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY_TIMEOUT);
1240                    msg.setAsynchronous(true);
1241                    mHandler.sendMessageAtTime(msg, nextTimeout);
1242                }
1243            } else {
1244                mUserActivitySummary = 0;
1245            }
1246
1247            if (DEBUG_SPEW) {
1248                Slog.d(TAG, "updateUserActivitySummaryLocked: mWakefulness="
1249                        + wakefulnessToString(mWakefulness)
1250                        + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
1251                        + ", nextTimeout=" + TimeUtils.formatUptime(nextTimeout));
1252            }
1253        }
1254    }
1255
1256    /**
1257     * Called when a user activity timeout has occurred.
1258     * Simply indicates that something about user activity has changed so that the new
1259     * state can be recomputed when the power state is updated.
1260     *
1261     * This function must have no other side-effects besides setting the dirty
1262     * bit and calling update power state.  Wakefulness transitions are handled elsewhere.
1263     */
1264    private void handleUserActivityTimeout() { // runs on handler thread
1265        synchronized (mLock) {
1266            if (DEBUG_SPEW) {
1267                Slog.d(TAG, "handleUserActivityTimeout");
1268            }
1269
1270            mDirty |= DIRTY_USER_ACTIVITY;
1271            updatePowerStateLocked();
1272        }
1273    }
1274
1275    private int getScreenOffTimeoutLocked() {
1276        int timeout = mScreenOffTimeoutSetting;
1277        if (isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
1278            timeout = Math.min(timeout, mMaximumScreenOffTimeoutFromDeviceAdmin);
1279        }
1280        if (mUserActivityTimeoutOverrideFromWindowManager >= 0) {
1281            timeout = (int)Math.min(timeout, mUserActivityTimeoutOverrideFromWindowManager);
1282        }
1283        return Math.max(timeout, MINIMUM_SCREEN_OFF_TIMEOUT);
1284    }
1285
1286    private int getScreenDimDurationLocked(int screenOffTimeout) {
1287        return Math.min(SCREEN_DIM_DURATION,
1288                (int)(screenOffTimeout * MAXIMUM_SCREEN_DIM_RATIO));
1289    }
1290
1291    /**
1292     * Updates the wakefulness of the device.
1293     *
1294     * This is the function that decides whether the device should start napping
1295     * based on the current wake locks and user activity state.  It may modify mDirty
1296     * if the wakefulness changes.
1297     *
1298     * Returns true if the wakefulness changed and we need to restart power state calculation.
1299     */
1300    private boolean updateWakefulnessLocked(int dirty) {
1301        boolean changed = false;
1302        if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_BOOT_COMPLETED
1303                | DIRTY_WAKEFULNESS | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE)) != 0) {
1304            if (mWakefulness == WAKEFULNESS_AWAKE && isItBedTimeYetLocked()) {
1305                if (DEBUG_SPEW) {
1306                    Slog.d(TAG, "updateWakefulnessLocked: Bed time...");
1307                }
1308                final long time = SystemClock.uptimeMillis();
1309                if (mDreamsActivateOnSleepSetting) {
1310                    changed = napNoUpdateLocked(time);
1311                } else {
1312                    changed = goToSleepNoUpdateLocked(time,
1313                            PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
1314                }
1315            }
1316        }
1317        return changed;
1318    }
1319
1320    /**
1321     * Returns true if the device should go to sleep now.
1322     * Also used when exiting a dream to determine whether we should go back
1323     * to being fully awake or else go to sleep for good.
1324     */
1325    private boolean isItBedTimeYetLocked() {
1326        return mBootCompleted && !isBeingKeptAwakeLocked();
1327    }
1328
1329    /**
1330     * Returns true if the device is being kept awake by a wake lock, user activity
1331     * or the stay on while powered setting.
1332     */
1333    private boolean isBeingKeptAwakeLocked() {
1334        return mStayOn
1335                || mProximityPositive
1336                || (mWakeLockSummary & (WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM)) != 0
1337                || (mUserActivitySummary & (USER_ACTIVITY_SCREEN_BRIGHT
1338                        | USER_ACTIVITY_SCREEN_DIM)) != 0;
1339    }
1340
1341    /**
1342     * Determines whether to post a message to the sandman to update the dream state.
1343     */
1344    private void updateDreamLocked(int dirty) {
1345        if ((dirty & (DIRTY_WAKEFULNESS
1346                | DIRTY_USER_ACTIVITY
1347                | DIRTY_WAKE_LOCKS
1348                | DIRTY_BOOT_COMPLETED
1349                | DIRTY_SETTINGS
1350                | DIRTY_IS_POWERED
1351                | DIRTY_STAY_ON
1352                | DIRTY_PROXIMITY_POSITIVE
1353                | DIRTY_BATTERY_STATE)) != 0) {
1354            scheduleSandmanLocked();
1355        }
1356    }
1357
1358    private void scheduleSandmanLocked() {
1359        if (!mSandmanScheduled) {
1360            mSandmanScheduled = true;
1361            Message msg = mHandler.obtainMessage(MSG_SANDMAN);
1362            msg.setAsynchronous(true);
1363            mHandler.sendMessage(msg);
1364        }
1365    }
1366
1367    /**
1368     * Called when the device enters or exits a napping or dreaming state.
1369     *
1370     * We do this asynchronously because we must call out of the power manager to start
1371     * the dream and we don't want to hold our lock while doing so.  There is a risk that
1372     * the device will wake or go to sleep in the meantime so we have to handle that case.
1373     */
1374    private void handleSandman() { // runs on handler thread
1375        // Handle preconditions.
1376        boolean startDreaming = false;
1377        synchronized (mLock) {
1378            mSandmanScheduled = false;
1379            boolean canDream = canDreamLocked();
1380            if (DEBUG_SPEW) {
1381                Log.d(TAG, "handleSandman: canDream=" + canDream
1382                        + ", mWakefulness=" + wakefulnessToString(mWakefulness));
1383            }
1384
1385            if (canDream && mWakefulness == WAKEFULNESS_NAPPING) {
1386                startDreaming = true;
1387            }
1388        }
1389
1390        // Start dreaming if needed.
1391        // We only control the dream on the handler thread, so we don't need to worry about
1392        // concurrent attempts to start or stop the dream.
1393        boolean isDreaming = false;
1394        if (mDreamManager != null) {
1395            if (startDreaming) {
1396                mDreamManager.startDream();
1397            }
1398            isDreaming = mDreamManager.isDreaming();
1399        }
1400
1401        // Update dream state.
1402        // We might need to stop the dream again if the preconditions changed.
1403        boolean continueDreaming = false;
1404        synchronized (mLock) {
1405            if (isDreaming && canDreamLocked()) {
1406                if (mWakefulness == WAKEFULNESS_NAPPING) {
1407                    mWakefulness = WAKEFULNESS_DREAMING;
1408                    mDirty |= DIRTY_WAKEFULNESS;
1409                    updatePowerStateLocked();
1410                    continueDreaming = true;
1411                } else if (mWakefulness == WAKEFULNESS_DREAMING) {
1412                    continueDreaming = true;
1413                }
1414            }
1415            if (!continueDreaming) {
1416                handleDreamFinishedLocked();
1417            }
1418        }
1419
1420        // Stop dreaming if needed.
1421        // It's possible that something else changed to make us need to start the dream again.
1422        // If so, then the power manager will have posted another message to the handler
1423        // to take care of it later.
1424        if (mDreamManager != null) {
1425            if (!continueDreaming) {
1426                mDreamManager.stopDream();
1427            }
1428        }
1429    }
1430
1431    /**
1432     * Returns true if the device is allowed to dream in its current state
1433     * assuming that it is currently napping or dreaming.
1434     */
1435    private boolean canDreamLocked() {
1436        return mDreamsSupportedConfig
1437                && mDreamsEnabledSetting
1438                && mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF
1439                && mBootCompleted
1440                && (mIsPowered || isBeingKeptAwakeLocked());
1441    }
1442
1443    /**
1444     * Called when a dream is ending to figure out what to do next.
1445     */
1446    private void handleDreamFinishedLocked() {
1447        if (mWakefulness == WAKEFULNESS_NAPPING
1448                || mWakefulness == WAKEFULNESS_DREAMING) {
1449            if (isItBedTimeYetLocked()) {
1450                goToSleepNoUpdateLocked(SystemClock.uptimeMillis(),
1451                        PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
1452                updatePowerStateLocked();
1453            } else {
1454                wakeUpNoUpdateLocked(SystemClock.uptimeMillis());
1455                updatePowerStateLocked();
1456            }
1457        }
1458    }
1459
1460    private void handleScreenOnBlockerReleased() {
1461        synchronized (mLock) {
1462            mDirty |= DIRTY_SCREEN_ON_BLOCKER_RELEASED;
1463            updatePowerStateLocked();
1464        }
1465    }
1466
1467    /**
1468     * Updates the display power state asynchronously.
1469     * When the update is finished, mDisplayReady will be set to true.  The display
1470     * controller posts a message to tell us when the actual display power state
1471     * has been updated so we come back here to double-check and finish up.
1472     *
1473     * This function recalculates the display power state each time.
1474     */
1475    private void updateDisplayPowerStateLocked(int dirty) {
1476        if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS
1477                | DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED
1478                | DIRTY_SETTINGS | DIRTY_SCREEN_ON_BLOCKER_RELEASED)) != 0) {
1479            int newScreenState = getDesiredScreenPowerStateLocked();
1480            if (newScreenState != mDisplayPowerRequest.screenState) {
1481                if (newScreenState == DisplayPowerRequest.SCREEN_STATE_OFF
1482                        && mDisplayPowerRequest.screenState
1483                                != DisplayPowerRequest.SCREEN_STATE_OFF) {
1484                    mLastScreenOffEventElapsedRealTime = SystemClock.elapsedRealtime();
1485                }
1486
1487                mDisplayPowerRequest.screenState = newScreenState;
1488                nativeSetPowerState(
1489                        newScreenState != DisplayPowerRequest.SCREEN_STATE_OFF,
1490                        newScreenState == DisplayPowerRequest.SCREEN_STATE_BRIGHT);
1491            }
1492
1493            int screenBrightness = mScreenBrightnessSettingDefault;
1494            float screenAutoBrightnessAdjustment = 0.0f;
1495            boolean autoBrightness = (mScreenBrightnessModeSetting ==
1496                    Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
1497            if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)) {
1498                screenBrightness = mScreenBrightnessOverrideFromWindowManager;
1499                autoBrightness = false;
1500            } else if (isValidBrightness(mTemporaryScreenBrightnessSettingOverride)) {
1501                screenBrightness = mTemporaryScreenBrightnessSettingOverride;
1502            } else if (isValidBrightness(mScreenBrightnessSetting)) {
1503                screenBrightness = mScreenBrightnessSetting;
1504            }
1505            if (autoBrightness) {
1506                screenBrightness = mScreenBrightnessSettingDefault;
1507                if (isValidAutoBrightnessAdjustment(
1508                        mTemporaryScreenAutoBrightnessAdjustmentSettingOverride)) {
1509                    screenAutoBrightnessAdjustment =
1510                            mTemporaryScreenAutoBrightnessAdjustmentSettingOverride;
1511                } else if (isValidAutoBrightnessAdjustment(
1512                        mScreenAutoBrightnessAdjustmentSetting)) {
1513                    screenAutoBrightnessAdjustment = mScreenAutoBrightnessAdjustmentSetting;
1514                }
1515            }
1516            screenBrightness = Math.max(Math.min(screenBrightness,
1517                    mScreenBrightnessSettingMaximum), mScreenBrightnessSettingMinimum);
1518            screenAutoBrightnessAdjustment = Math.max(Math.min(
1519                    screenAutoBrightnessAdjustment, 1.0f), -1.0f);
1520            mDisplayPowerRequest.screenBrightness = screenBrightness;
1521            mDisplayPowerRequest.screenAutoBrightnessAdjustment =
1522                    screenAutoBrightnessAdjustment;
1523            mDisplayPowerRequest.useAutoBrightness = autoBrightness;
1524
1525            mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
1526
1527            mDisplayPowerRequest.blockScreenOn = mScreenOnBlocker.isHeld();
1528
1529            mDisplayReady = mDisplayPowerController.requestPowerState(mDisplayPowerRequest,
1530                    mRequestWaitForNegativeProximity);
1531            mRequestWaitForNegativeProximity = false;
1532
1533            if (DEBUG_SPEW) {
1534                Slog.d(TAG, "updateScreenStateLocked: mDisplayReady=" + mDisplayReady
1535                        + ", newScreenState=" + newScreenState
1536                        + ", mWakefulness=" + mWakefulness
1537                        + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary)
1538                        + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
1539                        + ", mBootCompleted=" + mBootCompleted);
1540            }
1541        }
1542    }
1543
1544    private static boolean isValidBrightness(int value) {
1545        return value >= 0 && value <= 255;
1546    }
1547
1548    private static boolean isValidAutoBrightnessAdjustment(float value) {
1549        // Handles NaN by always returning false.
1550        return value >= -1.0f && value <= 1.0f;
1551    }
1552
1553    private int getDesiredScreenPowerStateLocked() {
1554        if (mWakefulness == WAKEFULNESS_ASLEEP) {
1555            return DisplayPowerRequest.SCREEN_STATE_OFF;
1556        }
1557
1558        if ((mWakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0
1559                || (mUserActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0
1560                || !mBootCompleted) {
1561            return DisplayPowerRequest.SCREEN_STATE_BRIGHT;
1562        }
1563
1564        return DisplayPowerRequest.SCREEN_STATE_DIM;
1565    }
1566
1567    private final DisplayPowerController.Callbacks mDisplayPowerControllerCallbacks =
1568            new DisplayPowerController.Callbacks() {
1569        @Override
1570        public void onStateChanged() {
1571            mDirty |= DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED;
1572            updatePowerStateLocked();
1573        }
1574
1575        @Override
1576        public void onProximityPositive() {
1577            mProximityPositive = true;
1578            mDirty |= DIRTY_PROXIMITY_POSITIVE;
1579            updatePowerStateLocked();
1580        }
1581
1582        @Override
1583        public void onProximityNegative() {
1584            mProximityPositive = false;
1585            mDirty |= DIRTY_PROXIMITY_POSITIVE;
1586            userActivityNoUpdateLocked(SystemClock.uptimeMillis(),
1587                    PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
1588            updatePowerStateLocked();
1589        }
1590    };
1591
1592    private boolean shouldUseProximitySensorLocked() {
1593        return (mWakeLockSummary & WAKE_LOCK_PROXIMITY_SCREEN_OFF) != 0;
1594    }
1595
1596    /**
1597     * Updates the suspend blocker that keeps the CPU alive.
1598     *
1599     * This function must have no other side-effects.
1600     */
1601    private void updateSuspendBlockerLocked() {
1602        boolean wantCpu = isCpuNeededLocked();
1603        if (wantCpu != mHoldingWakeLockSuspendBlocker) {
1604            mHoldingWakeLockSuspendBlocker = wantCpu;
1605            if (wantCpu) {
1606                if (DEBUG) {
1607                    Slog.d(TAG, "updateSuspendBlockerLocked: Acquiring suspend blocker.");
1608                }
1609                mWakeLockSuspendBlocker.acquire();
1610            } else {
1611                if (DEBUG) {
1612                    Slog.d(TAG, "updateSuspendBlockerLocked: Releasing suspend blocker.");
1613                }
1614                mWakeLockSuspendBlocker.release();
1615            }
1616        }
1617    }
1618
1619    private boolean isCpuNeededLocked() {
1620        return !mBootCompleted
1621                || mWakeLockSummary != 0
1622                || mUserActivitySummary != 0
1623                || mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF
1624                || !mDisplayReady;
1625    }
1626
1627    @Override // Binder call
1628    public boolean isScreenOn() {
1629        final long ident = Binder.clearCallingIdentity();
1630        try {
1631            return isScreenOnInternal();
1632        } finally {
1633            Binder.restoreCallingIdentity(ident);
1634        }
1635    }
1636
1637    private boolean isScreenOnInternal() {
1638        synchronized (mLock) {
1639            return !mSystemReady
1640                    || mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF;
1641        }
1642    }
1643
1644    private void handleBatteryStateChangedLocked() {
1645        mDirty |= DIRTY_BATTERY_STATE;
1646        updatePowerStateLocked();
1647    }
1648
1649    private void handleBootCompletedLocked() {
1650        final long now = SystemClock.uptimeMillis();
1651        mBootCompleted = true;
1652        mDirty |= DIRTY_BOOT_COMPLETED;
1653        userActivityNoUpdateLocked(
1654                now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
1655        updatePowerStateLocked();
1656    }
1657
1658    /**
1659     * Reboot the device, passing 'reason' (may be null)
1660     * to the underlying __reboot system call.  Should not return.
1661     */
1662    @Override // Binder call
1663    public void reboot(boolean confirm, String reason, boolean wait) {
1664        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
1665
1666        final long ident = Binder.clearCallingIdentity();
1667        try {
1668            rebootInternal(false, confirm, reason, wait);
1669        } finally {
1670            Binder.restoreCallingIdentity(ident);
1671        }
1672    }
1673
1674    /**
1675     * Shutdown the devic, passing 'reason' (may be null)
1676     * to the underlying __reboot system call.  Should not return.
1677     */
1678    @Override // Binder call
1679    public void shutdown(boolean confirm, boolean wait) {
1680        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
1681
1682        final long ident = Binder.clearCallingIdentity();
1683        try {
1684            rebootInternal(true, confirm, null, wait);
1685        } finally {
1686            Binder.restoreCallingIdentity(ident);
1687        }
1688    }
1689
1690    private void rebootInternal(final boolean shutdown, final boolean confirm,
1691            final String reason, boolean wait) {
1692        if (mHandler == null || !mSystemReady) {
1693            throw new IllegalStateException("Too early to call reboot()");
1694        }
1695
1696        Runnable runnable = new Runnable() {
1697            public void run() {
1698                synchronized (this) {
1699                    if (shutdown) {
1700                        ShutdownThread.shutdown(mContext, confirm);
1701                    } else {
1702                        ShutdownThread.reboot(mContext, reason, confirm);
1703                    }
1704                }
1705            }
1706        };
1707
1708        // ShutdownThread must run on a looper capable of displaying the UI.
1709        Message msg = Message.obtain(mHandler, runnable);
1710        msg.setAsynchronous(true);
1711        mHandler.sendMessage(msg);
1712
1713        // PowerManager.reboot() is documented not to return so just wait for the inevitable.
1714        if (wait) {
1715            synchronized (runnable) {
1716                while (true) {
1717                    try {
1718                        runnable.wait();
1719                    } catch (InterruptedException e) {
1720                    }
1721                }
1722            }
1723        }
1724    }
1725
1726    /**
1727     * Crash the runtime (causing a complete restart of the Android framework).
1728     * Requires REBOOT permission.  Mostly for testing.  Should not return.
1729     */
1730    @Override // Binder call
1731    public void crash(String message) {
1732        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
1733
1734        final long ident = Binder.clearCallingIdentity();
1735        try {
1736            crashInternal(message);
1737        } finally {
1738            Binder.restoreCallingIdentity(ident);
1739        }
1740    }
1741
1742    private void crashInternal(final String message) {
1743        Thread t = new Thread("PowerManagerService.crash()") {
1744            public void run() {
1745                throw new RuntimeException(message);
1746            }
1747        };
1748        try {
1749            t.start();
1750            t.join();
1751        } catch (InterruptedException e) {
1752            Log.wtf(TAG, e);
1753        }
1754    }
1755
1756    /**
1757     * Set the setting that determines whether the device stays on when plugged in.
1758     * The argument is a bit string, with each bit specifying a power source that,
1759     * when the device is connected to that source, causes the device to stay on.
1760     * See {@link android.os.BatteryManager} for the list of power sources that
1761     * can be specified. Current values include {@link android.os.BatteryManager#BATTERY_PLUGGED_AC}
1762     * and {@link android.os.BatteryManager#BATTERY_PLUGGED_USB}
1763     *
1764     * Used by "adb shell svc power stayon ..."
1765     *
1766     * @param val an {@code int} containing the bits that specify which power sources
1767     * should cause the device to stay on.
1768     */
1769    @Override // Binder call
1770    public void setStayOnSetting(int val) {
1771        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS, null);
1772
1773        final long ident = Binder.clearCallingIdentity();
1774        try {
1775            setStayOnSettingInternal(val);
1776        } finally {
1777            Binder.restoreCallingIdentity(ident);
1778        }
1779    }
1780
1781    private void setStayOnSettingInternal(int val) {
1782        Settings.Global.putInt(mContext.getContentResolver(),
1783                Settings.Global.STAY_ON_WHILE_PLUGGED_IN, val);
1784    }
1785
1786    /**
1787     * Used by device administration to set the maximum screen off timeout.
1788     *
1789     * This method must only be called by the device administration policy manager.
1790     */
1791    @Override // Binder call
1792    public void setMaximumScreenOffTimeoutFromDeviceAdmin(int timeMs) {
1793        final long ident = Binder.clearCallingIdentity();
1794        try {
1795            setMaximumScreenOffTimeoutFromDeviceAdminInternal(timeMs);
1796        } finally {
1797            Binder.restoreCallingIdentity(ident);
1798        }
1799    }
1800
1801    private void setMaximumScreenOffTimeoutFromDeviceAdminInternal(int timeMs) {
1802        synchronized (mLock) {
1803            mMaximumScreenOffTimeoutFromDeviceAdmin = timeMs;
1804            mDirty |= DIRTY_SETTINGS;
1805            updatePowerStateLocked();
1806        }
1807    }
1808
1809    private boolean isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked() {
1810        return mMaximumScreenOffTimeoutFromDeviceAdmin >= 0
1811                && mMaximumScreenOffTimeoutFromDeviceAdmin < Integer.MAX_VALUE;
1812    }
1813
1814    /**
1815     * Used by the phone application to make the attention LED flash when ringing.
1816     */
1817    @Override // Binder call
1818    public void setAttentionLight(boolean on, int color) {
1819        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1820
1821        final long ident = Binder.clearCallingIdentity();
1822        try {
1823            setAttentionLightInternal(on, color);
1824        } finally {
1825            Binder.restoreCallingIdentity(ident);
1826        }
1827    }
1828
1829    private void setAttentionLightInternal(boolean on, int color) {
1830        LightsService.Light light;
1831        synchronized (mLock) {
1832            if (!mSystemReady) {
1833                return;
1834            }
1835            light = mAttentionLight;
1836        }
1837
1838        // Control light outside of lock.
1839        light.setFlashing(color, LightsService.LIGHT_FLASH_HARDWARE, (on ? 3 : 0), 0);
1840    }
1841
1842    /**
1843     * Used by the Watchdog.
1844     */
1845    public long timeSinceScreenWasLastOn() {
1846        synchronized (mLock) {
1847            if (mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF) {
1848                return 0;
1849            }
1850            return SystemClock.elapsedRealtime() - mLastScreenOffEventElapsedRealTime;
1851        }
1852    }
1853
1854    /**
1855     * Used by the window manager to override the screen brightness based on the
1856     * current foreground activity.
1857     *
1858     * This method must only be called by the window manager.
1859     *
1860     * @param brightness The overridden brightness, or -1 to disable the override.
1861     */
1862    public void setScreenBrightnessOverrideFromWindowManager(int brightness) {
1863        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1864
1865        final long ident = Binder.clearCallingIdentity();
1866        try {
1867            setScreenBrightnessOverrideFromWindowManagerInternal(brightness);
1868        } finally {
1869            Binder.restoreCallingIdentity(ident);
1870        }
1871    }
1872
1873    private void setScreenBrightnessOverrideFromWindowManagerInternal(int brightness) {
1874        synchronized (mLock) {
1875            if (mScreenBrightnessOverrideFromWindowManager != brightness) {
1876                mScreenBrightnessOverrideFromWindowManager = brightness;
1877                mDirty |= DIRTY_SETTINGS;
1878                updatePowerStateLocked();
1879            }
1880        }
1881    }
1882
1883    /**
1884     * Used by the window manager to override the button brightness based on the
1885     * current foreground activity.
1886     *
1887     * This method must only be called by the window manager.
1888     *
1889     * @param brightness The overridden brightness, or -1 to disable the override.
1890     */
1891    public void setButtonBrightnessOverrideFromWindowManager(int brightness) {
1892        // Do nothing.
1893        // Button lights are not currently supported in the new implementation.
1894        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1895    }
1896
1897    /**
1898     * Used by the window manager to override the user activity timeout based on the
1899     * current foreground activity.  It can only be used to make the timeout shorter
1900     * than usual, not longer.
1901     *
1902     * This method must only be called by the window manager.
1903     *
1904     * @param timeoutMillis The overridden timeout, or -1 to disable the override.
1905     */
1906    public void setUserActivityTimeoutOverrideFromWindowManager(long timeoutMillis) {
1907        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1908
1909        final long ident = Binder.clearCallingIdentity();
1910        try {
1911            setUserActivityTimeoutOverrideFromWindowManagerInternal(timeoutMillis);
1912        } finally {
1913            Binder.restoreCallingIdentity(ident);
1914        }
1915    }
1916
1917    private void setUserActivityTimeoutOverrideFromWindowManagerInternal(long timeoutMillis) {
1918        synchronized (mLock) {
1919            if (mUserActivityTimeoutOverrideFromWindowManager != timeoutMillis) {
1920                mUserActivityTimeoutOverrideFromWindowManager = timeoutMillis;
1921                mDirty |= DIRTY_SETTINGS;
1922                updatePowerStateLocked();
1923            }
1924        }
1925    }
1926
1927    /**
1928     * Used by the settings application and brightness control widgets to
1929     * temporarily override the current screen brightness setting so that the
1930     * user can observe the effect of an intended settings change without applying
1931     * it immediately.
1932     *
1933     * The override will be canceled when the setting value is next updated.
1934     *
1935     * @param brightness The overridden brightness.
1936     *
1937     * @see Settings.System#SCREEN_BRIGHTNESS
1938     */
1939    @Override // Binder call
1940    public void setTemporaryScreenBrightnessSettingOverride(int brightness) {
1941        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1942
1943        final long ident = Binder.clearCallingIdentity();
1944        try {
1945            setTemporaryScreenBrightnessSettingOverrideInternal(brightness);
1946        } finally {
1947            Binder.restoreCallingIdentity(ident);
1948        }
1949    }
1950
1951    private void setTemporaryScreenBrightnessSettingOverrideInternal(int brightness) {
1952        synchronized (mLock) {
1953            if (mTemporaryScreenBrightnessSettingOverride != brightness) {
1954                mTemporaryScreenBrightnessSettingOverride = brightness;
1955                mDirty |= DIRTY_SETTINGS;
1956                updatePowerStateLocked();
1957            }
1958        }
1959    }
1960
1961    /**
1962     * Used by the settings application and brightness control widgets to
1963     * temporarily override the current screen auto-brightness adjustment setting so that the
1964     * user can observe the effect of an intended settings change without applying
1965     * it immediately.
1966     *
1967     * The override will be canceled when the setting value is next updated.
1968     *
1969     * @param adj The overridden brightness, or Float.NaN to disable the override.
1970     *
1971     * @see Settings.System#SCREEN_AUTO_BRIGHTNESS_ADJ
1972     */
1973    @Override // Binder call
1974    public void setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(float adj) {
1975        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1976
1977        final long ident = Binder.clearCallingIdentity();
1978        try {
1979            setTemporaryScreenAutoBrightnessAdjustmentSettingOverrideInternal(adj);
1980        } finally {
1981            Binder.restoreCallingIdentity(ident);
1982        }
1983    }
1984
1985    private void setTemporaryScreenAutoBrightnessAdjustmentSettingOverrideInternal(float adj) {
1986        synchronized (mLock) {
1987            // Note: This condition handles NaN because NaN is not equal to any other
1988            // value, including itself.
1989            if (mTemporaryScreenAutoBrightnessAdjustmentSettingOverride != adj) {
1990                mTemporaryScreenAutoBrightnessAdjustmentSettingOverride = adj;
1991                mDirty |= DIRTY_SETTINGS;
1992                updatePowerStateLocked();
1993            }
1994        }
1995    }
1996
1997    /**
1998     * Low-level function turn the device off immediately, without trying
1999     * to be clean.  Most people should use {@link ShutdownThread} for a clean shutdown.
2000     */
2001    public static void lowLevelShutdown() {
2002        nativeShutdown();
2003    }
2004
2005    /**
2006     * Low-level function to reboot the device.
2007     *
2008     * @param reason code to pass to the kernel (e.g. "recovery"), or null.
2009     * @throws IOException if reboot fails for some reason (eg, lack of
2010     *         permission)
2011     */
2012    public static void lowLevelReboot(String reason) throws IOException {
2013        nativeReboot(reason);
2014    }
2015
2016    @Override // Watchdog.Monitor implementation
2017    public void monitor() {
2018        // Grab and release lock for watchdog monitor to detect deadlocks.
2019        synchronized (mLock) {
2020        }
2021    }
2022
2023    @Override // Binder call
2024    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2025        if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
2026                != PackageManager.PERMISSION_GRANTED) {
2027            pw.println("Permission Denial: can't dump PowerManager from from pid="
2028                    + Binder.getCallingPid()
2029                    + ", uid=" + Binder.getCallingUid());
2030            return;
2031        }
2032
2033        pw.println("POWER MANAGER (dumpsys power)\n");
2034
2035        final DisplayPowerController dpc;
2036        synchronized (mLock) {
2037            pw.println("Power Manager State:");
2038            pw.println("  mDirty=0x" + Integer.toHexString(mDirty));
2039            pw.println("  mWakefulness=" + wakefulnessToString(mWakefulness));
2040            pw.println("  mIsPowered=" + mIsPowered);
2041            pw.println("  mPlugType=" + mPlugType);
2042            pw.println("  mStayOn=" + mStayOn);
2043            pw.println("  mProximityPositive=" + mProximityPositive);
2044            pw.println("  mBootCompleted=" + mBootCompleted);
2045            pw.println("  mSystemReady=" + mSystemReady);
2046            pw.println("  mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary));
2047            pw.println("  mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary));
2048            pw.println("  mRequestWaitForNegativeProximity=" + mRequestWaitForNegativeProximity);
2049            pw.println("  mSandmanScheduled=" + mSandmanScheduled);
2050            pw.println("  mLastWakeTime=" + TimeUtils.formatUptime(mLastWakeTime));
2051            pw.println("  mLastSleepTime=" + TimeUtils.formatUptime(mLastSleepTime));
2052            pw.println("  mSendWakeUpFinishedNotificationWhenReady="
2053                    + mSendWakeUpFinishedNotificationWhenReady);
2054            pw.println("  mSendGoToSleepFinishedNotificationWhenReady="
2055                    + mSendGoToSleepFinishedNotificationWhenReady);
2056            pw.println("  mLastUserActivityTime=" + TimeUtils.formatUptime(mLastUserActivityTime));
2057            pw.println("  mLastUserActivityTimeNoChangeLights="
2058                    + TimeUtils.formatUptime(mLastUserActivityTimeNoChangeLights));
2059            pw.println("  mDisplayReady=" + mDisplayReady);
2060            pw.println("  mHoldingWakeLockSuspendBlocker=" + mHoldingWakeLockSuspendBlocker);
2061
2062            pw.println();
2063            pw.println("Settings and Configuration:");
2064            pw.println("  mDreamsSupportedConfig=" + mDreamsSupportedConfig);
2065            pw.println("  mDreamsEnabledSetting=" + mDreamsEnabledSetting);
2066            pw.println("  mDreamsActivateOnSleepSetting=" + mDreamsActivateOnSleepSetting);
2067            pw.println("  mScreenOffTimeoutSetting=" + mScreenOffTimeoutSetting);
2068            pw.println("  mMaximumScreenOffTimeoutFromDeviceAdmin="
2069                    + mMaximumScreenOffTimeoutFromDeviceAdmin + " (enforced="
2070                    + isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked() + ")");
2071            pw.println("  mStayOnWhilePluggedInSetting=" + mStayOnWhilePluggedInSetting);
2072            pw.println("  mScreenBrightnessSetting=" + mScreenBrightnessSetting);
2073            pw.println("  mScreenAutoBrightnessAdjustmentSetting="
2074                    + mScreenAutoBrightnessAdjustmentSetting);
2075            pw.println("  mScreenBrightnessModeSetting=" + mScreenBrightnessModeSetting);
2076            pw.println("  mScreenBrightnessOverrideFromWindowManager="
2077                    + mScreenBrightnessOverrideFromWindowManager);
2078            pw.println("  mUserActivityTimeoutOverrideFromWindowManager="
2079                    + mUserActivityTimeoutOverrideFromWindowManager);
2080            pw.println("  mTemporaryScreenBrightnessSettingOverride="
2081                    + mTemporaryScreenBrightnessSettingOverride);
2082            pw.println("  mTemporaryScreenAutoBrightnessAdjustmentSettingOverride="
2083                    + mTemporaryScreenAutoBrightnessAdjustmentSettingOverride);
2084            pw.println("  mScreenBrightnessSettingMinimum=" + mScreenBrightnessSettingMinimum);
2085            pw.println("  mScreenBrightnessSettingMaximum=" + mScreenBrightnessSettingMaximum);
2086            pw.println("  mScreenBrightnessSettingDefault=" + mScreenBrightnessSettingDefault);
2087
2088            final int screenOffTimeout = getScreenOffTimeoutLocked();
2089            final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
2090            pw.println();
2091            pw.println("Screen off timeout: " + screenOffTimeout + " ms");
2092            pw.println("Screen dim duration: " + screenDimDuration + " ms");
2093
2094            pw.println();
2095            pw.println("Wake Locks: size=" + mWakeLocks.size());
2096            for (WakeLock wl : mWakeLocks) {
2097                pw.println("  " + wl);
2098            }
2099
2100            pw.println();
2101            pw.println("Suspend Blockers: size=" + mSuspendBlockers.size());
2102            for (SuspendBlocker sb : mSuspendBlockers) {
2103                pw.println("  " + sb);
2104            }
2105
2106            pw.println();
2107            pw.println("Screen On Blocker: " + mScreenOnBlocker);
2108
2109            dpc = mDisplayPowerController;
2110        }
2111
2112        if (dpc != null) {
2113            dpc.dump(pw);
2114        }
2115    }
2116
2117    private SuspendBlocker createSuspendBlockerLocked(String name) {
2118        SuspendBlocker suspendBlocker = new SuspendBlockerImpl(name);
2119        mSuspendBlockers.add(suspendBlocker);
2120        return suspendBlocker;
2121    }
2122
2123    private static String wakefulnessToString(int wakefulness) {
2124        switch (wakefulness) {
2125            case WAKEFULNESS_ASLEEP:
2126                return "Asleep";
2127            case WAKEFULNESS_AWAKE:
2128                return "Awake";
2129            case WAKEFULNESS_DREAMING:
2130                return "Dreaming";
2131            case WAKEFULNESS_NAPPING:
2132                return "Napping";
2133            default:
2134                return Integer.toString(wakefulness);
2135        }
2136    }
2137
2138    private static WorkSource copyWorkSource(WorkSource workSource) {
2139        return workSource != null ? new WorkSource(workSource) : null;
2140    }
2141
2142    private final class BatteryReceiver extends BroadcastReceiver {
2143        @Override
2144        public void onReceive(Context context, Intent intent) {
2145            synchronized (mLock) {
2146                handleBatteryStateChangedLocked();
2147            }
2148        }
2149    }
2150
2151    private final class BootCompletedReceiver extends BroadcastReceiver {
2152        @Override
2153        public void onReceive(Context context, Intent intent) {
2154            synchronized (mLock) {
2155                handleBootCompletedLocked();
2156            }
2157        }
2158    }
2159
2160    private final class DreamReceiver extends BroadcastReceiver {
2161        @Override
2162        public void onReceive(Context context, Intent intent) {
2163            synchronized (mLock) {
2164                scheduleSandmanLocked();
2165            }
2166        }
2167    }
2168
2169    private final class UserSwitchedReceiver extends BroadcastReceiver {
2170        @Override
2171        public void onReceive(Context context, Intent intent) {
2172            synchronized (mLock) {
2173                handleSettingsChangedLocked();
2174            }
2175        }
2176    }
2177
2178    private final class SettingsObserver extends ContentObserver {
2179        public SettingsObserver(Handler handler) {
2180            super(handler);
2181        }
2182
2183        @Override
2184        public void onChange(boolean selfChange, Uri uri) {
2185            synchronized (mLock) {
2186                handleSettingsChangedLocked();
2187            }
2188        }
2189    }
2190
2191    /**
2192     * Handler for asynchronous operations performed by the power manager.
2193     */
2194    private final class PowerManagerHandler extends Handler {
2195        public PowerManagerHandler(Looper looper) {
2196            super(looper, null, true /*async*/);
2197        }
2198
2199        @Override
2200        public void handleMessage(Message msg) {
2201            switch (msg.what) {
2202                case MSG_USER_ACTIVITY_TIMEOUT:
2203                    handleUserActivityTimeout();
2204                    break;
2205                case MSG_SANDMAN:
2206                    handleSandman();
2207                    break;
2208                case MSG_SCREEN_ON_BLOCKER_RELEASED:
2209                    handleScreenOnBlockerReleased();
2210                    break;
2211            }
2212        }
2213    }
2214
2215    /**
2216     * Represents a wake lock that has been acquired by an application.
2217     */
2218    private final class WakeLock implements IBinder.DeathRecipient {
2219        public final IBinder mLock;
2220        public int mFlags;
2221        public String mTag;
2222        public WorkSource mWorkSource;
2223        public int mOwnerUid;
2224        public int mOwnerPid;
2225
2226        public WakeLock(IBinder lock, int flags, String tag, WorkSource workSource,
2227                int ownerUid, int ownerPid) {
2228            mLock = lock;
2229            mFlags = flags;
2230            mTag = tag;
2231            mWorkSource = copyWorkSource(workSource);
2232            mOwnerUid = ownerUid;
2233            mOwnerPid = ownerPid;
2234        }
2235
2236        @Override
2237        public void binderDied() {
2238            PowerManagerService.this.handleWakeLockDeath(this);
2239        }
2240
2241        public boolean hasSameProperties(int flags, String tag, WorkSource workSource,
2242                int ownerUid, int ownerPid) {
2243            return mFlags == flags
2244                    && mTag.equals(tag)
2245                    && hasSameWorkSource(workSource)
2246                    && mOwnerUid == ownerUid
2247                    && mOwnerPid == ownerPid;
2248        }
2249
2250        public void updateProperties(int flags, String tag, WorkSource workSource,
2251                int ownerUid, int ownerPid) {
2252            mFlags = flags;
2253            mTag = tag;
2254            updateWorkSource(workSource);
2255            mOwnerUid = ownerUid;
2256            mOwnerPid = ownerPid;
2257        }
2258
2259        public boolean hasSameWorkSource(WorkSource workSource) {
2260            return Objects.equal(mWorkSource, workSource);
2261        }
2262
2263        public void updateWorkSource(WorkSource workSource) {
2264            mWorkSource = copyWorkSource(workSource);
2265        }
2266
2267        @Override
2268        public String toString() {
2269            return getLockLevelString()
2270                    + " '" + mTag + "'" + getLockFlagsString()
2271                    + " (uid=" + mOwnerUid + ", pid=" + mOwnerPid + ", ws=" + mWorkSource + ")";
2272        }
2273
2274        private String getLockLevelString() {
2275            switch (mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
2276                case PowerManager.FULL_WAKE_LOCK:
2277                    return "FULL_WAKE_LOCK                ";
2278                case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
2279                    return "SCREEN_BRIGHT_WAKE_LOCK       ";
2280                case PowerManager.SCREEN_DIM_WAKE_LOCK:
2281                    return "SCREEN_DIM_WAKE_LOCK          ";
2282                case PowerManager.PARTIAL_WAKE_LOCK:
2283                    return "PARTIAL_WAKE_LOCK             ";
2284                case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
2285                    return "PROXIMITY_SCREEN_OFF_WAKE_LOCK";
2286                default:
2287                    return "???                           ";
2288            }
2289        }
2290
2291        private String getLockFlagsString() {
2292            String result = "";
2293            if ((mFlags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {
2294                result += " ACQUIRE_CAUSES_WAKEUP";
2295            }
2296            if ((mFlags & PowerManager.ON_AFTER_RELEASE) != 0) {
2297                result += " ON_AFTER_RELEASE";
2298            }
2299            return result;
2300        }
2301    }
2302
2303    private final class SuspendBlockerImpl implements SuspendBlocker {
2304        private final String mName;
2305        private int mReferenceCount;
2306
2307        public SuspendBlockerImpl(String name) {
2308            mName = name;
2309        }
2310
2311        @Override
2312        protected void finalize() throws Throwable {
2313            try {
2314                if (mReferenceCount != 0) {
2315                    Log.wtf(TAG, "Suspend blocker \"" + mName
2316                            + "\" was finalized without being released!");
2317                    mReferenceCount = 0;
2318                    nativeReleaseSuspendBlocker(mName);
2319                }
2320            } finally {
2321                super.finalize();
2322            }
2323        }
2324
2325        @Override
2326        public void acquire() {
2327            synchronized (this) {
2328                mReferenceCount += 1;
2329                if (mReferenceCount == 1) {
2330                    nativeAcquireSuspendBlocker(mName);
2331                }
2332            }
2333        }
2334
2335        @Override
2336        public void release() {
2337            synchronized (this) {
2338                mReferenceCount -= 1;
2339                if (mReferenceCount == 0) {
2340                    nativeReleaseSuspendBlocker(mName);
2341                } else if (mReferenceCount < 0) {
2342                    Log.wtf(TAG, "Suspend blocker \"" + mName
2343                            + "\" was released without being acquired!", new Throwable());
2344                    mReferenceCount = 0;
2345                }
2346            }
2347        }
2348
2349        @Override
2350        public String toString() {
2351            synchronized (this) {
2352                return mName + ": ref count=" + mReferenceCount;
2353            }
2354        }
2355    }
2356
2357    private final class ScreenOnBlockerImpl implements ScreenOnBlocker {
2358        private int mNestCount;
2359
2360        public boolean isHeld() {
2361            synchronized (this) {
2362                return mNestCount != 0;
2363            }
2364        }
2365
2366        @Override
2367        public void acquire() {
2368            synchronized (this) {
2369                mNestCount += 1;
2370                if (DEBUG) {
2371                    Slog.d(TAG, "Screen on blocked: mNestCount=" + mNestCount);
2372                }
2373            }
2374        }
2375
2376        @Override
2377        public void release() {
2378            synchronized (this) {
2379                mNestCount -= 1;
2380                if (mNestCount < 0) {
2381                    Log.wtf(TAG, "Screen on blocker was released without being acquired!",
2382                            new Throwable());
2383                    mNestCount = 0;
2384                }
2385                if (mNestCount == 0) {
2386                    mHandler.sendEmptyMessage(MSG_SCREEN_ON_BLOCKER_RELEASED);
2387                }
2388                if (DEBUG) {
2389                    Slog.d(TAG, "Screen on unblocked: mNestCount=" + mNestCount);
2390                }
2391            }
2392        }
2393
2394        @Override
2395        public String toString() {
2396            synchronized (this) {
2397                return "held=" + (mNestCount != 0) + ", mNestCount=" + mNestCount;
2398            }
2399        }
2400    };
2401}
2402