PowerManagerService.java revision 2139276ce8b54aba5faa858ca69ed5f01445c269
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.IAppOpsService;
20import com.android.internal.app.IBatteryStats;
21import com.android.internal.os.BackgroundThread;
22import com.android.server.EventLogTags;
23import com.android.server.LocalServices;
24import com.android.server.ServiceThread;
25import com.android.server.am.BatteryStatsService;
26import com.android.server.lights.Light;
27import com.android.server.lights.LightsManager;
28import com.android.server.Watchdog;
29
30import android.Manifest;
31import android.content.BroadcastReceiver;
32import android.content.ContentResolver;
33import android.content.Context;
34import android.content.Intent;
35import android.content.IntentFilter;
36import android.content.pm.PackageManager;
37import android.content.res.Resources;
38import android.database.ContentObserver;
39import android.hardware.SensorManager;
40import android.hardware.SystemSensorManager;
41import android.hardware.display.DisplayManagerInternal;
42import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
43import android.net.Uri;
44import android.os.BatteryManager;
45import android.os.BatteryManagerInternal;
46import android.os.Binder;
47import android.os.Handler;
48import android.os.IBinder;
49import android.os.IPowerManager;
50import android.os.Looper;
51import android.os.Message;
52import android.os.PowerManager;
53import android.os.PowerManagerInternal;
54import android.os.Process;
55import android.os.RemoteException;
56import android.os.SystemClock;
57import android.os.SystemProperties;
58import android.os.SystemService;
59import android.os.UserHandle;
60import android.os.WorkSource;
61import android.provider.Settings;
62import android.service.dreams.DreamManagerInternal;
63import android.util.EventLog;
64import android.util.Log;
65import android.util.Slog;
66import android.util.TimeUtils;
67import android.view.Display;
68import android.view.WindowManagerPolicy;
69
70import java.io.FileDescriptor;
71import java.io.PrintWriter;
72import java.util.ArrayList;
73
74import libcore.util.Objects;
75
76/**
77 * The power manager service is responsible for coordinating power management
78 * functions on the device.
79 */
80public final class PowerManagerService extends com.android.server.SystemService
81        implements Watchdog.Monitor {
82    private static final String TAG = "PowerManagerService";
83
84    private static final boolean DEBUG = false;
85    private static final boolean DEBUG_SPEW = DEBUG && true;
86
87    // Message: Sent when a user activity timeout occurs to update the power state.
88    private static final int MSG_USER_ACTIVITY_TIMEOUT = 1;
89    // Message: Sent when the device enters or exits a dreaming or dozing state.
90    private static final int MSG_SANDMAN = 2;
91    // Message: Sent when the screen on blocker is released.
92    private static final int MSG_SCREEN_ON_BLOCKER_RELEASED = 3;
93    // Message: Sent to poll whether the boot animation has terminated.
94    private static final int MSG_CHECK_IF_BOOT_ANIMATION_FINISHED = 4;
95
96    // Dirty bit: mWakeLocks changed
97    private static final int DIRTY_WAKE_LOCKS = 1 << 0;
98    // Dirty bit: mWakefulness changed
99    private static final int DIRTY_WAKEFULNESS = 1 << 1;
100    // Dirty bit: user activity was poked or may have timed out
101    private static final int DIRTY_USER_ACTIVITY = 1 << 2;
102    // Dirty bit: actual display power state was updated asynchronously
103    private static final int DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED = 1 << 3;
104    // Dirty bit: mBootCompleted changed
105    private static final int DIRTY_BOOT_COMPLETED = 1 << 4;
106    // Dirty bit: settings changed
107    private static final int DIRTY_SETTINGS = 1 << 5;
108    // Dirty bit: mIsPowered changed
109    private static final int DIRTY_IS_POWERED = 1 << 6;
110    // Dirty bit: mStayOn changed
111    private static final int DIRTY_STAY_ON = 1 << 7;
112    // Dirty bit: battery state changed
113    private static final int DIRTY_BATTERY_STATE = 1 << 8;
114    // Dirty bit: proximity state changed
115    private static final int DIRTY_PROXIMITY_POSITIVE = 1 << 9;
116    // Dirty bit: screen on blocker state became held or unheld
117    private static final int DIRTY_SCREEN_ON_BLOCKER_RELEASED = 1 << 10;
118    // Dirty bit: dock state changed
119    private static final int DIRTY_DOCK_STATE = 1 << 11;
120
121    // Wakefulness: The device is asleep and can only be awoken by a call to wakeUp().
122    // The screen should be off or in the process of being turned off by the display controller.
123    // The device typically passes through the dozing state first.
124    private static final int WAKEFULNESS_ASLEEP = 0;
125    // Wakefulness: The device is fully awake.  It can be put to sleep by a call to goToSleep().
126    // When the user activity timeout expires, the device may start dreaming or go to sleep.
127    private static final int WAKEFULNESS_AWAKE = 1;
128    // Wakefulness: The device is dreaming.  It can be awoken by a call to wakeUp(),
129    // which ends the dream.  The device goes to sleep when goToSleep() is called, when
130    // the dream ends or when unplugged.
131    // User activity may brighten the screen but does not end the dream.
132    private static final int WAKEFULNESS_DREAMING = 2;
133    // Wakefulness: The device is dozing.  It is almost asleep but is allowing a special
134    // low-power "doze" dream to run which keeps the display on but lets the application
135    // processor be suspended.  It can be awoken by a call to wakeUp() which ends the dream.
136    // The device fully goes to sleep if the dream cannot be started or ends on its own.
137    private static final int WAKEFULNESS_DOZING = 3;
138
139    // Summarizes the state of all active wakelocks.
140    private static final int WAKE_LOCK_CPU = 1 << 0;
141    private static final int WAKE_LOCK_SCREEN_BRIGHT = 1 << 1;
142    private static final int WAKE_LOCK_SCREEN_DIM = 1 << 2;
143    private static final int WAKE_LOCK_BUTTON_BRIGHT = 1 << 3;
144    private static final int WAKE_LOCK_PROXIMITY_SCREEN_OFF = 1 << 4;
145    private static final int WAKE_LOCK_STAY_AWAKE = 1 << 5; // only set if already awake
146    private static final int WAKE_LOCK_DOZE = 1 << 6;
147
148    // Summarizes the user activity state.
149    private static final int USER_ACTIVITY_SCREEN_BRIGHT = 1 << 0;
150    private static final int USER_ACTIVITY_SCREEN_DIM = 1 << 1;
151
152    // Default timeout in milliseconds.  This is only used until the settings
153    // provider populates the actual default value (R.integer.def_screen_off_timeout).
154    private static final int DEFAULT_SCREEN_OFF_TIMEOUT = 15 * 1000;
155
156    // The name of the boot animation service in init.rc.
157    private static final String BOOT_ANIMATION_SERVICE = "bootanim";
158
159    // Poll interval in milliseconds for watching boot animation finished.
160    private static final int BOOT_ANIMATION_POLL_INTERVAL = 200;
161
162    // Used to send the hint to the PowerHAL indicating transitions
163    // from and to the low power mode.
164    private static final int POWER_HINT_LOW_POWER_MODE = 5;
165
166    private final Context mContext;
167    private final ServiceThread mHandlerThread;
168    private final PowerManagerHandler mHandler;
169
170    private LightsManager mLightsManager;
171    private BatteryManagerInternal mBatteryManagerInternal;
172    private DisplayManagerInternal mDisplayManagerInternal;
173    private IBatteryStats mBatteryStats;
174    private IAppOpsService mAppOps;
175    private WindowManagerPolicy mPolicy;
176    private Notifier mNotifier;
177    private WirelessChargerDetector mWirelessChargerDetector;
178    private SettingsObserver mSettingsObserver;
179    private DreamManagerInternal mDreamManager;
180    private Light mAttentionLight;
181
182    private final Object mLock = new Object();
183
184    // A bitfield that indicates what parts of the power state have
185    // changed and need to be recalculated.
186    private int mDirty;
187
188    // Indicates whether the device is awake or asleep or somewhere in between.
189    // This is distinct from the screen power state, which is managed separately.
190    private int mWakefulness;
191
192    // True if the sandman has just been summoned for the first time since entering the
193    // dreaming or dozing state.  Indicates whether a new dream should begin.
194    private boolean mSandmanSummoned;
195
196    // True if MSG_SANDMAN has been scheduled.
197    private boolean mSandmanScheduled;
198
199    // Table of all suspend blockers.
200    // There should only be a few of these.
201    private final ArrayList<SuspendBlocker> mSuspendBlockers = new ArrayList<SuspendBlocker>();
202
203    // Table of all wake locks acquired by applications.
204    private final ArrayList<WakeLock> mWakeLocks = new ArrayList<WakeLock>();
205
206    // A bitfield that summarizes the state of all active wakelocks.
207    private int mWakeLockSummary;
208
209    // True if the device is in an interactive state.
210    private boolean mInteractive;
211    private boolean mInteractiveChanging;
212
213    // If true, instructs the display controller to wait for the proximity sensor to
214    // go negative before turning the screen on.
215    private boolean mRequestWaitForNegativeProximity;
216
217    // Timestamp of the last time the device was awoken or put to sleep.
218    private long mLastWakeTime;
219    private long mLastSleepTime;
220
221    // Timestamp of the last call to user activity.
222    private long mLastUserActivityTime;
223    private long mLastUserActivityTimeNoChangeLights;
224
225    // A bitfield that summarizes the effect of the user activity timer.
226    // A zero value indicates that the user activity timer has expired.
227    private int mUserActivitySummary;
228
229    // The desired display power state.  The actual state may lag behind the
230    // requested because it is updated asynchronously by the display power controller.
231    private final DisplayPowerRequest mDisplayPowerRequest = new DisplayPowerRequest();
232
233    // True if the display power state has been fully applied, which means the display
234    // is actually on or actually off or whatever was requested.
235    private boolean mDisplayReady;
236
237    // The suspend blocker used to keep the CPU alive when an application has acquired
238    // a wake lock.
239    private final SuspendBlocker mWakeLockSuspendBlocker;
240
241    // True if the wake lock suspend blocker has been acquired.
242    private boolean mHoldingWakeLockSuspendBlocker;
243
244    // The suspend blocker used to keep the CPU alive when the display is on, the
245    // display is getting ready or there is user activity (in which case the display
246    // must be on).
247    private final SuspendBlocker mDisplaySuspendBlocker;
248
249    // True if the display suspend blocker has been acquired.
250    private boolean mHoldingDisplaySuspendBlocker;
251
252    // The screen on blocker used to keep the screen from turning on while the lock
253    // screen is coming up.
254    private final ScreenOnBlockerImpl mScreenOnBlocker;
255
256    // True if systemReady() has been called.
257    private boolean mSystemReady;
258
259    // True if boot completed occurred.  We keep the screen on until this happens.
260    private boolean mBootCompleted;
261
262    // True if auto-suspend mode is enabled.
263    // Refer to autosuspend.h.
264    private boolean mHalAutoSuspendModeEnabled;
265
266    // True if interactive mode is enabled.
267    // Refer to power.h.
268    private boolean mHalInteractiveModeEnabled;
269
270    // True if the device is plugged into a power source.
271    private boolean mIsPowered;
272
273    // The current plug type, such as BatteryManager.BATTERY_PLUGGED_WIRELESS.
274    private int mPlugType;
275
276    // The current battery level percentage.
277    private int mBatteryLevel;
278
279    // The battery level percentage at the time the dream started.
280    // This is used to terminate a dream and go to sleep if the battery is
281    // draining faster than it is charging and the user activity timeout has expired.
282    private int mBatteryLevelWhenDreamStarted;
283
284    // The current dock state.
285    private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
286
287    // True to decouple auto-suspend mode from the display state.
288    private boolean mDecoupleHalAutoSuspendModeFromDisplayConfig;
289
290    // True to decouple interactive mode from the display state.
291    private boolean mDecoupleHalInteractiveModeFromDisplayConfig;
292
293    // True if the device should wake up when plugged or unplugged.
294    private boolean mWakeUpWhenPluggedOrUnpluggedConfig;
295
296    // True if the device should suspend when the screen is off due to proximity.
297    private boolean mSuspendWhenScreenOffDueToProximityConfig;
298
299    // True if dreams are supported on this device.
300    private boolean mDreamsSupportedConfig;
301
302    // Default value for dreams enabled
303    private boolean mDreamsEnabledByDefaultConfig;
304
305    // Default value for dreams activate-on-sleep
306    private boolean mDreamsActivatedOnSleepByDefaultConfig;
307
308    // Default value for dreams activate-on-dock
309    private boolean mDreamsActivatedOnDockByDefaultConfig;
310
311    // True if dreams can run while not plugged in.
312    private boolean mDreamsEnabledOnBatteryConfig;
313
314    // Minimum battery level to allow dreaming when powered.
315    // Use -1 to disable this safety feature.
316    private int mDreamsBatteryLevelMinimumWhenPoweredConfig;
317
318    // Minimum battery level to allow dreaming when not powered.
319    // Use -1 to disable this safety feature.
320    private int mDreamsBatteryLevelMinimumWhenNotPoweredConfig;
321
322    // If the battery level drops by this percentage and the user activity timeout
323    // has expired, then assume the device is receiving insufficient current to charge
324    // effectively and terminate the dream.  Use -1 to disable this safety feature.
325    private int mDreamsBatteryLevelDrainCutoffConfig;
326
327    // True if dreams are enabled by the user.
328    private boolean mDreamsEnabledSetting;
329
330    // True if dreams should be activated on sleep.
331    private boolean mDreamsActivateOnSleepSetting;
332
333    // True if dreams should be activated on dock.
334    private boolean mDreamsActivateOnDockSetting;
335
336    // The minimum screen off timeout, in milliseconds.
337    private int mMinimumScreenOffTimeoutConfig;
338
339    // The screen dim duration, in milliseconds.
340    // This is subtracted from the end of the screen off timeout so the
341    // minimum screen off timeout should be longer than this.
342    private int mMaximumScreenDimDurationConfig;
343
344    // The maximum screen dim time expressed as a ratio relative to the screen
345    // off timeout.  If the screen off timeout is very short then we want the
346    // dim timeout to also be quite short so that most of the time is spent on.
347    // Otherwise the user won't get much screen on time before dimming occurs.
348    private float mMaximumScreenDimRatioConfig;
349
350    // The screen off timeout setting value in milliseconds.
351    private int mScreenOffTimeoutSetting;
352
353    // The maximum allowable screen off timeout according to the device
354    // administration policy.  Overrides other settings.
355    private int mMaximumScreenOffTimeoutFromDeviceAdmin = Integer.MAX_VALUE;
356
357    // The stay on while plugged in setting.
358    // A bitfield of battery conditions under which to make the screen stay on.
359    private int mStayOnWhilePluggedInSetting;
360
361    // True if the device should stay on.
362    private boolean mStayOn;
363
364    // True if the proximity sensor reads a positive result.
365    private boolean mProximityPositive;
366
367    // Screen brightness setting limits.
368    private int mScreenBrightnessSettingMinimum;
369    private int mScreenBrightnessSettingMaximum;
370    private int mScreenBrightnessSettingDefault;
371
372    // The screen brightness setting, from 0 to 255.
373    // Use -1 if no value has been set.
374    private int mScreenBrightnessSetting;
375
376    // The screen auto-brightness adjustment setting, from -1 to 1.
377    // Use 0 if there is no adjustment.
378    private float mScreenAutoBrightnessAdjustmentSetting;
379
380    // The screen brightness mode.
381    // One of the Settings.System.SCREEN_BRIGHTNESS_MODE_* constants.
382    private int mScreenBrightnessModeSetting;
383
384    // The screen brightness setting override from the window manager
385    // to allow the current foreground activity to override the brightness.
386    // Use -1 to disable.
387    private int mScreenBrightnessOverrideFromWindowManager = -1;
388
389    // The user activity timeout override from the window manager
390    // to allow the current foreground activity to override the user activity timeout.
391    // Use -1 to disable.
392    private long mUserActivityTimeoutOverrideFromWindowManager = -1;
393
394    // The screen brightness setting override from the settings application
395    // to temporarily adjust the brightness until next updated,
396    // Use -1 to disable.
397    private int mTemporaryScreenBrightnessSettingOverride = -1;
398
399    // The screen brightness adjustment setting override from the settings
400    // application to temporarily adjust the auto-brightness adjustment factor
401    // until next updated, in the range -1..1.
402    // Use NaN to disable.
403    private float mTemporaryScreenAutoBrightnessAdjustmentSettingOverride = Float.NaN;
404
405    // Time when we last logged a warning about calling userActivity() without permission.
406    private long mLastWarningAboutUserActivityPermission = Long.MIN_VALUE;
407
408    // If true, the device is in low power mode.
409    private boolean mLowPowerModeEnabled;
410
411    // Current state of the low power mode setting.
412    private boolean mLowPowerModeSetting;
413
414    // Current state of whether the settings are allowing auto low power mode.
415    private boolean mAutoLowPowerModeEnabled;
416
417    // True if the battery level is currently considered low.
418    private boolean mBatteryLevelLow;
419
420    private final ArrayList<PowerManagerInternal.LowPowerModeListener> mLowPowerModeListeners
421            = new ArrayList<PowerManagerInternal.LowPowerModeListener>();
422
423    private native void nativeInit();
424
425    private static native void nativeAcquireSuspendBlocker(String name);
426    private static native void nativeReleaseSuspendBlocker(String name);
427    private static native void nativeSetInteractive(boolean enable);
428    private static native void nativeSetAutoSuspend(boolean enable);
429    private static native void nativeSendPowerHint(int hintId, int data);
430
431    public PowerManagerService(Context context) {
432        super(context);
433        mContext = context;
434        mHandlerThread = new ServiceThread(TAG,
435                Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/);
436        mHandlerThread.start();
437        mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
438
439        synchronized (mLock) {
440            mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks");
441            mDisplaySuspendBlocker = createSuspendBlockerLocked("PowerManagerService.Display");
442            mDisplaySuspendBlocker.acquire();
443            mHoldingDisplaySuspendBlocker = true;
444            mHalAutoSuspendModeEnabled = false;
445            mHalInteractiveModeEnabled = true;
446
447            mScreenOnBlocker = new ScreenOnBlockerImpl();
448            mWakefulness = WAKEFULNESS_AWAKE;
449            mInteractive = true;
450
451            nativeInit();
452            nativeSetAutoSuspend(false);
453            nativeSetInteractive(true);
454        }
455    }
456
457    @Override
458    public void onStart() {
459        publishBinderService(Context.POWER_SERVICE, new BinderService());
460        publishLocalService(PowerManagerInternal.class, new LocalService());
461
462        Watchdog.getInstance().addMonitor(this);
463        Watchdog.getInstance().addThread(mHandler);
464    }
465
466    public void systemReady(IAppOpsService appOps) {
467        synchronized (mLock) {
468            mSystemReady = true;
469            mAppOps = appOps;
470            mDreamManager = getLocalService(DreamManagerInternal.class);
471            mDisplayManagerInternal = getLocalService(DisplayManagerInternal.class);
472            mPolicy = getLocalService(WindowManagerPolicy.class);
473            mBatteryManagerInternal = getLocalService(BatteryManagerInternal.class);
474
475            PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
476            mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting();
477            mScreenBrightnessSettingMaximum = pm.getMaximumScreenBrightnessSetting();
478            mScreenBrightnessSettingDefault = pm.getDefaultScreenBrightnessSetting();
479
480            SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper());
481
482            // The notifier runs on the system server's main looper so as not to interfere
483            // with the animations and other critical functions of the power manager.
484            mBatteryStats = BatteryStatsService.getService();
485            mNotifier = new Notifier(Looper.getMainLooper(), mContext, mBatteryStats,
486                    mAppOps, createSuspendBlockerLocked("PowerManagerService.Broadcasts"),
487                    mScreenOnBlocker, mPolicy);
488
489            mWirelessChargerDetector = new WirelessChargerDetector(sensorManager,
490                    createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector"),
491                    mHandler);
492            mSettingsObserver = new SettingsObserver(mHandler);
493
494            mLightsManager = getLocalService(LightsManager.class);
495            mAttentionLight = mLightsManager.getLight(LightsManager.LIGHT_ID_ATTENTION);
496
497            // Initialize display power management.
498            mDisplayManagerInternal.initPowerManagement(
499                    mDisplayPowerCallbacks, mHandler, sensorManager);
500
501            // Register for broadcasts from other components of the system.
502            IntentFilter filter = new IntentFilter();
503            filter.addAction(Intent.ACTION_BATTERY_CHANGED);
504            filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
505            mContext.registerReceiver(new BatteryReceiver(), filter, null, mHandler);
506
507            filter = new IntentFilter();
508            filter.addAction(Intent.ACTION_BOOT_COMPLETED);
509            filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
510            mContext.registerReceiver(new BootCompletedReceiver(), filter, null, mHandler);
511
512            filter = new IntentFilter();
513            filter.addAction(Intent.ACTION_DREAMING_STARTED);
514            filter.addAction(Intent.ACTION_DREAMING_STOPPED);
515            mContext.registerReceiver(new DreamReceiver(), filter, null, mHandler);
516
517            filter = new IntentFilter();
518            filter.addAction(Intent.ACTION_USER_SWITCHED);
519            mContext.registerReceiver(new UserSwitchedReceiver(), filter, null, mHandler);
520
521            filter = new IntentFilter();
522            filter.addAction(Intent.ACTION_DOCK_EVENT);
523            mContext.registerReceiver(new DockReceiver(), filter, null, mHandler);
524
525            // Register for settings changes.
526            final ContentResolver resolver = mContext.getContentResolver();
527            resolver.registerContentObserver(Settings.Secure.getUriFor(
528                    Settings.Secure.SCREENSAVER_ENABLED),
529                    false, mSettingsObserver, UserHandle.USER_ALL);
530            resolver.registerContentObserver(Settings.Secure.getUriFor(
531                    Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP),
532                    false, mSettingsObserver, UserHandle.USER_ALL);
533            resolver.registerContentObserver(Settings.Secure.getUriFor(
534                    Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK),
535                    false, mSettingsObserver, UserHandle.USER_ALL);
536            resolver.registerContentObserver(Settings.System.getUriFor(
537                    Settings.System.SCREEN_OFF_TIMEOUT),
538                    false, mSettingsObserver, UserHandle.USER_ALL);
539            resolver.registerContentObserver(Settings.Global.getUriFor(
540                    Settings.Global.STAY_ON_WHILE_PLUGGED_IN),
541                    false, mSettingsObserver, UserHandle.USER_ALL);
542            resolver.registerContentObserver(Settings.System.getUriFor(
543                    Settings.System.SCREEN_BRIGHTNESS),
544                    false, mSettingsObserver, UserHandle.USER_ALL);
545            resolver.registerContentObserver(Settings.System.getUriFor(
546                    Settings.System.SCREEN_BRIGHTNESS_MODE),
547                    false, mSettingsObserver, UserHandle.USER_ALL);
548            resolver.registerContentObserver(Settings.System.getUriFor(
549                    Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ),
550                    false, mSettingsObserver, UserHandle.USER_ALL);
551            resolver.registerContentObserver(Settings.Global.getUriFor(
552                    Settings.Global.LOW_POWER_MODE),
553                    false, mSettingsObserver, UserHandle.USER_ALL);
554            resolver.registerContentObserver(Settings.Global.getUriFor(
555                    Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),
556                    false, mSettingsObserver, UserHandle.USER_ALL);
557            // Go.
558            readConfigurationLocked();
559            updateSettingsLocked();
560            mDirty |= DIRTY_BATTERY_STATE;
561            updatePowerStateLocked();
562        }
563    }
564
565    private void readConfigurationLocked() {
566        final Resources resources = mContext.getResources();
567
568        mDecoupleHalAutoSuspendModeFromDisplayConfig = resources.getBoolean(
569                com.android.internal.R.bool.config_powerDecoupleAutoSuspendModeFromDisplay);
570        mDecoupleHalInteractiveModeFromDisplayConfig = resources.getBoolean(
571                com.android.internal.R.bool.config_powerDecoupleInteractiveModeFromDisplay);
572        mWakeUpWhenPluggedOrUnpluggedConfig = resources.getBoolean(
573                com.android.internal.R.bool.config_unplugTurnsOnScreen);
574        mSuspendWhenScreenOffDueToProximityConfig = resources.getBoolean(
575                com.android.internal.R.bool.config_suspendWhenScreenOffDueToProximity);
576        mDreamsSupportedConfig = resources.getBoolean(
577                com.android.internal.R.bool.config_dreamsSupported);
578        mDreamsEnabledByDefaultConfig = resources.getBoolean(
579                com.android.internal.R.bool.config_dreamsEnabledByDefault);
580        mDreamsActivatedOnSleepByDefaultConfig = resources.getBoolean(
581                com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault);
582        mDreamsActivatedOnDockByDefaultConfig = resources.getBoolean(
583                com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault);
584        mDreamsEnabledOnBatteryConfig = resources.getBoolean(
585                com.android.internal.R.bool.config_dreamsEnabledOnBattery);
586        mDreamsBatteryLevelMinimumWhenPoweredConfig = resources.getInteger(
587                com.android.internal.R.integer.config_dreamsBatteryLevelMinimumWhenPowered);
588        mDreamsBatteryLevelMinimumWhenNotPoweredConfig = resources.getInteger(
589                com.android.internal.R.integer.config_dreamsBatteryLevelMinimumWhenNotPowered);
590        mDreamsBatteryLevelDrainCutoffConfig = resources.getInteger(
591                com.android.internal.R.integer.config_dreamsBatteryLevelDrainCutoff);
592        mMinimumScreenOffTimeoutConfig = resources.getInteger(
593                com.android.internal.R.integer.config_minimumScreenOffTimeout);
594        mMaximumScreenDimDurationConfig = resources.getInteger(
595                com.android.internal.R.integer.config_maximumScreenDimDuration);
596        mMaximumScreenDimRatioConfig = resources.getFraction(
597                com.android.internal.R.fraction.config_maximumScreenDimRatio, 1, 1);
598    }
599
600    private void updateSettingsLocked() {
601        final ContentResolver resolver = mContext.getContentResolver();
602
603        mDreamsEnabledSetting = (Settings.Secure.getIntForUser(resolver,
604                Settings.Secure.SCREENSAVER_ENABLED,
605                mDreamsEnabledByDefaultConfig ? 1 : 0,
606                UserHandle.USER_CURRENT) != 0);
607        mDreamsActivateOnSleepSetting = (Settings.Secure.getIntForUser(resolver,
608                Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
609                mDreamsActivatedOnSleepByDefaultConfig ? 1 : 0,
610                UserHandle.USER_CURRENT) != 0);
611        mDreamsActivateOnDockSetting = (Settings.Secure.getIntForUser(resolver,
612                Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
613                mDreamsActivatedOnDockByDefaultConfig ? 1 : 0,
614                UserHandle.USER_CURRENT) != 0);
615        mScreenOffTimeoutSetting = Settings.System.getIntForUser(resolver,
616                Settings.System.SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT,
617                UserHandle.USER_CURRENT);
618        mStayOnWhilePluggedInSetting = Settings.Global.getInt(resolver,
619                Settings.Global.STAY_ON_WHILE_PLUGGED_IN, BatteryManager.BATTERY_PLUGGED_AC);
620
621        final int oldScreenBrightnessSetting = mScreenBrightnessSetting;
622        mScreenBrightnessSetting = Settings.System.getIntForUser(resolver,
623                Settings.System.SCREEN_BRIGHTNESS, mScreenBrightnessSettingDefault,
624                UserHandle.USER_CURRENT);
625        if (oldScreenBrightnessSetting != mScreenBrightnessSetting) {
626            mTemporaryScreenBrightnessSettingOverride = -1;
627        }
628
629        final float oldScreenAutoBrightnessAdjustmentSetting =
630                mScreenAutoBrightnessAdjustmentSetting;
631        mScreenAutoBrightnessAdjustmentSetting = Settings.System.getFloatForUser(resolver,
632                Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f,
633                UserHandle.USER_CURRENT);
634        if (oldScreenAutoBrightnessAdjustmentSetting != mScreenAutoBrightnessAdjustmentSetting) {
635            mTemporaryScreenAutoBrightnessAdjustmentSettingOverride = Float.NaN;
636        }
637
638        mScreenBrightnessModeSetting = Settings.System.getIntForUser(resolver,
639                Settings.System.SCREEN_BRIGHTNESS_MODE,
640                Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, UserHandle.USER_CURRENT);
641
642        final boolean lowPowerModeEnabled = Settings.Global.getInt(resolver,
643                Settings.Global.LOW_POWER_MODE, 0) != 0;
644        final boolean autoLowPowerModeEnabled = Settings.Global.getInt(resolver,
645                Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 15) != 0;
646        if (lowPowerModeEnabled != mLowPowerModeSetting
647                || autoLowPowerModeEnabled != mAutoLowPowerModeEnabled) {
648            mLowPowerModeSetting = lowPowerModeEnabled;
649            mAutoLowPowerModeEnabled = autoLowPowerModeEnabled;
650            updateLowPowerModeLocked();
651        }
652
653        mDirty |= DIRTY_SETTINGS;
654    }
655
656    void updateLowPowerModeLocked() {
657        final boolean lowPowerModeEnabled = !mIsPowered
658                && (mLowPowerModeSetting || (mAutoLowPowerModeEnabled && mBatteryLevelLow));
659        if (mLowPowerModeEnabled != lowPowerModeEnabled) {
660            mLowPowerModeEnabled = lowPowerModeEnabled;
661            powerHintInternal(POWER_HINT_LOW_POWER_MODE, lowPowerModeEnabled ? 1 : 0);
662            mLowPowerModeEnabled = lowPowerModeEnabled;
663            BackgroundThread.getHandler().post(new Runnable() {
664                @Override
665                public void run() {
666                    ArrayList<PowerManagerInternal.LowPowerModeListener> listeners;
667                    synchronized (mLock) {
668                        listeners = new ArrayList<PowerManagerInternal.LowPowerModeListener>(
669                                mLowPowerModeListeners);
670                    }
671                    for (int i=0; i<listeners.size(); i++) {
672                        listeners.get(i).onLowPowerModeChanged(lowPowerModeEnabled);
673                    }
674                    Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
675                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
676                    mContext.sendBroadcast(intent);
677                }
678            });
679        }
680    }
681
682    private void handleSettingsChangedLocked() {
683        updateSettingsLocked();
684        updatePowerStateLocked();
685    }
686
687    private void acquireWakeLockInternal(IBinder lock, int flags, String tag, String packageName,
688            WorkSource ws, String historyTag, int uid, int pid) {
689        synchronized (mLock) {
690            if (DEBUG_SPEW) {
691                Slog.d(TAG, "acquireWakeLockInternal: lock=" + Objects.hashCode(lock)
692                        + ", flags=0x" + Integer.toHexString(flags)
693                        + ", tag=\"" + tag + "\", ws=" + ws + ", uid=" + uid + ", pid=" + pid);
694            }
695
696            WakeLock wakeLock;
697            int index = findWakeLockIndexLocked(lock);
698            if (index >= 0) {
699                wakeLock = mWakeLocks.get(index);
700                if (!wakeLock.hasSameProperties(flags, tag, ws, uid, pid)) {
701                    // Update existing wake lock.  This shouldn't happen but is harmless.
702                    notifyWakeLockChangingLocked(wakeLock, flags, tag, packageName,
703                            uid, pid, ws, historyTag);
704                    wakeLock.updateProperties(flags, tag, packageName, ws, historyTag, uid, pid);
705                }
706            } else {
707                wakeLock = new WakeLock(lock, flags, tag, packageName, ws, historyTag, uid, pid);
708                try {
709                    lock.linkToDeath(wakeLock, 0);
710                } catch (RemoteException ex) {
711                    throw new IllegalArgumentException("Wake lock is already dead.");
712                }
713                notifyWakeLockAcquiredLocked(wakeLock);
714                mWakeLocks.add(wakeLock);
715            }
716
717            applyWakeLockFlagsOnAcquireLocked(wakeLock);
718            mDirty |= DIRTY_WAKE_LOCKS;
719            updatePowerStateLocked();
720        }
721    }
722
723    @SuppressWarnings("deprecation")
724    private static boolean isScreenLock(final WakeLock wakeLock) {
725        switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
726            case PowerManager.FULL_WAKE_LOCK:
727            case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
728            case PowerManager.SCREEN_DIM_WAKE_LOCK:
729                return true;
730        }
731        return false;
732    }
733
734    private void applyWakeLockFlagsOnAcquireLocked(WakeLock wakeLock) {
735        if ((wakeLock.mFlags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0
736                && isScreenLock(wakeLock)) {
737            wakeUpNoUpdateLocked(SystemClock.uptimeMillis());
738        }
739    }
740
741    private void releaseWakeLockInternal(IBinder lock, int flags) {
742        synchronized (mLock) {
743            int index = findWakeLockIndexLocked(lock);
744            if (index < 0) {
745                if (DEBUG_SPEW) {
746                    Slog.d(TAG, "releaseWakeLockInternal: lock=" + Objects.hashCode(lock)
747                            + " [not found], flags=0x" + Integer.toHexString(flags));
748                }
749                return;
750            }
751
752            WakeLock wakeLock = mWakeLocks.get(index);
753            if (DEBUG_SPEW) {
754                Slog.d(TAG, "releaseWakeLockInternal: lock=" + Objects.hashCode(lock)
755                        + " [" + wakeLock.mTag + "], flags=0x" + Integer.toHexString(flags));
756            }
757
758            mWakeLocks.remove(index);
759            notifyWakeLockReleasedLocked(wakeLock);
760            wakeLock.mLock.unlinkToDeath(wakeLock, 0);
761
762            if ((flags & PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE) != 0) {
763                mRequestWaitForNegativeProximity = true;
764            }
765
766            applyWakeLockFlagsOnReleaseLocked(wakeLock);
767            mDirty |= DIRTY_WAKE_LOCKS;
768            updatePowerStateLocked();
769        }
770    }
771
772    private void handleWakeLockDeath(WakeLock wakeLock) {
773        synchronized (mLock) {
774            if (DEBUG_SPEW) {
775                Slog.d(TAG, "handleWakeLockDeath: lock=" + Objects.hashCode(wakeLock.mLock)
776                        + " [" + wakeLock.mTag + "]");
777            }
778
779            int index = mWakeLocks.indexOf(wakeLock);
780            if (index < 0) {
781                return;
782            }
783
784            mWakeLocks.remove(index);
785            notifyWakeLockReleasedLocked(wakeLock);
786
787            applyWakeLockFlagsOnReleaseLocked(wakeLock);
788            mDirty |= DIRTY_WAKE_LOCKS;
789            updatePowerStateLocked();
790        }
791    }
792
793    private void applyWakeLockFlagsOnReleaseLocked(WakeLock wakeLock) {
794        if ((wakeLock.mFlags & PowerManager.ON_AFTER_RELEASE) != 0
795                && isScreenLock(wakeLock)) {
796            userActivityNoUpdateLocked(SystemClock.uptimeMillis(),
797                    PowerManager.USER_ACTIVITY_EVENT_OTHER,
798                    PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS,
799                    wakeLock.mOwnerUid);
800        }
801    }
802
803    private void updateWakeLockWorkSourceInternal(IBinder lock, WorkSource ws, String historyTag) {
804        synchronized (mLock) {
805            int index = findWakeLockIndexLocked(lock);
806            if (index < 0) {
807                if (DEBUG_SPEW) {
808                    Slog.d(TAG, "updateWakeLockWorkSourceInternal: lock=" + Objects.hashCode(lock)
809                            + " [not found], ws=" + ws);
810                }
811                throw new IllegalArgumentException("Wake lock not active");
812            }
813
814            WakeLock wakeLock = mWakeLocks.get(index);
815            if (DEBUG_SPEW) {
816                Slog.d(TAG, "updateWakeLockWorkSourceInternal: lock=" + Objects.hashCode(lock)
817                        + " [" + wakeLock.mTag + "], ws=" + ws);
818            }
819
820            if (!wakeLock.hasSameWorkSource(ws)) {
821                notifyWakeLockChangingLocked(wakeLock, wakeLock.mFlags, wakeLock.mTag,
822                        wakeLock.mPackageName, wakeLock.mOwnerUid, wakeLock.mOwnerPid,
823                        ws, historyTag);
824                wakeLock.mHistoryTag = historyTag;
825                wakeLock.updateWorkSource(ws);
826            }
827        }
828    }
829
830    private int findWakeLockIndexLocked(IBinder lock) {
831        final int count = mWakeLocks.size();
832        for (int i = 0; i < count; i++) {
833            if (mWakeLocks.get(i).mLock == lock) {
834                return i;
835            }
836        }
837        return -1;
838    }
839
840    private void notifyWakeLockAcquiredLocked(WakeLock wakeLock) {
841        if (mSystemReady) {
842            wakeLock.mNotifiedAcquired = true;
843            mNotifier.onWakeLockAcquired(wakeLock.mFlags, wakeLock.mTag, wakeLock.mPackageName,
844                    wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource,
845                    wakeLock.mHistoryTag);
846        }
847    }
848
849    private void notifyWakeLockChangingLocked(WakeLock wakeLock, int flags, String tag,
850            String packageName, int uid, int pid, WorkSource ws, String historyTag) {
851        if (mSystemReady && wakeLock.mNotifiedAcquired) {
852            mNotifier.onWakeLockChanging(wakeLock.mFlags, wakeLock.mTag, wakeLock.mPackageName,
853                    wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource,
854                    wakeLock.mHistoryTag, flags, tag, packageName, uid, pid, ws, historyTag);
855        }
856    }
857
858    private void notifyWakeLockReleasedLocked(WakeLock wakeLock) {
859        if (mSystemReady && wakeLock.mNotifiedAcquired) {
860            wakeLock.mNotifiedAcquired = false;
861            mNotifier.onWakeLockReleased(wakeLock.mFlags, wakeLock.mTag,
862                    wakeLock.mPackageName, wakeLock.mOwnerUid, wakeLock.mOwnerPid,
863                    wakeLock.mWorkSource, wakeLock.mHistoryTag);
864        }
865    }
866
867    @SuppressWarnings("deprecation")
868    private boolean isWakeLockLevelSupportedInternal(int level) {
869        synchronized (mLock) {
870            switch (level) {
871                case PowerManager.PARTIAL_WAKE_LOCK:
872                case PowerManager.SCREEN_DIM_WAKE_LOCK:
873                case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
874                case PowerManager.FULL_WAKE_LOCK:
875                case PowerManager.DOZE_WAKE_LOCK:
876                    return true;
877
878                case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
879                    return mSystemReady && mDisplayManagerInternal.isProximitySensorAvailable();
880
881                default:
882                    return false;
883            }
884        }
885    }
886
887    // Called from native code.
888    private void userActivityFromNative(long eventTime, int event, int flags) {
889        userActivityInternal(eventTime, event, flags, Process.SYSTEM_UID);
890    }
891
892    private void userActivityInternal(long eventTime, int event, int flags, int uid) {
893        synchronized (mLock) {
894            if (userActivityNoUpdateLocked(eventTime, event, flags, uid)) {
895                updatePowerStateLocked();
896            }
897        }
898    }
899
900    private boolean userActivityNoUpdateLocked(long eventTime, int event, int flags, int uid) {
901        if (DEBUG_SPEW) {
902            Slog.d(TAG, "userActivityNoUpdateLocked: eventTime=" + eventTime
903                    + ", event=" + event + ", flags=0x" + Integer.toHexString(flags)
904                    + ", uid=" + uid);
905        }
906
907        if (eventTime < mLastSleepTime || eventTime < mLastWakeTime
908                || mWakefulness == WAKEFULNESS_ASLEEP || mWakefulness == WAKEFULNESS_DOZING
909                || !mBootCompleted || !mSystemReady) {
910            return false;
911        }
912
913        mNotifier.onUserActivity(event, uid);
914
915        if ((flags & PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS) != 0) {
916            if (eventTime > mLastUserActivityTimeNoChangeLights
917                    && eventTime > mLastUserActivityTime) {
918                mLastUserActivityTimeNoChangeLights = eventTime;
919                mDirty |= DIRTY_USER_ACTIVITY;
920                return true;
921            }
922        } else {
923            if (eventTime > mLastUserActivityTime) {
924                mLastUserActivityTime = eventTime;
925                mDirty |= DIRTY_USER_ACTIVITY;
926                return true;
927            }
928        }
929        return false;
930    }
931
932    private void wakeUpInternal(long eventTime) {
933        synchronized (mLock) {
934            if (wakeUpNoUpdateLocked(eventTime)) {
935                updatePowerStateLocked();
936            }
937        }
938    }
939
940    private boolean wakeUpNoUpdateLocked(long eventTime) {
941        if (DEBUG_SPEW) {
942            Slog.d(TAG, "wakeUpNoUpdateLocked: eventTime=" + eventTime);
943        }
944
945        if (eventTime < mLastSleepTime || mWakefulness == WAKEFULNESS_AWAKE
946                || !mBootCompleted || !mSystemReady) {
947            return false;
948        }
949
950        switch (mWakefulness) {
951            case WAKEFULNESS_ASLEEP:
952                Slog.i(TAG, "Waking up from sleep...");
953                break;
954            case WAKEFULNESS_DREAMING:
955                Slog.i(TAG, "Waking up from dream...");
956                break;
957            case WAKEFULNESS_DOZING:
958                Slog.i(TAG, "Waking up from dozing...");
959                break;
960        }
961
962        mLastWakeTime = eventTime;
963        mDirty |= DIRTY_WAKEFULNESS;
964        mWakefulness = WAKEFULNESS_AWAKE;
965        setInteractiveStateLocked(true, 0);
966
967        userActivityNoUpdateLocked(
968                eventTime, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
969        return true;
970    }
971
972    private void goToSleepInternal(long eventTime, int reason, int flags) {
973        synchronized (mLock) {
974            if (goToSleepNoUpdateLocked(eventTime, reason, flags)) {
975                updatePowerStateLocked();
976            }
977        }
978    }
979
980    // This method is called goToSleep for historical reasons but we actually start
981    // dozing before really going to sleep.
982    @SuppressWarnings("deprecation")
983    private boolean goToSleepNoUpdateLocked(long eventTime, int reason, int flags) {
984        if (DEBUG_SPEW) {
985            Slog.d(TAG, "goToSleepNoUpdateLocked: eventTime=" + eventTime
986                    + ", reason=" + reason + ", flags=" + flags);
987        }
988
989        if (eventTime < mLastWakeTime
990                || mWakefulness == WAKEFULNESS_ASLEEP
991                || mWakefulness == WAKEFULNESS_DOZING
992                || !mBootCompleted || !mSystemReady) {
993            return false;
994        }
995
996        switch (reason) {
997            case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN:
998                Slog.i(TAG, "Going to sleep due to device administration policy...");
999                break;
1000            case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT:
1001                Slog.i(TAG, "Going to sleep due to screen timeout...");
1002                break;
1003            default:
1004                Slog.i(TAG, "Going to sleep by user request...");
1005                reason = PowerManager.GO_TO_SLEEP_REASON_USER;
1006                break;
1007        }
1008
1009        mLastSleepTime = eventTime;
1010        mDirty |= DIRTY_WAKEFULNESS;
1011        mWakefulness = WAKEFULNESS_DOZING;
1012        mSandmanSummoned = true;
1013        setInteractiveStateLocked(false, reason);
1014
1015        // Report the number of wake locks that will be cleared by going to sleep.
1016        int numWakeLocksCleared = 0;
1017        final int numWakeLocks = mWakeLocks.size();
1018        for (int i = 0; i < numWakeLocks; i++) {
1019            final WakeLock wakeLock = mWakeLocks.get(i);
1020            switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
1021                case PowerManager.FULL_WAKE_LOCK:
1022                case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
1023                case PowerManager.SCREEN_DIM_WAKE_LOCK:
1024                    numWakeLocksCleared += 1;
1025                    break;
1026            }
1027        }
1028        EventLog.writeEvent(EventLogTags.POWER_SLEEP_REQUESTED, numWakeLocksCleared);
1029
1030        // Skip dozing if requested.
1031        if ((flags & PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE) != 0) {
1032            reallyGoToSleepNoUpdateLocked(eventTime);
1033        }
1034        return true;
1035    }
1036
1037    private void napInternal(long eventTime) {
1038        synchronized (mLock) {
1039            if (napNoUpdateLocked(eventTime)) {
1040                updatePowerStateLocked();
1041            }
1042        }
1043    }
1044
1045    private boolean napNoUpdateLocked(long eventTime) {
1046        if (DEBUG_SPEW) {
1047            Slog.d(TAG, "napNoUpdateLocked: eventTime=" + eventTime);
1048        }
1049
1050        if (eventTime < mLastWakeTime || mWakefulness != WAKEFULNESS_AWAKE
1051                || !mBootCompleted || !mSystemReady) {
1052            return false;
1053        }
1054
1055        Slog.i(TAG, "Nap time...");
1056
1057        mDirty |= DIRTY_WAKEFULNESS;
1058        mWakefulness = WAKEFULNESS_DREAMING;
1059        mSandmanSummoned = true;
1060        setInteractiveStateLocked(true, 0);
1061        return true;
1062    }
1063
1064    // Done dozing, drop everything and go to sleep.
1065    private boolean reallyGoToSleepNoUpdateLocked(long eventTime) {
1066        if (DEBUG_SPEW) {
1067            Slog.d(TAG, "reallyGoToSleepNoUpdateLocked: eventTime=" + eventTime);
1068        }
1069
1070        if (eventTime < mLastWakeTime || mWakefulness == WAKEFULNESS_ASLEEP
1071                || !mBootCompleted || !mSystemReady) {
1072            return false;
1073        }
1074
1075        Slog.i(TAG, "Sleeping...");
1076
1077        mDirty |= DIRTY_WAKEFULNESS;
1078        mWakefulness = WAKEFULNESS_ASLEEP;
1079        setInteractiveStateLocked(false, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
1080        return true;
1081    }
1082
1083    private void setInteractiveStateLocked(boolean interactive, int reason) {
1084        if (mInteractive != interactive) {
1085            finishInteractiveStateChangeLocked();
1086
1087            mInteractive = interactive;
1088            mInteractiveChanging = true;
1089            mNotifier.onInteractiveStateChangeStarted(interactive, reason);
1090        }
1091    }
1092
1093    private void finishInteractiveStateChangeLocked() {
1094        if (mInteractiveChanging) {
1095            mNotifier.onInteractiveStateChangeFinished(mInteractive);
1096            mInteractiveChanging = false;
1097        }
1098    }
1099
1100    /**
1101     * Updates the global power state based on dirty bits recorded in mDirty.
1102     *
1103     * This is the main function that performs power state transitions.
1104     * We centralize them here so that we can recompute the power state completely
1105     * each time something important changes, and ensure that we do it the same
1106     * way each time.  The point is to gather all of the transition logic here.
1107     */
1108    private void updatePowerStateLocked() {
1109        if (!mSystemReady || mDirty == 0) {
1110            return;
1111        }
1112        if (!Thread.holdsLock(mLock)) {
1113            Slog.wtf(TAG, "Power manager lock was not held when calling updatePowerStateLocked");
1114        }
1115
1116        // Phase 0: Basic state updates.
1117        updateIsPoweredLocked(mDirty);
1118        updateStayOnLocked(mDirty);
1119
1120        // Phase 1: Update wakefulness.
1121        // Loop because the wake lock and user activity computations are influenced
1122        // by changes in wakefulness.
1123        final long now = SystemClock.uptimeMillis();
1124        int dirtyPhase2 = 0;
1125        for (;;) {
1126            int dirtyPhase1 = mDirty;
1127            dirtyPhase2 |= dirtyPhase1;
1128            mDirty = 0;
1129
1130            updateWakeLockSummaryLocked(dirtyPhase1);
1131            updateUserActivitySummaryLocked(now, dirtyPhase1);
1132            if (!updateWakefulnessLocked(dirtyPhase1)) {
1133                break;
1134            }
1135        }
1136
1137        // Phase 2: Update dreams and display power state.
1138        updateDreamLocked(dirtyPhase2);
1139        updateDisplayPowerStateLocked(dirtyPhase2);
1140
1141        // Phase 3: Send notifications, if needed.
1142        if (mDisplayReady) {
1143            finishInteractiveStateChangeLocked();
1144        }
1145
1146        // Phase 4: Update suspend blocker.
1147        // Because we might release the last suspend blocker here, we need to make sure
1148        // we finished everything else first!
1149        updateSuspendBlockerLocked();
1150    }
1151
1152    /**
1153     * Updates the value of mIsPowered.
1154     * Sets DIRTY_IS_POWERED if a change occurred.
1155     */
1156    private void updateIsPoweredLocked(int dirty) {
1157        if ((dirty & DIRTY_BATTERY_STATE) != 0) {
1158            final boolean wasPowered = mIsPowered;
1159            final int oldPlugType = mPlugType;
1160            final boolean oldLevelLow = mBatteryLevelLow;
1161            mIsPowered = mBatteryManagerInternal.isPowered(BatteryManager.BATTERY_PLUGGED_ANY);
1162            mPlugType = mBatteryManagerInternal.getPlugType();
1163            mBatteryLevel = mBatteryManagerInternal.getBatteryLevel();
1164            mBatteryLevelLow = mBatteryManagerInternal.getBatteryLevelLow();
1165
1166            if (DEBUG_SPEW) {
1167                Slog.d(TAG, "updateIsPoweredLocked: wasPowered=" + wasPowered
1168                        + ", mIsPowered=" + mIsPowered
1169                        + ", oldPlugType=" + oldPlugType
1170                        + ", mPlugType=" + mPlugType
1171                        + ", mBatteryLevel=" + mBatteryLevel);
1172            }
1173
1174            if (wasPowered != mIsPowered || oldPlugType != mPlugType) {
1175                mDirty |= DIRTY_IS_POWERED;
1176
1177                // Update wireless dock detection state.
1178                final boolean dockedOnWirelessCharger = mWirelessChargerDetector.update(
1179                        mIsPowered, mPlugType, mBatteryLevel);
1180
1181                // Treat plugging and unplugging the devices as a user activity.
1182                // Users find it disconcerting when they plug or unplug the device
1183                // and it shuts off right away.
1184                // Some devices also wake the device when plugged or unplugged because
1185                // they don't have a charging LED.
1186                final long now = SystemClock.uptimeMillis();
1187                if (shouldWakeUpWhenPluggedOrUnpluggedLocked(wasPowered, oldPlugType,
1188                        dockedOnWirelessCharger)) {
1189                    wakeUpNoUpdateLocked(now);
1190                }
1191                userActivityNoUpdateLocked(
1192                        now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
1193
1194                // Tell the notifier whether wireless charging has started so that
1195                // it can provide feedback to the user.
1196                if (dockedOnWirelessCharger) {
1197                    mNotifier.onWirelessChargingStarted();
1198                }
1199            }
1200
1201            if (wasPowered != mIsPowered || oldLevelLow != mBatteryLevelLow) {
1202                updateLowPowerModeLocked();
1203            }
1204        }
1205    }
1206
1207    private boolean shouldWakeUpWhenPluggedOrUnpluggedLocked(
1208            boolean wasPowered, int oldPlugType, boolean dockedOnWirelessCharger) {
1209        // Don't wake when powered unless configured to do so.
1210        if (!mWakeUpWhenPluggedOrUnpluggedConfig) {
1211            return false;
1212        }
1213
1214        // Don't wake when undocked from wireless charger.
1215        // See WirelessChargerDetector for justification.
1216        if (wasPowered && !mIsPowered
1217                && oldPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS) {
1218            return false;
1219        }
1220
1221        // Don't wake when docked on wireless charger unless we are certain of it.
1222        // See WirelessChargerDetector for justification.
1223        if (!wasPowered && mIsPowered
1224                && mPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS
1225                && !dockedOnWirelessCharger) {
1226            return false;
1227        }
1228
1229        // If already dreaming and becoming powered, then don't wake.
1230        if (mIsPowered && mWakefulness == WAKEFULNESS_DREAMING) {
1231            return false;
1232        }
1233
1234        // Otherwise wake up!
1235        return true;
1236    }
1237
1238    /**
1239     * Updates the value of mStayOn.
1240     * Sets DIRTY_STAY_ON if a change occurred.
1241     */
1242    private void updateStayOnLocked(int dirty) {
1243        if ((dirty & (DIRTY_BATTERY_STATE | DIRTY_SETTINGS)) != 0) {
1244            final boolean wasStayOn = mStayOn;
1245            if (mStayOnWhilePluggedInSetting != 0
1246                    && !isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
1247                mStayOn = mBatteryManagerInternal.isPowered(mStayOnWhilePluggedInSetting);
1248            } else {
1249                mStayOn = false;
1250            }
1251
1252            if (mStayOn != wasStayOn) {
1253                mDirty |= DIRTY_STAY_ON;
1254            }
1255        }
1256    }
1257
1258    /**
1259     * Updates the value of mWakeLockSummary to summarize the state of all active wake locks.
1260     * Note that most wake-locks are ignored when the system is asleep.
1261     *
1262     * This function must have no other side-effects.
1263     */
1264    @SuppressWarnings("deprecation")
1265    private void updateWakeLockSummaryLocked(int dirty) {
1266        if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_WAKEFULNESS)) != 0) {
1267            mWakeLockSummary = 0;
1268
1269            final int numWakeLocks = mWakeLocks.size();
1270            for (int i = 0; i < numWakeLocks; i++) {
1271                final WakeLock wakeLock = mWakeLocks.get(i);
1272                switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
1273                    case PowerManager.PARTIAL_WAKE_LOCK:
1274                        mWakeLockSummary |= WAKE_LOCK_CPU;
1275                        break;
1276                    case PowerManager.FULL_WAKE_LOCK:
1277                        mWakeLockSummary |= WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_BUTTON_BRIGHT;
1278                        break;
1279                    case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
1280                        mWakeLockSummary |= WAKE_LOCK_SCREEN_BRIGHT;
1281                        break;
1282                    case PowerManager.SCREEN_DIM_WAKE_LOCK:
1283                        mWakeLockSummary |= WAKE_LOCK_SCREEN_DIM;
1284                        break;
1285                    case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
1286                        mWakeLockSummary |= WAKE_LOCK_PROXIMITY_SCREEN_OFF;
1287                        break;
1288                    case PowerManager.DOZE_WAKE_LOCK:
1289                        mWakeLockSummary |= WAKE_LOCK_DOZE;
1290                        break;
1291                }
1292            }
1293
1294            // Cancel wake locks that make no sense based on the current state.
1295            if (mWakefulness != WAKEFULNESS_DOZING) {
1296                mWakeLockSummary &= ~WAKE_LOCK_DOZE;
1297            }
1298            if (mWakefulness == WAKEFULNESS_ASLEEP
1299                    || (mWakeLockSummary & WAKE_LOCK_DOZE) != 0) {
1300                mWakeLockSummary &= ~(WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM
1301                        | WAKE_LOCK_BUTTON_BRIGHT);
1302                if (mWakefulness == WAKEFULNESS_ASLEEP) {
1303                    mWakeLockSummary &= ~WAKE_LOCK_PROXIMITY_SCREEN_OFF;
1304                }
1305            }
1306
1307            // Infer implied wake locks where necessary based on the current state.
1308            if ((mWakeLockSummary & (WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM)) != 0) {
1309                if (mWakefulness == WAKEFULNESS_AWAKE) {
1310                    mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_STAY_AWAKE;
1311                } else if (mWakefulness == WAKEFULNESS_DREAMING) {
1312                    mWakeLockSummary |= WAKE_LOCK_CPU;
1313                }
1314            }
1315
1316            if (DEBUG_SPEW) {
1317                Slog.d(TAG, "updateWakeLockSummaryLocked: mWakefulness="
1318                        + wakefulnessToString(mWakefulness)
1319                        + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary));
1320            }
1321        }
1322    }
1323
1324    /**
1325     * Updates the value of mUserActivitySummary to summarize the user requested
1326     * state of the system such as whether the screen should be bright or dim.
1327     * Note that user activity is ignored when the system is asleep.
1328     *
1329     * This function must have no other side-effects.
1330     */
1331    private void updateUserActivitySummaryLocked(long now, int dirty) {
1332        // Update the status of the user activity timeout timer.
1333        if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY
1334                | DIRTY_WAKEFULNESS | DIRTY_SETTINGS)) != 0) {
1335            mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT);
1336
1337            long nextTimeout = 0;
1338            if (mWakefulness == WAKEFULNESS_AWAKE
1339                    || mWakefulness == WAKEFULNESS_DREAMING
1340                    || mWakefulness == WAKEFULNESS_DOZING) {
1341                final int screenOffTimeout = getScreenOffTimeoutLocked();
1342                final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
1343
1344                mUserActivitySummary = 0;
1345                if (mLastUserActivityTime >= mLastWakeTime) {
1346                    nextTimeout = mLastUserActivityTime
1347                            + screenOffTimeout - screenDimDuration;
1348                    if (now < nextTimeout) {
1349                        mUserActivitySummary |= USER_ACTIVITY_SCREEN_BRIGHT;
1350                    } else {
1351                        nextTimeout = mLastUserActivityTime + screenOffTimeout;
1352                        if (now < nextTimeout) {
1353                            mUserActivitySummary |= USER_ACTIVITY_SCREEN_DIM;
1354                        }
1355                    }
1356                }
1357                if (mUserActivitySummary == 0
1358                        && mLastUserActivityTimeNoChangeLights >= mLastWakeTime) {
1359                    nextTimeout = mLastUserActivityTimeNoChangeLights + screenOffTimeout;
1360                    if (now < nextTimeout
1361                            && mDisplayPowerRequest.wantScreenOnNormal()) {
1362                        mUserActivitySummary = mDisplayPowerRequest.screenState
1363                                == DisplayPowerRequest.SCREEN_STATE_BRIGHT ?
1364                                USER_ACTIVITY_SCREEN_BRIGHT : USER_ACTIVITY_SCREEN_DIM;
1365                    }
1366                }
1367                if (mUserActivitySummary != 0) {
1368                    Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY_TIMEOUT);
1369                    msg.setAsynchronous(true);
1370                    mHandler.sendMessageAtTime(msg, nextTimeout);
1371                }
1372            } else {
1373                mUserActivitySummary = 0;
1374            }
1375
1376            if (DEBUG_SPEW) {
1377                Slog.d(TAG, "updateUserActivitySummaryLocked: mWakefulness="
1378                        + wakefulnessToString(mWakefulness)
1379                        + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
1380                        + ", nextTimeout=" + TimeUtils.formatUptime(nextTimeout));
1381            }
1382        }
1383    }
1384
1385    /**
1386     * Called when a user activity timeout has occurred.
1387     * Simply indicates that something about user activity has changed so that the new
1388     * state can be recomputed when the power state is updated.
1389     *
1390     * This function must have no other side-effects besides setting the dirty
1391     * bit and calling update power state.  Wakefulness transitions are handled elsewhere.
1392     */
1393    private void handleUserActivityTimeout() { // runs on handler thread
1394        synchronized (mLock) {
1395            if (DEBUG_SPEW) {
1396                Slog.d(TAG, "handleUserActivityTimeout");
1397            }
1398
1399            mDirty |= DIRTY_USER_ACTIVITY;
1400            updatePowerStateLocked();
1401        }
1402    }
1403
1404    private int getScreenOffTimeoutLocked() {
1405        int timeout = mScreenOffTimeoutSetting;
1406        if (isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
1407            timeout = Math.min(timeout, mMaximumScreenOffTimeoutFromDeviceAdmin);
1408        }
1409        if (mUserActivityTimeoutOverrideFromWindowManager >= 0) {
1410            timeout = (int)Math.min(timeout, mUserActivityTimeoutOverrideFromWindowManager);
1411        }
1412        return Math.max(timeout, mMinimumScreenOffTimeoutConfig);
1413    }
1414
1415    private int getScreenDimDurationLocked(int screenOffTimeout) {
1416        return Math.min(mMaximumScreenDimDurationConfig,
1417                (int)(screenOffTimeout * mMaximumScreenDimRatioConfig));
1418    }
1419
1420    /**
1421     * Updates the wakefulness of the device.
1422     *
1423     * This is the function that decides whether the device should start dreaming
1424     * based on the current wake locks and user activity state.  It may modify mDirty
1425     * if the wakefulness changes.
1426     *
1427     * Returns true if the wakefulness changed and we need to restart power state calculation.
1428     */
1429    private boolean updateWakefulnessLocked(int dirty) {
1430        boolean changed = false;
1431        if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_BOOT_COMPLETED
1432                | DIRTY_WAKEFULNESS | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE
1433                | DIRTY_DOCK_STATE)) != 0) {
1434            if (mWakefulness == WAKEFULNESS_AWAKE && isItBedTimeYetLocked()) {
1435                if (DEBUG_SPEW) {
1436                    Slog.d(TAG, "updateWakefulnessLocked: Bed time...");
1437                }
1438                final long time = SystemClock.uptimeMillis();
1439                if (shouldNapAtBedTimeLocked()) {
1440                    changed = napNoUpdateLocked(time);
1441                } else {
1442                    changed = goToSleepNoUpdateLocked(time,
1443                            PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0);
1444                }
1445            }
1446        }
1447        return changed;
1448    }
1449
1450    /**
1451     * Returns true if the device should automatically nap and start dreaming when the user
1452     * activity timeout has expired and it's bedtime.
1453     */
1454    private boolean shouldNapAtBedTimeLocked() {
1455        return mDreamsActivateOnSleepSetting
1456                || (mDreamsActivateOnDockSetting
1457                        && mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED);
1458    }
1459
1460    /**
1461     * Returns true if the device should go to sleep now.
1462     * Also used when exiting a dream to determine whether we should go back
1463     * to being fully awake or else go to sleep for good.
1464     */
1465    private boolean isItBedTimeYetLocked() {
1466        return mBootCompleted && !isBeingKeptAwakeLocked();
1467    }
1468
1469    /**
1470     * Returns true if the device is being kept awake by a wake lock, user activity
1471     * or the stay on while powered setting.  We also keep the phone awake when
1472     * the proximity sensor returns a positive result so that the device does not
1473     * lock while in a phone call.  This function only controls whether the device
1474     * will go to sleep or dream which is independent of whether it will be allowed
1475     * to suspend.
1476     */
1477    private boolean isBeingKeptAwakeLocked() {
1478        return mStayOn
1479                || mProximityPositive
1480                || (mWakeLockSummary & WAKE_LOCK_STAY_AWAKE) != 0
1481                || (mUserActivitySummary & (USER_ACTIVITY_SCREEN_BRIGHT
1482                        | USER_ACTIVITY_SCREEN_DIM)) != 0;
1483    }
1484
1485    /**
1486     * Determines whether to post a message to the sandman to update the dream state.
1487     */
1488    private void updateDreamLocked(int dirty) {
1489        if ((dirty & (DIRTY_WAKEFULNESS
1490                | DIRTY_USER_ACTIVITY
1491                | DIRTY_WAKE_LOCKS
1492                | DIRTY_BOOT_COMPLETED
1493                | DIRTY_SETTINGS
1494                | DIRTY_IS_POWERED
1495                | DIRTY_STAY_ON
1496                | DIRTY_PROXIMITY_POSITIVE
1497                | DIRTY_BATTERY_STATE)) != 0) {
1498            scheduleSandmanLocked();
1499        }
1500    }
1501
1502    private void scheduleSandmanLocked() {
1503        if (!mSandmanScheduled) {
1504            mSandmanScheduled = true;
1505            Message msg = mHandler.obtainMessage(MSG_SANDMAN);
1506            msg.setAsynchronous(true);
1507            mHandler.sendMessage(msg);
1508        }
1509    }
1510
1511    /**
1512     * Called when the device enters or exits a dreaming or dozing state.
1513     *
1514     * We do this asynchronously because we must call out of the power manager to start
1515     * the dream and we don't want to hold our lock while doing so.  There is a risk that
1516     * the device will wake or go to sleep in the meantime so we have to handle that case.
1517     */
1518    private void handleSandman() { // runs on handler thread
1519        // Handle preconditions.
1520        final boolean startDreaming;
1521        final int wakefulness;
1522        synchronized (mLock) {
1523            mSandmanScheduled = false;
1524            wakefulness = mWakefulness;
1525            if (mSandmanSummoned) {
1526                startDreaming = ((wakefulness == WAKEFULNESS_DREAMING && canDreamLocked())
1527                        || wakefulness == WAKEFULNESS_DOZING);
1528                mSandmanSummoned = false;
1529            } else {
1530                startDreaming = false;
1531            }
1532        }
1533
1534        // Start dreaming if needed.
1535        // We only control the dream on the handler thread, so we don't need to worry about
1536        // concurrent attempts to start or stop the dream.
1537        final boolean isDreaming;
1538        if (mDreamManager != null) {
1539            // Restart the dream whenever the sandman is summoned.
1540            if (startDreaming) {
1541                mDreamManager.stopDream();
1542                mDreamManager.startDream(wakefulness == WAKEFULNESS_DOZING);
1543            }
1544            isDreaming = mDreamManager.isDreaming();
1545        } else {
1546            isDreaming = false;
1547        }
1548
1549        // Update dream state.
1550        synchronized (mLock) {
1551            // Remember the initial battery level when the dream started.
1552            if (startDreaming && isDreaming) {
1553                mBatteryLevelWhenDreamStarted = mBatteryLevel;
1554                if (wakefulness == WAKEFULNESS_DOZING) {
1555                    Slog.i(TAG, "Dozing...");
1556                } else {
1557                    Slog.i(TAG, "Dreaming...");
1558                }
1559            }
1560
1561            // If preconditions changed, wait for the next iteration to determine
1562            // whether the dream should continue (or be restarted).
1563            if (mSandmanSummoned || mWakefulness != wakefulness) {
1564                return; // wait for next cycle
1565            }
1566
1567            // Determine whether the dream should continue.
1568            if (wakefulness == WAKEFULNESS_DREAMING) {
1569                if (isDreaming && canDreamLocked()) {
1570                    if (mDreamsBatteryLevelDrainCutoffConfig >= 0
1571                            && mBatteryLevel < mBatteryLevelWhenDreamStarted
1572                                    - mDreamsBatteryLevelDrainCutoffConfig
1573                            && !isBeingKeptAwakeLocked()) {
1574                        // If the user activity timeout expired and the battery appears
1575                        // to be draining faster than it is charging then stop dreaming
1576                        // and go to sleep.
1577                        Slog.i(TAG, "Stopping dream because the battery appears to "
1578                                + "be draining faster than it is charging.  "
1579                                + "Battery level when dream started: "
1580                                + mBatteryLevelWhenDreamStarted + "%.  "
1581                                + "Battery level now: " + mBatteryLevel + "%.");
1582                    } else {
1583                        return; // continue dreaming
1584                    }
1585                }
1586
1587                // Dream has ended or will be stopped.  Update the power state.
1588                if (isItBedTimeYetLocked()) {
1589                    goToSleepNoUpdateLocked(SystemClock.uptimeMillis(),
1590                            PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0);
1591                    updatePowerStateLocked();
1592                } else {
1593                    wakeUpNoUpdateLocked(SystemClock.uptimeMillis());
1594                    updatePowerStateLocked();
1595                }
1596            } else if (wakefulness == WAKEFULNESS_DOZING) {
1597                if (isDreaming) {
1598                    return; // continue dozing
1599                }
1600
1601                // Doze has ended or will be stopped.  Update the power state.
1602                reallyGoToSleepNoUpdateLocked(SystemClock.uptimeMillis());
1603                updatePowerStateLocked();
1604            }
1605        }
1606
1607        // Stop dream.
1608        if (isDreaming) {
1609            mDreamManager.stopDream();
1610        }
1611    }
1612
1613    /**
1614     * Returns true if the device is allowed to dream in its current state.
1615     * This function is not called when dozing.
1616     */
1617    private boolean canDreamLocked() {
1618        if (mWakefulness != WAKEFULNESS_DREAMING
1619                || !mDreamsSupportedConfig
1620                || !mDreamsEnabledSetting
1621                || !mDisplayPowerRequest.wantScreenOnNormal()
1622                || !mBootCompleted) {
1623            return false;
1624        }
1625        if (!isBeingKeptAwakeLocked()) {
1626            if (!mIsPowered && !mDreamsEnabledOnBatteryConfig) {
1627                return false;
1628            }
1629            if (!mIsPowered
1630                    && mDreamsBatteryLevelMinimumWhenNotPoweredConfig >= 0
1631                    && mBatteryLevel < mDreamsBatteryLevelMinimumWhenNotPoweredConfig) {
1632                return false;
1633            }
1634            if (mIsPowered
1635                    && mDreamsBatteryLevelMinimumWhenPoweredConfig >= 0
1636                    && mBatteryLevel < mDreamsBatteryLevelMinimumWhenPoweredConfig) {
1637                return false;
1638            }
1639        }
1640        return true;
1641    }
1642
1643    private void handleScreenOnBlockerReleased() {
1644        synchronized (mLock) {
1645            mDirty |= DIRTY_SCREEN_ON_BLOCKER_RELEASED;
1646            updatePowerStateLocked();
1647        }
1648    }
1649
1650    /**
1651     * Updates the display power state asynchronously.
1652     * When the update is finished, mDisplayReady will be set to true.  The display
1653     * controller posts a message to tell us when the actual display power state
1654     * has been updated so we come back here to double-check and finish up.
1655     *
1656     * This function recalculates the display power state each time.
1657     */
1658    private void updateDisplayPowerStateLocked(int dirty) {
1659        if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS
1660                | DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED
1661                | DIRTY_SETTINGS | DIRTY_SCREEN_ON_BLOCKER_RELEASED)) != 0) {
1662            final int newScreenState = getDesiredScreenPowerStateLocked();
1663            mDisplayPowerRequest.screenState = newScreenState;
1664
1665            int screenBrightness = mScreenBrightnessSettingDefault;
1666            float screenAutoBrightnessAdjustment = 0.0f;
1667            boolean autoBrightness = (mScreenBrightnessModeSetting ==
1668                    Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
1669            if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)) {
1670                screenBrightness = mScreenBrightnessOverrideFromWindowManager;
1671                autoBrightness = false;
1672            } else if (isValidBrightness(mTemporaryScreenBrightnessSettingOverride)) {
1673                screenBrightness = mTemporaryScreenBrightnessSettingOverride;
1674            } else if (isValidBrightness(mScreenBrightnessSetting)) {
1675                screenBrightness = mScreenBrightnessSetting;
1676            }
1677            if (autoBrightness) {
1678                screenBrightness = mScreenBrightnessSettingDefault;
1679                if (isValidAutoBrightnessAdjustment(
1680                        mTemporaryScreenAutoBrightnessAdjustmentSettingOverride)) {
1681                    screenAutoBrightnessAdjustment =
1682                            mTemporaryScreenAutoBrightnessAdjustmentSettingOverride;
1683                } else if (isValidAutoBrightnessAdjustment(
1684                        mScreenAutoBrightnessAdjustmentSetting)) {
1685                    screenAutoBrightnessAdjustment = mScreenAutoBrightnessAdjustmentSetting;
1686                }
1687            }
1688            screenBrightness = Math.max(Math.min(screenBrightness,
1689                    mScreenBrightnessSettingMaximum), mScreenBrightnessSettingMinimum);
1690            screenAutoBrightnessAdjustment = Math.max(Math.min(
1691                    screenAutoBrightnessAdjustment, 1.0f), -1.0f);
1692            mDisplayPowerRequest.screenBrightness = screenBrightness;
1693            mDisplayPowerRequest.screenAutoBrightnessAdjustment =
1694                    screenAutoBrightnessAdjustment;
1695            mDisplayPowerRequest.useAutoBrightness = autoBrightness;
1696
1697            mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
1698
1699            mDisplayPowerRequest.blockScreenOn = mScreenOnBlocker.isHeld();
1700
1701            mDisplayPowerRequest.lowPowerMode = mLowPowerModeEnabled;
1702
1703            mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest,
1704                    mRequestWaitForNegativeProximity);
1705            mRequestWaitForNegativeProximity = false;
1706
1707            if (DEBUG_SPEW) {
1708                Slog.d(TAG, "updateScreenStateLocked: mDisplayReady=" + mDisplayReady
1709                        + ", newScreenState=" + newScreenState
1710                        + ", mWakefulness=" + mWakefulness
1711                        + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary)
1712                        + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
1713                        + ", mBootCompleted=" + mBootCompleted);
1714            }
1715        }
1716    }
1717
1718    private static boolean isValidBrightness(int value) {
1719        return value >= 0 && value <= 255;
1720    }
1721
1722    private static boolean isValidAutoBrightnessAdjustment(float value) {
1723        // Handles NaN by always returning false.
1724        return value >= -1.0f && value <= 1.0f;
1725    }
1726
1727    private int getDesiredScreenPowerStateLocked() {
1728        if (mWakefulness == WAKEFULNESS_ASLEEP) {
1729            return DisplayPowerRequest.SCREEN_STATE_OFF;
1730        }
1731
1732        if ((mWakeLockSummary & WAKE_LOCK_DOZE) != 0) {
1733            return DisplayPowerRequest.SCREEN_STATE_DOZE;
1734        }
1735
1736        if ((mWakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0
1737                || (mUserActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0
1738                || !mBootCompleted) {
1739            return DisplayPowerRequest.SCREEN_STATE_BRIGHT;
1740        }
1741
1742        return DisplayPowerRequest.SCREEN_STATE_DIM;
1743    }
1744
1745    private final DisplayManagerInternal.DisplayPowerCallbacks mDisplayPowerCallbacks =
1746            new DisplayManagerInternal.DisplayPowerCallbacks() {
1747        private int mDisplayState = Display.STATE_UNKNOWN;
1748
1749        @Override
1750        public void onStateChanged() {
1751            synchronized (mLock) {
1752                mDirty |= DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED;
1753                updatePowerStateLocked();
1754            }
1755        }
1756
1757        @Override
1758        public void onProximityPositive() {
1759            synchronized (mLock) {
1760                mProximityPositive = true;
1761                mDirty |= DIRTY_PROXIMITY_POSITIVE;
1762                updatePowerStateLocked();
1763            }
1764        }
1765
1766        @Override
1767        public void onProximityNegative() {
1768            synchronized (mLock) {
1769                mProximityPositive = false;
1770                mDirty |= DIRTY_PROXIMITY_POSITIVE;
1771                userActivityNoUpdateLocked(SystemClock.uptimeMillis(),
1772                        PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
1773                updatePowerStateLocked();
1774            }
1775        }
1776
1777        @Override
1778        public void onDisplayStateChange(int state) {
1779            // This method is only needed to support legacy display blanking behavior
1780            // where the display's power state is coupled to suspend or to the power HAL.
1781            // The order of operations matters here.
1782            synchronized (mLock) {
1783                if (mDisplayState != state) {
1784                    mDisplayState = state;
1785                    if (state == Display.STATE_OFF) {
1786                        if (!mDecoupleHalInteractiveModeFromDisplayConfig) {
1787                            setHalInteractiveModeLocked(false);
1788                        }
1789                        if (!mDecoupleHalAutoSuspendModeFromDisplayConfig) {
1790                            setHalAutoSuspendModeLocked(true);
1791                        }
1792                    } else {
1793                        if (!mDecoupleHalAutoSuspendModeFromDisplayConfig) {
1794                            setHalAutoSuspendModeLocked(false);
1795                        }
1796                        if (!mDecoupleHalInteractiveModeFromDisplayConfig) {
1797                            setHalInteractiveModeLocked(true);
1798                        }
1799                    }
1800                }
1801            }
1802        }
1803
1804        @Override
1805        public void acquireSuspendBlocker() {
1806            mDisplaySuspendBlocker.acquire();
1807        }
1808
1809        @Override
1810        public void releaseSuspendBlocker() {
1811            mDisplaySuspendBlocker.release();
1812        }
1813
1814        @Override
1815        public String toString() {
1816            synchronized (this) {
1817                return "state=" + Display.stateToString(mDisplayState);
1818            }
1819        }
1820    };
1821
1822    private boolean shouldUseProximitySensorLocked() {
1823        return (mWakeLockSummary & WAKE_LOCK_PROXIMITY_SCREEN_OFF) != 0;
1824    }
1825
1826    /**
1827     * Updates the suspend blocker that keeps the CPU alive.
1828     *
1829     * This function must have no other side-effects.
1830     */
1831    private void updateSuspendBlockerLocked() {
1832        final boolean needWakeLockSuspendBlocker = ((mWakeLockSummary & WAKE_LOCK_CPU) != 0);
1833        final boolean needDisplaySuspendBlocker = needDisplaySuspendBlockerLocked();
1834        final boolean autoSuspend = !needDisplaySuspendBlocker;
1835
1836        // Disable auto-suspend if needed.
1837        if (!autoSuspend) {
1838            if (mDecoupleHalAutoSuspendModeFromDisplayConfig) {
1839                setHalAutoSuspendModeLocked(false);
1840            }
1841            if (mDecoupleHalInteractiveModeFromDisplayConfig) {
1842                setHalInteractiveModeLocked(true);
1843            }
1844        }
1845
1846        // First acquire suspend blockers if needed.
1847        if (needWakeLockSuspendBlocker && !mHoldingWakeLockSuspendBlocker) {
1848            mWakeLockSuspendBlocker.acquire();
1849            mHoldingWakeLockSuspendBlocker = true;
1850        }
1851        if (needDisplaySuspendBlocker && !mHoldingDisplaySuspendBlocker) {
1852            mDisplaySuspendBlocker.acquire();
1853            mHoldingDisplaySuspendBlocker = true;
1854        }
1855
1856        // Then release suspend blockers if needed.
1857        if (!needWakeLockSuspendBlocker && mHoldingWakeLockSuspendBlocker) {
1858            mWakeLockSuspendBlocker.release();
1859            mHoldingWakeLockSuspendBlocker = false;
1860        }
1861        if (!needDisplaySuspendBlocker && mHoldingDisplaySuspendBlocker) {
1862            mDisplaySuspendBlocker.release();
1863            mHoldingDisplaySuspendBlocker = false;
1864        }
1865
1866        // Enable auto-suspend if needed.
1867        if (autoSuspend) {
1868            if (mDecoupleHalInteractiveModeFromDisplayConfig) {
1869                setHalInteractiveModeLocked(false);
1870            }
1871            if (mDecoupleHalAutoSuspendModeFromDisplayConfig) {
1872                setHalAutoSuspendModeLocked(true);
1873            }
1874        }
1875    }
1876
1877    /**
1878     * Return true if we must keep a suspend blocker active on behalf of the display.
1879     * We do so if the screen is on or is in transition between states.
1880     */
1881    private boolean needDisplaySuspendBlockerLocked() {
1882        if (!mDisplayReady) {
1883            return true;
1884        }
1885        if (mDisplayPowerRequest.wantScreenOnNormal()) {
1886            // If we asked for the screen to be on but it is off due to the proximity
1887            // sensor then we may suspend but only if the configuration allows it.
1888            // On some hardware it may not be safe to suspend because the proximity
1889            // sensor may not be correctly configured as a wake-up source.
1890            if (!mDisplayPowerRequest.useProximitySensor || !mProximityPositive
1891                    || !mSuspendWhenScreenOffDueToProximityConfig) {
1892                return true;
1893            }
1894        }
1895        // Let the system suspend if the screen is off or dozing.
1896        return false;
1897    }
1898
1899    private void setHalAutoSuspendModeLocked(boolean enable) {
1900        if (enable != mHalAutoSuspendModeEnabled) {
1901            if (DEBUG) {
1902                Slog.d(TAG, "Setting HAL auto-suspend mode to " + enable);
1903            }
1904            mHalAutoSuspendModeEnabled = enable;
1905            nativeSetAutoSuspend(enable);
1906        }
1907    }
1908
1909    private void setHalInteractiveModeLocked(boolean enable) {
1910        if (enable != mHalInteractiveModeEnabled) {
1911            if (DEBUG) {
1912                Slog.d(TAG, "Setting HAL interactive mode to " + enable);
1913            }
1914            mHalInteractiveModeEnabled = enable;
1915            nativeSetInteractive(enable);
1916        }
1917    }
1918
1919    private boolean isInteractiveInternal() {
1920        synchronized (mLock) {
1921            return mInteractive;
1922        }
1923    }
1924
1925    private boolean isLowPowerModeInternal() {
1926        synchronized (mLock) {
1927            return mLowPowerModeEnabled;
1928        }
1929    }
1930
1931    private void handleBatteryStateChangedLocked() {
1932        mDirty |= DIRTY_BATTERY_STATE;
1933        updatePowerStateLocked();
1934    }
1935
1936    private void startWatchingForBootAnimationFinished() {
1937        mHandler.sendEmptyMessage(MSG_CHECK_IF_BOOT_ANIMATION_FINISHED);
1938    }
1939
1940    private void checkIfBootAnimationFinished() {
1941        if (DEBUG) {
1942            Slog.d(TAG, "Check if boot animation finished...");
1943        }
1944
1945        if (SystemService.isRunning(BOOT_ANIMATION_SERVICE)) {
1946            mHandler.sendEmptyMessageDelayed(MSG_CHECK_IF_BOOT_ANIMATION_FINISHED,
1947                    BOOT_ANIMATION_POLL_INTERVAL);
1948            return;
1949        }
1950
1951        synchronized (mLock) {
1952            if (!mBootCompleted) {
1953                Slog.i(TAG, "Boot animation finished.");
1954                handleBootCompletedLocked();
1955            }
1956        }
1957    }
1958
1959    private void handleBootCompletedLocked() {
1960        final long now = SystemClock.uptimeMillis();
1961        mBootCompleted = true;
1962        mDirty |= DIRTY_BOOT_COMPLETED;
1963        userActivityNoUpdateLocked(
1964                now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
1965        updatePowerStateLocked();
1966    }
1967
1968    private void shutdownOrRebootInternal(final boolean shutdown, final boolean confirm,
1969            final String reason, boolean wait) {
1970        if (mHandler == null || !mSystemReady) {
1971            throw new IllegalStateException("Too early to call shutdown() or reboot()");
1972        }
1973
1974        Runnable runnable = new Runnable() {
1975            @Override
1976            public void run() {
1977                synchronized (this) {
1978                    if (shutdown) {
1979                        ShutdownThread.shutdown(mContext, confirm);
1980                    } else {
1981                        ShutdownThread.reboot(mContext, reason, confirm);
1982                    }
1983                }
1984            }
1985        };
1986
1987        // ShutdownThread must run on a looper capable of displaying the UI.
1988        Message msg = Message.obtain(mHandler, runnable);
1989        msg.setAsynchronous(true);
1990        mHandler.sendMessage(msg);
1991
1992        // PowerManager.reboot() is documented not to return so just wait for the inevitable.
1993        if (wait) {
1994            synchronized (runnable) {
1995                while (true) {
1996                    try {
1997                        runnable.wait();
1998                    } catch (InterruptedException e) {
1999                    }
2000                }
2001            }
2002        }
2003    }
2004
2005    private void crashInternal(final String message) {
2006        Thread t = new Thread("PowerManagerService.crash()") {
2007            @Override
2008            public void run() {
2009                throw new RuntimeException(message);
2010            }
2011        };
2012        try {
2013            t.start();
2014            t.join();
2015        } catch (InterruptedException e) {
2016            Log.wtf(TAG, e);
2017        }
2018    }
2019
2020    private void setStayOnSettingInternal(int val) {
2021        Settings.Global.putInt(mContext.getContentResolver(),
2022                Settings.Global.STAY_ON_WHILE_PLUGGED_IN, val);
2023    }
2024
2025    private void setMaximumScreenOffTimeoutFromDeviceAdminInternal(int timeMs) {
2026        synchronized (mLock) {
2027            mMaximumScreenOffTimeoutFromDeviceAdmin = timeMs;
2028            mDirty |= DIRTY_SETTINGS;
2029            updatePowerStateLocked();
2030        }
2031    }
2032
2033    private boolean isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked() {
2034        return mMaximumScreenOffTimeoutFromDeviceAdmin >= 0
2035                && mMaximumScreenOffTimeoutFromDeviceAdmin < Integer.MAX_VALUE;
2036    }
2037
2038    private void setAttentionLightInternal(boolean on, int color) {
2039        Light light;
2040        synchronized (mLock) {
2041            if (!mSystemReady) {
2042                return;
2043            }
2044            light = mAttentionLight;
2045        }
2046
2047        // Control light outside of lock.
2048        light.setFlashing(color, Light.LIGHT_FLASH_HARDWARE, (on ? 3 : 0), 0);
2049    }
2050
2051    private void setScreenBrightnessOverrideFromWindowManagerInternal(int brightness) {
2052        synchronized (mLock) {
2053            if (mScreenBrightnessOverrideFromWindowManager != brightness) {
2054                mScreenBrightnessOverrideFromWindowManager = brightness;
2055                mDirty |= DIRTY_SETTINGS;
2056                updatePowerStateLocked();
2057            }
2058        }
2059    }
2060
2061    private void setUserActivityTimeoutOverrideFromWindowManagerInternal(long timeoutMillis) {
2062        synchronized (mLock) {
2063            if (mUserActivityTimeoutOverrideFromWindowManager != timeoutMillis) {
2064                mUserActivityTimeoutOverrideFromWindowManager = timeoutMillis;
2065                mDirty |= DIRTY_SETTINGS;
2066                updatePowerStateLocked();
2067            }
2068        }
2069    }
2070
2071    private void setTemporaryScreenBrightnessSettingOverrideInternal(int brightness) {
2072        synchronized (mLock) {
2073            if (mTemporaryScreenBrightnessSettingOverride != brightness) {
2074                mTemporaryScreenBrightnessSettingOverride = brightness;
2075                mDirty |= DIRTY_SETTINGS;
2076                updatePowerStateLocked();
2077            }
2078        }
2079    }
2080
2081    private void setTemporaryScreenAutoBrightnessAdjustmentSettingOverrideInternal(float adj) {
2082        synchronized (mLock) {
2083            // Note: This condition handles NaN because NaN is not equal to any other
2084            // value, including itself.
2085            if (mTemporaryScreenAutoBrightnessAdjustmentSettingOverride != adj) {
2086                mTemporaryScreenAutoBrightnessAdjustmentSettingOverride = adj;
2087                mDirty |= DIRTY_SETTINGS;
2088                updatePowerStateLocked();
2089            }
2090        }
2091    }
2092
2093    private void powerHintInternal(int hintId, int data) {
2094        nativeSendPowerHint(hintId, data);
2095    }
2096
2097    /**
2098     * Low-level function turn the device off immediately, without trying
2099     * to be clean.  Most people should use {@link ShutdownThread} for a clean shutdown.
2100     */
2101    public static void lowLevelShutdown() {
2102        SystemProperties.set("sys.powerctl", "shutdown");
2103    }
2104
2105    /**
2106     * Low-level function to reboot the device. On success, this
2107     * function doesn't return. If more than 20 seconds passes from
2108     * the time a reboot is requested (120 seconds for reboot to
2109     * recovery), this method returns.
2110     *
2111     * @param reason code to pass to the kernel (e.g. "recovery"), or null.
2112     */
2113    public static void lowLevelReboot(String reason) {
2114        if (reason == null) {
2115            reason = "";
2116        }
2117        long duration;
2118        if (reason.equals(PowerManager.REBOOT_RECOVERY)) {
2119            // If we are rebooting to go into recovery, instead of
2120            // setting sys.powerctl directly we'll start the
2121            // pre-recovery service which will do some preparation for
2122            // recovery and then reboot for us.
2123            //
2124            // This preparation can take more than 20 seconds if
2125            // there's a very large update package, so lengthen the
2126            // timeout.
2127            SystemProperties.set("ctl.start", "pre-recovery");
2128            duration = 120 * 1000L;
2129        } else {
2130            SystemProperties.set("sys.powerctl", "reboot," + reason);
2131            duration = 20 * 1000L;
2132        }
2133        try {
2134            Thread.sleep(duration);
2135        } catch (InterruptedException e) {
2136            Thread.currentThread().interrupt();
2137        }
2138    }
2139
2140    @Override // Watchdog.Monitor implementation
2141    public void monitor() {
2142        // Grab and release lock for watchdog monitor to detect deadlocks.
2143        synchronized (mLock) {
2144        }
2145    }
2146
2147    private void dumpInternal(PrintWriter pw) {
2148        pw.println("POWER MANAGER (dumpsys power)\n");
2149
2150        final WirelessChargerDetector wcd;
2151        synchronized (mLock) {
2152            pw.println("Power Manager State:");
2153            pw.println("  mDirty=0x" + Integer.toHexString(mDirty));
2154            pw.println("  mWakefulness=" + wakefulnessToString(mWakefulness));
2155            pw.println("  mInteractive=" + mInteractive);
2156            pw.println("  mIsPowered=" + mIsPowered);
2157            pw.println("  mPlugType=" + mPlugType);
2158            pw.println("  mBatteryLevel=" + mBatteryLevel);
2159            pw.println("  mBatteryLevelWhenDreamStarted=" + mBatteryLevelWhenDreamStarted);
2160            pw.println("  mDockState=" + mDockState);
2161            pw.println("  mStayOn=" + mStayOn);
2162            pw.println("  mProximityPositive=" + mProximityPositive);
2163            pw.println("  mBootCompleted=" + mBootCompleted);
2164            pw.println("  mSystemReady=" + mSystemReady);
2165            pw.println("  mHalAutoSuspendModeEnabled=" + mHalAutoSuspendModeEnabled);
2166            pw.println("  mHalInteractiveModeEnabled=" + mHalInteractiveModeEnabled);
2167            pw.println("  mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary));
2168            pw.println("  mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary));
2169            pw.println("  mRequestWaitForNegativeProximity=" + mRequestWaitForNegativeProximity);
2170            pw.println("  mSandmanScheduled=" + mSandmanScheduled);
2171            pw.println("  mSandmanSummoned=" + mSandmanSummoned);
2172            pw.println("  mLowPowerModeEnabled=" + mLowPowerModeEnabled);
2173            pw.println("  mBatteryLevelLow=" + mBatteryLevelLow);
2174            pw.println("  mLastWakeTime=" + TimeUtils.formatUptime(mLastWakeTime));
2175            pw.println("  mLastSleepTime=" + TimeUtils.formatUptime(mLastSleepTime));
2176            pw.println("  mLastUserActivityTime=" + TimeUtils.formatUptime(mLastUserActivityTime));
2177            pw.println("  mLastUserActivityTimeNoChangeLights="
2178                    + TimeUtils.formatUptime(mLastUserActivityTimeNoChangeLights));
2179            pw.println("  mDisplayReady=" + mDisplayReady);
2180            pw.println("  mHoldingWakeLockSuspendBlocker=" + mHoldingWakeLockSuspendBlocker);
2181            pw.println("  mHoldingDisplaySuspendBlocker=" + mHoldingDisplaySuspendBlocker);
2182
2183            pw.println();
2184            pw.println("Settings and Configuration:");
2185            pw.println("  mDecoupleHalAutoSuspendModeFromDisplayConfig="
2186                    + mDecoupleHalAutoSuspendModeFromDisplayConfig);
2187            pw.println("  mDecoupleHalInteractiveModeFromDisplayConfig="
2188                    + mDecoupleHalInteractiveModeFromDisplayConfig);
2189            pw.println("  mWakeUpWhenPluggedOrUnpluggedConfig="
2190                    + mWakeUpWhenPluggedOrUnpluggedConfig);
2191            pw.println("  mSuspendWhenScreenOffDueToProximityConfig="
2192                    + mSuspendWhenScreenOffDueToProximityConfig);
2193            pw.println("  mDreamsSupportedConfig=" + mDreamsSupportedConfig);
2194            pw.println("  mDreamsEnabledByDefaultConfig=" + mDreamsEnabledByDefaultConfig);
2195            pw.println("  mDreamsActivatedOnSleepByDefaultConfig="
2196                    + mDreamsActivatedOnSleepByDefaultConfig);
2197            pw.println("  mDreamsActivatedOnDockByDefaultConfig="
2198                    + mDreamsActivatedOnDockByDefaultConfig);
2199            pw.println("  mDreamsEnabledOnBatteryConfig="
2200                    + mDreamsEnabledOnBatteryConfig);
2201            pw.println("  mDreamsBatteryLevelMinimumWhenPoweredConfig="
2202                    + mDreamsBatteryLevelMinimumWhenPoweredConfig);
2203            pw.println("  mDreamsBatteryLevelMinimumWhenNotPoweredConfig="
2204                    + mDreamsBatteryLevelMinimumWhenNotPoweredConfig);
2205            pw.println("  mDreamsBatteryLevelDrainCutoffConfig="
2206                    + mDreamsBatteryLevelDrainCutoffConfig);
2207            pw.println("  mDreamsEnabledSetting=" + mDreamsEnabledSetting);
2208            pw.println("  mDreamsActivateOnSleepSetting=" + mDreamsActivateOnSleepSetting);
2209            pw.println("  mDreamsActivateOnDockSetting=" + mDreamsActivateOnDockSetting);
2210            pw.println("  mLowPowerModeSetting=" + mLowPowerModeSetting);
2211            pw.println("  mAutoLowPowerModeEnabled=" + mAutoLowPowerModeEnabled);
2212            pw.println("  mMinimumScreenOffTimeoutConfig=" + mMinimumScreenOffTimeoutConfig);
2213            pw.println("  mMaximumScreenDimDurationConfig=" + mMaximumScreenDimDurationConfig);
2214            pw.println("  mMaximumScreenDimRatioConfig=" + mMaximumScreenDimRatioConfig);
2215            pw.println("  mScreenOffTimeoutSetting=" + mScreenOffTimeoutSetting);
2216            pw.println("  mMaximumScreenOffTimeoutFromDeviceAdmin="
2217                    + mMaximumScreenOffTimeoutFromDeviceAdmin + " (enforced="
2218                    + isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked() + ")");
2219            pw.println("  mStayOnWhilePluggedInSetting=" + mStayOnWhilePluggedInSetting);
2220            pw.println("  mScreenBrightnessSetting=" + mScreenBrightnessSetting);
2221            pw.println("  mScreenAutoBrightnessAdjustmentSetting="
2222                    + mScreenAutoBrightnessAdjustmentSetting);
2223            pw.println("  mScreenBrightnessModeSetting=" + mScreenBrightnessModeSetting);
2224            pw.println("  mScreenBrightnessOverrideFromWindowManager="
2225                    + mScreenBrightnessOverrideFromWindowManager);
2226            pw.println("  mUserActivityTimeoutOverrideFromWindowManager="
2227                    + mUserActivityTimeoutOverrideFromWindowManager);
2228            pw.println("  mTemporaryScreenBrightnessSettingOverride="
2229                    + mTemporaryScreenBrightnessSettingOverride);
2230            pw.println("  mTemporaryScreenAutoBrightnessAdjustmentSettingOverride="
2231                    + mTemporaryScreenAutoBrightnessAdjustmentSettingOverride);
2232            pw.println("  mScreenBrightnessSettingMinimum=" + mScreenBrightnessSettingMinimum);
2233            pw.println("  mScreenBrightnessSettingMaximum=" + mScreenBrightnessSettingMaximum);
2234            pw.println("  mScreenBrightnessSettingDefault=" + mScreenBrightnessSettingDefault);
2235
2236            final int screenOffTimeout = getScreenOffTimeoutLocked();
2237            final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
2238            pw.println();
2239            pw.println("Screen off timeout: " + screenOffTimeout + " ms");
2240            pw.println("Screen dim duration: " + screenDimDuration + " ms");
2241
2242            pw.println();
2243            pw.println("Wake Locks: size=" + mWakeLocks.size());
2244            for (WakeLock wl : mWakeLocks) {
2245                pw.println("  " + wl);
2246            }
2247
2248            pw.println();
2249            pw.println("Suspend Blockers: size=" + mSuspendBlockers.size());
2250            for (SuspendBlocker sb : mSuspendBlockers) {
2251                pw.println("  " + sb);
2252            }
2253
2254            pw.println();
2255            pw.println("Screen On Blocker: " + mScreenOnBlocker);
2256
2257            pw.println();
2258            pw.println("Display Power: " + mDisplayPowerCallbacks);
2259
2260            wcd = mWirelessChargerDetector;
2261        }
2262
2263        if (wcd != null) {
2264            wcd.dump(pw);
2265        }
2266    }
2267
2268    private SuspendBlocker createSuspendBlockerLocked(String name) {
2269        SuspendBlocker suspendBlocker = new SuspendBlockerImpl(name);
2270        mSuspendBlockers.add(suspendBlocker);
2271        return suspendBlocker;
2272    }
2273
2274    private static String wakefulnessToString(int wakefulness) {
2275        switch (wakefulness) {
2276            case WAKEFULNESS_ASLEEP:
2277                return "Asleep";
2278            case WAKEFULNESS_AWAKE:
2279                return "Awake";
2280            case WAKEFULNESS_DREAMING:
2281                return "Dreaming";
2282            case WAKEFULNESS_DOZING:
2283                return "Dozing";
2284            default:
2285                return Integer.toString(wakefulness);
2286        }
2287    }
2288
2289    private static WorkSource copyWorkSource(WorkSource workSource) {
2290        return workSource != null ? new WorkSource(workSource) : null;
2291    }
2292
2293    private final class BatteryReceiver extends BroadcastReceiver {
2294        @Override
2295        public void onReceive(Context context, Intent intent) {
2296            synchronized (mLock) {
2297                handleBatteryStateChangedLocked();
2298            }
2299        }
2300    }
2301
2302    private final class BootCompletedReceiver extends BroadcastReceiver {
2303        @Override
2304        public void onReceive(Context context, Intent intent) {
2305            // This is our early signal that the system thinks it has finished booting.
2306            // However, the boot animation may still be running for a few more seconds
2307            // since it is ultimately in charge of when it terminates.
2308            // Defer transitioning into the boot completed state until the animation exits.
2309            // We do this so that the screen does not start to dim prematurely before
2310            // the user has actually had a chance to interact with the device.
2311            startWatchingForBootAnimationFinished();
2312        }
2313    }
2314
2315    private final class DreamReceiver extends BroadcastReceiver {
2316        @Override
2317        public void onReceive(Context context, Intent intent) {
2318            synchronized (mLock) {
2319                scheduleSandmanLocked();
2320            }
2321        }
2322    }
2323
2324    private final class UserSwitchedReceiver extends BroadcastReceiver {
2325        @Override
2326        public void onReceive(Context context, Intent intent) {
2327            synchronized (mLock) {
2328                handleSettingsChangedLocked();
2329            }
2330        }
2331    }
2332
2333    private final class DockReceiver extends BroadcastReceiver {
2334        @Override
2335        public void onReceive(Context context, Intent intent) {
2336            synchronized (mLock) {
2337                int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
2338                        Intent.EXTRA_DOCK_STATE_UNDOCKED);
2339                if (mDockState != dockState) {
2340                    mDockState = dockState;
2341                    mDirty |= DIRTY_DOCK_STATE;
2342                    updatePowerStateLocked();
2343                }
2344            }
2345        }
2346    }
2347
2348    private final class SettingsObserver extends ContentObserver {
2349        public SettingsObserver(Handler handler) {
2350            super(handler);
2351        }
2352
2353        @Override
2354        public void onChange(boolean selfChange, Uri uri) {
2355            synchronized (mLock) {
2356                handleSettingsChangedLocked();
2357            }
2358        }
2359    }
2360
2361    /**
2362     * Handler for asynchronous operations performed by the power manager.
2363     */
2364    private final class PowerManagerHandler extends Handler {
2365        public PowerManagerHandler(Looper looper) {
2366            super(looper, null, true /*async*/);
2367        }
2368
2369        @Override
2370        public void handleMessage(Message msg) {
2371            switch (msg.what) {
2372                case MSG_USER_ACTIVITY_TIMEOUT:
2373                    handleUserActivityTimeout();
2374                    break;
2375                case MSG_SANDMAN:
2376                    handleSandman();
2377                    break;
2378                case MSG_SCREEN_ON_BLOCKER_RELEASED:
2379                    handleScreenOnBlockerReleased();
2380                    break;
2381                case MSG_CHECK_IF_BOOT_ANIMATION_FINISHED:
2382                    checkIfBootAnimationFinished();
2383                    break;
2384            }
2385        }
2386    }
2387
2388    /**
2389     * Represents a wake lock that has been acquired by an application.
2390     */
2391    private final class WakeLock implements IBinder.DeathRecipient {
2392        public final IBinder mLock;
2393        public int mFlags;
2394        public String mTag;
2395        public final String mPackageName;
2396        public WorkSource mWorkSource;
2397        public String mHistoryTag;
2398        public final int mOwnerUid;
2399        public final int mOwnerPid;
2400        public boolean mNotifiedAcquired;
2401
2402        public WakeLock(IBinder lock, int flags, String tag, String packageName,
2403                WorkSource workSource, String historyTag, int ownerUid, int ownerPid) {
2404            mLock = lock;
2405            mFlags = flags;
2406            mTag = tag;
2407            mPackageName = packageName;
2408            mWorkSource = copyWorkSource(workSource);
2409            mHistoryTag = historyTag;
2410            mOwnerUid = ownerUid;
2411            mOwnerPid = ownerPid;
2412        }
2413
2414        @Override
2415        public void binderDied() {
2416            PowerManagerService.this.handleWakeLockDeath(this);
2417        }
2418
2419        public boolean hasSameProperties(int flags, String tag, WorkSource workSource,
2420                int ownerUid, int ownerPid) {
2421            return mFlags == flags
2422                    && mTag.equals(tag)
2423                    && hasSameWorkSource(workSource)
2424                    && mOwnerUid == ownerUid
2425                    && mOwnerPid == ownerPid;
2426        }
2427
2428        public void updateProperties(int flags, String tag, String packageName,
2429                WorkSource workSource, String historyTag, int ownerUid, int ownerPid) {
2430            if (!mPackageName.equals(packageName)) {
2431                throw new IllegalStateException("Existing wake lock package name changed: "
2432                        + mPackageName + " to " + packageName);
2433            }
2434            if (mOwnerUid != ownerUid) {
2435                throw new IllegalStateException("Existing wake lock uid changed: "
2436                        + mOwnerUid + " to " + ownerUid);
2437            }
2438            if (mOwnerPid != ownerPid) {
2439                throw new IllegalStateException("Existing wake lock pid changed: "
2440                        + mOwnerPid + " to " + ownerPid);
2441            }
2442            mFlags = flags;
2443            mTag = tag;
2444            updateWorkSource(workSource);
2445            mHistoryTag = historyTag;
2446        }
2447
2448        public boolean hasSameWorkSource(WorkSource workSource) {
2449            return Objects.equal(mWorkSource, workSource);
2450        }
2451
2452        public void updateWorkSource(WorkSource workSource) {
2453            mWorkSource = copyWorkSource(workSource);
2454        }
2455
2456        @Override
2457        public String toString() {
2458            return getLockLevelString()
2459                    + " '" + mTag + "'" + getLockFlagsString()
2460                    + " (uid=" + mOwnerUid + ", pid=" + mOwnerPid + ", ws=" + mWorkSource + ")";
2461        }
2462
2463        @SuppressWarnings("deprecation")
2464        private String getLockLevelString() {
2465            switch (mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
2466                case PowerManager.FULL_WAKE_LOCK:
2467                    return "FULL_WAKE_LOCK                ";
2468                case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
2469                    return "SCREEN_BRIGHT_WAKE_LOCK       ";
2470                case PowerManager.SCREEN_DIM_WAKE_LOCK:
2471                    return "SCREEN_DIM_WAKE_LOCK          ";
2472                case PowerManager.PARTIAL_WAKE_LOCK:
2473                    return "PARTIAL_WAKE_LOCK             ";
2474                case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
2475                    return "PROXIMITY_SCREEN_OFF_WAKE_LOCK";
2476                case PowerManager.DOZE_WAKE_LOCK:
2477                    return "DOZE_WAKE_LOCK                ";
2478                default:
2479                    return "???                           ";
2480            }
2481        }
2482
2483        private String getLockFlagsString() {
2484            String result = "";
2485            if ((mFlags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {
2486                result += " ACQUIRE_CAUSES_WAKEUP";
2487            }
2488            if ((mFlags & PowerManager.ON_AFTER_RELEASE) != 0) {
2489                result += " ON_AFTER_RELEASE";
2490            }
2491            return result;
2492        }
2493    }
2494
2495    private final class SuspendBlockerImpl implements SuspendBlocker {
2496        private final String mName;
2497        private int mReferenceCount;
2498
2499        public SuspendBlockerImpl(String name) {
2500            mName = name;
2501        }
2502
2503        @Override
2504        protected void finalize() throws Throwable {
2505            try {
2506                if (mReferenceCount != 0) {
2507                    Log.wtf(TAG, "Suspend blocker \"" + mName
2508                            + "\" was finalized without being released!");
2509                    mReferenceCount = 0;
2510                    nativeReleaseSuspendBlocker(mName);
2511                }
2512            } finally {
2513                super.finalize();
2514            }
2515        }
2516
2517        @Override
2518        public void acquire() {
2519            synchronized (this) {
2520                mReferenceCount += 1;
2521                if (mReferenceCount == 1) {
2522                    if (DEBUG_SPEW) {
2523                        Slog.d(TAG, "Acquiring suspend blocker \"" + mName + "\".");
2524                    }
2525                    nativeAcquireSuspendBlocker(mName);
2526                }
2527            }
2528        }
2529
2530        @Override
2531        public void release() {
2532            synchronized (this) {
2533                mReferenceCount -= 1;
2534                if (mReferenceCount == 0) {
2535                    if (DEBUG_SPEW) {
2536                        Slog.d(TAG, "Releasing suspend blocker \"" + mName + "\".");
2537                    }
2538                    nativeReleaseSuspendBlocker(mName);
2539                } else if (mReferenceCount < 0) {
2540                    Log.wtf(TAG, "Suspend blocker \"" + mName
2541                            + "\" was released without being acquired!", new Throwable());
2542                    mReferenceCount = 0;
2543                }
2544            }
2545        }
2546
2547        @Override
2548        public String toString() {
2549            synchronized (this) {
2550                return mName + ": ref count=" + mReferenceCount;
2551            }
2552        }
2553    }
2554
2555    private final class ScreenOnBlockerImpl implements ScreenOnBlocker {
2556        private int mNestCount;
2557
2558        public boolean isHeld() {
2559            synchronized (this) {
2560                return mNestCount != 0;
2561            }
2562        }
2563
2564        @Override
2565        public void acquire() {
2566            synchronized (this) {
2567                mNestCount += 1;
2568                if (DEBUG) {
2569                    Slog.d(TAG, "Screen on blocked: mNestCount=" + mNestCount);
2570                }
2571            }
2572        }
2573
2574        @Override
2575        public void release() {
2576            synchronized (this) {
2577                mNestCount -= 1;
2578                if (mNestCount < 0) {
2579                    Log.wtf(TAG, "Screen on blocker was released without being acquired!",
2580                            new Throwable());
2581                    mNestCount = 0;
2582                }
2583                if (mNestCount == 0) {
2584                    mHandler.sendEmptyMessage(MSG_SCREEN_ON_BLOCKER_RELEASED);
2585                }
2586                if (DEBUG) {
2587                    Slog.d(TAG, "Screen on unblocked: mNestCount=" + mNestCount);
2588                }
2589            }
2590        }
2591
2592        @Override
2593        public String toString() {
2594            synchronized (this) {
2595                return "held=" + (mNestCount != 0) + ", mNestCount=" + mNestCount;
2596            }
2597        }
2598    }
2599
2600    private final class BinderService extends IPowerManager.Stub {
2601        @Override // Binder call
2602        public void acquireWakeLockWithUid(IBinder lock, int flags, String tag,
2603                String packageName, int uid) {
2604            if (uid < 0) {
2605                uid = Binder.getCallingUid();
2606            }
2607            acquireWakeLock(lock, flags, tag, packageName, new WorkSource(uid), null);
2608        }
2609
2610        @Override // Binder call
2611        public void powerHint(int hintId, int data) {
2612            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
2613            powerHintInternal(hintId, data);
2614        }
2615
2616        @Override // Binder call
2617        public void acquireWakeLock(IBinder lock, int flags, String tag, String packageName,
2618                WorkSource ws, String historyTag) {
2619            if (lock == null) {
2620                throw new IllegalArgumentException("lock must not be null");
2621            }
2622            if (packageName == null) {
2623                throw new IllegalArgumentException("packageName must not be null");
2624            }
2625            PowerManager.validateWakeLockParameters(flags, tag);
2626
2627            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
2628            if (ws != null && ws.size() != 0) {
2629                mContext.enforceCallingOrSelfPermission(
2630                        android.Manifest.permission.UPDATE_DEVICE_STATS, null);
2631            } else {
2632                ws = null;
2633            }
2634
2635            final int uid = Binder.getCallingUid();
2636            final int pid = Binder.getCallingPid();
2637            final long ident = Binder.clearCallingIdentity();
2638            try {
2639                acquireWakeLockInternal(lock, flags, tag, packageName, ws, historyTag, uid, pid);
2640            } finally {
2641                Binder.restoreCallingIdentity(ident);
2642            }
2643        }
2644
2645        @Override // Binder call
2646        public void releaseWakeLock(IBinder lock, int flags) {
2647            if (lock == null) {
2648                throw new IllegalArgumentException("lock must not be null");
2649            }
2650
2651            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
2652
2653            final long ident = Binder.clearCallingIdentity();
2654            try {
2655                releaseWakeLockInternal(lock, flags);
2656            } finally {
2657                Binder.restoreCallingIdentity(ident);
2658            }
2659        }
2660
2661        @Override // Binder call
2662        public void updateWakeLockUids(IBinder lock, int[] uids) {
2663            WorkSource ws = null;
2664
2665            if (uids != null) {
2666                ws = new WorkSource();
2667                // XXX should WorkSource have a way to set uids as an int[] instead of adding them
2668                // one at a time?
2669                for (int i = 0; i < uids.length; i++) {
2670                    ws.add(uids[i]);
2671                }
2672            }
2673            updateWakeLockWorkSource(lock, ws, null);
2674        }
2675
2676        @Override // Binder call
2677        public void updateWakeLockWorkSource(IBinder lock, WorkSource ws, String historyTag) {
2678            if (lock == null) {
2679                throw new IllegalArgumentException("lock must not be null");
2680            }
2681
2682            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
2683            if (ws != null && ws.size() != 0) {
2684                mContext.enforceCallingOrSelfPermission(
2685                        android.Manifest.permission.UPDATE_DEVICE_STATS, null);
2686            } else {
2687                ws = null;
2688            }
2689
2690            final long ident = Binder.clearCallingIdentity();
2691            try {
2692                updateWakeLockWorkSourceInternal(lock, ws, historyTag);
2693            } finally {
2694                Binder.restoreCallingIdentity(ident);
2695            }
2696        }
2697
2698        @Override // Binder call
2699        public boolean isWakeLockLevelSupported(int level) {
2700            final long ident = Binder.clearCallingIdentity();
2701            try {
2702                return isWakeLockLevelSupportedInternal(level);
2703            } finally {
2704                Binder.restoreCallingIdentity(ident);
2705            }
2706        }
2707
2708        @Override // Binder call
2709        public void userActivity(long eventTime, int event, int flags) {
2710            final long now = SystemClock.uptimeMillis();
2711            if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER)
2712                    != PackageManager.PERMISSION_GRANTED) {
2713                // Once upon a time applications could call userActivity().
2714                // Now we require the DEVICE_POWER permission.  Log a warning and ignore the
2715                // request instead of throwing a SecurityException so we don't break old apps.
2716                synchronized (mLock) {
2717                    if (now >= mLastWarningAboutUserActivityPermission + (5 * 60 * 1000)) {
2718                        mLastWarningAboutUserActivityPermission = now;
2719                        Slog.w(TAG, "Ignoring call to PowerManager.userActivity() because the "
2720                                + "caller does not have DEVICE_POWER permission.  "
2721                                + "Please fix your app!  "
2722                                + " pid=" + Binder.getCallingPid()
2723                                + " uid=" + Binder.getCallingUid());
2724                    }
2725                }
2726                return;
2727            }
2728
2729            if (eventTime > SystemClock.uptimeMillis()) {
2730                throw new IllegalArgumentException("event time must not be in the future");
2731            }
2732
2733            final int uid = Binder.getCallingUid();
2734            final long ident = Binder.clearCallingIdentity();
2735            try {
2736                userActivityInternal(eventTime, event, flags, uid);
2737            } finally {
2738                Binder.restoreCallingIdentity(ident);
2739            }
2740        }
2741
2742        @Override // Binder call
2743        public void wakeUp(long eventTime) {
2744            if (eventTime > SystemClock.uptimeMillis()) {
2745                throw new IllegalArgumentException("event time must not be in the future");
2746            }
2747
2748            mContext.enforceCallingOrSelfPermission(
2749                    android.Manifest.permission.DEVICE_POWER, null);
2750
2751            final long ident = Binder.clearCallingIdentity();
2752            try {
2753                wakeUpInternal(eventTime);
2754            } finally {
2755                Binder.restoreCallingIdentity(ident);
2756            }
2757        }
2758
2759        @Override // Binder call
2760        public void goToSleep(long eventTime, int reason, int flags) {
2761            if (eventTime > SystemClock.uptimeMillis()) {
2762                throw new IllegalArgumentException("event time must not be in the future");
2763            }
2764
2765            mContext.enforceCallingOrSelfPermission(
2766                    android.Manifest.permission.DEVICE_POWER, null);
2767
2768            final long ident = Binder.clearCallingIdentity();
2769            try {
2770                goToSleepInternal(eventTime, reason, flags);
2771            } finally {
2772                Binder.restoreCallingIdentity(ident);
2773            }
2774        }
2775
2776        @Override // Binder call
2777        public void nap(long eventTime) {
2778            if (eventTime > SystemClock.uptimeMillis()) {
2779                throw new IllegalArgumentException("event time must not be in the future");
2780            }
2781
2782            mContext.enforceCallingOrSelfPermission(
2783                    android.Manifest.permission.DEVICE_POWER, null);
2784
2785            final long ident = Binder.clearCallingIdentity();
2786            try {
2787                napInternal(eventTime);
2788            } finally {
2789                Binder.restoreCallingIdentity(ident);
2790            }
2791        }
2792
2793        @Override // Binder call
2794        public boolean isInteractive() {
2795            final long ident = Binder.clearCallingIdentity();
2796            try {
2797                return isInteractiveInternal();
2798            } finally {
2799                Binder.restoreCallingIdentity(ident);
2800            }
2801        }
2802
2803        @Override // Binder call
2804        public boolean isPowerSaveMode() {
2805            final long ident = Binder.clearCallingIdentity();
2806            try {
2807                return isLowPowerModeInternal();
2808            } finally {
2809                Binder.restoreCallingIdentity(ident);
2810            }
2811        }
2812
2813        /**
2814         * Reboots the device.
2815         *
2816         * @param confirm If true, shows a reboot confirmation dialog.
2817         * @param reason The reason for the reboot, or null if none.
2818         * @param wait If true, this call waits for the reboot to complete and does not return.
2819         */
2820        @Override // Binder call
2821        public void reboot(boolean confirm, String reason, boolean wait) {
2822            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
2823            if (PowerManager.REBOOT_RECOVERY.equals(reason)) {
2824                mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY, null);
2825            }
2826
2827            final long ident = Binder.clearCallingIdentity();
2828            try {
2829                shutdownOrRebootInternal(false, confirm, reason, wait);
2830            } finally {
2831                Binder.restoreCallingIdentity(ident);
2832            }
2833        }
2834
2835        /**
2836         * Shuts down the device.
2837         *
2838         * @param confirm If true, shows a shutdown confirmation dialog.
2839         * @param wait If true, this call waits for the shutdown to complete and does not return.
2840         */
2841        @Override // Binder call
2842        public void shutdown(boolean confirm, boolean wait) {
2843            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
2844
2845            final long ident = Binder.clearCallingIdentity();
2846            try {
2847                shutdownOrRebootInternal(true, confirm, null, wait);
2848            } finally {
2849                Binder.restoreCallingIdentity(ident);
2850            }
2851        }
2852
2853        /**
2854         * Crash the runtime (causing a complete restart of the Android framework).
2855         * Requires REBOOT permission.  Mostly for testing.  Should not return.
2856         */
2857        @Override // Binder call
2858        public void crash(String message) {
2859            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
2860
2861            final long ident = Binder.clearCallingIdentity();
2862            try {
2863                crashInternal(message);
2864            } finally {
2865                Binder.restoreCallingIdentity(ident);
2866            }
2867        }
2868
2869        /**
2870         * Set the setting that determines whether the device stays on when plugged in.
2871         * The argument is a bit string, with each bit specifying a power source that,
2872         * when the device is connected to that source, causes the device to stay on.
2873         * See {@link android.os.BatteryManager} for the list of power sources that
2874         * can be specified. Current values include
2875         * {@link android.os.BatteryManager#BATTERY_PLUGGED_AC}
2876         * and {@link android.os.BatteryManager#BATTERY_PLUGGED_USB}
2877         *
2878         * Used by "adb shell svc power stayon ..."
2879         *
2880         * @param val an {@code int} containing the bits that specify which power sources
2881         * should cause the device to stay on.
2882         */
2883        @Override // Binder call
2884        public void setStayOnSetting(int val) {
2885            mContext.enforceCallingOrSelfPermission(
2886                    android.Manifest.permission.WRITE_SETTINGS, null);
2887
2888            final long ident = Binder.clearCallingIdentity();
2889            try {
2890                setStayOnSettingInternal(val);
2891            } finally {
2892                Binder.restoreCallingIdentity(ident);
2893            }
2894        }
2895
2896        /**
2897         * Used by device administration to set the maximum screen off timeout.
2898         *
2899         * This method must only be called by the device administration policy manager.
2900         */
2901        @Override // Binder call
2902        public void setMaximumScreenOffTimeoutFromDeviceAdmin(int timeMs) {
2903            final long ident = Binder.clearCallingIdentity();
2904            try {
2905                setMaximumScreenOffTimeoutFromDeviceAdminInternal(timeMs);
2906            } finally {
2907                Binder.restoreCallingIdentity(ident);
2908            }
2909        }
2910
2911        /**
2912         * Used by the settings application and brightness control widgets to
2913         * temporarily override the current screen brightness setting so that the
2914         * user can observe the effect of an intended settings change without applying
2915         * it immediately.
2916         *
2917         * The override will be canceled when the setting value is next updated.
2918         *
2919         * @param brightness The overridden brightness.
2920         *
2921         * @see android.provider.Settings.System#SCREEN_BRIGHTNESS
2922         */
2923        @Override // Binder call
2924        public void setTemporaryScreenBrightnessSettingOverride(int brightness) {
2925            mContext.enforceCallingOrSelfPermission(
2926                    android.Manifest.permission.DEVICE_POWER, null);
2927
2928            final long ident = Binder.clearCallingIdentity();
2929            try {
2930                setTemporaryScreenBrightnessSettingOverrideInternal(brightness);
2931            } finally {
2932                Binder.restoreCallingIdentity(ident);
2933            }
2934        }
2935
2936        /**
2937         * Used by the settings application and brightness control widgets to
2938         * temporarily override the current screen auto-brightness adjustment setting so that the
2939         * user can observe the effect of an intended settings change without applying
2940         * it immediately.
2941         *
2942         * The override will be canceled when the setting value is next updated.
2943         *
2944         * @param adj The overridden brightness, or Float.NaN to disable the override.
2945         *
2946         * @see android.provider.Settings.System#SCREEN_AUTO_BRIGHTNESS_ADJ
2947         */
2948        @Override // Binder call
2949        public void setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(float adj) {
2950            mContext.enforceCallingOrSelfPermission(
2951                    android.Manifest.permission.DEVICE_POWER, null);
2952
2953            final long ident = Binder.clearCallingIdentity();
2954            try {
2955                setTemporaryScreenAutoBrightnessAdjustmentSettingOverrideInternal(adj);
2956            } finally {
2957                Binder.restoreCallingIdentity(ident);
2958            }
2959        }
2960
2961        /**
2962         * Used by the phone application to make the attention LED flash when ringing.
2963         */
2964        @Override // Binder call
2965        public void setAttentionLight(boolean on, int color) {
2966            mContext.enforceCallingOrSelfPermission(
2967                    android.Manifest.permission.DEVICE_POWER, null);
2968
2969            final long ident = Binder.clearCallingIdentity();
2970            try {
2971                setAttentionLightInternal(on, color);
2972            } finally {
2973                Binder.restoreCallingIdentity(ident);
2974            }
2975        }
2976
2977        @Override // Binder call
2978        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2979            if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
2980                    != PackageManager.PERMISSION_GRANTED) {
2981                pw.println("Permission Denial: can't dump PowerManager from from pid="
2982                        + Binder.getCallingPid()
2983                        + ", uid=" + Binder.getCallingUid());
2984                return;
2985            }
2986
2987            final long ident = Binder.clearCallingIdentity();
2988            try {
2989                dumpInternal(pw);
2990            } finally {
2991                Binder.restoreCallingIdentity(ident);
2992            }
2993        }
2994    }
2995
2996    private final class LocalService extends PowerManagerInternal {
2997        /**
2998         * Used by the window manager to override the screen brightness based on the
2999         * current foreground activity.
3000         *
3001         * This method must only be called by the window manager.
3002         *
3003         * @param brightness The overridden brightness, or -1 to disable the override.
3004         */
3005        @Override
3006        public void setScreenBrightnessOverrideFromWindowManager(int brightness) {
3007            mContext.enforceCallingOrSelfPermission(
3008                    android.Manifest.permission.DEVICE_POWER, null);
3009
3010            final long ident = Binder.clearCallingIdentity();
3011            try {
3012                setScreenBrightnessOverrideFromWindowManagerInternal(brightness);
3013            } finally {
3014                Binder.restoreCallingIdentity(ident);
3015            }
3016        }
3017
3018        /**
3019         * Used by the window manager to override the button brightness based on the
3020         * current foreground activity.
3021         *
3022         * This method must only be called by the window manager.
3023         *
3024         * @param brightness The overridden brightness, or -1 to disable the override.
3025         */
3026        @Override
3027        public void setButtonBrightnessOverrideFromWindowManager(int brightness) {
3028            // Do nothing.
3029            // Button lights are not currently supported in the new implementation.
3030            mContext.enforceCallingOrSelfPermission(
3031                    android.Manifest.permission.DEVICE_POWER, null);
3032        }
3033
3034        /**
3035         * Used by the window manager to override the user activity timeout based on the
3036         * current foreground activity.  It can only be used to make the timeout shorter
3037         * than usual, not longer.
3038         *
3039         * This method must only be called by the window manager.
3040         *
3041         * @param timeoutMillis The overridden timeout, or -1 to disable the override.
3042         */
3043        @Override
3044        public void setUserActivityTimeoutOverrideFromWindowManager(long timeoutMillis) {
3045            mContext.enforceCallingOrSelfPermission(
3046                    android.Manifest.permission.DEVICE_POWER, null);
3047
3048            final long ident = Binder.clearCallingIdentity();
3049            try {
3050                setUserActivityTimeoutOverrideFromWindowManagerInternal(timeoutMillis);
3051            } finally {
3052                Binder.restoreCallingIdentity(ident);
3053            }
3054        }
3055
3056        @Override
3057        public boolean getLowPowerModeEnabled() {
3058            synchronized (mLock) {
3059                return mLowPowerModeEnabled;
3060            }
3061        }
3062
3063        @Override
3064        public void registerLowPowerModeObserver(LowPowerModeListener listener) {
3065            synchronized (mLock) {
3066                mLowPowerModeListeners.add(listener);
3067            }
3068        }
3069    }
3070}
3071