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