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