blob: abbae5bb0ad97d44d6b4efb4f7fc0d736190f14b [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
Jeff Brown4f8ecd82012-06-18 18:29:13 -070017package com.android.server.power;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018
19import com.android.internal.app.IBatteryStats;
Jeff Brown4f8ecd82012-06-18 18:29:13 -070020import com.android.server.BatteryService;
21import com.android.server.EventLogTags;
22import com.android.server.LightsService;
Jeff Brownaa202a62012-08-21 22:14:26 -070023import com.android.server.TwilightService;
Jeff Brown4f8ecd82012-06-18 18:29:13 -070024import com.android.server.Watchdog;
Jeff Brown96307042012-07-27 15:51:34 -070025import com.android.server.am.ActivityManagerService;
Jeff Brownfa25bf52012-07-23 19:26:30 -070026import com.android.server.display.DisplayManagerService;
Jeff Brown62c82e42012-09-26 01:30:41 -070027import com.android.server.dreams.DreamManagerService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028
Jeff Brown96307042012-07-27 15:51:34 -070029import android.Manifest;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.content.BroadcastReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import android.content.ContentResolver;
32import android.content.Context;
33import android.content.Intent;
34import android.content.IntentFilter;
35import android.content.pm.PackageManager;
Mike Lockwoodd7786b42009-10-15 17:09:16 -070036import android.content.res.Resources;
Doug Zongker43866e02010-01-07 12:09:54 -080037import android.database.ContentObserver;
Jeff Brown96307042012-07-27 15:51:34 -070038import android.net.Uri;
Amith Yamasani8b619832010-09-22 16:11:59 -070039import android.os.BatteryManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import android.os.Binder;
41import android.os.Handler;
42import android.os.HandlerThread;
43import android.os.IBinder;
44import android.os.IPowerManager;
Jeff Brown96307042012-07-27 15:51:34 -070045import android.os.Looper;
Jim Miller92e66dd2012-02-21 18:57:12 -080046import android.os.Message;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047import android.os.PowerManager;
48import android.os.Process;
49import android.os.RemoteException;
50import android.os.SystemClock;
Jeff Brownd4935962012-09-25 13:27:20 -070051import android.os.UserHandle;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070052import android.os.WorkSource;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053import android.provider.Settings;
54import android.util.EventLog;
55import android.util.Log;
Joe Onorato8a9b2202010-02-26 18:56:32 -080056import android.util.Slog;
Jeff Brown96307042012-07-27 15:51:34 -070057import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058import android.view.WindowManagerPolicy;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059
60import java.io.FileDescriptor;
Jeff Brown7304c342012-05-11 18:42:42 -070061import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062import java.io.PrintWriter;
63import java.util.ArrayList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064
Jeff Brown96307042012-07-27 15:51:34 -070065import libcore.util.Objects;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066
Jeff Brown96307042012-07-27 15:51:34 -070067/**
68 * The power manager service is responsible for coordinating power management
69 * functions on the device.
70 */
71public final class PowerManagerService extends IPowerManager.Stub
72 implements Watchdog.Monitor {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073 private static final String TAG = "PowerManagerService";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074
Jeff Brown88c997a2012-06-22 13:57:45 -070075 private static final boolean DEBUG = false;
Jeff Brown96307042012-07-27 15:51:34 -070076 private static final boolean DEBUG_SPEW = DEBUG && true;
Jeff Brown88c997a2012-06-22 13:57:45 -070077
Jeff Brown96307042012-07-27 15:51:34 -070078 // Message: Sent when a user activity timeout occurs to update the power state.
79 private static final int MSG_USER_ACTIVITY_TIMEOUT = 1;
80 // Message: Sent when the device enters or exits a napping or dreaming state.
81 private static final int MSG_SANDMAN = 2;
Jeff Brownc38c9be2012-10-04 13:16:19 -070082 // Message: Sent when the screen on blocker is released.
83 private static final int MSG_SCREEN_ON_BLOCKER_RELEASED = 3;
Jeff Brown7304c342012-05-11 18:42:42 -070084
Jeff Brown96307042012-07-27 15:51:34 -070085 // Dirty bit: mWakeLocks changed
86 private static final int DIRTY_WAKE_LOCKS = 1 << 0;
87 // Dirty bit: mWakefulness changed
88 private static final int DIRTY_WAKEFULNESS = 1 << 1;
89 // Dirty bit: user activity was poked or may have timed out
90 private static final int DIRTY_USER_ACTIVITY = 1 << 2;
91 // Dirty bit: actual display power state was updated asynchronously
92 private static final int DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED = 1 << 3;
93 // Dirty bit: mBootCompleted changed
94 private static final int DIRTY_BOOT_COMPLETED = 1 << 4;
95 // Dirty bit: settings changed
96 private static final int DIRTY_SETTINGS = 1 << 5;
97 // Dirty bit: mIsPowered changed
98 private static final int DIRTY_IS_POWERED = 1 << 6;
99 // Dirty bit: mStayOn changed
100 private static final int DIRTY_STAY_ON = 1 << 7;
101 // Dirty bit: battery state changed
102 private static final int DIRTY_BATTERY_STATE = 1 << 8;
Jeff Brown93cbbb22012-10-04 13:18:36 -0700103 // Dirty bit: proximity state changed
104 private static final int DIRTY_PROXIMITY_POSITIVE = 1 << 9;
Jeff Brownc38c9be2012-10-04 13:16:19 -0700105 // Dirty bit: screen on blocker state became held or unheld
106 private static final int DIRTY_SCREEN_ON_BLOCKER_RELEASED = 1 << 10;
Jeff Brown7304c342012-05-11 18:42:42 -0700107
Jeff Brown96307042012-07-27 15:51:34 -0700108 // Wakefulness: The device is asleep and can only be awoken by a call to wakeUp().
109 // The screen should be off or in the process of being turned off by the display controller.
110 private static final int WAKEFULNESS_ASLEEP = 0;
111 // Wakefulness: The device is fully awake. It can be put to sleep by a call to goToSleep().
Jeff Brown62c82e42012-09-26 01:30:41 -0700112 // When the user activity timeout expires, the device may start napping or go to sleep.
Jeff Brown96307042012-07-27 15:51:34 -0700113 private static final int WAKEFULNESS_AWAKE = 1;
114 // Wakefulness: The device is napping. It is deciding whether to dream or go to sleep
115 // but hasn't gotten around to it yet. It can be awoken by a call to wakeUp(), which
116 // ends the nap. User activity may brighten the screen but does not end the nap.
117 private static final int WAKEFULNESS_NAPPING = 2;
118 // Wakefulness: The device is dreaming. It can be awoken by a call to wakeUp(),
119 // which ends the dream. The device goes to sleep when goToSleep() is called, when
120 // the dream ends or when unplugged.
121 // User activity may brighten the screen but does not end the dream.
122 private static final int WAKEFULNESS_DREAMING = 3;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800123
Jeff Brown96307042012-07-27 15:51:34 -0700124 // Summarizes the state of all active wakelocks.
125 private static final int WAKE_LOCK_CPU = 1 << 0;
126 private static final int WAKE_LOCK_SCREEN_BRIGHT = 1 << 1;
127 private static final int WAKE_LOCK_SCREEN_DIM = 1 << 2;
128 private static final int WAKE_LOCK_BUTTON_BRIGHT = 1 << 3;
129 private static final int WAKE_LOCK_PROXIMITY_SCREEN_OFF = 1 << 4;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130
Jeff Brown96307042012-07-27 15:51:34 -0700131 // Summarizes the user activity state.
132 private static final int USER_ACTIVITY_SCREEN_BRIGHT = 1 << 0;
133 private static final int USER_ACTIVITY_SCREEN_DIM = 1 << 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134
Jeff Brown96307042012-07-27 15:51:34 -0700135 // Default and minimum screen off timeout in milliseconds.
136 private static final int DEFAULT_SCREEN_OFF_TIMEOUT = 15 * 1000;
137 private static final int MINIMUM_SCREEN_OFF_TIMEOUT = 10 * 1000;
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700138
Jeff Brownff532542012-10-02 21:18:04 -0700139 // The screen dim duration, in milliseconds.
Jeff Brown96307042012-07-27 15:51:34 -0700140 // This is subtracted from the end of the screen off timeout so the
141 // minimum screen off timeout should be longer than this.
142 private static final int SCREEN_DIM_DURATION = 7 * 1000;
Mathias Agopian47f1fe52011-11-08 17:18:41 -0800143
Jeff Brownff532542012-10-02 21:18:04 -0700144 // The maximum screen dim time expressed as a ratio relative to the screen
145 // off timeout. If the screen off timeout is very short then we want the
146 // dim timeout to also be quite short so that most of the time is spent on.
147 // Otherwise the user won't get much screen on time before dimming occurs.
148 private static final float MAXIMUM_SCREEN_DIM_RATIO = 0.2f;
149
Jeff Brownf3fb8952012-10-02 20:57:05 -0700150 // Upper bound on the battery charge percentage in order to consider turning
151 // the screen on when the device starts charging wirelessly.
152 // See point of use for more details.
153 private static final int WIRELESS_CHARGER_TURN_ON_BATTERY_LEVEL_LIMIT = 95;
154
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800155 private Context mContext;
Jeff Brown96307042012-07-27 15:51:34 -0700156 private LightsService mLightsService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157 private BatteryService mBatteryService;
Jeff Brown96307042012-07-27 15:51:34 -0700158 private IBatteryStats mBatteryStats;
159 private HandlerThread mHandlerThread;
160 private PowerManagerHandler mHandler;
161 private WindowManagerPolicy mPolicy;
162 private Notifier mNotifier;
163 private DisplayPowerController mDisplayPowerController;
164 private SettingsObserver mSettingsObserver;
Jeff Brown62c82e42012-09-26 01:30:41 -0700165 private DreamManagerService mDreamManager;
Jeff Brown96307042012-07-27 15:51:34 -0700166 private LightsService.Light mAttentionLight;
Joe Onorato609695d2010-10-14 14:57:49 -0700167
Jeff Brown96307042012-07-27 15:51:34 -0700168 private final Object mLock = new Object();
169
170 // A bitfield that indicates what parts of the power state have
171 // changed and need to be recalculated.
172 private int mDirty;
173
174 // Indicates whether the device is awake or asleep or somewhere in between.
175 // This is distinct from the screen power state, which is managed separately.
176 private int mWakefulness;
177
178 // True if MSG_SANDMAN has been scheduled.
179 private boolean mSandmanScheduled;
180
181 // Table of all suspend blockers.
182 // There should only be a few of these.
183 private final ArrayList<SuspendBlocker> mSuspendBlockers = new ArrayList<SuspendBlocker>();
184
185 // Table of all wake locks acquired by applications.
186 private final ArrayList<WakeLock> mWakeLocks = new ArrayList<WakeLock>();
187
188 // A bitfield that summarizes the state of all active wakelocks.
189 private int mWakeLockSummary;
190
191 // If true, instructs the display controller to wait for the proximity sensor to
192 // go negative before turning the screen on.
193 private boolean mRequestWaitForNegativeProximity;
194
195 // Timestamp of the last time the device was awoken or put to sleep.
196 private long mLastWakeTime;
197 private long mLastSleepTime;
198
199 // True if we need to send a wake up or go to sleep finished notification
200 // when the display is ready.
201 private boolean mSendWakeUpFinishedNotificationWhenReady;
202 private boolean mSendGoToSleepFinishedNotificationWhenReady;
203
204 // Timestamp of the last call to user activity.
205 private long mLastUserActivityTime;
206 private long mLastUserActivityTimeNoChangeLights;
207
208 // A bitfield that summarizes the effect of the user activity timer.
209 // A zero value indicates that the user activity timer has expired.
210 private int mUserActivitySummary;
211
212 // The desired display power state. The actual state may lag behind the
213 // requested because it is updated asynchronously by the display power controller.
214 private final DisplayPowerRequest mDisplayPowerRequest = new DisplayPowerRequest();
215
216 // The time the screen was last turned off, in elapsedRealtime() timebase.
217 private long mLastScreenOffEventElapsedRealTime;
218
219 // True if the display power state has been fully applied, which means the display
220 // is actually on or actually off or whatever was requested.
221 private boolean mDisplayReady;
222
223 // True if holding a wake-lock to block suspend of the CPU.
224 private boolean mHoldingWakeLockSuspendBlocker;
225
226 // The suspend blocker used to keep the CPU alive when wake locks have been acquired.
227 private final SuspendBlocker mWakeLockSuspendBlocker;
228
Jeff Brownc38c9be2012-10-04 13:16:19 -0700229 // The screen on blocker used to keep the screen from turning on while the lock
230 // screen is coming up.
231 private final ScreenOnBlockerImpl mScreenOnBlocker;
232
Jeff Brown96307042012-07-27 15:51:34 -0700233 // True if systemReady() has been called.
234 private boolean mSystemReady;
235
236 // True if boot completed occurred. We keep the screen on until this happens.
237 private boolean mBootCompleted;
238
239 // True if the device is plugged into a power source.
240 private boolean mIsPowered;
241
Jeff Brownf3fb8952012-10-02 20:57:05 -0700242 // The current plug type, such as BatteryManager.BATTERY_PLUGGED_WIRELESS.
243 private int mPlugType;
244
Jeff Brown96307042012-07-27 15:51:34 -0700245 // True if the device should wake up when plugged or unplugged.
246 private boolean mWakeUpWhenPluggedOrUnpluggedConfig;
247
248 // True if dreams are supported on this device.
249 private boolean mDreamsSupportedConfig;
250
251 // True if dreams are enabled by the user.
252 private boolean mDreamsEnabledSetting;
253
John Spurlock1a868b72012-08-22 09:56:51 -0400254 // True if dreams should be activated on sleep.
255 private boolean mDreamsActivateOnSleepSetting;
256
Jeff Brown96307042012-07-27 15:51:34 -0700257 // The screen off timeout setting value in milliseconds.
258 private int mScreenOffTimeoutSetting;
259
260 // The maximum allowable screen off timeout according to the device
261 // administration policy. Overrides other settings.
262 private int mMaximumScreenOffTimeoutFromDeviceAdmin = Integer.MAX_VALUE;
263
264 // The stay on while plugged in setting.
265 // A bitfield of battery conditions under which to make the screen stay on.
266 private int mStayOnWhilePluggedInSetting;
267
268 // True if the device should stay on.
269 private boolean mStayOn;
270
Jeff Brown93cbbb22012-10-04 13:18:36 -0700271 // True if the proximity sensor reads a positive result.
272 private boolean mProximityPositive;
273
Jeff Brown96307042012-07-27 15:51:34 -0700274 // Screen brightness setting limits.
275 private int mScreenBrightnessSettingMinimum;
276 private int mScreenBrightnessSettingMaximum;
277 private int mScreenBrightnessSettingDefault;
278
279 // The screen brightness setting, from 0 to 255.
280 // Use -1 if no value has been set.
281 private int mScreenBrightnessSetting;
282
Jeff Brown330560f2012-08-21 22:10:57 -0700283 // The screen auto-brightness adjustment setting, from -1 to 1.
284 // Use 0 if there is no adjustment.
285 private float mScreenAutoBrightnessAdjustmentSetting;
286
Jeff Brown96307042012-07-27 15:51:34 -0700287 // The screen brightness mode.
288 // One of the Settings.System.SCREEN_BRIGHTNESS_MODE_* constants.
289 private int mScreenBrightnessModeSetting;
290
291 // The screen brightness setting override from the window manager
292 // to allow the current foreground activity to override the brightness.
293 // Use -1 to disable.
294 private int mScreenBrightnessOverrideFromWindowManager = -1;
295
Jeff Brown1e3b98d2012-09-30 18:58:59 -0700296 // The user activity timeout override from the window manager
297 // to allow the current foreground activity to override the user activity timeout.
298 // Use -1 to disable.
299 private long mUserActivityTimeoutOverrideFromWindowManager = -1;
300
Jeff Brown96307042012-07-27 15:51:34 -0700301 // The screen brightness setting override from the settings application
302 // to temporarily adjust the brightness until next updated,
303 // Use -1 to disable.
304 private int mTemporaryScreenBrightnessSettingOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305
Jeff Brown330560f2012-08-21 22:10:57 -0700306 // The screen brightness adjustment setting override from the settings
307 // application to temporarily adjust the auto-brightness adjustment factor
308 // until next updated, in the range -1..1.
309 // Use NaN to disable.
310 private float mTemporaryScreenAutoBrightnessAdjustmentSettingOverride = Float.NaN;
311
Jeff Brown9ba8d782012-10-01 16:38:23 -0700312 // Time when we last logged a warning about calling userActivity() without permission.
313 private long mLastWarningAboutUserActivityPermission = Long.MIN_VALUE;
314
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700315 private native void nativeInit();
Jeff Brown7304c342012-05-11 18:42:42 -0700316 private static native void nativeShutdown();
317 private static native void nativeReboot(String reason) throws IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800318
Jeff Brown96307042012-07-27 15:51:34 -0700319 private static native void nativeSetPowerState(boolean screenOn, boolean screenBright);
320 private static native void nativeAcquireSuspendBlocker(String name);
321 private static native void nativeReleaseSuspendBlocker(String name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800322
Jeff Brown96307042012-07-27 15:51:34 -0700323 static native void nativeSetScreenState(boolean on);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800324
Jeff Brown4f8ecd82012-06-18 18:29:13 -0700325 public PowerManagerService() {
Jeff Brown96307042012-07-27 15:51:34 -0700326 synchronized (mLock) {
327 mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService");
328 mWakeLockSuspendBlocker.acquire();
Jeff Brownc38c9be2012-10-04 13:16:19 -0700329 mScreenOnBlocker = new ScreenOnBlockerImpl();
Jeff Brown96307042012-07-27 15:51:34 -0700330 mHoldingWakeLockSuspendBlocker = true;
331 mWakefulness = WAKEFULNESS_AWAKE;
332 }
Jeff Brown7304c342012-05-11 18:42:42 -0700333
334 nativeInit();
Jeff Brownf75724b2012-08-25 13:34:32 -0700335 nativeSetPowerState(true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800336 }
337
Jeff Brown96307042012-07-27 15:51:34 -0700338 /**
339 * Initialize the power manager.
340 * Must be called before any other functions within the power manager are called.
341 */
342 public void init(Context context, LightsService ls,
343 ActivityManagerService am, BatteryService bs, IBatteryStats bss,
344 DisplayManagerService dm) {
Jeff Brownf75724b2012-08-25 13:34:32 -0700345 // Forcibly turn the screen on at boot so that it is in a known power state.
346 // We do this in init() rather than in the constructor because setting the
347 // screen state requires a call into surface flinger which then needs to call back
348 // into the activity manager to check permissions. Unfortunately the
349 // activity manager is not running when the constructor is called, so we
350 // have to defer setting the screen state until this point.
351 nativeSetScreenState(true);
352
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800353 mContext = context;
Jeff Brown96307042012-07-27 15:51:34 -0700354 mLightsService = ls;
355 mBatteryService = bs;
356 mBatteryStats = bss;
357 mHandlerThread = new HandlerThread(TAG);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800358 mHandlerThread.start();
Jeff Brown96307042012-07-27 15:51:34 -0700359 mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800360
Jeff Brown96307042012-07-27 15:51:34 -0700361 Watchdog.getInstance().addMonitor(this);
362 }
Jim Miller92e66dd2012-02-21 18:57:12 -0800363
Jeff Brown96307042012-07-27 15:51:34 -0700364 public void setPolicy(WindowManagerPolicy policy) {
365 synchronized (mLock) {
366 mPolicy = policy;
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700367 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800368 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800369
Jeff Brown62c82e42012-09-26 01:30:41 -0700370 public void systemReady(TwilightService twilight, DreamManagerService dreamManager) {
Jeff Brown96307042012-07-27 15:51:34 -0700371 synchronized (mLock) {
372 mSystemReady = true;
Jeff Brown62c82e42012-09-26 01:30:41 -0700373 mDreamManager = dreamManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800374
Jeff Brown96307042012-07-27 15:51:34 -0700375 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
376 mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting();
377 mScreenBrightnessSettingMaximum = pm.getMaximumScreenBrightnessSetting();
378 mScreenBrightnessSettingDefault = pm.getDefaultScreenBrightnessSetting();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800379
Jeff Brownc38c9be2012-10-04 13:16:19 -0700380 // The notifier runs on the system server's main looper so as not to interfere
381 // with the animations and other critical functions of the power manager.
382 mNotifier = new Notifier(Looper.getMainLooper(), mContext, mBatteryStats,
Jeff Brown96307042012-07-27 15:51:34 -0700383 createSuspendBlockerLocked("PowerManagerService.Broadcasts"),
Jeff Brownc38c9be2012-10-04 13:16:19 -0700384 mScreenOnBlocker, mPolicy);
385
386 // The display power controller runs on the power manager service's
387 // own handler thread.
Jeff Brown96307042012-07-27 15:51:34 -0700388 mDisplayPowerController = new DisplayPowerController(mHandler.getLooper(),
Jeff Brownaa202a62012-08-21 22:14:26 -0700389 mContext, mNotifier, mLightsService, twilight,
Jeff Brown96307042012-07-27 15:51:34 -0700390 createSuspendBlockerLocked("PowerManagerService.Display"),
391 mDisplayPowerControllerCallbacks, mHandler);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800392
Jeff Brown96307042012-07-27 15:51:34 -0700393 mSettingsObserver = new SettingsObserver(mHandler);
394 mAttentionLight = mLightsService.getLight(LightsService.LIGHT_ID_ATTENTION);
Mike Lockwoodaa66ea82009-10-31 16:31:27 -0400395
Jeff Brown96307042012-07-27 15:51:34 -0700396 // Register for broadcasts from other components of the system.
397 IntentFilter filter = new IntentFilter();
398 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
Jeff Brownd4935962012-09-25 13:27:20 -0700399 mContext.registerReceiver(new BatteryReceiver(), filter, null, mHandler);
Joe Onoratob08a1af2010-10-11 19:28:58 -0700400
Jeff Brown96307042012-07-27 15:51:34 -0700401 filter = new IntentFilter();
402 filter.addAction(Intent.ACTION_BOOT_COMPLETED);
Jeff Brownd4935962012-09-25 13:27:20 -0700403 mContext.registerReceiver(new BootCompletedReceiver(), filter, null, mHandler);
Jeff Brown96307042012-07-27 15:51:34 -0700404
405 filter = new IntentFilter();
Dianne Hackbornbe87e2f2012-09-28 16:31:34 -0700406 filter.addAction(Intent.ACTION_DREAMING_STARTED);
407 filter.addAction(Intent.ACTION_DREAMING_STOPPED);
Jeff Brownd4935962012-09-25 13:27:20 -0700408 mContext.registerReceiver(new DreamReceiver(), filter, null, mHandler);
409
410 filter = new IntentFilter();
411 filter.addAction(Intent.ACTION_USER_SWITCHED);
412 mContext.registerReceiver(new UserSwitchedReceiver(), filter, null, mHandler);
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400413
Jeff Brown96307042012-07-27 15:51:34 -0700414 // Register for settings changes.
415 final ContentResolver resolver = mContext.getContentResolver();
416 resolver.registerContentObserver(Settings.Secure.getUriFor(
Jeff Brownd4935962012-09-25 13:27:20 -0700417 Settings.Secure.SCREENSAVER_ENABLED),
418 false, mSettingsObserver, UserHandle.USER_ALL);
John Spurlock1a868b72012-08-22 09:56:51 -0400419 resolver.registerContentObserver(Settings.Secure.getUriFor(
Jeff Brownd4935962012-09-25 13:27:20 -0700420 Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP),
421 false, mSettingsObserver, UserHandle.USER_ALL);
Jeff Brown96307042012-07-27 15:51:34 -0700422 resolver.registerContentObserver(Settings.System.getUriFor(
Jeff Brownd4935962012-09-25 13:27:20 -0700423 Settings.System.SCREEN_OFF_TIMEOUT),
424 false, mSettingsObserver, UserHandle.USER_ALL);
Christopher Tatead735322012-09-07 14:19:43 -0700425 resolver.registerContentObserver(Settings.Global.getUriFor(
Jeff Brownd4935962012-09-25 13:27:20 -0700426 Settings.Global.STAY_ON_WHILE_PLUGGED_IN),
427 false, mSettingsObserver, UserHandle.USER_ALL);
Jeff Brown96307042012-07-27 15:51:34 -0700428 resolver.registerContentObserver(Settings.System.getUriFor(
Jeff Brownd4935962012-09-25 13:27:20 -0700429 Settings.System.SCREEN_BRIGHTNESS),
430 false, mSettingsObserver, UserHandle.USER_ALL);
Jeff Brown96307042012-07-27 15:51:34 -0700431 resolver.registerContentObserver(Settings.System.getUriFor(
Jeff Brownd4935962012-09-25 13:27:20 -0700432 Settings.System.SCREEN_BRIGHTNESS_MODE),
433 false, mSettingsObserver, UserHandle.USER_ALL);
Jeff Brown96307042012-07-27 15:51:34 -0700434
435 // Go.
436 readConfigurationLocked();
437 updateSettingsLocked();
438 mDirty |= DIRTY_BATTERY_STATE;
439 updatePowerStateLocked();
440 }
441 }
442
443 private void readConfigurationLocked() {
444 final Resources resources = mContext.getResources();
445
446 mWakeUpWhenPluggedOrUnpluggedConfig = resources.getBoolean(
Joe Onorato6d747652010-10-11 15:15:31 -0700447 com.android.internal.R.bool.config_unplugTurnsOnScreen);
Jeff Brown96307042012-07-27 15:51:34 -0700448 mDreamsSupportedConfig = resources.getBoolean(
449 com.android.internal.R.bool.config_enableDreams);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800450 }
451
Jeff Brown96307042012-07-27 15:51:34 -0700452 private void updateSettingsLocked() {
453 final ContentResolver resolver = mContext.getContentResolver();
Jeff Brown7304c342012-05-11 18:42:42 -0700454
Jeff Brownd4935962012-09-25 13:27:20 -0700455 mDreamsEnabledSetting = (Settings.Secure.getIntForUser(resolver,
456 Settings.Secure.SCREENSAVER_ENABLED, 0,
457 UserHandle.USER_CURRENT) != 0);
458 mDreamsActivateOnSleepSetting = (Settings.Secure.getIntForUser(resolver,
459 Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, 0,
460 UserHandle.USER_CURRENT) != 0);
461 mScreenOffTimeoutSetting = Settings.System.getIntForUser(resolver,
462 Settings.System.SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT,
463 UserHandle.USER_CURRENT);
Christopher Tatead735322012-09-07 14:19:43 -0700464 mStayOnWhilePluggedInSetting = Settings.Global.getInt(resolver,
Jeff Brownd4935962012-09-25 13:27:20 -0700465 Settings.Global.STAY_ON_WHILE_PLUGGED_IN, BatteryManager.BATTERY_PLUGGED_AC);
Jeff Brown7304c342012-05-11 18:42:42 -0700466
Jeff Brown96307042012-07-27 15:51:34 -0700467 final int oldScreenBrightnessSetting = mScreenBrightnessSetting;
Jeff Brownd4935962012-09-25 13:27:20 -0700468 mScreenBrightnessSetting = Settings.System.getIntForUser(resolver,
469 Settings.System.SCREEN_BRIGHTNESS, mScreenBrightnessSettingDefault,
470 UserHandle.USER_CURRENT);
Jeff Brown96307042012-07-27 15:51:34 -0700471 if (oldScreenBrightnessSetting != mScreenBrightnessSetting) {
472 mTemporaryScreenBrightnessSettingOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800473 }
Jeff Brown96307042012-07-27 15:51:34 -0700474
Jeff Brown330560f2012-08-21 22:10:57 -0700475 final float oldScreenAutoBrightnessAdjustmentSetting =
476 mScreenAutoBrightnessAdjustmentSetting;
Jeff Brownd4935962012-09-25 13:27:20 -0700477 mScreenAutoBrightnessAdjustmentSetting = Settings.System.getFloatForUser(resolver,
478 Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f,
479 UserHandle.USER_CURRENT);
Jeff Brown330560f2012-08-21 22:10:57 -0700480 if (oldScreenAutoBrightnessAdjustmentSetting != mScreenAutoBrightnessAdjustmentSetting) {
Jeff Brown5d03a532012-08-22 13:22:02 -0700481 mTemporaryScreenAutoBrightnessAdjustmentSettingOverride = Float.NaN;
Jeff Brown330560f2012-08-21 22:10:57 -0700482 }
483
Jeff Brownd4935962012-09-25 13:27:20 -0700484 mScreenBrightnessModeSetting = Settings.System.getIntForUser(resolver,
Jeff Brown96307042012-07-27 15:51:34 -0700485 Settings.System.SCREEN_BRIGHTNESS_MODE,
Jeff Brownd4935962012-09-25 13:27:20 -0700486 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, UserHandle.USER_CURRENT);
Jeff Brown96307042012-07-27 15:51:34 -0700487
488 mDirty |= DIRTY_SETTINGS;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800489 }
490
Jeff Brown96307042012-07-27 15:51:34 -0700491 private void handleSettingsChangedLocked() {
492 updateSettingsLocked();
493 updatePowerStateLocked();
494 }
495
496 @Override // Binder call
497 public void acquireWakeLock(IBinder lock, int flags, String tag, WorkSource ws) {
498 if (lock == null) {
499 throw new IllegalArgumentException("lock must not be null");
500 }
501 PowerManager.validateWakeLockParameters(flags, tag);
502
503 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
504 if (ws != null && ws.size() != 0) {
505 mContext.enforceCallingOrSelfPermission(
506 android.Manifest.permission.UPDATE_DEVICE_STATS, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800507 } else {
Jeff Brown96307042012-07-27 15:51:34 -0700508 ws = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800509 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800510
Jeff Brown96307042012-07-27 15:51:34 -0700511 final int uid = Binder.getCallingUid();
512 final int pid = Binder.getCallingPid();
513 final long ident = Binder.clearCallingIdentity();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800514 try {
Jeff Brown96307042012-07-27 15:51:34 -0700515 acquireWakeLockInternal(lock, flags, tag, ws, uid, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800516 } finally {
517 Binder.restoreCallingIdentity(ident);
518 }
519 }
520
Jeff Brown96307042012-07-27 15:51:34 -0700521 private void acquireWakeLockInternal(IBinder lock, int flags, String tag, WorkSource ws,
522 int uid, int pid) {
523 synchronized (mLock) {
524 if (DEBUG_SPEW) {
525 Slog.d(TAG, "acquireWakeLockInternal: lock=" + Objects.hashCode(lock)
526 + ", flags=0x" + Integer.toHexString(flags)
527 + ", tag=\"" + tag + "\", ws=" + ws + ", uid=" + uid + ", pid=" + pid);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700528 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800529
Jeff Brown96307042012-07-27 15:51:34 -0700530 WakeLock wakeLock;
531 int index = findWakeLockIndexLocked(lock);
532 if (index >= 0) {
533 wakeLock = mWakeLocks.get(index);
534 if (!wakeLock.hasSameProperties(flags, tag, ws, uid, pid)) {
535 // Update existing wake lock. This shouldn't happen but is harmless.
536 notifyWakeLockReleasedLocked(wakeLock);
537 wakeLock.updateProperties(flags, tag, ws, uid, pid);
538 notifyWakeLockAcquiredLocked(wakeLock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800539 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800540 } else {
Jeff Brown96307042012-07-27 15:51:34 -0700541 wakeLock = new WakeLock(lock, flags, tag, ws, uid, pid);
542 try {
543 lock.linkToDeath(wakeLock, 0);
544 } catch (RemoteException ex) {
545 throw new IllegalArgumentException("Wake lock is already dead.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800546 }
Jeff Brown96307042012-07-27 15:51:34 -0700547 notifyWakeLockAcquiredLocked(wakeLock);
548 mWakeLocks.add(wakeLock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800549 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800550
Jeff Brown96307042012-07-27 15:51:34 -0700551 applyWakeLockFlagsOnAcquireLocked(wakeLock);
552 mDirty |= DIRTY_WAKE_LOCKS;
553 updatePowerStateLocked();
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700554 }
555 }
556
Jeff Brown96307042012-07-27 15:51:34 -0700557 private void applyWakeLockFlagsOnAcquireLocked(WakeLock wakeLock) {
558 if ((wakeLock.mFlags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {
559 wakeUpNoUpdateLocked(SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800560 }
561 }
562
Jeff Brown96307042012-07-27 15:51:34 -0700563 @Override // Binder call
Mike Lockwood0e39ea82009-11-18 15:37:10 -0500564 public void releaseWakeLock(IBinder lock, int flags) {
Jeff Brown96307042012-07-27 15:51:34 -0700565 if (lock == null) {
566 throw new IllegalArgumentException("lock must not be null");
Michael Chane96440f2009-05-06 10:27:36 -0700567 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800568
Jeff Brown96307042012-07-27 15:51:34 -0700569 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
570
571 final long ident = Binder.clearCallingIdentity();
572 try {
573 releaseWakeLockInternal(lock, flags);
574 } finally {
575 Binder.restoreCallingIdentity(ident);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800576 }
577 }
578
Jeff Brown96307042012-07-27 15:51:34 -0700579 private void releaseWakeLockInternal(IBinder lock, int flags) {
580 synchronized (mLock) {
581 if (DEBUG_SPEW) {
582 Slog.d(TAG, "releaseWakeLockInternal: lock=" + Objects.hashCode(lock)
583 + ", flags=0x" + Integer.toHexString(flags));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800584 }
585
Jeff Brown96307042012-07-27 15:51:34 -0700586 int index = findWakeLockIndexLocked(lock);
587 if (index < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800588 return;
589 }
Mike Lockwood3333fa42009-10-26 14:50:42 -0400590
Jeff Brown96307042012-07-27 15:51:34 -0700591 WakeLock wakeLock = mWakeLocks.get(index);
592 mWakeLocks.remove(index);
593 notifyWakeLockReleasedLocked(wakeLock);
594 wakeLock.mLock.unlinkToDeath(wakeLock, 0);
595
596 if ((flags & PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE) != 0) {
597 mRequestWaitForNegativeProximity = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800598 }
599
Jeff Brown96307042012-07-27 15:51:34 -0700600 applyWakeLockFlagsOnReleaseLocked(wakeLock);
601 mDirty |= DIRTY_WAKE_LOCKS;
602 updatePowerStateLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800603 }
604 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700605
Jeff Brown96307042012-07-27 15:51:34 -0700606 private void handleWakeLockDeath(WakeLock wakeLock) {
607 synchronized (mLock) {
608 if (DEBUG_SPEW) {
609 Slog.d(TAG, "handleWakeLockDeath: lock=" + Objects.hashCode(wakeLock.mLock));
610 }
611
612 int index = mWakeLocks.indexOf(wakeLock);
613 if (index < 0) {
614 return;
615 }
616
617 mWakeLocks.remove(index);
618 notifyWakeLockReleasedLocked(wakeLock);
619
620 applyWakeLockFlagsOnReleaseLocked(wakeLock);
621 mDirty |= DIRTY_WAKE_LOCKS;
622 updatePowerStateLocked();
Mike Lockwood3a74bd32011-08-12 13:55:22 -0700623 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700624 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800625
Jeff Brown96307042012-07-27 15:51:34 -0700626 private void applyWakeLockFlagsOnReleaseLocked(WakeLock wakeLock) {
627 if ((wakeLock.mFlags & PowerManager.ON_AFTER_RELEASE) != 0) {
628 userActivityNoUpdateLocked(SystemClock.uptimeMillis(),
629 PowerManager.USER_ACTIVITY_EVENT_OTHER,
630 PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS,
631 wakeLock.mOwnerUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800632 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800633 }
634
Jeff Brown96307042012-07-27 15:51:34 -0700635 @Override // Binder call
636 public void updateWakeLockWorkSource(IBinder lock, WorkSource ws) {
637 if (lock == null) {
638 throw new IllegalArgumentException("lock must not be null");
639 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800640
Jeff Brown96307042012-07-27 15:51:34 -0700641 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
642 if (ws != null && ws.size() != 0) {
643 mContext.enforceCallingOrSelfPermission(
644 android.Manifest.permission.UPDATE_DEVICE_STATS, null);
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700645 } else {
Jeff Brown96307042012-07-27 15:51:34 -0700646 ws = null;
647 }
648
649 final long ident = Binder.clearCallingIdentity();
650 try {
651 updateWakeLockWorkSourceInternal(lock, ws);
652 } finally {
653 Binder.restoreCallingIdentity(ident);
654 }
655 }
656
657 private void updateWakeLockWorkSourceInternal(IBinder lock, WorkSource ws) {
658 synchronized (mLock) {
659 int index = findWakeLockIndexLocked(lock);
660 if (index < 0) {
661 throw new IllegalArgumentException("Wake lock not active");
662 }
663
664 WakeLock wakeLock = mWakeLocks.get(index);
665 if (!wakeLock.hasSameWorkSource(ws)) {
666 notifyWakeLockReleasedLocked(wakeLock);
667 wakeLock.updateWorkSource(ws);
668 notifyWakeLockAcquiredLocked(wakeLock);
669 }
670 }
671 }
672
673 private int findWakeLockIndexLocked(IBinder lock) {
674 final int count = mWakeLocks.size();
675 for (int i = 0; i < count; i++) {
676 if (mWakeLocks.get(i).mLock == lock) {
677 return i;
678 }
679 }
680 return -1;
681 }
682
683 private void notifyWakeLockAcquiredLocked(WakeLock wakeLock) {
684 if (mSystemReady) {
685 mNotifier.onWakeLockAcquired(wakeLock.mFlags, wakeLock.mTag,
686 wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource);
687 }
688 }
689
690 private void notifyWakeLockReleasedLocked(WakeLock wakeLock) {
691 if (mSystemReady) {
692 mNotifier.onWakeLockReleased(wakeLock.mFlags, wakeLock.mTag,
693 wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource);
694 }
695 }
696
697 @Override // Binder call
698 public boolean isWakeLockLevelSupported(int level) {
699 final long ident = Binder.clearCallingIdentity();
700 try {
701 return isWakeLockLevelSupportedInternal(level);
702 } finally {
703 Binder.restoreCallingIdentity(ident);
704 }
705 }
706
707 private boolean isWakeLockLevelSupportedInternal(int level) {
708 synchronized (mLock) {
709 switch (level) {
710 case PowerManager.PARTIAL_WAKE_LOCK:
711 case PowerManager.SCREEN_DIM_WAKE_LOCK:
712 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
713 case PowerManager.FULL_WAKE_LOCK:
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700714 return true;
Jeff Brown96307042012-07-27 15:51:34 -0700715
716 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
717 return mSystemReady && mDisplayPowerController.isProximitySensorAvailable();
718
719 default:
720 return false;
721 }
722 }
723 }
724
725 @Override // Binder call
726 public void userActivity(long eventTime, int event, int flags) {
Jeff Brown9ba8d782012-10-01 16:38:23 -0700727 final long now = SystemClock.uptimeMillis();
728 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER)
729 != PackageManager.PERMISSION_GRANTED) {
730 // Once upon a time applications could call userActivity().
731 // Now we require the DEVICE_POWER permission. Log a warning and ignore the
732 // request instead of throwing a SecurityException so we don't break old apps.
733 synchronized (mLock) {
734 if (now >= mLastWarningAboutUserActivityPermission + (5 * 60 * 1000)) {
735 mLastWarningAboutUserActivityPermission = now;
736 Slog.w(TAG, "Ignoring call to PowerManager.userActivity() because the "
737 + "caller does not have DEVICE_POWER permission. "
738 + "Please fix your app! "
739 + " pid=" + Binder.getCallingPid()
740 + " uid=" + Binder.getCallingUid());
741 }
742 }
743 return;
744 }
745
Jeff Brown96307042012-07-27 15:51:34 -0700746 if (eventTime > SystemClock.uptimeMillis()) {
747 throw new IllegalArgumentException("event time must not be in the future");
748 }
749
Jeff Brown96307042012-07-27 15:51:34 -0700750 final int uid = Binder.getCallingUid();
751 final long ident = Binder.clearCallingIdentity();
752 try {
753 userActivityInternal(eventTime, event, flags, uid);
754 } finally {
755 Binder.restoreCallingIdentity(ident);
756 }
757 }
758
759 // Called from native code.
760 private void userActivityFromNative(long eventTime, int event, int flags) {
761 userActivityInternal(eventTime, event, flags, Process.SYSTEM_UID);
762 }
763
764 private void userActivityInternal(long eventTime, int event, int flags, int uid) {
765 synchronized (mLock) {
766 if (userActivityNoUpdateLocked(eventTime, event, flags, uid)) {
767 updatePowerStateLocked();
768 }
769 }
770 }
771
772 private boolean userActivityNoUpdateLocked(long eventTime, int event, int flags, int uid) {
773 if (DEBUG_SPEW) {
774 Slog.d(TAG, "userActivityNoUpdateLocked: eventTime=" + eventTime
775 + ", event=" + event + ", flags=0x" + Integer.toHexString(flags)
776 + ", uid=" + uid);
777 }
778
779 if (eventTime < mLastSleepTime || eventTime < mLastWakeTime
780 || mWakefulness == WAKEFULNESS_ASLEEP || !mBootCompleted || !mSystemReady) {
781 return false;
782 }
783
784 mNotifier.onUserActivity(event, uid);
785
786 if ((flags & PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS) != 0) {
787 if (eventTime > mLastUserActivityTimeNoChangeLights
788 && eventTime > mLastUserActivityTime) {
789 mLastUserActivityTimeNoChangeLights = eventTime;
790 mDirty |= DIRTY_USER_ACTIVITY;
791 return true;
792 }
793 } else {
794 if (eventTime > mLastUserActivityTime) {
795 mLastUserActivityTime = eventTime;
796 mDirty |= DIRTY_USER_ACTIVITY;
797 return true;
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700798 }
799 }
800 return false;
801 }
802
Jeff Brown96307042012-07-27 15:51:34 -0700803 @Override // Binder call
804 public void wakeUp(long eventTime) {
805 if (eventTime > SystemClock.uptimeMillis()) {
806 throw new IllegalArgumentException("event time must not be in the future");
807 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700808
Jeff Brown96307042012-07-27 15:51:34 -0700809 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
810
811 final long ident = Binder.clearCallingIdentity();
812 try {
813 wakeUpInternal(eventTime);
814 } finally {
815 Binder.restoreCallingIdentity(ident);
816 }
817 }
818
819 // Called from native code.
820 private void wakeUpFromNative(long eventTime) {
821 wakeUpInternal(eventTime);
822 }
823
824 private void wakeUpInternal(long eventTime) {
825 synchronized (mLock) {
826 if (wakeUpNoUpdateLocked(eventTime)) {
827 updatePowerStateLocked();
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700828 }
829 }
Jeff Brown96307042012-07-27 15:51:34 -0700830 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700831
Jeff Brown96307042012-07-27 15:51:34 -0700832 private boolean wakeUpNoUpdateLocked(long eventTime) {
833 if (DEBUG_SPEW) {
834 Slog.d(TAG, "wakeUpNoUpdateLocked: eventTime=" + eventTime);
Joe Onorato60607a92010-10-23 14:49:30 -0700835 }
Jeff Brown96307042012-07-27 15:51:34 -0700836
837 if (eventTime < mLastSleepTime || mWakefulness == WAKEFULNESS_AWAKE
838 || !mBootCompleted || !mSystemReady) {
839 return false;
840 }
841
842 switch (mWakefulness) {
843 case WAKEFULNESS_ASLEEP:
844 Slog.i(TAG, "Waking up from sleep...");
Jeff Brown54308352012-10-04 17:59:58 -0700845 sendPendingNotificationsLocked();
Jeff Brown96307042012-07-27 15:51:34 -0700846 mNotifier.onWakeUpStarted();
847 mSendWakeUpFinishedNotificationWhenReady = true;
Jeff Brown96307042012-07-27 15:51:34 -0700848 break;
849 case WAKEFULNESS_DREAMING:
850 Slog.i(TAG, "Waking up from dream...");
851 break;
852 case WAKEFULNESS_NAPPING:
853 Slog.i(TAG, "Waking up from nap...");
854 break;
855 }
856
857 mLastWakeTime = eventTime;
858 mWakefulness = WAKEFULNESS_AWAKE;
859 mDirty |= DIRTY_WAKEFULNESS;
860
861 userActivityNoUpdateLocked(
862 eventTime, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
863 return true;
864 }
865
866 @Override // Binder call
867 public void goToSleep(long eventTime, int reason) {
868 if (eventTime > SystemClock.uptimeMillis()) {
869 throw new IllegalArgumentException("event time must not be in the future");
870 }
871
872 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
873
874 final long ident = Binder.clearCallingIdentity();
875 try {
876 goToSleepInternal(eventTime, reason);
877 } finally {
878 Binder.restoreCallingIdentity(ident);
879 }
880 }
881
882 // Called from native code.
883 private void goToSleepFromNative(long eventTime, int reason) {
884 goToSleepInternal(eventTime, reason);
885 }
886
887 private void goToSleepInternal(long eventTime, int reason) {
888 synchronized (mLock) {
889 if (goToSleepNoUpdateLocked(eventTime, reason)) {
890 updatePowerStateLocked();
891 }
892 }
893 }
894
895 private boolean goToSleepNoUpdateLocked(long eventTime, int reason) {
896 if (DEBUG_SPEW) {
897 Slog.d(TAG, "goToSleepNoUpdateLocked: eventTime=" + eventTime + ", reason=" + reason);
898 }
899
900 if (eventTime < mLastWakeTime || mWakefulness == WAKEFULNESS_ASLEEP
901 || !mBootCompleted || !mSystemReady) {
902 return false;
903 }
904
905 switch (reason) {
906 case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN:
907 Slog.i(TAG, "Going to sleep due to device administration policy...");
908 break;
909 case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT:
910 Slog.i(TAG, "Going to sleep due to screen timeout...");
911 break;
912 default:
913 Slog.i(TAG, "Going to sleep by user request...");
914 reason = PowerManager.GO_TO_SLEEP_REASON_USER;
915 break;
916 }
917
Jeff Brown54308352012-10-04 17:59:58 -0700918 sendPendingNotificationsLocked();
919 mNotifier.onGoToSleepStarted(reason);
920 mSendGoToSleepFinishedNotificationWhenReady = true;
921
Jeff Brown96307042012-07-27 15:51:34 -0700922 mLastSleepTime = eventTime;
923 mDirty |= DIRTY_WAKEFULNESS;
924 mWakefulness = WAKEFULNESS_ASLEEP;
Jeff Brown96307042012-07-27 15:51:34 -0700925
926 // Report the number of wake locks that will be cleared by going to sleep.
927 int numWakeLocksCleared = 0;
928 final int numWakeLocks = mWakeLocks.size();
929 for (int i = 0; i < numWakeLocks; i++) {
930 final WakeLock wakeLock = mWakeLocks.get(i);
931 switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
932 case PowerManager.FULL_WAKE_LOCK:
933 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
934 case PowerManager.SCREEN_DIM_WAKE_LOCK:
935 numWakeLocksCleared += 1;
936 break;
937 }
938 }
939 EventLog.writeEvent(EventLogTags.POWER_SLEEP_REQUESTED, numWakeLocksCleared);
940 return true;
941 }
942
Jeff Brown62c82e42012-09-26 01:30:41 -0700943 @Override // Binder call
944 public void nap(long eventTime) {
945 if (eventTime > SystemClock.uptimeMillis()) {
946 throw new IllegalArgumentException("event time must not be in the future");
947 }
948
949 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
950
951 final long ident = Binder.clearCallingIdentity();
952 try {
953 napInternal(eventTime);
954 } finally {
955 Binder.restoreCallingIdentity(ident);
956 }
957 }
958
959 private void napInternal(long eventTime) {
960 synchronized (mLock) {
961 if (napNoUpdateLocked(eventTime)) {
962 updatePowerStateLocked();
963 }
964 }
965 }
966
967 private boolean napNoUpdateLocked(long eventTime) {
968 if (DEBUG_SPEW) {
969 Slog.d(TAG, "napNoUpdateLocked: eventTime=" + eventTime);
970 }
971
972 if (eventTime < mLastWakeTime || mWakefulness != WAKEFULNESS_AWAKE
973 || !mBootCompleted || !mSystemReady) {
974 return false;
975 }
976
977 Slog.i(TAG, "Nap time...");
978
979 mDirty |= DIRTY_WAKEFULNESS;
980 mWakefulness = WAKEFULNESS_NAPPING;
981 return true;
982 }
983
Jeff Brown96307042012-07-27 15:51:34 -0700984 /**
985 * Updates the global power state based on dirty bits recorded in mDirty.
986 *
987 * This is the main function that performs power state transitions.
988 * We centralize them here so that we can recompute the power state completely
989 * each time something important changes, and ensure that we do it the same
990 * way each time. The point is to gather all of the transition logic here.
991 */
992 private void updatePowerStateLocked() {
993 if (!mSystemReady || mDirty == 0) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700994 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800995 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800996
Jeff Brown96307042012-07-27 15:51:34 -0700997 // Phase 0: Basic state updates.
998 updateIsPoweredLocked(mDirty);
999 updateStayOnLocked(mDirty);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001000
Jeff Brown96307042012-07-27 15:51:34 -07001001 // Phase 1: Update wakefulness.
1002 // Loop because the wake lock and user activity computations are influenced
1003 // by changes in wakefulness.
1004 final long now = SystemClock.uptimeMillis();
1005 int dirtyPhase2 = 0;
1006 for (;;) {
1007 int dirtyPhase1 = mDirty;
1008 dirtyPhase2 |= dirtyPhase1;
1009 mDirty = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001010
Jeff Brown96307042012-07-27 15:51:34 -07001011 updateWakeLockSummaryLocked(dirtyPhase1);
1012 updateUserActivitySummaryLocked(now, dirtyPhase1);
1013 if (!updateWakefulnessLocked(dirtyPhase1)) {
1014 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001015 }
1016 }
1017
Jeff Brown96307042012-07-27 15:51:34 -07001018 // Phase 2: Update dreams and display power state.
1019 updateDreamLocked(dirtyPhase2);
1020 updateDisplayPowerStateLocked(dirtyPhase2);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001021
Jeff Brown96307042012-07-27 15:51:34 -07001022 // Phase 3: Send notifications, if needed.
Jeff Brown54308352012-10-04 17:59:58 -07001023 if (mDisplayReady) {
1024 sendPendingNotificationsLocked();
1025 }
Craig Mautner75fc9de2012-06-18 16:53:27 -07001026
Jeff Brown96307042012-07-27 15:51:34 -07001027 // Phase 4: Update suspend blocker.
1028 // Because we might release the last suspend blocker here, we need to make sure
1029 // we finished everything else first!
1030 updateSuspendBlockerLocked();
1031 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001032
Jeff Brown96307042012-07-27 15:51:34 -07001033 private void sendPendingNotificationsLocked() {
Jeff Brown54308352012-10-04 17:59:58 -07001034 if (mSendWakeUpFinishedNotificationWhenReady) {
1035 mSendWakeUpFinishedNotificationWhenReady = false;
1036 mNotifier.onWakeUpFinished();
1037 }
1038 if (mSendGoToSleepFinishedNotificationWhenReady) {
1039 mSendGoToSleepFinishedNotificationWhenReady = false;
1040 mNotifier.onGoToSleepFinished();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001041 }
The Android Open Source Project10592532009-03-18 17:39:46 -07001042 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001043
Jim Miller92e66dd2012-02-21 18:57:12 -08001044 /**
Jeff Brown96307042012-07-27 15:51:34 -07001045 * Updates the value of mIsPowered.
1046 * Sets DIRTY_IS_POWERED if a change occurred.
Jim Miller92e66dd2012-02-21 18:57:12 -08001047 */
Jeff Brown96307042012-07-27 15:51:34 -07001048 private void updateIsPoweredLocked(int dirty) {
1049 if ((dirty & DIRTY_BATTERY_STATE) != 0) {
Jeff Brownf3fb8952012-10-02 20:57:05 -07001050 final boolean wasPowered = mIsPowered;
1051 final int oldPlugType = mPlugType;
Jeff Browna4d82042012-10-02 19:11:19 -07001052 mIsPowered = mBatteryService.isPowered(BatteryManager.BATTERY_PLUGGED_ANY);
Jeff Brownf3fb8952012-10-02 20:57:05 -07001053 mPlugType = mBatteryService.getPlugType();
Jeff Browna4d82042012-10-02 19:11:19 -07001054
1055 if (DEBUG) {
1056 Slog.d(TAG, "updateIsPoweredLocked: wasPowered=" + wasPowered
Jeff Brownf3fb8952012-10-02 20:57:05 -07001057 + ", mIsPowered=" + mIsPowered
1058 + ", oldPlugType=" + oldPlugType
1059 + ", mPlugType=" + mPlugType);
Jeff Browna4d82042012-10-02 19:11:19 -07001060 }
Jim Miller92e66dd2012-02-21 18:57:12 -08001061
Jeff Brownf3fb8952012-10-02 20:57:05 -07001062 if (wasPowered != mIsPowered || oldPlugType != mPlugType) {
Jeff Brown96307042012-07-27 15:51:34 -07001063 mDirty |= DIRTY_IS_POWERED;
1064
1065 // Treat plugging and unplugging the devices as a user activity.
1066 // Users find it disconcerting when they plug or unplug the device
1067 // and it shuts off right away.
1068 // Some devices also wake the device when plugged or unplugged because
1069 // they don't have a charging LED.
1070 final long now = SystemClock.uptimeMillis();
Jeff Brownf3fb8952012-10-02 20:57:05 -07001071 if (shouldWakeUpWhenPluggedOrUnpluggedLocked(wasPowered, oldPlugType)) {
Jeff Brown96307042012-07-27 15:51:34 -07001072 wakeUpNoUpdateLocked(now);
1073 }
1074 userActivityNoUpdateLocked(
1075 now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
1076 }
1077 }
1078 }
1079
Jeff Brownf3fb8952012-10-02 20:57:05 -07001080 private boolean shouldWakeUpWhenPluggedOrUnpluggedLocked(boolean wasPowered, int oldPlugType) {
Jeff Brown9fca9e92012-10-05 14:42:56 -07001081 // Don't wake when powered unless configured to do so.
1082 if (!mWakeUpWhenPluggedOrUnpluggedConfig) {
1083 return false;
Jeff Brownf3fb8952012-10-02 20:57:05 -07001084 }
Jeff Brown9fca9e92012-10-05 14:42:56 -07001085
1086 // FIXME: Need more accurate detection of wireless chargers.
1087 //
1088 // We are unable to accurately detect whether the device is resting on the
1089 // charger unless it is actually receiving power. This causes us some grief
1090 // because the device might not appear to be plugged into the wireless charger
1091 // unless it actually charging.
1092 //
1093 // To avoid spuriously waking the screen, we apply a special policy to
1094 // wireless chargers.
1095 //
1096 // 1. Don't wake the device when unplugged from wireless charger because
1097 // it might be that the device is still resting on the wireless charger
1098 // but is not receiving power anymore because the battery is full.
1099 //
1100 // 2. Don't wake the device when plugged into a wireless charger if the
1101 // battery already appears to be mostly full. This situation may indicate
1102 // that the device was resting on the charger the whole time and simply
1103 // wasn't receiving power because the battery was full. We can't tell
1104 // whether the device was just placed on the charger or whether it has
1105 // been there for half of the night slowly discharging until it hit
1106 // the point where it needed to start charging again.
1107 if (wasPowered && !mIsPowered
1108 && oldPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS) {
1109 return false;
1110 }
1111 if (!wasPowered && mIsPowered
1112 && mPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS
1113 && mBatteryService.getBatteryLevel() >=
1114 WIRELESS_CHARGER_TURN_ON_BATTERY_LEVEL_LIMIT) {
1115 return false;
1116 }
1117
1118 // If already dreaming and becoming powered, then don't wake.
1119 if (mIsPowered && (mWakefulness == WAKEFULNESS_NAPPING
1120 || mWakefulness == WAKEFULNESS_DREAMING)) {
1121 return false;
1122 }
1123
1124 // Otherwise wake up!
1125 return true;
Jeff Brownf3fb8952012-10-02 20:57:05 -07001126 }
1127
Jeff Brown96307042012-07-27 15:51:34 -07001128 /**
1129 * Updates the value of mStayOn.
1130 * Sets DIRTY_STAY_ON if a change occurred.
1131 */
1132 private void updateStayOnLocked(int dirty) {
1133 if ((dirty & (DIRTY_BATTERY_STATE | DIRTY_SETTINGS)) != 0) {
Jeff Brown93cbbb22012-10-04 13:18:36 -07001134 final boolean wasStayOn = mStayOn;
Jeff Brown96307042012-07-27 15:51:34 -07001135 if (mStayOnWhilePluggedInSetting != 0
1136 && !isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
1137 mStayOn = mBatteryService.isPowered(mStayOnWhilePluggedInSetting);
1138 } else {
1139 mStayOn = false;
1140 }
Jeff Brown93cbbb22012-10-04 13:18:36 -07001141
1142 if (mStayOn != wasStayOn) {
1143 mDirty |= DIRTY_STAY_ON;
1144 }
Jeff Brown96307042012-07-27 15:51:34 -07001145 }
1146 }
1147
1148 /**
1149 * Updates the value of mWakeLockSummary to summarize the state of all active wake locks.
1150 * Note that most wake-locks are ignored when the system is asleep.
1151 *
1152 * This function must have no other side-effects.
1153 */
1154 private void updateWakeLockSummaryLocked(int dirty) {
1155 if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_WAKEFULNESS)) != 0) {
1156 mWakeLockSummary = 0;
1157
1158 final int numWakeLocks = mWakeLocks.size();
1159 for (int i = 0; i < numWakeLocks; i++) {
1160 final WakeLock wakeLock = mWakeLocks.get(i);
1161 switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
1162 case PowerManager.PARTIAL_WAKE_LOCK:
1163 mWakeLockSummary |= WAKE_LOCK_CPU;
1164 break;
1165 case PowerManager.FULL_WAKE_LOCK:
1166 if (mWakefulness != WAKEFULNESS_ASLEEP) {
1167 mWakeLockSummary |= WAKE_LOCK_CPU
1168 | WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_BUTTON_BRIGHT;
1169 }
1170 break;
1171 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
1172 if (mWakefulness != WAKEFULNESS_ASLEEP) {
1173 mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_SCREEN_BRIGHT;
1174 }
1175 break;
1176 case PowerManager.SCREEN_DIM_WAKE_LOCK:
1177 if (mWakefulness != WAKEFULNESS_ASLEEP) {
1178 mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_SCREEN_DIM;
1179 }
1180 break;
1181 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
1182 if (mWakefulness != WAKEFULNESS_ASLEEP) {
1183 mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_PROXIMITY_SCREEN_OFF;
1184 }
1185 break;
1186 }
1187 }
1188
1189 if (DEBUG_SPEW) {
1190 Slog.d(TAG, "updateWakeLockSummaryLocked: mWakefulness="
1191 + wakefulnessToString(mWakefulness)
1192 + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary));
1193 }
1194 }
1195 }
1196
1197 /**
1198 * Updates the value of mUserActivitySummary to summarize the user requested
1199 * state of the system such as whether the screen should be bright or dim.
1200 * Note that user activity is ignored when the system is asleep.
1201 *
1202 * This function must have no other side-effects.
1203 */
1204 private void updateUserActivitySummaryLocked(long now, int dirty) {
1205 // Update the status of the user activity timeout timer.
1206 if ((dirty & (DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS | DIRTY_SETTINGS)) != 0) {
1207 mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT);
1208
1209 long nextTimeout = 0;
1210 if (mWakefulness != WAKEFULNESS_ASLEEP) {
1211 final int screenOffTimeout = getScreenOffTimeoutLocked();
Jeff Brownff532542012-10-02 21:18:04 -07001212 final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
Jeff Brown96307042012-07-27 15:51:34 -07001213
1214 mUserActivitySummary = 0;
1215 if (mLastUserActivityTime >= mLastWakeTime) {
1216 nextTimeout = mLastUserActivityTime
1217 + screenOffTimeout - screenDimDuration;
1218 if (now < nextTimeout) {
1219 mUserActivitySummary |= USER_ACTIVITY_SCREEN_BRIGHT;
1220 } else {
1221 nextTimeout = mLastUserActivityTime + screenOffTimeout;
1222 if (now < nextTimeout) {
1223 mUserActivitySummary |= USER_ACTIVITY_SCREEN_DIM;
1224 }
1225 }
1226 }
1227 if (mUserActivitySummary == 0
1228 && mLastUserActivityTimeNoChangeLights >= mLastWakeTime) {
1229 nextTimeout = mLastUserActivityTimeNoChangeLights + screenOffTimeout;
1230 if (now < nextTimeout
1231 && mDisplayPowerRequest.screenState
1232 != DisplayPowerRequest.SCREEN_STATE_OFF) {
1233 mUserActivitySummary = mDisplayPowerRequest.screenState
1234 == DisplayPowerRequest.SCREEN_STATE_BRIGHT ?
1235 USER_ACTIVITY_SCREEN_BRIGHT : USER_ACTIVITY_SCREEN_DIM;
1236 }
1237 }
1238 if (mUserActivitySummary != 0) {
1239 Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY_TIMEOUT);
1240 msg.setAsynchronous(true);
1241 mHandler.sendMessageAtTime(msg, nextTimeout);
1242 }
1243 } else {
1244 mUserActivitySummary = 0;
1245 }
1246
1247 if (DEBUG_SPEW) {
1248 Slog.d(TAG, "updateUserActivitySummaryLocked: mWakefulness="
1249 + wakefulnessToString(mWakefulness)
1250 + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
1251 + ", nextTimeout=" + TimeUtils.formatUptime(nextTimeout));
1252 }
1253 }
1254 }
1255
1256 /**
1257 * Called when a user activity timeout has occurred.
1258 * Simply indicates that something about user activity has changed so that the new
1259 * state can be recomputed when the power state is updated.
1260 *
1261 * This function must have no other side-effects besides setting the dirty
1262 * bit and calling update power state. Wakefulness transitions are handled elsewhere.
1263 */
1264 private void handleUserActivityTimeout() { // runs on handler thread
1265 synchronized (mLock) {
1266 if (DEBUG_SPEW) {
1267 Slog.d(TAG, "handleUserActivityTimeout");
1268 }
1269
1270 mDirty |= DIRTY_USER_ACTIVITY;
1271 updatePowerStateLocked();
1272 }
1273 }
1274
1275 private int getScreenOffTimeoutLocked() {
1276 int timeout = mScreenOffTimeoutSetting;
1277 if (isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
1278 timeout = Math.min(timeout, mMaximumScreenOffTimeoutFromDeviceAdmin);
1279 }
Jeff Brown1e3b98d2012-09-30 18:58:59 -07001280 if (mUserActivityTimeoutOverrideFromWindowManager >= 0) {
1281 timeout = (int)Math.min(timeout, mUserActivityTimeoutOverrideFromWindowManager);
1282 }
Jeff Brown96307042012-07-27 15:51:34 -07001283 return Math.max(timeout, MINIMUM_SCREEN_OFF_TIMEOUT);
1284 }
1285
Jeff Brownff532542012-10-02 21:18:04 -07001286 private int getScreenDimDurationLocked(int screenOffTimeout) {
1287 return Math.min(SCREEN_DIM_DURATION,
1288 (int)(screenOffTimeout * MAXIMUM_SCREEN_DIM_RATIO));
Jeff Brown96307042012-07-27 15:51:34 -07001289 }
1290
1291 /**
1292 * Updates the wakefulness of the device.
1293 *
1294 * This is the function that decides whether the device should start napping
1295 * based on the current wake locks and user activity state. It may modify mDirty
1296 * if the wakefulness changes.
1297 *
1298 * Returns true if the wakefulness changed and we need to restart power state calculation.
1299 */
1300 private boolean updateWakefulnessLocked(int dirty) {
1301 boolean changed = false;
1302 if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_BOOT_COMPLETED
Jeff Brown93cbbb22012-10-04 13:18:36 -07001303 | DIRTY_WAKEFULNESS | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE)) != 0) {
Jeff Brown96307042012-07-27 15:51:34 -07001304 if (mWakefulness == WAKEFULNESS_AWAKE && isItBedTimeYetLocked()) {
1305 if (DEBUG_SPEW) {
Jeff Brown62c82e42012-09-26 01:30:41 -07001306 Slog.d(TAG, "updateWakefulnessLocked: Bed time...");
Jeff Brown96307042012-07-27 15:51:34 -07001307 }
Jeff Brown62c82e42012-09-26 01:30:41 -07001308 final long time = SystemClock.uptimeMillis();
1309 if (mDreamsActivateOnSleepSetting) {
1310 changed = napNoUpdateLocked(time);
1311 } else {
1312 changed = goToSleepNoUpdateLocked(time,
1313 PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
1314 }
Jeff Brown96307042012-07-27 15:51:34 -07001315 }
1316 }
1317 return changed;
1318 }
1319
Jeff Brown645832d2012-10-03 14:57:03 -07001320 /**
1321 * Returns true if the device should go to sleep now.
1322 * Also used when exiting a dream to determine whether we should go back
1323 * to being fully awake or else go to sleep for good.
1324 */
Jeff Brown96307042012-07-27 15:51:34 -07001325 private boolean isItBedTimeYetLocked() {
Jeff Brown93cbbb22012-10-04 13:18:36 -07001326 return mBootCompleted && !isBeingKeptAwakeLocked();
Jeff Brown645832d2012-10-03 14:57:03 -07001327 }
1328
1329 /**
Jeff Brown93cbbb22012-10-04 13:18:36 -07001330 * Returns true if the device is being kept awake by a wake lock, user activity
Jeff Brown645832d2012-10-03 14:57:03 -07001331 * or the stay on while powered setting.
1332 */
Jeff Brown93cbbb22012-10-04 13:18:36 -07001333 private boolean isBeingKeptAwakeLocked() {
Jeff Brown645832d2012-10-03 14:57:03 -07001334 return mStayOn
Jeff Brown93cbbb22012-10-04 13:18:36 -07001335 || mProximityPositive
1336 || (mWakeLockSummary & (WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM)) != 0
Jeff Brown645832d2012-10-03 14:57:03 -07001337 || (mUserActivitySummary & (USER_ACTIVITY_SCREEN_BRIGHT
1338 | USER_ACTIVITY_SCREEN_DIM)) != 0;
Jeff Brown96307042012-07-27 15:51:34 -07001339 }
1340
1341 /**
1342 * Determines whether to post a message to the sandman to update the dream state.
1343 */
1344 private void updateDreamLocked(int dirty) {
John Spurlockf4f6b4c2012-08-25 12:08:03 -04001345 if ((dirty & (DIRTY_WAKEFULNESS
Jeff Brown645832d2012-10-03 14:57:03 -07001346 | DIRTY_USER_ACTIVITY
1347 | DIRTY_WAKE_LOCKS
1348 | DIRTY_BOOT_COMPLETED
John Spurlockf4f6b4c2012-08-25 12:08:03 -04001349 | DIRTY_SETTINGS
1350 | DIRTY_IS_POWERED
1351 | DIRTY_STAY_ON
Jeff Brown93cbbb22012-10-04 13:18:36 -07001352 | DIRTY_PROXIMITY_POSITIVE
Jeff Brown62c82e42012-09-26 01:30:41 -07001353 | DIRTY_BATTERY_STATE)) != 0) {
Jeff Brown96307042012-07-27 15:51:34 -07001354 scheduleSandmanLocked();
1355 }
1356 }
1357
1358 private void scheduleSandmanLocked() {
1359 if (!mSandmanScheduled) {
1360 mSandmanScheduled = true;
1361 Message msg = mHandler.obtainMessage(MSG_SANDMAN);
1362 msg.setAsynchronous(true);
1363 mHandler.sendMessage(msg);
1364 }
1365 }
1366
1367 /**
1368 * Called when the device enters or exits a napping or dreaming state.
1369 *
1370 * We do this asynchronously because we must call out of the power manager to start
1371 * the dream and we don't want to hold our lock while doing so. There is a risk that
1372 * the device will wake or go to sleep in the meantime so we have to handle that case.
1373 */
1374 private void handleSandman() { // runs on handler thread
1375 // Handle preconditions.
1376 boolean startDreaming = false;
1377 synchronized (mLock) {
1378 mSandmanScheduled = false;
John Spurlock10fb2242012-08-23 15:32:28 -04001379 boolean canDream = canDreamLocked();
Jeff Brown96307042012-07-27 15:51:34 -07001380 if (DEBUG_SPEW) {
John Spurlock10fb2242012-08-23 15:32:28 -04001381 Log.d(TAG, "handleSandman: canDream=" + canDream
Jeff Brown96307042012-07-27 15:51:34 -07001382 + ", mWakefulness=" + wakefulnessToString(mWakefulness));
1383 }
1384
John Spurlock10fb2242012-08-23 15:32:28 -04001385 if (canDream && mWakefulness == WAKEFULNESS_NAPPING) {
Jeff Brown96307042012-07-27 15:51:34 -07001386 startDreaming = true;
1387 }
1388 }
1389
Jeff Brown96307042012-07-27 15:51:34 -07001390 // Start dreaming if needed.
1391 // We only control the dream on the handler thread, so we don't need to worry about
1392 // concurrent attempts to start or stop the dream.
1393 boolean isDreaming = false;
1394 if (mDreamManager != null) {
Jeff Brown62c82e42012-09-26 01:30:41 -07001395 if (startDreaming) {
1396 mDreamManager.startDream();
Jeff Brown96307042012-07-27 15:51:34 -07001397 }
Jeff Brown62c82e42012-09-26 01:30:41 -07001398 isDreaming = mDreamManager.isDreaming();
Jeff Brown96307042012-07-27 15:51:34 -07001399 }
1400
1401 // Update dream state.
1402 // We might need to stop the dream again if the preconditions changed.
1403 boolean continueDreaming = false;
1404 synchronized (mLock) {
1405 if (isDreaming && canDreamLocked()) {
1406 if (mWakefulness == WAKEFULNESS_NAPPING) {
1407 mWakefulness = WAKEFULNESS_DREAMING;
1408 mDirty |= DIRTY_WAKEFULNESS;
1409 updatePowerStateLocked();
1410 continueDreaming = true;
1411 } else if (mWakefulness == WAKEFULNESS_DREAMING) {
1412 continueDreaming = true;
1413 }
1414 }
1415 if (!continueDreaming) {
1416 handleDreamFinishedLocked();
1417 }
Jeff Brown96307042012-07-27 15:51:34 -07001418 }
1419
1420 // Stop dreaming if needed.
1421 // It's possible that something else changed to make us need to start the dream again.
1422 // If so, then the power manager will have posted another message to the handler
1423 // to take care of it later.
1424 if (mDreamManager != null) {
Jeff Brown62c82e42012-09-26 01:30:41 -07001425 if (!continueDreaming) {
1426 mDreamManager.stopDream();
Jeff Brown96307042012-07-27 15:51:34 -07001427 }
1428 }
1429 }
1430
1431 /**
Jeff Brown645832d2012-10-03 14:57:03 -07001432 * Returns true if the device is allowed to dream in its current state
1433 * assuming that it is currently napping or dreaming.
Jeff Brown96307042012-07-27 15:51:34 -07001434 */
1435 private boolean canDreamLocked() {
Jeff Brown645832d2012-10-03 14:57:03 -07001436 return mDreamsSupportedConfig
John Spurlock10fb2242012-08-23 15:32:28 -04001437 && mDreamsEnabledSetting
Jeff Brown645832d2012-10-03 14:57:03 -07001438 && mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF
1439 && mBootCompleted
Jeff Brown93cbbb22012-10-04 13:18:36 -07001440 && (mIsPowered || isBeingKeptAwakeLocked());
Jeff Brown96307042012-07-27 15:51:34 -07001441 }
1442
1443 /**
1444 * Called when a dream is ending to figure out what to do next.
1445 */
1446 private void handleDreamFinishedLocked() {
1447 if (mWakefulness == WAKEFULNESS_NAPPING
1448 || mWakefulness == WAKEFULNESS_DREAMING) {
1449 if (isItBedTimeYetLocked()) {
1450 goToSleepNoUpdateLocked(SystemClock.uptimeMillis(),
1451 PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
1452 updatePowerStateLocked();
1453 } else {
1454 wakeUpNoUpdateLocked(SystemClock.uptimeMillis());
1455 updatePowerStateLocked();
1456 }
1457 }
1458 }
1459
Jeff Brownc38c9be2012-10-04 13:16:19 -07001460 private void handleScreenOnBlockerReleased() {
1461 synchronized (mLock) {
1462 mDirty |= DIRTY_SCREEN_ON_BLOCKER_RELEASED;
1463 updatePowerStateLocked();
1464 }
1465 }
1466
Jeff Brown96307042012-07-27 15:51:34 -07001467 /**
1468 * Updates the display power state asynchronously.
1469 * When the update is finished, mDisplayReady will be set to true. The display
1470 * controller posts a message to tell us when the actual display power state
1471 * has been updated so we come back here to double-check and finish up.
1472 *
1473 * This function recalculates the display power state each time.
1474 */
1475 private void updateDisplayPowerStateLocked(int dirty) {
1476 if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS
1477 | DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED
Jeff Brownc38c9be2012-10-04 13:16:19 -07001478 | DIRTY_SETTINGS | DIRTY_SCREEN_ON_BLOCKER_RELEASED)) != 0) {
1479 int newScreenState = getDesiredScreenPowerStateLocked();
Jeff Brown96307042012-07-27 15:51:34 -07001480 if (newScreenState != mDisplayPowerRequest.screenState) {
1481 if (newScreenState == DisplayPowerRequest.SCREEN_STATE_OFF
1482 && mDisplayPowerRequest.screenState
1483 != DisplayPowerRequest.SCREEN_STATE_OFF) {
1484 mLastScreenOffEventElapsedRealTime = SystemClock.elapsedRealtime();
1485 }
1486
1487 mDisplayPowerRequest.screenState = newScreenState;
1488 nativeSetPowerState(
1489 newScreenState != DisplayPowerRequest.SCREEN_STATE_OFF,
1490 newScreenState == DisplayPowerRequest.SCREEN_STATE_BRIGHT);
1491 }
1492
1493 int screenBrightness = mScreenBrightnessSettingDefault;
Jeff Brown330560f2012-08-21 22:10:57 -07001494 float screenAutoBrightnessAdjustment = 0.0f;
Jeff Brown96307042012-07-27 15:51:34 -07001495 boolean autoBrightness = (mScreenBrightnessModeSetting ==
1496 Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
1497 if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)) {
1498 screenBrightness = mScreenBrightnessOverrideFromWindowManager;
1499 autoBrightness = false;
1500 } else if (isValidBrightness(mTemporaryScreenBrightnessSettingOverride)) {
1501 screenBrightness = mTemporaryScreenBrightnessSettingOverride;
1502 } else if (isValidBrightness(mScreenBrightnessSetting)) {
Jeff Brown330560f2012-08-21 22:10:57 -07001503 screenBrightness = mScreenBrightnessSetting;
Jeff Brown96307042012-07-27 15:51:34 -07001504 }
1505 if (autoBrightness) {
1506 screenBrightness = mScreenBrightnessSettingDefault;
Jeff Brown330560f2012-08-21 22:10:57 -07001507 if (isValidAutoBrightnessAdjustment(
1508 mTemporaryScreenAutoBrightnessAdjustmentSettingOverride)) {
1509 screenAutoBrightnessAdjustment =
1510 mTemporaryScreenAutoBrightnessAdjustmentSettingOverride;
1511 } else if (isValidAutoBrightnessAdjustment(
1512 mScreenAutoBrightnessAdjustmentSetting)) {
1513 screenAutoBrightnessAdjustment = mScreenAutoBrightnessAdjustmentSetting;
1514 }
Jeff Brown96307042012-07-27 15:51:34 -07001515 }
1516 screenBrightness = Math.max(Math.min(screenBrightness,
1517 mScreenBrightnessSettingMaximum), mScreenBrightnessSettingMinimum);
Jeff Brown330560f2012-08-21 22:10:57 -07001518 screenAutoBrightnessAdjustment = Math.max(Math.min(
1519 screenAutoBrightnessAdjustment, 1.0f), -1.0f);
Jeff Brown96307042012-07-27 15:51:34 -07001520 mDisplayPowerRequest.screenBrightness = screenBrightness;
Jeff Brown330560f2012-08-21 22:10:57 -07001521 mDisplayPowerRequest.screenAutoBrightnessAdjustment =
1522 screenAutoBrightnessAdjustment;
Jeff Brown96307042012-07-27 15:51:34 -07001523 mDisplayPowerRequest.useAutoBrightness = autoBrightness;
1524
1525 mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
1526
Jeff Brownc38c9be2012-10-04 13:16:19 -07001527 mDisplayPowerRequest.blockScreenOn = mScreenOnBlocker.isHeld();
1528
Jeff Brown96307042012-07-27 15:51:34 -07001529 mDisplayReady = mDisplayPowerController.requestPowerState(mDisplayPowerRequest,
1530 mRequestWaitForNegativeProximity);
1531 mRequestWaitForNegativeProximity = false;
1532
1533 if (DEBUG_SPEW) {
Jeff Brownc38c9be2012-10-04 13:16:19 -07001534 Slog.d(TAG, "updateScreenStateLocked: mDisplayReady=" + mDisplayReady
Jeff Brown96307042012-07-27 15:51:34 -07001535 + ", newScreenState=" + newScreenState
1536 + ", mWakefulness=" + mWakefulness
1537 + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary)
1538 + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
1539 + ", mBootCompleted=" + mBootCompleted);
1540 }
1541 }
1542 }
1543
1544 private static boolean isValidBrightness(int value) {
1545 return value >= 0 && value <= 255;
1546 }
1547
Jeff Brown330560f2012-08-21 22:10:57 -07001548 private static boolean isValidAutoBrightnessAdjustment(float value) {
Jeff Brown5d03a532012-08-22 13:22:02 -07001549 // Handles NaN by always returning false.
1550 return value >= -1.0f && value <= 1.0f;
Jeff Brown330560f2012-08-21 22:10:57 -07001551 }
1552
Jeff Brownc38c9be2012-10-04 13:16:19 -07001553 private int getDesiredScreenPowerStateLocked() {
Jeff Brown96307042012-07-27 15:51:34 -07001554 if (mWakefulness == WAKEFULNESS_ASLEEP) {
1555 return DisplayPowerRequest.SCREEN_STATE_OFF;
1556 }
1557
1558 if ((mWakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0
1559 || (mUserActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0
1560 || !mBootCompleted) {
1561 return DisplayPowerRequest.SCREEN_STATE_BRIGHT;
1562 }
1563
1564 return DisplayPowerRequest.SCREEN_STATE_DIM;
1565 }
1566
1567 private final DisplayPowerController.Callbacks mDisplayPowerControllerCallbacks =
1568 new DisplayPowerController.Callbacks() {
1569 @Override
1570 public void onStateChanged() {
1571 mDirty |= DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED;
1572 updatePowerStateLocked();
Jim Miller92e66dd2012-02-21 18:57:12 -08001573 }
1574
1575 @Override
Jeff Brown93cbbb22012-10-04 13:18:36 -07001576 public void onProximityPositive() {
1577 mProximityPositive = true;
1578 mDirty |= DIRTY_PROXIMITY_POSITIVE;
1579 updatePowerStateLocked();
1580 }
1581
1582 @Override
Jeff Brown96307042012-07-27 15:51:34 -07001583 public void onProximityNegative() {
Jeff Brown93cbbb22012-10-04 13:18:36 -07001584 mProximityPositive = false;
1585 mDirty |= DIRTY_PROXIMITY_POSITIVE;
Jeff Brown96307042012-07-27 15:51:34 -07001586 userActivityNoUpdateLocked(SystemClock.uptimeMillis(),
1587 PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
1588 updatePowerStateLocked();
1589 }
1590 };
Jim Miller92e66dd2012-02-21 18:57:12 -08001591
Jeff Brown96307042012-07-27 15:51:34 -07001592 private boolean shouldUseProximitySensorLocked() {
1593 return (mWakeLockSummary & WAKE_LOCK_PROXIMITY_SCREEN_OFF) != 0;
1594 }
Jim Miller92e66dd2012-02-21 18:57:12 -08001595
Jeff Brown96307042012-07-27 15:51:34 -07001596 /**
1597 * Updates the suspend blocker that keeps the CPU alive.
1598 *
1599 * This function must have no other side-effects.
1600 */
1601 private void updateSuspendBlockerLocked() {
1602 boolean wantCpu = isCpuNeededLocked();
1603 if (wantCpu != mHoldingWakeLockSuspendBlocker) {
1604 mHoldingWakeLockSuspendBlocker = wantCpu;
1605 if (wantCpu) {
1606 if (DEBUG) {
1607 Slog.d(TAG, "updateSuspendBlockerLocked: Acquiring suspend blocker.");
Jim Miller92e66dd2012-02-21 18:57:12 -08001608 }
Jeff Brown96307042012-07-27 15:51:34 -07001609 mWakeLockSuspendBlocker.acquire();
Joe Onorato4b9f62d2010-10-11 13:41:35 -07001610 } else {
Jeff Brown96307042012-07-27 15:51:34 -07001611 if (DEBUG) {
1612 Slog.d(TAG, "updateSuspendBlockerLocked: Releasing suspend blocker.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001613 }
Jeff Brown96307042012-07-27 15:51:34 -07001614 mWakeLockSuspendBlocker.release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001615 }
1616 }
1617 }
1618
Jeff Brown96307042012-07-27 15:51:34 -07001619 private boolean isCpuNeededLocked() {
1620 return !mBootCompleted
1621 || mWakeLockSummary != 0
1622 || mUserActivitySummary != 0
1623 || mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF
1624 || !mDisplayReady;
1625 }
1626
1627 @Override // Binder call
1628 public boolean isScreenOn() {
1629 final long ident = Binder.clearCallingIdentity();
Mike Lockwoodd7786b42009-10-15 17:09:16 -07001630 try {
Jeff Brown96307042012-07-27 15:51:34 -07001631 return isScreenOnInternal();
1632 } finally {
1633 Binder.restoreCallingIdentity(ident);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07001634 }
1635 }
1636
Jeff Brown96307042012-07-27 15:51:34 -07001637 private boolean isScreenOnInternal() {
1638 synchronized (mLock) {
1639 return !mSystemReady
1640 || mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF;
Mike Lockwoodb2865412010-02-02 22:40:33 -05001641 }
1642 }
1643
Jeff Brown96307042012-07-27 15:51:34 -07001644 private void handleBatteryStateChangedLocked() {
1645 mDirty |= DIRTY_BATTERY_STATE;
1646 updatePowerStateLocked();
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001647 }
1648
Jeff Brown96307042012-07-27 15:51:34 -07001649 private void handleBootCompletedLocked() {
1650 final long now = SystemClock.uptimeMillis();
1651 mBootCompleted = true;
1652 mDirty |= DIRTY_BOOT_COMPLETED;
1653 userActivityNoUpdateLocked(
1654 now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
1655 updatePowerStateLocked();
Dianne Hackborn254cb442010-01-27 19:23:59 -08001656 }
1657
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001658 /**
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001659 * Reboot the device, passing 'reason' (may be null)
Doug Zongker50a21f42009-11-19 12:49:53 -08001660 * to the underlying __reboot system call. Should not return.
1661 */
Jeff Brown96307042012-07-27 15:51:34 -07001662 @Override // Binder call
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001663 public void reboot(boolean confirm, String reason, boolean wait) {
Doug Zongker50a21f42009-11-19 12:49:53 -08001664 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
San Mehat14e69af2010-01-06 14:58:18 -08001665
Jeff Brown96307042012-07-27 15:51:34 -07001666 final long ident = Binder.clearCallingIdentity();
1667 try {
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001668 rebootInternal(false, confirm, reason, wait);
Jeff Brown96307042012-07-27 15:51:34 -07001669 } finally {
1670 Binder.restoreCallingIdentity(ident);
1671 }
1672 }
1673
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001674 /**
1675 * Shutdown the devic, passing 'reason' (may be null)
1676 * to the underlying __reboot system call. Should not return.
1677 */
1678 @Override // Binder call
1679 public void shutdown(boolean confirm, boolean wait) {
1680 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
1681
1682 final long ident = Binder.clearCallingIdentity();
1683 try {
1684 rebootInternal(true, confirm, null, wait);
1685 } finally {
1686 Binder.restoreCallingIdentity(ident);
1687 }
1688 }
1689
1690 private void rebootInternal(final boolean shutdown, final boolean confirm,
1691 final String reason, boolean wait) {
Jeff Brown96307042012-07-27 15:51:34 -07001692 if (mHandler == null || !mSystemReady) {
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001693 throw new IllegalStateException("Too early to call reboot()");
1694 }
Mike Lockwoodb62f9592010-03-12 07:55:23 -05001695
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001696 Runnable runnable = new Runnable() {
1697 public void run() {
1698 synchronized (this) {
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001699 if (shutdown) {
1700 ShutdownThread.shutdown(mContext, confirm);
1701 } else {
1702 ShutdownThread.reboot(mContext, reason, confirm);
1703 }
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001704 }
San Mehat1e512792010-01-07 10:40:29 -08001705 }
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001706 };
Jeff Brown96307042012-07-27 15:51:34 -07001707
Mike Lockwoodb62f9592010-03-12 07:55:23 -05001708 // ShutdownThread must run on a looper capable of displaying the UI.
Jeff Brown96307042012-07-27 15:51:34 -07001709 Message msg = Message.obtain(mHandler, runnable);
1710 msg.setAsynchronous(true);
1711 mHandler.sendMessage(msg);
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001712
Mike Lockwoodb62f9592010-03-12 07:55:23 -05001713 // PowerManager.reboot() is documented not to return so just wait for the inevitable.
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001714 if (wait) {
1715 synchronized (runnable) {
1716 while (true) {
1717 try {
1718 runnable.wait();
1719 } catch (InterruptedException e) {
1720 }
Mike Lockwoodb62f9592010-03-12 07:55:23 -05001721 }
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001722 }
Doug Zongker50a21f42009-11-19 12:49:53 -08001723 }
1724 }
1725
Dan Egnor60d87622009-12-16 16:32:58 -08001726 /**
1727 * Crash the runtime (causing a complete restart of the Android framework).
1728 * Requires REBOOT permission. Mostly for testing. Should not return.
1729 */
Jeff Brown96307042012-07-27 15:51:34 -07001730 @Override // Binder call
1731 public void crash(String message) {
Dan Egnor60d87622009-12-16 16:32:58 -08001732 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
Jeff Brown96307042012-07-27 15:51:34 -07001733
1734 final long ident = Binder.clearCallingIdentity();
1735 try {
1736 crashInternal(message);
1737 } finally {
1738 Binder.restoreCallingIdentity(ident);
1739 }
1740 }
1741
1742 private void crashInternal(final String message) {
Dan Egnor60d87622009-12-16 16:32:58 -08001743 Thread t = new Thread("PowerManagerService.crash()") {
Jeff Brown96307042012-07-27 15:51:34 -07001744 public void run() {
1745 throw new RuntimeException(message);
1746 }
Dan Egnor60d87622009-12-16 16:32:58 -08001747 };
1748 try {
1749 t.start();
1750 t.join();
1751 } catch (InterruptedException e) {
1752 Log.wtf(TAG, e);
1753 }
1754 }
1755
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001756 /**
Jeff Brown96307042012-07-27 15:51:34 -07001757 * Set the setting that determines whether the device stays on when plugged in.
1758 * The argument is a bit string, with each bit specifying a power source that,
1759 * when the device is connected to that source, causes the device to stay on.
1760 * See {@link android.os.BatteryManager} for the list of power sources that
1761 * can be specified. Current values include {@link android.os.BatteryManager#BATTERY_PLUGGED_AC}
1762 * and {@link android.os.BatteryManager#BATTERY_PLUGGED_USB}
1763 *
1764 * Used by "adb shell svc power stayon ..."
1765 *
1766 * @param val an {@code int} containing the bits that specify which power sources
1767 * should cause the device to stay on.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001768 */
Jeff Brown96307042012-07-27 15:51:34 -07001769 @Override // Binder call
1770 public void setStayOnSetting(int val) {
1771 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS, null);
1772
1773 final long ident = Binder.clearCallingIdentity();
1774 try {
1775 setStayOnSettingInternal(val);
1776 } finally {
1777 Binder.restoreCallingIdentity(ident);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001778 }
1779 }
1780
Jeff Brown96307042012-07-27 15:51:34 -07001781 private void setStayOnSettingInternal(int val) {
Christopher Tatead735322012-09-07 14:19:43 -07001782 Settings.Global.putInt(mContext.getContentResolver(),
1783 Settings.Global.STAY_ON_WHILE_PLUGGED_IN, val);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001784 }
1785
1786 /**
Jeff Brown96307042012-07-27 15:51:34 -07001787 * Used by device administration to set the maximum screen off timeout.
1788 *
1789 * This method must only be called by the device administration policy manager.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001790 */
Jeff Brown96307042012-07-27 15:51:34 -07001791 @Override // Binder call
1792 public void setMaximumScreenOffTimeoutFromDeviceAdmin(int timeMs) {
1793 final long ident = Binder.clearCallingIdentity();
1794 try {
1795 setMaximumScreenOffTimeoutFromDeviceAdminInternal(timeMs);
1796 } finally {
1797 Binder.restoreCallingIdentity(ident);
Michael Chane96440f2009-05-06 10:27:36 -07001798 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001799 }
1800
Jeff Brown96307042012-07-27 15:51:34 -07001801 private void setMaximumScreenOffTimeoutFromDeviceAdminInternal(int timeMs) {
1802 synchronized (mLock) {
1803 mMaximumScreenOffTimeoutFromDeviceAdmin = timeMs;
1804 mDirty |= DIRTY_SETTINGS;
1805 updatePowerStateLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001806 }
1807 }
1808
Jeff Brown96307042012-07-27 15:51:34 -07001809 private boolean isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked() {
1810 return mMaximumScreenOffTimeoutFromDeviceAdmin >= 0
1811 && mMaximumScreenOffTimeoutFromDeviceAdmin < Integer.MAX_VALUE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001812 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001813
Jeff Brown96307042012-07-27 15:51:34 -07001814 /**
1815 * Used by the phone application to make the attention LED flash when ringing.
1816 */
1817 @Override // Binder call
Mike Lockwoodb11832d2009-11-25 15:25:55 -05001818 public void setAttentionLight(boolean on, int color) {
1819 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
Jeff Brown96307042012-07-27 15:51:34 -07001820
1821 final long ident = Binder.clearCallingIdentity();
1822 try {
1823 setAttentionLightInternal(on, color);
1824 } finally {
1825 Binder.restoreCallingIdentity(ident);
1826 }
Mike Lockwoodb11832d2009-11-25 15:25:55 -05001827 }
1828
Jeff Brown96307042012-07-27 15:51:34 -07001829 private void setAttentionLightInternal(boolean on, int color) {
1830 LightsService.Light light;
1831 synchronized (mLock) {
1832 if (!mSystemReady) {
1833 return;
1834 }
1835 light = mAttentionLight;
Mike Lockwood36fc3022009-08-25 16:49:06 -07001836 }
Jeff Brown96307042012-07-27 15:51:34 -07001837
1838 // Control light outside of lock.
1839 light.setFlashing(color, LightsService.LIGHT_FLASH_HARDWARE, (on ? 3 : 0), 0);
1840 }
1841
1842 /**
1843 * Used by the Watchdog.
1844 */
1845 public long timeSinceScreenWasLastOn() {
1846 synchronized (mLock) {
1847 if (mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF) {
1848 return 0;
1849 }
1850 return SystemClock.elapsedRealtime() - mLastScreenOffEventElapsedRealTime;
1851 }
1852 }
1853
1854 /**
1855 * Used by the window manager to override the screen brightness based on the
1856 * current foreground activity.
1857 *
1858 * This method must only be called by the window manager.
1859 *
1860 * @param brightness The overridden brightness, or -1 to disable the override.
1861 */
1862 public void setScreenBrightnessOverrideFromWindowManager(int brightness) {
1863 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1864
1865 final long ident = Binder.clearCallingIdentity();
1866 try {
1867 setScreenBrightnessOverrideFromWindowManagerInternal(brightness);
1868 } finally {
1869 Binder.restoreCallingIdentity(ident);
1870 }
1871 }
1872
1873 private void setScreenBrightnessOverrideFromWindowManagerInternal(int brightness) {
1874 synchronized (mLock) {
1875 if (mScreenBrightnessOverrideFromWindowManager != brightness) {
1876 mScreenBrightnessOverrideFromWindowManager = brightness;
1877 mDirty |= DIRTY_SETTINGS;
1878 updatePowerStateLocked();
Mike Lockwoodee2b0942009-11-09 14:09:02 -05001879 }
Mike Lockwood809ad0f2009-10-26 22:10:33 -04001880 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07001881 }
1882
Jeff Brown96307042012-07-27 15:51:34 -07001883 /**
1884 * Used by the window manager to override the button brightness based on the
1885 * current foreground activity.
1886 *
1887 * This method must only be called by the window manager.
1888 *
1889 * @param brightness The overridden brightness, or -1 to disable the override.
1890 */
1891 public void setButtonBrightnessOverrideFromWindowManager(int brightness) {
1892 // Do nothing.
1893 // Button lights are not currently supported in the new implementation.
1894 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1895 }
1896
1897 /**
Jeff Brown1e3b98d2012-09-30 18:58:59 -07001898 * Used by the window manager to override the user activity timeout based on the
1899 * current foreground activity. It can only be used to make the timeout shorter
1900 * than usual, not longer.
1901 *
1902 * This method must only be called by the window manager.
1903 *
1904 * @param timeoutMillis The overridden timeout, or -1 to disable the override.
1905 */
1906 public void setUserActivityTimeoutOverrideFromWindowManager(long timeoutMillis) {
1907 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1908
1909 final long ident = Binder.clearCallingIdentity();
1910 try {
1911 setUserActivityTimeoutOverrideFromWindowManagerInternal(timeoutMillis);
1912 } finally {
1913 Binder.restoreCallingIdentity(ident);
1914 }
1915 }
1916
1917 private void setUserActivityTimeoutOverrideFromWindowManagerInternal(long timeoutMillis) {
1918 synchronized (mLock) {
1919 if (mUserActivityTimeoutOverrideFromWindowManager != timeoutMillis) {
1920 mUserActivityTimeoutOverrideFromWindowManager = timeoutMillis;
1921 mDirty |= DIRTY_SETTINGS;
1922 updatePowerStateLocked();
1923 }
1924 }
1925 }
1926
1927 /**
Jeff Brown96307042012-07-27 15:51:34 -07001928 * Used by the settings application and brightness control widgets to
1929 * temporarily override the current screen brightness setting so that the
1930 * user can observe the effect of an intended settings change without applying
1931 * it immediately.
1932 *
1933 * The override will be canceled when the setting value is next updated.
1934 *
1935 * @param brightness The overridden brightness.
1936 *
1937 * @see Settings.System#SCREEN_BRIGHTNESS
1938 */
1939 @Override // Binder call
1940 public void setTemporaryScreenBrightnessSettingOverride(int brightness) {
1941 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1942
1943 final long ident = Binder.clearCallingIdentity();
1944 try {
1945 setTemporaryScreenBrightnessSettingOverrideInternal(brightness);
1946 } finally {
1947 Binder.restoreCallingIdentity(ident);
Mike Lockwood36fc3022009-08-25 16:49:06 -07001948 }
Jeff Brown96307042012-07-27 15:51:34 -07001949 }
1950
1951 private void setTemporaryScreenBrightnessSettingOverrideInternal(int brightness) {
1952 synchronized (mLock) {
1953 if (mTemporaryScreenBrightnessSettingOverride != brightness) {
1954 mTemporaryScreenBrightnessSettingOverride = brightness;
1955 mDirty |= DIRTY_SETTINGS;
1956 updatePowerStateLocked();
Mike Lockwoodee2b0942009-11-09 14:09:02 -05001957 }
Mike Lockwood200b30b2009-09-20 00:23:59 -04001958 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07001959 }
1960
Jeff Brown96307042012-07-27 15:51:34 -07001961 /**
1962 * Used by the settings application and brightness control widgets to
1963 * temporarily override the current screen auto-brightness adjustment setting so that the
1964 * user can observe the effect of an intended settings change without applying
1965 * it immediately.
1966 *
1967 * The override will be canceled when the setting value is next updated.
1968 *
Jeff Brown330560f2012-08-21 22:10:57 -07001969 * @param adj The overridden brightness, or Float.NaN to disable the override.
Jeff Brown96307042012-07-27 15:51:34 -07001970 *
1971 * @see Settings.System#SCREEN_AUTO_BRIGHTNESS_ADJ
1972 */
1973 @Override // Binder call
1974 public void setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(float adj) {
Jeff Brown96307042012-07-27 15:51:34 -07001975 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
Jeff Brown330560f2012-08-21 22:10:57 -07001976
1977 final long ident = Binder.clearCallingIdentity();
1978 try {
1979 setTemporaryScreenAutoBrightnessAdjustmentSettingOverrideInternal(adj);
1980 } finally {
1981 Binder.restoreCallingIdentity(ident);
1982 }
1983 }
1984
1985 private void setTemporaryScreenAutoBrightnessAdjustmentSettingOverrideInternal(float adj) {
1986 synchronized (mLock) {
1987 // Note: This condition handles NaN because NaN is not equal to any other
1988 // value, including itself.
1989 if (mTemporaryScreenAutoBrightnessAdjustmentSettingOverride != adj) {
1990 mTemporaryScreenAutoBrightnessAdjustmentSettingOverride = adj;
1991 mDirty |= DIRTY_SETTINGS;
1992 updatePowerStateLocked();
1993 }
1994 }
Jeff Brown96307042012-07-27 15:51:34 -07001995 }
1996
1997 /**
1998 * Low-level function turn the device off immediately, without trying
1999 * to be clean. Most people should use {@link ShutdownThread} for a clean shutdown.
2000 */
2001 public static void lowLevelShutdown() {
2002 nativeShutdown();
2003 }
2004
2005 /**
2006 * Low-level function to reboot the device.
2007 *
2008 * @param reason code to pass to the kernel (e.g. "recovery"), or null.
2009 * @throws IOException if reboot fails for some reason (eg, lack of
2010 * permission)
2011 */
2012 public static void lowLevelReboot(String reason) throws IOException {
2013 nativeReboot(reason);
2014 }
2015
2016 @Override // Watchdog.Monitor implementation
2017 public void monitor() {
2018 // Grab and release lock for watchdog monitor to detect deadlocks.
2019 synchronized (mLock) {
Mike Lockwood20f87d72009-11-05 16:08:51 -05002020 }
Jeff Brown96307042012-07-27 15:51:34 -07002021 }
2022
2023 @Override // Binder call
2024 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2025 if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
2026 != PackageManager.PERMISSION_GRANTED) {
2027 pw.println("Permission Denial: can't dump PowerManager from from pid="
2028 + Binder.getCallingPid()
2029 + ", uid=" + Binder.getCallingUid());
Mike Lockwood0d72f7e2009-11-05 20:53:00 -05002030 return;
2031 }
Jeff Brown96307042012-07-27 15:51:34 -07002032
2033 pw.println("POWER MANAGER (dumpsys power)\n");
2034
2035 final DisplayPowerController dpc;
2036 synchronized (mLock) {
2037 pw.println("Power Manager State:");
2038 pw.println(" mDirty=0x" + Integer.toHexString(mDirty));
2039 pw.println(" mWakefulness=" + wakefulnessToString(mWakefulness));
2040 pw.println(" mIsPowered=" + mIsPowered);
Jeff Brownf3fb8952012-10-02 20:57:05 -07002041 pw.println(" mPlugType=" + mPlugType);
Jeff Brown96307042012-07-27 15:51:34 -07002042 pw.println(" mStayOn=" + mStayOn);
Jeff Brown93cbbb22012-10-04 13:18:36 -07002043 pw.println(" mProximityPositive=" + mProximityPositive);
Jeff Brown96307042012-07-27 15:51:34 -07002044 pw.println(" mBootCompleted=" + mBootCompleted);
2045 pw.println(" mSystemReady=" + mSystemReady);
2046 pw.println(" mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary));
2047 pw.println(" mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary));
2048 pw.println(" mRequestWaitForNegativeProximity=" + mRequestWaitForNegativeProximity);
2049 pw.println(" mSandmanScheduled=" + mSandmanScheduled);
2050 pw.println(" mLastWakeTime=" + TimeUtils.formatUptime(mLastWakeTime));
2051 pw.println(" mLastSleepTime=" + TimeUtils.formatUptime(mLastSleepTime));
2052 pw.println(" mSendWakeUpFinishedNotificationWhenReady="
2053 + mSendWakeUpFinishedNotificationWhenReady);
2054 pw.println(" mSendGoToSleepFinishedNotificationWhenReady="
2055 + mSendGoToSleepFinishedNotificationWhenReady);
2056 pw.println(" mLastUserActivityTime=" + TimeUtils.formatUptime(mLastUserActivityTime));
2057 pw.println(" mLastUserActivityTimeNoChangeLights="
2058 + TimeUtils.formatUptime(mLastUserActivityTimeNoChangeLights));
2059 pw.println(" mDisplayReady=" + mDisplayReady);
2060 pw.println(" mHoldingWakeLockSuspendBlocker=" + mHoldingWakeLockSuspendBlocker);
2061
2062 pw.println();
2063 pw.println("Settings and Configuration:");
2064 pw.println(" mDreamsSupportedConfig=" + mDreamsSupportedConfig);
2065 pw.println(" mDreamsEnabledSetting=" + mDreamsEnabledSetting);
John Spurlock1a868b72012-08-22 09:56:51 -04002066 pw.println(" mDreamsActivateOnSleepSetting=" + mDreamsActivateOnSleepSetting);
Jeff Brown96307042012-07-27 15:51:34 -07002067 pw.println(" mScreenOffTimeoutSetting=" + mScreenOffTimeoutSetting);
2068 pw.println(" mMaximumScreenOffTimeoutFromDeviceAdmin="
2069 + mMaximumScreenOffTimeoutFromDeviceAdmin + " (enforced="
2070 + isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked() + ")");
2071 pw.println(" mStayOnWhilePluggedInSetting=" + mStayOnWhilePluggedInSetting);
2072 pw.println(" mScreenBrightnessSetting=" + mScreenBrightnessSetting);
Jeff Brown330560f2012-08-21 22:10:57 -07002073 pw.println(" mScreenAutoBrightnessAdjustmentSetting="
2074 + mScreenAutoBrightnessAdjustmentSetting);
Jeff Brown96307042012-07-27 15:51:34 -07002075 pw.println(" mScreenBrightnessModeSetting=" + mScreenBrightnessModeSetting);
2076 pw.println(" mScreenBrightnessOverrideFromWindowManager="
2077 + mScreenBrightnessOverrideFromWindowManager);
Jeff Brown1e3b98d2012-09-30 18:58:59 -07002078 pw.println(" mUserActivityTimeoutOverrideFromWindowManager="
2079 + mUserActivityTimeoutOverrideFromWindowManager);
Jeff Brown96307042012-07-27 15:51:34 -07002080 pw.println(" mTemporaryScreenBrightnessSettingOverride="
2081 + mTemporaryScreenBrightnessSettingOverride);
Jeff Brown330560f2012-08-21 22:10:57 -07002082 pw.println(" mTemporaryScreenAutoBrightnessAdjustmentSettingOverride="
2083 + mTemporaryScreenAutoBrightnessAdjustmentSettingOverride);
Jeff Brown96307042012-07-27 15:51:34 -07002084 pw.println(" mScreenBrightnessSettingMinimum=" + mScreenBrightnessSettingMinimum);
2085 pw.println(" mScreenBrightnessSettingMaximum=" + mScreenBrightnessSettingMaximum);
2086 pw.println(" mScreenBrightnessSettingDefault=" + mScreenBrightnessSettingDefault);
2087
Jeff Brownff532542012-10-02 21:18:04 -07002088 final int screenOffTimeout = getScreenOffTimeoutLocked();
2089 final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
2090 pw.println();
2091 pw.println("Screen off timeout: " + screenOffTimeout + " ms");
2092 pw.println("Screen dim duration: " + screenDimDuration + " ms");
2093
Jeff Brown96307042012-07-27 15:51:34 -07002094 pw.println();
2095 pw.println("Wake Locks: size=" + mWakeLocks.size());
2096 for (WakeLock wl : mWakeLocks) {
2097 pw.println(" " + wl);
Joe Onorato8274a0e2010-10-05 17:38:09 -04002098 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05002099
Jeff Brown96307042012-07-27 15:51:34 -07002100 pw.println();
2101 pw.println("Suspend Blockers: size=" + mSuspendBlockers.size());
2102 for (SuspendBlocker sb : mSuspendBlockers) {
2103 pw.println(" " + sb);
2104 }
2105
Jeff Brownc38c9be2012-10-04 13:16:19 -07002106 pw.println();
2107 pw.println("Screen On Blocker: " + mScreenOnBlocker);
2108
Jeff Brown96307042012-07-27 15:51:34 -07002109 dpc = mDisplayPowerController;
2110 }
2111
2112 if (dpc != null) {
2113 dpc.dump(pw);
2114 }
2115 }
2116
2117 private SuspendBlocker createSuspendBlockerLocked(String name) {
2118 SuspendBlocker suspendBlocker = new SuspendBlockerImpl(name);
2119 mSuspendBlockers.add(suspendBlocker);
2120 return suspendBlocker;
2121 }
2122
2123 private static String wakefulnessToString(int wakefulness) {
2124 switch (wakefulness) {
2125 case WAKEFULNESS_ASLEEP:
2126 return "Asleep";
2127 case WAKEFULNESS_AWAKE:
2128 return "Awake";
2129 case WAKEFULNESS_DREAMING:
2130 return "Dreaming";
2131 case WAKEFULNESS_NAPPING:
2132 return "Napping";
2133 default:
2134 return Integer.toString(wakefulness);
2135 }
2136 }
2137
2138 private static WorkSource copyWorkSource(WorkSource workSource) {
2139 return workSource != null ? new WorkSource(workSource) : null;
2140 }
2141
2142 private final class BatteryReceiver extends BroadcastReceiver {
2143 @Override
2144 public void onReceive(Context context, Intent intent) {
2145 synchronized (mLock) {
2146 handleBatteryStateChangedLocked();
Mike Lockwoodee2b0942009-11-09 14:09:02 -05002147 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05002148 }
2149 }
2150
Jeff Brown96307042012-07-27 15:51:34 -07002151 private final class BootCompletedReceiver extends BroadcastReceiver {
2152 @Override
2153 public void onReceive(Context context, Intent intent) {
2154 synchronized (mLock) {
2155 handleBootCompletedLocked();
2156 }
Joe Onoratod28f7532010-11-06 12:56:53 -07002157 }
Jeff Brown96307042012-07-27 15:51:34 -07002158 }
2159
John Spurlockf4f6b4c2012-08-25 12:08:03 -04002160 private final class DreamReceiver extends BroadcastReceiver {
2161 @Override
2162 public void onReceive(Context context, Intent intent) {
2163 synchronized (mLock) {
Jeff Brown62c82e42012-09-26 01:30:41 -07002164 scheduleSandmanLocked();
John Spurlockf4f6b4c2012-08-25 12:08:03 -04002165 }
2166 }
2167 }
2168
Jeff Brownd4935962012-09-25 13:27:20 -07002169 private final class UserSwitchedReceiver extends BroadcastReceiver {
2170 @Override
2171 public void onReceive(Context context, Intent intent) {
2172 synchronized (mLock) {
2173 handleSettingsChangedLocked();
2174 }
2175 }
2176 }
2177
Jeff Brown96307042012-07-27 15:51:34 -07002178 private final class SettingsObserver extends ContentObserver {
2179 public SettingsObserver(Handler handler) {
2180 super(handler);
2181 }
2182
2183 @Override
2184 public void onChange(boolean selfChange, Uri uri) {
2185 synchronized (mLock) {
2186 handleSettingsChangedLocked();
2187 }
2188 }
2189 }
2190
Jeff Brown96307042012-07-27 15:51:34 -07002191 /**
2192 * Handler for asynchronous operations performed by the power manager.
2193 */
2194 private final class PowerManagerHandler extends Handler {
2195 public PowerManagerHandler(Looper looper) {
Jeff Browna2910d02012-08-25 12:29:46 -07002196 super(looper, null, true /*async*/);
Jeff Brown96307042012-07-27 15:51:34 -07002197 }
2198
2199 @Override
2200 public void handleMessage(Message msg) {
2201 switch (msg.what) {
2202 case MSG_USER_ACTIVITY_TIMEOUT:
2203 handleUserActivityTimeout();
2204 break;
2205 case MSG_SANDMAN:
2206 handleSandman();
2207 break;
Jeff Brownc38c9be2012-10-04 13:16:19 -07002208 case MSG_SCREEN_ON_BLOCKER_RELEASED:
2209 handleScreenOnBlockerReleased();
2210 break;
Jeff Brown96307042012-07-27 15:51:34 -07002211 }
2212 }
2213 }
2214
2215 /**
2216 * Represents a wake lock that has been acquired by an application.
2217 */
2218 private final class WakeLock implements IBinder.DeathRecipient {
2219 public final IBinder mLock;
2220 public int mFlags;
2221 public String mTag;
2222 public WorkSource mWorkSource;
2223 public int mOwnerUid;
2224 public int mOwnerPid;
2225
2226 public WakeLock(IBinder lock, int flags, String tag, WorkSource workSource,
2227 int ownerUid, int ownerPid) {
2228 mLock = lock;
2229 mFlags = flags;
2230 mTag = tag;
2231 mWorkSource = copyWorkSource(workSource);
2232 mOwnerUid = ownerUid;
2233 mOwnerPid = ownerPid;
2234 }
2235
2236 @Override
2237 public void binderDied() {
2238 PowerManagerService.this.handleWakeLockDeath(this);
2239 }
2240
2241 public boolean hasSameProperties(int flags, String tag, WorkSource workSource,
2242 int ownerUid, int ownerPid) {
2243 return mFlags == flags
2244 && mTag.equals(tag)
2245 && hasSameWorkSource(workSource)
2246 && mOwnerUid == ownerUid
2247 && mOwnerPid == ownerPid;
2248 }
2249
2250 public void updateProperties(int flags, String tag, WorkSource workSource,
2251 int ownerUid, int ownerPid) {
2252 mFlags = flags;
2253 mTag = tag;
2254 updateWorkSource(workSource);
2255 mOwnerUid = ownerUid;
2256 mOwnerPid = ownerPid;
2257 }
2258
2259 public boolean hasSameWorkSource(WorkSource workSource) {
2260 return Objects.equal(mWorkSource, workSource);
2261 }
2262
2263 public void updateWorkSource(WorkSource workSource) {
2264 mWorkSource = copyWorkSource(workSource);
2265 }
2266
2267 @Override
2268 public String toString() {
2269 return getLockLevelString()
2270 + " '" + mTag + "'" + getLockFlagsString()
2271 + " (uid=" + mOwnerUid + ", pid=" + mOwnerPid + ", ws=" + mWorkSource + ")";
2272 }
2273
2274 private String getLockLevelString() {
2275 switch (mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
2276 case PowerManager.FULL_WAKE_LOCK:
2277 return "FULL_WAKE_LOCK ";
2278 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
2279 return "SCREEN_BRIGHT_WAKE_LOCK ";
2280 case PowerManager.SCREEN_DIM_WAKE_LOCK:
2281 return "SCREEN_DIM_WAKE_LOCK ";
2282 case PowerManager.PARTIAL_WAKE_LOCK:
2283 return "PARTIAL_WAKE_LOCK ";
2284 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
2285 return "PROXIMITY_SCREEN_OFF_WAKE_LOCK";
2286 default:
2287 return "??? ";
2288 }
2289 }
2290
2291 private String getLockFlagsString() {
2292 String result = "";
2293 if ((mFlags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {
2294 result += " ACQUIRE_CAUSES_WAKEUP";
2295 }
2296 if ((mFlags & PowerManager.ON_AFTER_RELEASE) != 0) {
2297 result += " ON_AFTER_RELEASE";
2298 }
2299 return result;
2300 }
2301 }
2302
2303 private final class SuspendBlockerImpl implements SuspendBlocker {
2304 private final String mName;
2305 private int mReferenceCount;
2306
2307 public SuspendBlockerImpl(String name) {
2308 mName = name;
2309 }
2310
2311 @Override
2312 protected void finalize() throws Throwable {
Mike Lockwood809ad0f2009-10-26 22:10:33 -04002313 try {
Jeff Brown96307042012-07-27 15:51:34 -07002314 if (mReferenceCount != 0) {
2315 Log.wtf(TAG, "Suspend blocker \"" + mName
2316 + "\" was finalized without being released!");
2317 mReferenceCount = 0;
2318 nativeReleaseSuspendBlocker(mName);
Mike Lockwood809ad0f2009-10-26 22:10:33 -04002319 }
2320 } finally {
Jeff Brown96307042012-07-27 15:51:34 -07002321 super.finalize();
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002322 }
2323 }
2324
Craig Mautner75fc9de2012-06-18 16:53:27 -07002325 @Override
Jeff Brown96307042012-07-27 15:51:34 -07002326 public void acquire() {
2327 synchronized (this) {
2328 mReferenceCount += 1;
2329 if (mReferenceCount == 1) {
2330 nativeAcquireSuspendBlocker(mName);
Craig Mautner37933682012-06-06 14:13:39 -07002331 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002332 }
2333 }
2334
Craig Mautner75fc9de2012-06-18 16:53:27 -07002335 @Override
Jeff Brown96307042012-07-27 15:51:34 -07002336 public void release() {
2337 synchronized (this) {
2338 mReferenceCount -= 1;
2339 if (mReferenceCount == 0) {
2340 nativeReleaseSuspendBlocker(mName);
2341 } else if (mReferenceCount < 0) {
2342 Log.wtf(TAG, "Suspend blocker \"" + mName
2343 + "\" was released without being acquired!", new Throwable());
2344 mReferenceCount = 0;
2345 }
2346 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002347 }
Jeff Brown96307042012-07-27 15:51:34 -07002348
2349 @Override
2350 public String toString() {
2351 synchronized (this) {
2352 return mName + ": ref count=" + mReferenceCount;
2353 }
2354 }
2355 }
Jeff Brownc38c9be2012-10-04 13:16:19 -07002356
2357 private final class ScreenOnBlockerImpl implements ScreenOnBlocker {
2358 private int mNestCount;
2359
2360 public boolean isHeld() {
2361 synchronized (this) {
2362 return mNestCount != 0;
2363 }
2364 }
2365
2366 @Override
2367 public void acquire() {
2368 synchronized (this) {
2369 mNestCount += 1;
2370 if (DEBUG) {
2371 Slog.d(TAG, "Screen on blocked: mNestCount=" + mNestCount);
2372 }
2373 }
2374 }
2375
2376 @Override
2377 public void release() {
2378 synchronized (this) {
2379 mNestCount -= 1;
2380 if (mNestCount < 0) {
2381 Log.wtf(TAG, "Screen on blocker was released without being acquired!",
2382 new Throwable());
2383 mNestCount = 0;
2384 }
2385 if (mNestCount == 0) {
2386 mHandler.sendEmptyMessage(MSG_SCREEN_ON_BLOCKER_RELEASED);
2387 }
2388 if (DEBUG) {
2389 Slog.d(TAG, "Screen on unblocked: mNestCount=" + mNestCount);
2390 }
2391 }
2392 }
2393
2394 @Override
2395 public String toString() {
2396 synchronized (this) {
2397 return "held=" + (mNestCount != 0) + ", mNestCount=" + mNestCount;
2398 }
2399 }
2400 };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002401}