blob: 777ffe7c0b65c6645b794a4ada56ab89c89a6044 [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
Dianne Hackborn713df152013-05-17 11:27:57 -070019import com.android.internal.app.IAppOpsService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import com.android.internal.app.IBatteryStats;
Jeff Brown4f8ecd82012-06-18 18:29:13 -070021import com.android.server.BatteryService;
22import com.android.server.EventLogTags;
23import com.android.server.LightsService;
Jeff Brownaa202a62012-08-21 22:14:26 -070024import com.android.server.TwilightService;
Jeff Brown4f8ecd82012-06-18 18:29:13 -070025import com.android.server.Watchdog;
Jeff Brown96307042012-07-27 15:51:34 -070026import com.android.server.am.ActivityManagerService;
Jeff Brownfa25bf52012-07-23 19:26:30 -070027import com.android.server.display.DisplayManagerService;
Jeff Brown62c82e42012-09-26 01:30:41 -070028import com.android.server.dreams.DreamManagerService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029
Jeff Brown96307042012-07-27 15:51:34 -070030import android.Manifest;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import android.content.BroadcastReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.content.ContentResolver;
33import android.content.Context;
34import android.content.Intent;
35import android.content.IntentFilter;
36import android.content.pm.PackageManager;
Mike Lockwoodd7786b42009-10-15 17:09:16 -070037import android.content.res.Resources;
Doug Zongker43866e02010-01-07 12:09:54 -080038import android.database.ContentObserver;
Jeff Brown3b971592013-01-09 18:46:37 -080039import android.hardware.SensorManager;
40import android.hardware.SystemSensorManager;
Jeff Brown96307042012-07-27 15:51:34 -070041import android.net.Uri;
Amith Yamasani8b619832010-09-22 16:11:59 -070042import android.os.BatteryManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043import android.os.Binder;
44import android.os.Handler;
45import android.os.HandlerThread;
46import android.os.IBinder;
47import android.os.IPowerManager;
Jeff Brown96307042012-07-27 15:51:34 -070048import android.os.Looper;
Jim Miller92e66dd2012-02-21 18:57:12 -080049import android.os.Message;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050import android.os.PowerManager;
51import android.os.Process;
52import android.os.RemoteException;
53import android.os.SystemClock;
Nick Kralevichdbcf2d72013-04-18 14:41:40 -070054import android.os.SystemProperties;
Jeff Brown20767b22012-10-09 18:57:07 -070055import android.os.SystemService;
Jeff Brownd4935962012-09-25 13:27:20 -070056import android.os.UserHandle;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070057import android.os.WorkSource;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058import android.provider.Settings;
59import android.util.EventLog;
60import android.util.Log;
Joe Onorato8a9b2202010-02-26 18:56:32 -080061import android.util.Slog;
Jeff Brown96307042012-07-27 15:51:34 -070062import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063import android.view.WindowManagerPolicy;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064
65import java.io.FileDescriptor;
Jeff Brown7304c342012-05-11 18:42:42 -070066import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067import java.io.PrintWriter;
68import java.util.ArrayList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069
Jeff Brown96307042012-07-27 15:51:34 -070070import libcore.util.Objects;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071
Jeff Brown96307042012-07-27 15:51:34 -070072/**
73 * The power manager service is responsible for coordinating power management
74 * functions on the device.
75 */
76public final class PowerManagerService extends IPowerManager.Stub
77 implements Watchdog.Monitor {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078 private static final String TAG = "PowerManagerService";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079
Jeff Brown88c997a2012-06-22 13:57:45 -070080 private static final boolean DEBUG = false;
Jeff Brown96307042012-07-27 15:51:34 -070081 private static final boolean DEBUG_SPEW = DEBUG && true;
Jeff Brown88c997a2012-06-22 13:57:45 -070082
Jeff Brown96307042012-07-27 15:51:34 -070083 // Message: Sent when a user activity timeout occurs to update the power state.
84 private static final int MSG_USER_ACTIVITY_TIMEOUT = 1;
85 // Message: Sent when the device enters or exits a napping or dreaming state.
86 private static final int MSG_SANDMAN = 2;
Jeff Brownc38c9be2012-10-04 13:16:19 -070087 // Message: Sent when the screen on blocker is released.
88 private static final int MSG_SCREEN_ON_BLOCKER_RELEASED = 3;
Jeff Brown20767b22012-10-09 18:57:07 -070089 // Message: Sent to poll whether the boot animation has terminated.
90 private static final int MSG_CHECK_IF_BOOT_ANIMATION_FINISHED = 4;
Jeff Brown7304c342012-05-11 18:42:42 -070091
Jeff Brown96307042012-07-27 15:51:34 -070092 // Dirty bit: mWakeLocks changed
93 private static final int DIRTY_WAKE_LOCKS = 1 << 0;
94 // Dirty bit: mWakefulness changed
95 private static final int DIRTY_WAKEFULNESS = 1 << 1;
96 // Dirty bit: user activity was poked or may have timed out
97 private static final int DIRTY_USER_ACTIVITY = 1 << 2;
98 // Dirty bit: actual display power state was updated asynchronously
99 private static final int DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED = 1 << 3;
100 // Dirty bit: mBootCompleted changed
101 private static final int DIRTY_BOOT_COMPLETED = 1 << 4;
102 // Dirty bit: settings changed
103 private static final int DIRTY_SETTINGS = 1 << 5;
104 // Dirty bit: mIsPowered changed
105 private static final int DIRTY_IS_POWERED = 1 << 6;
106 // Dirty bit: mStayOn changed
107 private static final int DIRTY_STAY_ON = 1 << 7;
108 // Dirty bit: battery state changed
109 private static final int DIRTY_BATTERY_STATE = 1 << 8;
Jeff Brown93cbbb22012-10-04 13:18:36 -0700110 // Dirty bit: proximity state changed
111 private static final int DIRTY_PROXIMITY_POSITIVE = 1 << 9;
Jeff Brownc38c9be2012-10-04 13:16:19 -0700112 // Dirty bit: screen on blocker state became held or unheld
113 private static final int DIRTY_SCREEN_ON_BLOCKER_RELEASED = 1 << 10;
Jeff Brownec6aa592012-10-17 20:30:25 -0700114 // Dirty bit: dock state changed
115 private static final int DIRTY_DOCK_STATE = 1 << 11;
Jeff Brown7304c342012-05-11 18:42:42 -0700116
Jeff Brown96307042012-07-27 15:51:34 -0700117 // Wakefulness: The device is asleep and can only be awoken by a call to wakeUp().
118 // The screen should be off or in the process of being turned off by the display controller.
119 private static final int WAKEFULNESS_ASLEEP = 0;
120 // Wakefulness: The device is fully awake. It can be put to sleep by a call to goToSleep().
Jeff Brown62c82e42012-09-26 01:30:41 -0700121 // When the user activity timeout expires, the device may start napping or go to sleep.
Jeff Brown96307042012-07-27 15:51:34 -0700122 private static final int WAKEFULNESS_AWAKE = 1;
123 // Wakefulness: The device is napping. It is deciding whether to dream or go to sleep
124 // but hasn't gotten around to it yet. It can be awoken by a call to wakeUp(), which
125 // ends the nap. User activity may brighten the screen but does not end the nap.
126 private static final int WAKEFULNESS_NAPPING = 2;
127 // Wakefulness: The device is dreaming. It can be awoken by a call to wakeUp(),
128 // which ends the dream. The device goes to sleep when goToSleep() is called, when
129 // the dream ends or when unplugged.
130 // User activity may brighten the screen but does not end the dream.
131 private static final int WAKEFULNESS_DREAMING = 3;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132
Jeff Brown96307042012-07-27 15:51:34 -0700133 // Summarizes the state of all active wakelocks.
134 private static final int WAKE_LOCK_CPU = 1 << 0;
135 private static final int WAKE_LOCK_SCREEN_BRIGHT = 1 << 1;
136 private static final int WAKE_LOCK_SCREEN_DIM = 1 << 2;
137 private static final int WAKE_LOCK_BUTTON_BRIGHT = 1 << 3;
138 private static final int WAKE_LOCK_PROXIMITY_SCREEN_OFF = 1 << 4;
Jeff Brown10428742012-10-09 15:47:30 -0700139 private static final int WAKE_LOCK_STAY_AWAKE = 1 << 5; // only set if already awake
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800140
Jeff Brown96307042012-07-27 15:51:34 -0700141 // Summarizes the user activity state.
142 private static final int USER_ACTIVITY_SCREEN_BRIGHT = 1 << 0;
143 private static final int USER_ACTIVITY_SCREEN_DIM = 1 << 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144
Jeff Brown96307042012-07-27 15:51:34 -0700145 // Default and minimum screen off timeout in milliseconds.
146 private static final int DEFAULT_SCREEN_OFF_TIMEOUT = 15 * 1000;
147 private static final int MINIMUM_SCREEN_OFF_TIMEOUT = 10 * 1000;
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700148
Jeff Brownff532542012-10-02 21:18:04 -0700149 // The screen dim duration, in milliseconds.
Jeff Brown96307042012-07-27 15:51:34 -0700150 // This is subtracted from the end of the screen off timeout so the
151 // minimum screen off timeout should be longer than this.
152 private static final int SCREEN_DIM_DURATION = 7 * 1000;
Mathias Agopian47f1fe52011-11-08 17:18:41 -0800153
Jeff Brownff532542012-10-02 21:18:04 -0700154 // The maximum screen dim time expressed as a ratio relative to the screen
155 // off timeout. If the screen off timeout is very short then we want the
156 // dim timeout to also be quite short so that most of the time is spent on.
157 // Otherwise the user won't get much screen on time before dimming occurs.
158 private static final float MAXIMUM_SCREEN_DIM_RATIO = 0.2f;
159
Jeff Brown20767b22012-10-09 18:57:07 -0700160 // The name of the boot animation service in init.rc.
161 private static final String BOOT_ANIMATION_SERVICE = "bootanim";
162
163 // Poll interval in milliseconds for watching boot animation finished.
164 private static final int BOOT_ANIMATION_POLL_INTERVAL = 200;
165
Jeff Brown016ff142012-10-15 16:47:22 -0700166 // If the battery level drops by this percentage and the user activity timeout
167 // has expired, then assume the device is receiving insufficient current to charge
168 // effectively and terminate the dream.
169 private static final int DREAM_BATTERY_LEVEL_DRAIN_CUTOFF = 5;
170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 private Context mContext;
Jeff Brown96307042012-07-27 15:51:34 -0700172 private LightsService mLightsService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800173 private BatteryService mBatteryService;
Jeff Brown9e316a12012-10-08 19:17:06 -0700174 private DisplayManagerService mDisplayManagerService;
Jeff Brown96307042012-07-27 15:51:34 -0700175 private IBatteryStats mBatteryStats;
Dianne Hackborn713df152013-05-17 11:27:57 -0700176 private IAppOpsService mAppOps;
Jeff Brown96307042012-07-27 15:51:34 -0700177 private HandlerThread mHandlerThread;
178 private PowerManagerHandler mHandler;
179 private WindowManagerPolicy mPolicy;
180 private Notifier mNotifier;
181 private DisplayPowerController mDisplayPowerController;
Jeff Brown3b971592013-01-09 18:46:37 -0800182 private WirelessChargerDetector mWirelessChargerDetector;
Jeff Brown96307042012-07-27 15:51:34 -0700183 private SettingsObserver mSettingsObserver;
Jeff Brown62c82e42012-09-26 01:30:41 -0700184 private DreamManagerService mDreamManager;
Jeff Brown96307042012-07-27 15:51:34 -0700185 private LightsService.Light mAttentionLight;
Joe Onorato609695d2010-10-14 14:57:49 -0700186
Jeff Brown96307042012-07-27 15:51:34 -0700187 private final Object mLock = new Object();
188
189 // A bitfield that indicates what parts of the power state have
190 // changed and need to be recalculated.
191 private int mDirty;
192
193 // Indicates whether the device is awake or asleep or somewhere in between.
194 // This is distinct from the screen power state, which is managed separately.
195 private int mWakefulness;
196
197 // True if MSG_SANDMAN has been scheduled.
198 private boolean mSandmanScheduled;
199
200 // Table of all suspend blockers.
201 // There should only be a few of these.
202 private final ArrayList<SuspendBlocker> mSuspendBlockers = new ArrayList<SuspendBlocker>();
203
204 // Table of all wake locks acquired by applications.
205 private final ArrayList<WakeLock> mWakeLocks = new ArrayList<WakeLock>();
206
207 // A bitfield that summarizes the state of all active wakelocks.
208 private int mWakeLockSummary;
209
210 // If true, instructs the display controller to wait for the proximity sensor to
211 // go negative before turning the screen on.
212 private boolean mRequestWaitForNegativeProximity;
213
214 // Timestamp of the last time the device was awoken or put to sleep.
215 private long mLastWakeTime;
216 private long mLastSleepTime;
217
218 // True if we need to send a wake up or go to sleep finished notification
219 // when the display is ready.
220 private boolean mSendWakeUpFinishedNotificationWhenReady;
221 private boolean mSendGoToSleepFinishedNotificationWhenReady;
222
223 // Timestamp of the last call to user activity.
224 private long mLastUserActivityTime;
225 private long mLastUserActivityTimeNoChangeLights;
226
227 // A bitfield that summarizes the effect of the user activity timer.
228 // A zero value indicates that the user activity timer has expired.
229 private int mUserActivitySummary;
230
231 // The desired display power state. The actual state may lag behind the
232 // requested because it is updated asynchronously by the display power controller.
233 private final DisplayPowerRequest mDisplayPowerRequest = new DisplayPowerRequest();
234
235 // The time the screen was last turned off, in elapsedRealtime() timebase.
236 private long mLastScreenOffEventElapsedRealTime;
237
238 // True if the display power state has been fully applied, which means the display
239 // is actually on or actually off or whatever was requested.
240 private boolean mDisplayReady;
241
Jeff Brown27f7a862012-12-12 15:43:31 -0800242 // The suspend blocker used to keep the CPU alive when an application has acquired
243 // a wake lock.
244 private final SuspendBlocker mWakeLockSuspendBlocker;
245
246 // True if the wake lock suspend blocker has been acquired.
Jeff Brown96307042012-07-27 15:51:34 -0700247 private boolean mHoldingWakeLockSuspendBlocker;
248
Jeff Brown27f7a862012-12-12 15:43:31 -0800249 // The suspend blocker used to keep the CPU alive when the display is on, the
250 // display is getting ready or there is user activity (in which case the display
251 // must be on).
252 private final SuspendBlocker mDisplaySuspendBlocker;
253
254 // True if the display suspend blocker has been acquired.
255 private boolean mHoldingDisplaySuspendBlocker;
Jeff Brown96307042012-07-27 15:51:34 -0700256
Jeff Brownc38c9be2012-10-04 13:16:19 -0700257 // The screen on blocker used to keep the screen from turning on while the lock
258 // screen is coming up.
259 private final ScreenOnBlockerImpl mScreenOnBlocker;
260
Jeff Brown9e316a12012-10-08 19:17:06 -0700261 // The display blanker used to turn the screen on or off.
262 private final DisplayBlankerImpl mDisplayBlanker;
263
Jeff Brown96307042012-07-27 15:51:34 -0700264 // True if systemReady() has been called.
265 private boolean mSystemReady;
266
267 // True if boot completed occurred. We keep the screen on until this happens.
268 private boolean mBootCompleted;
269
270 // True if the device is plugged into a power source.
271 private boolean mIsPowered;
272
Jeff Brownf3fb8952012-10-02 20:57:05 -0700273 // The current plug type, such as BatteryManager.BATTERY_PLUGGED_WIRELESS.
274 private int mPlugType;
275
Jeff Brown016ff142012-10-15 16:47:22 -0700276 // The current battery level percentage.
277 private int mBatteryLevel;
278
279 // The battery level percentage at the time the dream started.
280 // This is used to terminate a dream and go to sleep if the battery is
281 // draining faster than it is charging and the user activity timeout has expired.
282 private int mBatteryLevelWhenDreamStarted;
283
Jeff Brownec6aa592012-10-17 20:30:25 -0700284 // The current dock state.
285 private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
286
Jeff Brown96307042012-07-27 15:51:34 -0700287 // True if the device should wake up when plugged or unplugged.
288 private boolean mWakeUpWhenPluggedOrUnpluggedConfig;
289
290 // True if dreams are supported on this device.
291 private boolean mDreamsSupportedConfig;
292
John Spurlocked108f32012-10-18 16:49:24 -0400293 // Default value for dreams enabled
294 private boolean mDreamsEnabledByDefaultConfig;
295
296 // Default value for dreams activate-on-sleep
297 private boolean mDreamsActivatedOnSleepByDefaultConfig;
298
299 // Default value for dreams activate-on-dock
300 private boolean mDreamsActivatedOnDockByDefaultConfig;
301
Jeff Brown96307042012-07-27 15:51:34 -0700302 // True if dreams are enabled by the user.
303 private boolean mDreamsEnabledSetting;
304
John Spurlock1a868b72012-08-22 09:56:51 -0400305 // True if dreams should be activated on sleep.
306 private boolean mDreamsActivateOnSleepSetting;
307
Jeff Brownec6aa592012-10-17 20:30:25 -0700308 // True if dreams should be activated on dock.
309 private boolean mDreamsActivateOnDockSetting;
310
Jeff Brown96307042012-07-27 15:51:34 -0700311 // The screen off timeout setting value in milliseconds.
312 private int mScreenOffTimeoutSetting;
313
314 // The maximum allowable screen off timeout according to the device
315 // administration policy. Overrides other settings.
316 private int mMaximumScreenOffTimeoutFromDeviceAdmin = Integer.MAX_VALUE;
317
318 // The stay on while plugged in setting.
319 // A bitfield of battery conditions under which to make the screen stay on.
320 private int mStayOnWhilePluggedInSetting;
321
322 // True if the device should stay on.
323 private boolean mStayOn;
324
Jeff Brown93cbbb22012-10-04 13:18:36 -0700325 // True if the proximity sensor reads a positive result.
326 private boolean mProximityPositive;
327
Jeff Brown96307042012-07-27 15:51:34 -0700328 // Screen brightness setting limits.
329 private int mScreenBrightnessSettingMinimum;
330 private int mScreenBrightnessSettingMaximum;
331 private int mScreenBrightnessSettingDefault;
332
333 // The screen brightness setting, from 0 to 255.
334 // Use -1 if no value has been set.
335 private int mScreenBrightnessSetting;
336
Jeff Brown330560f2012-08-21 22:10:57 -0700337 // The screen auto-brightness adjustment setting, from -1 to 1.
338 // Use 0 if there is no adjustment.
339 private float mScreenAutoBrightnessAdjustmentSetting;
340
Jeff Brown96307042012-07-27 15:51:34 -0700341 // The screen brightness mode.
342 // One of the Settings.System.SCREEN_BRIGHTNESS_MODE_* constants.
343 private int mScreenBrightnessModeSetting;
344
345 // The screen brightness setting override from the window manager
346 // to allow the current foreground activity to override the brightness.
347 // Use -1 to disable.
348 private int mScreenBrightnessOverrideFromWindowManager = -1;
349
Jeff Brown1e3b98d2012-09-30 18:58:59 -0700350 // The user activity timeout override from the window manager
351 // to allow the current foreground activity to override the user activity timeout.
352 // Use -1 to disable.
353 private long mUserActivityTimeoutOverrideFromWindowManager = -1;
354
Jeff Brown96307042012-07-27 15:51:34 -0700355 // The screen brightness setting override from the settings application
356 // to temporarily adjust the brightness until next updated,
357 // Use -1 to disable.
358 private int mTemporaryScreenBrightnessSettingOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800359
Jeff Brown330560f2012-08-21 22:10:57 -0700360 // The screen brightness adjustment setting override from the settings
361 // application to temporarily adjust the auto-brightness adjustment factor
362 // until next updated, in the range -1..1.
363 // Use NaN to disable.
364 private float mTemporaryScreenAutoBrightnessAdjustmentSettingOverride = Float.NaN;
365
Jeff Brown9ba8d782012-10-01 16:38:23 -0700366 // Time when we last logged a warning about calling userActivity() without permission.
367 private long mLastWarningAboutUserActivityPermission = Long.MIN_VALUE;
368
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700369 private native void nativeInit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800370
Jeff Brown96307042012-07-27 15:51:34 -0700371 private static native void nativeSetPowerState(boolean screenOn, boolean screenBright);
372 private static native void nativeAcquireSuspendBlocker(String name);
373 private static native void nativeReleaseSuspendBlocker(String name);
Jeff Brown9e316a12012-10-08 19:17:06 -0700374 private static native void nativeSetInteractive(boolean enable);
375 private static native void nativeSetAutoSuspend(boolean enable);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800376
Jeff Brown4f8ecd82012-06-18 18:29:13 -0700377 public PowerManagerService() {
Jeff Brown96307042012-07-27 15:51:34 -0700378 synchronized (mLock) {
Jeff Brown27f7a862012-12-12 15:43:31 -0800379 mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks");
380 mDisplaySuspendBlocker = createSuspendBlockerLocked("PowerManagerService.Display");
381 mDisplaySuspendBlocker.acquire();
382 mHoldingDisplaySuspendBlocker = true;
383
Jeff Brownc38c9be2012-10-04 13:16:19 -0700384 mScreenOnBlocker = new ScreenOnBlockerImpl();
Jeff Brown9e316a12012-10-08 19:17:06 -0700385 mDisplayBlanker = new DisplayBlankerImpl();
Jeff Brown96307042012-07-27 15:51:34 -0700386 mWakefulness = WAKEFULNESS_AWAKE;
387 }
Jeff Brown7304c342012-05-11 18:42:42 -0700388
389 nativeInit();
Jeff Brownf75724b2012-08-25 13:34:32 -0700390 nativeSetPowerState(true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800391 }
392
Jeff Brown96307042012-07-27 15:51:34 -0700393 /**
394 * Initialize the power manager.
395 * Must be called before any other functions within the power manager are called.
396 */
397 public void init(Context context, LightsService ls,
398 ActivityManagerService am, BatteryService bs, IBatteryStats bss,
Dianne Hackborn713df152013-05-17 11:27:57 -0700399 IAppOpsService appOps, DisplayManagerService dm) {
Jeff Brown9e316a12012-10-08 19:17:06 -0700400 mContext = context;
401 mLightsService = ls;
402 mBatteryService = bs;
403 mBatteryStats = bss;
Dianne Hackborn713df152013-05-17 11:27:57 -0700404 mAppOps = appOps;
Jeff Brown9e316a12012-10-08 19:17:06 -0700405 mDisplayManagerService = dm;
406 mHandlerThread = new HandlerThread(TAG);
407 mHandlerThread.start();
408 mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
409
410 Watchdog.getInstance().addMonitor(this);
Dianne Hackbornfa012b32013-05-10 15:23:28 -0700411 Watchdog.getInstance().addThread(mHandler, mHandlerThread.getName());
Jeff Brown9e316a12012-10-08 19:17:06 -0700412
Jeff Brownf75724b2012-08-25 13:34:32 -0700413 // Forcibly turn the screen on at boot so that it is in a known power state.
414 // We do this in init() rather than in the constructor because setting the
415 // screen state requires a call into surface flinger which then needs to call back
416 // into the activity manager to check permissions. Unfortunately the
417 // activity manager is not running when the constructor is called, so we
418 // have to defer setting the screen state until this point.
Jeff Brown9e316a12012-10-08 19:17:06 -0700419 mDisplayBlanker.unblankAllDisplays();
Jeff Brown96307042012-07-27 15:51:34 -0700420 }
Jim Miller92e66dd2012-02-21 18:57:12 -0800421
Jeff Brown96307042012-07-27 15:51:34 -0700422 public void setPolicy(WindowManagerPolicy policy) {
423 synchronized (mLock) {
424 mPolicy = policy;
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700425 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800426 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800427
Jeff Brown62c82e42012-09-26 01:30:41 -0700428 public void systemReady(TwilightService twilight, DreamManagerService dreamManager) {
Jeff Brown96307042012-07-27 15:51:34 -0700429 synchronized (mLock) {
430 mSystemReady = true;
Jeff Brown62c82e42012-09-26 01:30:41 -0700431 mDreamManager = dreamManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800432
Jeff Brown96307042012-07-27 15:51:34 -0700433 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
434 mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting();
435 mScreenBrightnessSettingMaximum = pm.getMaximumScreenBrightnessSetting();
436 mScreenBrightnessSettingDefault = pm.getDefaultScreenBrightnessSetting();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800437
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -0700438 SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper());
Jeff Brown3b971592013-01-09 18:46:37 -0800439
Jeff Brownc38c9be2012-10-04 13:16:19 -0700440 // The notifier runs on the system server's main looper so as not to interfere
441 // with the animations and other critical functions of the power manager.
442 mNotifier = new Notifier(Looper.getMainLooper(), mContext, mBatteryStats,
Dianne Hackborn713df152013-05-17 11:27:57 -0700443 mAppOps, createSuspendBlockerLocked("PowerManagerService.Broadcasts"),
Jeff Brownc38c9be2012-10-04 13:16:19 -0700444 mScreenOnBlocker, mPolicy);
445
446 // The display power controller runs on the power manager service's
Jeff Brown3b971592013-01-09 18:46:37 -0800447 // own handler thread to ensure timely operation.
Jeff Brown96307042012-07-27 15:51:34 -0700448 mDisplayPowerController = new DisplayPowerController(mHandler.getLooper(),
Jeff Brown3b971592013-01-09 18:46:37 -0800449 mContext, mNotifier, mLightsService, twilight, sensorManager,
450 mDisplayManagerService, mDisplayBlanker,
451 mDisplayPowerControllerCallbacks, mHandler);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800452
Jeff Brown3b971592013-01-09 18:46:37 -0800453 mWirelessChargerDetector = new WirelessChargerDetector(sensorManager,
454 createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector"));
Jeff Brown96307042012-07-27 15:51:34 -0700455 mSettingsObserver = new SettingsObserver(mHandler);
456 mAttentionLight = mLightsService.getLight(LightsService.LIGHT_ID_ATTENTION);
Mike Lockwoodaa66ea82009-10-31 16:31:27 -0400457
Jeff Brown96307042012-07-27 15:51:34 -0700458 // Register for broadcasts from other components of the system.
459 IntentFilter filter = new IntentFilter();
460 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
Jeff Brownd4935962012-09-25 13:27:20 -0700461 mContext.registerReceiver(new BatteryReceiver(), filter, null, mHandler);
Joe Onoratob08a1af2010-10-11 19:28:58 -0700462
Jeff Brown96307042012-07-27 15:51:34 -0700463 filter = new IntentFilter();
464 filter.addAction(Intent.ACTION_BOOT_COMPLETED);
Jeff Brownd4935962012-09-25 13:27:20 -0700465 mContext.registerReceiver(new BootCompletedReceiver(), filter, null, mHandler);
Jeff Brown96307042012-07-27 15:51:34 -0700466
467 filter = new IntentFilter();
Dianne Hackbornbe87e2f2012-09-28 16:31:34 -0700468 filter.addAction(Intent.ACTION_DREAMING_STARTED);
469 filter.addAction(Intent.ACTION_DREAMING_STOPPED);
Jeff Brownd4935962012-09-25 13:27:20 -0700470 mContext.registerReceiver(new DreamReceiver(), filter, null, mHandler);
471
472 filter = new IntentFilter();
473 filter.addAction(Intent.ACTION_USER_SWITCHED);
474 mContext.registerReceiver(new UserSwitchedReceiver(), filter, null, mHandler);
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400475
Jeff Brownec6aa592012-10-17 20:30:25 -0700476 filter = new IntentFilter();
477 filter.addAction(Intent.ACTION_DOCK_EVENT);
478 mContext.registerReceiver(new DockReceiver(), filter, null, mHandler);
479
Jeff Brown96307042012-07-27 15:51:34 -0700480 // Register for settings changes.
481 final ContentResolver resolver = mContext.getContentResolver();
482 resolver.registerContentObserver(Settings.Secure.getUriFor(
Jeff Brownd4935962012-09-25 13:27:20 -0700483 Settings.Secure.SCREENSAVER_ENABLED),
484 false, mSettingsObserver, UserHandle.USER_ALL);
John Spurlock1a868b72012-08-22 09:56:51 -0400485 resolver.registerContentObserver(Settings.Secure.getUriFor(
Jeff Brownd4935962012-09-25 13:27:20 -0700486 Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP),
487 false, mSettingsObserver, UserHandle.USER_ALL);
Jeff Brownec6aa592012-10-17 20:30:25 -0700488 resolver.registerContentObserver(Settings.Secure.getUriFor(
489 Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK),
490 false, mSettingsObserver, UserHandle.USER_ALL);
Jeff Brown96307042012-07-27 15:51:34 -0700491 resolver.registerContentObserver(Settings.System.getUriFor(
Jeff Brownd4935962012-09-25 13:27:20 -0700492 Settings.System.SCREEN_OFF_TIMEOUT),
493 false, mSettingsObserver, UserHandle.USER_ALL);
Christopher Tatead735322012-09-07 14:19:43 -0700494 resolver.registerContentObserver(Settings.Global.getUriFor(
Jeff Brownd4935962012-09-25 13:27:20 -0700495 Settings.Global.STAY_ON_WHILE_PLUGGED_IN),
496 false, mSettingsObserver, UserHandle.USER_ALL);
Jeff Brown96307042012-07-27 15:51:34 -0700497 resolver.registerContentObserver(Settings.System.getUriFor(
Jeff Brownd4935962012-09-25 13:27:20 -0700498 Settings.System.SCREEN_BRIGHTNESS),
499 false, mSettingsObserver, UserHandle.USER_ALL);
Jeff Brown96307042012-07-27 15:51:34 -0700500 resolver.registerContentObserver(Settings.System.getUriFor(
Jeff Brownd4935962012-09-25 13:27:20 -0700501 Settings.System.SCREEN_BRIGHTNESS_MODE),
502 false, mSettingsObserver, UserHandle.USER_ALL);
Jeff Brown96307042012-07-27 15:51:34 -0700503
504 // Go.
505 readConfigurationLocked();
506 updateSettingsLocked();
507 mDirty |= DIRTY_BATTERY_STATE;
508 updatePowerStateLocked();
509 }
510 }
511
512 private void readConfigurationLocked() {
513 final Resources resources = mContext.getResources();
514
515 mWakeUpWhenPluggedOrUnpluggedConfig = resources.getBoolean(
Joe Onorato6d747652010-10-11 15:15:31 -0700516 com.android.internal.R.bool.config_unplugTurnsOnScreen);
Jeff Brown96307042012-07-27 15:51:34 -0700517 mDreamsSupportedConfig = resources.getBoolean(
John Spurlocked108f32012-10-18 16:49:24 -0400518 com.android.internal.R.bool.config_dreamsSupported);
519 mDreamsEnabledByDefaultConfig = resources.getBoolean(
520 com.android.internal.R.bool.config_dreamsEnabledByDefault);
521 mDreamsActivatedOnSleepByDefaultConfig = resources.getBoolean(
522 com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault);
523 mDreamsActivatedOnDockByDefaultConfig = resources.getBoolean(
524 com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800525 }
526
Jeff Brown96307042012-07-27 15:51:34 -0700527 private void updateSettingsLocked() {
528 final ContentResolver resolver = mContext.getContentResolver();
Jeff Brown7304c342012-05-11 18:42:42 -0700529
Jeff Brownd4935962012-09-25 13:27:20 -0700530 mDreamsEnabledSetting = (Settings.Secure.getIntForUser(resolver,
John Spurlocked108f32012-10-18 16:49:24 -0400531 Settings.Secure.SCREENSAVER_ENABLED,
532 mDreamsEnabledByDefaultConfig ? 1 : 0,
Jeff Brownd4935962012-09-25 13:27:20 -0700533 UserHandle.USER_CURRENT) != 0);
534 mDreamsActivateOnSleepSetting = (Settings.Secure.getIntForUser(resolver,
John Spurlocked108f32012-10-18 16:49:24 -0400535 Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
536 mDreamsActivatedOnSleepByDefaultConfig ? 1 : 0,
Jeff Brownd4935962012-09-25 13:27:20 -0700537 UserHandle.USER_CURRENT) != 0);
Jeff Brownec6aa592012-10-17 20:30:25 -0700538 mDreamsActivateOnDockSetting = (Settings.Secure.getIntForUser(resolver,
John Spurlocked108f32012-10-18 16:49:24 -0400539 Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
540 mDreamsActivatedOnDockByDefaultConfig ? 1 : 0,
Jeff Brownec6aa592012-10-17 20:30:25 -0700541 UserHandle.USER_CURRENT) != 0);
Jeff Brownd4935962012-09-25 13:27:20 -0700542 mScreenOffTimeoutSetting = Settings.System.getIntForUser(resolver,
543 Settings.System.SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT,
544 UserHandle.USER_CURRENT);
Christopher Tatead735322012-09-07 14:19:43 -0700545 mStayOnWhilePluggedInSetting = Settings.Global.getInt(resolver,
Jeff Brownd4935962012-09-25 13:27:20 -0700546 Settings.Global.STAY_ON_WHILE_PLUGGED_IN, BatteryManager.BATTERY_PLUGGED_AC);
Jeff Brown7304c342012-05-11 18:42:42 -0700547
Jeff Brown96307042012-07-27 15:51:34 -0700548 final int oldScreenBrightnessSetting = mScreenBrightnessSetting;
Jeff Brownd4935962012-09-25 13:27:20 -0700549 mScreenBrightnessSetting = Settings.System.getIntForUser(resolver,
550 Settings.System.SCREEN_BRIGHTNESS, mScreenBrightnessSettingDefault,
551 UserHandle.USER_CURRENT);
Jeff Brown96307042012-07-27 15:51:34 -0700552 if (oldScreenBrightnessSetting != mScreenBrightnessSetting) {
553 mTemporaryScreenBrightnessSettingOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800554 }
Jeff Brown96307042012-07-27 15:51:34 -0700555
Jeff Brown330560f2012-08-21 22:10:57 -0700556 final float oldScreenAutoBrightnessAdjustmentSetting =
557 mScreenAutoBrightnessAdjustmentSetting;
Jeff Brownd4935962012-09-25 13:27:20 -0700558 mScreenAutoBrightnessAdjustmentSetting = Settings.System.getFloatForUser(resolver,
559 Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f,
560 UserHandle.USER_CURRENT);
Jeff Brown330560f2012-08-21 22:10:57 -0700561 if (oldScreenAutoBrightnessAdjustmentSetting != mScreenAutoBrightnessAdjustmentSetting) {
Jeff Brown5d03a532012-08-22 13:22:02 -0700562 mTemporaryScreenAutoBrightnessAdjustmentSettingOverride = Float.NaN;
Jeff Brown330560f2012-08-21 22:10:57 -0700563 }
564
Jeff Brownd4935962012-09-25 13:27:20 -0700565 mScreenBrightnessModeSetting = Settings.System.getIntForUser(resolver,
Jeff Brown96307042012-07-27 15:51:34 -0700566 Settings.System.SCREEN_BRIGHTNESS_MODE,
Jeff Brownd4935962012-09-25 13:27:20 -0700567 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, UserHandle.USER_CURRENT);
Jeff Brown96307042012-07-27 15:51:34 -0700568
569 mDirty |= DIRTY_SETTINGS;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800570 }
571
Jeff Brown96307042012-07-27 15:51:34 -0700572 private void handleSettingsChangedLocked() {
573 updateSettingsLocked();
574 updatePowerStateLocked();
575 }
576
577 @Override // Binder call
Dianne Hackborn713df152013-05-17 11:27:57 -0700578 public void acquireWakeLock(IBinder lock, int flags, String tag, String packageName,
579 WorkSource ws) {
Jeff Brown96307042012-07-27 15:51:34 -0700580 if (lock == null) {
581 throw new IllegalArgumentException("lock must not be null");
582 }
Dianne Hackborn713df152013-05-17 11:27:57 -0700583 if (packageName == null) {
584 throw new IllegalArgumentException("packageName must not be null");
585 }
Jeff Brown96307042012-07-27 15:51:34 -0700586 PowerManager.validateWakeLockParameters(flags, tag);
587
588 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
589 if (ws != null && ws.size() != 0) {
590 mContext.enforceCallingOrSelfPermission(
591 android.Manifest.permission.UPDATE_DEVICE_STATS, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800592 } else {
Jeff Brown96307042012-07-27 15:51:34 -0700593 ws = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800594 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800595
Jeff Brown96307042012-07-27 15:51:34 -0700596 final int uid = Binder.getCallingUid();
597 final int pid = Binder.getCallingPid();
598 final long ident = Binder.clearCallingIdentity();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800599 try {
Dianne Hackborn713df152013-05-17 11:27:57 -0700600 acquireWakeLockInternal(lock, flags, tag, packageName, ws, uid, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800601 } finally {
602 Binder.restoreCallingIdentity(ident);
603 }
604 }
605
Dianne Hackborn713df152013-05-17 11:27:57 -0700606 private void acquireWakeLockInternal(IBinder lock, int flags, String tag, String packageName,
607 WorkSource ws, int uid, int pid) {
Jeff Brown96307042012-07-27 15:51:34 -0700608 synchronized (mLock) {
609 if (DEBUG_SPEW) {
610 Slog.d(TAG, "acquireWakeLockInternal: lock=" + Objects.hashCode(lock)
611 + ", flags=0x" + Integer.toHexString(flags)
612 + ", tag=\"" + tag + "\", ws=" + ws + ", uid=" + uid + ", pid=" + pid);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700613 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800614
Jeff Brown96307042012-07-27 15:51:34 -0700615 WakeLock wakeLock;
616 int index = findWakeLockIndexLocked(lock);
617 if (index >= 0) {
618 wakeLock = mWakeLocks.get(index);
619 if (!wakeLock.hasSameProperties(flags, tag, ws, uid, pid)) {
620 // Update existing wake lock. This shouldn't happen but is harmless.
621 notifyWakeLockReleasedLocked(wakeLock);
Dianne Hackborn713df152013-05-17 11:27:57 -0700622 wakeLock.updateProperties(flags, tag, packageName, ws, uid, pid);
Jeff Brown96307042012-07-27 15:51:34 -0700623 notifyWakeLockAcquiredLocked(wakeLock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800624 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800625 } else {
Dianne Hackborn713df152013-05-17 11:27:57 -0700626 wakeLock = new WakeLock(lock, flags, tag, packageName, ws, uid, pid);
Jeff Brown96307042012-07-27 15:51:34 -0700627 try {
628 lock.linkToDeath(wakeLock, 0);
629 } catch (RemoteException ex) {
630 throw new IllegalArgumentException("Wake lock is already dead.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800631 }
Jeff Brown96307042012-07-27 15:51:34 -0700632 notifyWakeLockAcquiredLocked(wakeLock);
633 mWakeLocks.add(wakeLock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800634 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800635
Jeff Brown96307042012-07-27 15:51:34 -0700636 applyWakeLockFlagsOnAcquireLocked(wakeLock);
637 mDirty |= DIRTY_WAKE_LOCKS;
638 updatePowerStateLocked();
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700639 }
640 }
641
Craig Mautner6edb6db2012-11-20 18:21:12 -0800642 private static boolean isScreenLock(final WakeLock wakeLock) {
643 switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
644 case PowerManager.FULL_WAKE_LOCK:
645 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
646 case PowerManager.SCREEN_DIM_WAKE_LOCK:
647 return true;
648 }
649 return false;
650 }
651
Jeff Brown96307042012-07-27 15:51:34 -0700652 private void applyWakeLockFlagsOnAcquireLocked(WakeLock wakeLock) {
Craig Mautner6edb6db2012-11-20 18:21:12 -0800653 if ((wakeLock.mFlags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0 &&
654 isScreenLock(wakeLock)) {
Jeff Brown96307042012-07-27 15:51:34 -0700655 wakeUpNoUpdateLocked(SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800656 }
657 }
658
Jeff Brown96307042012-07-27 15:51:34 -0700659 @Override // Binder call
Mike Lockwood0e39ea82009-11-18 15:37:10 -0500660 public void releaseWakeLock(IBinder lock, int flags) {
Jeff Brown96307042012-07-27 15:51:34 -0700661 if (lock == null) {
662 throw new IllegalArgumentException("lock must not be null");
Michael Chane96440f2009-05-06 10:27:36 -0700663 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800664
Jeff Brown96307042012-07-27 15:51:34 -0700665 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
666
667 final long ident = Binder.clearCallingIdentity();
668 try {
669 releaseWakeLockInternal(lock, flags);
670 } finally {
671 Binder.restoreCallingIdentity(ident);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800672 }
673 }
674
Jeff Brown96307042012-07-27 15:51:34 -0700675 private void releaseWakeLockInternal(IBinder lock, int flags) {
676 synchronized (mLock) {
Jeff Brown96307042012-07-27 15:51:34 -0700677 int index = findWakeLockIndexLocked(lock);
678 if (index < 0) {
Jeff Brown27f7a862012-12-12 15:43:31 -0800679 if (DEBUG_SPEW) {
680 Slog.d(TAG, "releaseWakeLockInternal: lock=" + Objects.hashCode(lock)
681 + " [not found], flags=0x" + Integer.toHexString(flags));
682 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800683 return;
684 }
Mike Lockwood3333fa42009-10-26 14:50:42 -0400685
Jeff Brown96307042012-07-27 15:51:34 -0700686 WakeLock wakeLock = mWakeLocks.get(index);
Jeff Brown27f7a862012-12-12 15:43:31 -0800687 if (DEBUG_SPEW) {
688 Slog.d(TAG, "releaseWakeLockInternal: lock=" + Objects.hashCode(lock)
689 + " [" + wakeLock.mTag + "], flags=0x" + Integer.toHexString(flags));
690 }
691
Jeff Brown96307042012-07-27 15:51:34 -0700692 mWakeLocks.remove(index);
693 notifyWakeLockReleasedLocked(wakeLock);
694 wakeLock.mLock.unlinkToDeath(wakeLock, 0);
695
696 if ((flags & PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE) != 0) {
697 mRequestWaitForNegativeProximity = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800698 }
699
Jeff Brown96307042012-07-27 15:51:34 -0700700 applyWakeLockFlagsOnReleaseLocked(wakeLock);
701 mDirty |= DIRTY_WAKE_LOCKS;
702 updatePowerStateLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800703 }
704 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700705
Jeff Brown96307042012-07-27 15:51:34 -0700706 private void handleWakeLockDeath(WakeLock wakeLock) {
707 synchronized (mLock) {
708 if (DEBUG_SPEW) {
Jeff Brown27f7a862012-12-12 15:43:31 -0800709 Slog.d(TAG, "handleWakeLockDeath: lock=" + Objects.hashCode(wakeLock.mLock)
710 + " [" + wakeLock.mTag + "]");
Jeff Brown96307042012-07-27 15:51:34 -0700711 }
712
713 int index = mWakeLocks.indexOf(wakeLock);
714 if (index < 0) {
715 return;
716 }
717
718 mWakeLocks.remove(index);
719 notifyWakeLockReleasedLocked(wakeLock);
720
721 applyWakeLockFlagsOnReleaseLocked(wakeLock);
722 mDirty |= DIRTY_WAKE_LOCKS;
723 updatePowerStateLocked();
Mike Lockwood3a74bd32011-08-12 13:55:22 -0700724 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700725 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800726
Jeff Brown96307042012-07-27 15:51:34 -0700727 private void applyWakeLockFlagsOnReleaseLocked(WakeLock wakeLock) {
728 if ((wakeLock.mFlags & PowerManager.ON_AFTER_RELEASE) != 0) {
729 userActivityNoUpdateLocked(SystemClock.uptimeMillis(),
730 PowerManager.USER_ACTIVITY_EVENT_OTHER,
731 PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS,
732 wakeLock.mOwnerUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800733 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800734 }
735
Jeff Brown96307042012-07-27 15:51:34 -0700736 @Override // Binder call
737 public void updateWakeLockWorkSource(IBinder lock, WorkSource ws) {
738 if (lock == null) {
739 throw new IllegalArgumentException("lock must not be null");
740 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800741
Jeff Brown96307042012-07-27 15:51:34 -0700742 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
743 if (ws != null && ws.size() != 0) {
744 mContext.enforceCallingOrSelfPermission(
745 android.Manifest.permission.UPDATE_DEVICE_STATS, null);
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700746 } else {
Jeff Brown96307042012-07-27 15:51:34 -0700747 ws = null;
748 }
749
750 final long ident = Binder.clearCallingIdentity();
751 try {
752 updateWakeLockWorkSourceInternal(lock, ws);
753 } finally {
754 Binder.restoreCallingIdentity(ident);
755 }
756 }
757
758 private void updateWakeLockWorkSourceInternal(IBinder lock, WorkSource ws) {
759 synchronized (mLock) {
760 int index = findWakeLockIndexLocked(lock);
761 if (index < 0) {
Jeff Brown27f7a862012-12-12 15:43:31 -0800762 if (DEBUG_SPEW) {
763 Slog.d(TAG, "updateWakeLockWorkSourceInternal: lock=" + Objects.hashCode(lock)
764 + " [not found], ws=" + ws);
765 }
Jeff Brown96307042012-07-27 15:51:34 -0700766 throw new IllegalArgumentException("Wake lock not active");
767 }
768
769 WakeLock wakeLock = mWakeLocks.get(index);
Jeff Brown27f7a862012-12-12 15:43:31 -0800770 if (DEBUG_SPEW) {
771 Slog.d(TAG, "updateWakeLockWorkSourceInternal: lock=" + Objects.hashCode(lock)
772 + " [" + wakeLock.mTag + "], ws=" + ws);
773 }
774
Jeff Brown96307042012-07-27 15:51:34 -0700775 if (!wakeLock.hasSameWorkSource(ws)) {
776 notifyWakeLockReleasedLocked(wakeLock);
777 wakeLock.updateWorkSource(ws);
778 notifyWakeLockAcquiredLocked(wakeLock);
779 }
780 }
781 }
782
783 private int findWakeLockIndexLocked(IBinder lock) {
784 final int count = mWakeLocks.size();
785 for (int i = 0; i < count; i++) {
786 if (mWakeLocks.get(i).mLock == lock) {
787 return i;
788 }
789 }
790 return -1;
791 }
792
793 private void notifyWakeLockAcquiredLocked(WakeLock wakeLock) {
794 if (mSystemReady) {
Dianne Hackborn713df152013-05-17 11:27:57 -0700795 wakeLock.mNotifiedAcquired = true;
796 mNotifier.onWakeLockAcquired(wakeLock.mFlags, wakeLock.mTag, wakeLock.mPackageName,
Jeff Brown96307042012-07-27 15:51:34 -0700797 wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource);
798 }
799 }
800
801 private void notifyWakeLockReleasedLocked(WakeLock wakeLock) {
Dianne Hackborn713df152013-05-17 11:27:57 -0700802 if (mSystemReady && wakeLock.mNotifiedAcquired) {
803 wakeLock.mNotifiedAcquired = false;
804 mNotifier.onWakeLockReleased(wakeLock.mFlags, wakeLock.mTag, wakeLock.mPackageName,
Jeff Brown96307042012-07-27 15:51:34 -0700805 wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource);
806 }
807 }
808
809 @Override // Binder call
810 public boolean isWakeLockLevelSupported(int level) {
811 final long ident = Binder.clearCallingIdentity();
812 try {
813 return isWakeLockLevelSupportedInternal(level);
814 } finally {
815 Binder.restoreCallingIdentity(ident);
816 }
817 }
818
819 private boolean isWakeLockLevelSupportedInternal(int level) {
820 synchronized (mLock) {
821 switch (level) {
822 case PowerManager.PARTIAL_WAKE_LOCK:
823 case PowerManager.SCREEN_DIM_WAKE_LOCK:
824 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
825 case PowerManager.FULL_WAKE_LOCK:
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700826 return true;
Jeff Brown96307042012-07-27 15:51:34 -0700827
828 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
829 return mSystemReady && mDisplayPowerController.isProximitySensorAvailable();
830
831 default:
832 return false;
833 }
834 }
835 }
836
837 @Override // Binder call
838 public void userActivity(long eventTime, int event, int flags) {
Jeff Brown9ba8d782012-10-01 16:38:23 -0700839 final long now = SystemClock.uptimeMillis();
840 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER)
841 != PackageManager.PERMISSION_GRANTED) {
842 // Once upon a time applications could call userActivity().
843 // Now we require the DEVICE_POWER permission. Log a warning and ignore the
844 // request instead of throwing a SecurityException so we don't break old apps.
845 synchronized (mLock) {
846 if (now >= mLastWarningAboutUserActivityPermission + (5 * 60 * 1000)) {
847 mLastWarningAboutUserActivityPermission = now;
848 Slog.w(TAG, "Ignoring call to PowerManager.userActivity() because the "
849 + "caller does not have DEVICE_POWER permission. "
850 + "Please fix your app! "
851 + " pid=" + Binder.getCallingPid()
852 + " uid=" + Binder.getCallingUid());
853 }
854 }
855 return;
856 }
857
Jeff Brown96307042012-07-27 15:51:34 -0700858 if (eventTime > SystemClock.uptimeMillis()) {
859 throw new IllegalArgumentException("event time must not be in the future");
860 }
861
Jeff Brown96307042012-07-27 15:51:34 -0700862 final int uid = Binder.getCallingUid();
863 final long ident = Binder.clearCallingIdentity();
864 try {
865 userActivityInternal(eventTime, event, flags, uid);
866 } finally {
867 Binder.restoreCallingIdentity(ident);
868 }
869 }
870
871 // Called from native code.
872 private void userActivityFromNative(long eventTime, int event, int flags) {
873 userActivityInternal(eventTime, event, flags, Process.SYSTEM_UID);
874 }
875
876 private void userActivityInternal(long eventTime, int event, int flags, int uid) {
877 synchronized (mLock) {
878 if (userActivityNoUpdateLocked(eventTime, event, flags, uid)) {
879 updatePowerStateLocked();
880 }
881 }
882 }
883
884 private boolean userActivityNoUpdateLocked(long eventTime, int event, int flags, int uid) {
885 if (DEBUG_SPEW) {
886 Slog.d(TAG, "userActivityNoUpdateLocked: eventTime=" + eventTime
887 + ", event=" + event + ", flags=0x" + Integer.toHexString(flags)
888 + ", uid=" + uid);
889 }
890
891 if (eventTime < mLastSleepTime || eventTime < mLastWakeTime
892 || mWakefulness == WAKEFULNESS_ASLEEP || !mBootCompleted || !mSystemReady) {
893 return false;
894 }
895
896 mNotifier.onUserActivity(event, uid);
897
898 if ((flags & PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS) != 0) {
899 if (eventTime > mLastUserActivityTimeNoChangeLights
900 && eventTime > mLastUserActivityTime) {
901 mLastUserActivityTimeNoChangeLights = eventTime;
902 mDirty |= DIRTY_USER_ACTIVITY;
903 return true;
904 }
905 } else {
906 if (eventTime > mLastUserActivityTime) {
907 mLastUserActivityTime = eventTime;
908 mDirty |= DIRTY_USER_ACTIVITY;
909 return true;
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700910 }
911 }
912 return false;
913 }
914
Jeff Brown96307042012-07-27 15:51:34 -0700915 @Override // Binder call
916 public void wakeUp(long eventTime) {
917 if (eventTime > SystemClock.uptimeMillis()) {
918 throw new IllegalArgumentException("event time must not be in the future");
919 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700920
Jeff Brown96307042012-07-27 15:51:34 -0700921 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
922
923 final long ident = Binder.clearCallingIdentity();
924 try {
925 wakeUpInternal(eventTime);
926 } finally {
927 Binder.restoreCallingIdentity(ident);
928 }
929 }
930
931 // Called from native code.
932 private void wakeUpFromNative(long eventTime) {
933 wakeUpInternal(eventTime);
934 }
935
936 private void wakeUpInternal(long eventTime) {
937 synchronized (mLock) {
938 if (wakeUpNoUpdateLocked(eventTime)) {
939 updatePowerStateLocked();
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700940 }
941 }
Jeff Brown96307042012-07-27 15:51:34 -0700942 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700943
Jeff Brown96307042012-07-27 15:51:34 -0700944 private boolean wakeUpNoUpdateLocked(long eventTime) {
945 if (DEBUG_SPEW) {
946 Slog.d(TAG, "wakeUpNoUpdateLocked: eventTime=" + eventTime);
Joe Onorato60607a92010-10-23 14:49:30 -0700947 }
Jeff Brown96307042012-07-27 15:51:34 -0700948
949 if (eventTime < mLastSleepTime || mWakefulness == WAKEFULNESS_AWAKE
950 || !mBootCompleted || !mSystemReady) {
951 return false;
952 }
953
954 switch (mWakefulness) {
955 case WAKEFULNESS_ASLEEP:
956 Slog.i(TAG, "Waking up from sleep...");
Jeff Brown54308352012-10-04 17:59:58 -0700957 sendPendingNotificationsLocked();
Jeff Brown96307042012-07-27 15:51:34 -0700958 mNotifier.onWakeUpStarted();
959 mSendWakeUpFinishedNotificationWhenReady = true;
Jeff Brown96307042012-07-27 15:51:34 -0700960 break;
961 case WAKEFULNESS_DREAMING:
962 Slog.i(TAG, "Waking up from dream...");
963 break;
964 case WAKEFULNESS_NAPPING:
965 Slog.i(TAG, "Waking up from nap...");
966 break;
967 }
968
969 mLastWakeTime = eventTime;
970 mWakefulness = WAKEFULNESS_AWAKE;
971 mDirty |= DIRTY_WAKEFULNESS;
972
973 userActivityNoUpdateLocked(
974 eventTime, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
975 return true;
976 }
977
978 @Override // Binder call
979 public void goToSleep(long eventTime, int reason) {
980 if (eventTime > SystemClock.uptimeMillis()) {
981 throw new IllegalArgumentException("event time must not be in the future");
982 }
983
984 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
985
986 final long ident = Binder.clearCallingIdentity();
987 try {
988 goToSleepInternal(eventTime, reason);
989 } finally {
990 Binder.restoreCallingIdentity(ident);
991 }
992 }
993
994 // Called from native code.
995 private void goToSleepFromNative(long eventTime, int reason) {
996 goToSleepInternal(eventTime, reason);
997 }
998
999 private void goToSleepInternal(long eventTime, int reason) {
1000 synchronized (mLock) {
1001 if (goToSleepNoUpdateLocked(eventTime, reason)) {
1002 updatePowerStateLocked();
1003 }
1004 }
1005 }
1006
1007 private boolean goToSleepNoUpdateLocked(long eventTime, int reason) {
1008 if (DEBUG_SPEW) {
1009 Slog.d(TAG, "goToSleepNoUpdateLocked: eventTime=" + eventTime + ", reason=" + reason);
1010 }
1011
1012 if (eventTime < mLastWakeTime || mWakefulness == WAKEFULNESS_ASLEEP
1013 || !mBootCompleted || !mSystemReady) {
1014 return false;
1015 }
1016
1017 switch (reason) {
1018 case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN:
1019 Slog.i(TAG, "Going to sleep due to device administration policy...");
1020 break;
1021 case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT:
1022 Slog.i(TAG, "Going to sleep due to screen timeout...");
1023 break;
1024 default:
1025 Slog.i(TAG, "Going to sleep by user request...");
1026 reason = PowerManager.GO_TO_SLEEP_REASON_USER;
1027 break;
1028 }
1029
Jeff Brown54308352012-10-04 17:59:58 -07001030 sendPendingNotificationsLocked();
1031 mNotifier.onGoToSleepStarted(reason);
1032 mSendGoToSleepFinishedNotificationWhenReady = true;
1033
Jeff Brown96307042012-07-27 15:51:34 -07001034 mLastSleepTime = eventTime;
1035 mDirty |= DIRTY_WAKEFULNESS;
1036 mWakefulness = WAKEFULNESS_ASLEEP;
Jeff Brown96307042012-07-27 15:51:34 -07001037
1038 // Report the number of wake locks that will be cleared by going to sleep.
1039 int numWakeLocksCleared = 0;
1040 final int numWakeLocks = mWakeLocks.size();
1041 for (int i = 0; i < numWakeLocks; i++) {
1042 final WakeLock wakeLock = mWakeLocks.get(i);
1043 switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
1044 case PowerManager.FULL_WAKE_LOCK:
1045 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
1046 case PowerManager.SCREEN_DIM_WAKE_LOCK:
1047 numWakeLocksCleared += 1;
1048 break;
1049 }
1050 }
1051 EventLog.writeEvent(EventLogTags.POWER_SLEEP_REQUESTED, numWakeLocksCleared);
1052 return true;
1053 }
1054
Jeff Brown62c82e42012-09-26 01:30:41 -07001055 @Override // Binder call
1056 public void nap(long eventTime) {
1057 if (eventTime > SystemClock.uptimeMillis()) {
1058 throw new IllegalArgumentException("event time must not be in the future");
1059 }
1060
1061 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1062
1063 final long ident = Binder.clearCallingIdentity();
1064 try {
1065 napInternal(eventTime);
1066 } finally {
1067 Binder.restoreCallingIdentity(ident);
1068 }
1069 }
1070
1071 private void napInternal(long eventTime) {
1072 synchronized (mLock) {
1073 if (napNoUpdateLocked(eventTime)) {
1074 updatePowerStateLocked();
1075 }
1076 }
1077 }
1078
1079 private boolean napNoUpdateLocked(long eventTime) {
1080 if (DEBUG_SPEW) {
1081 Slog.d(TAG, "napNoUpdateLocked: eventTime=" + eventTime);
1082 }
1083
1084 if (eventTime < mLastWakeTime || mWakefulness != WAKEFULNESS_AWAKE
1085 || !mBootCompleted || !mSystemReady) {
1086 return false;
1087 }
1088
1089 Slog.i(TAG, "Nap time...");
1090
1091 mDirty |= DIRTY_WAKEFULNESS;
1092 mWakefulness = WAKEFULNESS_NAPPING;
1093 return true;
1094 }
1095
Jeff Brown96307042012-07-27 15:51:34 -07001096 /**
1097 * Updates the global power state based on dirty bits recorded in mDirty.
1098 *
1099 * This is the main function that performs power state transitions.
1100 * We centralize them here so that we can recompute the power state completely
1101 * each time something important changes, and ensure that we do it the same
1102 * way each time. The point is to gather all of the transition logic here.
1103 */
1104 private void updatePowerStateLocked() {
1105 if (!mSystemReady || mDirty == 0) {
The Android Open Source Project10592532009-03-18 17:39:46 -07001106 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001107 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001108
Jeff Brown96307042012-07-27 15:51:34 -07001109 // Phase 0: Basic state updates.
1110 updateIsPoweredLocked(mDirty);
1111 updateStayOnLocked(mDirty);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001112
Jeff Brown96307042012-07-27 15:51:34 -07001113 // Phase 1: Update wakefulness.
1114 // Loop because the wake lock and user activity computations are influenced
1115 // by changes in wakefulness.
1116 final long now = SystemClock.uptimeMillis();
1117 int dirtyPhase2 = 0;
1118 for (;;) {
1119 int dirtyPhase1 = mDirty;
1120 dirtyPhase2 |= dirtyPhase1;
1121 mDirty = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001122
Jeff Brown96307042012-07-27 15:51:34 -07001123 updateWakeLockSummaryLocked(dirtyPhase1);
1124 updateUserActivitySummaryLocked(now, dirtyPhase1);
1125 if (!updateWakefulnessLocked(dirtyPhase1)) {
1126 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001127 }
1128 }
1129
Jeff Brown96307042012-07-27 15:51:34 -07001130 // Phase 2: Update dreams and display power state.
1131 updateDreamLocked(dirtyPhase2);
1132 updateDisplayPowerStateLocked(dirtyPhase2);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001133
Jeff Brown96307042012-07-27 15:51:34 -07001134 // Phase 3: Send notifications, if needed.
Jeff Brown54308352012-10-04 17:59:58 -07001135 if (mDisplayReady) {
1136 sendPendingNotificationsLocked();
1137 }
Craig Mautner75fc9de2012-06-18 16:53:27 -07001138
Jeff Brown96307042012-07-27 15:51:34 -07001139 // Phase 4: Update suspend blocker.
1140 // Because we might release the last suspend blocker here, we need to make sure
1141 // we finished everything else first!
1142 updateSuspendBlockerLocked();
1143 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001144
Jeff Brown96307042012-07-27 15:51:34 -07001145 private void sendPendingNotificationsLocked() {
Jeff Brown54308352012-10-04 17:59:58 -07001146 if (mSendWakeUpFinishedNotificationWhenReady) {
1147 mSendWakeUpFinishedNotificationWhenReady = false;
1148 mNotifier.onWakeUpFinished();
1149 }
1150 if (mSendGoToSleepFinishedNotificationWhenReady) {
1151 mSendGoToSleepFinishedNotificationWhenReady = false;
1152 mNotifier.onGoToSleepFinished();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001153 }
The Android Open Source Project10592532009-03-18 17:39:46 -07001154 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001155
Jim Miller92e66dd2012-02-21 18:57:12 -08001156 /**
Jeff Brown96307042012-07-27 15:51:34 -07001157 * Updates the value of mIsPowered.
1158 * Sets DIRTY_IS_POWERED if a change occurred.
Jim Miller92e66dd2012-02-21 18:57:12 -08001159 */
Jeff Brown96307042012-07-27 15:51:34 -07001160 private void updateIsPoweredLocked(int dirty) {
1161 if ((dirty & DIRTY_BATTERY_STATE) != 0) {
Jeff Brownf3fb8952012-10-02 20:57:05 -07001162 final boolean wasPowered = mIsPowered;
1163 final int oldPlugType = mPlugType;
Jeff Browna4d82042012-10-02 19:11:19 -07001164 mIsPowered = mBatteryService.isPowered(BatteryManager.BATTERY_PLUGGED_ANY);
Jeff Brownf3fb8952012-10-02 20:57:05 -07001165 mPlugType = mBatteryService.getPlugType();
Jeff Brown016ff142012-10-15 16:47:22 -07001166 mBatteryLevel = mBatteryService.getBatteryLevel();
Jeff Browna4d82042012-10-02 19:11:19 -07001167
1168 if (DEBUG) {
1169 Slog.d(TAG, "updateIsPoweredLocked: wasPowered=" + wasPowered
Jeff Brownf3fb8952012-10-02 20:57:05 -07001170 + ", mIsPowered=" + mIsPowered
1171 + ", oldPlugType=" + oldPlugType
Jeff Brown016ff142012-10-15 16:47:22 -07001172 + ", mPlugType=" + mPlugType
1173 + ", mBatteryLevel=" + mBatteryLevel);
Jeff Browna4d82042012-10-02 19:11:19 -07001174 }
Jim Miller92e66dd2012-02-21 18:57:12 -08001175
Jeff Brownf3fb8952012-10-02 20:57:05 -07001176 if (wasPowered != mIsPowered || oldPlugType != mPlugType) {
Jeff Brown96307042012-07-27 15:51:34 -07001177 mDirty |= DIRTY_IS_POWERED;
1178
Jeff Brown3b971592013-01-09 18:46:37 -08001179 // Update wireless dock detection state.
1180 final boolean dockedOnWirelessCharger = mWirelessChargerDetector.update(
1181 mIsPowered, mPlugType, mBatteryLevel);
1182
Jeff Brown96307042012-07-27 15:51:34 -07001183 // Treat plugging and unplugging the devices as a user activity.
1184 // Users find it disconcerting when they plug or unplug the device
1185 // and it shuts off right away.
1186 // Some devices also wake the device when plugged or unplugged because
1187 // they don't have a charging LED.
1188 final long now = SystemClock.uptimeMillis();
Jeff Brown3b971592013-01-09 18:46:37 -08001189 if (shouldWakeUpWhenPluggedOrUnpluggedLocked(wasPowered, oldPlugType,
1190 dockedOnWirelessCharger)) {
Jeff Brown96307042012-07-27 15:51:34 -07001191 wakeUpNoUpdateLocked(now);
1192 }
1193 userActivityNoUpdateLocked(
1194 now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
Jeff Brown84e27562012-12-07 13:56:34 -08001195
1196 // Tell the notifier whether wireless charging has started so that
Jeff Brown3b971592013-01-09 18:46:37 -08001197 // it can provide feedback to the user.
1198 if (dockedOnWirelessCharger) {
Jeff Brown84e27562012-12-07 13:56:34 -08001199 mNotifier.onWirelessChargingStarted();
1200 }
Jeff Brown96307042012-07-27 15:51:34 -07001201 }
1202 }
1203 }
1204
Jeff Brown3b971592013-01-09 18:46:37 -08001205 private boolean shouldWakeUpWhenPluggedOrUnpluggedLocked(
1206 boolean wasPowered, int oldPlugType, boolean dockedOnWirelessCharger) {
Jeff Brown9fca9e92012-10-05 14:42:56 -07001207 // Don't wake when powered unless configured to do so.
1208 if (!mWakeUpWhenPluggedOrUnpluggedConfig) {
1209 return false;
Jeff Brownf3fb8952012-10-02 20:57:05 -07001210 }
Jeff Brown9fca9e92012-10-05 14:42:56 -07001211
Jeff Brown3b971592013-01-09 18:46:37 -08001212 // Don't wake when undocked from wireless charger.
1213 // See WirelessChargerDetector for justification.
Jeff Brown9fca9e92012-10-05 14:42:56 -07001214 if (wasPowered && !mIsPowered
1215 && oldPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS) {
1216 return false;
1217 }
Jeff Brown3b971592013-01-09 18:46:37 -08001218
1219 // Don't wake when docked on wireless charger unless we are certain of it.
1220 // See WirelessChargerDetector for justification.
Jeff Brown9fca9e92012-10-05 14:42:56 -07001221 if (!wasPowered && mIsPowered
1222 && mPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS
Jeff Brown3b971592013-01-09 18:46:37 -08001223 && !dockedOnWirelessCharger) {
Jeff Brown9fca9e92012-10-05 14:42:56 -07001224 return false;
1225 }
1226
1227 // If already dreaming and becoming powered, then don't wake.
1228 if (mIsPowered && (mWakefulness == WAKEFULNESS_NAPPING
1229 || mWakefulness == WAKEFULNESS_DREAMING)) {
1230 return false;
1231 }
1232
1233 // Otherwise wake up!
1234 return true;
Jeff Brownf3fb8952012-10-02 20:57:05 -07001235 }
1236
Jeff Brown96307042012-07-27 15:51:34 -07001237 /**
1238 * Updates the value of mStayOn.
1239 * Sets DIRTY_STAY_ON if a change occurred.
1240 */
1241 private void updateStayOnLocked(int dirty) {
1242 if ((dirty & (DIRTY_BATTERY_STATE | DIRTY_SETTINGS)) != 0) {
Jeff Brown93cbbb22012-10-04 13:18:36 -07001243 final boolean wasStayOn = mStayOn;
Jeff Brown96307042012-07-27 15:51:34 -07001244 if (mStayOnWhilePluggedInSetting != 0
1245 && !isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
1246 mStayOn = mBatteryService.isPowered(mStayOnWhilePluggedInSetting);
1247 } else {
1248 mStayOn = false;
1249 }
Jeff Brown93cbbb22012-10-04 13:18:36 -07001250
1251 if (mStayOn != wasStayOn) {
1252 mDirty |= DIRTY_STAY_ON;
1253 }
Jeff Brown96307042012-07-27 15:51:34 -07001254 }
1255 }
1256
1257 /**
1258 * Updates the value of mWakeLockSummary to summarize the state of all active wake locks.
1259 * Note that most wake-locks are ignored when the system is asleep.
1260 *
1261 * This function must have no other side-effects.
1262 */
1263 private void updateWakeLockSummaryLocked(int dirty) {
1264 if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_WAKEFULNESS)) != 0) {
1265 mWakeLockSummary = 0;
1266
1267 final int numWakeLocks = mWakeLocks.size();
1268 for (int i = 0; i < numWakeLocks; i++) {
1269 final WakeLock wakeLock = mWakeLocks.get(i);
1270 switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
1271 case PowerManager.PARTIAL_WAKE_LOCK:
1272 mWakeLockSummary |= WAKE_LOCK_CPU;
1273 break;
1274 case PowerManager.FULL_WAKE_LOCK:
1275 if (mWakefulness != WAKEFULNESS_ASLEEP) {
1276 mWakeLockSummary |= WAKE_LOCK_CPU
1277 | WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_BUTTON_BRIGHT;
Jeff Brown10428742012-10-09 15:47:30 -07001278 if (mWakefulness == WAKEFULNESS_AWAKE) {
1279 mWakeLockSummary |= WAKE_LOCK_STAY_AWAKE;
1280 }
Jeff Brown96307042012-07-27 15:51:34 -07001281 }
1282 break;
1283 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
1284 if (mWakefulness != WAKEFULNESS_ASLEEP) {
1285 mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_SCREEN_BRIGHT;
Jeff Brown10428742012-10-09 15:47:30 -07001286 if (mWakefulness == WAKEFULNESS_AWAKE) {
1287 mWakeLockSummary |= WAKE_LOCK_STAY_AWAKE;
1288 }
Jeff Brown96307042012-07-27 15:51:34 -07001289 }
1290 break;
1291 case PowerManager.SCREEN_DIM_WAKE_LOCK:
1292 if (mWakefulness != WAKEFULNESS_ASLEEP) {
1293 mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_SCREEN_DIM;
Jeff Brown10428742012-10-09 15:47:30 -07001294 if (mWakefulness == WAKEFULNESS_AWAKE) {
1295 mWakeLockSummary |= WAKE_LOCK_STAY_AWAKE;
1296 }
Jeff Brown96307042012-07-27 15:51:34 -07001297 }
1298 break;
1299 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
1300 if (mWakefulness != WAKEFULNESS_ASLEEP) {
1301 mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_PROXIMITY_SCREEN_OFF;
1302 }
1303 break;
1304 }
1305 }
1306
1307 if (DEBUG_SPEW) {
1308 Slog.d(TAG, "updateWakeLockSummaryLocked: mWakefulness="
1309 + wakefulnessToString(mWakefulness)
1310 + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary));
1311 }
1312 }
1313 }
1314
1315 /**
1316 * Updates the value of mUserActivitySummary to summarize the user requested
1317 * state of the system such as whether the screen should be bright or dim.
1318 * Note that user activity is ignored when the system is asleep.
1319 *
1320 * This function must have no other side-effects.
1321 */
1322 private void updateUserActivitySummaryLocked(long now, int dirty) {
1323 // Update the status of the user activity timeout timer.
1324 if ((dirty & (DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS | DIRTY_SETTINGS)) != 0) {
1325 mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT);
1326
1327 long nextTimeout = 0;
1328 if (mWakefulness != WAKEFULNESS_ASLEEP) {
1329 final int screenOffTimeout = getScreenOffTimeoutLocked();
Jeff Brownff532542012-10-02 21:18:04 -07001330 final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
Jeff Brown96307042012-07-27 15:51:34 -07001331
1332 mUserActivitySummary = 0;
1333 if (mLastUserActivityTime >= mLastWakeTime) {
1334 nextTimeout = mLastUserActivityTime
1335 + screenOffTimeout - screenDimDuration;
1336 if (now < nextTimeout) {
1337 mUserActivitySummary |= USER_ACTIVITY_SCREEN_BRIGHT;
1338 } else {
1339 nextTimeout = mLastUserActivityTime + screenOffTimeout;
1340 if (now < nextTimeout) {
1341 mUserActivitySummary |= USER_ACTIVITY_SCREEN_DIM;
1342 }
1343 }
1344 }
1345 if (mUserActivitySummary == 0
1346 && mLastUserActivityTimeNoChangeLights >= mLastWakeTime) {
1347 nextTimeout = mLastUserActivityTimeNoChangeLights + screenOffTimeout;
1348 if (now < nextTimeout
1349 && mDisplayPowerRequest.screenState
1350 != DisplayPowerRequest.SCREEN_STATE_OFF) {
1351 mUserActivitySummary = mDisplayPowerRequest.screenState
1352 == DisplayPowerRequest.SCREEN_STATE_BRIGHT ?
1353 USER_ACTIVITY_SCREEN_BRIGHT : USER_ACTIVITY_SCREEN_DIM;
1354 }
1355 }
1356 if (mUserActivitySummary != 0) {
1357 Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY_TIMEOUT);
1358 msg.setAsynchronous(true);
1359 mHandler.sendMessageAtTime(msg, nextTimeout);
1360 }
1361 } else {
1362 mUserActivitySummary = 0;
1363 }
1364
1365 if (DEBUG_SPEW) {
1366 Slog.d(TAG, "updateUserActivitySummaryLocked: mWakefulness="
1367 + wakefulnessToString(mWakefulness)
1368 + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
1369 + ", nextTimeout=" + TimeUtils.formatUptime(nextTimeout));
1370 }
1371 }
1372 }
1373
1374 /**
1375 * Called when a user activity timeout has occurred.
1376 * Simply indicates that something about user activity has changed so that the new
1377 * state can be recomputed when the power state is updated.
1378 *
1379 * This function must have no other side-effects besides setting the dirty
1380 * bit and calling update power state. Wakefulness transitions are handled elsewhere.
1381 */
1382 private void handleUserActivityTimeout() { // runs on handler thread
1383 synchronized (mLock) {
1384 if (DEBUG_SPEW) {
1385 Slog.d(TAG, "handleUserActivityTimeout");
1386 }
1387
1388 mDirty |= DIRTY_USER_ACTIVITY;
1389 updatePowerStateLocked();
1390 }
1391 }
1392
1393 private int getScreenOffTimeoutLocked() {
1394 int timeout = mScreenOffTimeoutSetting;
1395 if (isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
1396 timeout = Math.min(timeout, mMaximumScreenOffTimeoutFromDeviceAdmin);
1397 }
Jeff Brown1e3b98d2012-09-30 18:58:59 -07001398 if (mUserActivityTimeoutOverrideFromWindowManager >= 0) {
1399 timeout = (int)Math.min(timeout, mUserActivityTimeoutOverrideFromWindowManager);
1400 }
Jeff Brown96307042012-07-27 15:51:34 -07001401 return Math.max(timeout, MINIMUM_SCREEN_OFF_TIMEOUT);
1402 }
1403
Jeff Brownff532542012-10-02 21:18:04 -07001404 private int getScreenDimDurationLocked(int screenOffTimeout) {
1405 return Math.min(SCREEN_DIM_DURATION,
1406 (int)(screenOffTimeout * MAXIMUM_SCREEN_DIM_RATIO));
Jeff Brown96307042012-07-27 15:51:34 -07001407 }
1408
1409 /**
1410 * Updates the wakefulness of the device.
1411 *
1412 * This is the function that decides whether the device should start napping
1413 * based on the current wake locks and user activity state. It may modify mDirty
1414 * if the wakefulness changes.
1415 *
1416 * Returns true if the wakefulness changed and we need to restart power state calculation.
1417 */
1418 private boolean updateWakefulnessLocked(int dirty) {
1419 boolean changed = false;
1420 if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_BOOT_COMPLETED
Jeff Brownec6aa592012-10-17 20:30:25 -07001421 | DIRTY_WAKEFULNESS | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE
1422 | DIRTY_DOCK_STATE)) != 0) {
Jeff Brown96307042012-07-27 15:51:34 -07001423 if (mWakefulness == WAKEFULNESS_AWAKE && isItBedTimeYetLocked()) {
1424 if (DEBUG_SPEW) {
Jeff Brown62c82e42012-09-26 01:30:41 -07001425 Slog.d(TAG, "updateWakefulnessLocked: Bed time...");
Jeff Brown96307042012-07-27 15:51:34 -07001426 }
Jeff Brown62c82e42012-09-26 01:30:41 -07001427 final long time = SystemClock.uptimeMillis();
Jeff Brownec6aa592012-10-17 20:30:25 -07001428 if (shouldNapAtBedTimeLocked()) {
Jeff Brown62c82e42012-09-26 01:30:41 -07001429 changed = napNoUpdateLocked(time);
1430 } else {
1431 changed = goToSleepNoUpdateLocked(time,
1432 PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
1433 }
Jeff Brown96307042012-07-27 15:51:34 -07001434 }
1435 }
1436 return changed;
1437 }
1438
Jeff Brown645832d2012-10-03 14:57:03 -07001439 /**
Jeff Brownec6aa592012-10-17 20:30:25 -07001440 * Returns true if the device should automatically nap and start dreaming when the user
1441 * activity timeout has expired and it's bedtime.
1442 */
1443 private boolean shouldNapAtBedTimeLocked() {
1444 return mDreamsActivateOnSleepSetting
1445 || (mDreamsActivateOnDockSetting
1446 && mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED);
1447 }
1448
1449 /**
Jeff Brown645832d2012-10-03 14:57:03 -07001450 * Returns true if the device should go to sleep now.
1451 * Also used when exiting a dream to determine whether we should go back
1452 * to being fully awake or else go to sleep for good.
1453 */
Jeff Brown96307042012-07-27 15:51:34 -07001454 private boolean isItBedTimeYetLocked() {
Jeff Brown93cbbb22012-10-04 13:18:36 -07001455 return mBootCompleted && !isBeingKeptAwakeLocked();
Jeff Brown645832d2012-10-03 14:57:03 -07001456 }
1457
1458 /**
Jeff Brown93cbbb22012-10-04 13:18:36 -07001459 * Returns true if the device is being kept awake by a wake lock, user activity
Jeff Brown645832d2012-10-03 14:57:03 -07001460 * or the stay on while powered setting.
1461 */
Jeff Brown93cbbb22012-10-04 13:18:36 -07001462 private boolean isBeingKeptAwakeLocked() {
Jeff Brown645832d2012-10-03 14:57:03 -07001463 return mStayOn
Jeff Brown93cbbb22012-10-04 13:18:36 -07001464 || mProximityPositive
Jeff Brown10428742012-10-09 15:47:30 -07001465 || (mWakeLockSummary & WAKE_LOCK_STAY_AWAKE) != 0
Jeff Brown645832d2012-10-03 14:57:03 -07001466 || (mUserActivitySummary & (USER_ACTIVITY_SCREEN_BRIGHT
1467 | USER_ACTIVITY_SCREEN_DIM)) != 0;
Jeff Brown96307042012-07-27 15:51:34 -07001468 }
1469
1470 /**
1471 * Determines whether to post a message to the sandman to update the dream state.
1472 */
1473 private void updateDreamLocked(int dirty) {
John Spurlockf4f6b4c2012-08-25 12:08:03 -04001474 if ((dirty & (DIRTY_WAKEFULNESS
Jeff Brown645832d2012-10-03 14:57:03 -07001475 | DIRTY_USER_ACTIVITY
1476 | DIRTY_WAKE_LOCKS
1477 | DIRTY_BOOT_COMPLETED
John Spurlockf4f6b4c2012-08-25 12:08:03 -04001478 | DIRTY_SETTINGS
1479 | DIRTY_IS_POWERED
1480 | DIRTY_STAY_ON
Jeff Brown93cbbb22012-10-04 13:18:36 -07001481 | DIRTY_PROXIMITY_POSITIVE
Jeff Brown62c82e42012-09-26 01:30:41 -07001482 | DIRTY_BATTERY_STATE)) != 0) {
Jeff Brown96307042012-07-27 15:51:34 -07001483 scheduleSandmanLocked();
1484 }
1485 }
1486
1487 private void scheduleSandmanLocked() {
1488 if (!mSandmanScheduled) {
1489 mSandmanScheduled = true;
1490 Message msg = mHandler.obtainMessage(MSG_SANDMAN);
1491 msg.setAsynchronous(true);
1492 mHandler.sendMessage(msg);
1493 }
1494 }
1495
1496 /**
1497 * Called when the device enters or exits a napping or dreaming state.
1498 *
1499 * We do this asynchronously because we must call out of the power manager to start
1500 * the dream and we don't want to hold our lock while doing so. There is a risk that
1501 * the device will wake or go to sleep in the meantime so we have to handle that case.
1502 */
1503 private void handleSandman() { // runs on handler thread
1504 // Handle preconditions.
1505 boolean startDreaming = false;
1506 synchronized (mLock) {
1507 mSandmanScheduled = false;
John Spurlock10fb2242012-08-23 15:32:28 -04001508 boolean canDream = canDreamLocked();
Jeff Brown96307042012-07-27 15:51:34 -07001509 if (DEBUG_SPEW) {
Jeff Brown016ff142012-10-15 16:47:22 -07001510 Slog.d(TAG, "handleSandman: canDream=" + canDream
Jeff Brown96307042012-07-27 15:51:34 -07001511 + ", mWakefulness=" + wakefulnessToString(mWakefulness));
1512 }
1513
John Spurlock10fb2242012-08-23 15:32:28 -04001514 if (canDream && mWakefulness == WAKEFULNESS_NAPPING) {
Jeff Brown96307042012-07-27 15:51:34 -07001515 startDreaming = true;
1516 }
1517 }
1518
Jeff Brown96307042012-07-27 15:51:34 -07001519 // Start dreaming if needed.
1520 // We only control the dream on the handler thread, so we don't need to worry about
1521 // concurrent attempts to start or stop the dream.
1522 boolean isDreaming = false;
1523 if (mDreamManager != null) {
Jeff Brown62c82e42012-09-26 01:30:41 -07001524 if (startDreaming) {
1525 mDreamManager.startDream();
Jeff Brown96307042012-07-27 15:51:34 -07001526 }
Jeff Brown62c82e42012-09-26 01:30:41 -07001527 isDreaming = mDreamManager.isDreaming();
Jeff Brown96307042012-07-27 15:51:34 -07001528 }
1529
1530 // Update dream state.
1531 // We might need to stop the dream again if the preconditions changed.
1532 boolean continueDreaming = false;
1533 synchronized (mLock) {
1534 if (isDreaming && canDreamLocked()) {
1535 if (mWakefulness == WAKEFULNESS_NAPPING) {
1536 mWakefulness = WAKEFULNESS_DREAMING;
1537 mDirty |= DIRTY_WAKEFULNESS;
Jeff Brown016ff142012-10-15 16:47:22 -07001538 mBatteryLevelWhenDreamStarted = mBatteryLevel;
Jeff Brown96307042012-07-27 15:51:34 -07001539 updatePowerStateLocked();
1540 continueDreaming = true;
1541 } else if (mWakefulness == WAKEFULNESS_DREAMING) {
Jeff Brown016ff142012-10-15 16:47:22 -07001542 if (!isBeingKeptAwakeLocked()
1543 && mBatteryLevel < mBatteryLevelWhenDreamStarted
1544 - DREAM_BATTERY_LEVEL_DRAIN_CUTOFF) {
1545 // If the user activity timeout expired and the battery appears
1546 // to be draining faster than it is charging then stop dreaming
1547 // and go to sleep.
1548 Slog.i(TAG, "Stopping dream because the battery appears to "
1549 + "be draining faster than it is charging. "
1550 + "Battery level when dream started: "
1551 + mBatteryLevelWhenDreamStarted + "%. "
1552 + "Battery level now: " + mBatteryLevel + "%.");
1553 } else {
1554 continueDreaming = true;
1555 }
Jeff Brown96307042012-07-27 15:51:34 -07001556 }
1557 }
1558 if (!continueDreaming) {
1559 handleDreamFinishedLocked();
1560 }
Jeff Brown96307042012-07-27 15:51:34 -07001561 }
1562
1563 // Stop dreaming if needed.
1564 // It's possible that something else changed to make us need to start the dream again.
1565 // If so, then the power manager will have posted another message to the handler
1566 // to take care of it later.
1567 if (mDreamManager != null) {
Jeff Brown62c82e42012-09-26 01:30:41 -07001568 if (!continueDreaming) {
1569 mDreamManager.stopDream();
Jeff Brown96307042012-07-27 15:51:34 -07001570 }
1571 }
1572 }
1573
1574 /**
Jeff Brown645832d2012-10-03 14:57:03 -07001575 * Returns true if the device is allowed to dream in its current state
1576 * assuming that it is currently napping or dreaming.
Jeff Brown96307042012-07-27 15:51:34 -07001577 */
1578 private boolean canDreamLocked() {
Jeff Brown645832d2012-10-03 14:57:03 -07001579 return mDreamsSupportedConfig
John Spurlock10fb2242012-08-23 15:32:28 -04001580 && mDreamsEnabledSetting
Jeff Brown645832d2012-10-03 14:57:03 -07001581 && mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF
1582 && mBootCompleted
Jeff Brown93cbbb22012-10-04 13:18:36 -07001583 && (mIsPowered || isBeingKeptAwakeLocked());
Jeff Brown96307042012-07-27 15:51:34 -07001584 }
1585
1586 /**
1587 * Called when a dream is ending to figure out what to do next.
1588 */
1589 private void handleDreamFinishedLocked() {
1590 if (mWakefulness == WAKEFULNESS_NAPPING
1591 || mWakefulness == WAKEFULNESS_DREAMING) {
1592 if (isItBedTimeYetLocked()) {
1593 goToSleepNoUpdateLocked(SystemClock.uptimeMillis(),
1594 PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
1595 updatePowerStateLocked();
1596 } else {
1597 wakeUpNoUpdateLocked(SystemClock.uptimeMillis());
1598 updatePowerStateLocked();
1599 }
1600 }
1601 }
1602
Jeff Brownc38c9be2012-10-04 13:16:19 -07001603 private void handleScreenOnBlockerReleased() {
1604 synchronized (mLock) {
1605 mDirty |= DIRTY_SCREEN_ON_BLOCKER_RELEASED;
1606 updatePowerStateLocked();
1607 }
1608 }
1609
Jeff Brown96307042012-07-27 15:51:34 -07001610 /**
1611 * Updates the display power state asynchronously.
1612 * When the update is finished, mDisplayReady will be set to true. The display
1613 * controller posts a message to tell us when the actual display power state
1614 * has been updated so we come back here to double-check and finish up.
1615 *
1616 * This function recalculates the display power state each time.
1617 */
1618 private void updateDisplayPowerStateLocked(int dirty) {
1619 if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS
1620 | DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED
Jeff Brownc38c9be2012-10-04 13:16:19 -07001621 | DIRTY_SETTINGS | DIRTY_SCREEN_ON_BLOCKER_RELEASED)) != 0) {
1622 int newScreenState = getDesiredScreenPowerStateLocked();
Jeff Brown96307042012-07-27 15:51:34 -07001623 if (newScreenState != mDisplayPowerRequest.screenState) {
1624 if (newScreenState == DisplayPowerRequest.SCREEN_STATE_OFF
1625 && mDisplayPowerRequest.screenState
1626 != DisplayPowerRequest.SCREEN_STATE_OFF) {
1627 mLastScreenOffEventElapsedRealTime = SystemClock.elapsedRealtime();
1628 }
1629
1630 mDisplayPowerRequest.screenState = newScreenState;
1631 nativeSetPowerState(
1632 newScreenState != DisplayPowerRequest.SCREEN_STATE_OFF,
1633 newScreenState == DisplayPowerRequest.SCREEN_STATE_BRIGHT);
1634 }
1635
1636 int screenBrightness = mScreenBrightnessSettingDefault;
Jeff Brown330560f2012-08-21 22:10:57 -07001637 float screenAutoBrightnessAdjustment = 0.0f;
Jeff Brown96307042012-07-27 15:51:34 -07001638 boolean autoBrightness = (mScreenBrightnessModeSetting ==
1639 Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
1640 if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)) {
1641 screenBrightness = mScreenBrightnessOverrideFromWindowManager;
1642 autoBrightness = false;
1643 } else if (isValidBrightness(mTemporaryScreenBrightnessSettingOverride)) {
1644 screenBrightness = mTemporaryScreenBrightnessSettingOverride;
1645 } else if (isValidBrightness(mScreenBrightnessSetting)) {
Jeff Brown330560f2012-08-21 22:10:57 -07001646 screenBrightness = mScreenBrightnessSetting;
Jeff Brown96307042012-07-27 15:51:34 -07001647 }
1648 if (autoBrightness) {
1649 screenBrightness = mScreenBrightnessSettingDefault;
Jeff Brown330560f2012-08-21 22:10:57 -07001650 if (isValidAutoBrightnessAdjustment(
1651 mTemporaryScreenAutoBrightnessAdjustmentSettingOverride)) {
1652 screenAutoBrightnessAdjustment =
1653 mTemporaryScreenAutoBrightnessAdjustmentSettingOverride;
1654 } else if (isValidAutoBrightnessAdjustment(
1655 mScreenAutoBrightnessAdjustmentSetting)) {
1656 screenAutoBrightnessAdjustment = mScreenAutoBrightnessAdjustmentSetting;
1657 }
Jeff Brown96307042012-07-27 15:51:34 -07001658 }
1659 screenBrightness = Math.max(Math.min(screenBrightness,
1660 mScreenBrightnessSettingMaximum), mScreenBrightnessSettingMinimum);
Jeff Brown330560f2012-08-21 22:10:57 -07001661 screenAutoBrightnessAdjustment = Math.max(Math.min(
1662 screenAutoBrightnessAdjustment, 1.0f), -1.0f);
Jeff Brown96307042012-07-27 15:51:34 -07001663 mDisplayPowerRequest.screenBrightness = screenBrightness;
Jeff Brown330560f2012-08-21 22:10:57 -07001664 mDisplayPowerRequest.screenAutoBrightnessAdjustment =
1665 screenAutoBrightnessAdjustment;
Jeff Brown96307042012-07-27 15:51:34 -07001666 mDisplayPowerRequest.useAutoBrightness = autoBrightness;
1667
1668 mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
1669
Jeff Brownc38c9be2012-10-04 13:16:19 -07001670 mDisplayPowerRequest.blockScreenOn = mScreenOnBlocker.isHeld();
1671
Jeff Brown96307042012-07-27 15:51:34 -07001672 mDisplayReady = mDisplayPowerController.requestPowerState(mDisplayPowerRequest,
1673 mRequestWaitForNegativeProximity);
1674 mRequestWaitForNegativeProximity = false;
1675
1676 if (DEBUG_SPEW) {
Jeff Brownc38c9be2012-10-04 13:16:19 -07001677 Slog.d(TAG, "updateScreenStateLocked: mDisplayReady=" + mDisplayReady
Jeff Brown96307042012-07-27 15:51:34 -07001678 + ", newScreenState=" + newScreenState
1679 + ", mWakefulness=" + mWakefulness
1680 + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary)
1681 + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
1682 + ", mBootCompleted=" + mBootCompleted);
1683 }
1684 }
1685 }
1686
1687 private static boolean isValidBrightness(int value) {
1688 return value >= 0 && value <= 255;
1689 }
1690
Jeff Brown330560f2012-08-21 22:10:57 -07001691 private static boolean isValidAutoBrightnessAdjustment(float value) {
Jeff Brown5d03a532012-08-22 13:22:02 -07001692 // Handles NaN by always returning false.
1693 return value >= -1.0f && value <= 1.0f;
Jeff Brown330560f2012-08-21 22:10:57 -07001694 }
1695
Jeff Brownc38c9be2012-10-04 13:16:19 -07001696 private int getDesiredScreenPowerStateLocked() {
Jeff Brown96307042012-07-27 15:51:34 -07001697 if (mWakefulness == WAKEFULNESS_ASLEEP) {
1698 return DisplayPowerRequest.SCREEN_STATE_OFF;
1699 }
1700
1701 if ((mWakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0
1702 || (mUserActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0
1703 || !mBootCompleted) {
1704 return DisplayPowerRequest.SCREEN_STATE_BRIGHT;
1705 }
1706
1707 return DisplayPowerRequest.SCREEN_STATE_DIM;
1708 }
1709
1710 private final DisplayPowerController.Callbacks mDisplayPowerControllerCallbacks =
1711 new DisplayPowerController.Callbacks() {
1712 @Override
1713 public void onStateChanged() {
Jeff Brownd91e4172013-07-16 15:18:19 -07001714 synchronized (mLock) {
1715 mDirty |= DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED;
1716 updatePowerStateLocked();
1717 }
Jim Miller92e66dd2012-02-21 18:57:12 -08001718 }
1719
1720 @Override
Jeff Brown93cbbb22012-10-04 13:18:36 -07001721 public void onProximityPositive() {
Jeff Brownd91e4172013-07-16 15:18:19 -07001722 synchronized (mLock) {
1723 mProximityPositive = true;
1724 mDirty |= DIRTY_PROXIMITY_POSITIVE;
1725 updatePowerStateLocked();
1726 }
Jeff Brown93cbbb22012-10-04 13:18:36 -07001727 }
1728
1729 @Override
Jeff Brown96307042012-07-27 15:51:34 -07001730 public void onProximityNegative() {
Jeff Brownd91e4172013-07-16 15:18:19 -07001731 synchronized (mLock) {
1732 mProximityPositive = false;
1733 mDirty |= DIRTY_PROXIMITY_POSITIVE;
1734 userActivityNoUpdateLocked(SystemClock.uptimeMillis(),
1735 PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
1736 updatePowerStateLocked();
1737 }
Jeff Brown96307042012-07-27 15:51:34 -07001738 }
1739 };
Jim Miller92e66dd2012-02-21 18:57:12 -08001740
Jeff Brown96307042012-07-27 15:51:34 -07001741 private boolean shouldUseProximitySensorLocked() {
1742 return (mWakeLockSummary & WAKE_LOCK_PROXIMITY_SCREEN_OFF) != 0;
1743 }
Jim Miller92e66dd2012-02-21 18:57:12 -08001744
Jeff Brown96307042012-07-27 15:51:34 -07001745 /**
1746 * Updates the suspend blocker that keeps the CPU alive.
1747 *
1748 * This function must have no other side-effects.
1749 */
1750 private void updateSuspendBlockerLocked() {
Jeff Brown27f7a862012-12-12 15:43:31 -08001751 final boolean needWakeLockSuspendBlocker = (mWakeLockSummary != 0);
1752 final boolean needDisplaySuspendBlocker = (mUserActivitySummary != 0
Jeff Brown96307042012-07-27 15:51:34 -07001753 || mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF
Jeff Brown27f7a862012-12-12 15:43:31 -08001754 || !mDisplayReady || !mBootCompleted);
1755
1756 // First acquire suspend blockers if needed.
1757 if (needWakeLockSuspendBlocker && !mHoldingWakeLockSuspendBlocker) {
1758 mWakeLockSuspendBlocker.acquire();
1759 mHoldingWakeLockSuspendBlocker = true;
1760 }
1761 if (needDisplaySuspendBlocker && !mHoldingDisplaySuspendBlocker) {
1762 mDisplaySuspendBlocker.acquire();
1763 mHoldingDisplaySuspendBlocker = true;
1764 }
1765
1766 // Then release suspend blockers if needed.
1767 if (!needWakeLockSuspendBlocker && mHoldingWakeLockSuspendBlocker) {
1768 mWakeLockSuspendBlocker.release();
1769 mHoldingWakeLockSuspendBlocker = false;
1770 }
1771 if (!needDisplaySuspendBlocker && mHoldingDisplaySuspendBlocker) {
1772 mDisplaySuspendBlocker.release();
1773 mHoldingDisplaySuspendBlocker = false;
1774 }
Jeff Brown96307042012-07-27 15:51:34 -07001775 }
1776
1777 @Override // Binder call
1778 public boolean isScreenOn() {
1779 final long ident = Binder.clearCallingIdentity();
Mike Lockwoodd7786b42009-10-15 17:09:16 -07001780 try {
Jeff Brown96307042012-07-27 15:51:34 -07001781 return isScreenOnInternal();
1782 } finally {
1783 Binder.restoreCallingIdentity(ident);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07001784 }
1785 }
1786
Jeff Brown96307042012-07-27 15:51:34 -07001787 private boolean isScreenOnInternal() {
1788 synchronized (mLock) {
1789 return !mSystemReady
1790 || mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF;
Mike Lockwoodb2865412010-02-02 22:40:33 -05001791 }
1792 }
1793
Jeff Brown96307042012-07-27 15:51:34 -07001794 private void handleBatteryStateChangedLocked() {
1795 mDirty |= DIRTY_BATTERY_STATE;
1796 updatePowerStateLocked();
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001797 }
1798
Jeff Brown20767b22012-10-09 18:57:07 -07001799 private void startWatchingForBootAnimationFinished() {
1800 mHandler.sendEmptyMessage(MSG_CHECK_IF_BOOT_ANIMATION_FINISHED);
1801 }
1802
1803 private void checkIfBootAnimationFinished() {
1804 if (DEBUG) {
1805 Slog.d(TAG, "Check if boot animation finished...");
1806 }
1807
1808 if (SystemService.isRunning(BOOT_ANIMATION_SERVICE)) {
1809 mHandler.sendEmptyMessageDelayed(MSG_CHECK_IF_BOOT_ANIMATION_FINISHED,
1810 BOOT_ANIMATION_POLL_INTERVAL);
1811 return;
1812 }
1813
1814 synchronized (mLock) {
1815 if (!mBootCompleted) {
1816 Slog.i(TAG, "Boot animation finished.");
1817 handleBootCompletedLocked();
1818 }
1819 }
1820 }
1821
Jeff Brown96307042012-07-27 15:51:34 -07001822 private void handleBootCompletedLocked() {
1823 final long now = SystemClock.uptimeMillis();
1824 mBootCompleted = true;
1825 mDirty |= DIRTY_BOOT_COMPLETED;
1826 userActivityNoUpdateLocked(
1827 now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
1828 updatePowerStateLocked();
Dianne Hackborn254cb442010-01-27 19:23:59 -08001829 }
1830
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001831 /**
Jeff Brownab887a02012-10-15 16:00:40 -07001832 * Reboots the device.
1833 *
1834 * @param confirm If true, shows a reboot confirmation dialog.
1835 * @param reason The reason for the reboot, or null if none.
1836 * @param wait If true, this call waits for the reboot to complete and does not return.
Doug Zongker50a21f42009-11-19 12:49:53 -08001837 */
Jeff Brown96307042012-07-27 15:51:34 -07001838 @Override // Binder call
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001839 public void reboot(boolean confirm, String reason, boolean wait) {
Doug Zongker50a21f42009-11-19 12:49:53 -08001840 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
San Mehat14e69af2010-01-06 14:58:18 -08001841
Jeff Brown96307042012-07-27 15:51:34 -07001842 final long ident = Binder.clearCallingIdentity();
1843 try {
Jeff Brownab887a02012-10-15 16:00:40 -07001844 shutdownOrRebootInternal(false, confirm, reason, wait);
Jeff Brown96307042012-07-27 15:51:34 -07001845 } finally {
1846 Binder.restoreCallingIdentity(ident);
1847 }
1848 }
1849
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001850 /**
Jeff Brownab887a02012-10-15 16:00:40 -07001851 * Shuts down the device.
1852 *
1853 * @param confirm If true, shows a shutdown confirmation dialog.
1854 * @param wait If true, this call waits for the shutdown to complete and does not return.
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001855 */
1856 @Override // Binder call
1857 public void shutdown(boolean confirm, boolean wait) {
1858 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
1859
1860 final long ident = Binder.clearCallingIdentity();
1861 try {
Jeff Brownab887a02012-10-15 16:00:40 -07001862 shutdownOrRebootInternal(true, confirm, null, wait);
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001863 } finally {
1864 Binder.restoreCallingIdentity(ident);
1865 }
1866 }
1867
Jeff Brownab887a02012-10-15 16:00:40 -07001868 private void shutdownOrRebootInternal(final boolean shutdown, final boolean confirm,
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001869 final String reason, boolean wait) {
Jeff Brown96307042012-07-27 15:51:34 -07001870 if (mHandler == null || !mSystemReady) {
Jeff Brownab887a02012-10-15 16:00:40 -07001871 throw new IllegalStateException("Too early to call shutdown() or reboot()");
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001872 }
Mike Lockwoodb62f9592010-03-12 07:55:23 -05001873
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001874 Runnable runnable = new Runnable() {
Jeff Brownab887a02012-10-15 16:00:40 -07001875 @Override
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001876 public void run() {
1877 synchronized (this) {
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001878 if (shutdown) {
1879 ShutdownThread.shutdown(mContext, confirm);
1880 } else {
1881 ShutdownThread.reboot(mContext, reason, confirm);
1882 }
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001883 }
San Mehat1e512792010-01-07 10:40:29 -08001884 }
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001885 };
Jeff Brown96307042012-07-27 15:51:34 -07001886
Mike Lockwoodb62f9592010-03-12 07:55:23 -05001887 // ShutdownThread must run on a looper capable of displaying the UI.
Jeff Brown96307042012-07-27 15:51:34 -07001888 Message msg = Message.obtain(mHandler, runnable);
1889 msg.setAsynchronous(true);
1890 mHandler.sendMessage(msg);
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001891
Mike Lockwoodb62f9592010-03-12 07:55:23 -05001892 // PowerManager.reboot() is documented not to return so just wait for the inevitable.
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001893 if (wait) {
1894 synchronized (runnable) {
1895 while (true) {
1896 try {
1897 runnable.wait();
1898 } catch (InterruptedException e) {
1899 }
Mike Lockwoodb62f9592010-03-12 07:55:23 -05001900 }
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001901 }
Doug Zongker50a21f42009-11-19 12:49:53 -08001902 }
1903 }
1904
Dan Egnor60d87622009-12-16 16:32:58 -08001905 /**
1906 * Crash the runtime (causing a complete restart of the Android framework).
1907 * Requires REBOOT permission. Mostly for testing. Should not return.
1908 */
Jeff Brown96307042012-07-27 15:51:34 -07001909 @Override // Binder call
1910 public void crash(String message) {
Dan Egnor60d87622009-12-16 16:32:58 -08001911 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
Jeff Brown96307042012-07-27 15:51:34 -07001912
1913 final long ident = Binder.clearCallingIdentity();
1914 try {
1915 crashInternal(message);
1916 } finally {
1917 Binder.restoreCallingIdentity(ident);
1918 }
1919 }
1920
1921 private void crashInternal(final String message) {
Dan Egnor60d87622009-12-16 16:32:58 -08001922 Thread t = new Thread("PowerManagerService.crash()") {
Jeff Brownab887a02012-10-15 16:00:40 -07001923 @Override
Jeff Brown96307042012-07-27 15:51:34 -07001924 public void run() {
1925 throw new RuntimeException(message);
1926 }
Dan Egnor60d87622009-12-16 16:32:58 -08001927 };
1928 try {
1929 t.start();
1930 t.join();
1931 } catch (InterruptedException e) {
1932 Log.wtf(TAG, e);
1933 }
1934 }
1935
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001936 /**
Jeff Brown96307042012-07-27 15:51:34 -07001937 * Set the setting that determines whether the device stays on when plugged in.
1938 * The argument is a bit string, with each bit specifying a power source that,
1939 * when the device is connected to that source, causes the device to stay on.
1940 * See {@link android.os.BatteryManager} for the list of power sources that
1941 * can be specified. Current values include {@link android.os.BatteryManager#BATTERY_PLUGGED_AC}
1942 * and {@link android.os.BatteryManager#BATTERY_PLUGGED_USB}
1943 *
1944 * Used by "adb shell svc power stayon ..."
1945 *
1946 * @param val an {@code int} containing the bits that specify which power sources
1947 * should cause the device to stay on.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001948 */
Jeff Brown96307042012-07-27 15:51:34 -07001949 @Override // Binder call
1950 public void setStayOnSetting(int val) {
1951 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS, null);
1952
1953 final long ident = Binder.clearCallingIdentity();
1954 try {
1955 setStayOnSettingInternal(val);
1956 } finally {
1957 Binder.restoreCallingIdentity(ident);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001958 }
1959 }
1960
Jeff Brown96307042012-07-27 15:51:34 -07001961 private void setStayOnSettingInternal(int val) {
Christopher Tatead735322012-09-07 14:19:43 -07001962 Settings.Global.putInt(mContext.getContentResolver(),
1963 Settings.Global.STAY_ON_WHILE_PLUGGED_IN, val);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001964 }
1965
1966 /**
Jeff Brown96307042012-07-27 15:51:34 -07001967 * Used by device administration to set the maximum screen off timeout.
1968 *
1969 * This method must only be called by the device administration policy manager.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001970 */
Jeff Brown96307042012-07-27 15:51:34 -07001971 @Override // Binder call
1972 public void setMaximumScreenOffTimeoutFromDeviceAdmin(int timeMs) {
1973 final long ident = Binder.clearCallingIdentity();
1974 try {
1975 setMaximumScreenOffTimeoutFromDeviceAdminInternal(timeMs);
1976 } finally {
1977 Binder.restoreCallingIdentity(ident);
Michael Chane96440f2009-05-06 10:27:36 -07001978 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001979 }
1980
Jeff Brown96307042012-07-27 15:51:34 -07001981 private void setMaximumScreenOffTimeoutFromDeviceAdminInternal(int timeMs) {
1982 synchronized (mLock) {
1983 mMaximumScreenOffTimeoutFromDeviceAdmin = timeMs;
1984 mDirty |= DIRTY_SETTINGS;
1985 updatePowerStateLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001986 }
1987 }
1988
Jeff Brown96307042012-07-27 15:51:34 -07001989 private boolean isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked() {
1990 return mMaximumScreenOffTimeoutFromDeviceAdmin >= 0
1991 && mMaximumScreenOffTimeoutFromDeviceAdmin < Integer.MAX_VALUE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001992 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001993
Jeff Brown96307042012-07-27 15:51:34 -07001994 /**
1995 * Used by the phone application to make the attention LED flash when ringing.
1996 */
1997 @Override // Binder call
Mike Lockwoodb11832d2009-11-25 15:25:55 -05001998 public void setAttentionLight(boolean on, int color) {
1999 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
Jeff Brown96307042012-07-27 15:51:34 -07002000
2001 final long ident = Binder.clearCallingIdentity();
2002 try {
2003 setAttentionLightInternal(on, color);
2004 } finally {
2005 Binder.restoreCallingIdentity(ident);
2006 }
Mike Lockwoodb11832d2009-11-25 15:25:55 -05002007 }
2008
Jeff Brown96307042012-07-27 15:51:34 -07002009 private void setAttentionLightInternal(boolean on, int color) {
2010 LightsService.Light light;
2011 synchronized (mLock) {
2012 if (!mSystemReady) {
2013 return;
2014 }
2015 light = mAttentionLight;
Mike Lockwood36fc3022009-08-25 16:49:06 -07002016 }
Jeff Brown96307042012-07-27 15:51:34 -07002017
2018 // Control light outside of lock.
2019 light.setFlashing(color, LightsService.LIGHT_FLASH_HARDWARE, (on ? 3 : 0), 0);
2020 }
2021
2022 /**
2023 * Used by the Watchdog.
2024 */
2025 public long timeSinceScreenWasLastOn() {
2026 synchronized (mLock) {
2027 if (mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF) {
2028 return 0;
2029 }
2030 return SystemClock.elapsedRealtime() - mLastScreenOffEventElapsedRealTime;
2031 }
2032 }
2033
2034 /**
2035 * Used by the window manager to override the screen brightness based on the
2036 * current foreground activity.
2037 *
2038 * This method must only be called by the window manager.
2039 *
2040 * @param brightness The overridden brightness, or -1 to disable the override.
2041 */
2042 public void setScreenBrightnessOverrideFromWindowManager(int brightness) {
2043 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
2044
2045 final long ident = Binder.clearCallingIdentity();
2046 try {
2047 setScreenBrightnessOverrideFromWindowManagerInternal(brightness);
2048 } finally {
2049 Binder.restoreCallingIdentity(ident);
2050 }
2051 }
2052
2053 private void setScreenBrightnessOverrideFromWindowManagerInternal(int brightness) {
2054 synchronized (mLock) {
2055 if (mScreenBrightnessOverrideFromWindowManager != brightness) {
2056 mScreenBrightnessOverrideFromWindowManager = brightness;
2057 mDirty |= DIRTY_SETTINGS;
2058 updatePowerStateLocked();
Mike Lockwoodee2b0942009-11-09 14:09:02 -05002059 }
Mike Lockwood809ad0f2009-10-26 22:10:33 -04002060 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07002061 }
2062
Jeff Brown96307042012-07-27 15:51:34 -07002063 /**
2064 * Used by the window manager to override the button brightness based on the
2065 * current foreground activity.
2066 *
2067 * This method must only be called by the window manager.
2068 *
2069 * @param brightness The overridden brightness, or -1 to disable the override.
2070 */
2071 public void setButtonBrightnessOverrideFromWindowManager(int brightness) {
2072 // Do nothing.
2073 // Button lights are not currently supported in the new implementation.
2074 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
2075 }
2076
2077 /**
Jeff Brown1e3b98d2012-09-30 18:58:59 -07002078 * Used by the window manager to override the user activity timeout based on the
2079 * current foreground activity. It can only be used to make the timeout shorter
2080 * than usual, not longer.
2081 *
2082 * This method must only be called by the window manager.
2083 *
2084 * @param timeoutMillis The overridden timeout, or -1 to disable the override.
2085 */
2086 public void setUserActivityTimeoutOverrideFromWindowManager(long timeoutMillis) {
2087 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
2088
2089 final long ident = Binder.clearCallingIdentity();
2090 try {
2091 setUserActivityTimeoutOverrideFromWindowManagerInternal(timeoutMillis);
2092 } finally {
2093 Binder.restoreCallingIdentity(ident);
2094 }
2095 }
2096
2097 private void setUserActivityTimeoutOverrideFromWindowManagerInternal(long timeoutMillis) {
2098 synchronized (mLock) {
2099 if (mUserActivityTimeoutOverrideFromWindowManager != timeoutMillis) {
2100 mUserActivityTimeoutOverrideFromWindowManager = timeoutMillis;
2101 mDirty |= DIRTY_SETTINGS;
2102 updatePowerStateLocked();
2103 }
2104 }
2105 }
2106
2107 /**
Jeff Brown96307042012-07-27 15:51:34 -07002108 * Used by the settings application and brightness control widgets to
2109 * temporarily override the current screen brightness setting so that the
2110 * user can observe the effect of an intended settings change without applying
2111 * it immediately.
2112 *
2113 * The override will be canceled when the setting value is next updated.
2114 *
2115 * @param brightness The overridden brightness.
2116 *
2117 * @see Settings.System#SCREEN_BRIGHTNESS
2118 */
2119 @Override // Binder call
2120 public void setTemporaryScreenBrightnessSettingOverride(int brightness) {
2121 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
2122
2123 final long ident = Binder.clearCallingIdentity();
2124 try {
2125 setTemporaryScreenBrightnessSettingOverrideInternal(brightness);
2126 } finally {
2127 Binder.restoreCallingIdentity(ident);
Mike Lockwood36fc3022009-08-25 16:49:06 -07002128 }
Jeff Brown96307042012-07-27 15:51:34 -07002129 }
2130
2131 private void setTemporaryScreenBrightnessSettingOverrideInternal(int brightness) {
2132 synchronized (mLock) {
2133 if (mTemporaryScreenBrightnessSettingOverride != brightness) {
2134 mTemporaryScreenBrightnessSettingOverride = brightness;
2135 mDirty |= DIRTY_SETTINGS;
2136 updatePowerStateLocked();
Mike Lockwoodee2b0942009-11-09 14:09:02 -05002137 }
Mike Lockwood200b30b2009-09-20 00:23:59 -04002138 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07002139 }
2140
Jeff Brown96307042012-07-27 15:51:34 -07002141 /**
2142 * Used by the settings application and brightness control widgets to
2143 * temporarily override the current screen auto-brightness adjustment setting so that the
2144 * user can observe the effect of an intended settings change without applying
2145 * it immediately.
2146 *
2147 * The override will be canceled when the setting value is next updated.
2148 *
Jeff Brown330560f2012-08-21 22:10:57 -07002149 * @param adj The overridden brightness, or Float.NaN to disable the override.
Jeff Brown96307042012-07-27 15:51:34 -07002150 *
2151 * @see Settings.System#SCREEN_AUTO_BRIGHTNESS_ADJ
2152 */
2153 @Override // Binder call
2154 public void setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(float adj) {
Jeff Brown96307042012-07-27 15:51:34 -07002155 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
Jeff Brown330560f2012-08-21 22:10:57 -07002156
2157 final long ident = Binder.clearCallingIdentity();
2158 try {
2159 setTemporaryScreenAutoBrightnessAdjustmentSettingOverrideInternal(adj);
2160 } finally {
2161 Binder.restoreCallingIdentity(ident);
2162 }
2163 }
2164
2165 private void setTemporaryScreenAutoBrightnessAdjustmentSettingOverrideInternal(float adj) {
2166 synchronized (mLock) {
2167 // Note: This condition handles NaN because NaN is not equal to any other
2168 // value, including itself.
2169 if (mTemporaryScreenAutoBrightnessAdjustmentSettingOverride != adj) {
2170 mTemporaryScreenAutoBrightnessAdjustmentSettingOverride = adj;
2171 mDirty |= DIRTY_SETTINGS;
2172 updatePowerStateLocked();
2173 }
2174 }
Jeff Brown96307042012-07-27 15:51:34 -07002175 }
2176
2177 /**
2178 * Low-level function turn the device off immediately, without trying
2179 * to be clean. Most people should use {@link ShutdownThread} for a clean shutdown.
2180 */
2181 public static void lowLevelShutdown() {
Nick Kralevichdbcf2d72013-04-18 14:41:40 -07002182 SystemProperties.set("sys.powerctl", "shutdown");
Jeff Brown96307042012-07-27 15:51:34 -07002183 }
2184
2185 /**
Nick Kralevichdbcf2d72013-04-18 14:41:40 -07002186 * Low-level function to reboot the device. On success, this function
2187 * doesn't return. If more than 5 seconds passes from the time,
2188 * a reboot is requested, this method returns.
Jeff Brown96307042012-07-27 15:51:34 -07002189 *
2190 * @param reason code to pass to the kernel (e.g. "recovery"), or null.
Jeff Brown96307042012-07-27 15:51:34 -07002191 */
Nick Kralevichdbcf2d72013-04-18 14:41:40 -07002192 public static void lowLevelReboot(String reason) {
2193 if (reason == null) {
2194 reason = "";
2195 }
2196 SystemProperties.set("sys.powerctl", "reboot," + reason);
2197 try {
2198 Thread.sleep(20000);
2199 } catch (InterruptedException e) {
2200 Thread.currentThread().interrupt();
2201 }
Jeff Brown96307042012-07-27 15:51:34 -07002202 }
2203
2204 @Override // Watchdog.Monitor implementation
2205 public void monitor() {
2206 // Grab and release lock for watchdog monitor to detect deadlocks.
2207 synchronized (mLock) {
Mike Lockwood20f87d72009-11-05 16:08:51 -05002208 }
Jeff Brown96307042012-07-27 15:51:34 -07002209 }
2210
2211 @Override // Binder call
2212 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2213 if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
2214 != PackageManager.PERMISSION_GRANTED) {
2215 pw.println("Permission Denial: can't dump PowerManager from from pid="
2216 + Binder.getCallingPid()
2217 + ", uid=" + Binder.getCallingUid());
Mike Lockwood0d72f7e2009-11-05 20:53:00 -05002218 return;
2219 }
Jeff Brown96307042012-07-27 15:51:34 -07002220
2221 pw.println("POWER MANAGER (dumpsys power)\n");
2222
2223 final DisplayPowerController dpc;
Jeff Brown3b971592013-01-09 18:46:37 -08002224 final WirelessChargerDetector wcd;
Jeff Brown96307042012-07-27 15:51:34 -07002225 synchronized (mLock) {
2226 pw.println("Power Manager State:");
2227 pw.println(" mDirty=0x" + Integer.toHexString(mDirty));
2228 pw.println(" mWakefulness=" + wakefulnessToString(mWakefulness));
2229 pw.println(" mIsPowered=" + mIsPowered);
Jeff Brownf3fb8952012-10-02 20:57:05 -07002230 pw.println(" mPlugType=" + mPlugType);
Jeff Brown016ff142012-10-15 16:47:22 -07002231 pw.println(" mBatteryLevel=" + mBatteryLevel);
2232 pw.println(" mBatteryLevelWhenDreamStarted=" + mBatteryLevelWhenDreamStarted);
Jeff Brownec6aa592012-10-17 20:30:25 -07002233 pw.println(" mDockState=" + mDockState);
Jeff Brown96307042012-07-27 15:51:34 -07002234 pw.println(" mStayOn=" + mStayOn);
Jeff Brown93cbbb22012-10-04 13:18:36 -07002235 pw.println(" mProximityPositive=" + mProximityPositive);
Jeff Brown96307042012-07-27 15:51:34 -07002236 pw.println(" mBootCompleted=" + mBootCompleted);
2237 pw.println(" mSystemReady=" + mSystemReady);
2238 pw.println(" mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary));
2239 pw.println(" mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary));
2240 pw.println(" mRequestWaitForNegativeProximity=" + mRequestWaitForNegativeProximity);
2241 pw.println(" mSandmanScheduled=" + mSandmanScheduled);
2242 pw.println(" mLastWakeTime=" + TimeUtils.formatUptime(mLastWakeTime));
2243 pw.println(" mLastSleepTime=" + TimeUtils.formatUptime(mLastSleepTime));
2244 pw.println(" mSendWakeUpFinishedNotificationWhenReady="
2245 + mSendWakeUpFinishedNotificationWhenReady);
2246 pw.println(" mSendGoToSleepFinishedNotificationWhenReady="
2247 + mSendGoToSleepFinishedNotificationWhenReady);
2248 pw.println(" mLastUserActivityTime=" + TimeUtils.formatUptime(mLastUserActivityTime));
2249 pw.println(" mLastUserActivityTimeNoChangeLights="
2250 + TimeUtils.formatUptime(mLastUserActivityTimeNoChangeLights));
2251 pw.println(" mDisplayReady=" + mDisplayReady);
2252 pw.println(" mHoldingWakeLockSuspendBlocker=" + mHoldingWakeLockSuspendBlocker);
Jeff Brown27f7a862012-12-12 15:43:31 -08002253 pw.println(" mHoldingDisplaySuspendBlocker=" + mHoldingDisplaySuspendBlocker);
Jeff Brown96307042012-07-27 15:51:34 -07002254
2255 pw.println();
2256 pw.println("Settings and Configuration:");
2257 pw.println(" mDreamsSupportedConfig=" + mDreamsSupportedConfig);
2258 pw.println(" mDreamsEnabledSetting=" + mDreamsEnabledSetting);
John Spurlock1a868b72012-08-22 09:56:51 -04002259 pw.println(" mDreamsActivateOnSleepSetting=" + mDreamsActivateOnSleepSetting);
Jeff Brownec6aa592012-10-17 20:30:25 -07002260 pw.println(" mDreamsActivateOnDockSetting=" + mDreamsActivateOnDockSetting);
Jeff Brown96307042012-07-27 15:51:34 -07002261 pw.println(" mScreenOffTimeoutSetting=" + mScreenOffTimeoutSetting);
2262 pw.println(" mMaximumScreenOffTimeoutFromDeviceAdmin="
2263 + mMaximumScreenOffTimeoutFromDeviceAdmin + " (enforced="
2264 + isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked() + ")");
2265 pw.println(" mStayOnWhilePluggedInSetting=" + mStayOnWhilePluggedInSetting);
2266 pw.println(" mScreenBrightnessSetting=" + mScreenBrightnessSetting);
Jeff Brown330560f2012-08-21 22:10:57 -07002267 pw.println(" mScreenAutoBrightnessAdjustmentSetting="
2268 + mScreenAutoBrightnessAdjustmentSetting);
Jeff Brown96307042012-07-27 15:51:34 -07002269 pw.println(" mScreenBrightnessModeSetting=" + mScreenBrightnessModeSetting);
2270 pw.println(" mScreenBrightnessOverrideFromWindowManager="
2271 + mScreenBrightnessOverrideFromWindowManager);
Jeff Brown1e3b98d2012-09-30 18:58:59 -07002272 pw.println(" mUserActivityTimeoutOverrideFromWindowManager="
2273 + mUserActivityTimeoutOverrideFromWindowManager);
Jeff Brown96307042012-07-27 15:51:34 -07002274 pw.println(" mTemporaryScreenBrightnessSettingOverride="
2275 + mTemporaryScreenBrightnessSettingOverride);
Jeff Brown330560f2012-08-21 22:10:57 -07002276 pw.println(" mTemporaryScreenAutoBrightnessAdjustmentSettingOverride="
2277 + mTemporaryScreenAutoBrightnessAdjustmentSettingOverride);
Jeff Brown96307042012-07-27 15:51:34 -07002278 pw.println(" mScreenBrightnessSettingMinimum=" + mScreenBrightnessSettingMinimum);
2279 pw.println(" mScreenBrightnessSettingMaximum=" + mScreenBrightnessSettingMaximum);
2280 pw.println(" mScreenBrightnessSettingDefault=" + mScreenBrightnessSettingDefault);
2281
Jeff Brownff532542012-10-02 21:18:04 -07002282 final int screenOffTimeout = getScreenOffTimeoutLocked();
2283 final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
2284 pw.println();
2285 pw.println("Screen off timeout: " + screenOffTimeout + " ms");
2286 pw.println("Screen dim duration: " + screenDimDuration + " ms");
2287
Jeff Brown96307042012-07-27 15:51:34 -07002288 pw.println();
2289 pw.println("Wake Locks: size=" + mWakeLocks.size());
2290 for (WakeLock wl : mWakeLocks) {
2291 pw.println(" " + wl);
Joe Onorato8274a0e2010-10-05 17:38:09 -04002292 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05002293
Jeff Brown96307042012-07-27 15:51:34 -07002294 pw.println();
2295 pw.println("Suspend Blockers: size=" + mSuspendBlockers.size());
2296 for (SuspendBlocker sb : mSuspendBlockers) {
2297 pw.println(" " + sb);
2298 }
2299
Jeff Brownc38c9be2012-10-04 13:16:19 -07002300 pw.println();
2301 pw.println("Screen On Blocker: " + mScreenOnBlocker);
2302
Jeff Brown9e316a12012-10-08 19:17:06 -07002303 pw.println();
2304 pw.println("Display Blanker: " + mDisplayBlanker);
2305
Jeff Brown96307042012-07-27 15:51:34 -07002306 dpc = mDisplayPowerController;
Jeff Brown3b971592013-01-09 18:46:37 -08002307 wcd = mWirelessChargerDetector;
Jeff Brown96307042012-07-27 15:51:34 -07002308 }
2309
2310 if (dpc != null) {
2311 dpc.dump(pw);
2312 }
Jeff Brown3b971592013-01-09 18:46:37 -08002313
2314 if (wcd != null) {
2315 wcd.dump(pw);
2316 }
Jeff Brown96307042012-07-27 15:51:34 -07002317 }
2318
2319 private SuspendBlocker createSuspendBlockerLocked(String name) {
2320 SuspendBlocker suspendBlocker = new SuspendBlockerImpl(name);
2321 mSuspendBlockers.add(suspendBlocker);
2322 return suspendBlocker;
2323 }
2324
2325 private static String wakefulnessToString(int wakefulness) {
2326 switch (wakefulness) {
2327 case WAKEFULNESS_ASLEEP:
2328 return "Asleep";
2329 case WAKEFULNESS_AWAKE:
2330 return "Awake";
2331 case WAKEFULNESS_DREAMING:
2332 return "Dreaming";
2333 case WAKEFULNESS_NAPPING:
2334 return "Napping";
2335 default:
2336 return Integer.toString(wakefulness);
2337 }
2338 }
2339
2340 private static WorkSource copyWorkSource(WorkSource workSource) {
2341 return workSource != null ? new WorkSource(workSource) : null;
2342 }
2343
2344 private final class BatteryReceiver extends BroadcastReceiver {
2345 @Override
2346 public void onReceive(Context context, Intent intent) {
2347 synchronized (mLock) {
2348 handleBatteryStateChangedLocked();
Mike Lockwoodee2b0942009-11-09 14:09:02 -05002349 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05002350 }
2351 }
2352
Jeff Brown96307042012-07-27 15:51:34 -07002353 private final class BootCompletedReceiver extends BroadcastReceiver {
2354 @Override
2355 public void onReceive(Context context, Intent intent) {
Jeff Brown20767b22012-10-09 18:57:07 -07002356 // This is our early signal that the system thinks it has finished booting.
2357 // However, the boot animation may still be running for a few more seconds
2358 // since it is ultimately in charge of when it terminates.
2359 // Defer transitioning into the boot completed state until the animation exits.
2360 // We do this so that the screen does not start to dim prematurely before
2361 // the user has actually had a chance to interact with the device.
2362 startWatchingForBootAnimationFinished();
Joe Onoratod28f7532010-11-06 12:56:53 -07002363 }
Jeff Brown96307042012-07-27 15:51:34 -07002364 }
2365
John Spurlockf4f6b4c2012-08-25 12:08:03 -04002366 private final class DreamReceiver extends BroadcastReceiver {
2367 @Override
2368 public void onReceive(Context context, Intent intent) {
2369 synchronized (mLock) {
Jeff Brown62c82e42012-09-26 01:30:41 -07002370 scheduleSandmanLocked();
John Spurlockf4f6b4c2012-08-25 12:08:03 -04002371 }
2372 }
2373 }
2374
Jeff Brownd4935962012-09-25 13:27:20 -07002375 private final class UserSwitchedReceiver extends BroadcastReceiver {
2376 @Override
2377 public void onReceive(Context context, Intent intent) {
2378 synchronized (mLock) {
2379 handleSettingsChangedLocked();
2380 }
2381 }
2382 }
2383
Jeff Brownec6aa592012-10-17 20:30:25 -07002384 private final class DockReceiver extends BroadcastReceiver {
2385 @Override
2386 public void onReceive(Context context, Intent intent) {
2387 synchronized (mLock) {
2388 int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
2389 Intent.EXTRA_DOCK_STATE_UNDOCKED);
2390 if (mDockState != dockState) {
2391 mDockState = dockState;
2392 mDirty |= DIRTY_DOCK_STATE;
2393 updatePowerStateLocked();
2394 }
2395 }
2396 }
2397 }
2398
Jeff Brown96307042012-07-27 15:51:34 -07002399 private final class SettingsObserver extends ContentObserver {
2400 public SettingsObserver(Handler handler) {
2401 super(handler);
2402 }
2403
2404 @Override
2405 public void onChange(boolean selfChange, Uri uri) {
2406 synchronized (mLock) {
2407 handleSettingsChangedLocked();
2408 }
2409 }
2410 }
2411
Jeff Brown96307042012-07-27 15:51:34 -07002412 /**
2413 * Handler for asynchronous operations performed by the power manager.
2414 */
2415 private final class PowerManagerHandler extends Handler {
2416 public PowerManagerHandler(Looper looper) {
Jeff Browna2910d02012-08-25 12:29:46 -07002417 super(looper, null, true /*async*/);
Jeff Brown96307042012-07-27 15:51:34 -07002418 }
2419
2420 @Override
2421 public void handleMessage(Message msg) {
2422 switch (msg.what) {
2423 case MSG_USER_ACTIVITY_TIMEOUT:
2424 handleUserActivityTimeout();
2425 break;
2426 case MSG_SANDMAN:
2427 handleSandman();
2428 break;
Jeff Brownc38c9be2012-10-04 13:16:19 -07002429 case MSG_SCREEN_ON_BLOCKER_RELEASED:
2430 handleScreenOnBlockerReleased();
2431 break;
Jeff Brown20767b22012-10-09 18:57:07 -07002432 case MSG_CHECK_IF_BOOT_ANIMATION_FINISHED:
2433 checkIfBootAnimationFinished();
2434 break;
Jeff Brown96307042012-07-27 15:51:34 -07002435 }
2436 }
2437 }
2438
2439 /**
2440 * Represents a wake lock that has been acquired by an application.
2441 */
2442 private final class WakeLock implements IBinder.DeathRecipient {
2443 public final IBinder mLock;
2444 public int mFlags;
2445 public String mTag;
Dianne Hackborn713df152013-05-17 11:27:57 -07002446 public final String mPackageName;
Jeff Brown96307042012-07-27 15:51:34 -07002447 public WorkSource mWorkSource;
Dianne Hackborn713df152013-05-17 11:27:57 -07002448 public final int mOwnerUid;
2449 public final int mOwnerPid;
2450 public boolean mNotifiedAcquired;
Jeff Brown96307042012-07-27 15:51:34 -07002451
Dianne Hackborn713df152013-05-17 11:27:57 -07002452 public WakeLock(IBinder lock, int flags, String tag, String packageName,
2453 WorkSource workSource, int ownerUid, int ownerPid) {
Jeff Brown96307042012-07-27 15:51:34 -07002454 mLock = lock;
2455 mFlags = flags;
2456 mTag = tag;
Dianne Hackborn713df152013-05-17 11:27:57 -07002457 mPackageName = packageName;
Jeff Brown96307042012-07-27 15:51:34 -07002458 mWorkSource = copyWorkSource(workSource);
2459 mOwnerUid = ownerUid;
2460 mOwnerPid = ownerPid;
2461 }
2462
2463 @Override
2464 public void binderDied() {
2465 PowerManagerService.this.handleWakeLockDeath(this);
2466 }
2467
2468 public boolean hasSameProperties(int flags, String tag, WorkSource workSource,
2469 int ownerUid, int ownerPid) {
2470 return mFlags == flags
2471 && mTag.equals(tag)
2472 && hasSameWorkSource(workSource)
2473 && mOwnerUid == ownerUid
2474 && mOwnerPid == ownerPid;
2475 }
2476
Dianne Hackborn713df152013-05-17 11:27:57 -07002477 public void updateProperties(int flags, String tag, String packageName,
2478 WorkSource workSource, int ownerUid, int ownerPid) {
2479 if (!mPackageName.equals(packageName)) {
2480 throw new IllegalStateException("Existing wake lock package name changed: "
2481 + mPackageName + " to " + packageName);
2482 }
2483 if (mOwnerUid != ownerUid) {
2484 throw new IllegalStateException("Existing wake lock uid changed: "
2485 + mOwnerUid + " to " + ownerUid);
2486 }
2487 if (mOwnerPid != ownerPid) {
2488 throw new IllegalStateException("Existing wake lock pid changed: "
2489 + mOwnerPid + " to " + ownerPid);
2490 }
Jeff Brown96307042012-07-27 15:51:34 -07002491 mFlags = flags;
2492 mTag = tag;
2493 updateWorkSource(workSource);
Jeff Brown96307042012-07-27 15:51:34 -07002494 }
2495
2496 public boolean hasSameWorkSource(WorkSource workSource) {
2497 return Objects.equal(mWorkSource, workSource);
2498 }
2499
2500 public void updateWorkSource(WorkSource workSource) {
2501 mWorkSource = copyWorkSource(workSource);
2502 }
2503
2504 @Override
2505 public String toString() {
2506 return getLockLevelString()
2507 + " '" + mTag + "'" + getLockFlagsString()
2508 + " (uid=" + mOwnerUid + ", pid=" + mOwnerPid + ", ws=" + mWorkSource + ")";
2509 }
2510
2511 private String getLockLevelString() {
2512 switch (mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
2513 case PowerManager.FULL_WAKE_LOCK:
2514 return "FULL_WAKE_LOCK ";
2515 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
2516 return "SCREEN_BRIGHT_WAKE_LOCK ";
2517 case PowerManager.SCREEN_DIM_WAKE_LOCK:
2518 return "SCREEN_DIM_WAKE_LOCK ";
2519 case PowerManager.PARTIAL_WAKE_LOCK:
2520 return "PARTIAL_WAKE_LOCK ";
2521 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
2522 return "PROXIMITY_SCREEN_OFF_WAKE_LOCK";
2523 default:
2524 return "??? ";
2525 }
2526 }
2527
2528 private String getLockFlagsString() {
2529 String result = "";
2530 if ((mFlags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {
2531 result += " ACQUIRE_CAUSES_WAKEUP";
2532 }
2533 if ((mFlags & PowerManager.ON_AFTER_RELEASE) != 0) {
2534 result += " ON_AFTER_RELEASE";
2535 }
2536 return result;
2537 }
2538 }
2539
2540 private final class SuspendBlockerImpl implements SuspendBlocker {
2541 private final String mName;
2542 private int mReferenceCount;
2543
2544 public SuspendBlockerImpl(String name) {
2545 mName = name;
2546 }
2547
2548 @Override
2549 protected void finalize() throws Throwable {
Mike Lockwood809ad0f2009-10-26 22:10:33 -04002550 try {
Jeff Brown96307042012-07-27 15:51:34 -07002551 if (mReferenceCount != 0) {
2552 Log.wtf(TAG, "Suspend blocker \"" + mName
2553 + "\" was finalized without being released!");
2554 mReferenceCount = 0;
2555 nativeReleaseSuspendBlocker(mName);
Mike Lockwood809ad0f2009-10-26 22:10:33 -04002556 }
2557 } finally {
Jeff Brown96307042012-07-27 15:51:34 -07002558 super.finalize();
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002559 }
2560 }
2561
Craig Mautner75fc9de2012-06-18 16:53:27 -07002562 @Override
Jeff Brown96307042012-07-27 15:51:34 -07002563 public void acquire() {
2564 synchronized (this) {
2565 mReferenceCount += 1;
2566 if (mReferenceCount == 1) {
Jeff Brown27f7a862012-12-12 15:43:31 -08002567 if (DEBUG_SPEW) {
2568 Slog.d(TAG, "Acquiring suspend blocker \"" + mName + "\".");
2569 }
Jeff Brown96307042012-07-27 15:51:34 -07002570 nativeAcquireSuspendBlocker(mName);
Craig Mautner37933682012-06-06 14:13:39 -07002571 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002572 }
2573 }
2574
Craig Mautner75fc9de2012-06-18 16:53:27 -07002575 @Override
Jeff Brown96307042012-07-27 15:51:34 -07002576 public void release() {
2577 synchronized (this) {
2578 mReferenceCount -= 1;
2579 if (mReferenceCount == 0) {
Jeff Brown27f7a862012-12-12 15:43:31 -08002580 if (DEBUG_SPEW) {
2581 Slog.d(TAG, "Releasing suspend blocker \"" + mName + "\".");
2582 }
Jeff Brown96307042012-07-27 15:51:34 -07002583 nativeReleaseSuspendBlocker(mName);
2584 } else if (mReferenceCount < 0) {
2585 Log.wtf(TAG, "Suspend blocker \"" + mName
2586 + "\" was released without being acquired!", new Throwable());
2587 mReferenceCount = 0;
2588 }
2589 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002590 }
Jeff Brown96307042012-07-27 15:51:34 -07002591
2592 @Override
2593 public String toString() {
2594 synchronized (this) {
2595 return mName + ": ref count=" + mReferenceCount;
2596 }
2597 }
2598 }
Jeff Brownc38c9be2012-10-04 13:16:19 -07002599
2600 private final class ScreenOnBlockerImpl implements ScreenOnBlocker {
2601 private int mNestCount;
2602
2603 public boolean isHeld() {
2604 synchronized (this) {
2605 return mNestCount != 0;
2606 }
2607 }
2608
2609 @Override
2610 public void acquire() {
2611 synchronized (this) {
2612 mNestCount += 1;
2613 if (DEBUG) {
2614 Slog.d(TAG, "Screen on blocked: mNestCount=" + mNestCount);
2615 }
2616 }
2617 }
2618
2619 @Override
2620 public void release() {
2621 synchronized (this) {
2622 mNestCount -= 1;
2623 if (mNestCount < 0) {
2624 Log.wtf(TAG, "Screen on blocker was released without being acquired!",
2625 new Throwable());
2626 mNestCount = 0;
2627 }
2628 if (mNestCount == 0) {
2629 mHandler.sendEmptyMessage(MSG_SCREEN_ON_BLOCKER_RELEASED);
2630 }
2631 if (DEBUG) {
2632 Slog.d(TAG, "Screen on unblocked: mNestCount=" + mNestCount);
2633 }
2634 }
2635 }
2636
2637 @Override
2638 public String toString() {
2639 synchronized (this) {
2640 return "held=" + (mNestCount != 0) + ", mNestCount=" + mNestCount;
2641 }
2642 }
Jeff Brown9e316a12012-10-08 19:17:06 -07002643 }
2644
2645 private final class DisplayBlankerImpl implements DisplayBlanker {
2646 private boolean mBlanked;
2647
2648 @Override
2649 public void blankAllDisplays() {
2650 synchronized (this) {
2651 mBlanked = true;
2652 mDisplayManagerService.blankAllDisplaysFromPowerManager();
2653 nativeSetInteractive(false);
2654 nativeSetAutoSuspend(true);
2655 }
2656 }
2657
2658 @Override
2659 public void unblankAllDisplays() {
2660 synchronized (this) {
2661 nativeSetAutoSuspend(false);
2662 nativeSetInteractive(true);
2663 mDisplayManagerService.unblankAllDisplaysFromPowerManager();
2664 mBlanked = false;
2665 }
2666 }
2667
2668 @Override
2669 public String toString() {
2670 synchronized (this) {
2671 return "blanked=" + mBlanked;
2672 }
2673 }
2674 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002675}