blob: 5a5d91000ef14968a2e8a819225850576bbdf811 [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 Brown20767b22012-10-09 18:57:07 -070051import android.os.SystemService;
Jeff Brownd4935962012-09-25 13:27:20 -070052import android.os.UserHandle;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070053import android.os.WorkSource;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054import android.provider.Settings;
55import android.util.EventLog;
56import android.util.Log;
Joe Onorato8a9b2202010-02-26 18:56:32 -080057import android.util.Slog;
Jeff Brown96307042012-07-27 15:51:34 -070058import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059import android.view.WindowManagerPolicy;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060
61import java.io.FileDescriptor;
Jeff Brown7304c342012-05-11 18:42:42 -070062import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063import java.io.PrintWriter;
64import java.util.ArrayList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065
Jeff Brown96307042012-07-27 15:51:34 -070066import libcore.util.Objects;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067
Jeff Brown96307042012-07-27 15:51:34 -070068/**
69 * The power manager service is responsible for coordinating power management
70 * functions on the device.
71 */
72public final class PowerManagerService extends IPowerManager.Stub
73 implements Watchdog.Monitor {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074 private static final String TAG = "PowerManagerService";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075
Jeff Brown88c997a2012-06-22 13:57:45 -070076 private static final boolean DEBUG = false;
Jeff Brown96307042012-07-27 15:51:34 -070077 private static final boolean DEBUG_SPEW = DEBUG && true;
Jeff Brown88c997a2012-06-22 13:57:45 -070078
Jeff Brown96307042012-07-27 15:51:34 -070079 // Message: Sent when a user activity timeout occurs to update the power state.
80 private static final int MSG_USER_ACTIVITY_TIMEOUT = 1;
81 // Message: Sent when the device enters or exits a napping or dreaming state.
82 private static final int MSG_SANDMAN = 2;
Jeff Brownc38c9be2012-10-04 13:16:19 -070083 // Message: Sent when the screen on blocker is released.
84 private static final int MSG_SCREEN_ON_BLOCKER_RELEASED = 3;
Jeff Brown20767b22012-10-09 18:57:07 -070085 // Message: Sent to poll whether the boot animation has terminated.
86 private static final int MSG_CHECK_IF_BOOT_ANIMATION_FINISHED = 4;
Jeff Brown7304c342012-05-11 18:42:42 -070087
Jeff Brown96307042012-07-27 15:51:34 -070088 // Dirty bit: mWakeLocks changed
89 private static final int DIRTY_WAKE_LOCKS = 1 << 0;
90 // Dirty bit: mWakefulness changed
91 private static final int DIRTY_WAKEFULNESS = 1 << 1;
92 // Dirty bit: user activity was poked or may have timed out
93 private static final int DIRTY_USER_ACTIVITY = 1 << 2;
94 // Dirty bit: actual display power state was updated asynchronously
95 private static final int DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED = 1 << 3;
96 // Dirty bit: mBootCompleted changed
97 private static final int DIRTY_BOOT_COMPLETED = 1 << 4;
98 // Dirty bit: settings changed
99 private static final int DIRTY_SETTINGS = 1 << 5;
100 // Dirty bit: mIsPowered changed
101 private static final int DIRTY_IS_POWERED = 1 << 6;
102 // Dirty bit: mStayOn changed
103 private static final int DIRTY_STAY_ON = 1 << 7;
104 // Dirty bit: battery state changed
105 private static final int DIRTY_BATTERY_STATE = 1 << 8;
Jeff Brown93cbbb22012-10-04 13:18:36 -0700106 // Dirty bit: proximity state changed
107 private static final int DIRTY_PROXIMITY_POSITIVE = 1 << 9;
Jeff Brownc38c9be2012-10-04 13:16:19 -0700108 // Dirty bit: screen on blocker state became held or unheld
109 private static final int DIRTY_SCREEN_ON_BLOCKER_RELEASED = 1 << 10;
Jeff Brownec6aa592012-10-17 20:30:25 -0700110 // Dirty bit: dock state changed
111 private static final int DIRTY_DOCK_STATE = 1 << 11;
Jeff Brown7304c342012-05-11 18:42:42 -0700112
Jeff Brown96307042012-07-27 15:51:34 -0700113 // Wakefulness: The device is asleep and can only be awoken by a call to wakeUp().
114 // The screen should be off or in the process of being turned off by the display controller.
115 private static final int WAKEFULNESS_ASLEEP = 0;
116 // Wakefulness: The device is fully awake. It can be put to sleep by a call to goToSleep().
Jeff Brown62c82e42012-09-26 01:30:41 -0700117 // When the user activity timeout expires, the device may start napping or go to sleep.
Jeff Brown96307042012-07-27 15:51:34 -0700118 private static final int WAKEFULNESS_AWAKE = 1;
119 // Wakefulness: The device is napping. It is deciding whether to dream or go to sleep
120 // but hasn't gotten around to it yet. It can be awoken by a call to wakeUp(), which
121 // ends the nap. User activity may brighten the screen but does not end the nap.
122 private static final int WAKEFULNESS_NAPPING = 2;
123 // Wakefulness: The device is dreaming. It can be awoken by a call to wakeUp(),
124 // which ends the dream. The device goes to sleep when goToSleep() is called, when
125 // the dream ends or when unplugged.
126 // User activity may brighten the screen but does not end the dream.
127 private static final int WAKEFULNESS_DREAMING = 3;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128
Jeff Brown96307042012-07-27 15:51:34 -0700129 // Summarizes the state of all active wakelocks.
130 private static final int WAKE_LOCK_CPU = 1 << 0;
131 private static final int WAKE_LOCK_SCREEN_BRIGHT = 1 << 1;
132 private static final int WAKE_LOCK_SCREEN_DIM = 1 << 2;
133 private static final int WAKE_LOCK_BUTTON_BRIGHT = 1 << 3;
134 private static final int WAKE_LOCK_PROXIMITY_SCREEN_OFF = 1 << 4;
Jeff Brown10428742012-10-09 15:47:30 -0700135 private static final int WAKE_LOCK_STAY_AWAKE = 1 << 5; // only set if already awake
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136
Jeff Brown96307042012-07-27 15:51:34 -0700137 // Summarizes the user activity state.
138 private static final int USER_ACTIVITY_SCREEN_BRIGHT = 1 << 0;
139 private static final int USER_ACTIVITY_SCREEN_DIM = 1 << 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800140
Jeff Brown96307042012-07-27 15:51:34 -0700141 // Default and minimum screen off timeout in milliseconds.
142 private static final int DEFAULT_SCREEN_OFF_TIMEOUT = 15 * 1000;
143 private static final int MINIMUM_SCREEN_OFF_TIMEOUT = 10 * 1000;
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700144
Jeff Brownff532542012-10-02 21:18:04 -0700145 // The screen dim duration, in milliseconds.
Jeff Brown96307042012-07-27 15:51:34 -0700146 // This is subtracted from the end of the screen off timeout so the
147 // minimum screen off timeout should be longer than this.
148 private static final int SCREEN_DIM_DURATION = 7 * 1000;
Mathias Agopian47f1fe52011-11-08 17:18:41 -0800149
Jeff Brownff532542012-10-02 21:18:04 -0700150 // The maximum screen dim time expressed as a ratio relative to the screen
151 // off timeout. If the screen off timeout is very short then we want the
152 // dim timeout to also be quite short so that most of the time is spent on.
153 // Otherwise the user won't get much screen on time before dimming occurs.
154 private static final float MAXIMUM_SCREEN_DIM_RATIO = 0.2f;
155
Jeff Brownf3fb8952012-10-02 20:57:05 -0700156 // Upper bound on the battery charge percentage in order to consider turning
157 // the screen on when the device starts charging wirelessly.
158 // See point of use for more details.
159 private static final int WIRELESS_CHARGER_TURN_ON_BATTERY_LEVEL_LIMIT = 95;
160
Jeff Brown20767b22012-10-09 18:57:07 -0700161 // The name of the boot animation service in init.rc.
162 private static final String BOOT_ANIMATION_SERVICE = "bootanim";
163
164 // Poll interval in milliseconds for watching boot animation finished.
165 private static final int BOOT_ANIMATION_POLL_INTERVAL = 200;
166
Jeff Brown016ff142012-10-15 16:47:22 -0700167 // If the battery level drops by this percentage and the user activity timeout
168 // has expired, then assume the device is receiving insufficient current to charge
169 // effectively and terminate the dream.
170 private static final int DREAM_BATTERY_LEVEL_DRAIN_CUTOFF = 5;
171
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172 private Context mContext;
Jeff Brown96307042012-07-27 15:51:34 -0700173 private LightsService mLightsService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 private BatteryService mBatteryService;
Jeff Brown9e316a12012-10-08 19:17:06 -0700175 private DisplayManagerService mDisplayManagerService;
Jeff Brown96307042012-07-27 15:51:34 -0700176 private IBatteryStats mBatteryStats;
177 private HandlerThread mHandlerThread;
178 private PowerManagerHandler mHandler;
179 private WindowManagerPolicy mPolicy;
180 private Notifier mNotifier;
181 private DisplayPowerController mDisplayPowerController;
182 private SettingsObserver mSettingsObserver;
Jeff Brown62c82e42012-09-26 01:30:41 -0700183 private DreamManagerService mDreamManager;
Jeff Brown96307042012-07-27 15:51:34 -0700184 private LightsService.Light mAttentionLight;
Joe Onorato609695d2010-10-14 14:57:49 -0700185
Jeff Brown96307042012-07-27 15:51:34 -0700186 private final Object mLock = new Object();
187
188 // A bitfield that indicates what parts of the power state have
189 // changed and need to be recalculated.
190 private int mDirty;
191
192 // Indicates whether the device is awake or asleep or somewhere in between.
193 // This is distinct from the screen power state, which is managed separately.
194 private int mWakefulness;
195
196 // True if MSG_SANDMAN has been scheduled.
197 private boolean mSandmanScheduled;
198
199 // Table of all suspend blockers.
200 // There should only be a few of these.
201 private final ArrayList<SuspendBlocker> mSuspendBlockers = new ArrayList<SuspendBlocker>();
202
203 // Table of all wake locks acquired by applications.
204 private final ArrayList<WakeLock> mWakeLocks = new ArrayList<WakeLock>();
205
206 // A bitfield that summarizes the state of all active wakelocks.
207 private int mWakeLockSummary;
208
209 // If true, instructs the display controller to wait for the proximity sensor to
210 // go negative before turning the screen on.
211 private boolean mRequestWaitForNegativeProximity;
212
213 // Timestamp of the last time the device was awoken or put to sleep.
214 private long mLastWakeTime;
215 private long mLastSleepTime;
216
217 // True if we need to send a wake up or go to sleep finished notification
218 // when the display is ready.
219 private boolean mSendWakeUpFinishedNotificationWhenReady;
220 private boolean mSendGoToSleepFinishedNotificationWhenReady;
221
222 // Timestamp of the last call to user activity.
223 private long mLastUserActivityTime;
224 private long mLastUserActivityTimeNoChangeLights;
225
226 // A bitfield that summarizes the effect of the user activity timer.
227 // A zero value indicates that the user activity timer has expired.
228 private int mUserActivitySummary;
229
230 // The desired display power state. The actual state may lag behind the
231 // requested because it is updated asynchronously by the display power controller.
232 private final DisplayPowerRequest mDisplayPowerRequest = new DisplayPowerRequest();
233
234 // The time the screen was last turned off, in elapsedRealtime() timebase.
235 private long mLastScreenOffEventElapsedRealTime;
236
237 // True if the display power state has been fully applied, which means the display
238 // is actually on or actually off or whatever was requested.
239 private boolean mDisplayReady;
240
241 // True if holding a wake-lock to block suspend of the CPU.
242 private boolean mHoldingWakeLockSuspendBlocker;
243
244 // The suspend blocker used to keep the CPU alive when wake locks have been acquired.
245 private final SuspendBlocker mWakeLockSuspendBlocker;
246
Jeff Brownc38c9be2012-10-04 13:16:19 -0700247 // The screen on blocker used to keep the screen from turning on while the lock
248 // screen is coming up.
249 private final ScreenOnBlockerImpl mScreenOnBlocker;
250
Jeff Brown9e316a12012-10-08 19:17:06 -0700251 // The display blanker used to turn the screen on or off.
252 private final DisplayBlankerImpl mDisplayBlanker;
253
Jeff Brown96307042012-07-27 15:51:34 -0700254 // True if systemReady() has been called.
255 private boolean mSystemReady;
256
257 // True if boot completed occurred. We keep the screen on until this happens.
258 private boolean mBootCompleted;
259
260 // True if the device is plugged into a power source.
261 private boolean mIsPowered;
262
Jeff Brownf3fb8952012-10-02 20:57:05 -0700263 // The current plug type, such as BatteryManager.BATTERY_PLUGGED_WIRELESS.
264 private int mPlugType;
265
Jeff Brown016ff142012-10-15 16:47:22 -0700266 // The current battery level percentage.
267 private int mBatteryLevel;
268
269 // The battery level percentage at the time the dream started.
270 // This is used to terminate a dream and go to sleep if the battery is
271 // draining faster than it is charging and the user activity timeout has expired.
272 private int mBatteryLevelWhenDreamStarted;
273
Jeff Brownec6aa592012-10-17 20:30:25 -0700274 // The current dock state.
275 private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
276
Jeff Brown96307042012-07-27 15:51:34 -0700277 // True if the device should wake up when plugged or unplugged.
278 private boolean mWakeUpWhenPluggedOrUnpluggedConfig;
279
280 // True if dreams are supported on this device.
281 private boolean mDreamsSupportedConfig;
282
John Spurlocked108f32012-10-18 16:49:24 -0400283 // Default value for dreams enabled
284 private boolean mDreamsEnabledByDefaultConfig;
285
286 // Default value for dreams activate-on-sleep
287 private boolean mDreamsActivatedOnSleepByDefaultConfig;
288
289 // Default value for dreams activate-on-dock
290 private boolean mDreamsActivatedOnDockByDefaultConfig;
291
Jeff Brown96307042012-07-27 15:51:34 -0700292 // True if dreams are enabled by the user.
293 private boolean mDreamsEnabledSetting;
294
John Spurlock1a868b72012-08-22 09:56:51 -0400295 // True if dreams should be activated on sleep.
296 private boolean mDreamsActivateOnSleepSetting;
297
Jeff Brownec6aa592012-10-17 20:30:25 -0700298 // True if dreams should be activated on dock.
299 private boolean mDreamsActivateOnDockSetting;
300
Jeff Brown96307042012-07-27 15:51:34 -0700301 // The screen off timeout setting value in milliseconds.
302 private int mScreenOffTimeoutSetting;
303
304 // The maximum allowable screen off timeout according to the device
305 // administration policy. Overrides other settings.
306 private int mMaximumScreenOffTimeoutFromDeviceAdmin = Integer.MAX_VALUE;
307
308 // The stay on while plugged in setting.
309 // A bitfield of battery conditions under which to make the screen stay on.
310 private int mStayOnWhilePluggedInSetting;
311
312 // True if the device should stay on.
313 private boolean mStayOn;
314
Jeff Brown93cbbb22012-10-04 13:18:36 -0700315 // True if the proximity sensor reads a positive result.
316 private boolean mProximityPositive;
317
Jeff Brown96307042012-07-27 15:51:34 -0700318 // Screen brightness setting limits.
319 private int mScreenBrightnessSettingMinimum;
320 private int mScreenBrightnessSettingMaximum;
321 private int mScreenBrightnessSettingDefault;
322
323 // The screen brightness setting, from 0 to 255.
324 // Use -1 if no value has been set.
325 private int mScreenBrightnessSetting;
326
Jeff Brown330560f2012-08-21 22:10:57 -0700327 // The screen auto-brightness adjustment setting, from -1 to 1.
328 // Use 0 if there is no adjustment.
329 private float mScreenAutoBrightnessAdjustmentSetting;
330
Jeff Brown96307042012-07-27 15:51:34 -0700331 // The screen brightness mode.
332 // One of the Settings.System.SCREEN_BRIGHTNESS_MODE_* constants.
333 private int mScreenBrightnessModeSetting;
334
335 // The screen brightness setting override from the window manager
336 // to allow the current foreground activity to override the brightness.
337 // Use -1 to disable.
338 private int mScreenBrightnessOverrideFromWindowManager = -1;
339
Jeff Brown1e3b98d2012-09-30 18:58:59 -0700340 // The user activity timeout override from the window manager
341 // to allow the current foreground activity to override the user activity timeout.
342 // Use -1 to disable.
343 private long mUserActivityTimeoutOverrideFromWindowManager = -1;
344
Jeff Brown96307042012-07-27 15:51:34 -0700345 // The screen brightness setting override from the settings application
346 // to temporarily adjust the brightness until next updated,
347 // Use -1 to disable.
348 private int mTemporaryScreenBrightnessSettingOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800349
Jeff Brown330560f2012-08-21 22:10:57 -0700350 // The screen brightness adjustment setting override from the settings
351 // application to temporarily adjust the auto-brightness adjustment factor
352 // until next updated, in the range -1..1.
353 // Use NaN to disable.
354 private float mTemporaryScreenAutoBrightnessAdjustmentSettingOverride = Float.NaN;
355
Jeff Brown9ba8d782012-10-01 16:38:23 -0700356 // Time when we last logged a warning about calling userActivity() without permission.
357 private long mLastWarningAboutUserActivityPermission = Long.MIN_VALUE;
358
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700359 private native void nativeInit();
Jeff Brown7304c342012-05-11 18:42:42 -0700360 private static native void nativeShutdown();
361 private static native void nativeReboot(String reason) throws IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800362
Jeff Brown96307042012-07-27 15:51:34 -0700363 private static native void nativeSetPowerState(boolean screenOn, boolean screenBright);
364 private static native void nativeAcquireSuspendBlocker(String name);
365 private static native void nativeReleaseSuspendBlocker(String name);
Jeff Brown9e316a12012-10-08 19:17:06 -0700366 private static native void nativeSetInteractive(boolean enable);
367 private static native void nativeSetAutoSuspend(boolean enable);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800368
Jeff Brown4f8ecd82012-06-18 18:29:13 -0700369 public PowerManagerService() {
Jeff Brown96307042012-07-27 15:51:34 -0700370 synchronized (mLock) {
371 mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService");
372 mWakeLockSuspendBlocker.acquire();
Jeff Brownc38c9be2012-10-04 13:16:19 -0700373 mScreenOnBlocker = new ScreenOnBlockerImpl();
Jeff Brown9e316a12012-10-08 19:17:06 -0700374 mDisplayBlanker = new DisplayBlankerImpl();
Jeff Brown96307042012-07-27 15:51:34 -0700375 mHoldingWakeLockSuspendBlocker = true;
376 mWakefulness = WAKEFULNESS_AWAKE;
377 }
Jeff Brown7304c342012-05-11 18:42:42 -0700378
379 nativeInit();
Jeff Brownf75724b2012-08-25 13:34:32 -0700380 nativeSetPowerState(true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800381 }
382
Jeff Brown96307042012-07-27 15:51:34 -0700383 /**
384 * Initialize the power manager.
385 * Must be called before any other functions within the power manager are called.
386 */
387 public void init(Context context, LightsService ls,
388 ActivityManagerService am, BatteryService bs, IBatteryStats bss,
389 DisplayManagerService dm) {
Jeff Brown9e316a12012-10-08 19:17:06 -0700390 mContext = context;
391 mLightsService = ls;
392 mBatteryService = bs;
393 mBatteryStats = bss;
394 mDisplayManagerService = dm;
395 mHandlerThread = new HandlerThread(TAG);
396 mHandlerThread.start();
397 mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
398
399 Watchdog.getInstance().addMonitor(this);
400
Jeff Brownf75724b2012-08-25 13:34:32 -0700401 // Forcibly turn the screen on at boot so that it is in a known power state.
402 // We do this in init() rather than in the constructor because setting the
403 // screen state requires a call into surface flinger which then needs to call back
404 // into the activity manager to check permissions. Unfortunately the
405 // activity manager is not running when the constructor is called, so we
406 // have to defer setting the screen state until this point.
Jeff Brown9e316a12012-10-08 19:17:06 -0700407 mDisplayBlanker.unblankAllDisplays();
Jeff Brown96307042012-07-27 15:51:34 -0700408 }
Jim Miller92e66dd2012-02-21 18:57:12 -0800409
Jeff Brown96307042012-07-27 15:51:34 -0700410 public void setPolicy(WindowManagerPolicy policy) {
411 synchronized (mLock) {
412 mPolicy = policy;
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700413 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800414 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800415
Jeff Brown62c82e42012-09-26 01:30:41 -0700416 public void systemReady(TwilightService twilight, DreamManagerService dreamManager) {
Jeff Brown96307042012-07-27 15:51:34 -0700417 synchronized (mLock) {
418 mSystemReady = true;
Jeff Brown62c82e42012-09-26 01:30:41 -0700419 mDreamManager = dreamManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800420
Jeff Brown96307042012-07-27 15:51:34 -0700421 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
422 mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting();
423 mScreenBrightnessSettingMaximum = pm.getMaximumScreenBrightnessSetting();
424 mScreenBrightnessSettingDefault = pm.getDefaultScreenBrightnessSetting();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800425
Jeff Brownc38c9be2012-10-04 13:16:19 -0700426 // The notifier runs on the system server's main looper so as not to interfere
427 // with the animations and other critical functions of the power manager.
428 mNotifier = new Notifier(Looper.getMainLooper(), mContext, mBatteryStats,
Jeff Brown96307042012-07-27 15:51:34 -0700429 createSuspendBlockerLocked("PowerManagerService.Broadcasts"),
Jeff Brownc38c9be2012-10-04 13:16:19 -0700430 mScreenOnBlocker, mPolicy);
431
432 // The display power controller runs on the power manager service's
433 // own handler thread.
Jeff Brown96307042012-07-27 15:51:34 -0700434 mDisplayPowerController = new DisplayPowerController(mHandler.getLooper(),
Jeff Brown7f3994e2012-12-04 14:04:28 -0800435 mContext, mNotifier, mLightsService, twilight, mDisplayManagerService,
Jeff Brown9e316a12012-10-08 19:17:06 -0700436 mDisplayBlanker, mDisplayPowerControllerCallbacks, mHandler);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800437
Jeff Brown96307042012-07-27 15:51:34 -0700438 mSettingsObserver = new SettingsObserver(mHandler);
439 mAttentionLight = mLightsService.getLight(LightsService.LIGHT_ID_ATTENTION);
Mike Lockwoodaa66ea82009-10-31 16:31:27 -0400440
Jeff Brown96307042012-07-27 15:51:34 -0700441 // Register for broadcasts from other components of the system.
442 IntentFilter filter = new IntentFilter();
443 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
Jeff Brownd4935962012-09-25 13:27:20 -0700444 mContext.registerReceiver(new BatteryReceiver(), filter, null, mHandler);
Joe Onoratob08a1af2010-10-11 19:28:58 -0700445
Jeff Brown96307042012-07-27 15:51:34 -0700446 filter = new IntentFilter();
447 filter.addAction(Intent.ACTION_BOOT_COMPLETED);
Jeff Brownd4935962012-09-25 13:27:20 -0700448 mContext.registerReceiver(new BootCompletedReceiver(), filter, null, mHandler);
Jeff Brown96307042012-07-27 15:51:34 -0700449
450 filter = new IntentFilter();
Dianne Hackbornbe87e2f2012-09-28 16:31:34 -0700451 filter.addAction(Intent.ACTION_DREAMING_STARTED);
452 filter.addAction(Intent.ACTION_DREAMING_STOPPED);
Jeff Brownd4935962012-09-25 13:27:20 -0700453 mContext.registerReceiver(new DreamReceiver(), filter, null, mHandler);
454
455 filter = new IntentFilter();
456 filter.addAction(Intent.ACTION_USER_SWITCHED);
457 mContext.registerReceiver(new UserSwitchedReceiver(), filter, null, mHandler);
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400458
Jeff Brownec6aa592012-10-17 20:30:25 -0700459 filter = new IntentFilter();
460 filter.addAction(Intent.ACTION_DOCK_EVENT);
461 mContext.registerReceiver(new DockReceiver(), filter, null, mHandler);
462
Jeff Brown96307042012-07-27 15:51:34 -0700463 // Register for settings changes.
464 final ContentResolver resolver = mContext.getContentResolver();
465 resolver.registerContentObserver(Settings.Secure.getUriFor(
Jeff Brownd4935962012-09-25 13:27:20 -0700466 Settings.Secure.SCREENSAVER_ENABLED),
467 false, mSettingsObserver, UserHandle.USER_ALL);
John Spurlock1a868b72012-08-22 09:56:51 -0400468 resolver.registerContentObserver(Settings.Secure.getUriFor(
Jeff Brownd4935962012-09-25 13:27:20 -0700469 Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP),
470 false, mSettingsObserver, UserHandle.USER_ALL);
Jeff Brownec6aa592012-10-17 20:30:25 -0700471 resolver.registerContentObserver(Settings.Secure.getUriFor(
472 Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK),
473 false, mSettingsObserver, UserHandle.USER_ALL);
Jeff Brown96307042012-07-27 15:51:34 -0700474 resolver.registerContentObserver(Settings.System.getUriFor(
Jeff Brownd4935962012-09-25 13:27:20 -0700475 Settings.System.SCREEN_OFF_TIMEOUT),
476 false, mSettingsObserver, UserHandle.USER_ALL);
Christopher Tatead735322012-09-07 14:19:43 -0700477 resolver.registerContentObserver(Settings.Global.getUriFor(
Jeff Brownd4935962012-09-25 13:27:20 -0700478 Settings.Global.STAY_ON_WHILE_PLUGGED_IN),
479 false, mSettingsObserver, UserHandle.USER_ALL);
Jeff Brown96307042012-07-27 15:51:34 -0700480 resolver.registerContentObserver(Settings.System.getUriFor(
Jeff Brownd4935962012-09-25 13:27:20 -0700481 Settings.System.SCREEN_BRIGHTNESS),
482 false, mSettingsObserver, UserHandle.USER_ALL);
Jeff Brown96307042012-07-27 15:51:34 -0700483 resolver.registerContentObserver(Settings.System.getUriFor(
Jeff Brownd4935962012-09-25 13:27:20 -0700484 Settings.System.SCREEN_BRIGHTNESS_MODE),
485 false, mSettingsObserver, UserHandle.USER_ALL);
Jeff Brown96307042012-07-27 15:51:34 -0700486
487 // Go.
488 readConfigurationLocked();
489 updateSettingsLocked();
490 mDirty |= DIRTY_BATTERY_STATE;
491 updatePowerStateLocked();
492 }
493 }
494
495 private void readConfigurationLocked() {
496 final Resources resources = mContext.getResources();
497
498 mWakeUpWhenPluggedOrUnpluggedConfig = resources.getBoolean(
Joe Onorato6d747652010-10-11 15:15:31 -0700499 com.android.internal.R.bool.config_unplugTurnsOnScreen);
Jeff Brown96307042012-07-27 15:51:34 -0700500 mDreamsSupportedConfig = resources.getBoolean(
John Spurlocked108f32012-10-18 16:49:24 -0400501 com.android.internal.R.bool.config_dreamsSupported);
502 mDreamsEnabledByDefaultConfig = resources.getBoolean(
503 com.android.internal.R.bool.config_dreamsEnabledByDefault);
504 mDreamsActivatedOnSleepByDefaultConfig = resources.getBoolean(
505 com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault);
506 mDreamsActivatedOnDockByDefaultConfig = resources.getBoolean(
507 com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800508 }
509
Jeff Brown96307042012-07-27 15:51:34 -0700510 private void updateSettingsLocked() {
511 final ContentResolver resolver = mContext.getContentResolver();
Jeff Brown7304c342012-05-11 18:42:42 -0700512
Jeff Brownd4935962012-09-25 13:27:20 -0700513 mDreamsEnabledSetting = (Settings.Secure.getIntForUser(resolver,
John Spurlocked108f32012-10-18 16:49:24 -0400514 Settings.Secure.SCREENSAVER_ENABLED,
515 mDreamsEnabledByDefaultConfig ? 1 : 0,
Jeff Brownd4935962012-09-25 13:27:20 -0700516 UserHandle.USER_CURRENT) != 0);
517 mDreamsActivateOnSleepSetting = (Settings.Secure.getIntForUser(resolver,
John Spurlocked108f32012-10-18 16:49:24 -0400518 Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
519 mDreamsActivatedOnSleepByDefaultConfig ? 1 : 0,
Jeff Brownd4935962012-09-25 13:27:20 -0700520 UserHandle.USER_CURRENT) != 0);
Jeff Brownec6aa592012-10-17 20:30:25 -0700521 mDreamsActivateOnDockSetting = (Settings.Secure.getIntForUser(resolver,
John Spurlocked108f32012-10-18 16:49:24 -0400522 Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
523 mDreamsActivatedOnDockByDefaultConfig ? 1 : 0,
Jeff Brownec6aa592012-10-17 20:30:25 -0700524 UserHandle.USER_CURRENT) != 0);
Jeff Brownd4935962012-09-25 13:27:20 -0700525 mScreenOffTimeoutSetting = Settings.System.getIntForUser(resolver,
526 Settings.System.SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT,
527 UserHandle.USER_CURRENT);
Christopher Tatead735322012-09-07 14:19:43 -0700528 mStayOnWhilePluggedInSetting = Settings.Global.getInt(resolver,
Jeff Brownd4935962012-09-25 13:27:20 -0700529 Settings.Global.STAY_ON_WHILE_PLUGGED_IN, BatteryManager.BATTERY_PLUGGED_AC);
Jeff Brown7304c342012-05-11 18:42:42 -0700530
Jeff Brown96307042012-07-27 15:51:34 -0700531 final int oldScreenBrightnessSetting = mScreenBrightnessSetting;
Jeff Brownd4935962012-09-25 13:27:20 -0700532 mScreenBrightnessSetting = Settings.System.getIntForUser(resolver,
533 Settings.System.SCREEN_BRIGHTNESS, mScreenBrightnessSettingDefault,
534 UserHandle.USER_CURRENT);
Jeff Brown96307042012-07-27 15:51:34 -0700535 if (oldScreenBrightnessSetting != mScreenBrightnessSetting) {
536 mTemporaryScreenBrightnessSettingOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800537 }
Jeff Brown96307042012-07-27 15:51:34 -0700538
Jeff Brown330560f2012-08-21 22:10:57 -0700539 final float oldScreenAutoBrightnessAdjustmentSetting =
540 mScreenAutoBrightnessAdjustmentSetting;
Jeff Brownd4935962012-09-25 13:27:20 -0700541 mScreenAutoBrightnessAdjustmentSetting = Settings.System.getFloatForUser(resolver,
542 Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f,
543 UserHandle.USER_CURRENT);
Jeff Brown330560f2012-08-21 22:10:57 -0700544 if (oldScreenAutoBrightnessAdjustmentSetting != mScreenAutoBrightnessAdjustmentSetting) {
Jeff Brown5d03a532012-08-22 13:22:02 -0700545 mTemporaryScreenAutoBrightnessAdjustmentSettingOverride = Float.NaN;
Jeff Brown330560f2012-08-21 22:10:57 -0700546 }
547
Jeff Brownd4935962012-09-25 13:27:20 -0700548 mScreenBrightnessModeSetting = Settings.System.getIntForUser(resolver,
Jeff Brown96307042012-07-27 15:51:34 -0700549 Settings.System.SCREEN_BRIGHTNESS_MODE,
Jeff Brownd4935962012-09-25 13:27:20 -0700550 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, UserHandle.USER_CURRENT);
Jeff Brown96307042012-07-27 15:51:34 -0700551
552 mDirty |= DIRTY_SETTINGS;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800553 }
554
Jeff Brown96307042012-07-27 15:51:34 -0700555 private void handleSettingsChangedLocked() {
556 updateSettingsLocked();
557 updatePowerStateLocked();
558 }
559
560 @Override // Binder call
561 public void acquireWakeLock(IBinder lock, int flags, String tag, WorkSource ws) {
562 if (lock == null) {
563 throw new IllegalArgumentException("lock must not be null");
564 }
565 PowerManager.validateWakeLockParameters(flags, tag);
566
567 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
568 if (ws != null && ws.size() != 0) {
569 mContext.enforceCallingOrSelfPermission(
570 android.Manifest.permission.UPDATE_DEVICE_STATS, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800571 } else {
Jeff Brown96307042012-07-27 15:51:34 -0700572 ws = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800573 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800574
Jeff Brown96307042012-07-27 15:51:34 -0700575 final int uid = Binder.getCallingUid();
576 final int pid = Binder.getCallingPid();
577 final long ident = Binder.clearCallingIdentity();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800578 try {
Jeff Brown96307042012-07-27 15:51:34 -0700579 acquireWakeLockInternal(lock, flags, tag, ws, uid, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800580 } finally {
581 Binder.restoreCallingIdentity(ident);
582 }
583 }
584
Jeff Brown96307042012-07-27 15:51:34 -0700585 private void acquireWakeLockInternal(IBinder lock, int flags, String tag, WorkSource ws,
586 int uid, int pid) {
587 synchronized (mLock) {
588 if (DEBUG_SPEW) {
589 Slog.d(TAG, "acquireWakeLockInternal: lock=" + Objects.hashCode(lock)
590 + ", flags=0x" + Integer.toHexString(flags)
591 + ", tag=\"" + tag + "\", ws=" + ws + ", uid=" + uid + ", pid=" + pid);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700592 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800593
Jeff Brown96307042012-07-27 15:51:34 -0700594 WakeLock wakeLock;
595 int index = findWakeLockIndexLocked(lock);
596 if (index >= 0) {
597 wakeLock = mWakeLocks.get(index);
598 if (!wakeLock.hasSameProperties(flags, tag, ws, uid, pid)) {
599 // Update existing wake lock. This shouldn't happen but is harmless.
600 notifyWakeLockReleasedLocked(wakeLock);
601 wakeLock.updateProperties(flags, tag, ws, uid, pid);
602 notifyWakeLockAcquiredLocked(wakeLock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800603 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800604 } else {
Jeff Brown96307042012-07-27 15:51:34 -0700605 wakeLock = new WakeLock(lock, flags, tag, ws, uid, pid);
606 try {
607 lock.linkToDeath(wakeLock, 0);
608 } catch (RemoteException ex) {
609 throw new IllegalArgumentException("Wake lock is already dead.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800610 }
Jeff Brown96307042012-07-27 15:51:34 -0700611 notifyWakeLockAcquiredLocked(wakeLock);
612 mWakeLocks.add(wakeLock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800613 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800614
Jeff Brown96307042012-07-27 15:51:34 -0700615 applyWakeLockFlagsOnAcquireLocked(wakeLock);
616 mDirty |= DIRTY_WAKE_LOCKS;
617 updatePowerStateLocked();
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700618 }
619 }
620
Craig Mautner6edb6db2012-11-20 18:21:12 -0800621 private static boolean isScreenLock(final WakeLock wakeLock) {
622 switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
623 case PowerManager.FULL_WAKE_LOCK:
624 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
625 case PowerManager.SCREEN_DIM_WAKE_LOCK:
626 return true;
627 }
628 return false;
629 }
630
Jeff Brown96307042012-07-27 15:51:34 -0700631 private void applyWakeLockFlagsOnAcquireLocked(WakeLock wakeLock) {
Craig Mautner6edb6db2012-11-20 18:21:12 -0800632 if ((wakeLock.mFlags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0 &&
633 isScreenLock(wakeLock)) {
Jeff Brown96307042012-07-27 15:51:34 -0700634 wakeUpNoUpdateLocked(SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800635 }
636 }
637
Jeff Brown96307042012-07-27 15:51:34 -0700638 @Override // Binder call
Mike Lockwood0e39ea82009-11-18 15:37:10 -0500639 public void releaseWakeLock(IBinder lock, int flags) {
Jeff Brown96307042012-07-27 15:51:34 -0700640 if (lock == null) {
641 throw new IllegalArgumentException("lock must not be null");
Michael Chane96440f2009-05-06 10:27:36 -0700642 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800643
Jeff Brown96307042012-07-27 15:51:34 -0700644 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
645
646 final long ident = Binder.clearCallingIdentity();
647 try {
648 releaseWakeLockInternal(lock, flags);
649 } finally {
650 Binder.restoreCallingIdentity(ident);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800651 }
652 }
653
Jeff Brown96307042012-07-27 15:51:34 -0700654 private void releaseWakeLockInternal(IBinder lock, int flags) {
655 synchronized (mLock) {
656 if (DEBUG_SPEW) {
657 Slog.d(TAG, "releaseWakeLockInternal: lock=" + Objects.hashCode(lock)
658 + ", flags=0x" + Integer.toHexString(flags));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800659 }
660
Jeff Brown96307042012-07-27 15:51:34 -0700661 int index = findWakeLockIndexLocked(lock);
662 if (index < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800663 return;
664 }
Mike Lockwood3333fa42009-10-26 14:50:42 -0400665
Jeff Brown96307042012-07-27 15:51:34 -0700666 WakeLock wakeLock = mWakeLocks.get(index);
667 mWakeLocks.remove(index);
668 notifyWakeLockReleasedLocked(wakeLock);
669 wakeLock.mLock.unlinkToDeath(wakeLock, 0);
670
671 if ((flags & PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE) != 0) {
672 mRequestWaitForNegativeProximity = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800673 }
674
Jeff Brown96307042012-07-27 15:51:34 -0700675 applyWakeLockFlagsOnReleaseLocked(wakeLock);
676 mDirty |= DIRTY_WAKE_LOCKS;
677 updatePowerStateLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800678 }
679 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700680
Jeff Brown96307042012-07-27 15:51:34 -0700681 private void handleWakeLockDeath(WakeLock wakeLock) {
682 synchronized (mLock) {
683 if (DEBUG_SPEW) {
684 Slog.d(TAG, "handleWakeLockDeath: lock=" + Objects.hashCode(wakeLock.mLock));
685 }
686
687 int index = mWakeLocks.indexOf(wakeLock);
688 if (index < 0) {
689 return;
690 }
691
692 mWakeLocks.remove(index);
693 notifyWakeLockReleasedLocked(wakeLock);
694
695 applyWakeLockFlagsOnReleaseLocked(wakeLock);
696 mDirty |= DIRTY_WAKE_LOCKS;
697 updatePowerStateLocked();
Mike Lockwood3a74bd32011-08-12 13:55:22 -0700698 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700699 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800700
Jeff Brown96307042012-07-27 15:51:34 -0700701 private void applyWakeLockFlagsOnReleaseLocked(WakeLock wakeLock) {
702 if ((wakeLock.mFlags & PowerManager.ON_AFTER_RELEASE) != 0) {
703 userActivityNoUpdateLocked(SystemClock.uptimeMillis(),
704 PowerManager.USER_ACTIVITY_EVENT_OTHER,
705 PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS,
706 wakeLock.mOwnerUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800707 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800708 }
709
Jeff Brown96307042012-07-27 15:51:34 -0700710 @Override // Binder call
711 public void updateWakeLockWorkSource(IBinder lock, WorkSource ws) {
712 if (lock == null) {
713 throw new IllegalArgumentException("lock must not be null");
714 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800715
Jeff Brown96307042012-07-27 15:51:34 -0700716 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
717 if (ws != null && ws.size() != 0) {
718 mContext.enforceCallingOrSelfPermission(
719 android.Manifest.permission.UPDATE_DEVICE_STATS, null);
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700720 } else {
Jeff Brown96307042012-07-27 15:51:34 -0700721 ws = null;
722 }
723
724 final long ident = Binder.clearCallingIdentity();
725 try {
726 updateWakeLockWorkSourceInternal(lock, ws);
727 } finally {
728 Binder.restoreCallingIdentity(ident);
729 }
730 }
731
732 private void updateWakeLockWorkSourceInternal(IBinder lock, WorkSource ws) {
733 synchronized (mLock) {
734 int index = findWakeLockIndexLocked(lock);
735 if (index < 0) {
736 throw new IllegalArgumentException("Wake lock not active");
737 }
738
739 WakeLock wakeLock = mWakeLocks.get(index);
740 if (!wakeLock.hasSameWorkSource(ws)) {
741 notifyWakeLockReleasedLocked(wakeLock);
742 wakeLock.updateWorkSource(ws);
743 notifyWakeLockAcquiredLocked(wakeLock);
744 }
745 }
746 }
747
748 private int findWakeLockIndexLocked(IBinder lock) {
749 final int count = mWakeLocks.size();
750 for (int i = 0; i < count; i++) {
751 if (mWakeLocks.get(i).mLock == lock) {
752 return i;
753 }
754 }
755 return -1;
756 }
757
758 private void notifyWakeLockAcquiredLocked(WakeLock wakeLock) {
759 if (mSystemReady) {
760 mNotifier.onWakeLockAcquired(wakeLock.mFlags, wakeLock.mTag,
761 wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource);
762 }
763 }
764
765 private void notifyWakeLockReleasedLocked(WakeLock wakeLock) {
766 if (mSystemReady) {
767 mNotifier.onWakeLockReleased(wakeLock.mFlags, wakeLock.mTag,
768 wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource);
769 }
770 }
771
772 @Override // Binder call
773 public boolean isWakeLockLevelSupported(int level) {
774 final long ident = Binder.clearCallingIdentity();
775 try {
776 return isWakeLockLevelSupportedInternal(level);
777 } finally {
778 Binder.restoreCallingIdentity(ident);
779 }
780 }
781
782 private boolean isWakeLockLevelSupportedInternal(int level) {
783 synchronized (mLock) {
784 switch (level) {
785 case PowerManager.PARTIAL_WAKE_LOCK:
786 case PowerManager.SCREEN_DIM_WAKE_LOCK:
787 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
788 case PowerManager.FULL_WAKE_LOCK:
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700789 return true;
Jeff Brown96307042012-07-27 15:51:34 -0700790
791 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
792 return mSystemReady && mDisplayPowerController.isProximitySensorAvailable();
793
794 default:
795 return false;
796 }
797 }
798 }
799
800 @Override // Binder call
801 public void userActivity(long eventTime, int event, int flags) {
Jeff Brown9ba8d782012-10-01 16:38:23 -0700802 final long now = SystemClock.uptimeMillis();
803 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER)
804 != PackageManager.PERMISSION_GRANTED) {
805 // Once upon a time applications could call userActivity().
806 // Now we require the DEVICE_POWER permission. Log a warning and ignore the
807 // request instead of throwing a SecurityException so we don't break old apps.
808 synchronized (mLock) {
809 if (now >= mLastWarningAboutUserActivityPermission + (5 * 60 * 1000)) {
810 mLastWarningAboutUserActivityPermission = now;
811 Slog.w(TAG, "Ignoring call to PowerManager.userActivity() because the "
812 + "caller does not have DEVICE_POWER permission. "
813 + "Please fix your app! "
814 + " pid=" + Binder.getCallingPid()
815 + " uid=" + Binder.getCallingUid());
816 }
817 }
818 return;
819 }
820
Jeff Brown96307042012-07-27 15:51:34 -0700821 if (eventTime > SystemClock.uptimeMillis()) {
822 throw new IllegalArgumentException("event time must not be in the future");
823 }
824
Jeff Brown96307042012-07-27 15:51:34 -0700825 final int uid = Binder.getCallingUid();
826 final long ident = Binder.clearCallingIdentity();
827 try {
828 userActivityInternal(eventTime, event, flags, uid);
829 } finally {
830 Binder.restoreCallingIdentity(ident);
831 }
832 }
833
834 // Called from native code.
835 private void userActivityFromNative(long eventTime, int event, int flags) {
836 userActivityInternal(eventTime, event, flags, Process.SYSTEM_UID);
837 }
838
839 private void userActivityInternal(long eventTime, int event, int flags, int uid) {
840 synchronized (mLock) {
841 if (userActivityNoUpdateLocked(eventTime, event, flags, uid)) {
842 updatePowerStateLocked();
843 }
844 }
845 }
846
847 private boolean userActivityNoUpdateLocked(long eventTime, int event, int flags, int uid) {
848 if (DEBUG_SPEW) {
849 Slog.d(TAG, "userActivityNoUpdateLocked: eventTime=" + eventTime
850 + ", event=" + event + ", flags=0x" + Integer.toHexString(flags)
851 + ", uid=" + uid);
852 }
853
854 if (eventTime < mLastSleepTime || eventTime < mLastWakeTime
855 || mWakefulness == WAKEFULNESS_ASLEEP || !mBootCompleted || !mSystemReady) {
856 return false;
857 }
858
859 mNotifier.onUserActivity(event, uid);
860
861 if ((flags & PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS) != 0) {
862 if (eventTime > mLastUserActivityTimeNoChangeLights
863 && eventTime > mLastUserActivityTime) {
864 mLastUserActivityTimeNoChangeLights = eventTime;
865 mDirty |= DIRTY_USER_ACTIVITY;
866 return true;
867 }
868 } else {
869 if (eventTime > mLastUserActivityTime) {
870 mLastUserActivityTime = eventTime;
871 mDirty |= DIRTY_USER_ACTIVITY;
872 return true;
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700873 }
874 }
875 return false;
876 }
877
Jeff Brown96307042012-07-27 15:51:34 -0700878 @Override // Binder call
879 public void wakeUp(long eventTime) {
880 if (eventTime > SystemClock.uptimeMillis()) {
881 throw new IllegalArgumentException("event time must not be in the future");
882 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700883
Jeff Brown96307042012-07-27 15:51:34 -0700884 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
885
886 final long ident = Binder.clearCallingIdentity();
887 try {
888 wakeUpInternal(eventTime);
889 } finally {
890 Binder.restoreCallingIdentity(ident);
891 }
892 }
893
894 // Called from native code.
895 private void wakeUpFromNative(long eventTime) {
896 wakeUpInternal(eventTime);
897 }
898
899 private void wakeUpInternal(long eventTime) {
900 synchronized (mLock) {
901 if (wakeUpNoUpdateLocked(eventTime)) {
902 updatePowerStateLocked();
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700903 }
904 }
Jeff Brown96307042012-07-27 15:51:34 -0700905 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700906
Jeff Brown96307042012-07-27 15:51:34 -0700907 private boolean wakeUpNoUpdateLocked(long eventTime) {
908 if (DEBUG_SPEW) {
909 Slog.d(TAG, "wakeUpNoUpdateLocked: eventTime=" + eventTime);
Joe Onorato60607a92010-10-23 14:49:30 -0700910 }
Jeff Brown96307042012-07-27 15:51:34 -0700911
912 if (eventTime < mLastSleepTime || mWakefulness == WAKEFULNESS_AWAKE
913 || !mBootCompleted || !mSystemReady) {
914 return false;
915 }
916
917 switch (mWakefulness) {
918 case WAKEFULNESS_ASLEEP:
919 Slog.i(TAG, "Waking up from sleep...");
Jeff Brown54308352012-10-04 17:59:58 -0700920 sendPendingNotificationsLocked();
Jeff Brown96307042012-07-27 15:51:34 -0700921 mNotifier.onWakeUpStarted();
922 mSendWakeUpFinishedNotificationWhenReady = true;
Jeff Brown96307042012-07-27 15:51:34 -0700923 break;
924 case WAKEFULNESS_DREAMING:
925 Slog.i(TAG, "Waking up from dream...");
926 break;
927 case WAKEFULNESS_NAPPING:
928 Slog.i(TAG, "Waking up from nap...");
929 break;
930 }
931
932 mLastWakeTime = eventTime;
933 mWakefulness = WAKEFULNESS_AWAKE;
934 mDirty |= DIRTY_WAKEFULNESS;
935
936 userActivityNoUpdateLocked(
937 eventTime, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
938 return true;
939 }
940
941 @Override // Binder call
942 public void goToSleep(long eventTime, int reason) {
943 if (eventTime > SystemClock.uptimeMillis()) {
944 throw new IllegalArgumentException("event time must not be in the future");
945 }
946
947 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
948
949 final long ident = Binder.clearCallingIdentity();
950 try {
951 goToSleepInternal(eventTime, reason);
952 } finally {
953 Binder.restoreCallingIdentity(ident);
954 }
955 }
956
957 // Called from native code.
958 private void goToSleepFromNative(long eventTime, int reason) {
959 goToSleepInternal(eventTime, reason);
960 }
961
962 private void goToSleepInternal(long eventTime, int reason) {
963 synchronized (mLock) {
964 if (goToSleepNoUpdateLocked(eventTime, reason)) {
965 updatePowerStateLocked();
966 }
967 }
968 }
969
970 private boolean goToSleepNoUpdateLocked(long eventTime, int reason) {
971 if (DEBUG_SPEW) {
972 Slog.d(TAG, "goToSleepNoUpdateLocked: eventTime=" + eventTime + ", reason=" + reason);
973 }
974
975 if (eventTime < mLastWakeTime || mWakefulness == WAKEFULNESS_ASLEEP
976 || !mBootCompleted || !mSystemReady) {
977 return false;
978 }
979
980 switch (reason) {
981 case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN:
982 Slog.i(TAG, "Going to sleep due to device administration policy...");
983 break;
984 case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT:
985 Slog.i(TAG, "Going to sleep due to screen timeout...");
986 break;
987 default:
988 Slog.i(TAG, "Going to sleep by user request...");
989 reason = PowerManager.GO_TO_SLEEP_REASON_USER;
990 break;
991 }
992
Jeff Brown54308352012-10-04 17:59:58 -0700993 sendPendingNotificationsLocked();
994 mNotifier.onGoToSleepStarted(reason);
995 mSendGoToSleepFinishedNotificationWhenReady = true;
996
Jeff Brown96307042012-07-27 15:51:34 -0700997 mLastSleepTime = eventTime;
998 mDirty |= DIRTY_WAKEFULNESS;
999 mWakefulness = WAKEFULNESS_ASLEEP;
Jeff Brown96307042012-07-27 15:51:34 -07001000
1001 // Report the number of wake locks that will be cleared by going to sleep.
1002 int numWakeLocksCleared = 0;
1003 final int numWakeLocks = mWakeLocks.size();
1004 for (int i = 0; i < numWakeLocks; i++) {
1005 final WakeLock wakeLock = mWakeLocks.get(i);
1006 switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
1007 case PowerManager.FULL_WAKE_LOCK:
1008 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
1009 case PowerManager.SCREEN_DIM_WAKE_LOCK:
1010 numWakeLocksCleared += 1;
1011 break;
1012 }
1013 }
1014 EventLog.writeEvent(EventLogTags.POWER_SLEEP_REQUESTED, numWakeLocksCleared);
1015 return true;
1016 }
1017
Jeff Brown62c82e42012-09-26 01:30:41 -07001018 @Override // Binder call
1019 public void nap(long eventTime) {
1020 if (eventTime > SystemClock.uptimeMillis()) {
1021 throw new IllegalArgumentException("event time must not be in the future");
1022 }
1023
1024 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1025
1026 final long ident = Binder.clearCallingIdentity();
1027 try {
1028 napInternal(eventTime);
1029 } finally {
1030 Binder.restoreCallingIdentity(ident);
1031 }
1032 }
1033
1034 private void napInternal(long eventTime) {
1035 synchronized (mLock) {
1036 if (napNoUpdateLocked(eventTime)) {
1037 updatePowerStateLocked();
1038 }
1039 }
1040 }
1041
1042 private boolean napNoUpdateLocked(long eventTime) {
1043 if (DEBUG_SPEW) {
1044 Slog.d(TAG, "napNoUpdateLocked: eventTime=" + eventTime);
1045 }
1046
1047 if (eventTime < mLastWakeTime || mWakefulness != WAKEFULNESS_AWAKE
1048 || !mBootCompleted || !mSystemReady) {
1049 return false;
1050 }
1051
1052 Slog.i(TAG, "Nap time...");
1053
1054 mDirty |= DIRTY_WAKEFULNESS;
1055 mWakefulness = WAKEFULNESS_NAPPING;
1056 return true;
1057 }
1058
Jeff Brown96307042012-07-27 15:51:34 -07001059 /**
1060 * Updates the global power state based on dirty bits recorded in mDirty.
1061 *
1062 * This is the main function that performs power state transitions.
1063 * We centralize them here so that we can recompute the power state completely
1064 * each time something important changes, and ensure that we do it the same
1065 * way each time. The point is to gather all of the transition logic here.
1066 */
1067 private void updatePowerStateLocked() {
1068 if (!mSystemReady || mDirty == 0) {
The Android Open Source Project10592532009-03-18 17:39:46 -07001069 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001070 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001071
Jeff Brown96307042012-07-27 15:51:34 -07001072 // Phase 0: Basic state updates.
1073 updateIsPoweredLocked(mDirty);
1074 updateStayOnLocked(mDirty);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001075
Jeff Brown96307042012-07-27 15:51:34 -07001076 // Phase 1: Update wakefulness.
1077 // Loop because the wake lock and user activity computations are influenced
1078 // by changes in wakefulness.
1079 final long now = SystemClock.uptimeMillis();
1080 int dirtyPhase2 = 0;
1081 for (;;) {
1082 int dirtyPhase1 = mDirty;
1083 dirtyPhase2 |= dirtyPhase1;
1084 mDirty = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001085
Jeff Brown96307042012-07-27 15:51:34 -07001086 updateWakeLockSummaryLocked(dirtyPhase1);
1087 updateUserActivitySummaryLocked(now, dirtyPhase1);
1088 if (!updateWakefulnessLocked(dirtyPhase1)) {
1089 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001090 }
1091 }
1092
Jeff Brown96307042012-07-27 15:51:34 -07001093 // Phase 2: Update dreams and display power state.
1094 updateDreamLocked(dirtyPhase2);
1095 updateDisplayPowerStateLocked(dirtyPhase2);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001096
Jeff Brown96307042012-07-27 15:51:34 -07001097 // Phase 3: Send notifications, if needed.
Jeff Brown54308352012-10-04 17:59:58 -07001098 if (mDisplayReady) {
1099 sendPendingNotificationsLocked();
1100 }
Craig Mautner75fc9de2012-06-18 16:53:27 -07001101
Jeff Brown96307042012-07-27 15:51:34 -07001102 // Phase 4: Update suspend blocker.
1103 // Because we might release the last suspend blocker here, we need to make sure
1104 // we finished everything else first!
1105 updateSuspendBlockerLocked();
1106 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001107
Jeff Brown96307042012-07-27 15:51:34 -07001108 private void sendPendingNotificationsLocked() {
Jeff Brown54308352012-10-04 17:59:58 -07001109 if (mSendWakeUpFinishedNotificationWhenReady) {
1110 mSendWakeUpFinishedNotificationWhenReady = false;
1111 mNotifier.onWakeUpFinished();
1112 }
1113 if (mSendGoToSleepFinishedNotificationWhenReady) {
1114 mSendGoToSleepFinishedNotificationWhenReady = false;
1115 mNotifier.onGoToSleepFinished();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001116 }
The Android Open Source Project10592532009-03-18 17:39:46 -07001117 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001118
Jim Miller92e66dd2012-02-21 18:57:12 -08001119 /**
Jeff Brown96307042012-07-27 15:51:34 -07001120 * Updates the value of mIsPowered.
1121 * Sets DIRTY_IS_POWERED if a change occurred.
Jim Miller92e66dd2012-02-21 18:57:12 -08001122 */
Jeff Brown96307042012-07-27 15:51:34 -07001123 private void updateIsPoweredLocked(int dirty) {
1124 if ((dirty & DIRTY_BATTERY_STATE) != 0) {
Jeff Brownf3fb8952012-10-02 20:57:05 -07001125 final boolean wasPowered = mIsPowered;
1126 final int oldPlugType = mPlugType;
Jeff Browna4d82042012-10-02 19:11:19 -07001127 mIsPowered = mBatteryService.isPowered(BatteryManager.BATTERY_PLUGGED_ANY);
Jeff Brownf3fb8952012-10-02 20:57:05 -07001128 mPlugType = mBatteryService.getPlugType();
Jeff Brown016ff142012-10-15 16:47:22 -07001129 mBatteryLevel = mBatteryService.getBatteryLevel();
Jeff Browna4d82042012-10-02 19:11:19 -07001130
1131 if (DEBUG) {
1132 Slog.d(TAG, "updateIsPoweredLocked: wasPowered=" + wasPowered
Jeff Brownf3fb8952012-10-02 20:57:05 -07001133 + ", mIsPowered=" + mIsPowered
1134 + ", oldPlugType=" + oldPlugType
Jeff Brown016ff142012-10-15 16:47:22 -07001135 + ", mPlugType=" + mPlugType
1136 + ", mBatteryLevel=" + mBatteryLevel);
Jeff Browna4d82042012-10-02 19:11:19 -07001137 }
Jim Miller92e66dd2012-02-21 18:57:12 -08001138
Jeff Brownf3fb8952012-10-02 20:57:05 -07001139 if (wasPowered != mIsPowered || oldPlugType != mPlugType) {
Jeff Brown96307042012-07-27 15:51:34 -07001140 mDirty |= DIRTY_IS_POWERED;
1141
1142 // Treat plugging and unplugging the devices as a user activity.
1143 // Users find it disconcerting when they plug or unplug the device
1144 // and it shuts off right away.
1145 // Some devices also wake the device when plugged or unplugged because
1146 // they don't have a charging LED.
1147 final long now = SystemClock.uptimeMillis();
Jeff Brownf3fb8952012-10-02 20:57:05 -07001148 if (shouldWakeUpWhenPluggedOrUnpluggedLocked(wasPowered, oldPlugType)) {
Jeff Brown96307042012-07-27 15:51:34 -07001149 wakeUpNoUpdateLocked(now);
1150 }
1151 userActivityNoUpdateLocked(
1152 now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
Jeff Brown84e27562012-12-07 13:56:34 -08001153
1154 // Tell the notifier whether wireless charging has started so that
1155 // it can provide feedback to the user. Refer to
1156 // shouldWakeUpWhenPluggedOrUnpluggedLocked for justification of the
1157 // heuristics used here.
1158 if (!wasPowered && mIsPowered
1159 && mPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS
1160 && mBatteryLevel < WIRELESS_CHARGER_TURN_ON_BATTERY_LEVEL_LIMIT) {
1161 mNotifier.onWirelessChargingStarted();
1162 }
Jeff Brown96307042012-07-27 15:51:34 -07001163 }
1164 }
1165 }
1166
Jeff Brownf3fb8952012-10-02 20:57:05 -07001167 private boolean shouldWakeUpWhenPluggedOrUnpluggedLocked(boolean wasPowered, int oldPlugType) {
Jeff Brown9fca9e92012-10-05 14:42:56 -07001168 // Don't wake when powered unless configured to do so.
1169 if (!mWakeUpWhenPluggedOrUnpluggedConfig) {
1170 return false;
Jeff Brownf3fb8952012-10-02 20:57:05 -07001171 }
Jeff Brown9fca9e92012-10-05 14:42:56 -07001172
1173 // FIXME: Need more accurate detection of wireless chargers.
1174 //
1175 // We are unable to accurately detect whether the device is resting on the
1176 // charger unless it is actually receiving power. This causes us some grief
1177 // because the device might not appear to be plugged into the wireless charger
1178 // unless it actually charging.
1179 //
1180 // To avoid spuriously waking the screen, we apply a special policy to
1181 // wireless chargers.
1182 //
1183 // 1. Don't wake the device when unplugged from wireless charger because
1184 // it might be that the device is still resting on the wireless charger
1185 // but is not receiving power anymore because the battery is full.
1186 //
1187 // 2. Don't wake the device when plugged into a wireless charger if the
1188 // battery already appears to be mostly full. This situation may indicate
1189 // that the device was resting on the charger the whole time and simply
1190 // wasn't receiving power because the battery was full. We can't tell
1191 // whether the device was just placed on the charger or whether it has
1192 // been there for half of the night slowly discharging until it hit
1193 // the point where it needed to start charging again.
1194 if (wasPowered && !mIsPowered
1195 && oldPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS) {
1196 return false;
1197 }
1198 if (!wasPowered && mIsPowered
1199 && mPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS
Jeff Brown016ff142012-10-15 16:47:22 -07001200 && mBatteryLevel >= WIRELESS_CHARGER_TURN_ON_BATTERY_LEVEL_LIMIT) {
Jeff Brown9fca9e92012-10-05 14:42:56 -07001201 return false;
1202 }
1203
1204 // If already dreaming and becoming powered, then don't wake.
1205 if (mIsPowered && (mWakefulness == WAKEFULNESS_NAPPING
1206 || mWakefulness == WAKEFULNESS_DREAMING)) {
1207 return false;
1208 }
1209
1210 // Otherwise wake up!
1211 return true;
Jeff Brownf3fb8952012-10-02 20:57:05 -07001212 }
1213
Jeff Brown96307042012-07-27 15:51:34 -07001214 /**
1215 * Updates the value of mStayOn.
1216 * Sets DIRTY_STAY_ON if a change occurred.
1217 */
1218 private void updateStayOnLocked(int dirty) {
1219 if ((dirty & (DIRTY_BATTERY_STATE | DIRTY_SETTINGS)) != 0) {
Jeff Brown93cbbb22012-10-04 13:18:36 -07001220 final boolean wasStayOn = mStayOn;
Jeff Brown96307042012-07-27 15:51:34 -07001221 if (mStayOnWhilePluggedInSetting != 0
1222 && !isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
1223 mStayOn = mBatteryService.isPowered(mStayOnWhilePluggedInSetting);
1224 } else {
1225 mStayOn = false;
1226 }
Jeff Brown93cbbb22012-10-04 13:18:36 -07001227
1228 if (mStayOn != wasStayOn) {
1229 mDirty |= DIRTY_STAY_ON;
1230 }
Jeff Brown96307042012-07-27 15:51:34 -07001231 }
1232 }
1233
1234 /**
1235 * Updates the value of mWakeLockSummary to summarize the state of all active wake locks.
1236 * Note that most wake-locks are ignored when the system is asleep.
1237 *
1238 * This function must have no other side-effects.
1239 */
1240 private void updateWakeLockSummaryLocked(int dirty) {
1241 if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_WAKEFULNESS)) != 0) {
1242 mWakeLockSummary = 0;
1243
1244 final int numWakeLocks = mWakeLocks.size();
1245 for (int i = 0; i < numWakeLocks; i++) {
1246 final WakeLock wakeLock = mWakeLocks.get(i);
1247 switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
1248 case PowerManager.PARTIAL_WAKE_LOCK:
1249 mWakeLockSummary |= WAKE_LOCK_CPU;
1250 break;
1251 case PowerManager.FULL_WAKE_LOCK:
1252 if (mWakefulness != WAKEFULNESS_ASLEEP) {
1253 mWakeLockSummary |= WAKE_LOCK_CPU
1254 | WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_BUTTON_BRIGHT;
Jeff Brown10428742012-10-09 15:47:30 -07001255 if (mWakefulness == WAKEFULNESS_AWAKE) {
1256 mWakeLockSummary |= WAKE_LOCK_STAY_AWAKE;
1257 }
Jeff Brown96307042012-07-27 15:51:34 -07001258 }
1259 break;
1260 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
1261 if (mWakefulness != WAKEFULNESS_ASLEEP) {
1262 mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_SCREEN_BRIGHT;
Jeff Brown10428742012-10-09 15:47:30 -07001263 if (mWakefulness == WAKEFULNESS_AWAKE) {
1264 mWakeLockSummary |= WAKE_LOCK_STAY_AWAKE;
1265 }
Jeff Brown96307042012-07-27 15:51:34 -07001266 }
1267 break;
1268 case PowerManager.SCREEN_DIM_WAKE_LOCK:
1269 if (mWakefulness != WAKEFULNESS_ASLEEP) {
1270 mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_SCREEN_DIM;
Jeff Brown10428742012-10-09 15:47:30 -07001271 if (mWakefulness == WAKEFULNESS_AWAKE) {
1272 mWakeLockSummary |= WAKE_LOCK_STAY_AWAKE;
1273 }
Jeff Brown96307042012-07-27 15:51:34 -07001274 }
1275 break;
1276 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
1277 if (mWakefulness != WAKEFULNESS_ASLEEP) {
1278 mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_PROXIMITY_SCREEN_OFF;
1279 }
1280 break;
1281 }
1282 }
1283
1284 if (DEBUG_SPEW) {
1285 Slog.d(TAG, "updateWakeLockSummaryLocked: mWakefulness="
1286 + wakefulnessToString(mWakefulness)
1287 + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary));
1288 }
1289 }
1290 }
1291
1292 /**
1293 * Updates the value of mUserActivitySummary to summarize the user requested
1294 * state of the system such as whether the screen should be bright or dim.
1295 * Note that user activity is ignored when the system is asleep.
1296 *
1297 * This function must have no other side-effects.
1298 */
1299 private void updateUserActivitySummaryLocked(long now, int dirty) {
1300 // Update the status of the user activity timeout timer.
1301 if ((dirty & (DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS | DIRTY_SETTINGS)) != 0) {
1302 mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT);
1303
1304 long nextTimeout = 0;
1305 if (mWakefulness != WAKEFULNESS_ASLEEP) {
1306 final int screenOffTimeout = getScreenOffTimeoutLocked();
Jeff Brownff532542012-10-02 21:18:04 -07001307 final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
Jeff Brown96307042012-07-27 15:51:34 -07001308
1309 mUserActivitySummary = 0;
1310 if (mLastUserActivityTime >= mLastWakeTime) {
1311 nextTimeout = mLastUserActivityTime
1312 + screenOffTimeout - screenDimDuration;
1313 if (now < nextTimeout) {
1314 mUserActivitySummary |= USER_ACTIVITY_SCREEN_BRIGHT;
1315 } else {
1316 nextTimeout = mLastUserActivityTime + screenOffTimeout;
1317 if (now < nextTimeout) {
1318 mUserActivitySummary |= USER_ACTIVITY_SCREEN_DIM;
1319 }
1320 }
1321 }
1322 if (mUserActivitySummary == 0
1323 && mLastUserActivityTimeNoChangeLights >= mLastWakeTime) {
1324 nextTimeout = mLastUserActivityTimeNoChangeLights + screenOffTimeout;
1325 if (now < nextTimeout
1326 && mDisplayPowerRequest.screenState
1327 != DisplayPowerRequest.SCREEN_STATE_OFF) {
1328 mUserActivitySummary = mDisplayPowerRequest.screenState
1329 == DisplayPowerRequest.SCREEN_STATE_BRIGHT ?
1330 USER_ACTIVITY_SCREEN_BRIGHT : USER_ACTIVITY_SCREEN_DIM;
1331 }
1332 }
1333 if (mUserActivitySummary != 0) {
1334 Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY_TIMEOUT);
1335 msg.setAsynchronous(true);
1336 mHandler.sendMessageAtTime(msg, nextTimeout);
1337 }
1338 } else {
1339 mUserActivitySummary = 0;
1340 }
1341
1342 if (DEBUG_SPEW) {
1343 Slog.d(TAG, "updateUserActivitySummaryLocked: mWakefulness="
1344 + wakefulnessToString(mWakefulness)
1345 + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
1346 + ", nextTimeout=" + TimeUtils.formatUptime(nextTimeout));
1347 }
1348 }
1349 }
1350
1351 /**
1352 * Called when a user activity timeout has occurred.
1353 * Simply indicates that something about user activity has changed so that the new
1354 * state can be recomputed when the power state is updated.
1355 *
1356 * This function must have no other side-effects besides setting the dirty
1357 * bit and calling update power state. Wakefulness transitions are handled elsewhere.
1358 */
1359 private void handleUserActivityTimeout() { // runs on handler thread
1360 synchronized (mLock) {
1361 if (DEBUG_SPEW) {
1362 Slog.d(TAG, "handleUserActivityTimeout");
1363 }
1364
1365 mDirty |= DIRTY_USER_ACTIVITY;
1366 updatePowerStateLocked();
1367 }
1368 }
1369
1370 private int getScreenOffTimeoutLocked() {
1371 int timeout = mScreenOffTimeoutSetting;
1372 if (isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
1373 timeout = Math.min(timeout, mMaximumScreenOffTimeoutFromDeviceAdmin);
1374 }
Jeff Brown1e3b98d2012-09-30 18:58:59 -07001375 if (mUserActivityTimeoutOverrideFromWindowManager >= 0) {
1376 timeout = (int)Math.min(timeout, mUserActivityTimeoutOverrideFromWindowManager);
1377 }
Jeff Brown96307042012-07-27 15:51:34 -07001378 return Math.max(timeout, MINIMUM_SCREEN_OFF_TIMEOUT);
1379 }
1380
Jeff Brownff532542012-10-02 21:18:04 -07001381 private int getScreenDimDurationLocked(int screenOffTimeout) {
1382 return Math.min(SCREEN_DIM_DURATION,
1383 (int)(screenOffTimeout * MAXIMUM_SCREEN_DIM_RATIO));
Jeff Brown96307042012-07-27 15:51:34 -07001384 }
1385
1386 /**
1387 * Updates the wakefulness of the device.
1388 *
1389 * This is the function that decides whether the device should start napping
1390 * based on the current wake locks and user activity state. It may modify mDirty
1391 * if the wakefulness changes.
1392 *
1393 * Returns true if the wakefulness changed and we need to restart power state calculation.
1394 */
1395 private boolean updateWakefulnessLocked(int dirty) {
1396 boolean changed = false;
1397 if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_BOOT_COMPLETED
Jeff Brownec6aa592012-10-17 20:30:25 -07001398 | DIRTY_WAKEFULNESS | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE
1399 | DIRTY_DOCK_STATE)) != 0) {
Jeff Brown96307042012-07-27 15:51:34 -07001400 if (mWakefulness == WAKEFULNESS_AWAKE && isItBedTimeYetLocked()) {
1401 if (DEBUG_SPEW) {
Jeff Brown62c82e42012-09-26 01:30:41 -07001402 Slog.d(TAG, "updateWakefulnessLocked: Bed time...");
Jeff Brown96307042012-07-27 15:51:34 -07001403 }
Jeff Brown62c82e42012-09-26 01:30:41 -07001404 final long time = SystemClock.uptimeMillis();
Jeff Brownec6aa592012-10-17 20:30:25 -07001405 if (shouldNapAtBedTimeLocked()) {
Jeff Brown62c82e42012-09-26 01:30:41 -07001406 changed = napNoUpdateLocked(time);
1407 } else {
1408 changed = goToSleepNoUpdateLocked(time,
1409 PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
1410 }
Jeff Brown96307042012-07-27 15:51:34 -07001411 }
1412 }
1413 return changed;
1414 }
1415
Jeff Brown645832d2012-10-03 14:57:03 -07001416 /**
Jeff Brownec6aa592012-10-17 20:30:25 -07001417 * Returns true if the device should automatically nap and start dreaming when the user
1418 * activity timeout has expired and it's bedtime.
1419 */
1420 private boolean shouldNapAtBedTimeLocked() {
1421 return mDreamsActivateOnSleepSetting
1422 || (mDreamsActivateOnDockSetting
1423 && mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED);
1424 }
1425
1426 /**
Jeff Brown645832d2012-10-03 14:57:03 -07001427 * Returns true if the device should go to sleep now.
1428 * Also used when exiting a dream to determine whether we should go back
1429 * to being fully awake or else go to sleep for good.
1430 */
Jeff Brown96307042012-07-27 15:51:34 -07001431 private boolean isItBedTimeYetLocked() {
Jeff Brown93cbbb22012-10-04 13:18:36 -07001432 return mBootCompleted && !isBeingKeptAwakeLocked();
Jeff Brown645832d2012-10-03 14:57:03 -07001433 }
1434
1435 /**
Jeff Brown93cbbb22012-10-04 13:18:36 -07001436 * Returns true if the device is being kept awake by a wake lock, user activity
Jeff Brown645832d2012-10-03 14:57:03 -07001437 * or the stay on while powered setting.
1438 */
Jeff Brown93cbbb22012-10-04 13:18:36 -07001439 private boolean isBeingKeptAwakeLocked() {
Jeff Brown645832d2012-10-03 14:57:03 -07001440 return mStayOn
Jeff Brown93cbbb22012-10-04 13:18:36 -07001441 || mProximityPositive
Jeff Brown10428742012-10-09 15:47:30 -07001442 || (mWakeLockSummary & WAKE_LOCK_STAY_AWAKE) != 0
Jeff Brown645832d2012-10-03 14:57:03 -07001443 || (mUserActivitySummary & (USER_ACTIVITY_SCREEN_BRIGHT
1444 | USER_ACTIVITY_SCREEN_DIM)) != 0;
Jeff Brown96307042012-07-27 15:51:34 -07001445 }
1446
1447 /**
1448 * Determines whether to post a message to the sandman to update the dream state.
1449 */
1450 private void updateDreamLocked(int dirty) {
John Spurlockf4f6b4c2012-08-25 12:08:03 -04001451 if ((dirty & (DIRTY_WAKEFULNESS
Jeff Brown645832d2012-10-03 14:57:03 -07001452 | DIRTY_USER_ACTIVITY
1453 | DIRTY_WAKE_LOCKS
1454 | DIRTY_BOOT_COMPLETED
John Spurlockf4f6b4c2012-08-25 12:08:03 -04001455 | DIRTY_SETTINGS
1456 | DIRTY_IS_POWERED
1457 | DIRTY_STAY_ON
Jeff Brown93cbbb22012-10-04 13:18:36 -07001458 | DIRTY_PROXIMITY_POSITIVE
Jeff Brown62c82e42012-09-26 01:30:41 -07001459 | DIRTY_BATTERY_STATE)) != 0) {
Jeff Brown96307042012-07-27 15:51:34 -07001460 scheduleSandmanLocked();
1461 }
1462 }
1463
1464 private void scheduleSandmanLocked() {
1465 if (!mSandmanScheduled) {
1466 mSandmanScheduled = true;
1467 Message msg = mHandler.obtainMessage(MSG_SANDMAN);
1468 msg.setAsynchronous(true);
1469 mHandler.sendMessage(msg);
1470 }
1471 }
1472
1473 /**
1474 * Called when the device enters or exits a napping or dreaming state.
1475 *
1476 * We do this asynchronously because we must call out of the power manager to start
1477 * the dream and we don't want to hold our lock while doing so. There is a risk that
1478 * the device will wake or go to sleep in the meantime so we have to handle that case.
1479 */
1480 private void handleSandman() { // runs on handler thread
1481 // Handle preconditions.
1482 boolean startDreaming = false;
1483 synchronized (mLock) {
1484 mSandmanScheduled = false;
John Spurlock10fb2242012-08-23 15:32:28 -04001485 boolean canDream = canDreamLocked();
Jeff Brown96307042012-07-27 15:51:34 -07001486 if (DEBUG_SPEW) {
Jeff Brown016ff142012-10-15 16:47:22 -07001487 Slog.d(TAG, "handleSandman: canDream=" + canDream
Jeff Brown96307042012-07-27 15:51:34 -07001488 + ", mWakefulness=" + wakefulnessToString(mWakefulness));
1489 }
1490
John Spurlock10fb2242012-08-23 15:32:28 -04001491 if (canDream && mWakefulness == WAKEFULNESS_NAPPING) {
Jeff Brown96307042012-07-27 15:51:34 -07001492 startDreaming = true;
1493 }
1494 }
1495
Jeff Brown96307042012-07-27 15:51:34 -07001496 // Start dreaming if needed.
1497 // We only control the dream on the handler thread, so we don't need to worry about
1498 // concurrent attempts to start or stop the dream.
1499 boolean isDreaming = false;
1500 if (mDreamManager != null) {
Jeff Brown62c82e42012-09-26 01:30:41 -07001501 if (startDreaming) {
1502 mDreamManager.startDream();
Jeff Brown96307042012-07-27 15:51:34 -07001503 }
Jeff Brown62c82e42012-09-26 01:30:41 -07001504 isDreaming = mDreamManager.isDreaming();
Jeff Brown96307042012-07-27 15:51:34 -07001505 }
1506
1507 // Update dream state.
1508 // We might need to stop the dream again if the preconditions changed.
1509 boolean continueDreaming = false;
1510 synchronized (mLock) {
1511 if (isDreaming && canDreamLocked()) {
1512 if (mWakefulness == WAKEFULNESS_NAPPING) {
1513 mWakefulness = WAKEFULNESS_DREAMING;
1514 mDirty |= DIRTY_WAKEFULNESS;
Jeff Brown016ff142012-10-15 16:47:22 -07001515 mBatteryLevelWhenDreamStarted = mBatteryLevel;
Jeff Brown96307042012-07-27 15:51:34 -07001516 updatePowerStateLocked();
1517 continueDreaming = true;
1518 } else if (mWakefulness == WAKEFULNESS_DREAMING) {
Jeff Brown016ff142012-10-15 16:47:22 -07001519 if (!isBeingKeptAwakeLocked()
1520 && mBatteryLevel < mBatteryLevelWhenDreamStarted
1521 - DREAM_BATTERY_LEVEL_DRAIN_CUTOFF) {
1522 // If the user activity timeout expired and the battery appears
1523 // to be draining faster than it is charging then stop dreaming
1524 // and go to sleep.
1525 Slog.i(TAG, "Stopping dream because the battery appears to "
1526 + "be draining faster than it is charging. "
1527 + "Battery level when dream started: "
1528 + mBatteryLevelWhenDreamStarted + "%. "
1529 + "Battery level now: " + mBatteryLevel + "%.");
1530 } else {
1531 continueDreaming = true;
1532 }
Jeff Brown96307042012-07-27 15:51:34 -07001533 }
1534 }
1535 if (!continueDreaming) {
1536 handleDreamFinishedLocked();
1537 }
Jeff Brown96307042012-07-27 15:51:34 -07001538 }
1539
1540 // Stop dreaming if needed.
1541 // It's possible that something else changed to make us need to start the dream again.
1542 // If so, then the power manager will have posted another message to the handler
1543 // to take care of it later.
1544 if (mDreamManager != null) {
Jeff Brown62c82e42012-09-26 01:30:41 -07001545 if (!continueDreaming) {
1546 mDreamManager.stopDream();
Jeff Brown96307042012-07-27 15:51:34 -07001547 }
1548 }
1549 }
1550
1551 /**
Jeff Brown645832d2012-10-03 14:57:03 -07001552 * Returns true if the device is allowed to dream in its current state
1553 * assuming that it is currently napping or dreaming.
Jeff Brown96307042012-07-27 15:51:34 -07001554 */
1555 private boolean canDreamLocked() {
Jeff Brown645832d2012-10-03 14:57:03 -07001556 return mDreamsSupportedConfig
John Spurlock10fb2242012-08-23 15:32:28 -04001557 && mDreamsEnabledSetting
Jeff Brown645832d2012-10-03 14:57:03 -07001558 && mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF
1559 && mBootCompleted
Jeff Brown93cbbb22012-10-04 13:18:36 -07001560 && (mIsPowered || isBeingKeptAwakeLocked());
Jeff Brown96307042012-07-27 15:51:34 -07001561 }
1562
1563 /**
1564 * Called when a dream is ending to figure out what to do next.
1565 */
1566 private void handleDreamFinishedLocked() {
1567 if (mWakefulness == WAKEFULNESS_NAPPING
1568 || mWakefulness == WAKEFULNESS_DREAMING) {
1569 if (isItBedTimeYetLocked()) {
1570 goToSleepNoUpdateLocked(SystemClock.uptimeMillis(),
1571 PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
1572 updatePowerStateLocked();
1573 } else {
1574 wakeUpNoUpdateLocked(SystemClock.uptimeMillis());
1575 updatePowerStateLocked();
1576 }
1577 }
1578 }
1579
Jeff Brownc38c9be2012-10-04 13:16:19 -07001580 private void handleScreenOnBlockerReleased() {
1581 synchronized (mLock) {
1582 mDirty |= DIRTY_SCREEN_ON_BLOCKER_RELEASED;
1583 updatePowerStateLocked();
1584 }
1585 }
1586
Jeff Brown96307042012-07-27 15:51:34 -07001587 /**
1588 * Updates the display power state asynchronously.
1589 * When the update is finished, mDisplayReady will be set to true. The display
1590 * controller posts a message to tell us when the actual display power state
1591 * has been updated so we come back here to double-check and finish up.
1592 *
1593 * This function recalculates the display power state each time.
1594 */
1595 private void updateDisplayPowerStateLocked(int dirty) {
1596 if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS
1597 | DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED
Jeff Brownc38c9be2012-10-04 13:16:19 -07001598 | DIRTY_SETTINGS | DIRTY_SCREEN_ON_BLOCKER_RELEASED)) != 0) {
1599 int newScreenState = getDesiredScreenPowerStateLocked();
Jeff Brown96307042012-07-27 15:51:34 -07001600 if (newScreenState != mDisplayPowerRequest.screenState) {
1601 if (newScreenState == DisplayPowerRequest.SCREEN_STATE_OFF
1602 && mDisplayPowerRequest.screenState
1603 != DisplayPowerRequest.SCREEN_STATE_OFF) {
1604 mLastScreenOffEventElapsedRealTime = SystemClock.elapsedRealtime();
1605 }
1606
1607 mDisplayPowerRequest.screenState = newScreenState;
1608 nativeSetPowerState(
1609 newScreenState != DisplayPowerRequest.SCREEN_STATE_OFF,
1610 newScreenState == DisplayPowerRequest.SCREEN_STATE_BRIGHT);
1611 }
1612
1613 int screenBrightness = mScreenBrightnessSettingDefault;
Jeff Brown330560f2012-08-21 22:10:57 -07001614 float screenAutoBrightnessAdjustment = 0.0f;
Jeff Brown96307042012-07-27 15:51:34 -07001615 boolean autoBrightness = (mScreenBrightnessModeSetting ==
1616 Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
1617 if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)) {
1618 screenBrightness = mScreenBrightnessOverrideFromWindowManager;
1619 autoBrightness = false;
1620 } else if (isValidBrightness(mTemporaryScreenBrightnessSettingOverride)) {
1621 screenBrightness = mTemporaryScreenBrightnessSettingOverride;
1622 } else if (isValidBrightness(mScreenBrightnessSetting)) {
Jeff Brown330560f2012-08-21 22:10:57 -07001623 screenBrightness = mScreenBrightnessSetting;
Jeff Brown96307042012-07-27 15:51:34 -07001624 }
1625 if (autoBrightness) {
1626 screenBrightness = mScreenBrightnessSettingDefault;
Jeff Brown330560f2012-08-21 22:10:57 -07001627 if (isValidAutoBrightnessAdjustment(
1628 mTemporaryScreenAutoBrightnessAdjustmentSettingOverride)) {
1629 screenAutoBrightnessAdjustment =
1630 mTemporaryScreenAutoBrightnessAdjustmentSettingOverride;
1631 } else if (isValidAutoBrightnessAdjustment(
1632 mScreenAutoBrightnessAdjustmentSetting)) {
1633 screenAutoBrightnessAdjustment = mScreenAutoBrightnessAdjustmentSetting;
1634 }
Jeff Brown96307042012-07-27 15:51:34 -07001635 }
1636 screenBrightness = Math.max(Math.min(screenBrightness,
1637 mScreenBrightnessSettingMaximum), mScreenBrightnessSettingMinimum);
Jeff Brown330560f2012-08-21 22:10:57 -07001638 screenAutoBrightnessAdjustment = Math.max(Math.min(
1639 screenAutoBrightnessAdjustment, 1.0f), -1.0f);
Jeff Brown96307042012-07-27 15:51:34 -07001640 mDisplayPowerRequest.screenBrightness = screenBrightness;
Jeff Brown330560f2012-08-21 22:10:57 -07001641 mDisplayPowerRequest.screenAutoBrightnessAdjustment =
1642 screenAutoBrightnessAdjustment;
Jeff Brown96307042012-07-27 15:51:34 -07001643 mDisplayPowerRequest.useAutoBrightness = autoBrightness;
1644
1645 mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
1646
Jeff Brownc38c9be2012-10-04 13:16:19 -07001647 mDisplayPowerRequest.blockScreenOn = mScreenOnBlocker.isHeld();
1648
Jeff Brown96307042012-07-27 15:51:34 -07001649 mDisplayReady = mDisplayPowerController.requestPowerState(mDisplayPowerRequest,
1650 mRequestWaitForNegativeProximity);
1651 mRequestWaitForNegativeProximity = false;
1652
1653 if (DEBUG_SPEW) {
Jeff Brownc38c9be2012-10-04 13:16:19 -07001654 Slog.d(TAG, "updateScreenStateLocked: mDisplayReady=" + mDisplayReady
Jeff Brown96307042012-07-27 15:51:34 -07001655 + ", newScreenState=" + newScreenState
1656 + ", mWakefulness=" + mWakefulness
1657 + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary)
1658 + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
1659 + ", mBootCompleted=" + mBootCompleted);
1660 }
1661 }
1662 }
1663
1664 private static boolean isValidBrightness(int value) {
1665 return value >= 0 && value <= 255;
1666 }
1667
Jeff Brown330560f2012-08-21 22:10:57 -07001668 private static boolean isValidAutoBrightnessAdjustment(float value) {
Jeff Brown5d03a532012-08-22 13:22:02 -07001669 // Handles NaN by always returning false.
1670 return value >= -1.0f && value <= 1.0f;
Jeff Brown330560f2012-08-21 22:10:57 -07001671 }
1672
Jeff Brownc38c9be2012-10-04 13:16:19 -07001673 private int getDesiredScreenPowerStateLocked() {
Jeff Brown96307042012-07-27 15:51:34 -07001674 if (mWakefulness == WAKEFULNESS_ASLEEP) {
1675 return DisplayPowerRequest.SCREEN_STATE_OFF;
1676 }
1677
1678 if ((mWakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0
1679 || (mUserActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0
1680 || !mBootCompleted) {
1681 return DisplayPowerRequest.SCREEN_STATE_BRIGHT;
1682 }
1683
1684 return DisplayPowerRequest.SCREEN_STATE_DIM;
1685 }
1686
1687 private final DisplayPowerController.Callbacks mDisplayPowerControllerCallbacks =
1688 new DisplayPowerController.Callbacks() {
1689 @Override
1690 public void onStateChanged() {
1691 mDirty |= DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED;
1692 updatePowerStateLocked();
Jim Miller92e66dd2012-02-21 18:57:12 -08001693 }
1694
1695 @Override
Jeff Brown93cbbb22012-10-04 13:18:36 -07001696 public void onProximityPositive() {
1697 mProximityPositive = true;
1698 mDirty |= DIRTY_PROXIMITY_POSITIVE;
1699 updatePowerStateLocked();
1700 }
1701
1702 @Override
Jeff Brown96307042012-07-27 15:51:34 -07001703 public void onProximityNegative() {
Jeff Brown93cbbb22012-10-04 13:18:36 -07001704 mProximityPositive = false;
1705 mDirty |= DIRTY_PROXIMITY_POSITIVE;
Jeff Brown96307042012-07-27 15:51:34 -07001706 userActivityNoUpdateLocked(SystemClock.uptimeMillis(),
1707 PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
1708 updatePowerStateLocked();
1709 }
1710 };
Jim Miller92e66dd2012-02-21 18:57:12 -08001711
Jeff Brown96307042012-07-27 15:51:34 -07001712 private boolean shouldUseProximitySensorLocked() {
1713 return (mWakeLockSummary & WAKE_LOCK_PROXIMITY_SCREEN_OFF) != 0;
1714 }
Jim Miller92e66dd2012-02-21 18:57:12 -08001715
Jeff Brown96307042012-07-27 15:51:34 -07001716 /**
1717 * Updates the suspend blocker that keeps the CPU alive.
1718 *
1719 * This function must have no other side-effects.
1720 */
1721 private void updateSuspendBlockerLocked() {
1722 boolean wantCpu = isCpuNeededLocked();
1723 if (wantCpu != mHoldingWakeLockSuspendBlocker) {
1724 mHoldingWakeLockSuspendBlocker = wantCpu;
1725 if (wantCpu) {
1726 if (DEBUG) {
1727 Slog.d(TAG, "updateSuspendBlockerLocked: Acquiring suspend blocker.");
Jim Miller92e66dd2012-02-21 18:57:12 -08001728 }
Jeff Brown96307042012-07-27 15:51:34 -07001729 mWakeLockSuspendBlocker.acquire();
Joe Onorato4b9f62d2010-10-11 13:41:35 -07001730 } else {
Jeff Brown96307042012-07-27 15:51:34 -07001731 if (DEBUG) {
1732 Slog.d(TAG, "updateSuspendBlockerLocked: Releasing suspend blocker.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001733 }
Jeff Brown96307042012-07-27 15:51:34 -07001734 mWakeLockSuspendBlocker.release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001735 }
1736 }
1737 }
1738
Jeff Brown96307042012-07-27 15:51:34 -07001739 private boolean isCpuNeededLocked() {
1740 return !mBootCompleted
1741 || mWakeLockSummary != 0
1742 || mUserActivitySummary != 0
1743 || mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF
1744 || !mDisplayReady;
1745 }
1746
1747 @Override // Binder call
1748 public boolean isScreenOn() {
1749 final long ident = Binder.clearCallingIdentity();
Mike Lockwoodd7786b42009-10-15 17:09:16 -07001750 try {
Jeff Brown96307042012-07-27 15:51:34 -07001751 return isScreenOnInternal();
1752 } finally {
1753 Binder.restoreCallingIdentity(ident);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07001754 }
1755 }
1756
Jeff Brown96307042012-07-27 15:51:34 -07001757 private boolean isScreenOnInternal() {
1758 synchronized (mLock) {
1759 return !mSystemReady
1760 || mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF;
Mike Lockwoodb2865412010-02-02 22:40:33 -05001761 }
1762 }
1763
Jeff Brown96307042012-07-27 15:51:34 -07001764 private void handleBatteryStateChangedLocked() {
1765 mDirty |= DIRTY_BATTERY_STATE;
1766 updatePowerStateLocked();
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001767 }
1768
Jeff Brown20767b22012-10-09 18:57:07 -07001769 private void startWatchingForBootAnimationFinished() {
1770 mHandler.sendEmptyMessage(MSG_CHECK_IF_BOOT_ANIMATION_FINISHED);
1771 }
1772
1773 private void checkIfBootAnimationFinished() {
1774 if (DEBUG) {
1775 Slog.d(TAG, "Check if boot animation finished...");
1776 }
1777
1778 if (SystemService.isRunning(BOOT_ANIMATION_SERVICE)) {
1779 mHandler.sendEmptyMessageDelayed(MSG_CHECK_IF_BOOT_ANIMATION_FINISHED,
1780 BOOT_ANIMATION_POLL_INTERVAL);
1781 return;
1782 }
1783
1784 synchronized (mLock) {
1785 if (!mBootCompleted) {
1786 Slog.i(TAG, "Boot animation finished.");
1787 handleBootCompletedLocked();
1788 }
1789 }
1790 }
1791
Jeff Brown96307042012-07-27 15:51:34 -07001792 private void handleBootCompletedLocked() {
1793 final long now = SystemClock.uptimeMillis();
1794 mBootCompleted = true;
1795 mDirty |= DIRTY_BOOT_COMPLETED;
1796 userActivityNoUpdateLocked(
1797 now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
1798 updatePowerStateLocked();
Dianne Hackborn254cb442010-01-27 19:23:59 -08001799 }
1800
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001801 /**
Jeff Brownab887a02012-10-15 16:00:40 -07001802 * Reboots the device.
1803 *
1804 * @param confirm If true, shows a reboot confirmation dialog.
1805 * @param reason The reason for the reboot, or null if none.
1806 * @param wait If true, this call waits for the reboot to complete and does not return.
Doug Zongker50a21f42009-11-19 12:49:53 -08001807 */
Jeff Brown96307042012-07-27 15:51:34 -07001808 @Override // Binder call
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001809 public void reboot(boolean confirm, String reason, boolean wait) {
Doug Zongker50a21f42009-11-19 12:49:53 -08001810 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
San Mehat14e69af2010-01-06 14:58:18 -08001811
Jeff Brown96307042012-07-27 15:51:34 -07001812 final long ident = Binder.clearCallingIdentity();
1813 try {
Jeff Brownab887a02012-10-15 16:00:40 -07001814 shutdownOrRebootInternal(false, confirm, reason, wait);
Jeff Brown96307042012-07-27 15:51:34 -07001815 } finally {
1816 Binder.restoreCallingIdentity(ident);
1817 }
1818 }
1819
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001820 /**
Jeff Brownab887a02012-10-15 16:00:40 -07001821 * Shuts down the device.
1822 *
1823 * @param confirm If true, shows a shutdown confirmation dialog.
1824 * @param wait If true, this call waits for the shutdown to complete and does not return.
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001825 */
1826 @Override // Binder call
1827 public void shutdown(boolean confirm, boolean wait) {
1828 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
1829
1830 final long ident = Binder.clearCallingIdentity();
1831 try {
Jeff Brownab887a02012-10-15 16:00:40 -07001832 shutdownOrRebootInternal(true, confirm, null, wait);
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001833 } finally {
1834 Binder.restoreCallingIdentity(ident);
1835 }
1836 }
1837
Jeff Brownab887a02012-10-15 16:00:40 -07001838 private void shutdownOrRebootInternal(final boolean shutdown, final boolean confirm,
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001839 final String reason, boolean wait) {
Jeff Brown96307042012-07-27 15:51:34 -07001840 if (mHandler == null || !mSystemReady) {
Jeff Brownab887a02012-10-15 16:00:40 -07001841 throw new IllegalStateException("Too early to call shutdown() or reboot()");
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001842 }
Mike Lockwoodb62f9592010-03-12 07:55:23 -05001843
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001844 Runnable runnable = new Runnable() {
Jeff Brownab887a02012-10-15 16:00:40 -07001845 @Override
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001846 public void run() {
1847 synchronized (this) {
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001848 if (shutdown) {
1849 ShutdownThread.shutdown(mContext, confirm);
1850 } else {
1851 ShutdownThread.reboot(mContext, reason, confirm);
1852 }
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001853 }
San Mehat1e512792010-01-07 10:40:29 -08001854 }
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001855 };
Jeff Brown96307042012-07-27 15:51:34 -07001856
Mike Lockwoodb62f9592010-03-12 07:55:23 -05001857 // ShutdownThread must run on a looper capable of displaying the UI.
Jeff Brown96307042012-07-27 15:51:34 -07001858 Message msg = Message.obtain(mHandler, runnable);
1859 msg.setAsynchronous(true);
1860 mHandler.sendMessage(msg);
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001861
Mike Lockwoodb62f9592010-03-12 07:55:23 -05001862 // PowerManager.reboot() is documented not to return so just wait for the inevitable.
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001863 if (wait) {
1864 synchronized (runnable) {
1865 while (true) {
1866 try {
1867 runnable.wait();
1868 } catch (InterruptedException e) {
1869 }
Mike Lockwoodb62f9592010-03-12 07:55:23 -05001870 }
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001871 }
Doug Zongker50a21f42009-11-19 12:49:53 -08001872 }
1873 }
1874
Dan Egnor60d87622009-12-16 16:32:58 -08001875 /**
1876 * Crash the runtime (causing a complete restart of the Android framework).
1877 * Requires REBOOT permission. Mostly for testing. Should not return.
1878 */
Jeff Brown96307042012-07-27 15:51:34 -07001879 @Override // Binder call
1880 public void crash(String message) {
Dan Egnor60d87622009-12-16 16:32:58 -08001881 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
Jeff Brown96307042012-07-27 15:51:34 -07001882
1883 final long ident = Binder.clearCallingIdentity();
1884 try {
1885 crashInternal(message);
1886 } finally {
1887 Binder.restoreCallingIdentity(ident);
1888 }
1889 }
1890
1891 private void crashInternal(final String message) {
Dan Egnor60d87622009-12-16 16:32:58 -08001892 Thread t = new Thread("PowerManagerService.crash()") {
Jeff Brownab887a02012-10-15 16:00:40 -07001893 @Override
Jeff Brown96307042012-07-27 15:51:34 -07001894 public void run() {
1895 throw new RuntimeException(message);
1896 }
Dan Egnor60d87622009-12-16 16:32:58 -08001897 };
1898 try {
1899 t.start();
1900 t.join();
1901 } catch (InterruptedException e) {
1902 Log.wtf(TAG, e);
1903 }
1904 }
1905
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001906 /**
Jeff Brown96307042012-07-27 15:51:34 -07001907 * Set the setting that determines whether the device stays on when plugged in.
1908 * The argument is a bit string, with each bit specifying a power source that,
1909 * when the device is connected to that source, causes the device to stay on.
1910 * See {@link android.os.BatteryManager} for the list of power sources that
1911 * can be specified. Current values include {@link android.os.BatteryManager#BATTERY_PLUGGED_AC}
1912 * and {@link android.os.BatteryManager#BATTERY_PLUGGED_USB}
1913 *
1914 * Used by "adb shell svc power stayon ..."
1915 *
1916 * @param val an {@code int} containing the bits that specify which power sources
1917 * should cause the device to stay on.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001918 */
Jeff Brown96307042012-07-27 15:51:34 -07001919 @Override // Binder call
1920 public void setStayOnSetting(int val) {
1921 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS, null);
1922
1923 final long ident = Binder.clearCallingIdentity();
1924 try {
1925 setStayOnSettingInternal(val);
1926 } finally {
1927 Binder.restoreCallingIdentity(ident);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001928 }
1929 }
1930
Jeff Brown96307042012-07-27 15:51:34 -07001931 private void setStayOnSettingInternal(int val) {
Christopher Tatead735322012-09-07 14:19:43 -07001932 Settings.Global.putInt(mContext.getContentResolver(),
1933 Settings.Global.STAY_ON_WHILE_PLUGGED_IN, val);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001934 }
1935
1936 /**
Jeff Brown96307042012-07-27 15:51:34 -07001937 * Used by device administration to set the maximum screen off timeout.
1938 *
1939 * This method must only be called by the device administration policy manager.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001940 */
Jeff Brown96307042012-07-27 15:51:34 -07001941 @Override // Binder call
1942 public void setMaximumScreenOffTimeoutFromDeviceAdmin(int timeMs) {
1943 final long ident = Binder.clearCallingIdentity();
1944 try {
1945 setMaximumScreenOffTimeoutFromDeviceAdminInternal(timeMs);
1946 } finally {
1947 Binder.restoreCallingIdentity(ident);
Michael Chane96440f2009-05-06 10:27:36 -07001948 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001949 }
1950
Jeff Brown96307042012-07-27 15:51:34 -07001951 private void setMaximumScreenOffTimeoutFromDeviceAdminInternal(int timeMs) {
1952 synchronized (mLock) {
1953 mMaximumScreenOffTimeoutFromDeviceAdmin = timeMs;
1954 mDirty |= DIRTY_SETTINGS;
1955 updatePowerStateLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001956 }
1957 }
1958
Jeff Brown96307042012-07-27 15:51:34 -07001959 private boolean isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked() {
1960 return mMaximumScreenOffTimeoutFromDeviceAdmin >= 0
1961 && mMaximumScreenOffTimeoutFromDeviceAdmin < Integer.MAX_VALUE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001962 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001963
Jeff Brown96307042012-07-27 15:51:34 -07001964 /**
1965 * Used by the phone application to make the attention LED flash when ringing.
1966 */
1967 @Override // Binder call
Mike Lockwoodb11832d2009-11-25 15:25:55 -05001968 public void setAttentionLight(boolean on, int color) {
1969 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
Jeff Brown96307042012-07-27 15:51:34 -07001970
1971 final long ident = Binder.clearCallingIdentity();
1972 try {
1973 setAttentionLightInternal(on, color);
1974 } finally {
1975 Binder.restoreCallingIdentity(ident);
1976 }
Mike Lockwoodb11832d2009-11-25 15:25:55 -05001977 }
1978
Jeff Brown96307042012-07-27 15:51:34 -07001979 private void setAttentionLightInternal(boolean on, int color) {
1980 LightsService.Light light;
1981 synchronized (mLock) {
1982 if (!mSystemReady) {
1983 return;
1984 }
1985 light = mAttentionLight;
Mike Lockwood36fc3022009-08-25 16:49:06 -07001986 }
Jeff Brown96307042012-07-27 15:51:34 -07001987
1988 // Control light outside of lock.
1989 light.setFlashing(color, LightsService.LIGHT_FLASH_HARDWARE, (on ? 3 : 0), 0);
1990 }
1991
1992 /**
1993 * Used by the Watchdog.
1994 */
1995 public long timeSinceScreenWasLastOn() {
1996 synchronized (mLock) {
1997 if (mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF) {
1998 return 0;
1999 }
2000 return SystemClock.elapsedRealtime() - mLastScreenOffEventElapsedRealTime;
2001 }
2002 }
2003
2004 /**
2005 * Used by the window manager to override the screen brightness based on the
2006 * current foreground activity.
2007 *
2008 * This method must only be called by the window manager.
2009 *
2010 * @param brightness The overridden brightness, or -1 to disable the override.
2011 */
2012 public void setScreenBrightnessOverrideFromWindowManager(int brightness) {
2013 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
2014
2015 final long ident = Binder.clearCallingIdentity();
2016 try {
2017 setScreenBrightnessOverrideFromWindowManagerInternal(brightness);
2018 } finally {
2019 Binder.restoreCallingIdentity(ident);
2020 }
2021 }
2022
2023 private void setScreenBrightnessOverrideFromWindowManagerInternal(int brightness) {
2024 synchronized (mLock) {
2025 if (mScreenBrightnessOverrideFromWindowManager != brightness) {
2026 mScreenBrightnessOverrideFromWindowManager = brightness;
2027 mDirty |= DIRTY_SETTINGS;
2028 updatePowerStateLocked();
Mike Lockwoodee2b0942009-11-09 14:09:02 -05002029 }
Mike Lockwood809ad0f2009-10-26 22:10:33 -04002030 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07002031 }
2032
Jeff Brown96307042012-07-27 15:51:34 -07002033 /**
2034 * Used by the window manager to override the button brightness based on the
2035 * current foreground activity.
2036 *
2037 * This method must only be called by the window manager.
2038 *
2039 * @param brightness The overridden brightness, or -1 to disable the override.
2040 */
2041 public void setButtonBrightnessOverrideFromWindowManager(int brightness) {
2042 // Do nothing.
2043 // Button lights are not currently supported in the new implementation.
2044 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
2045 }
2046
2047 /**
Jeff Brown1e3b98d2012-09-30 18:58:59 -07002048 * Used by the window manager to override the user activity timeout based on the
2049 * current foreground activity. It can only be used to make the timeout shorter
2050 * than usual, not longer.
2051 *
2052 * This method must only be called by the window manager.
2053 *
2054 * @param timeoutMillis The overridden timeout, or -1 to disable the override.
2055 */
2056 public void setUserActivityTimeoutOverrideFromWindowManager(long timeoutMillis) {
2057 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
2058
2059 final long ident = Binder.clearCallingIdentity();
2060 try {
2061 setUserActivityTimeoutOverrideFromWindowManagerInternal(timeoutMillis);
2062 } finally {
2063 Binder.restoreCallingIdentity(ident);
2064 }
2065 }
2066
2067 private void setUserActivityTimeoutOverrideFromWindowManagerInternal(long timeoutMillis) {
2068 synchronized (mLock) {
2069 if (mUserActivityTimeoutOverrideFromWindowManager != timeoutMillis) {
2070 mUserActivityTimeoutOverrideFromWindowManager = timeoutMillis;
2071 mDirty |= DIRTY_SETTINGS;
2072 updatePowerStateLocked();
2073 }
2074 }
2075 }
2076
2077 /**
Jeff Brown96307042012-07-27 15:51:34 -07002078 * Used by the settings application and brightness control widgets to
2079 * temporarily override the current screen brightness setting so that the
2080 * user can observe the effect of an intended settings change without applying
2081 * it immediately.
2082 *
2083 * The override will be canceled when the setting value is next updated.
2084 *
2085 * @param brightness The overridden brightness.
2086 *
2087 * @see Settings.System#SCREEN_BRIGHTNESS
2088 */
2089 @Override // Binder call
2090 public void setTemporaryScreenBrightnessSettingOverride(int brightness) {
2091 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
2092
2093 final long ident = Binder.clearCallingIdentity();
2094 try {
2095 setTemporaryScreenBrightnessSettingOverrideInternal(brightness);
2096 } finally {
2097 Binder.restoreCallingIdentity(ident);
Mike Lockwood36fc3022009-08-25 16:49:06 -07002098 }
Jeff Brown96307042012-07-27 15:51:34 -07002099 }
2100
2101 private void setTemporaryScreenBrightnessSettingOverrideInternal(int brightness) {
2102 synchronized (mLock) {
2103 if (mTemporaryScreenBrightnessSettingOverride != brightness) {
2104 mTemporaryScreenBrightnessSettingOverride = brightness;
2105 mDirty |= DIRTY_SETTINGS;
2106 updatePowerStateLocked();
Mike Lockwoodee2b0942009-11-09 14:09:02 -05002107 }
Mike Lockwood200b30b2009-09-20 00:23:59 -04002108 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07002109 }
2110
Jeff Brown96307042012-07-27 15:51:34 -07002111 /**
2112 * Used by the settings application and brightness control widgets to
2113 * temporarily override the current screen auto-brightness adjustment setting so that the
2114 * user can observe the effect of an intended settings change without applying
2115 * it immediately.
2116 *
2117 * The override will be canceled when the setting value is next updated.
2118 *
Jeff Brown330560f2012-08-21 22:10:57 -07002119 * @param adj The overridden brightness, or Float.NaN to disable the override.
Jeff Brown96307042012-07-27 15:51:34 -07002120 *
2121 * @see Settings.System#SCREEN_AUTO_BRIGHTNESS_ADJ
2122 */
2123 @Override // Binder call
2124 public void setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(float adj) {
Jeff Brown96307042012-07-27 15:51:34 -07002125 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
Jeff Brown330560f2012-08-21 22:10:57 -07002126
2127 final long ident = Binder.clearCallingIdentity();
2128 try {
2129 setTemporaryScreenAutoBrightnessAdjustmentSettingOverrideInternal(adj);
2130 } finally {
2131 Binder.restoreCallingIdentity(ident);
2132 }
2133 }
2134
2135 private void setTemporaryScreenAutoBrightnessAdjustmentSettingOverrideInternal(float adj) {
2136 synchronized (mLock) {
2137 // Note: This condition handles NaN because NaN is not equal to any other
2138 // value, including itself.
2139 if (mTemporaryScreenAutoBrightnessAdjustmentSettingOverride != adj) {
2140 mTemporaryScreenAutoBrightnessAdjustmentSettingOverride = adj;
2141 mDirty |= DIRTY_SETTINGS;
2142 updatePowerStateLocked();
2143 }
2144 }
Jeff Brown96307042012-07-27 15:51:34 -07002145 }
2146
2147 /**
2148 * Low-level function turn the device off immediately, without trying
2149 * to be clean. Most people should use {@link ShutdownThread} for a clean shutdown.
2150 */
2151 public static void lowLevelShutdown() {
2152 nativeShutdown();
2153 }
2154
2155 /**
2156 * Low-level function to reboot the device.
2157 *
2158 * @param reason code to pass to the kernel (e.g. "recovery"), or null.
2159 * @throws IOException if reboot fails for some reason (eg, lack of
2160 * permission)
2161 */
2162 public static void lowLevelReboot(String reason) throws IOException {
2163 nativeReboot(reason);
2164 }
2165
2166 @Override // Watchdog.Monitor implementation
2167 public void monitor() {
2168 // Grab and release lock for watchdog monitor to detect deadlocks.
2169 synchronized (mLock) {
Mike Lockwood20f87d72009-11-05 16:08:51 -05002170 }
Jeff Brown96307042012-07-27 15:51:34 -07002171 }
2172
2173 @Override // Binder call
2174 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2175 if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
2176 != PackageManager.PERMISSION_GRANTED) {
2177 pw.println("Permission Denial: can't dump PowerManager from from pid="
2178 + Binder.getCallingPid()
2179 + ", uid=" + Binder.getCallingUid());
Mike Lockwood0d72f7e2009-11-05 20:53:00 -05002180 return;
2181 }
Jeff Brown96307042012-07-27 15:51:34 -07002182
2183 pw.println("POWER MANAGER (dumpsys power)\n");
2184
2185 final DisplayPowerController dpc;
2186 synchronized (mLock) {
2187 pw.println("Power Manager State:");
2188 pw.println(" mDirty=0x" + Integer.toHexString(mDirty));
2189 pw.println(" mWakefulness=" + wakefulnessToString(mWakefulness));
2190 pw.println(" mIsPowered=" + mIsPowered);
Jeff Brownf3fb8952012-10-02 20:57:05 -07002191 pw.println(" mPlugType=" + mPlugType);
Jeff Brown016ff142012-10-15 16:47:22 -07002192 pw.println(" mBatteryLevel=" + mBatteryLevel);
2193 pw.println(" mBatteryLevelWhenDreamStarted=" + mBatteryLevelWhenDreamStarted);
Jeff Brownec6aa592012-10-17 20:30:25 -07002194 pw.println(" mDockState=" + mDockState);
Jeff Brown96307042012-07-27 15:51:34 -07002195 pw.println(" mStayOn=" + mStayOn);
Jeff Brown93cbbb22012-10-04 13:18:36 -07002196 pw.println(" mProximityPositive=" + mProximityPositive);
Jeff Brown96307042012-07-27 15:51:34 -07002197 pw.println(" mBootCompleted=" + mBootCompleted);
2198 pw.println(" mSystemReady=" + mSystemReady);
2199 pw.println(" mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary));
2200 pw.println(" mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary));
2201 pw.println(" mRequestWaitForNegativeProximity=" + mRequestWaitForNegativeProximity);
2202 pw.println(" mSandmanScheduled=" + mSandmanScheduled);
2203 pw.println(" mLastWakeTime=" + TimeUtils.formatUptime(mLastWakeTime));
2204 pw.println(" mLastSleepTime=" + TimeUtils.formatUptime(mLastSleepTime));
2205 pw.println(" mSendWakeUpFinishedNotificationWhenReady="
2206 + mSendWakeUpFinishedNotificationWhenReady);
2207 pw.println(" mSendGoToSleepFinishedNotificationWhenReady="
2208 + mSendGoToSleepFinishedNotificationWhenReady);
2209 pw.println(" mLastUserActivityTime=" + TimeUtils.formatUptime(mLastUserActivityTime));
2210 pw.println(" mLastUserActivityTimeNoChangeLights="
2211 + TimeUtils.formatUptime(mLastUserActivityTimeNoChangeLights));
2212 pw.println(" mDisplayReady=" + mDisplayReady);
2213 pw.println(" mHoldingWakeLockSuspendBlocker=" + mHoldingWakeLockSuspendBlocker);
2214
2215 pw.println();
2216 pw.println("Settings and Configuration:");
2217 pw.println(" mDreamsSupportedConfig=" + mDreamsSupportedConfig);
2218 pw.println(" mDreamsEnabledSetting=" + mDreamsEnabledSetting);
John Spurlock1a868b72012-08-22 09:56:51 -04002219 pw.println(" mDreamsActivateOnSleepSetting=" + mDreamsActivateOnSleepSetting);
Jeff Brownec6aa592012-10-17 20:30:25 -07002220 pw.println(" mDreamsActivateOnDockSetting=" + mDreamsActivateOnDockSetting);
Jeff Brown96307042012-07-27 15:51:34 -07002221 pw.println(" mScreenOffTimeoutSetting=" + mScreenOffTimeoutSetting);
2222 pw.println(" mMaximumScreenOffTimeoutFromDeviceAdmin="
2223 + mMaximumScreenOffTimeoutFromDeviceAdmin + " (enforced="
2224 + isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked() + ")");
2225 pw.println(" mStayOnWhilePluggedInSetting=" + mStayOnWhilePluggedInSetting);
2226 pw.println(" mScreenBrightnessSetting=" + mScreenBrightnessSetting);
Jeff Brown330560f2012-08-21 22:10:57 -07002227 pw.println(" mScreenAutoBrightnessAdjustmentSetting="
2228 + mScreenAutoBrightnessAdjustmentSetting);
Jeff Brown96307042012-07-27 15:51:34 -07002229 pw.println(" mScreenBrightnessModeSetting=" + mScreenBrightnessModeSetting);
2230 pw.println(" mScreenBrightnessOverrideFromWindowManager="
2231 + mScreenBrightnessOverrideFromWindowManager);
Jeff Brown1e3b98d2012-09-30 18:58:59 -07002232 pw.println(" mUserActivityTimeoutOverrideFromWindowManager="
2233 + mUserActivityTimeoutOverrideFromWindowManager);
Jeff Brown96307042012-07-27 15:51:34 -07002234 pw.println(" mTemporaryScreenBrightnessSettingOverride="
2235 + mTemporaryScreenBrightnessSettingOverride);
Jeff Brown330560f2012-08-21 22:10:57 -07002236 pw.println(" mTemporaryScreenAutoBrightnessAdjustmentSettingOverride="
2237 + mTemporaryScreenAutoBrightnessAdjustmentSettingOverride);
Jeff Brown96307042012-07-27 15:51:34 -07002238 pw.println(" mScreenBrightnessSettingMinimum=" + mScreenBrightnessSettingMinimum);
2239 pw.println(" mScreenBrightnessSettingMaximum=" + mScreenBrightnessSettingMaximum);
2240 pw.println(" mScreenBrightnessSettingDefault=" + mScreenBrightnessSettingDefault);
2241
Jeff Brownff532542012-10-02 21:18:04 -07002242 final int screenOffTimeout = getScreenOffTimeoutLocked();
2243 final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
2244 pw.println();
2245 pw.println("Screen off timeout: " + screenOffTimeout + " ms");
2246 pw.println("Screen dim duration: " + screenDimDuration + " ms");
2247
Jeff Brown96307042012-07-27 15:51:34 -07002248 pw.println();
2249 pw.println("Wake Locks: size=" + mWakeLocks.size());
2250 for (WakeLock wl : mWakeLocks) {
2251 pw.println(" " + wl);
Joe Onorato8274a0e2010-10-05 17:38:09 -04002252 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05002253
Jeff Brown96307042012-07-27 15:51:34 -07002254 pw.println();
2255 pw.println("Suspend Blockers: size=" + mSuspendBlockers.size());
2256 for (SuspendBlocker sb : mSuspendBlockers) {
2257 pw.println(" " + sb);
2258 }
2259
Jeff Brownc38c9be2012-10-04 13:16:19 -07002260 pw.println();
2261 pw.println("Screen On Blocker: " + mScreenOnBlocker);
2262
Jeff Brown9e316a12012-10-08 19:17:06 -07002263 pw.println();
2264 pw.println("Display Blanker: " + mDisplayBlanker);
2265
Jeff Brown96307042012-07-27 15:51:34 -07002266 dpc = mDisplayPowerController;
2267 }
2268
2269 if (dpc != null) {
2270 dpc.dump(pw);
2271 }
2272 }
2273
2274 private SuspendBlocker createSuspendBlockerLocked(String name) {
2275 SuspendBlocker suspendBlocker = new SuspendBlockerImpl(name);
2276 mSuspendBlockers.add(suspendBlocker);
2277 return suspendBlocker;
2278 }
2279
2280 private static String wakefulnessToString(int wakefulness) {
2281 switch (wakefulness) {
2282 case WAKEFULNESS_ASLEEP:
2283 return "Asleep";
2284 case WAKEFULNESS_AWAKE:
2285 return "Awake";
2286 case WAKEFULNESS_DREAMING:
2287 return "Dreaming";
2288 case WAKEFULNESS_NAPPING:
2289 return "Napping";
2290 default:
2291 return Integer.toString(wakefulness);
2292 }
2293 }
2294
2295 private static WorkSource copyWorkSource(WorkSource workSource) {
2296 return workSource != null ? new WorkSource(workSource) : null;
2297 }
2298
2299 private final class BatteryReceiver extends BroadcastReceiver {
2300 @Override
2301 public void onReceive(Context context, Intent intent) {
2302 synchronized (mLock) {
2303 handleBatteryStateChangedLocked();
Mike Lockwoodee2b0942009-11-09 14:09:02 -05002304 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05002305 }
2306 }
2307
Jeff Brown96307042012-07-27 15:51:34 -07002308 private final class BootCompletedReceiver extends BroadcastReceiver {
2309 @Override
2310 public void onReceive(Context context, Intent intent) {
Jeff Brown20767b22012-10-09 18:57:07 -07002311 // This is our early signal that the system thinks it has finished booting.
2312 // However, the boot animation may still be running for a few more seconds
2313 // since it is ultimately in charge of when it terminates.
2314 // Defer transitioning into the boot completed state until the animation exits.
2315 // We do this so that the screen does not start to dim prematurely before
2316 // the user has actually had a chance to interact with the device.
2317 startWatchingForBootAnimationFinished();
Joe Onoratod28f7532010-11-06 12:56:53 -07002318 }
Jeff Brown96307042012-07-27 15:51:34 -07002319 }
2320
John Spurlockf4f6b4c2012-08-25 12:08:03 -04002321 private final class DreamReceiver extends BroadcastReceiver {
2322 @Override
2323 public void onReceive(Context context, Intent intent) {
2324 synchronized (mLock) {
Jeff Brown62c82e42012-09-26 01:30:41 -07002325 scheduleSandmanLocked();
John Spurlockf4f6b4c2012-08-25 12:08:03 -04002326 }
2327 }
2328 }
2329
Jeff Brownd4935962012-09-25 13:27:20 -07002330 private final class UserSwitchedReceiver extends BroadcastReceiver {
2331 @Override
2332 public void onReceive(Context context, Intent intent) {
2333 synchronized (mLock) {
2334 handleSettingsChangedLocked();
2335 }
2336 }
2337 }
2338
Jeff Brownec6aa592012-10-17 20:30:25 -07002339 private final class DockReceiver extends BroadcastReceiver {
2340 @Override
2341 public void onReceive(Context context, Intent intent) {
2342 synchronized (mLock) {
2343 int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
2344 Intent.EXTRA_DOCK_STATE_UNDOCKED);
2345 if (mDockState != dockState) {
2346 mDockState = dockState;
2347 mDirty |= DIRTY_DOCK_STATE;
2348 updatePowerStateLocked();
2349 }
2350 }
2351 }
2352 }
2353
Jeff Brown96307042012-07-27 15:51:34 -07002354 private final class SettingsObserver extends ContentObserver {
2355 public SettingsObserver(Handler handler) {
2356 super(handler);
2357 }
2358
2359 @Override
2360 public void onChange(boolean selfChange, Uri uri) {
2361 synchronized (mLock) {
2362 handleSettingsChangedLocked();
2363 }
2364 }
2365 }
2366
Jeff Brown96307042012-07-27 15:51:34 -07002367 /**
2368 * Handler for asynchronous operations performed by the power manager.
2369 */
2370 private final class PowerManagerHandler extends Handler {
2371 public PowerManagerHandler(Looper looper) {
Jeff Browna2910d02012-08-25 12:29:46 -07002372 super(looper, null, true /*async*/);
Jeff Brown96307042012-07-27 15:51:34 -07002373 }
2374
2375 @Override
2376 public void handleMessage(Message msg) {
2377 switch (msg.what) {
2378 case MSG_USER_ACTIVITY_TIMEOUT:
2379 handleUserActivityTimeout();
2380 break;
2381 case MSG_SANDMAN:
2382 handleSandman();
2383 break;
Jeff Brownc38c9be2012-10-04 13:16:19 -07002384 case MSG_SCREEN_ON_BLOCKER_RELEASED:
2385 handleScreenOnBlockerReleased();
2386 break;
Jeff Brown20767b22012-10-09 18:57:07 -07002387 case MSG_CHECK_IF_BOOT_ANIMATION_FINISHED:
2388 checkIfBootAnimationFinished();
2389 break;
Jeff Brown96307042012-07-27 15:51:34 -07002390 }
2391 }
2392 }
2393
2394 /**
2395 * Represents a wake lock that has been acquired by an application.
2396 */
2397 private final class WakeLock implements IBinder.DeathRecipient {
2398 public final IBinder mLock;
2399 public int mFlags;
2400 public String mTag;
2401 public WorkSource mWorkSource;
2402 public int mOwnerUid;
2403 public int mOwnerPid;
2404
2405 public WakeLock(IBinder lock, int flags, String tag, WorkSource workSource,
2406 int ownerUid, int ownerPid) {
2407 mLock = lock;
2408 mFlags = flags;
2409 mTag = tag;
2410 mWorkSource = copyWorkSource(workSource);
2411 mOwnerUid = ownerUid;
2412 mOwnerPid = ownerPid;
2413 }
2414
2415 @Override
2416 public void binderDied() {
2417 PowerManagerService.this.handleWakeLockDeath(this);
2418 }
2419
2420 public boolean hasSameProperties(int flags, String tag, WorkSource workSource,
2421 int ownerUid, int ownerPid) {
2422 return mFlags == flags
2423 && mTag.equals(tag)
2424 && hasSameWorkSource(workSource)
2425 && mOwnerUid == ownerUid
2426 && mOwnerPid == ownerPid;
2427 }
2428
2429 public void updateProperties(int flags, String tag, WorkSource workSource,
2430 int ownerUid, int ownerPid) {
2431 mFlags = flags;
2432 mTag = tag;
2433 updateWorkSource(workSource);
2434 mOwnerUid = ownerUid;
2435 mOwnerPid = ownerPid;
2436 }
2437
2438 public boolean hasSameWorkSource(WorkSource workSource) {
2439 return Objects.equal(mWorkSource, workSource);
2440 }
2441
2442 public void updateWorkSource(WorkSource workSource) {
2443 mWorkSource = copyWorkSource(workSource);
2444 }
2445
2446 @Override
2447 public String toString() {
2448 return getLockLevelString()
2449 + " '" + mTag + "'" + getLockFlagsString()
2450 + " (uid=" + mOwnerUid + ", pid=" + mOwnerPid + ", ws=" + mWorkSource + ")";
2451 }
2452
2453 private String getLockLevelString() {
2454 switch (mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
2455 case PowerManager.FULL_WAKE_LOCK:
2456 return "FULL_WAKE_LOCK ";
2457 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
2458 return "SCREEN_BRIGHT_WAKE_LOCK ";
2459 case PowerManager.SCREEN_DIM_WAKE_LOCK:
2460 return "SCREEN_DIM_WAKE_LOCK ";
2461 case PowerManager.PARTIAL_WAKE_LOCK:
2462 return "PARTIAL_WAKE_LOCK ";
2463 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
2464 return "PROXIMITY_SCREEN_OFF_WAKE_LOCK";
2465 default:
2466 return "??? ";
2467 }
2468 }
2469
2470 private String getLockFlagsString() {
2471 String result = "";
2472 if ((mFlags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {
2473 result += " ACQUIRE_CAUSES_WAKEUP";
2474 }
2475 if ((mFlags & PowerManager.ON_AFTER_RELEASE) != 0) {
2476 result += " ON_AFTER_RELEASE";
2477 }
2478 return result;
2479 }
2480 }
2481
2482 private final class SuspendBlockerImpl implements SuspendBlocker {
2483 private final String mName;
2484 private int mReferenceCount;
2485
2486 public SuspendBlockerImpl(String name) {
2487 mName = name;
2488 }
2489
2490 @Override
2491 protected void finalize() throws Throwable {
Mike Lockwood809ad0f2009-10-26 22:10:33 -04002492 try {
Jeff Brown96307042012-07-27 15:51:34 -07002493 if (mReferenceCount != 0) {
2494 Log.wtf(TAG, "Suspend blocker \"" + mName
2495 + "\" was finalized without being released!");
2496 mReferenceCount = 0;
2497 nativeReleaseSuspendBlocker(mName);
Mike Lockwood809ad0f2009-10-26 22:10:33 -04002498 }
2499 } finally {
Jeff Brown96307042012-07-27 15:51:34 -07002500 super.finalize();
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002501 }
2502 }
2503
Craig Mautner75fc9de2012-06-18 16:53:27 -07002504 @Override
Jeff Brown96307042012-07-27 15:51:34 -07002505 public void acquire() {
2506 synchronized (this) {
2507 mReferenceCount += 1;
2508 if (mReferenceCount == 1) {
2509 nativeAcquireSuspendBlocker(mName);
Craig Mautner37933682012-06-06 14:13:39 -07002510 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002511 }
2512 }
2513
Craig Mautner75fc9de2012-06-18 16:53:27 -07002514 @Override
Jeff Brown96307042012-07-27 15:51:34 -07002515 public void release() {
2516 synchronized (this) {
2517 mReferenceCount -= 1;
2518 if (mReferenceCount == 0) {
2519 nativeReleaseSuspendBlocker(mName);
2520 } else if (mReferenceCount < 0) {
2521 Log.wtf(TAG, "Suspend blocker \"" + mName
2522 + "\" was released without being acquired!", new Throwable());
2523 mReferenceCount = 0;
2524 }
2525 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002526 }
Jeff Brown96307042012-07-27 15:51:34 -07002527
2528 @Override
2529 public String toString() {
2530 synchronized (this) {
2531 return mName + ": ref count=" + mReferenceCount;
2532 }
2533 }
2534 }
Jeff Brownc38c9be2012-10-04 13:16:19 -07002535
2536 private final class ScreenOnBlockerImpl implements ScreenOnBlocker {
2537 private int mNestCount;
2538
2539 public boolean isHeld() {
2540 synchronized (this) {
2541 return mNestCount != 0;
2542 }
2543 }
2544
2545 @Override
2546 public void acquire() {
2547 synchronized (this) {
2548 mNestCount += 1;
2549 if (DEBUG) {
2550 Slog.d(TAG, "Screen on blocked: mNestCount=" + mNestCount);
2551 }
2552 }
2553 }
2554
2555 @Override
2556 public void release() {
2557 synchronized (this) {
2558 mNestCount -= 1;
2559 if (mNestCount < 0) {
2560 Log.wtf(TAG, "Screen on blocker was released without being acquired!",
2561 new Throwable());
2562 mNestCount = 0;
2563 }
2564 if (mNestCount == 0) {
2565 mHandler.sendEmptyMessage(MSG_SCREEN_ON_BLOCKER_RELEASED);
2566 }
2567 if (DEBUG) {
2568 Slog.d(TAG, "Screen on unblocked: mNestCount=" + mNestCount);
2569 }
2570 }
2571 }
2572
2573 @Override
2574 public String toString() {
2575 synchronized (this) {
2576 return "held=" + (mNestCount != 0) + ", mNestCount=" + mNestCount;
2577 }
2578 }
Jeff Brown9e316a12012-10-08 19:17:06 -07002579 }
2580
2581 private final class DisplayBlankerImpl implements DisplayBlanker {
2582 private boolean mBlanked;
2583
2584 @Override
2585 public void blankAllDisplays() {
2586 synchronized (this) {
2587 mBlanked = true;
2588 mDisplayManagerService.blankAllDisplaysFromPowerManager();
2589 nativeSetInteractive(false);
2590 nativeSetAutoSuspend(true);
2591 }
2592 }
2593
2594 @Override
2595 public void unblankAllDisplays() {
2596 synchronized (this) {
2597 nativeSetAutoSuspend(false);
2598 nativeSetInteractive(true);
2599 mDisplayManagerService.unblankAllDisplaysFromPowerManager();
2600 mBlanked = false;
2601 }
2602 }
2603
2604 @Override
2605 public String toString() {
2606 synchronized (this) {
2607 return "blanked=" + mBlanked;
2608 }
2609 }
2610 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002611}