blob: 9a01022873f168da9532777e2ad09fc46c4bfe70 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jeff Brown4f8ecd82012-06-18 18:29:13 -070017package com.android.server.power;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018
19import com.android.internal.app.IBatteryStats;
Jeff Brown4f8ecd82012-06-18 18:29:13 -070020import com.android.server.BatteryService;
21import com.android.server.EventLogTags;
22import com.android.server.LightsService;
Jeff Brownaa202a62012-08-21 22:14:26 -070023import com.android.server.TwilightService;
Jeff Brown4f8ecd82012-06-18 18:29:13 -070024import com.android.server.Watchdog;
Jeff Brown96307042012-07-27 15:51:34 -070025import com.android.server.am.ActivityManagerService;
Jeff Brownfa25bf52012-07-23 19:26:30 -070026import com.android.server.display.DisplayManagerService;
Jeff Brown62c82e42012-09-26 01:30:41 -070027import com.android.server.dreams.DreamManagerService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028
Jeff Brown96307042012-07-27 15:51:34 -070029import android.Manifest;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.content.BroadcastReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import android.content.ContentResolver;
32import android.content.Context;
33import android.content.Intent;
34import android.content.IntentFilter;
35import android.content.pm.PackageManager;
Mike Lockwoodd7786b42009-10-15 17:09:16 -070036import android.content.res.Resources;
Doug Zongker43866e02010-01-07 12:09:54 -080037import android.database.ContentObserver;
Jeff Brown96307042012-07-27 15:51:34 -070038import android.net.Uri;
Amith Yamasani8b619832010-09-22 16:11:59 -070039import android.os.BatteryManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import android.os.Binder;
41import android.os.Handler;
42import android.os.HandlerThread;
43import android.os.IBinder;
44import android.os.IPowerManager;
Jeff Brown96307042012-07-27 15:51:34 -070045import android.os.Looper;
Jim Miller92e66dd2012-02-21 18:57:12 -080046import android.os.Message;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047import android.os.PowerManager;
48import android.os.Process;
49import android.os.RemoteException;
50import android.os.SystemClock;
Jeff Brownd4935962012-09-25 13:27:20 -070051import android.os.UserHandle;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070052import android.os.WorkSource;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053import android.provider.Settings;
54import android.util.EventLog;
55import android.util.Log;
Joe Onorato8a9b2202010-02-26 18:56:32 -080056import android.util.Slog;
Jeff Brown96307042012-07-27 15:51:34 -070057import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058import android.view.WindowManagerPolicy;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059
60import java.io.FileDescriptor;
Jeff Brown7304c342012-05-11 18:42:42 -070061import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062import java.io.PrintWriter;
63import java.util.ArrayList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064
Jeff Brown96307042012-07-27 15:51:34 -070065import libcore.util.Objects;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066
Jeff Brown96307042012-07-27 15:51:34 -070067/**
68 * The power manager service is responsible for coordinating power management
69 * functions on the device.
70 */
71public final class PowerManagerService extends IPowerManager.Stub
72 implements Watchdog.Monitor {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073 private static final String TAG = "PowerManagerService";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074
Jeff Brown88c997a2012-06-22 13:57:45 -070075 private static final boolean DEBUG = false;
Jeff Brown96307042012-07-27 15:51:34 -070076 private static final boolean DEBUG_SPEW = DEBUG && true;
Jeff Brown88c997a2012-06-22 13:57:45 -070077
Jeff Brown96307042012-07-27 15:51:34 -070078 // Message: Sent when a user activity timeout occurs to update the power state.
79 private static final int MSG_USER_ACTIVITY_TIMEOUT = 1;
80 // Message: Sent when the device enters or exits a napping or dreaming state.
81 private static final int MSG_SANDMAN = 2;
Jeff Brown7304c342012-05-11 18:42:42 -070082
Jeff Brown96307042012-07-27 15:51:34 -070083 // Dirty bit: mWakeLocks changed
84 private static final int DIRTY_WAKE_LOCKS = 1 << 0;
85 // Dirty bit: mWakefulness changed
86 private static final int DIRTY_WAKEFULNESS = 1 << 1;
87 // Dirty bit: user activity was poked or may have timed out
88 private static final int DIRTY_USER_ACTIVITY = 1 << 2;
89 // Dirty bit: actual display power state was updated asynchronously
90 private static final int DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED = 1 << 3;
91 // Dirty bit: mBootCompleted changed
92 private static final int DIRTY_BOOT_COMPLETED = 1 << 4;
93 // Dirty bit: settings changed
94 private static final int DIRTY_SETTINGS = 1 << 5;
95 // Dirty bit: mIsPowered changed
96 private static final int DIRTY_IS_POWERED = 1 << 6;
97 // Dirty bit: mStayOn changed
98 private static final int DIRTY_STAY_ON = 1 << 7;
99 // Dirty bit: battery state changed
100 private static final int DIRTY_BATTERY_STATE = 1 << 8;
Jeff Brown7304c342012-05-11 18:42:42 -0700101
Jeff Brown96307042012-07-27 15:51:34 -0700102 // Wakefulness: The device is asleep and can only be awoken by a call to wakeUp().
103 // The screen should be off or in the process of being turned off by the display controller.
104 private static final int WAKEFULNESS_ASLEEP = 0;
105 // Wakefulness: The device is fully awake. It can be put to sleep by a call to goToSleep().
Jeff Brown62c82e42012-09-26 01:30:41 -0700106 // When the user activity timeout expires, the device may start napping or go to sleep.
Jeff Brown96307042012-07-27 15:51:34 -0700107 private static final int WAKEFULNESS_AWAKE = 1;
108 // Wakefulness: The device is napping. It is deciding whether to dream or go to sleep
109 // but hasn't gotten around to it yet. It can be awoken by a call to wakeUp(), which
110 // ends the nap. User activity may brighten the screen but does not end the nap.
111 private static final int WAKEFULNESS_NAPPING = 2;
112 // Wakefulness: The device is dreaming. It can be awoken by a call to wakeUp(),
113 // which ends the dream. The device goes to sleep when goToSleep() is called, when
114 // the dream ends or when unplugged.
115 // User activity may brighten the screen but does not end the dream.
116 private static final int WAKEFULNESS_DREAMING = 3;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117
Jeff Brown96307042012-07-27 15:51:34 -0700118 // Summarizes the state of all active wakelocks.
119 private static final int WAKE_LOCK_CPU = 1 << 0;
120 private static final int WAKE_LOCK_SCREEN_BRIGHT = 1 << 1;
121 private static final int WAKE_LOCK_SCREEN_DIM = 1 << 2;
122 private static final int WAKE_LOCK_BUTTON_BRIGHT = 1 << 3;
123 private static final int WAKE_LOCK_PROXIMITY_SCREEN_OFF = 1 << 4;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124
Jeff Brown96307042012-07-27 15:51:34 -0700125 // Summarizes the user activity state.
126 private static final int USER_ACTIVITY_SCREEN_BRIGHT = 1 << 0;
127 private static final int USER_ACTIVITY_SCREEN_DIM = 1 << 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128
Jeff Brown96307042012-07-27 15:51:34 -0700129 // Default and minimum screen off timeout in milliseconds.
130 private static final int DEFAULT_SCREEN_OFF_TIMEOUT = 15 * 1000;
131 private static final int MINIMUM_SCREEN_OFF_TIMEOUT = 10 * 1000;
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700132
Jeff Brownff532542012-10-02 21:18:04 -0700133 // The screen dim duration, in milliseconds.
Jeff Brown96307042012-07-27 15:51:34 -0700134 // This is subtracted from the end of the screen off timeout so the
135 // minimum screen off timeout should be longer than this.
136 private static final int SCREEN_DIM_DURATION = 7 * 1000;
Mathias Agopian47f1fe52011-11-08 17:18:41 -0800137
Jeff Brownff532542012-10-02 21:18:04 -0700138 // The maximum screen dim time expressed as a ratio relative to the screen
139 // off timeout. If the screen off timeout is very short then we want the
140 // dim timeout to also be quite short so that most of the time is spent on.
141 // Otherwise the user won't get much screen on time before dimming occurs.
142 private static final float MAXIMUM_SCREEN_DIM_RATIO = 0.2f;
143
Jeff Brownf3fb8952012-10-02 20:57:05 -0700144 // Upper bound on the battery charge percentage in order to consider turning
145 // the screen on when the device starts charging wirelessly.
146 // See point of use for more details.
147 private static final int WIRELESS_CHARGER_TURN_ON_BATTERY_LEVEL_LIMIT = 95;
148
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 private Context mContext;
Jeff Brown96307042012-07-27 15:51:34 -0700150 private LightsService mLightsService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151 private BatteryService mBatteryService;
Jeff Brown96307042012-07-27 15:51:34 -0700152 private IBatteryStats mBatteryStats;
153 private HandlerThread mHandlerThread;
154 private PowerManagerHandler mHandler;
155 private WindowManagerPolicy mPolicy;
156 private Notifier mNotifier;
157 private DisplayPowerController mDisplayPowerController;
158 private SettingsObserver mSettingsObserver;
Jeff Brown62c82e42012-09-26 01:30:41 -0700159 private DreamManagerService mDreamManager;
Jeff Brown96307042012-07-27 15:51:34 -0700160 private LightsService.Light mAttentionLight;
Joe Onorato609695d2010-10-14 14:57:49 -0700161
Jeff Brown96307042012-07-27 15:51:34 -0700162 private final Object mLock = new Object();
163
164 // A bitfield that indicates what parts of the power state have
165 // changed and need to be recalculated.
166 private int mDirty;
167
168 // Indicates whether the device is awake or asleep or somewhere in between.
169 // This is distinct from the screen power state, which is managed separately.
170 private int mWakefulness;
171
172 // True if MSG_SANDMAN has been scheduled.
173 private boolean mSandmanScheduled;
174
175 // Table of all suspend blockers.
176 // There should only be a few of these.
177 private final ArrayList<SuspendBlocker> mSuspendBlockers = new ArrayList<SuspendBlocker>();
178
179 // Table of all wake locks acquired by applications.
180 private final ArrayList<WakeLock> mWakeLocks = new ArrayList<WakeLock>();
181
182 // A bitfield that summarizes the state of all active wakelocks.
183 private int mWakeLockSummary;
184
185 // If true, instructs the display controller to wait for the proximity sensor to
186 // go negative before turning the screen on.
187 private boolean mRequestWaitForNegativeProximity;
188
189 // Timestamp of the last time the device was awoken or put to sleep.
190 private long mLastWakeTime;
191 private long mLastSleepTime;
192
193 // True if we need to send a wake up or go to sleep finished notification
194 // when the display is ready.
195 private boolean mSendWakeUpFinishedNotificationWhenReady;
196 private boolean mSendGoToSleepFinishedNotificationWhenReady;
197
198 // Timestamp of the last call to user activity.
199 private long mLastUserActivityTime;
200 private long mLastUserActivityTimeNoChangeLights;
201
202 // A bitfield that summarizes the effect of the user activity timer.
203 // A zero value indicates that the user activity timer has expired.
204 private int mUserActivitySummary;
205
206 // The desired display power state. The actual state may lag behind the
207 // requested because it is updated asynchronously by the display power controller.
208 private final DisplayPowerRequest mDisplayPowerRequest = new DisplayPowerRequest();
209
210 // The time the screen was last turned off, in elapsedRealtime() timebase.
211 private long mLastScreenOffEventElapsedRealTime;
212
213 // True if the display power state has been fully applied, which means the display
214 // is actually on or actually off or whatever was requested.
215 private boolean mDisplayReady;
216
217 // True if holding a wake-lock to block suspend of the CPU.
218 private boolean mHoldingWakeLockSuspendBlocker;
219
220 // The suspend blocker used to keep the CPU alive when wake locks have been acquired.
221 private final SuspendBlocker mWakeLockSuspendBlocker;
222
223 // True if systemReady() has been called.
224 private boolean mSystemReady;
225
226 // True if boot completed occurred. We keep the screen on until this happens.
227 private boolean mBootCompleted;
228
229 // True if the device is plugged into a power source.
230 private boolean mIsPowered;
231
Jeff Brownf3fb8952012-10-02 20:57:05 -0700232 // The current plug type, such as BatteryManager.BATTERY_PLUGGED_WIRELESS.
233 private int mPlugType;
234
Jeff Brown96307042012-07-27 15:51:34 -0700235 // True if the device should wake up when plugged or unplugged.
236 private boolean mWakeUpWhenPluggedOrUnpluggedConfig;
237
238 // True if dreams are supported on this device.
239 private boolean mDreamsSupportedConfig;
240
241 // True if dreams are enabled by the user.
242 private boolean mDreamsEnabledSetting;
243
John Spurlock1a868b72012-08-22 09:56:51 -0400244 // True if dreams should be activated on sleep.
245 private boolean mDreamsActivateOnSleepSetting;
246
Jeff Brown96307042012-07-27 15:51:34 -0700247 // The screen off timeout setting value in milliseconds.
248 private int mScreenOffTimeoutSetting;
249
250 // The maximum allowable screen off timeout according to the device
251 // administration policy. Overrides other settings.
252 private int mMaximumScreenOffTimeoutFromDeviceAdmin = Integer.MAX_VALUE;
253
254 // The stay on while plugged in setting.
255 // A bitfield of battery conditions under which to make the screen stay on.
256 private int mStayOnWhilePluggedInSetting;
257
258 // True if the device should stay on.
259 private boolean mStayOn;
260
261 // Screen brightness setting limits.
262 private int mScreenBrightnessSettingMinimum;
263 private int mScreenBrightnessSettingMaximum;
264 private int mScreenBrightnessSettingDefault;
265
266 // The screen brightness setting, from 0 to 255.
267 // Use -1 if no value has been set.
268 private int mScreenBrightnessSetting;
269
Jeff Brown330560f2012-08-21 22:10:57 -0700270 // The screen auto-brightness adjustment setting, from -1 to 1.
271 // Use 0 if there is no adjustment.
272 private float mScreenAutoBrightnessAdjustmentSetting;
273
Jeff Brown96307042012-07-27 15:51:34 -0700274 // The screen brightness mode.
275 // One of the Settings.System.SCREEN_BRIGHTNESS_MODE_* constants.
276 private int mScreenBrightnessModeSetting;
277
278 // The screen brightness setting override from the window manager
279 // to allow the current foreground activity to override the brightness.
280 // Use -1 to disable.
281 private int mScreenBrightnessOverrideFromWindowManager = -1;
282
Jeff Brown1e3b98d2012-09-30 18:58:59 -0700283 // The user activity timeout override from the window manager
284 // to allow the current foreground activity to override the user activity timeout.
285 // Use -1 to disable.
286 private long mUserActivityTimeoutOverrideFromWindowManager = -1;
287
Jeff Brown96307042012-07-27 15:51:34 -0700288 // The screen brightness setting override from the settings application
289 // to temporarily adjust the brightness until next updated,
290 // Use -1 to disable.
291 private int mTemporaryScreenBrightnessSettingOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800292
Jeff Brown330560f2012-08-21 22:10:57 -0700293 // The screen brightness adjustment setting override from the settings
294 // application to temporarily adjust the auto-brightness adjustment factor
295 // until next updated, in the range -1..1.
296 // Use NaN to disable.
297 private float mTemporaryScreenAutoBrightnessAdjustmentSettingOverride = Float.NaN;
298
Jeff Brown9ba8d782012-10-01 16:38:23 -0700299 // Time when we last logged a warning about calling userActivity() without permission.
300 private long mLastWarningAboutUserActivityPermission = Long.MIN_VALUE;
301
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700302 private native void nativeInit();
Jeff Brown7304c342012-05-11 18:42:42 -0700303 private static native void nativeShutdown();
304 private static native void nativeReboot(String reason) throws IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305
Jeff Brown96307042012-07-27 15:51:34 -0700306 private static native void nativeSetPowerState(boolean screenOn, boolean screenBright);
307 private static native void nativeAcquireSuspendBlocker(String name);
308 private static native void nativeReleaseSuspendBlocker(String name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800309
Jeff Brown96307042012-07-27 15:51:34 -0700310 static native void nativeSetScreenState(boolean on);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800311
Jeff Brown4f8ecd82012-06-18 18:29:13 -0700312 public PowerManagerService() {
Jeff Brown96307042012-07-27 15:51:34 -0700313 synchronized (mLock) {
314 mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService");
315 mWakeLockSuspendBlocker.acquire();
316 mHoldingWakeLockSuspendBlocker = true;
317 mWakefulness = WAKEFULNESS_AWAKE;
318 }
Jeff Brown7304c342012-05-11 18:42:42 -0700319
320 nativeInit();
Jeff Brownf75724b2012-08-25 13:34:32 -0700321 nativeSetPowerState(true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800322 }
323
Jeff Brown96307042012-07-27 15:51:34 -0700324 /**
325 * Initialize the power manager.
326 * Must be called before any other functions within the power manager are called.
327 */
328 public void init(Context context, LightsService ls,
329 ActivityManagerService am, BatteryService bs, IBatteryStats bss,
330 DisplayManagerService dm) {
Jeff Brownf75724b2012-08-25 13:34:32 -0700331 // Forcibly turn the screen on at boot so that it is in a known power state.
332 // We do this in init() rather than in the constructor because setting the
333 // screen state requires a call into surface flinger which then needs to call back
334 // into the activity manager to check permissions. Unfortunately the
335 // activity manager is not running when the constructor is called, so we
336 // have to defer setting the screen state until this point.
337 nativeSetScreenState(true);
338
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800339 mContext = context;
Jeff Brown96307042012-07-27 15:51:34 -0700340 mLightsService = ls;
341 mBatteryService = bs;
342 mBatteryStats = bss;
343 mHandlerThread = new HandlerThread(TAG);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800344 mHandlerThread.start();
Jeff Brown96307042012-07-27 15:51:34 -0700345 mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800346
Jeff Brown96307042012-07-27 15:51:34 -0700347 Watchdog.getInstance().addMonitor(this);
348 }
Jim Miller92e66dd2012-02-21 18:57:12 -0800349
Jeff Brown96307042012-07-27 15:51:34 -0700350 public void setPolicy(WindowManagerPolicy policy) {
351 synchronized (mLock) {
352 mPolicy = policy;
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700353 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800354 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800355
Jeff Brown62c82e42012-09-26 01:30:41 -0700356 public void systemReady(TwilightService twilight, DreamManagerService dreamManager) {
Jeff Brown96307042012-07-27 15:51:34 -0700357 synchronized (mLock) {
358 mSystemReady = true;
Jeff Brown62c82e42012-09-26 01:30:41 -0700359 mDreamManager = dreamManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800360
Jeff Brown96307042012-07-27 15:51:34 -0700361 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
362 mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting();
363 mScreenBrightnessSettingMaximum = pm.getMaximumScreenBrightnessSetting();
364 mScreenBrightnessSettingDefault = pm.getDefaultScreenBrightnessSetting();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800365
Jeff Brown96307042012-07-27 15:51:34 -0700366 mNotifier = new Notifier(mHandler.getLooper(), mContext, mBatteryStats,
367 createSuspendBlockerLocked("PowerManagerService.Broadcasts"),
368 mPolicy, mScreenOnListener);
369 mDisplayPowerController = new DisplayPowerController(mHandler.getLooper(),
Jeff Brownaa202a62012-08-21 22:14:26 -0700370 mContext, mNotifier, mLightsService, twilight,
Jeff Brown96307042012-07-27 15:51:34 -0700371 createSuspendBlockerLocked("PowerManagerService.Display"),
372 mDisplayPowerControllerCallbacks, mHandler);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800373
Jeff Brown96307042012-07-27 15:51:34 -0700374 mSettingsObserver = new SettingsObserver(mHandler);
375 mAttentionLight = mLightsService.getLight(LightsService.LIGHT_ID_ATTENTION);
Mike Lockwoodaa66ea82009-10-31 16:31:27 -0400376
Jeff Brown96307042012-07-27 15:51:34 -0700377 // Register for broadcasts from other components of the system.
378 IntentFilter filter = new IntentFilter();
379 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
Jeff Brownd4935962012-09-25 13:27:20 -0700380 mContext.registerReceiver(new BatteryReceiver(), filter, null, mHandler);
Joe Onoratob08a1af2010-10-11 19:28:58 -0700381
Jeff Brown96307042012-07-27 15:51:34 -0700382 filter = new IntentFilter();
383 filter.addAction(Intent.ACTION_BOOT_COMPLETED);
Jeff Brownd4935962012-09-25 13:27:20 -0700384 mContext.registerReceiver(new BootCompletedReceiver(), filter, null, mHandler);
Jeff Brown96307042012-07-27 15:51:34 -0700385
386 filter = new IntentFilter();
Dianne Hackbornbe87e2f2012-09-28 16:31:34 -0700387 filter.addAction(Intent.ACTION_DREAMING_STARTED);
388 filter.addAction(Intent.ACTION_DREAMING_STOPPED);
Jeff Brownd4935962012-09-25 13:27:20 -0700389 mContext.registerReceiver(new DreamReceiver(), filter, null, mHandler);
390
391 filter = new IntentFilter();
392 filter.addAction(Intent.ACTION_USER_SWITCHED);
393 mContext.registerReceiver(new UserSwitchedReceiver(), filter, null, mHandler);
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400394
Jeff Brown96307042012-07-27 15:51:34 -0700395 // Register for settings changes.
396 final ContentResolver resolver = mContext.getContentResolver();
397 resolver.registerContentObserver(Settings.Secure.getUriFor(
Jeff Brownd4935962012-09-25 13:27:20 -0700398 Settings.Secure.SCREENSAVER_ENABLED),
399 false, mSettingsObserver, UserHandle.USER_ALL);
John Spurlock1a868b72012-08-22 09:56:51 -0400400 resolver.registerContentObserver(Settings.Secure.getUriFor(
Jeff Brownd4935962012-09-25 13:27:20 -0700401 Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP),
402 false, mSettingsObserver, UserHandle.USER_ALL);
Jeff Brown96307042012-07-27 15:51:34 -0700403 resolver.registerContentObserver(Settings.System.getUriFor(
Jeff Brownd4935962012-09-25 13:27:20 -0700404 Settings.System.SCREEN_OFF_TIMEOUT),
405 false, mSettingsObserver, UserHandle.USER_ALL);
Christopher Tatead735322012-09-07 14:19:43 -0700406 resolver.registerContentObserver(Settings.Global.getUriFor(
Jeff Brownd4935962012-09-25 13:27:20 -0700407 Settings.Global.STAY_ON_WHILE_PLUGGED_IN),
408 false, mSettingsObserver, UserHandle.USER_ALL);
Jeff Brown96307042012-07-27 15:51:34 -0700409 resolver.registerContentObserver(Settings.System.getUriFor(
Jeff Brownd4935962012-09-25 13:27:20 -0700410 Settings.System.SCREEN_BRIGHTNESS),
411 false, mSettingsObserver, UserHandle.USER_ALL);
Jeff Brown96307042012-07-27 15:51:34 -0700412 resolver.registerContentObserver(Settings.System.getUriFor(
Jeff Brownd4935962012-09-25 13:27:20 -0700413 Settings.System.SCREEN_BRIGHTNESS_MODE),
414 false, mSettingsObserver, UserHandle.USER_ALL);
Jeff Brown96307042012-07-27 15:51:34 -0700415
416 // Go.
417 readConfigurationLocked();
418 updateSettingsLocked();
419 mDirty |= DIRTY_BATTERY_STATE;
420 updatePowerStateLocked();
421 }
422 }
423
424 private void readConfigurationLocked() {
425 final Resources resources = mContext.getResources();
426
427 mWakeUpWhenPluggedOrUnpluggedConfig = resources.getBoolean(
Joe Onorato6d747652010-10-11 15:15:31 -0700428 com.android.internal.R.bool.config_unplugTurnsOnScreen);
Jeff Brown96307042012-07-27 15:51:34 -0700429 mDreamsSupportedConfig = resources.getBoolean(
430 com.android.internal.R.bool.config_enableDreams);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800431 }
432
Jeff Brown96307042012-07-27 15:51:34 -0700433 private void updateSettingsLocked() {
434 final ContentResolver resolver = mContext.getContentResolver();
Jeff Brown7304c342012-05-11 18:42:42 -0700435
Jeff Brownd4935962012-09-25 13:27:20 -0700436 mDreamsEnabledSetting = (Settings.Secure.getIntForUser(resolver,
437 Settings.Secure.SCREENSAVER_ENABLED, 0,
438 UserHandle.USER_CURRENT) != 0);
439 mDreamsActivateOnSleepSetting = (Settings.Secure.getIntForUser(resolver,
440 Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, 0,
441 UserHandle.USER_CURRENT) != 0);
442 mScreenOffTimeoutSetting = Settings.System.getIntForUser(resolver,
443 Settings.System.SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT,
444 UserHandle.USER_CURRENT);
Christopher Tatead735322012-09-07 14:19:43 -0700445 mStayOnWhilePluggedInSetting = Settings.Global.getInt(resolver,
Jeff Brownd4935962012-09-25 13:27:20 -0700446 Settings.Global.STAY_ON_WHILE_PLUGGED_IN, BatteryManager.BATTERY_PLUGGED_AC);
Jeff Brown7304c342012-05-11 18:42:42 -0700447
Jeff Brown96307042012-07-27 15:51:34 -0700448 final int oldScreenBrightnessSetting = mScreenBrightnessSetting;
Jeff Brownd4935962012-09-25 13:27:20 -0700449 mScreenBrightnessSetting = Settings.System.getIntForUser(resolver,
450 Settings.System.SCREEN_BRIGHTNESS, mScreenBrightnessSettingDefault,
451 UserHandle.USER_CURRENT);
Jeff Brown96307042012-07-27 15:51:34 -0700452 if (oldScreenBrightnessSetting != mScreenBrightnessSetting) {
453 mTemporaryScreenBrightnessSettingOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800454 }
Jeff Brown96307042012-07-27 15:51:34 -0700455
Jeff Brown330560f2012-08-21 22:10:57 -0700456 final float oldScreenAutoBrightnessAdjustmentSetting =
457 mScreenAutoBrightnessAdjustmentSetting;
Jeff Brownd4935962012-09-25 13:27:20 -0700458 mScreenAutoBrightnessAdjustmentSetting = Settings.System.getFloatForUser(resolver,
459 Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f,
460 UserHandle.USER_CURRENT);
Jeff Brown330560f2012-08-21 22:10:57 -0700461 if (oldScreenAutoBrightnessAdjustmentSetting != mScreenAutoBrightnessAdjustmentSetting) {
Jeff Brown5d03a532012-08-22 13:22:02 -0700462 mTemporaryScreenAutoBrightnessAdjustmentSettingOverride = Float.NaN;
Jeff Brown330560f2012-08-21 22:10:57 -0700463 }
464
Jeff Brownd4935962012-09-25 13:27:20 -0700465 mScreenBrightnessModeSetting = Settings.System.getIntForUser(resolver,
Jeff Brown96307042012-07-27 15:51:34 -0700466 Settings.System.SCREEN_BRIGHTNESS_MODE,
Jeff Brownd4935962012-09-25 13:27:20 -0700467 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, UserHandle.USER_CURRENT);
Jeff Brown96307042012-07-27 15:51:34 -0700468
469 mDirty |= DIRTY_SETTINGS;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800470 }
471
Jeff Brown96307042012-07-27 15:51:34 -0700472 private void handleSettingsChangedLocked() {
473 updateSettingsLocked();
474 updatePowerStateLocked();
475 }
476
477 @Override // Binder call
478 public void acquireWakeLock(IBinder lock, int flags, String tag, WorkSource ws) {
479 if (lock == null) {
480 throw new IllegalArgumentException("lock must not be null");
481 }
482 PowerManager.validateWakeLockParameters(flags, tag);
483
484 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
485 if (ws != null && ws.size() != 0) {
486 mContext.enforceCallingOrSelfPermission(
487 android.Manifest.permission.UPDATE_DEVICE_STATS, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800488 } else {
Jeff Brown96307042012-07-27 15:51:34 -0700489 ws = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800490 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800491
Jeff Brown96307042012-07-27 15:51:34 -0700492 final int uid = Binder.getCallingUid();
493 final int pid = Binder.getCallingPid();
494 final long ident = Binder.clearCallingIdentity();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800495 try {
Jeff Brown96307042012-07-27 15:51:34 -0700496 acquireWakeLockInternal(lock, flags, tag, ws, uid, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800497 } finally {
498 Binder.restoreCallingIdentity(ident);
499 }
500 }
501
Jeff Brown96307042012-07-27 15:51:34 -0700502 private void acquireWakeLockInternal(IBinder lock, int flags, String tag, WorkSource ws,
503 int uid, int pid) {
504 synchronized (mLock) {
505 if (DEBUG_SPEW) {
506 Slog.d(TAG, "acquireWakeLockInternal: lock=" + Objects.hashCode(lock)
507 + ", flags=0x" + Integer.toHexString(flags)
508 + ", tag=\"" + tag + "\", ws=" + ws + ", uid=" + uid + ", pid=" + pid);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700509 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800510
Jeff Brown96307042012-07-27 15:51:34 -0700511 WakeLock wakeLock;
512 int index = findWakeLockIndexLocked(lock);
513 if (index >= 0) {
514 wakeLock = mWakeLocks.get(index);
515 if (!wakeLock.hasSameProperties(flags, tag, ws, uid, pid)) {
516 // Update existing wake lock. This shouldn't happen but is harmless.
517 notifyWakeLockReleasedLocked(wakeLock);
518 wakeLock.updateProperties(flags, tag, ws, uid, pid);
519 notifyWakeLockAcquiredLocked(wakeLock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800520 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800521 } else {
Jeff Brown96307042012-07-27 15:51:34 -0700522 wakeLock = new WakeLock(lock, flags, tag, ws, uid, pid);
523 try {
524 lock.linkToDeath(wakeLock, 0);
525 } catch (RemoteException ex) {
526 throw new IllegalArgumentException("Wake lock is already dead.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800527 }
Jeff Brown96307042012-07-27 15:51:34 -0700528 notifyWakeLockAcquiredLocked(wakeLock);
529 mWakeLocks.add(wakeLock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800530 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800531
Jeff Brown96307042012-07-27 15:51:34 -0700532 applyWakeLockFlagsOnAcquireLocked(wakeLock);
533 mDirty |= DIRTY_WAKE_LOCKS;
534 updatePowerStateLocked();
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700535 }
536 }
537
Jeff Brown96307042012-07-27 15:51:34 -0700538 private void applyWakeLockFlagsOnAcquireLocked(WakeLock wakeLock) {
539 if ((wakeLock.mFlags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {
540 wakeUpNoUpdateLocked(SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800541 }
542 }
543
Jeff Brown96307042012-07-27 15:51:34 -0700544 @Override // Binder call
Mike Lockwood0e39ea82009-11-18 15:37:10 -0500545 public void releaseWakeLock(IBinder lock, int flags) {
Jeff Brown96307042012-07-27 15:51:34 -0700546 if (lock == null) {
547 throw new IllegalArgumentException("lock must not be null");
Michael Chane96440f2009-05-06 10:27:36 -0700548 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800549
Jeff Brown96307042012-07-27 15:51:34 -0700550 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
551
552 final long ident = Binder.clearCallingIdentity();
553 try {
554 releaseWakeLockInternal(lock, flags);
555 } finally {
556 Binder.restoreCallingIdentity(ident);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800557 }
558 }
559
Jeff Brown96307042012-07-27 15:51:34 -0700560 private void releaseWakeLockInternal(IBinder lock, int flags) {
561 synchronized (mLock) {
562 if (DEBUG_SPEW) {
563 Slog.d(TAG, "releaseWakeLockInternal: lock=" + Objects.hashCode(lock)
564 + ", flags=0x" + Integer.toHexString(flags));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800565 }
566
Jeff Brown96307042012-07-27 15:51:34 -0700567 int index = findWakeLockIndexLocked(lock);
568 if (index < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800569 return;
570 }
Mike Lockwood3333fa42009-10-26 14:50:42 -0400571
Jeff Brown96307042012-07-27 15:51:34 -0700572 WakeLock wakeLock = mWakeLocks.get(index);
573 mWakeLocks.remove(index);
574 notifyWakeLockReleasedLocked(wakeLock);
575 wakeLock.mLock.unlinkToDeath(wakeLock, 0);
576
577 if ((flags & PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE) != 0) {
578 mRequestWaitForNegativeProximity = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800579 }
580
Jeff Brown96307042012-07-27 15:51:34 -0700581 applyWakeLockFlagsOnReleaseLocked(wakeLock);
582 mDirty |= DIRTY_WAKE_LOCKS;
583 updatePowerStateLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800584 }
585 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700586
Jeff Brown96307042012-07-27 15:51:34 -0700587 private void handleWakeLockDeath(WakeLock wakeLock) {
588 synchronized (mLock) {
589 if (DEBUG_SPEW) {
590 Slog.d(TAG, "handleWakeLockDeath: lock=" + Objects.hashCode(wakeLock.mLock));
591 }
592
593 int index = mWakeLocks.indexOf(wakeLock);
594 if (index < 0) {
595 return;
596 }
597
598 mWakeLocks.remove(index);
599 notifyWakeLockReleasedLocked(wakeLock);
600
601 applyWakeLockFlagsOnReleaseLocked(wakeLock);
602 mDirty |= DIRTY_WAKE_LOCKS;
603 updatePowerStateLocked();
Mike Lockwood3a74bd32011-08-12 13:55:22 -0700604 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700605 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800606
Jeff Brown96307042012-07-27 15:51:34 -0700607 private void applyWakeLockFlagsOnReleaseLocked(WakeLock wakeLock) {
608 if ((wakeLock.mFlags & PowerManager.ON_AFTER_RELEASE) != 0) {
609 userActivityNoUpdateLocked(SystemClock.uptimeMillis(),
610 PowerManager.USER_ACTIVITY_EVENT_OTHER,
611 PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS,
612 wakeLock.mOwnerUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800613 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800614 }
615
Jeff Brown96307042012-07-27 15:51:34 -0700616 @Override // Binder call
617 public void updateWakeLockWorkSource(IBinder lock, WorkSource ws) {
618 if (lock == null) {
619 throw new IllegalArgumentException("lock must not be null");
620 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800621
Jeff Brown96307042012-07-27 15:51:34 -0700622 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
623 if (ws != null && ws.size() != 0) {
624 mContext.enforceCallingOrSelfPermission(
625 android.Manifest.permission.UPDATE_DEVICE_STATS, null);
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700626 } else {
Jeff Brown96307042012-07-27 15:51:34 -0700627 ws = null;
628 }
629
630 final long ident = Binder.clearCallingIdentity();
631 try {
632 updateWakeLockWorkSourceInternal(lock, ws);
633 } finally {
634 Binder.restoreCallingIdentity(ident);
635 }
636 }
637
638 private void updateWakeLockWorkSourceInternal(IBinder lock, WorkSource ws) {
639 synchronized (mLock) {
640 int index = findWakeLockIndexLocked(lock);
641 if (index < 0) {
642 throw new IllegalArgumentException("Wake lock not active");
643 }
644
645 WakeLock wakeLock = mWakeLocks.get(index);
646 if (!wakeLock.hasSameWorkSource(ws)) {
647 notifyWakeLockReleasedLocked(wakeLock);
648 wakeLock.updateWorkSource(ws);
649 notifyWakeLockAcquiredLocked(wakeLock);
650 }
651 }
652 }
653
654 private int findWakeLockIndexLocked(IBinder lock) {
655 final int count = mWakeLocks.size();
656 for (int i = 0; i < count; i++) {
657 if (mWakeLocks.get(i).mLock == lock) {
658 return i;
659 }
660 }
661 return -1;
662 }
663
664 private void notifyWakeLockAcquiredLocked(WakeLock wakeLock) {
665 if (mSystemReady) {
666 mNotifier.onWakeLockAcquired(wakeLock.mFlags, wakeLock.mTag,
667 wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource);
668 }
669 }
670
671 private void notifyWakeLockReleasedLocked(WakeLock wakeLock) {
672 if (mSystemReady) {
673 mNotifier.onWakeLockReleased(wakeLock.mFlags, wakeLock.mTag,
674 wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource);
675 }
676 }
677
678 @Override // Binder call
679 public boolean isWakeLockLevelSupported(int level) {
680 final long ident = Binder.clearCallingIdentity();
681 try {
682 return isWakeLockLevelSupportedInternal(level);
683 } finally {
684 Binder.restoreCallingIdentity(ident);
685 }
686 }
687
688 private boolean isWakeLockLevelSupportedInternal(int level) {
689 synchronized (mLock) {
690 switch (level) {
691 case PowerManager.PARTIAL_WAKE_LOCK:
692 case PowerManager.SCREEN_DIM_WAKE_LOCK:
693 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
694 case PowerManager.FULL_WAKE_LOCK:
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700695 return true;
Jeff Brown96307042012-07-27 15:51:34 -0700696
697 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
698 return mSystemReady && mDisplayPowerController.isProximitySensorAvailable();
699
700 default:
701 return false;
702 }
703 }
704 }
705
706 @Override // Binder call
707 public void userActivity(long eventTime, int event, int flags) {
Jeff Brown9ba8d782012-10-01 16:38:23 -0700708 final long now = SystemClock.uptimeMillis();
709 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER)
710 != PackageManager.PERMISSION_GRANTED) {
711 // Once upon a time applications could call userActivity().
712 // Now we require the DEVICE_POWER permission. Log a warning and ignore the
713 // request instead of throwing a SecurityException so we don't break old apps.
714 synchronized (mLock) {
715 if (now >= mLastWarningAboutUserActivityPermission + (5 * 60 * 1000)) {
716 mLastWarningAboutUserActivityPermission = now;
717 Slog.w(TAG, "Ignoring call to PowerManager.userActivity() because the "
718 + "caller does not have DEVICE_POWER permission. "
719 + "Please fix your app! "
720 + " pid=" + Binder.getCallingPid()
721 + " uid=" + Binder.getCallingUid());
722 }
723 }
724 return;
725 }
726
Jeff Brown96307042012-07-27 15:51:34 -0700727 if (eventTime > SystemClock.uptimeMillis()) {
728 throw new IllegalArgumentException("event time must not be in the future");
729 }
730
Jeff Brown96307042012-07-27 15:51:34 -0700731 final int uid = Binder.getCallingUid();
732 final long ident = Binder.clearCallingIdentity();
733 try {
734 userActivityInternal(eventTime, event, flags, uid);
735 } finally {
736 Binder.restoreCallingIdentity(ident);
737 }
738 }
739
740 // Called from native code.
741 private void userActivityFromNative(long eventTime, int event, int flags) {
742 userActivityInternal(eventTime, event, flags, Process.SYSTEM_UID);
743 }
744
745 private void userActivityInternal(long eventTime, int event, int flags, int uid) {
746 synchronized (mLock) {
747 if (userActivityNoUpdateLocked(eventTime, event, flags, uid)) {
748 updatePowerStateLocked();
749 }
750 }
751 }
752
753 private boolean userActivityNoUpdateLocked(long eventTime, int event, int flags, int uid) {
754 if (DEBUG_SPEW) {
755 Slog.d(TAG, "userActivityNoUpdateLocked: eventTime=" + eventTime
756 + ", event=" + event + ", flags=0x" + Integer.toHexString(flags)
757 + ", uid=" + uid);
758 }
759
760 if (eventTime < mLastSleepTime || eventTime < mLastWakeTime
761 || mWakefulness == WAKEFULNESS_ASLEEP || !mBootCompleted || !mSystemReady) {
762 return false;
763 }
764
765 mNotifier.onUserActivity(event, uid);
766
767 if ((flags & PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS) != 0) {
768 if (eventTime > mLastUserActivityTimeNoChangeLights
769 && eventTime > mLastUserActivityTime) {
770 mLastUserActivityTimeNoChangeLights = eventTime;
771 mDirty |= DIRTY_USER_ACTIVITY;
772 return true;
773 }
774 } else {
775 if (eventTime > mLastUserActivityTime) {
776 mLastUserActivityTime = eventTime;
777 mDirty |= DIRTY_USER_ACTIVITY;
778 return true;
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700779 }
780 }
781 return false;
782 }
783
Jeff Brown96307042012-07-27 15:51:34 -0700784 @Override // Binder call
785 public void wakeUp(long eventTime) {
786 if (eventTime > SystemClock.uptimeMillis()) {
787 throw new IllegalArgumentException("event time must not be in the future");
788 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700789
Jeff Brown96307042012-07-27 15:51:34 -0700790 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
791
792 final long ident = Binder.clearCallingIdentity();
793 try {
794 wakeUpInternal(eventTime);
795 } finally {
796 Binder.restoreCallingIdentity(ident);
797 }
798 }
799
800 // Called from native code.
801 private void wakeUpFromNative(long eventTime) {
802 wakeUpInternal(eventTime);
803 }
804
805 private void wakeUpInternal(long eventTime) {
806 synchronized (mLock) {
807 if (wakeUpNoUpdateLocked(eventTime)) {
808 updatePowerStateLocked();
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700809 }
810 }
Jeff Brown96307042012-07-27 15:51:34 -0700811 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700812
Jeff Brown96307042012-07-27 15:51:34 -0700813 private boolean wakeUpNoUpdateLocked(long eventTime) {
814 if (DEBUG_SPEW) {
815 Slog.d(TAG, "wakeUpNoUpdateLocked: eventTime=" + eventTime);
Joe Onorato60607a92010-10-23 14:49:30 -0700816 }
Jeff Brown96307042012-07-27 15:51:34 -0700817
818 if (eventTime < mLastSleepTime || mWakefulness == WAKEFULNESS_AWAKE
819 || !mBootCompleted || !mSystemReady) {
820 return false;
821 }
822
823 switch (mWakefulness) {
824 case WAKEFULNESS_ASLEEP:
825 Slog.i(TAG, "Waking up from sleep...");
826 mNotifier.onWakeUpStarted();
827 mSendWakeUpFinishedNotificationWhenReady = true;
828 mSendGoToSleepFinishedNotificationWhenReady = false;
829 break;
830 case WAKEFULNESS_DREAMING:
831 Slog.i(TAG, "Waking up from dream...");
832 break;
833 case WAKEFULNESS_NAPPING:
834 Slog.i(TAG, "Waking up from nap...");
835 break;
836 }
837
838 mLastWakeTime = eventTime;
839 mWakefulness = WAKEFULNESS_AWAKE;
840 mDirty |= DIRTY_WAKEFULNESS;
841
842 userActivityNoUpdateLocked(
843 eventTime, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
844 return true;
845 }
846
847 @Override // Binder call
848 public void goToSleep(long eventTime, int reason) {
849 if (eventTime > SystemClock.uptimeMillis()) {
850 throw new IllegalArgumentException("event time must not be in the future");
851 }
852
853 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
854
855 final long ident = Binder.clearCallingIdentity();
856 try {
857 goToSleepInternal(eventTime, reason);
858 } finally {
859 Binder.restoreCallingIdentity(ident);
860 }
861 }
862
863 // Called from native code.
864 private void goToSleepFromNative(long eventTime, int reason) {
865 goToSleepInternal(eventTime, reason);
866 }
867
868 private void goToSleepInternal(long eventTime, int reason) {
869 synchronized (mLock) {
870 if (goToSleepNoUpdateLocked(eventTime, reason)) {
871 updatePowerStateLocked();
872 }
873 }
874 }
875
876 private boolean goToSleepNoUpdateLocked(long eventTime, int reason) {
877 if (DEBUG_SPEW) {
878 Slog.d(TAG, "goToSleepNoUpdateLocked: eventTime=" + eventTime + ", reason=" + reason);
879 }
880
881 if (eventTime < mLastWakeTime || mWakefulness == WAKEFULNESS_ASLEEP
882 || !mBootCompleted || !mSystemReady) {
883 return false;
884 }
885
886 switch (reason) {
887 case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN:
888 Slog.i(TAG, "Going to sleep due to device administration policy...");
889 break;
890 case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT:
891 Slog.i(TAG, "Going to sleep due to screen timeout...");
892 break;
893 default:
894 Slog.i(TAG, "Going to sleep by user request...");
895 reason = PowerManager.GO_TO_SLEEP_REASON_USER;
896 break;
897 }
898
899 mLastSleepTime = eventTime;
900 mDirty |= DIRTY_WAKEFULNESS;
901 mWakefulness = WAKEFULNESS_ASLEEP;
902 mNotifier.onGoToSleepStarted(reason);
903 mSendGoToSleepFinishedNotificationWhenReady = true;
904 mSendWakeUpFinishedNotificationWhenReady = false;
905
906 // Report the number of wake locks that will be cleared by going to sleep.
907 int numWakeLocksCleared = 0;
908 final int numWakeLocks = mWakeLocks.size();
909 for (int i = 0; i < numWakeLocks; i++) {
910 final WakeLock wakeLock = mWakeLocks.get(i);
911 switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
912 case PowerManager.FULL_WAKE_LOCK:
913 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
914 case PowerManager.SCREEN_DIM_WAKE_LOCK:
915 numWakeLocksCleared += 1;
916 break;
917 }
918 }
919 EventLog.writeEvent(EventLogTags.POWER_SLEEP_REQUESTED, numWakeLocksCleared);
920 return true;
921 }
922
Jeff Brown62c82e42012-09-26 01:30:41 -0700923 @Override // Binder call
924 public void nap(long eventTime) {
925 if (eventTime > SystemClock.uptimeMillis()) {
926 throw new IllegalArgumentException("event time must not be in the future");
927 }
928
929 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
930
931 final long ident = Binder.clearCallingIdentity();
932 try {
933 napInternal(eventTime);
934 } finally {
935 Binder.restoreCallingIdentity(ident);
936 }
937 }
938
939 private void napInternal(long eventTime) {
940 synchronized (mLock) {
941 if (napNoUpdateLocked(eventTime)) {
942 updatePowerStateLocked();
943 }
944 }
945 }
946
947 private boolean napNoUpdateLocked(long eventTime) {
948 if (DEBUG_SPEW) {
949 Slog.d(TAG, "napNoUpdateLocked: eventTime=" + eventTime);
950 }
951
952 if (eventTime < mLastWakeTime || mWakefulness != WAKEFULNESS_AWAKE
953 || !mBootCompleted || !mSystemReady) {
954 return false;
955 }
956
957 Slog.i(TAG, "Nap time...");
958
959 mDirty |= DIRTY_WAKEFULNESS;
960 mWakefulness = WAKEFULNESS_NAPPING;
961 return true;
962 }
963
Jeff Brown96307042012-07-27 15:51:34 -0700964 /**
965 * Updates the global power state based on dirty bits recorded in mDirty.
966 *
967 * This is the main function that performs power state transitions.
968 * We centralize them here so that we can recompute the power state completely
969 * each time something important changes, and ensure that we do it the same
970 * way each time. The point is to gather all of the transition logic here.
971 */
972 private void updatePowerStateLocked() {
973 if (!mSystemReady || mDirty == 0) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700974 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800975 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800976
Jeff Brown96307042012-07-27 15:51:34 -0700977 // Phase 0: Basic state updates.
978 updateIsPoweredLocked(mDirty);
979 updateStayOnLocked(mDirty);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800980
Jeff Brown96307042012-07-27 15:51:34 -0700981 // Phase 1: Update wakefulness.
982 // Loop because the wake lock and user activity computations are influenced
983 // by changes in wakefulness.
984 final long now = SystemClock.uptimeMillis();
985 int dirtyPhase2 = 0;
986 for (;;) {
987 int dirtyPhase1 = mDirty;
988 dirtyPhase2 |= dirtyPhase1;
989 mDirty = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800990
Jeff Brown96307042012-07-27 15:51:34 -0700991 updateWakeLockSummaryLocked(dirtyPhase1);
992 updateUserActivitySummaryLocked(now, dirtyPhase1);
993 if (!updateWakefulnessLocked(dirtyPhase1)) {
994 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800995 }
996 }
997
Jeff Brown96307042012-07-27 15:51:34 -0700998 // Phase 2: Update dreams and display power state.
999 updateDreamLocked(dirtyPhase2);
1000 updateDisplayPowerStateLocked(dirtyPhase2);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001001
Jeff Brown96307042012-07-27 15:51:34 -07001002 // Phase 3: Send notifications, if needed.
1003 sendPendingNotificationsLocked();
Craig Mautner75fc9de2012-06-18 16:53:27 -07001004
Jeff Brown96307042012-07-27 15:51:34 -07001005 // Phase 4: Update suspend blocker.
1006 // Because we might release the last suspend blocker here, we need to make sure
1007 // we finished everything else first!
1008 updateSuspendBlockerLocked();
1009 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001010
Jeff Brown96307042012-07-27 15:51:34 -07001011 private void sendPendingNotificationsLocked() {
1012 if (mDisplayReady) {
1013 if (mSendWakeUpFinishedNotificationWhenReady) {
1014 mSendWakeUpFinishedNotificationWhenReady = false;
1015 mNotifier.onWakeUpFinished();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001016 }
Jeff Brown96307042012-07-27 15:51:34 -07001017 if (mSendGoToSleepFinishedNotificationWhenReady) {
1018 mSendGoToSleepFinishedNotificationWhenReady = false;
1019 mNotifier.onGoToSleepFinished();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001020 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001021 }
The Android Open Source Project10592532009-03-18 17:39:46 -07001022 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001023
Jim Miller92e66dd2012-02-21 18:57:12 -08001024 /**
Jeff Brown96307042012-07-27 15:51:34 -07001025 * Updates the value of mIsPowered.
1026 * Sets DIRTY_IS_POWERED if a change occurred.
Jim Miller92e66dd2012-02-21 18:57:12 -08001027 */
Jeff Brown96307042012-07-27 15:51:34 -07001028 private void updateIsPoweredLocked(int dirty) {
1029 if ((dirty & DIRTY_BATTERY_STATE) != 0) {
Jeff Brownf3fb8952012-10-02 20:57:05 -07001030 final boolean wasPowered = mIsPowered;
1031 final int oldPlugType = mPlugType;
Jeff Browna4d82042012-10-02 19:11:19 -07001032 mIsPowered = mBatteryService.isPowered(BatteryManager.BATTERY_PLUGGED_ANY);
Jeff Brownf3fb8952012-10-02 20:57:05 -07001033 mPlugType = mBatteryService.getPlugType();
Jeff Browna4d82042012-10-02 19:11:19 -07001034
1035 if (DEBUG) {
1036 Slog.d(TAG, "updateIsPoweredLocked: wasPowered=" + wasPowered
Jeff Brownf3fb8952012-10-02 20:57:05 -07001037 + ", mIsPowered=" + mIsPowered
1038 + ", oldPlugType=" + oldPlugType
1039 + ", mPlugType=" + mPlugType);
Jeff Browna4d82042012-10-02 19:11:19 -07001040 }
Jim Miller92e66dd2012-02-21 18:57:12 -08001041
Jeff Brownf3fb8952012-10-02 20:57:05 -07001042 if (wasPowered != mIsPowered || oldPlugType != mPlugType) {
Jeff Brown96307042012-07-27 15:51:34 -07001043 mDirty |= DIRTY_IS_POWERED;
1044
1045 // Treat plugging and unplugging the devices as a user activity.
1046 // Users find it disconcerting when they plug or unplug the device
1047 // and it shuts off right away.
1048 // Some devices also wake the device when plugged or unplugged because
1049 // they don't have a charging LED.
1050 final long now = SystemClock.uptimeMillis();
Jeff Brownf3fb8952012-10-02 20:57:05 -07001051 if (shouldWakeUpWhenPluggedOrUnpluggedLocked(wasPowered, oldPlugType)) {
Jeff Brown96307042012-07-27 15:51:34 -07001052 wakeUpNoUpdateLocked(now);
1053 }
1054 userActivityNoUpdateLocked(
1055 now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
1056 }
1057 }
1058 }
1059
Jeff Brownf3fb8952012-10-02 20:57:05 -07001060 private boolean shouldWakeUpWhenPluggedOrUnpluggedLocked(boolean wasPowered, int oldPlugType) {
1061 if (mWakeUpWhenPluggedOrUnpluggedConfig) {
1062 // FIXME: Need more accurate detection of wireless chargers.
1063 //
1064 // We are unable to accurately detect whether the device is resting on the
1065 // charger unless it is actually receiving power. This causes us some grief
1066 // because the device might not appear to be plugged into the wireless charger
1067 // unless it actually charging.
1068 //
1069 // To avoid spuriously waking the screen, we apply a special policy to
1070 // wireless chargers.
1071 //
1072 // 1. Don't wake the device when unplugged from wireless charger because
1073 // it might be that the device is still resting on the wireless charger
1074 // but is not receiving power anymore because the battery is full.
1075 //
1076 // 2. Don't wake the device when plugged into a wireless charger if the
1077 // battery already appears to be mostly full. This situation may indicate
1078 // that the device was resting on the charger the whole time and simply
1079 // wasn't receiving power because the battery was full. We can't tell
1080 // whether the device was just placed on the charger or whether it has
1081 // been there for half of the night slowly discharging until it hit
1082 // the point where it needed to start charging again.
1083 if (wasPowered && !mIsPowered
1084 && oldPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS) {
1085 return false;
1086 }
1087 if (!wasPowered && mIsPowered
1088 && mPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS
1089 && mBatteryService.getBatteryLevel() >=
1090 WIRELESS_CHARGER_TURN_ON_BATTERY_LEVEL_LIMIT) {
1091 return false;
1092 }
1093 return true;
1094 }
1095 return false;
1096 }
1097
Jeff Brown96307042012-07-27 15:51:34 -07001098 /**
1099 * Updates the value of mStayOn.
1100 * Sets DIRTY_STAY_ON if a change occurred.
1101 */
1102 private void updateStayOnLocked(int dirty) {
1103 if ((dirty & (DIRTY_BATTERY_STATE | DIRTY_SETTINGS)) != 0) {
1104 if (mStayOnWhilePluggedInSetting != 0
1105 && !isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
1106 mStayOn = mBatteryService.isPowered(mStayOnWhilePluggedInSetting);
1107 } else {
1108 mStayOn = false;
1109 }
1110 }
1111 }
1112
1113 /**
1114 * Updates the value of mWakeLockSummary to summarize the state of all active wake locks.
1115 * Note that most wake-locks are ignored when the system is asleep.
1116 *
1117 * This function must have no other side-effects.
1118 */
1119 private void updateWakeLockSummaryLocked(int dirty) {
1120 if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_WAKEFULNESS)) != 0) {
1121 mWakeLockSummary = 0;
1122
1123 final int numWakeLocks = mWakeLocks.size();
1124 for (int i = 0; i < numWakeLocks; i++) {
1125 final WakeLock wakeLock = mWakeLocks.get(i);
1126 switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
1127 case PowerManager.PARTIAL_WAKE_LOCK:
1128 mWakeLockSummary |= WAKE_LOCK_CPU;
1129 break;
1130 case PowerManager.FULL_WAKE_LOCK:
1131 if (mWakefulness != WAKEFULNESS_ASLEEP) {
1132 mWakeLockSummary |= WAKE_LOCK_CPU
1133 | WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_BUTTON_BRIGHT;
1134 }
1135 break;
1136 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
1137 if (mWakefulness != WAKEFULNESS_ASLEEP) {
1138 mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_SCREEN_BRIGHT;
1139 }
1140 break;
1141 case PowerManager.SCREEN_DIM_WAKE_LOCK:
1142 if (mWakefulness != WAKEFULNESS_ASLEEP) {
1143 mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_SCREEN_DIM;
1144 }
1145 break;
1146 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
1147 if (mWakefulness != WAKEFULNESS_ASLEEP) {
1148 mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_PROXIMITY_SCREEN_OFF;
1149 }
1150 break;
1151 }
1152 }
1153
1154 if (DEBUG_SPEW) {
1155 Slog.d(TAG, "updateWakeLockSummaryLocked: mWakefulness="
1156 + wakefulnessToString(mWakefulness)
1157 + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary));
1158 }
1159 }
1160 }
1161
1162 /**
1163 * Updates the value of mUserActivitySummary to summarize the user requested
1164 * state of the system such as whether the screen should be bright or dim.
1165 * Note that user activity is ignored when the system is asleep.
1166 *
1167 * This function must have no other side-effects.
1168 */
1169 private void updateUserActivitySummaryLocked(long now, int dirty) {
1170 // Update the status of the user activity timeout timer.
1171 if ((dirty & (DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS | DIRTY_SETTINGS)) != 0) {
1172 mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT);
1173
1174 long nextTimeout = 0;
1175 if (mWakefulness != WAKEFULNESS_ASLEEP) {
1176 final int screenOffTimeout = getScreenOffTimeoutLocked();
Jeff Brownff532542012-10-02 21:18:04 -07001177 final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
Jeff Brown96307042012-07-27 15:51:34 -07001178
1179 mUserActivitySummary = 0;
1180 if (mLastUserActivityTime >= mLastWakeTime) {
1181 nextTimeout = mLastUserActivityTime
1182 + screenOffTimeout - screenDimDuration;
1183 if (now < nextTimeout) {
1184 mUserActivitySummary |= USER_ACTIVITY_SCREEN_BRIGHT;
1185 } else {
1186 nextTimeout = mLastUserActivityTime + screenOffTimeout;
1187 if (now < nextTimeout) {
1188 mUserActivitySummary |= USER_ACTIVITY_SCREEN_DIM;
1189 }
1190 }
1191 }
1192 if (mUserActivitySummary == 0
1193 && mLastUserActivityTimeNoChangeLights >= mLastWakeTime) {
1194 nextTimeout = mLastUserActivityTimeNoChangeLights + screenOffTimeout;
1195 if (now < nextTimeout
1196 && mDisplayPowerRequest.screenState
1197 != DisplayPowerRequest.SCREEN_STATE_OFF) {
1198 mUserActivitySummary = mDisplayPowerRequest.screenState
1199 == DisplayPowerRequest.SCREEN_STATE_BRIGHT ?
1200 USER_ACTIVITY_SCREEN_BRIGHT : USER_ACTIVITY_SCREEN_DIM;
1201 }
1202 }
1203 if (mUserActivitySummary != 0) {
1204 Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY_TIMEOUT);
1205 msg.setAsynchronous(true);
1206 mHandler.sendMessageAtTime(msg, nextTimeout);
1207 }
1208 } else {
1209 mUserActivitySummary = 0;
1210 }
1211
1212 if (DEBUG_SPEW) {
1213 Slog.d(TAG, "updateUserActivitySummaryLocked: mWakefulness="
1214 + wakefulnessToString(mWakefulness)
1215 + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
1216 + ", nextTimeout=" + TimeUtils.formatUptime(nextTimeout));
1217 }
1218 }
1219 }
1220
1221 /**
1222 * Called when a user activity timeout has occurred.
1223 * Simply indicates that something about user activity has changed so that the new
1224 * state can be recomputed when the power state is updated.
1225 *
1226 * This function must have no other side-effects besides setting the dirty
1227 * bit and calling update power state. Wakefulness transitions are handled elsewhere.
1228 */
1229 private void handleUserActivityTimeout() { // runs on handler thread
1230 synchronized (mLock) {
1231 if (DEBUG_SPEW) {
1232 Slog.d(TAG, "handleUserActivityTimeout");
1233 }
1234
1235 mDirty |= DIRTY_USER_ACTIVITY;
1236 updatePowerStateLocked();
1237 }
1238 }
1239
1240 private int getScreenOffTimeoutLocked() {
1241 int timeout = mScreenOffTimeoutSetting;
1242 if (isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
1243 timeout = Math.min(timeout, mMaximumScreenOffTimeoutFromDeviceAdmin);
1244 }
Jeff Brown1e3b98d2012-09-30 18:58:59 -07001245 if (mUserActivityTimeoutOverrideFromWindowManager >= 0) {
1246 timeout = (int)Math.min(timeout, mUserActivityTimeoutOverrideFromWindowManager);
1247 }
Jeff Brown96307042012-07-27 15:51:34 -07001248 return Math.max(timeout, MINIMUM_SCREEN_OFF_TIMEOUT);
1249 }
1250
Jeff Brownff532542012-10-02 21:18:04 -07001251 private int getScreenDimDurationLocked(int screenOffTimeout) {
1252 return Math.min(SCREEN_DIM_DURATION,
1253 (int)(screenOffTimeout * MAXIMUM_SCREEN_DIM_RATIO));
Jeff Brown96307042012-07-27 15:51:34 -07001254 }
1255
1256 /**
1257 * Updates the wakefulness of the device.
1258 *
1259 * This is the function that decides whether the device should start napping
1260 * based on the current wake locks and user activity state. It may modify mDirty
1261 * if the wakefulness changes.
1262 *
1263 * Returns true if the wakefulness changed and we need to restart power state calculation.
1264 */
1265 private boolean updateWakefulnessLocked(int dirty) {
1266 boolean changed = false;
1267 if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_BOOT_COMPLETED
1268 | DIRTY_WAKEFULNESS | DIRTY_STAY_ON)) != 0) {
1269 if (mWakefulness == WAKEFULNESS_AWAKE && isItBedTimeYetLocked()) {
1270 if (DEBUG_SPEW) {
Jeff Brown62c82e42012-09-26 01:30:41 -07001271 Slog.d(TAG, "updateWakefulnessLocked: Bed time...");
Jeff Brown96307042012-07-27 15:51:34 -07001272 }
Jeff Brown62c82e42012-09-26 01:30:41 -07001273 final long time = SystemClock.uptimeMillis();
1274 if (mDreamsActivateOnSleepSetting) {
1275 changed = napNoUpdateLocked(time);
1276 } else {
1277 changed = goToSleepNoUpdateLocked(time,
1278 PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
1279 }
Jeff Brown96307042012-07-27 15:51:34 -07001280 }
1281 }
1282 return changed;
1283 }
1284
Jeff Brown645832d2012-10-03 14:57:03 -07001285 /**
1286 * Returns true if the device should go to sleep now.
1287 * Also used when exiting a dream to determine whether we should go back
1288 * to being fully awake or else go to sleep for good.
1289 */
Jeff Brown96307042012-07-27 15:51:34 -07001290 private boolean isItBedTimeYetLocked() {
Jeff Brown645832d2012-10-03 14:57:03 -07001291 return mBootCompleted && !isScreenBeingKeptOnLocked();
1292 }
1293
1294 /**
1295 * Returns true if the screen is being kept on by a wake lock, user activity
1296 * or the stay on while powered setting.
1297 */
1298 private boolean isScreenBeingKeptOnLocked() {
1299 return mStayOn
1300 || (mWakeLockSummary & (WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM
1301 | WAKE_LOCK_PROXIMITY_SCREEN_OFF)) != 0
1302 || (mUserActivitySummary & (USER_ACTIVITY_SCREEN_BRIGHT
1303 | USER_ACTIVITY_SCREEN_DIM)) != 0;
Jeff Brown96307042012-07-27 15:51:34 -07001304 }
1305
1306 /**
1307 * Determines whether to post a message to the sandman to update the dream state.
1308 */
1309 private void updateDreamLocked(int dirty) {
John Spurlockf4f6b4c2012-08-25 12:08:03 -04001310 if ((dirty & (DIRTY_WAKEFULNESS
Jeff Brown645832d2012-10-03 14:57:03 -07001311 | DIRTY_USER_ACTIVITY
1312 | DIRTY_WAKE_LOCKS
1313 | DIRTY_BOOT_COMPLETED
John Spurlockf4f6b4c2012-08-25 12:08:03 -04001314 | DIRTY_SETTINGS
1315 | DIRTY_IS_POWERED
1316 | DIRTY_STAY_ON
Jeff Brown62c82e42012-09-26 01:30:41 -07001317 | DIRTY_BATTERY_STATE)) != 0) {
Jeff Brown96307042012-07-27 15:51:34 -07001318 scheduleSandmanLocked();
1319 }
1320 }
1321
1322 private void scheduleSandmanLocked() {
1323 if (!mSandmanScheduled) {
1324 mSandmanScheduled = true;
1325 Message msg = mHandler.obtainMessage(MSG_SANDMAN);
1326 msg.setAsynchronous(true);
1327 mHandler.sendMessage(msg);
1328 }
1329 }
1330
1331 /**
1332 * Called when the device enters or exits a napping or dreaming state.
1333 *
1334 * We do this asynchronously because we must call out of the power manager to start
1335 * the dream and we don't want to hold our lock while doing so. There is a risk that
1336 * the device will wake or go to sleep in the meantime so we have to handle that case.
1337 */
1338 private void handleSandman() { // runs on handler thread
1339 // Handle preconditions.
1340 boolean startDreaming = false;
1341 synchronized (mLock) {
1342 mSandmanScheduled = false;
John Spurlock10fb2242012-08-23 15:32:28 -04001343 boolean canDream = canDreamLocked();
Jeff Brown96307042012-07-27 15:51:34 -07001344 if (DEBUG_SPEW) {
John Spurlock10fb2242012-08-23 15:32:28 -04001345 Log.d(TAG, "handleSandman: canDream=" + canDream
Jeff Brown96307042012-07-27 15:51:34 -07001346 + ", mWakefulness=" + wakefulnessToString(mWakefulness));
1347 }
1348
John Spurlock10fb2242012-08-23 15:32:28 -04001349 if (canDream && mWakefulness == WAKEFULNESS_NAPPING) {
Jeff Brown96307042012-07-27 15:51:34 -07001350 startDreaming = true;
1351 }
1352 }
1353
Jeff Brown96307042012-07-27 15:51:34 -07001354 // Start dreaming if needed.
1355 // We only control the dream on the handler thread, so we don't need to worry about
1356 // concurrent attempts to start or stop the dream.
1357 boolean isDreaming = false;
1358 if (mDreamManager != null) {
Jeff Brown62c82e42012-09-26 01:30:41 -07001359 if (startDreaming) {
1360 mDreamManager.startDream();
Jeff Brown96307042012-07-27 15:51:34 -07001361 }
Jeff Brown62c82e42012-09-26 01:30:41 -07001362 isDreaming = mDreamManager.isDreaming();
Jeff Brown96307042012-07-27 15:51:34 -07001363 }
1364
1365 // Update dream state.
1366 // We might need to stop the dream again if the preconditions changed.
1367 boolean continueDreaming = false;
1368 synchronized (mLock) {
1369 if (isDreaming && canDreamLocked()) {
1370 if (mWakefulness == WAKEFULNESS_NAPPING) {
1371 mWakefulness = WAKEFULNESS_DREAMING;
1372 mDirty |= DIRTY_WAKEFULNESS;
1373 updatePowerStateLocked();
1374 continueDreaming = true;
1375 } else if (mWakefulness == WAKEFULNESS_DREAMING) {
1376 continueDreaming = true;
1377 }
1378 }
1379 if (!continueDreaming) {
1380 handleDreamFinishedLocked();
1381 }
Jeff Brown96307042012-07-27 15:51:34 -07001382 }
1383
1384 // Stop dreaming if needed.
1385 // It's possible that something else changed to make us need to start the dream again.
1386 // If so, then the power manager will have posted another message to the handler
1387 // to take care of it later.
1388 if (mDreamManager != null) {
Jeff Brown62c82e42012-09-26 01:30:41 -07001389 if (!continueDreaming) {
1390 mDreamManager.stopDream();
Jeff Brown96307042012-07-27 15:51:34 -07001391 }
1392 }
1393 }
1394
1395 /**
Jeff Brown645832d2012-10-03 14:57:03 -07001396 * Returns true if the device is allowed to dream in its current state
1397 * assuming that it is currently napping or dreaming.
Jeff Brown96307042012-07-27 15:51:34 -07001398 */
1399 private boolean canDreamLocked() {
Jeff Brown645832d2012-10-03 14:57:03 -07001400 return mDreamsSupportedConfig
John Spurlock10fb2242012-08-23 15:32:28 -04001401 && mDreamsEnabledSetting
Jeff Brown645832d2012-10-03 14:57:03 -07001402 && mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF
1403 && mBootCompleted
1404 && (mIsPowered || isScreenBeingKeptOnLocked());
Jeff Brown96307042012-07-27 15:51:34 -07001405 }
1406
1407 /**
1408 * Called when a dream is ending to figure out what to do next.
1409 */
1410 private void handleDreamFinishedLocked() {
1411 if (mWakefulness == WAKEFULNESS_NAPPING
1412 || mWakefulness == WAKEFULNESS_DREAMING) {
1413 if (isItBedTimeYetLocked()) {
1414 goToSleepNoUpdateLocked(SystemClock.uptimeMillis(),
1415 PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
1416 updatePowerStateLocked();
1417 } else {
1418 wakeUpNoUpdateLocked(SystemClock.uptimeMillis());
1419 updatePowerStateLocked();
1420 }
1421 }
1422 }
1423
Jeff Brown96307042012-07-27 15:51:34 -07001424 /**
1425 * Updates the display power state asynchronously.
1426 * When the update is finished, mDisplayReady will be set to true. The display
1427 * controller posts a message to tell us when the actual display power state
1428 * has been updated so we come back here to double-check and finish up.
1429 *
1430 * This function recalculates the display power state each time.
1431 */
1432 private void updateDisplayPowerStateLocked(int dirty) {
1433 if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS
1434 | DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED
1435 | DIRTY_SETTINGS)) != 0) {
1436 int newScreenState = getDesiredScreenPowerState();
1437 if (newScreenState != mDisplayPowerRequest.screenState) {
1438 if (newScreenState == DisplayPowerRequest.SCREEN_STATE_OFF
1439 && mDisplayPowerRequest.screenState
1440 != DisplayPowerRequest.SCREEN_STATE_OFF) {
1441 mLastScreenOffEventElapsedRealTime = SystemClock.elapsedRealtime();
1442 }
1443
1444 mDisplayPowerRequest.screenState = newScreenState;
1445 nativeSetPowerState(
1446 newScreenState != DisplayPowerRequest.SCREEN_STATE_OFF,
1447 newScreenState == DisplayPowerRequest.SCREEN_STATE_BRIGHT);
1448 }
1449
1450 int screenBrightness = mScreenBrightnessSettingDefault;
Jeff Brown330560f2012-08-21 22:10:57 -07001451 float screenAutoBrightnessAdjustment = 0.0f;
Jeff Brown96307042012-07-27 15:51:34 -07001452 boolean autoBrightness = (mScreenBrightnessModeSetting ==
1453 Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
1454 if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)) {
1455 screenBrightness = mScreenBrightnessOverrideFromWindowManager;
1456 autoBrightness = false;
1457 } else if (isValidBrightness(mTemporaryScreenBrightnessSettingOverride)) {
1458 screenBrightness = mTemporaryScreenBrightnessSettingOverride;
1459 } else if (isValidBrightness(mScreenBrightnessSetting)) {
Jeff Brown330560f2012-08-21 22:10:57 -07001460 screenBrightness = mScreenBrightnessSetting;
Jeff Brown96307042012-07-27 15:51:34 -07001461 }
1462 if (autoBrightness) {
1463 screenBrightness = mScreenBrightnessSettingDefault;
Jeff Brown330560f2012-08-21 22:10:57 -07001464 if (isValidAutoBrightnessAdjustment(
1465 mTemporaryScreenAutoBrightnessAdjustmentSettingOverride)) {
1466 screenAutoBrightnessAdjustment =
1467 mTemporaryScreenAutoBrightnessAdjustmentSettingOverride;
1468 } else if (isValidAutoBrightnessAdjustment(
1469 mScreenAutoBrightnessAdjustmentSetting)) {
1470 screenAutoBrightnessAdjustment = mScreenAutoBrightnessAdjustmentSetting;
1471 }
Jeff Brown96307042012-07-27 15:51:34 -07001472 }
1473 screenBrightness = Math.max(Math.min(screenBrightness,
1474 mScreenBrightnessSettingMaximum), mScreenBrightnessSettingMinimum);
Jeff Brown330560f2012-08-21 22:10:57 -07001475 screenAutoBrightnessAdjustment = Math.max(Math.min(
1476 screenAutoBrightnessAdjustment, 1.0f), -1.0f);
Jeff Brown96307042012-07-27 15:51:34 -07001477 mDisplayPowerRequest.screenBrightness = screenBrightness;
Jeff Brown330560f2012-08-21 22:10:57 -07001478 mDisplayPowerRequest.screenAutoBrightnessAdjustment =
1479 screenAutoBrightnessAdjustment;
Jeff Brown96307042012-07-27 15:51:34 -07001480 mDisplayPowerRequest.useAutoBrightness = autoBrightness;
1481
1482 mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
1483
1484 mDisplayReady = mDisplayPowerController.requestPowerState(mDisplayPowerRequest,
1485 mRequestWaitForNegativeProximity);
1486 mRequestWaitForNegativeProximity = false;
1487
1488 if (DEBUG_SPEW) {
1489 Slog.d(TAG, "updateScreenStateLocked: displayReady=" + mDisplayReady
1490 + ", newScreenState=" + newScreenState
1491 + ", mWakefulness=" + mWakefulness
1492 + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary)
1493 + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
1494 + ", mBootCompleted=" + mBootCompleted);
1495 }
1496 }
1497 }
1498
1499 private static boolean isValidBrightness(int value) {
1500 return value >= 0 && value <= 255;
1501 }
1502
Jeff Brown330560f2012-08-21 22:10:57 -07001503 private static boolean isValidAutoBrightnessAdjustment(float value) {
Jeff Brown5d03a532012-08-22 13:22:02 -07001504 // Handles NaN by always returning false.
1505 return value >= -1.0f && value <= 1.0f;
Jeff Brown330560f2012-08-21 22:10:57 -07001506 }
1507
Jeff Brown96307042012-07-27 15:51:34 -07001508 private int getDesiredScreenPowerState() {
1509 if (mWakefulness == WAKEFULNESS_ASLEEP) {
1510 return DisplayPowerRequest.SCREEN_STATE_OFF;
1511 }
1512
1513 if ((mWakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0
1514 || (mUserActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0
1515 || !mBootCompleted) {
1516 return DisplayPowerRequest.SCREEN_STATE_BRIGHT;
1517 }
1518
1519 return DisplayPowerRequest.SCREEN_STATE_DIM;
1520 }
1521
1522 private final DisplayPowerController.Callbacks mDisplayPowerControllerCallbacks =
1523 new DisplayPowerController.Callbacks() {
1524 @Override
1525 public void onStateChanged() {
1526 mDirty |= DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED;
1527 updatePowerStateLocked();
Jim Miller92e66dd2012-02-21 18:57:12 -08001528 }
1529
1530 @Override
Jeff Brown96307042012-07-27 15:51:34 -07001531 public void onProximityNegative() {
1532 userActivityNoUpdateLocked(SystemClock.uptimeMillis(),
1533 PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
1534 updatePowerStateLocked();
1535 }
1536 };
Jim Miller92e66dd2012-02-21 18:57:12 -08001537
Jeff Brown96307042012-07-27 15:51:34 -07001538 private boolean shouldUseProximitySensorLocked() {
1539 return (mWakeLockSummary & WAKE_LOCK_PROXIMITY_SCREEN_OFF) != 0;
1540 }
Jim Miller92e66dd2012-02-21 18:57:12 -08001541
Jeff Brown96307042012-07-27 15:51:34 -07001542 /**
1543 * Updates the suspend blocker that keeps the CPU alive.
1544 *
1545 * This function must have no other side-effects.
1546 */
1547 private void updateSuspendBlockerLocked() {
1548 boolean wantCpu = isCpuNeededLocked();
1549 if (wantCpu != mHoldingWakeLockSuspendBlocker) {
1550 mHoldingWakeLockSuspendBlocker = wantCpu;
1551 if (wantCpu) {
1552 if (DEBUG) {
1553 Slog.d(TAG, "updateSuspendBlockerLocked: Acquiring suspend blocker.");
Jim Miller92e66dd2012-02-21 18:57:12 -08001554 }
Jeff Brown96307042012-07-27 15:51:34 -07001555 mWakeLockSuspendBlocker.acquire();
Joe Onorato4b9f62d2010-10-11 13:41:35 -07001556 } else {
Jeff Brown96307042012-07-27 15:51:34 -07001557 if (DEBUG) {
1558 Slog.d(TAG, "updateSuspendBlockerLocked: Releasing suspend blocker.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001559 }
Jeff Brown96307042012-07-27 15:51:34 -07001560 mWakeLockSuspendBlocker.release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001561 }
1562 }
1563 }
1564
Jeff Brown96307042012-07-27 15:51:34 -07001565 private boolean isCpuNeededLocked() {
1566 return !mBootCompleted
1567 || mWakeLockSummary != 0
1568 || mUserActivitySummary != 0
1569 || mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF
1570 || !mDisplayReady;
1571 }
1572
1573 @Override // Binder call
1574 public boolean isScreenOn() {
1575 final long ident = Binder.clearCallingIdentity();
Mike Lockwoodd7786b42009-10-15 17:09:16 -07001576 try {
Jeff Brown96307042012-07-27 15:51:34 -07001577 return isScreenOnInternal();
1578 } finally {
1579 Binder.restoreCallingIdentity(ident);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07001580 }
1581 }
1582
Jeff Brown96307042012-07-27 15:51:34 -07001583 private boolean isScreenOnInternal() {
1584 synchronized (mLock) {
1585 return !mSystemReady
1586 || mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF;
Mike Lockwoodb2865412010-02-02 22:40:33 -05001587 }
1588 }
1589
Jeff Brown96307042012-07-27 15:51:34 -07001590 private void handleBatteryStateChangedLocked() {
1591 mDirty |= DIRTY_BATTERY_STATE;
1592 updatePowerStateLocked();
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001593 }
1594
Jeff Brown96307042012-07-27 15:51:34 -07001595 private void handleBootCompletedLocked() {
1596 final long now = SystemClock.uptimeMillis();
1597 mBootCompleted = true;
1598 mDirty |= DIRTY_BOOT_COMPLETED;
1599 userActivityNoUpdateLocked(
1600 now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
1601 updatePowerStateLocked();
Dianne Hackborn254cb442010-01-27 19:23:59 -08001602 }
1603
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001604 /**
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001605 * Reboot the device, passing 'reason' (may be null)
Doug Zongker50a21f42009-11-19 12:49:53 -08001606 * to the underlying __reboot system call. Should not return.
1607 */
Jeff Brown96307042012-07-27 15:51:34 -07001608 @Override // Binder call
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001609 public void reboot(boolean confirm, String reason, boolean wait) {
Doug Zongker50a21f42009-11-19 12:49:53 -08001610 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
San Mehat14e69af2010-01-06 14:58:18 -08001611
Jeff Brown96307042012-07-27 15:51:34 -07001612 final long ident = Binder.clearCallingIdentity();
1613 try {
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001614 rebootInternal(false, confirm, reason, wait);
Jeff Brown96307042012-07-27 15:51:34 -07001615 } finally {
1616 Binder.restoreCallingIdentity(ident);
1617 }
1618 }
1619
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001620 /**
1621 * Shutdown the devic, passing 'reason' (may be null)
1622 * to the underlying __reboot system call. Should not return.
1623 */
1624 @Override // Binder call
1625 public void shutdown(boolean confirm, boolean wait) {
1626 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
1627
1628 final long ident = Binder.clearCallingIdentity();
1629 try {
1630 rebootInternal(true, confirm, null, wait);
1631 } finally {
1632 Binder.restoreCallingIdentity(ident);
1633 }
1634 }
1635
1636 private void rebootInternal(final boolean shutdown, final boolean confirm,
1637 final String reason, boolean wait) {
Jeff Brown96307042012-07-27 15:51:34 -07001638 if (mHandler == null || !mSystemReady) {
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001639 throw new IllegalStateException("Too early to call reboot()");
1640 }
Mike Lockwoodb62f9592010-03-12 07:55:23 -05001641
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001642 Runnable runnable = new Runnable() {
1643 public void run() {
1644 synchronized (this) {
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001645 if (shutdown) {
1646 ShutdownThread.shutdown(mContext, confirm);
1647 } else {
1648 ShutdownThread.reboot(mContext, reason, confirm);
1649 }
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001650 }
San Mehat1e512792010-01-07 10:40:29 -08001651 }
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001652 };
Jeff Brown96307042012-07-27 15:51:34 -07001653
Mike Lockwoodb62f9592010-03-12 07:55:23 -05001654 // ShutdownThread must run on a looper capable of displaying the UI.
Jeff Brown96307042012-07-27 15:51:34 -07001655 Message msg = Message.obtain(mHandler, runnable);
1656 msg.setAsynchronous(true);
1657 mHandler.sendMessage(msg);
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001658
Mike Lockwoodb62f9592010-03-12 07:55:23 -05001659 // PowerManager.reboot() is documented not to return so just wait for the inevitable.
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001660 if (wait) {
1661 synchronized (runnable) {
1662 while (true) {
1663 try {
1664 runnable.wait();
1665 } catch (InterruptedException e) {
1666 }
Mike Lockwoodb62f9592010-03-12 07:55:23 -05001667 }
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001668 }
Doug Zongker50a21f42009-11-19 12:49:53 -08001669 }
1670 }
1671
Dan Egnor60d87622009-12-16 16:32:58 -08001672 /**
1673 * Crash the runtime (causing a complete restart of the Android framework).
1674 * Requires REBOOT permission. Mostly for testing. Should not return.
1675 */
Jeff Brown96307042012-07-27 15:51:34 -07001676 @Override // Binder call
1677 public void crash(String message) {
Dan Egnor60d87622009-12-16 16:32:58 -08001678 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
Jeff Brown96307042012-07-27 15:51:34 -07001679
1680 final long ident = Binder.clearCallingIdentity();
1681 try {
1682 crashInternal(message);
1683 } finally {
1684 Binder.restoreCallingIdentity(ident);
1685 }
1686 }
1687
1688 private void crashInternal(final String message) {
Dan Egnor60d87622009-12-16 16:32:58 -08001689 Thread t = new Thread("PowerManagerService.crash()") {
Jeff Brown96307042012-07-27 15:51:34 -07001690 public void run() {
1691 throw new RuntimeException(message);
1692 }
Dan Egnor60d87622009-12-16 16:32:58 -08001693 };
1694 try {
1695 t.start();
1696 t.join();
1697 } catch (InterruptedException e) {
1698 Log.wtf(TAG, e);
1699 }
1700 }
1701
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001702 /**
Jeff Brown96307042012-07-27 15:51:34 -07001703 * Set the setting that determines whether the device stays on when plugged in.
1704 * The argument is a bit string, with each bit specifying a power source that,
1705 * when the device is connected to that source, causes the device to stay on.
1706 * See {@link android.os.BatteryManager} for the list of power sources that
1707 * can be specified. Current values include {@link android.os.BatteryManager#BATTERY_PLUGGED_AC}
1708 * and {@link android.os.BatteryManager#BATTERY_PLUGGED_USB}
1709 *
1710 * Used by "adb shell svc power stayon ..."
1711 *
1712 * @param val an {@code int} containing the bits that specify which power sources
1713 * should cause the device to stay on.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001714 */
Jeff Brown96307042012-07-27 15:51:34 -07001715 @Override // Binder call
1716 public void setStayOnSetting(int val) {
1717 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS, null);
1718
1719 final long ident = Binder.clearCallingIdentity();
1720 try {
1721 setStayOnSettingInternal(val);
1722 } finally {
1723 Binder.restoreCallingIdentity(ident);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001724 }
1725 }
1726
Jeff Brown96307042012-07-27 15:51:34 -07001727 private void setStayOnSettingInternal(int val) {
Christopher Tatead735322012-09-07 14:19:43 -07001728 Settings.Global.putInt(mContext.getContentResolver(),
1729 Settings.Global.STAY_ON_WHILE_PLUGGED_IN, val);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001730 }
1731
1732 /**
Jeff Brown96307042012-07-27 15:51:34 -07001733 * Used by device administration to set the maximum screen off timeout.
1734 *
1735 * This method must only be called by the device administration policy manager.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001736 */
Jeff Brown96307042012-07-27 15:51:34 -07001737 @Override // Binder call
1738 public void setMaximumScreenOffTimeoutFromDeviceAdmin(int timeMs) {
1739 final long ident = Binder.clearCallingIdentity();
1740 try {
1741 setMaximumScreenOffTimeoutFromDeviceAdminInternal(timeMs);
1742 } finally {
1743 Binder.restoreCallingIdentity(ident);
Michael Chane96440f2009-05-06 10:27:36 -07001744 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001745 }
1746
Jeff Brown96307042012-07-27 15:51:34 -07001747 private void setMaximumScreenOffTimeoutFromDeviceAdminInternal(int timeMs) {
1748 synchronized (mLock) {
1749 mMaximumScreenOffTimeoutFromDeviceAdmin = timeMs;
1750 mDirty |= DIRTY_SETTINGS;
1751 updatePowerStateLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001752 }
1753 }
1754
Jeff Brown96307042012-07-27 15:51:34 -07001755 private boolean isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked() {
1756 return mMaximumScreenOffTimeoutFromDeviceAdmin >= 0
1757 && mMaximumScreenOffTimeoutFromDeviceAdmin < Integer.MAX_VALUE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001758 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001759
Jeff Brown96307042012-07-27 15:51:34 -07001760 /**
1761 * Used by the phone application to make the attention LED flash when ringing.
1762 */
1763 @Override // Binder call
Mike Lockwoodb11832d2009-11-25 15:25:55 -05001764 public void setAttentionLight(boolean on, int color) {
1765 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
Jeff Brown96307042012-07-27 15:51:34 -07001766
1767 final long ident = Binder.clearCallingIdentity();
1768 try {
1769 setAttentionLightInternal(on, color);
1770 } finally {
1771 Binder.restoreCallingIdentity(ident);
1772 }
Mike Lockwoodb11832d2009-11-25 15:25:55 -05001773 }
1774
Jeff Brown96307042012-07-27 15:51:34 -07001775 private void setAttentionLightInternal(boolean on, int color) {
1776 LightsService.Light light;
1777 synchronized (mLock) {
1778 if (!mSystemReady) {
1779 return;
1780 }
1781 light = mAttentionLight;
Mike Lockwood36fc3022009-08-25 16:49:06 -07001782 }
Jeff Brown96307042012-07-27 15:51:34 -07001783
1784 // Control light outside of lock.
1785 light.setFlashing(color, LightsService.LIGHT_FLASH_HARDWARE, (on ? 3 : 0), 0);
1786 }
1787
1788 /**
1789 * Used by the Watchdog.
1790 */
1791 public long timeSinceScreenWasLastOn() {
1792 synchronized (mLock) {
1793 if (mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF) {
1794 return 0;
1795 }
1796 return SystemClock.elapsedRealtime() - mLastScreenOffEventElapsedRealTime;
1797 }
1798 }
1799
1800 /**
1801 * Used by the window manager to override the screen brightness based on the
1802 * current foreground activity.
1803 *
1804 * This method must only be called by the window manager.
1805 *
1806 * @param brightness The overridden brightness, or -1 to disable the override.
1807 */
1808 public void setScreenBrightnessOverrideFromWindowManager(int brightness) {
1809 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1810
1811 final long ident = Binder.clearCallingIdentity();
1812 try {
1813 setScreenBrightnessOverrideFromWindowManagerInternal(brightness);
1814 } finally {
1815 Binder.restoreCallingIdentity(ident);
1816 }
1817 }
1818
1819 private void setScreenBrightnessOverrideFromWindowManagerInternal(int brightness) {
1820 synchronized (mLock) {
1821 if (mScreenBrightnessOverrideFromWindowManager != brightness) {
1822 mScreenBrightnessOverrideFromWindowManager = brightness;
1823 mDirty |= DIRTY_SETTINGS;
1824 updatePowerStateLocked();
Mike Lockwoodee2b0942009-11-09 14:09:02 -05001825 }
Mike Lockwood809ad0f2009-10-26 22:10:33 -04001826 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07001827 }
1828
Jeff Brown96307042012-07-27 15:51:34 -07001829 /**
1830 * Used by the window manager to override the button brightness based on the
1831 * current foreground activity.
1832 *
1833 * This method must only be called by the window manager.
1834 *
1835 * @param brightness The overridden brightness, or -1 to disable the override.
1836 */
1837 public void setButtonBrightnessOverrideFromWindowManager(int brightness) {
1838 // Do nothing.
1839 // Button lights are not currently supported in the new implementation.
1840 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1841 }
1842
1843 /**
Jeff Brown1e3b98d2012-09-30 18:58:59 -07001844 * Used by the window manager to override the user activity timeout based on the
1845 * current foreground activity. It can only be used to make the timeout shorter
1846 * than usual, not longer.
1847 *
1848 * This method must only be called by the window manager.
1849 *
1850 * @param timeoutMillis The overridden timeout, or -1 to disable the override.
1851 */
1852 public void setUserActivityTimeoutOverrideFromWindowManager(long timeoutMillis) {
1853 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1854
1855 final long ident = Binder.clearCallingIdentity();
1856 try {
1857 setUserActivityTimeoutOverrideFromWindowManagerInternal(timeoutMillis);
1858 } finally {
1859 Binder.restoreCallingIdentity(ident);
1860 }
1861 }
1862
1863 private void setUserActivityTimeoutOverrideFromWindowManagerInternal(long timeoutMillis) {
1864 synchronized (mLock) {
1865 if (mUserActivityTimeoutOverrideFromWindowManager != timeoutMillis) {
1866 mUserActivityTimeoutOverrideFromWindowManager = timeoutMillis;
1867 mDirty |= DIRTY_SETTINGS;
1868 updatePowerStateLocked();
1869 }
1870 }
1871 }
1872
1873 /**
Jeff Brown96307042012-07-27 15:51:34 -07001874 * Used by the settings application and brightness control widgets to
1875 * temporarily override the current screen brightness setting so that the
1876 * user can observe the effect of an intended settings change without applying
1877 * it immediately.
1878 *
1879 * The override will be canceled when the setting value is next updated.
1880 *
1881 * @param brightness The overridden brightness.
1882 *
1883 * @see Settings.System#SCREEN_BRIGHTNESS
1884 */
1885 @Override // Binder call
1886 public void setTemporaryScreenBrightnessSettingOverride(int brightness) {
1887 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1888
1889 final long ident = Binder.clearCallingIdentity();
1890 try {
1891 setTemporaryScreenBrightnessSettingOverrideInternal(brightness);
1892 } finally {
1893 Binder.restoreCallingIdentity(ident);
Mike Lockwood36fc3022009-08-25 16:49:06 -07001894 }
Jeff Brown96307042012-07-27 15:51:34 -07001895 }
1896
1897 private void setTemporaryScreenBrightnessSettingOverrideInternal(int brightness) {
1898 synchronized (mLock) {
1899 if (mTemporaryScreenBrightnessSettingOverride != brightness) {
1900 mTemporaryScreenBrightnessSettingOverride = brightness;
1901 mDirty |= DIRTY_SETTINGS;
1902 updatePowerStateLocked();
Mike Lockwoodee2b0942009-11-09 14:09:02 -05001903 }
Mike Lockwood200b30b2009-09-20 00:23:59 -04001904 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07001905 }
1906
Jeff Brown96307042012-07-27 15:51:34 -07001907 /**
1908 * Used by the settings application and brightness control widgets to
1909 * temporarily override the current screen auto-brightness adjustment setting so that the
1910 * user can observe the effect of an intended settings change without applying
1911 * it immediately.
1912 *
1913 * The override will be canceled when the setting value is next updated.
1914 *
Jeff Brown330560f2012-08-21 22:10:57 -07001915 * @param adj The overridden brightness, or Float.NaN to disable the override.
Jeff Brown96307042012-07-27 15:51:34 -07001916 *
1917 * @see Settings.System#SCREEN_AUTO_BRIGHTNESS_ADJ
1918 */
1919 @Override // Binder call
1920 public void setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(float adj) {
Jeff Brown96307042012-07-27 15:51:34 -07001921 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
Jeff Brown330560f2012-08-21 22:10:57 -07001922
1923 final long ident = Binder.clearCallingIdentity();
1924 try {
1925 setTemporaryScreenAutoBrightnessAdjustmentSettingOverrideInternal(adj);
1926 } finally {
1927 Binder.restoreCallingIdentity(ident);
1928 }
1929 }
1930
1931 private void setTemporaryScreenAutoBrightnessAdjustmentSettingOverrideInternal(float adj) {
1932 synchronized (mLock) {
1933 // Note: This condition handles NaN because NaN is not equal to any other
1934 // value, including itself.
1935 if (mTemporaryScreenAutoBrightnessAdjustmentSettingOverride != adj) {
1936 mTemporaryScreenAutoBrightnessAdjustmentSettingOverride = adj;
1937 mDirty |= DIRTY_SETTINGS;
1938 updatePowerStateLocked();
1939 }
1940 }
Jeff Brown96307042012-07-27 15:51:34 -07001941 }
1942
1943 /**
1944 * Low-level function turn the device off immediately, without trying
1945 * to be clean. Most people should use {@link ShutdownThread} for a clean shutdown.
1946 */
1947 public static void lowLevelShutdown() {
1948 nativeShutdown();
1949 }
1950
1951 /**
1952 * Low-level function to reboot the device.
1953 *
1954 * @param reason code to pass to the kernel (e.g. "recovery"), or null.
1955 * @throws IOException if reboot fails for some reason (eg, lack of
1956 * permission)
1957 */
1958 public static void lowLevelReboot(String reason) throws IOException {
1959 nativeReboot(reason);
1960 }
1961
1962 @Override // Watchdog.Monitor implementation
1963 public void monitor() {
1964 // Grab and release lock for watchdog monitor to detect deadlocks.
1965 synchronized (mLock) {
Mike Lockwood20f87d72009-11-05 16:08:51 -05001966 }
Jeff Brown96307042012-07-27 15:51:34 -07001967 }
1968
1969 @Override // Binder call
1970 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1971 if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
1972 != PackageManager.PERMISSION_GRANTED) {
1973 pw.println("Permission Denial: can't dump PowerManager from from pid="
1974 + Binder.getCallingPid()
1975 + ", uid=" + Binder.getCallingUid());
Mike Lockwood0d72f7e2009-11-05 20:53:00 -05001976 return;
1977 }
Jeff Brown96307042012-07-27 15:51:34 -07001978
1979 pw.println("POWER MANAGER (dumpsys power)\n");
1980
1981 final DisplayPowerController dpc;
1982 synchronized (mLock) {
1983 pw.println("Power Manager State:");
1984 pw.println(" mDirty=0x" + Integer.toHexString(mDirty));
1985 pw.println(" mWakefulness=" + wakefulnessToString(mWakefulness));
1986 pw.println(" mIsPowered=" + mIsPowered);
Jeff Brownf3fb8952012-10-02 20:57:05 -07001987 pw.println(" mPlugType=" + mPlugType);
Jeff Brown96307042012-07-27 15:51:34 -07001988 pw.println(" mStayOn=" + mStayOn);
1989 pw.println(" mBootCompleted=" + mBootCompleted);
1990 pw.println(" mSystemReady=" + mSystemReady);
1991 pw.println(" mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary));
1992 pw.println(" mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary));
1993 pw.println(" mRequestWaitForNegativeProximity=" + mRequestWaitForNegativeProximity);
1994 pw.println(" mSandmanScheduled=" + mSandmanScheduled);
1995 pw.println(" mLastWakeTime=" + TimeUtils.formatUptime(mLastWakeTime));
1996 pw.println(" mLastSleepTime=" + TimeUtils.formatUptime(mLastSleepTime));
1997 pw.println(" mSendWakeUpFinishedNotificationWhenReady="
1998 + mSendWakeUpFinishedNotificationWhenReady);
1999 pw.println(" mSendGoToSleepFinishedNotificationWhenReady="
2000 + mSendGoToSleepFinishedNotificationWhenReady);
2001 pw.println(" mLastUserActivityTime=" + TimeUtils.formatUptime(mLastUserActivityTime));
2002 pw.println(" mLastUserActivityTimeNoChangeLights="
2003 + TimeUtils.formatUptime(mLastUserActivityTimeNoChangeLights));
2004 pw.println(" mDisplayReady=" + mDisplayReady);
2005 pw.println(" mHoldingWakeLockSuspendBlocker=" + mHoldingWakeLockSuspendBlocker);
2006
2007 pw.println();
2008 pw.println("Settings and Configuration:");
2009 pw.println(" mDreamsSupportedConfig=" + mDreamsSupportedConfig);
2010 pw.println(" mDreamsEnabledSetting=" + mDreamsEnabledSetting);
John Spurlock1a868b72012-08-22 09:56:51 -04002011 pw.println(" mDreamsActivateOnSleepSetting=" + mDreamsActivateOnSleepSetting);
Jeff Brown96307042012-07-27 15:51:34 -07002012 pw.println(" mScreenOffTimeoutSetting=" + mScreenOffTimeoutSetting);
2013 pw.println(" mMaximumScreenOffTimeoutFromDeviceAdmin="
2014 + mMaximumScreenOffTimeoutFromDeviceAdmin + " (enforced="
2015 + isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked() + ")");
2016 pw.println(" mStayOnWhilePluggedInSetting=" + mStayOnWhilePluggedInSetting);
2017 pw.println(" mScreenBrightnessSetting=" + mScreenBrightnessSetting);
Jeff Brown330560f2012-08-21 22:10:57 -07002018 pw.println(" mScreenAutoBrightnessAdjustmentSetting="
2019 + mScreenAutoBrightnessAdjustmentSetting);
Jeff Brown96307042012-07-27 15:51:34 -07002020 pw.println(" mScreenBrightnessModeSetting=" + mScreenBrightnessModeSetting);
2021 pw.println(" mScreenBrightnessOverrideFromWindowManager="
2022 + mScreenBrightnessOverrideFromWindowManager);
Jeff Brown1e3b98d2012-09-30 18:58:59 -07002023 pw.println(" mUserActivityTimeoutOverrideFromWindowManager="
2024 + mUserActivityTimeoutOverrideFromWindowManager);
Jeff Brown96307042012-07-27 15:51:34 -07002025 pw.println(" mTemporaryScreenBrightnessSettingOverride="
2026 + mTemporaryScreenBrightnessSettingOverride);
Jeff Brown330560f2012-08-21 22:10:57 -07002027 pw.println(" mTemporaryScreenAutoBrightnessAdjustmentSettingOverride="
2028 + mTemporaryScreenAutoBrightnessAdjustmentSettingOverride);
Jeff Brown96307042012-07-27 15:51:34 -07002029 pw.println(" mScreenBrightnessSettingMinimum=" + mScreenBrightnessSettingMinimum);
2030 pw.println(" mScreenBrightnessSettingMaximum=" + mScreenBrightnessSettingMaximum);
2031 pw.println(" mScreenBrightnessSettingDefault=" + mScreenBrightnessSettingDefault);
2032
Jeff Brownff532542012-10-02 21:18:04 -07002033 final int screenOffTimeout = getScreenOffTimeoutLocked();
2034 final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
2035 pw.println();
2036 pw.println("Screen off timeout: " + screenOffTimeout + " ms");
2037 pw.println("Screen dim duration: " + screenDimDuration + " ms");
2038
Jeff Brown96307042012-07-27 15:51:34 -07002039 pw.println();
2040 pw.println("Wake Locks: size=" + mWakeLocks.size());
2041 for (WakeLock wl : mWakeLocks) {
2042 pw.println(" " + wl);
Joe Onorato8274a0e2010-10-05 17:38:09 -04002043 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05002044
Jeff Brown96307042012-07-27 15:51:34 -07002045 pw.println();
2046 pw.println("Suspend Blockers: size=" + mSuspendBlockers.size());
2047 for (SuspendBlocker sb : mSuspendBlockers) {
2048 pw.println(" " + sb);
2049 }
2050
2051 dpc = mDisplayPowerController;
2052 }
2053
2054 if (dpc != null) {
2055 dpc.dump(pw);
2056 }
2057 }
2058
2059 private SuspendBlocker createSuspendBlockerLocked(String name) {
2060 SuspendBlocker suspendBlocker = new SuspendBlockerImpl(name);
2061 mSuspendBlockers.add(suspendBlocker);
2062 return suspendBlocker;
2063 }
2064
2065 private static String wakefulnessToString(int wakefulness) {
2066 switch (wakefulness) {
2067 case WAKEFULNESS_ASLEEP:
2068 return "Asleep";
2069 case WAKEFULNESS_AWAKE:
2070 return "Awake";
2071 case WAKEFULNESS_DREAMING:
2072 return "Dreaming";
2073 case WAKEFULNESS_NAPPING:
2074 return "Napping";
2075 default:
2076 return Integer.toString(wakefulness);
2077 }
2078 }
2079
2080 private static WorkSource copyWorkSource(WorkSource workSource) {
2081 return workSource != null ? new WorkSource(workSource) : null;
2082 }
2083
2084 private final class BatteryReceiver extends BroadcastReceiver {
2085 @Override
2086 public void onReceive(Context context, Intent intent) {
2087 synchronized (mLock) {
2088 handleBatteryStateChangedLocked();
Mike Lockwoodee2b0942009-11-09 14:09:02 -05002089 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05002090 }
2091 }
2092
Jeff Brown96307042012-07-27 15:51:34 -07002093 private final class BootCompletedReceiver extends BroadcastReceiver {
2094 @Override
2095 public void onReceive(Context context, Intent intent) {
2096 synchronized (mLock) {
2097 handleBootCompletedLocked();
2098 }
Joe Onoratod28f7532010-11-06 12:56:53 -07002099 }
Jeff Brown96307042012-07-27 15:51:34 -07002100 }
2101
John Spurlockf4f6b4c2012-08-25 12:08:03 -04002102 private final class DreamReceiver extends BroadcastReceiver {
2103 @Override
2104 public void onReceive(Context context, Intent intent) {
2105 synchronized (mLock) {
Jeff Brown62c82e42012-09-26 01:30:41 -07002106 scheduleSandmanLocked();
John Spurlockf4f6b4c2012-08-25 12:08:03 -04002107 }
2108 }
2109 }
2110
Jeff Brownd4935962012-09-25 13:27:20 -07002111 private final class UserSwitchedReceiver extends BroadcastReceiver {
2112 @Override
2113 public void onReceive(Context context, Intent intent) {
2114 synchronized (mLock) {
2115 handleSettingsChangedLocked();
2116 }
2117 }
2118 }
2119
Jeff Brown96307042012-07-27 15:51:34 -07002120 private final class SettingsObserver extends ContentObserver {
2121 public SettingsObserver(Handler handler) {
2122 super(handler);
2123 }
2124
2125 @Override
2126 public void onChange(boolean selfChange, Uri uri) {
2127 synchronized (mLock) {
2128 handleSettingsChangedLocked();
2129 }
2130 }
2131 }
2132
2133 private final WindowManagerPolicy.ScreenOnListener mScreenOnListener =
2134 new WindowManagerPolicy.ScreenOnListener() {
2135 @Override
2136 public void onScreenOn() {
2137 }
2138 };
2139
2140 /**
2141 * Handler for asynchronous operations performed by the power manager.
2142 */
2143 private final class PowerManagerHandler extends Handler {
2144 public PowerManagerHandler(Looper looper) {
Jeff Browna2910d02012-08-25 12:29:46 -07002145 super(looper, null, true /*async*/);
Jeff Brown96307042012-07-27 15:51:34 -07002146 }
2147
2148 @Override
2149 public void handleMessage(Message msg) {
2150 switch (msg.what) {
2151 case MSG_USER_ACTIVITY_TIMEOUT:
2152 handleUserActivityTimeout();
2153 break;
2154 case MSG_SANDMAN:
2155 handleSandman();
2156 break;
2157 }
2158 }
2159 }
2160
2161 /**
2162 * Represents a wake lock that has been acquired by an application.
2163 */
2164 private final class WakeLock implements IBinder.DeathRecipient {
2165 public final IBinder mLock;
2166 public int mFlags;
2167 public String mTag;
2168 public WorkSource mWorkSource;
2169 public int mOwnerUid;
2170 public int mOwnerPid;
2171
2172 public WakeLock(IBinder lock, int flags, String tag, WorkSource workSource,
2173 int ownerUid, int ownerPid) {
2174 mLock = lock;
2175 mFlags = flags;
2176 mTag = tag;
2177 mWorkSource = copyWorkSource(workSource);
2178 mOwnerUid = ownerUid;
2179 mOwnerPid = ownerPid;
2180 }
2181
2182 @Override
2183 public void binderDied() {
2184 PowerManagerService.this.handleWakeLockDeath(this);
2185 }
2186
2187 public boolean hasSameProperties(int flags, String tag, WorkSource workSource,
2188 int ownerUid, int ownerPid) {
2189 return mFlags == flags
2190 && mTag.equals(tag)
2191 && hasSameWorkSource(workSource)
2192 && mOwnerUid == ownerUid
2193 && mOwnerPid == ownerPid;
2194 }
2195
2196 public void updateProperties(int flags, String tag, WorkSource workSource,
2197 int ownerUid, int ownerPid) {
2198 mFlags = flags;
2199 mTag = tag;
2200 updateWorkSource(workSource);
2201 mOwnerUid = ownerUid;
2202 mOwnerPid = ownerPid;
2203 }
2204
2205 public boolean hasSameWorkSource(WorkSource workSource) {
2206 return Objects.equal(mWorkSource, workSource);
2207 }
2208
2209 public void updateWorkSource(WorkSource workSource) {
2210 mWorkSource = copyWorkSource(workSource);
2211 }
2212
2213 @Override
2214 public String toString() {
2215 return getLockLevelString()
2216 + " '" + mTag + "'" + getLockFlagsString()
2217 + " (uid=" + mOwnerUid + ", pid=" + mOwnerPid + ", ws=" + mWorkSource + ")";
2218 }
2219
2220 private String getLockLevelString() {
2221 switch (mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
2222 case PowerManager.FULL_WAKE_LOCK:
2223 return "FULL_WAKE_LOCK ";
2224 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
2225 return "SCREEN_BRIGHT_WAKE_LOCK ";
2226 case PowerManager.SCREEN_DIM_WAKE_LOCK:
2227 return "SCREEN_DIM_WAKE_LOCK ";
2228 case PowerManager.PARTIAL_WAKE_LOCK:
2229 return "PARTIAL_WAKE_LOCK ";
2230 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
2231 return "PROXIMITY_SCREEN_OFF_WAKE_LOCK";
2232 default:
2233 return "??? ";
2234 }
2235 }
2236
2237 private String getLockFlagsString() {
2238 String result = "";
2239 if ((mFlags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {
2240 result += " ACQUIRE_CAUSES_WAKEUP";
2241 }
2242 if ((mFlags & PowerManager.ON_AFTER_RELEASE) != 0) {
2243 result += " ON_AFTER_RELEASE";
2244 }
2245 return result;
2246 }
2247 }
2248
2249 private final class SuspendBlockerImpl implements SuspendBlocker {
2250 private final String mName;
2251 private int mReferenceCount;
2252
2253 public SuspendBlockerImpl(String name) {
2254 mName = name;
2255 }
2256
2257 @Override
2258 protected void finalize() throws Throwable {
Mike Lockwood809ad0f2009-10-26 22:10:33 -04002259 try {
Jeff Brown96307042012-07-27 15:51:34 -07002260 if (mReferenceCount != 0) {
2261 Log.wtf(TAG, "Suspend blocker \"" + mName
2262 + "\" was finalized without being released!");
2263 mReferenceCount = 0;
2264 nativeReleaseSuspendBlocker(mName);
Mike Lockwood809ad0f2009-10-26 22:10:33 -04002265 }
2266 } finally {
Jeff Brown96307042012-07-27 15:51:34 -07002267 super.finalize();
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002268 }
2269 }
2270
Craig Mautner75fc9de2012-06-18 16:53:27 -07002271 @Override
Jeff Brown96307042012-07-27 15:51:34 -07002272 public void acquire() {
2273 synchronized (this) {
2274 mReferenceCount += 1;
2275 if (mReferenceCount == 1) {
2276 nativeAcquireSuspendBlocker(mName);
Craig Mautner37933682012-06-06 14:13:39 -07002277 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002278 }
2279 }
2280
Craig Mautner75fc9de2012-06-18 16:53:27 -07002281 @Override
Jeff Brown96307042012-07-27 15:51:34 -07002282 public void release() {
2283 synchronized (this) {
2284 mReferenceCount -= 1;
2285 if (mReferenceCount == 0) {
2286 nativeReleaseSuspendBlocker(mName);
2287 } else if (mReferenceCount < 0) {
2288 Log.wtf(TAG, "Suspend blocker \"" + mName
2289 + "\" was released without being acquired!", new Throwable());
2290 mReferenceCount = 0;
2291 }
2292 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002293 }
Jeff Brown96307042012-07-27 15:51:34 -07002294
2295 @Override
2296 public String toString() {
2297 synchronized (this) {
2298 return mName + ": ref count=" + mReferenceCount;
2299 }
2300 }
2301 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002302}