blob: 6f70712db20bb3a4ffee6bb966eb20ccc03afda6 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jeff Brown4f8ecd82012-06-18 18:29:13 -070017package com.android.server.power;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018
19import com.android.internal.app.IBatteryStats;
Jeff Brown4f8ecd82012-06-18 18:29:13 -070020import com.android.server.BatteryService;
21import com.android.server.EventLogTags;
22import com.android.server.LightsService;
Jeff Brownaa202a62012-08-21 22:14:26 -070023import com.android.server.TwilightService;
Jeff Brown4f8ecd82012-06-18 18:29:13 -070024import com.android.server.Watchdog;
Jeff Brown96307042012-07-27 15:51:34 -070025import com.android.server.am.ActivityManagerService;
Jeff Brownfa25bf52012-07-23 19:26:30 -070026import com.android.server.display.DisplayManagerService;
Jeff Brown62c82e42012-09-26 01:30:41 -070027import com.android.server.dreams.DreamManagerService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028
Jeff Brown96307042012-07-27 15:51:34 -070029import android.Manifest;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.content.BroadcastReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import android.content.ContentResolver;
32import android.content.Context;
33import android.content.Intent;
34import android.content.IntentFilter;
35import android.content.pm.PackageManager;
Mike Lockwoodd7786b42009-10-15 17:09:16 -070036import android.content.res.Resources;
Doug Zongker43866e02010-01-07 12:09:54 -080037import android.database.ContentObserver;
Jeff Brown3b971592013-01-09 18:46:37 -080038import android.hardware.SensorManager;
39import android.hardware.SystemSensorManager;
Jeff Brown96307042012-07-27 15:51:34 -070040import android.net.Uri;
Amith Yamasani8b619832010-09-22 16:11:59 -070041import android.os.BatteryManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042import android.os.Binder;
43import android.os.Handler;
44import android.os.HandlerThread;
45import android.os.IBinder;
46import android.os.IPowerManager;
Jeff Brown96307042012-07-27 15:51:34 -070047import android.os.Looper;
Jim Miller92e66dd2012-02-21 18:57:12 -080048import android.os.Message;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049import android.os.PowerManager;
50import android.os.Process;
51import android.os.RemoteException;
52import android.os.SystemClock;
Jeff Brown20767b22012-10-09 18:57:07 -070053import android.os.SystemService;
Jeff Brownd4935962012-09-25 13:27:20 -070054import android.os.UserHandle;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070055import android.os.WorkSource;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056import android.provider.Settings;
57import android.util.EventLog;
58import android.util.Log;
Joe Onorato8a9b2202010-02-26 18:56:32 -080059import android.util.Slog;
Jeff Brown96307042012-07-27 15:51:34 -070060import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061import android.view.WindowManagerPolicy;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062
63import java.io.FileDescriptor;
Jeff Brown7304c342012-05-11 18:42:42 -070064import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065import java.io.PrintWriter;
66import java.util.ArrayList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067
Jeff Brown96307042012-07-27 15:51:34 -070068import libcore.util.Objects;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069
Jeff Brown96307042012-07-27 15:51:34 -070070/**
71 * The power manager service is responsible for coordinating power management
72 * functions on the device.
73 */
74public final class PowerManagerService extends IPowerManager.Stub
75 implements Watchdog.Monitor {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076 private static final String TAG = "PowerManagerService";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077
Jeff Brown88c997a2012-06-22 13:57:45 -070078 private static final boolean DEBUG = false;
Jeff Brown96307042012-07-27 15:51:34 -070079 private static final boolean DEBUG_SPEW = DEBUG && true;
Jeff Brown88c997a2012-06-22 13:57:45 -070080
Jeff Brown96307042012-07-27 15:51:34 -070081 // Message: Sent when a user activity timeout occurs to update the power state.
82 private static final int MSG_USER_ACTIVITY_TIMEOUT = 1;
83 // Message: Sent when the device enters or exits a napping or dreaming state.
84 private static final int MSG_SANDMAN = 2;
Jeff Brownc38c9be2012-10-04 13:16:19 -070085 // Message: Sent when the screen on blocker is released.
86 private static final int MSG_SCREEN_ON_BLOCKER_RELEASED = 3;
Jeff Brown20767b22012-10-09 18:57:07 -070087 // Message: Sent to poll whether the boot animation has terminated.
88 private static final int MSG_CHECK_IF_BOOT_ANIMATION_FINISHED = 4;
Jeff Brown7304c342012-05-11 18:42:42 -070089
Jeff Brown96307042012-07-27 15:51:34 -070090 // Dirty bit: mWakeLocks changed
91 private static final int DIRTY_WAKE_LOCKS = 1 << 0;
92 // Dirty bit: mWakefulness changed
93 private static final int DIRTY_WAKEFULNESS = 1 << 1;
94 // Dirty bit: user activity was poked or may have timed out
95 private static final int DIRTY_USER_ACTIVITY = 1 << 2;
96 // Dirty bit: actual display power state was updated asynchronously
97 private static final int DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED = 1 << 3;
98 // Dirty bit: mBootCompleted changed
99 private static final int DIRTY_BOOT_COMPLETED = 1 << 4;
100 // Dirty bit: settings changed
101 private static final int DIRTY_SETTINGS = 1 << 5;
102 // Dirty bit: mIsPowered changed
103 private static final int DIRTY_IS_POWERED = 1 << 6;
104 // Dirty bit: mStayOn changed
105 private static final int DIRTY_STAY_ON = 1 << 7;
106 // Dirty bit: battery state changed
107 private static final int DIRTY_BATTERY_STATE = 1 << 8;
Jeff Brown93cbbb22012-10-04 13:18:36 -0700108 // Dirty bit: proximity state changed
109 private static final int DIRTY_PROXIMITY_POSITIVE = 1 << 9;
Jeff Brownc38c9be2012-10-04 13:16:19 -0700110 // Dirty bit: screen on blocker state became held or unheld
111 private static final int DIRTY_SCREEN_ON_BLOCKER_RELEASED = 1 << 10;
Jeff Brownec6aa592012-10-17 20:30:25 -0700112 // Dirty bit: dock state changed
113 private static final int DIRTY_DOCK_STATE = 1 << 11;
Jeff Brown7304c342012-05-11 18:42:42 -0700114
Jeff Brown96307042012-07-27 15:51:34 -0700115 // Wakefulness: The device is asleep and can only be awoken by a call to wakeUp().
116 // The screen should be off or in the process of being turned off by the display controller.
117 private static final int WAKEFULNESS_ASLEEP = 0;
118 // Wakefulness: The device is fully awake. It can be put to sleep by a call to goToSleep().
Jeff Brown62c82e42012-09-26 01:30:41 -0700119 // When the user activity timeout expires, the device may start napping or go to sleep.
Jeff Brown96307042012-07-27 15:51:34 -0700120 private static final int WAKEFULNESS_AWAKE = 1;
121 // Wakefulness: The device is napping. It is deciding whether to dream or go to sleep
122 // but hasn't gotten around to it yet. It can be awoken by a call to wakeUp(), which
123 // ends the nap. User activity may brighten the screen but does not end the nap.
124 private static final int WAKEFULNESS_NAPPING = 2;
125 // Wakefulness: The device is dreaming. It can be awoken by a call to wakeUp(),
126 // which ends the dream. The device goes to sleep when goToSleep() is called, when
127 // the dream ends or when unplugged.
128 // User activity may brighten the screen but does not end the dream.
129 private static final int WAKEFULNESS_DREAMING = 3;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130
Jeff Brown96307042012-07-27 15:51:34 -0700131 // Summarizes the state of all active wakelocks.
132 private static final int WAKE_LOCK_CPU = 1 << 0;
133 private static final int WAKE_LOCK_SCREEN_BRIGHT = 1 << 1;
134 private static final int WAKE_LOCK_SCREEN_DIM = 1 << 2;
135 private static final int WAKE_LOCK_BUTTON_BRIGHT = 1 << 3;
136 private static final int WAKE_LOCK_PROXIMITY_SCREEN_OFF = 1 << 4;
Jeff Brown10428742012-10-09 15:47:30 -0700137 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 -0800138
Jeff Brown96307042012-07-27 15:51:34 -0700139 // Summarizes the user activity state.
140 private static final int USER_ACTIVITY_SCREEN_BRIGHT = 1 << 0;
141 private static final int USER_ACTIVITY_SCREEN_DIM = 1 << 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142
Jeff Brown96307042012-07-27 15:51:34 -0700143 // Default and minimum screen off timeout in milliseconds.
144 private static final int DEFAULT_SCREEN_OFF_TIMEOUT = 15 * 1000;
145 private static final int MINIMUM_SCREEN_OFF_TIMEOUT = 10 * 1000;
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700146
Jeff Brownff532542012-10-02 21:18:04 -0700147 // The screen dim duration, in milliseconds.
Jeff Brown96307042012-07-27 15:51:34 -0700148 // This is subtracted from the end of the screen off timeout so the
149 // minimum screen off timeout should be longer than this.
150 private static final int SCREEN_DIM_DURATION = 7 * 1000;
Mathias Agopian47f1fe52011-11-08 17:18:41 -0800151
Jeff Brownff532542012-10-02 21:18:04 -0700152 // The maximum screen dim time expressed as a ratio relative to the screen
153 // off timeout. If the screen off timeout is very short then we want the
154 // dim timeout to also be quite short so that most of the time is spent on.
155 // Otherwise the user won't get much screen on time before dimming occurs.
156 private static final float MAXIMUM_SCREEN_DIM_RATIO = 0.2f;
157
Jeff Brown20767b22012-10-09 18:57:07 -0700158 // The name of the boot animation service in init.rc.
159 private static final String BOOT_ANIMATION_SERVICE = "bootanim";
160
161 // Poll interval in milliseconds for watching boot animation finished.
162 private static final int BOOT_ANIMATION_POLL_INTERVAL = 200;
163
Jeff Brown016ff142012-10-15 16:47:22 -0700164 // If the battery level drops by this percentage and the user activity timeout
165 // has expired, then assume the device is receiving insufficient current to charge
166 // effectively and terminate the dream.
167 private static final int DREAM_BATTERY_LEVEL_DRAIN_CUTOFF = 5;
168
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169 private Context mContext;
Jeff Brown96307042012-07-27 15:51:34 -0700170 private LightsService mLightsService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 private BatteryService mBatteryService;
Jeff Brown9e316a12012-10-08 19:17:06 -0700172 private DisplayManagerService mDisplayManagerService;
Jeff Brown96307042012-07-27 15:51:34 -0700173 private IBatteryStats mBatteryStats;
174 private HandlerThread mHandlerThread;
175 private PowerManagerHandler mHandler;
176 private WindowManagerPolicy mPolicy;
177 private Notifier mNotifier;
178 private DisplayPowerController mDisplayPowerController;
Jeff Brown3b971592013-01-09 18:46:37 -0800179 private WirelessChargerDetector mWirelessChargerDetector;
Jeff Brown96307042012-07-27 15:51:34 -0700180 private SettingsObserver mSettingsObserver;
Jeff Brown62c82e42012-09-26 01:30:41 -0700181 private DreamManagerService mDreamManager;
Jeff Brown96307042012-07-27 15:51:34 -0700182 private LightsService.Light mAttentionLight;
Joe Onorato609695d2010-10-14 14:57:49 -0700183
Jeff Brown96307042012-07-27 15:51:34 -0700184 private final Object mLock = new Object();
185
186 // A bitfield that indicates what parts of the power state have
187 // changed and need to be recalculated.
188 private int mDirty;
189
190 // Indicates whether the device is awake or asleep or somewhere in between.
191 // This is distinct from the screen power state, which is managed separately.
192 private int mWakefulness;
193
194 // True if MSG_SANDMAN has been scheduled.
195 private boolean mSandmanScheduled;
196
197 // Table of all suspend blockers.
198 // There should only be a few of these.
199 private final ArrayList<SuspendBlocker> mSuspendBlockers = new ArrayList<SuspendBlocker>();
200
201 // Table of all wake locks acquired by applications.
202 private final ArrayList<WakeLock> mWakeLocks = new ArrayList<WakeLock>();
203
204 // A bitfield that summarizes the state of all active wakelocks.
205 private int mWakeLockSummary;
206
207 // If true, instructs the display controller to wait for the proximity sensor to
208 // go negative before turning the screen on.
209 private boolean mRequestWaitForNegativeProximity;
210
211 // Timestamp of the last time the device was awoken or put to sleep.
212 private long mLastWakeTime;
213 private long mLastSleepTime;
214
215 // True if we need to send a wake up or go to sleep finished notification
216 // when the display is ready.
217 private boolean mSendWakeUpFinishedNotificationWhenReady;
218 private boolean mSendGoToSleepFinishedNotificationWhenReady;
219
220 // Timestamp of the last call to user activity.
221 private long mLastUserActivityTime;
222 private long mLastUserActivityTimeNoChangeLights;
223
224 // A bitfield that summarizes the effect of the user activity timer.
225 // A zero value indicates that the user activity timer has expired.
226 private int mUserActivitySummary;
227
228 // The desired display power state. The actual state may lag behind the
229 // requested because it is updated asynchronously by the display power controller.
230 private final DisplayPowerRequest mDisplayPowerRequest = new DisplayPowerRequest();
231
232 // The time the screen was last turned off, in elapsedRealtime() timebase.
233 private long mLastScreenOffEventElapsedRealTime;
234
235 // True if the display power state has been fully applied, which means the display
236 // is actually on or actually off or whatever was requested.
237 private boolean mDisplayReady;
238
Jeff Brown27f7a862012-12-12 15:43:31 -0800239 // The suspend blocker used to keep the CPU alive when an application has acquired
240 // a wake lock.
241 private final SuspendBlocker mWakeLockSuspendBlocker;
242
243 // True if the wake lock suspend blocker has been acquired.
Jeff Brown96307042012-07-27 15:51:34 -0700244 private boolean mHoldingWakeLockSuspendBlocker;
245
Jeff Brown27f7a862012-12-12 15:43:31 -0800246 // The suspend blocker used to keep the CPU alive when the display is on, the
247 // display is getting ready or there is user activity (in which case the display
248 // must be on).
249 private final SuspendBlocker mDisplaySuspendBlocker;
250
251 // True if the display suspend blocker has been acquired.
252 private boolean mHoldingDisplaySuspendBlocker;
Jeff Brown96307042012-07-27 15:51:34 -0700253
Jeff Brownc38c9be2012-10-04 13:16:19 -0700254 // The screen on blocker used to keep the screen from turning on while the lock
255 // screen is coming up.
256 private final ScreenOnBlockerImpl mScreenOnBlocker;
257
Jeff Brown9e316a12012-10-08 19:17:06 -0700258 // The display blanker used to turn the screen on or off.
259 private final DisplayBlankerImpl mDisplayBlanker;
260
Jeff Brown96307042012-07-27 15:51:34 -0700261 // True if systemReady() has been called.
262 private boolean mSystemReady;
263
264 // True if boot completed occurred. We keep the screen on until this happens.
265 private boolean mBootCompleted;
266
267 // True if the device is plugged into a power source.
268 private boolean mIsPowered;
269
Jeff Brownf3fb8952012-10-02 20:57:05 -0700270 // The current plug type, such as BatteryManager.BATTERY_PLUGGED_WIRELESS.
271 private int mPlugType;
272
Jeff Brown016ff142012-10-15 16:47:22 -0700273 // The current battery level percentage.
274 private int mBatteryLevel;
275
276 // The battery level percentage at the time the dream started.
277 // This is used to terminate a dream and go to sleep if the battery is
278 // draining faster than it is charging and the user activity timeout has expired.
279 private int mBatteryLevelWhenDreamStarted;
280
Jeff Brownec6aa592012-10-17 20:30:25 -0700281 // The current dock state.
282 private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
283
Jeff Brown96307042012-07-27 15:51:34 -0700284 // True if the device should wake up when plugged or unplugged.
285 private boolean mWakeUpWhenPluggedOrUnpluggedConfig;
286
287 // True if dreams are supported on this device.
288 private boolean mDreamsSupportedConfig;
289
John Spurlocked108f32012-10-18 16:49:24 -0400290 // Default value for dreams enabled
291 private boolean mDreamsEnabledByDefaultConfig;
292
293 // Default value for dreams activate-on-sleep
294 private boolean mDreamsActivatedOnSleepByDefaultConfig;
295
296 // Default value for dreams activate-on-dock
297 private boolean mDreamsActivatedOnDockByDefaultConfig;
298
Jeff Brown96307042012-07-27 15:51:34 -0700299 // True if dreams are enabled by the user.
300 private boolean mDreamsEnabledSetting;
301
John Spurlock1a868b72012-08-22 09:56:51 -0400302 // True if dreams should be activated on sleep.
303 private boolean mDreamsActivateOnSleepSetting;
304
Jeff Brownec6aa592012-10-17 20:30:25 -0700305 // True if dreams should be activated on dock.
306 private boolean mDreamsActivateOnDockSetting;
307
Jeff Brown96307042012-07-27 15:51:34 -0700308 // The screen off timeout setting value in milliseconds.
309 private int mScreenOffTimeoutSetting;
310
311 // The maximum allowable screen off timeout according to the device
312 // administration policy. Overrides other settings.
313 private int mMaximumScreenOffTimeoutFromDeviceAdmin = Integer.MAX_VALUE;
314
315 // The stay on while plugged in setting.
316 // A bitfield of battery conditions under which to make the screen stay on.
317 private int mStayOnWhilePluggedInSetting;
318
319 // True if the device should stay on.
320 private boolean mStayOn;
321
Jeff Brown93cbbb22012-10-04 13:18:36 -0700322 // True if the proximity sensor reads a positive result.
323 private boolean mProximityPositive;
324
Jeff Brown96307042012-07-27 15:51:34 -0700325 // Screen brightness setting limits.
326 private int mScreenBrightnessSettingMinimum;
327 private int mScreenBrightnessSettingMaximum;
328 private int mScreenBrightnessSettingDefault;
329
330 // The screen brightness setting, from 0 to 255.
331 // Use -1 if no value has been set.
332 private int mScreenBrightnessSetting;
333
Jeff Brown330560f2012-08-21 22:10:57 -0700334 // The screen auto-brightness adjustment setting, from -1 to 1.
335 // Use 0 if there is no adjustment.
336 private float mScreenAutoBrightnessAdjustmentSetting;
337
Jeff Brown96307042012-07-27 15:51:34 -0700338 // The screen brightness mode.
339 // One of the Settings.System.SCREEN_BRIGHTNESS_MODE_* constants.
340 private int mScreenBrightnessModeSetting;
341
342 // The screen brightness setting override from the window manager
343 // to allow the current foreground activity to override the brightness.
344 // Use -1 to disable.
345 private int mScreenBrightnessOverrideFromWindowManager = -1;
346
Jeff Brown1e3b98d2012-09-30 18:58:59 -0700347 // The user activity timeout override from the window manager
348 // to allow the current foreground activity to override the user activity timeout.
349 // Use -1 to disable.
350 private long mUserActivityTimeoutOverrideFromWindowManager = -1;
351
Jeff Brown96307042012-07-27 15:51:34 -0700352 // The screen brightness setting override from the settings application
353 // to temporarily adjust the brightness until next updated,
354 // Use -1 to disable.
355 private int mTemporaryScreenBrightnessSettingOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800356
Jeff Brown330560f2012-08-21 22:10:57 -0700357 // The screen brightness adjustment setting override from the settings
358 // application to temporarily adjust the auto-brightness adjustment factor
359 // until next updated, in the range -1..1.
360 // Use NaN to disable.
361 private float mTemporaryScreenAutoBrightnessAdjustmentSettingOverride = Float.NaN;
362
Jeff Brown9ba8d782012-10-01 16:38:23 -0700363 // Time when we last logged a warning about calling userActivity() without permission.
364 private long mLastWarningAboutUserActivityPermission = Long.MIN_VALUE;
365
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700366 private native void nativeInit();
Jeff Brown7304c342012-05-11 18:42:42 -0700367 private static native void nativeShutdown();
368 private static native void nativeReboot(String reason) throws IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800369
Jeff Brown96307042012-07-27 15:51:34 -0700370 private static native void nativeSetPowerState(boolean screenOn, boolean screenBright);
371 private static native void nativeAcquireSuspendBlocker(String name);
372 private static native void nativeReleaseSuspendBlocker(String name);
Jeff Brown9e316a12012-10-08 19:17:06 -0700373 private static native void nativeSetInteractive(boolean enable);
374 private static native void nativeSetAutoSuspend(boolean enable);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800375
Jeff Brown4f8ecd82012-06-18 18:29:13 -0700376 public PowerManagerService() {
Jeff Brown96307042012-07-27 15:51:34 -0700377 synchronized (mLock) {
Jeff Brown27f7a862012-12-12 15:43:31 -0800378 mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks");
379 mDisplaySuspendBlocker = createSuspendBlockerLocked("PowerManagerService.Display");
380 mDisplaySuspendBlocker.acquire();
381 mHoldingDisplaySuspendBlocker = true;
382
Jeff Brownc38c9be2012-10-04 13:16:19 -0700383 mScreenOnBlocker = new ScreenOnBlockerImpl();
Jeff Brown9e316a12012-10-08 19:17:06 -0700384 mDisplayBlanker = new DisplayBlankerImpl();
Jeff Brown96307042012-07-27 15:51:34 -0700385 mWakefulness = WAKEFULNESS_AWAKE;
386 }
Jeff Brown7304c342012-05-11 18:42:42 -0700387
388 nativeInit();
Jeff Brownf75724b2012-08-25 13:34:32 -0700389 nativeSetPowerState(true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800390 }
391
Jeff Brown96307042012-07-27 15:51:34 -0700392 /**
393 * Initialize the power manager.
394 * Must be called before any other functions within the power manager are called.
395 */
396 public void init(Context context, LightsService ls,
397 ActivityManagerService am, BatteryService bs, IBatteryStats bss,
398 DisplayManagerService dm) {
Jeff Brown9e316a12012-10-08 19:17:06 -0700399 mContext = context;
400 mLightsService = ls;
401 mBatteryService = bs;
402 mBatteryStats = bss;
403 mDisplayManagerService = dm;
404 mHandlerThread = new HandlerThread(TAG);
405 mHandlerThread.start();
406 mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
407
408 Watchdog.getInstance().addMonitor(this);
409
Jeff Brownf75724b2012-08-25 13:34:32 -0700410 // Forcibly turn the screen on at boot so that it is in a known power state.
411 // We do this in init() rather than in the constructor because setting the
412 // screen state requires a call into surface flinger which then needs to call back
413 // into the activity manager to check permissions. Unfortunately the
414 // activity manager is not running when the constructor is called, so we
415 // have to defer setting the screen state until this point.
Jeff Brown9e316a12012-10-08 19:17:06 -0700416 mDisplayBlanker.unblankAllDisplays();
Jeff Brown96307042012-07-27 15:51:34 -0700417 }
Jim Miller92e66dd2012-02-21 18:57:12 -0800418
Jeff Brown96307042012-07-27 15:51:34 -0700419 public void setPolicy(WindowManagerPolicy policy) {
420 synchronized (mLock) {
421 mPolicy = policy;
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700422 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800423 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800424
Jeff Brown62c82e42012-09-26 01:30:41 -0700425 public void systemReady(TwilightService twilight, DreamManagerService dreamManager) {
Jeff Brown96307042012-07-27 15:51:34 -0700426 synchronized (mLock) {
427 mSystemReady = true;
Jeff Brown62c82e42012-09-26 01:30:41 -0700428 mDreamManager = dreamManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800429
Jeff Brown96307042012-07-27 15:51:34 -0700430 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
431 mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting();
432 mScreenBrightnessSettingMaximum = pm.getMaximumScreenBrightnessSetting();
433 mScreenBrightnessSettingDefault = pm.getDefaultScreenBrightnessSetting();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800434
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -0700435 SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper());
Jeff Brown3b971592013-01-09 18:46:37 -0800436
Jeff Brownc38c9be2012-10-04 13:16:19 -0700437 // The notifier runs on the system server's main looper so as not to interfere
438 // with the animations and other critical functions of the power manager.
439 mNotifier = new Notifier(Looper.getMainLooper(), mContext, mBatteryStats,
Jeff Brown96307042012-07-27 15:51:34 -0700440 createSuspendBlockerLocked("PowerManagerService.Broadcasts"),
Jeff Brownc38c9be2012-10-04 13:16:19 -0700441 mScreenOnBlocker, mPolicy);
442
443 // The display power controller runs on the power manager service's
Jeff Brown3b971592013-01-09 18:46:37 -0800444 // own handler thread to ensure timely operation.
Jeff Brown96307042012-07-27 15:51:34 -0700445 mDisplayPowerController = new DisplayPowerController(mHandler.getLooper(),
Jeff Brown3b971592013-01-09 18:46:37 -0800446 mContext, mNotifier, mLightsService, twilight, sensorManager,
447 mDisplayManagerService, mDisplayBlanker,
448 mDisplayPowerControllerCallbacks, mHandler);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800449
Jeff Brown3b971592013-01-09 18:46:37 -0800450 mWirelessChargerDetector = new WirelessChargerDetector(sensorManager,
451 createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector"));
Jeff Brown96307042012-07-27 15:51:34 -0700452 mSettingsObserver = new SettingsObserver(mHandler);
453 mAttentionLight = mLightsService.getLight(LightsService.LIGHT_ID_ATTENTION);
Mike Lockwoodaa66ea82009-10-31 16:31:27 -0400454
Jeff Brown96307042012-07-27 15:51:34 -0700455 // Register for broadcasts from other components of the system.
456 IntentFilter filter = new IntentFilter();
457 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
Jeff Brownd4935962012-09-25 13:27:20 -0700458 mContext.registerReceiver(new BatteryReceiver(), filter, null, mHandler);
Joe Onoratob08a1af2010-10-11 19:28:58 -0700459
Jeff Brown96307042012-07-27 15:51:34 -0700460 filter = new IntentFilter();
461 filter.addAction(Intent.ACTION_BOOT_COMPLETED);
Jeff Brownd4935962012-09-25 13:27:20 -0700462 mContext.registerReceiver(new BootCompletedReceiver(), filter, null, mHandler);
Jeff Brown96307042012-07-27 15:51:34 -0700463
464 filter = new IntentFilter();
Dianne Hackbornbe87e2f2012-09-28 16:31:34 -0700465 filter.addAction(Intent.ACTION_DREAMING_STARTED);
466 filter.addAction(Intent.ACTION_DREAMING_STOPPED);
Jeff Brownd4935962012-09-25 13:27:20 -0700467 mContext.registerReceiver(new DreamReceiver(), filter, null, mHandler);
468
469 filter = new IntentFilter();
470 filter.addAction(Intent.ACTION_USER_SWITCHED);
471 mContext.registerReceiver(new UserSwitchedReceiver(), filter, null, mHandler);
John Spurlockf4f6b4c2012-08-25 12:08:03 -0400472
Jeff Brownec6aa592012-10-17 20:30:25 -0700473 filter = new IntentFilter();
474 filter.addAction(Intent.ACTION_DOCK_EVENT);
475 mContext.registerReceiver(new DockReceiver(), filter, null, mHandler);
476
Jeff Brown96307042012-07-27 15:51:34 -0700477 // Register for settings changes.
478 final ContentResolver resolver = mContext.getContentResolver();
479 resolver.registerContentObserver(Settings.Secure.getUriFor(
Jeff Brownd4935962012-09-25 13:27:20 -0700480 Settings.Secure.SCREENSAVER_ENABLED),
481 false, mSettingsObserver, UserHandle.USER_ALL);
John Spurlock1a868b72012-08-22 09:56:51 -0400482 resolver.registerContentObserver(Settings.Secure.getUriFor(
Jeff Brownd4935962012-09-25 13:27:20 -0700483 Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP),
484 false, mSettingsObserver, UserHandle.USER_ALL);
Jeff Brownec6aa592012-10-17 20:30:25 -0700485 resolver.registerContentObserver(Settings.Secure.getUriFor(
486 Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK),
487 false, mSettingsObserver, UserHandle.USER_ALL);
Jeff Brown96307042012-07-27 15:51:34 -0700488 resolver.registerContentObserver(Settings.System.getUriFor(
Jeff Brownd4935962012-09-25 13:27:20 -0700489 Settings.System.SCREEN_OFF_TIMEOUT),
490 false, mSettingsObserver, UserHandle.USER_ALL);
Christopher Tatead735322012-09-07 14:19:43 -0700491 resolver.registerContentObserver(Settings.Global.getUriFor(
Jeff Brownd4935962012-09-25 13:27:20 -0700492 Settings.Global.STAY_ON_WHILE_PLUGGED_IN),
493 false, mSettingsObserver, UserHandle.USER_ALL);
Jeff Brown96307042012-07-27 15:51:34 -0700494 resolver.registerContentObserver(Settings.System.getUriFor(
Jeff Brownd4935962012-09-25 13:27:20 -0700495 Settings.System.SCREEN_BRIGHTNESS),
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_MODE),
499 false, mSettingsObserver, UserHandle.USER_ALL);
Jeff Brown96307042012-07-27 15:51:34 -0700500
501 // Go.
502 readConfigurationLocked();
503 updateSettingsLocked();
504 mDirty |= DIRTY_BATTERY_STATE;
505 updatePowerStateLocked();
506 }
507 }
508
509 private void readConfigurationLocked() {
510 final Resources resources = mContext.getResources();
511
512 mWakeUpWhenPluggedOrUnpluggedConfig = resources.getBoolean(
Joe Onorato6d747652010-10-11 15:15:31 -0700513 com.android.internal.R.bool.config_unplugTurnsOnScreen);
Jeff Brown96307042012-07-27 15:51:34 -0700514 mDreamsSupportedConfig = resources.getBoolean(
John Spurlocked108f32012-10-18 16:49:24 -0400515 com.android.internal.R.bool.config_dreamsSupported);
516 mDreamsEnabledByDefaultConfig = resources.getBoolean(
517 com.android.internal.R.bool.config_dreamsEnabledByDefault);
518 mDreamsActivatedOnSleepByDefaultConfig = resources.getBoolean(
519 com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault);
520 mDreamsActivatedOnDockByDefaultConfig = resources.getBoolean(
521 com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800522 }
523
Jeff Brown96307042012-07-27 15:51:34 -0700524 private void updateSettingsLocked() {
525 final ContentResolver resolver = mContext.getContentResolver();
Jeff Brown7304c342012-05-11 18:42:42 -0700526
Jeff Brownd4935962012-09-25 13:27:20 -0700527 mDreamsEnabledSetting = (Settings.Secure.getIntForUser(resolver,
John Spurlocked108f32012-10-18 16:49:24 -0400528 Settings.Secure.SCREENSAVER_ENABLED,
529 mDreamsEnabledByDefaultConfig ? 1 : 0,
Jeff Brownd4935962012-09-25 13:27:20 -0700530 UserHandle.USER_CURRENT) != 0);
531 mDreamsActivateOnSleepSetting = (Settings.Secure.getIntForUser(resolver,
John Spurlocked108f32012-10-18 16:49:24 -0400532 Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
533 mDreamsActivatedOnSleepByDefaultConfig ? 1 : 0,
Jeff Brownd4935962012-09-25 13:27:20 -0700534 UserHandle.USER_CURRENT) != 0);
Jeff Brownec6aa592012-10-17 20:30:25 -0700535 mDreamsActivateOnDockSetting = (Settings.Secure.getIntForUser(resolver,
John Spurlocked108f32012-10-18 16:49:24 -0400536 Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
537 mDreamsActivatedOnDockByDefaultConfig ? 1 : 0,
Jeff Brownec6aa592012-10-17 20:30:25 -0700538 UserHandle.USER_CURRENT) != 0);
Jeff Brownd4935962012-09-25 13:27:20 -0700539 mScreenOffTimeoutSetting = Settings.System.getIntForUser(resolver,
540 Settings.System.SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT,
541 UserHandle.USER_CURRENT);
Christopher Tatead735322012-09-07 14:19:43 -0700542 mStayOnWhilePluggedInSetting = Settings.Global.getInt(resolver,
Jeff Brownd4935962012-09-25 13:27:20 -0700543 Settings.Global.STAY_ON_WHILE_PLUGGED_IN, BatteryManager.BATTERY_PLUGGED_AC);
Jeff Brown7304c342012-05-11 18:42:42 -0700544
Jeff Brown96307042012-07-27 15:51:34 -0700545 final int oldScreenBrightnessSetting = mScreenBrightnessSetting;
Jeff Brownd4935962012-09-25 13:27:20 -0700546 mScreenBrightnessSetting = Settings.System.getIntForUser(resolver,
547 Settings.System.SCREEN_BRIGHTNESS, mScreenBrightnessSettingDefault,
548 UserHandle.USER_CURRENT);
Jeff Brown96307042012-07-27 15:51:34 -0700549 if (oldScreenBrightnessSetting != mScreenBrightnessSetting) {
550 mTemporaryScreenBrightnessSettingOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800551 }
Jeff Brown96307042012-07-27 15:51:34 -0700552
Jeff Brown330560f2012-08-21 22:10:57 -0700553 final float oldScreenAutoBrightnessAdjustmentSetting =
554 mScreenAutoBrightnessAdjustmentSetting;
Jeff Brownd4935962012-09-25 13:27:20 -0700555 mScreenAutoBrightnessAdjustmentSetting = Settings.System.getFloatForUser(resolver,
556 Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f,
557 UserHandle.USER_CURRENT);
Jeff Brown330560f2012-08-21 22:10:57 -0700558 if (oldScreenAutoBrightnessAdjustmentSetting != mScreenAutoBrightnessAdjustmentSetting) {
Jeff Brown5d03a532012-08-22 13:22:02 -0700559 mTemporaryScreenAutoBrightnessAdjustmentSettingOverride = Float.NaN;
Jeff Brown330560f2012-08-21 22:10:57 -0700560 }
561
Jeff Brownd4935962012-09-25 13:27:20 -0700562 mScreenBrightnessModeSetting = Settings.System.getIntForUser(resolver,
Jeff Brown96307042012-07-27 15:51:34 -0700563 Settings.System.SCREEN_BRIGHTNESS_MODE,
Jeff Brownd4935962012-09-25 13:27:20 -0700564 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, UserHandle.USER_CURRENT);
Jeff Brown96307042012-07-27 15:51:34 -0700565
566 mDirty |= DIRTY_SETTINGS;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800567 }
568
Jeff Brown96307042012-07-27 15:51:34 -0700569 private void handleSettingsChangedLocked() {
570 updateSettingsLocked();
571 updatePowerStateLocked();
572 }
573
574 @Override // Binder call
575 public void acquireWakeLock(IBinder lock, int flags, String tag, WorkSource ws) {
576 if (lock == null) {
577 throw new IllegalArgumentException("lock must not be null");
578 }
579 PowerManager.validateWakeLockParameters(flags, tag);
580
581 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
582 if (ws != null && ws.size() != 0) {
583 mContext.enforceCallingOrSelfPermission(
584 android.Manifest.permission.UPDATE_DEVICE_STATS, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800585 } else {
Jeff Brown96307042012-07-27 15:51:34 -0700586 ws = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800587 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800588
Jeff Brown96307042012-07-27 15:51:34 -0700589 final int uid = Binder.getCallingUid();
590 final int pid = Binder.getCallingPid();
591 final long ident = Binder.clearCallingIdentity();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800592 try {
Jeff Brown96307042012-07-27 15:51:34 -0700593 acquireWakeLockInternal(lock, flags, tag, ws, uid, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800594 } finally {
595 Binder.restoreCallingIdentity(ident);
596 }
597 }
598
Jeff Brown96307042012-07-27 15:51:34 -0700599 private void acquireWakeLockInternal(IBinder lock, int flags, String tag, WorkSource ws,
600 int uid, int pid) {
601 synchronized (mLock) {
602 if (DEBUG_SPEW) {
603 Slog.d(TAG, "acquireWakeLockInternal: lock=" + Objects.hashCode(lock)
604 + ", flags=0x" + Integer.toHexString(flags)
605 + ", tag=\"" + tag + "\", ws=" + ws + ", uid=" + uid + ", pid=" + pid);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700606 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800607
Jeff Brown96307042012-07-27 15:51:34 -0700608 WakeLock wakeLock;
609 int index = findWakeLockIndexLocked(lock);
610 if (index >= 0) {
611 wakeLock = mWakeLocks.get(index);
612 if (!wakeLock.hasSameProperties(flags, tag, ws, uid, pid)) {
613 // Update existing wake lock. This shouldn't happen but is harmless.
614 notifyWakeLockReleasedLocked(wakeLock);
615 wakeLock.updateProperties(flags, tag, ws, uid, pid);
616 notifyWakeLockAcquiredLocked(wakeLock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800617 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800618 } else {
Jeff Brown96307042012-07-27 15:51:34 -0700619 wakeLock = new WakeLock(lock, flags, tag, ws, uid, pid);
620 try {
621 lock.linkToDeath(wakeLock, 0);
622 } catch (RemoteException ex) {
623 throw new IllegalArgumentException("Wake lock is already dead.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800624 }
Jeff Brown96307042012-07-27 15:51:34 -0700625 notifyWakeLockAcquiredLocked(wakeLock);
626 mWakeLocks.add(wakeLock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800627 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800628
Jeff Brown96307042012-07-27 15:51:34 -0700629 applyWakeLockFlagsOnAcquireLocked(wakeLock);
630 mDirty |= DIRTY_WAKE_LOCKS;
631 updatePowerStateLocked();
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700632 }
633 }
634
Craig Mautner6edb6db2012-11-20 18:21:12 -0800635 private static boolean isScreenLock(final WakeLock wakeLock) {
636 switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
637 case PowerManager.FULL_WAKE_LOCK:
638 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
639 case PowerManager.SCREEN_DIM_WAKE_LOCK:
640 return true;
641 }
642 return false;
643 }
644
Jeff Brown96307042012-07-27 15:51:34 -0700645 private void applyWakeLockFlagsOnAcquireLocked(WakeLock wakeLock) {
Craig Mautner6edb6db2012-11-20 18:21:12 -0800646 if ((wakeLock.mFlags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0 &&
647 isScreenLock(wakeLock)) {
Jeff Brown96307042012-07-27 15:51:34 -0700648 wakeUpNoUpdateLocked(SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800649 }
650 }
651
Jeff Brown96307042012-07-27 15:51:34 -0700652 @Override // Binder call
Mike Lockwood0e39ea82009-11-18 15:37:10 -0500653 public void releaseWakeLock(IBinder lock, int flags) {
Jeff Brown96307042012-07-27 15:51:34 -0700654 if (lock == null) {
655 throw new IllegalArgumentException("lock must not be null");
Michael Chane96440f2009-05-06 10:27:36 -0700656 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800657
Jeff Brown96307042012-07-27 15:51:34 -0700658 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
659
660 final long ident = Binder.clearCallingIdentity();
661 try {
662 releaseWakeLockInternal(lock, flags);
663 } finally {
664 Binder.restoreCallingIdentity(ident);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800665 }
666 }
667
Jeff Brown96307042012-07-27 15:51:34 -0700668 private void releaseWakeLockInternal(IBinder lock, int flags) {
669 synchronized (mLock) {
Jeff Brown96307042012-07-27 15:51:34 -0700670 int index = findWakeLockIndexLocked(lock);
671 if (index < 0) {
Jeff Brown27f7a862012-12-12 15:43:31 -0800672 if (DEBUG_SPEW) {
673 Slog.d(TAG, "releaseWakeLockInternal: lock=" + Objects.hashCode(lock)
674 + " [not found], flags=0x" + Integer.toHexString(flags));
675 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800676 return;
677 }
Mike Lockwood3333fa42009-10-26 14:50:42 -0400678
Jeff Brown96307042012-07-27 15:51:34 -0700679 WakeLock wakeLock = mWakeLocks.get(index);
Jeff Brown27f7a862012-12-12 15:43:31 -0800680 if (DEBUG_SPEW) {
681 Slog.d(TAG, "releaseWakeLockInternal: lock=" + Objects.hashCode(lock)
682 + " [" + wakeLock.mTag + "], flags=0x" + Integer.toHexString(flags));
683 }
684
Jeff Brown96307042012-07-27 15:51:34 -0700685 mWakeLocks.remove(index);
686 notifyWakeLockReleasedLocked(wakeLock);
687 wakeLock.mLock.unlinkToDeath(wakeLock, 0);
688
689 if ((flags & PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE) != 0) {
690 mRequestWaitForNegativeProximity = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800691 }
692
Jeff Brown96307042012-07-27 15:51:34 -0700693 applyWakeLockFlagsOnReleaseLocked(wakeLock);
694 mDirty |= DIRTY_WAKE_LOCKS;
695 updatePowerStateLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800696 }
697 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700698
Jeff Brown96307042012-07-27 15:51:34 -0700699 private void handleWakeLockDeath(WakeLock wakeLock) {
700 synchronized (mLock) {
701 if (DEBUG_SPEW) {
Jeff Brown27f7a862012-12-12 15:43:31 -0800702 Slog.d(TAG, "handleWakeLockDeath: lock=" + Objects.hashCode(wakeLock.mLock)
703 + " [" + wakeLock.mTag + "]");
Jeff Brown96307042012-07-27 15:51:34 -0700704 }
705
706 int index = mWakeLocks.indexOf(wakeLock);
707 if (index < 0) {
708 return;
709 }
710
711 mWakeLocks.remove(index);
712 notifyWakeLockReleasedLocked(wakeLock);
713
714 applyWakeLockFlagsOnReleaseLocked(wakeLock);
715 mDirty |= DIRTY_WAKE_LOCKS;
716 updatePowerStateLocked();
Mike Lockwood3a74bd32011-08-12 13:55:22 -0700717 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700718 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800719
Jeff Brown96307042012-07-27 15:51:34 -0700720 private void applyWakeLockFlagsOnReleaseLocked(WakeLock wakeLock) {
721 if ((wakeLock.mFlags & PowerManager.ON_AFTER_RELEASE) != 0) {
722 userActivityNoUpdateLocked(SystemClock.uptimeMillis(),
723 PowerManager.USER_ACTIVITY_EVENT_OTHER,
724 PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS,
725 wakeLock.mOwnerUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800726 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800727 }
728
Jeff Brown96307042012-07-27 15:51:34 -0700729 @Override // Binder call
730 public void updateWakeLockWorkSource(IBinder lock, WorkSource ws) {
731 if (lock == null) {
732 throw new IllegalArgumentException("lock must not be null");
733 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800734
Jeff Brown96307042012-07-27 15:51:34 -0700735 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
736 if (ws != null && ws.size() != 0) {
737 mContext.enforceCallingOrSelfPermission(
738 android.Manifest.permission.UPDATE_DEVICE_STATS, null);
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700739 } else {
Jeff Brown96307042012-07-27 15:51:34 -0700740 ws = null;
741 }
742
743 final long ident = Binder.clearCallingIdentity();
744 try {
745 updateWakeLockWorkSourceInternal(lock, ws);
746 } finally {
747 Binder.restoreCallingIdentity(ident);
748 }
749 }
750
751 private void updateWakeLockWorkSourceInternal(IBinder lock, WorkSource ws) {
752 synchronized (mLock) {
753 int index = findWakeLockIndexLocked(lock);
754 if (index < 0) {
Jeff Brown27f7a862012-12-12 15:43:31 -0800755 if (DEBUG_SPEW) {
756 Slog.d(TAG, "updateWakeLockWorkSourceInternal: lock=" + Objects.hashCode(lock)
757 + " [not found], ws=" + ws);
758 }
Jeff Brown96307042012-07-27 15:51:34 -0700759 throw new IllegalArgumentException("Wake lock not active");
760 }
761
762 WakeLock wakeLock = mWakeLocks.get(index);
Jeff Brown27f7a862012-12-12 15:43:31 -0800763 if (DEBUG_SPEW) {
764 Slog.d(TAG, "updateWakeLockWorkSourceInternal: lock=" + Objects.hashCode(lock)
765 + " [" + wakeLock.mTag + "], ws=" + ws);
766 }
767
Jeff Brown96307042012-07-27 15:51:34 -0700768 if (!wakeLock.hasSameWorkSource(ws)) {
769 notifyWakeLockReleasedLocked(wakeLock);
770 wakeLock.updateWorkSource(ws);
771 notifyWakeLockAcquiredLocked(wakeLock);
772 }
773 }
774 }
775
776 private int findWakeLockIndexLocked(IBinder lock) {
777 final int count = mWakeLocks.size();
778 for (int i = 0; i < count; i++) {
779 if (mWakeLocks.get(i).mLock == lock) {
780 return i;
781 }
782 }
783 return -1;
784 }
785
786 private void notifyWakeLockAcquiredLocked(WakeLock wakeLock) {
787 if (mSystemReady) {
788 mNotifier.onWakeLockAcquired(wakeLock.mFlags, wakeLock.mTag,
789 wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource);
790 }
791 }
792
793 private void notifyWakeLockReleasedLocked(WakeLock wakeLock) {
794 if (mSystemReady) {
795 mNotifier.onWakeLockReleased(wakeLock.mFlags, wakeLock.mTag,
796 wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource);
797 }
798 }
799
800 @Override // Binder call
801 public boolean isWakeLockLevelSupported(int level) {
802 final long ident = Binder.clearCallingIdentity();
803 try {
804 return isWakeLockLevelSupportedInternal(level);
805 } finally {
806 Binder.restoreCallingIdentity(ident);
807 }
808 }
809
810 private boolean isWakeLockLevelSupportedInternal(int level) {
811 synchronized (mLock) {
812 switch (level) {
813 case PowerManager.PARTIAL_WAKE_LOCK:
814 case PowerManager.SCREEN_DIM_WAKE_LOCK:
815 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
816 case PowerManager.FULL_WAKE_LOCK:
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700817 return true;
Jeff Brown96307042012-07-27 15:51:34 -0700818
819 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
820 return mSystemReady && mDisplayPowerController.isProximitySensorAvailable();
821
822 default:
823 return false;
824 }
825 }
826 }
827
828 @Override // Binder call
829 public void userActivity(long eventTime, int event, int flags) {
Jeff Brown9ba8d782012-10-01 16:38:23 -0700830 final long now = SystemClock.uptimeMillis();
831 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER)
832 != PackageManager.PERMISSION_GRANTED) {
833 // Once upon a time applications could call userActivity().
834 // Now we require the DEVICE_POWER permission. Log a warning and ignore the
835 // request instead of throwing a SecurityException so we don't break old apps.
836 synchronized (mLock) {
837 if (now >= mLastWarningAboutUserActivityPermission + (5 * 60 * 1000)) {
838 mLastWarningAboutUserActivityPermission = now;
839 Slog.w(TAG, "Ignoring call to PowerManager.userActivity() because the "
840 + "caller does not have DEVICE_POWER permission. "
841 + "Please fix your app! "
842 + " pid=" + Binder.getCallingPid()
843 + " uid=" + Binder.getCallingUid());
844 }
845 }
846 return;
847 }
848
Jeff Brown96307042012-07-27 15:51:34 -0700849 if (eventTime > SystemClock.uptimeMillis()) {
850 throw new IllegalArgumentException("event time must not be in the future");
851 }
852
Jeff Brown96307042012-07-27 15:51:34 -0700853 final int uid = Binder.getCallingUid();
854 final long ident = Binder.clearCallingIdentity();
855 try {
856 userActivityInternal(eventTime, event, flags, uid);
857 } finally {
858 Binder.restoreCallingIdentity(ident);
859 }
860 }
861
862 // Called from native code.
863 private void userActivityFromNative(long eventTime, int event, int flags) {
864 userActivityInternal(eventTime, event, flags, Process.SYSTEM_UID);
865 }
866
867 private void userActivityInternal(long eventTime, int event, int flags, int uid) {
868 synchronized (mLock) {
869 if (userActivityNoUpdateLocked(eventTime, event, flags, uid)) {
870 updatePowerStateLocked();
871 }
872 }
873 }
874
875 private boolean userActivityNoUpdateLocked(long eventTime, int event, int flags, int uid) {
876 if (DEBUG_SPEW) {
877 Slog.d(TAG, "userActivityNoUpdateLocked: eventTime=" + eventTime
878 + ", event=" + event + ", flags=0x" + Integer.toHexString(flags)
879 + ", uid=" + uid);
880 }
881
882 if (eventTime < mLastSleepTime || eventTime < mLastWakeTime
883 || mWakefulness == WAKEFULNESS_ASLEEP || !mBootCompleted || !mSystemReady) {
884 return false;
885 }
886
887 mNotifier.onUserActivity(event, uid);
888
889 if ((flags & PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS) != 0) {
890 if (eventTime > mLastUserActivityTimeNoChangeLights
891 && eventTime > mLastUserActivityTime) {
892 mLastUserActivityTimeNoChangeLights = eventTime;
893 mDirty |= DIRTY_USER_ACTIVITY;
894 return true;
895 }
896 } else {
897 if (eventTime > mLastUserActivityTime) {
898 mLastUserActivityTime = eventTime;
899 mDirty |= DIRTY_USER_ACTIVITY;
900 return true;
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700901 }
902 }
903 return false;
904 }
905
Jeff Brown96307042012-07-27 15:51:34 -0700906 @Override // Binder call
907 public void wakeUp(long eventTime) {
908 if (eventTime > SystemClock.uptimeMillis()) {
909 throw new IllegalArgumentException("event time must not be in the future");
910 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700911
Jeff Brown96307042012-07-27 15:51:34 -0700912 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
913
914 final long ident = Binder.clearCallingIdentity();
915 try {
916 wakeUpInternal(eventTime);
917 } finally {
918 Binder.restoreCallingIdentity(ident);
919 }
920 }
921
922 // Called from native code.
923 private void wakeUpFromNative(long eventTime) {
924 wakeUpInternal(eventTime);
925 }
926
927 private void wakeUpInternal(long eventTime) {
928 synchronized (mLock) {
929 if (wakeUpNoUpdateLocked(eventTime)) {
930 updatePowerStateLocked();
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700931 }
932 }
Jeff Brown96307042012-07-27 15:51:34 -0700933 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700934
Jeff Brown96307042012-07-27 15:51:34 -0700935 private boolean wakeUpNoUpdateLocked(long eventTime) {
936 if (DEBUG_SPEW) {
937 Slog.d(TAG, "wakeUpNoUpdateLocked: eventTime=" + eventTime);
Joe Onorato60607a92010-10-23 14:49:30 -0700938 }
Jeff Brown96307042012-07-27 15:51:34 -0700939
940 if (eventTime < mLastSleepTime || mWakefulness == WAKEFULNESS_AWAKE
941 || !mBootCompleted || !mSystemReady) {
942 return false;
943 }
944
945 switch (mWakefulness) {
946 case WAKEFULNESS_ASLEEP:
947 Slog.i(TAG, "Waking up from sleep...");
Jeff Brown54308352012-10-04 17:59:58 -0700948 sendPendingNotificationsLocked();
Jeff Brown96307042012-07-27 15:51:34 -0700949 mNotifier.onWakeUpStarted();
950 mSendWakeUpFinishedNotificationWhenReady = true;
Jeff Brown96307042012-07-27 15:51:34 -0700951 break;
952 case WAKEFULNESS_DREAMING:
953 Slog.i(TAG, "Waking up from dream...");
954 break;
955 case WAKEFULNESS_NAPPING:
956 Slog.i(TAG, "Waking up from nap...");
957 break;
958 }
959
960 mLastWakeTime = eventTime;
961 mWakefulness = WAKEFULNESS_AWAKE;
962 mDirty |= DIRTY_WAKEFULNESS;
963
964 userActivityNoUpdateLocked(
965 eventTime, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
966 return true;
967 }
968
969 @Override // Binder call
970 public void goToSleep(long eventTime, int reason) {
971 if (eventTime > SystemClock.uptimeMillis()) {
972 throw new IllegalArgumentException("event time must not be in the future");
973 }
974
975 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
976
977 final long ident = Binder.clearCallingIdentity();
978 try {
979 goToSleepInternal(eventTime, reason);
980 } finally {
981 Binder.restoreCallingIdentity(ident);
982 }
983 }
984
985 // Called from native code.
986 private void goToSleepFromNative(long eventTime, int reason) {
987 goToSleepInternal(eventTime, reason);
988 }
989
990 private void goToSleepInternal(long eventTime, int reason) {
991 synchronized (mLock) {
992 if (goToSleepNoUpdateLocked(eventTime, reason)) {
993 updatePowerStateLocked();
994 }
995 }
996 }
997
998 private boolean goToSleepNoUpdateLocked(long eventTime, int reason) {
999 if (DEBUG_SPEW) {
1000 Slog.d(TAG, "goToSleepNoUpdateLocked: eventTime=" + eventTime + ", reason=" + reason);
1001 }
1002
1003 if (eventTime < mLastWakeTime || mWakefulness == WAKEFULNESS_ASLEEP
1004 || !mBootCompleted || !mSystemReady) {
1005 return false;
1006 }
1007
1008 switch (reason) {
1009 case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN:
1010 Slog.i(TAG, "Going to sleep due to device administration policy...");
1011 break;
1012 case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT:
1013 Slog.i(TAG, "Going to sleep due to screen timeout...");
1014 break;
1015 default:
1016 Slog.i(TAG, "Going to sleep by user request...");
1017 reason = PowerManager.GO_TO_SLEEP_REASON_USER;
1018 break;
1019 }
1020
Jeff Brown54308352012-10-04 17:59:58 -07001021 sendPendingNotificationsLocked();
1022 mNotifier.onGoToSleepStarted(reason);
1023 mSendGoToSleepFinishedNotificationWhenReady = true;
1024
Jeff Brown96307042012-07-27 15:51:34 -07001025 mLastSleepTime = eventTime;
1026 mDirty |= DIRTY_WAKEFULNESS;
1027 mWakefulness = WAKEFULNESS_ASLEEP;
Jeff Brown96307042012-07-27 15:51:34 -07001028
1029 // Report the number of wake locks that will be cleared by going to sleep.
1030 int numWakeLocksCleared = 0;
1031 final int numWakeLocks = mWakeLocks.size();
1032 for (int i = 0; i < numWakeLocks; i++) {
1033 final WakeLock wakeLock = mWakeLocks.get(i);
1034 switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
1035 case PowerManager.FULL_WAKE_LOCK:
1036 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
1037 case PowerManager.SCREEN_DIM_WAKE_LOCK:
1038 numWakeLocksCleared += 1;
1039 break;
1040 }
1041 }
1042 EventLog.writeEvent(EventLogTags.POWER_SLEEP_REQUESTED, numWakeLocksCleared);
1043 return true;
1044 }
1045
Jeff Brown62c82e42012-09-26 01:30:41 -07001046 @Override // Binder call
1047 public void nap(long eventTime) {
1048 if (eventTime > SystemClock.uptimeMillis()) {
1049 throw new IllegalArgumentException("event time must not be in the future");
1050 }
1051
1052 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1053
1054 final long ident = Binder.clearCallingIdentity();
1055 try {
1056 napInternal(eventTime);
1057 } finally {
1058 Binder.restoreCallingIdentity(ident);
1059 }
1060 }
1061
1062 private void napInternal(long eventTime) {
1063 synchronized (mLock) {
1064 if (napNoUpdateLocked(eventTime)) {
1065 updatePowerStateLocked();
1066 }
1067 }
1068 }
1069
1070 private boolean napNoUpdateLocked(long eventTime) {
1071 if (DEBUG_SPEW) {
1072 Slog.d(TAG, "napNoUpdateLocked: eventTime=" + eventTime);
1073 }
1074
1075 if (eventTime < mLastWakeTime || mWakefulness != WAKEFULNESS_AWAKE
1076 || !mBootCompleted || !mSystemReady) {
1077 return false;
1078 }
1079
1080 Slog.i(TAG, "Nap time...");
1081
1082 mDirty |= DIRTY_WAKEFULNESS;
1083 mWakefulness = WAKEFULNESS_NAPPING;
1084 return true;
1085 }
1086
Jeff Brown96307042012-07-27 15:51:34 -07001087 /**
1088 * Updates the global power state based on dirty bits recorded in mDirty.
1089 *
1090 * This is the main function that performs power state transitions.
1091 * We centralize them here so that we can recompute the power state completely
1092 * each time something important changes, and ensure that we do it the same
1093 * way each time. The point is to gather all of the transition logic here.
1094 */
1095 private void updatePowerStateLocked() {
1096 if (!mSystemReady || mDirty == 0) {
The Android Open Source Project10592532009-03-18 17:39:46 -07001097 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001098 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001099
Jeff Brown96307042012-07-27 15:51:34 -07001100 // Phase 0: Basic state updates.
1101 updateIsPoweredLocked(mDirty);
1102 updateStayOnLocked(mDirty);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001103
Jeff Brown96307042012-07-27 15:51:34 -07001104 // Phase 1: Update wakefulness.
1105 // Loop because the wake lock and user activity computations are influenced
1106 // by changes in wakefulness.
1107 final long now = SystemClock.uptimeMillis();
1108 int dirtyPhase2 = 0;
1109 for (;;) {
1110 int dirtyPhase1 = mDirty;
1111 dirtyPhase2 |= dirtyPhase1;
1112 mDirty = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001113
Jeff Brown96307042012-07-27 15:51:34 -07001114 updateWakeLockSummaryLocked(dirtyPhase1);
1115 updateUserActivitySummaryLocked(now, dirtyPhase1);
1116 if (!updateWakefulnessLocked(dirtyPhase1)) {
1117 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001118 }
1119 }
1120
Jeff Brown96307042012-07-27 15:51:34 -07001121 // Phase 2: Update dreams and display power state.
1122 updateDreamLocked(dirtyPhase2);
1123 updateDisplayPowerStateLocked(dirtyPhase2);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001124
Jeff Brown96307042012-07-27 15:51:34 -07001125 // Phase 3: Send notifications, if needed.
Jeff Brown54308352012-10-04 17:59:58 -07001126 if (mDisplayReady) {
1127 sendPendingNotificationsLocked();
1128 }
Craig Mautner75fc9de2012-06-18 16:53:27 -07001129
Jeff Brown96307042012-07-27 15:51:34 -07001130 // Phase 4: Update suspend blocker.
1131 // Because we might release the last suspend blocker here, we need to make sure
1132 // we finished everything else first!
1133 updateSuspendBlockerLocked();
1134 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001135
Jeff Brown96307042012-07-27 15:51:34 -07001136 private void sendPendingNotificationsLocked() {
Jeff Brown54308352012-10-04 17:59:58 -07001137 if (mSendWakeUpFinishedNotificationWhenReady) {
1138 mSendWakeUpFinishedNotificationWhenReady = false;
1139 mNotifier.onWakeUpFinished();
1140 }
1141 if (mSendGoToSleepFinishedNotificationWhenReady) {
1142 mSendGoToSleepFinishedNotificationWhenReady = false;
1143 mNotifier.onGoToSleepFinished();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001144 }
The Android Open Source Project10592532009-03-18 17:39:46 -07001145 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001146
Jim Miller92e66dd2012-02-21 18:57:12 -08001147 /**
Jeff Brown96307042012-07-27 15:51:34 -07001148 * Updates the value of mIsPowered.
1149 * Sets DIRTY_IS_POWERED if a change occurred.
Jim Miller92e66dd2012-02-21 18:57:12 -08001150 */
Jeff Brown96307042012-07-27 15:51:34 -07001151 private void updateIsPoweredLocked(int dirty) {
1152 if ((dirty & DIRTY_BATTERY_STATE) != 0) {
Jeff Brownf3fb8952012-10-02 20:57:05 -07001153 final boolean wasPowered = mIsPowered;
1154 final int oldPlugType = mPlugType;
Jeff Browna4d82042012-10-02 19:11:19 -07001155 mIsPowered = mBatteryService.isPowered(BatteryManager.BATTERY_PLUGGED_ANY);
Jeff Brownf3fb8952012-10-02 20:57:05 -07001156 mPlugType = mBatteryService.getPlugType();
Jeff Brown016ff142012-10-15 16:47:22 -07001157 mBatteryLevel = mBatteryService.getBatteryLevel();
Jeff Browna4d82042012-10-02 19:11:19 -07001158
1159 if (DEBUG) {
1160 Slog.d(TAG, "updateIsPoweredLocked: wasPowered=" + wasPowered
Jeff Brownf3fb8952012-10-02 20:57:05 -07001161 + ", mIsPowered=" + mIsPowered
1162 + ", oldPlugType=" + oldPlugType
Jeff Brown016ff142012-10-15 16:47:22 -07001163 + ", mPlugType=" + mPlugType
1164 + ", mBatteryLevel=" + mBatteryLevel);
Jeff Browna4d82042012-10-02 19:11:19 -07001165 }
Jim Miller92e66dd2012-02-21 18:57:12 -08001166
Jeff Brownf3fb8952012-10-02 20:57:05 -07001167 if (wasPowered != mIsPowered || oldPlugType != mPlugType) {
Jeff Brown96307042012-07-27 15:51:34 -07001168 mDirty |= DIRTY_IS_POWERED;
1169
Jeff Brown3b971592013-01-09 18:46:37 -08001170 // Update wireless dock detection state.
1171 final boolean dockedOnWirelessCharger = mWirelessChargerDetector.update(
1172 mIsPowered, mPlugType, mBatteryLevel);
1173
Jeff Brown96307042012-07-27 15:51:34 -07001174 // Treat plugging and unplugging the devices as a user activity.
1175 // Users find it disconcerting when they plug or unplug the device
1176 // and it shuts off right away.
1177 // Some devices also wake the device when plugged or unplugged because
1178 // they don't have a charging LED.
1179 final long now = SystemClock.uptimeMillis();
Jeff Brown3b971592013-01-09 18:46:37 -08001180 if (shouldWakeUpWhenPluggedOrUnpluggedLocked(wasPowered, oldPlugType,
1181 dockedOnWirelessCharger)) {
Jeff Brown96307042012-07-27 15:51:34 -07001182 wakeUpNoUpdateLocked(now);
1183 }
1184 userActivityNoUpdateLocked(
1185 now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
Jeff Brown84e27562012-12-07 13:56:34 -08001186
1187 // Tell the notifier whether wireless charging has started so that
Jeff Brown3b971592013-01-09 18:46:37 -08001188 // it can provide feedback to the user.
1189 if (dockedOnWirelessCharger) {
Jeff Brown84e27562012-12-07 13:56:34 -08001190 mNotifier.onWirelessChargingStarted();
1191 }
Jeff Brown96307042012-07-27 15:51:34 -07001192 }
1193 }
1194 }
1195
Jeff Brown3b971592013-01-09 18:46:37 -08001196 private boolean shouldWakeUpWhenPluggedOrUnpluggedLocked(
1197 boolean wasPowered, int oldPlugType, boolean dockedOnWirelessCharger) {
Jeff Brown9fca9e92012-10-05 14:42:56 -07001198 // Don't wake when powered unless configured to do so.
1199 if (!mWakeUpWhenPluggedOrUnpluggedConfig) {
1200 return false;
Jeff Brownf3fb8952012-10-02 20:57:05 -07001201 }
Jeff Brown9fca9e92012-10-05 14:42:56 -07001202
Jeff Brown3b971592013-01-09 18:46:37 -08001203 // Don't wake when undocked from wireless charger.
1204 // See WirelessChargerDetector for justification.
Jeff Brown9fca9e92012-10-05 14:42:56 -07001205 if (wasPowered && !mIsPowered
1206 && oldPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS) {
1207 return false;
1208 }
Jeff Brown3b971592013-01-09 18:46:37 -08001209
1210 // Don't wake when docked on wireless charger unless we are certain of it.
1211 // See WirelessChargerDetector for justification.
Jeff Brown9fca9e92012-10-05 14:42:56 -07001212 if (!wasPowered && mIsPowered
1213 && mPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS
Jeff Brown3b971592013-01-09 18:46:37 -08001214 && !dockedOnWirelessCharger) {
Jeff Brown9fca9e92012-10-05 14:42:56 -07001215 return false;
1216 }
1217
1218 // If already dreaming and becoming powered, then don't wake.
1219 if (mIsPowered && (mWakefulness == WAKEFULNESS_NAPPING
1220 || mWakefulness == WAKEFULNESS_DREAMING)) {
1221 return false;
1222 }
1223
1224 // Otherwise wake up!
1225 return true;
Jeff Brownf3fb8952012-10-02 20:57:05 -07001226 }
1227
Jeff Brown96307042012-07-27 15:51:34 -07001228 /**
1229 * Updates the value of mStayOn.
1230 * Sets DIRTY_STAY_ON if a change occurred.
1231 */
1232 private void updateStayOnLocked(int dirty) {
1233 if ((dirty & (DIRTY_BATTERY_STATE | DIRTY_SETTINGS)) != 0) {
Jeff Brown93cbbb22012-10-04 13:18:36 -07001234 final boolean wasStayOn = mStayOn;
Jeff Brown96307042012-07-27 15:51:34 -07001235 if (mStayOnWhilePluggedInSetting != 0
1236 && !isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
1237 mStayOn = mBatteryService.isPowered(mStayOnWhilePluggedInSetting);
1238 } else {
1239 mStayOn = false;
1240 }
Jeff Brown93cbbb22012-10-04 13:18:36 -07001241
1242 if (mStayOn != wasStayOn) {
1243 mDirty |= DIRTY_STAY_ON;
1244 }
Jeff Brown96307042012-07-27 15:51:34 -07001245 }
1246 }
1247
1248 /**
1249 * Updates the value of mWakeLockSummary to summarize the state of all active wake locks.
1250 * Note that most wake-locks are ignored when the system is asleep.
1251 *
1252 * This function must have no other side-effects.
1253 */
1254 private void updateWakeLockSummaryLocked(int dirty) {
1255 if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_WAKEFULNESS)) != 0) {
1256 mWakeLockSummary = 0;
1257
1258 final int numWakeLocks = mWakeLocks.size();
1259 for (int i = 0; i < numWakeLocks; i++) {
1260 final WakeLock wakeLock = mWakeLocks.get(i);
1261 switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
1262 case PowerManager.PARTIAL_WAKE_LOCK:
1263 mWakeLockSummary |= WAKE_LOCK_CPU;
1264 break;
1265 case PowerManager.FULL_WAKE_LOCK:
1266 if (mWakefulness != WAKEFULNESS_ASLEEP) {
1267 mWakeLockSummary |= WAKE_LOCK_CPU
1268 | WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_BUTTON_BRIGHT;
Jeff Brown10428742012-10-09 15:47:30 -07001269 if (mWakefulness == WAKEFULNESS_AWAKE) {
1270 mWakeLockSummary |= WAKE_LOCK_STAY_AWAKE;
1271 }
Jeff Brown96307042012-07-27 15:51:34 -07001272 }
1273 break;
1274 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
1275 if (mWakefulness != WAKEFULNESS_ASLEEP) {
1276 mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_SCREEN_BRIGHT;
Jeff Brown10428742012-10-09 15:47:30 -07001277 if (mWakefulness == WAKEFULNESS_AWAKE) {
1278 mWakeLockSummary |= WAKE_LOCK_STAY_AWAKE;
1279 }
Jeff Brown96307042012-07-27 15:51:34 -07001280 }
1281 break;
1282 case PowerManager.SCREEN_DIM_WAKE_LOCK:
1283 if (mWakefulness != WAKEFULNESS_ASLEEP) {
1284 mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_SCREEN_DIM;
Jeff Brown10428742012-10-09 15:47:30 -07001285 if (mWakefulness == WAKEFULNESS_AWAKE) {
1286 mWakeLockSummary |= WAKE_LOCK_STAY_AWAKE;
1287 }
Jeff Brown96307042012-07-27 15:51:34 -07001288 }
1289 break;
1290 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
1291 if (mWakefulness != WAKEFULNESS_ASLEEP) {
1292 mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_PROXIMITY_SCREEN_OFF;
1293 }
1294 break;
1295 }
1296 }
1297
1298 if (DEBUG_SPEW) {
1299 Slog.d(TAG, "updateWakeLockSummaryLocked: mWakefulness="
1300 + wakefulnessToString(mWakefulness)
1301 + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary));
1302 }
1303 }
1304 }
1305
1306 /**
1307 * Updates the value of mUserActivitySummary to summarize the user requested
1308 * state of the system such as whether the screen should be bright or dim.
1309 * Note that user activity is ignored when the system is asleep.
1310 *
1311 * This function must have no other side-effects.
1312 */
1313 private void updateUserActivitySummaryLocked(long now, int dirty) {
1314 // Update the status of the user activity timeout timer.
1315 if ((dirty & (DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS | DIRTY_SETTINGS)) != 0) {
1316 mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT);
1317
1318 long nextTimeout = 0;
1319 if (mWakefulness != WAKEFULNESS_ASLEEP) {
1320 final int screenOffTimeout = getScreenOffTimeoutLocked();
Jeff Brownff532542012-10-02 21:18:04 -07001321 final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
Jeff Brown96307042012-07-27 15:51:34 -07001322
1323 mUserActivitySummary = 0;
1324 if (mLastUserActivityTime >= mLastWakeTime) {
1325 nextTimeout = mLastUserActivityTime
1326 + screenOffTimeout - screenDimDuration;
1327 if (now < nextTimeout) {
1328 mUserActivitySummary |= USER_ACTIVITY_SCREEN_BRIGHT;
1329 } else {
1330 nextTimeout = mLastUserActivityTime + screenOffTimeout;
1331 if (now < nextTimeout) {
1332 mUserActivitySummary |= USER_ACTIVITY_SCREEN_DIM;
1333 }
1334 }
1335 }
1336 if (mUserActivitySummary == 0
1337 && mLastUserActivityTimeNoChangeLights >= mLastWakeTime) {
1338 nextTimeout = mLastUserActivityTimeNoChangeLights + screenOffTimeout;
1339 if (now < nextTimeout
1340 && mDisplayPowerRequest.screenState
1341 != DisplayPowerRequest.SCREEN_STATE_OFF) {
1342 mUserActivitySummary = mDisplayPowerRequest.screenState
1343 == DisplayPowerRequest.SCREEN_STATE_BRIGHT ?
1344 USER_ACTIVITY_SCREEN_BRIGHT : USER_ACTIVITY_SCREEN_DIM;
1345 }
1346 }
1347 if (mUserActivitySummary != 0) {
1348 Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY_TIMEOUT);
1349 msg.setAsynchronous(true);
1350 mHandler.sendMessageAtTime(msg, nextTimeout);
1351 }
1352 } else {
1353 mUserActivitySummary = 0;
1354 }
1355
1356 if (DEBUG_SPEW) {
1357 Slog.d(TAG, "updateUserActivitySummaryLocked: mWakefulness="
1358 + wakefulnessToString(mWakefulness)
1359 + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
1360 + ", nextTimeout=" + TimeUtils.formatUptime(nextTimeout));
1361 }
1362 }
1363 }
1364
1365 /**
1366 * Called when a user activity timeout has occurred.
1367 * Simply indicates that something about user activity has changed so that the new
1368 * state can be recomputed when the power state is updated.
1369 *
1370 * This function must have no other side-effects besides setting the dirty
1371 * bit and calling update power state. Wakefulness transitions are handled elsewhere.
1372 */
1373 private void handleUserActivityTimeout() { // runs on handler thread
1374 synchronized (mLock) {
1375 if (DEBUG_SPEW) {
1376 Slog.d(TAG, "handleUserActivityTimeout");
1377 }
1378
1379 mDirty |= DIRTY_USER_ACTIVITY;
1380 updatePowerStateLocked();
1381 }
1382 }
1383
1384 private int getScreenOffTimeoutLocked() {
1385 int timeout = mScreenOffTimeoutSetting;
1386 if (isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
1387 timeout = Math.min(timeout, mMaximumScreenOffTimeoutFromDeviceAdmin);
1388 }
Jeff Brown1e3b98d2012-09-30 18:58:59 -07001389 if (mUserActivityTimeoutOverrideFromWindowManager >= 0) {
1390 timeout = (int)Math.min(timeout, mUserActivityTimeoutOverrideFromWindowManager);
1391 }
Jeff Brown96307042012-07-27 15:51:34 -07001392 return Math.max(timeout, MINIMUM_SCREEN_OFF_TIMEOUT);
1393 }
1394
Jeff Brownff532542012-10-02 21:18:04 -07001395 private int getScreenDimDurationLocked(int screenOffTimeout) {
1396 return Math.min(SCREEN_DIM_DURATION,
1397 (int)(screenOffTimeout * MAXIMUM_SCREEN_DIM_RATIO));
Jeff Brown96307042012-07-27 15:51:34 -07001398 }
1399
1400 /**
1401 * Updates the wakefulness of the device.
1402 *
1403 * This is the function that decides whether the device should start napping
1404 * based on the current wake locks and user activity state. It may modify mDirty
1405 * if the wakefulness changes.
1406 *
1407 * Returns true if the wakefulness changed and we need to restart power state calculation.
1408 */
1409 private boolean updateWakefulnessLocked(int dirty) {
1410 boolean changed = false;
1411 if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_BOOT_COMPLETED
Jeff Brownec6aa592012-10-17 20:30:25 -07001412 | DIRTY_WAKEFULNESS | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE
1413 | DIRTY_DOCK_STATE)) != 0) {
Jeff Brown96307042012-07-27 15:51:34 -07001414 if (mWakefulness == WAKEFULNESS_AWAKE && isItBedTimeYetLocked()) {
1415 if (DEBUG_SPEW) {
Jeff Brown62c82e42012-09-26 01:30:41 -07001416 Slog.d(TAG, "updateWakefulnessLocked: Bed time...");
Jeff Brown96307042012-07-27 15:51:34 -07001417 }
Jeff Brown62c82e42012-09-26 01:30:41 -07001418 final long time = SystemClock.uptimeMillis();
Jeff Brownec6aa592012-10-17 20:30:25 -07001419 if (shouldNapAtBedTimeLocked()) {
Jeff Brown62c82e42012-09-26 01:30:41 -07001420 changed = napNoUpdateLocked(time);
1421 } else {
1422 changed = goToSleepNoUpdateLocked(time,
1423 PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
1424 }
Jeff Brown96307042012-07-27 15:51:34 -07001425 }
1426 }
1427 return changed;
1428 }
1429
Jeff Brown645832d2012-10-03 14:57:03 -07001430 /**
Jeff Brownec6aa592012-10-17 20:30:25 -07001431 * Returns true if the device should automatically nap and start dreaming when the user
1432 * activity timeout has expired and it's bedtime.
1433 */
1434 private boolean shouldNapAtBedTimeLocked() {
1435 return mDreamsActivateOnSleepSetting
1436 || (mDreamsActivateOnDockSetting
1437 && mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED);
1438 }
1439
1440 /**
Jeff Brown645832d2012-10-03 14:57:03 -07001441 * Returns true if the device should go to sleep now.
1442 * Also used when exiting a dream to determine whether we should go back
1443 * to being fully awake or else go to sleep for good.
1444 */
Jeff Brown96307042012-07-27 15:51:34 -07001445 private boolean isItBedTimeYetLocked() {
Jeff Brown93cbbb22012-10-04 13:18:36 -07001446 return mBootCompleted && !isBeingKeptAwakeLocked();
Jeff Brown645832d2012-10-03 14:57:03 -07001447 }
1448
1449 /**
Jeff Brown93cbbb22012-10-04 13:18:36 -07001450 * Returns true if the device is being kept awake by a wake lock, user activity
Jeff Brown645832d2012-10-03 14:57:03 -07001451 * or the stay on while powered setting.
1452 */
Jeff Brown93cbbb22012-10-04 13:18:36 -07001453 private boolean isBeingKeptAwakeLocked() {
Jeff Brown645832d2012-10-03 14:57:03 -07001454 return mStayOn
Jeff Brown93cbbb22012-10-04 13:18:36 -07001455 || mProximityPositive
Jeff Brown10428742012-10-09 15:47:30 -07001456 || (mWakeLockSummary & WAKE_LOCK_STAY_AWAKE) != 0
Jeff Brown645832d2012-10-03 14:57:03 -07001457 || (mUserActivitySummary & (USER_ACTIVITY_SCREEN_BRIGHT
1458 | USER_ACTIVITY_SCREEN_DIM)) != 0;
Jeff Brown96307042012-07-27 15:51:34 -07001459 }
1460
1461 /**
1462 * Determines whether to post a message to the sandman to update the dream state.
1463 */
1464 private void updateDreamLocked(int dirty) {
John Spurlockf4f6b4c2012-08-25 12:08:03 -04001465 if ((dirty & (DIRTY_WAKEFULNESS
Jeff Brown645832d2012-10-03 14:57:03 -07001466 | DIRTY_USER_ACTIVITY
1467 | DIRTY_WAKE_LOCKS
1468 | DIRTY_BOOT_COMPLETED
John Spurlockf4f6b4c2012-08-25 12:08:03 -04001469 | DIRTY_SETTINGS
1470 | DIRTY_IS_POWERED
1471 | DIRTY_STAY_ON
Jeff Brown93cbbb22012-10-04 13:18:36 -07001472 | DIRTY_PROXIMITY_POSITIVE
Jeff Brown62c82e42012-09-26 01:30:41 -07001473 | DIRTY_BATTERY_STATE)) != 0) {
Jeff Brown96307042012-07-27 15:51:34 -07001474 scheduleSandmanLocked();
1475 }
1476 }
1477
1478 private void scheduleSandmanLocked() {
1479 if (!mSandmanScheduled) {
1480 mSandmanScheduled = true;
1481 Message msg = mHandler.obtainMessage(MSG_SANDMAN);
1482 msg.setAsynchronous(true);
1483 mHandler.sendMessage(msg);
1484 }
1485 }
1486
1487 /**
1488 * Called when the device enters or exits a napping or dreaming state.
1489 *
1490 * We do this asynchronously because we must call out of the power manager to start
1491 * the dream and we don't want to hold our lock while doing so. There is a risk that
1492 * the device will wake or go to sleep in the meantime so we have to handle that case.
1493 */
1494 private void handleSandman() { // runs on handler thread
1495 // Handle preconditions.
1496 boolean startDreaming = false;
1497 synchronized (mLock) {
1498 mSandmanScheduled = false;
John Spurlock10fb2242012-08-23 15:32:28 -04001499 boolean canDream = canDreamLocked();
Jeff Brown96307042012-07-27 15:51:34 -07001500 if (DEBUG_SPEW) {
Jeff Brown016ff142012-10-15 16:47:22 -07001501 Slog.d(TAG, "handleSandman: canDream=" + canDream
Jeff Brown96307042012-07-27 15:51:34 -07001502 + ", mWakefulness=" + wakefulnessToString(mWakefulness));
1503 }
1504
John Spurlock10fb2242012-08-23 15:32:28 -04001505 if (canDream && mWakefulness == WAKEFULNESS_NAPPING) {
Jeff Brown96307042012-07-27 15:51:34 -07001506 startDreaming = true;
1507 }
1508 }
1509
Jeff Brown96307042012-07-27 15:51:34 -07001510 // Start dreaming if needed.
1511 // We only control the dream on the handler thread, so we don't need to worry about
1512 // concurrent attempts to start or stop the dream.
1513 boolean isDreaming = false;
1514 if (mDreamManager != null) {
Jeff Brown62c82e42012-09-26 01:30:41 -07001515 if (startDreaming) {
1516 mDreamManager.startDream();
Jeff Brown96307042012-07-27 15:51:34 -07001517 }
Jeff Brown62c82e42012-09-26 01:30:41 -07001518 isDreaming = mDreamManager.isDreaming();
Jeff Brown96307042012-07-27 15:51:34 -07001519 }
1520
1521 // Update dream state.
1522 // We might need to stop the dream again if the preconditions changed.
1523 boolean continueDreaming = false;
1524 synchronized (mLock) {
1525 if (isDreaming && canDreamLocked()) {
1526 if (mWakefulness == WAKEFULNESS_NAPPING) {
1527 mWakefulness = WAKEFULNESS_DREAMING;
1528 mDirty |= DIRTY_WAKEFULNESS;
Jeff Brown016ff142012-10-15 16:47:22 -07001529 mBatteryLevelWhenDreamStarted = mBatteryLevel;
Jeff Brown96307042012-07-27 15:51:34 -07001530 updatePowerStateLocked();
1531 continueDreaming = true;
1532 } else if (mWakefulness == WAKEFULNESS_DREAMING) {
Jeff Brown016ff142012-10-15 16:47:22 -07001533 if (!isBeingKeptAwakeLocked()
1534 && mBatteryLevel < mBatteryLevelWhenDreamStarted
1535 - DREAM_BATTERY_LEVEL_DRAIN_CUTOFF) {
1536 // If the user activity timeout expired and the battery appears
1537 // to be draining faster than it is charging then stop dreaming
1538 // and go to sleep.
1539 Slog.i(TAG, "Stopping dream because the battery appears to "
1540 + "be draining faster than it is charging. "
1541 + "Battery level when dream started: "
1542 + mBatteryLevelWhenDreamStarted + "%. "
1543 + "Battery level now: " + mBatteryLevel + "%.");
1544 } else {
1545 continueDreaming = true;
1546 }
Jeff Brown96307042012-07-27 15:51:34 -07001547 }
1548 }
1549 if (!continueDreaming) {
1550 handleDreamFinishedLocked();
1551 }
Jeff Brown96307042012-07-27 15:51:34 -07001552 }
1553
1554 // Stop dreaming if needed.
1555 // It's possible that something else changed to make us need to start the dream again.
1556 // If so, then the power manager will have posted another message to the handler
1557 // to take care of it later.
1558 if (mDreamManager != null) {
Jeff Brown62c82e42012-09-26 01:30:41 -07001559 if (!continueDreaming) {
1560 mDreamManager.stopDream();
Jeff Brown96307042012-07-27 15:51:34 -07001561 }
1562 }
1563 }
1564
1565 /**
Jeff Brown645832d2012-10-03 14:57:03 -07001566 * Returns true if the device is allowed to dream in its current state
1567 * assuming that it is currently napping or dreaming.
Jeff Brown96307042012-07-27 15:51:34 -07001568 */
1569 private boolean canDreamLocked() {
Jeff Brown645832d2012-10-03 14:57:03 -07001570 return mDreamsSupportedConfig
John Spurlock10fb2242012-08-23 15:32:28 -04001571 && mDreamsEnabledSetting
Jeff Brown645832d2012-10-03 14:57:03 -07001572 && mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF
1573 && mBootCompleted
Jeff Brown93cbbb22012-10-04 13:18:36 -07001574 && (mIsPowered || isBeingKeptAwakeLocked());
Jeff Brown96307042012-07-27 15:51:34 -07001575 }
1576
1577 /**
1578 * Called when a dream is ending to figure out what to do next.
1579 */
1580 private void handleDreamFinishedLocked() {
1581 if (mWakefulness == WAKEFULNESS_NAPPING
1582 || mWakefulness == WAKEFULNESS_DREAMING) {
1583 if (isItBedTimeYetLocked()) {
1584 goToSleepNoUpdateLocked(SystemClock.uptimeMillis(),
1585 PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
1586 updatePowerStateLocked();
1587 } else {
1588 wakeUpNoUpdateLocked(SystemClock.uptimeMillis());
1589 updatePowerStateLocked();
1590 }
1591 }
1592 }
1593
Jeff Brownc38c9be2012-10-04 13:16:19 -07001594 private void handleScreenOnBlockerReleased() {
1595 synchronized (mLock) {
1596 mDirty |= DIRTY_SCREEN_ON_BLOCKER_RELEASED;
1597 updatePowerStateLocked();
1598 }
1599 }
1600
Jeff Brown96307042012-07-27 15:51:34 -07001601 /**
1602 * Updates the display power state asynchronously.
1603 * When the update is finished, mDisplayReady will be set to true. The display
1604 * controller posts a message to tell us when the actual display power state
1605 * has been updated so we come back here to double-check and finish up.
1606 *
1607 * This function recalculates the display power state each time.
1608 */
1609 private void updateDisplayPowerStateLocked(int dirty) {
1610 if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS
1611 | DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED
Jeff Brownc38c9be2012-10-04 13:16:19 -07001612 | DIRTY_SETTINGS | DIRTY_SCREEN_ON_BLOCKER_RELEASED)) != 0) {
1613 int newScreenState = getDesiredScreenPowerStateLocked();
Jeff Brown96307042012-07-27 15:51:34 -07001614 if (newScreenState != mDisplayPowerRequest.screenState) {
1615 if (newScreenState == DisplayPowerRequest.SCREEN_STATE_OFF
1616 && mDisplayPowerRequest.screenState
1617 != DisplayPowerRequest.SCREEN_STATE_OFF) {
1618 mLastScreenOffEventElapsedRealTime = SystemClock.elapsedRealtime();
1619 }
1620
1621 mDisplayPowerRequest.screenState = newScreenState;
1622 nativeSetPowerState(
1623 newScreenState != DisplayPowerRequest.SCREEN_STATE_OFF,
1624 newScreenState == DisplayPowerRequest.SCREEN_STATE_BRIGHT);
1625 }
1626
1627 int screenBrightness = mScreenBrightnessSettingDefault;
Jeff Brown330560f2012-08-21 22:10:57 -07001628 float screenAutoBrightnessAdjustment = 0.0f;
Jeff Brown96307042012-07-27 15:51:34 -07001629 boolean autoBrightness = (mScreenBrightnessModeSetting ==
1630 Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
1631 if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)) {
1632 screenBrightness = mScreenBrightnessOverrideFromWindowManager;
1633 autoBrightness = false;
1634 } else if (isValidBrightness(mTemporaryScreenBrightnessSettingOverride)) {
1635 screenBrightness = mTemporaryScreenBrightnessSettingOverride;
1636 } else if (isValidBrightness(mScreenBrightnessSetting)) {
Jeff Brown330560f2012-08-21 22:10:57 -07001637 screenBrightness = mScreenBrightnessSetting;
Jeff Brown96307042012-07-27 15:51:34 -07001638 }
1639 if (autoBrightness) {
1640 screenBrightness = mScreenBrightnessSettingDefault;
Jeff Brown330560f2012-08-21 22:10:57 -07001641 if (isValidAutoBrightnessAdjustment(
1642 mTemporaryScreenAutoBrightnessAdjustmentSettingOverride)) {
1643 screenAutoBrightnessAdjustment =
1644 mTemporaryScreenAutoBrightnessAdjustmentSettingOverride;
1645 } else if (isValidAutoBrightnessAdjustment(
1646 mScreenAutoBrightnessAdjustmentSetting)) {
1647 screenAutoBrightnessAdjustment = mScreenAutoBrightnessAdjustmentSetting;
1648 }
Jeff Brown96307042012-07-27 15:51:34 -07001649 }
1650 screenBrightness = Math.max(Math.min(screenBrightness,
1651 mScreenBrightnessSettingMaximum), mScreenBrightnessSettingMinimum);
Jeff Brown330560f2012-08-21 22:10:57 -07001652 screenAutoBrightnessAdjustment = Math.max(Math.min(
1653 screenAutoBrightnessAdjustment, 1.0f), -1.0f);
Jeff Brown96307042012-07-27 15:51:34 -07001654 mDisplayPowerRequest.screenBrightness = screenBrightness;
Jeff Brown330560f2012-08-21 22:10:57 -07001655 mDisplayPowerRequest.screenAutoBrightnessAdjustment =
1656 screenAutoBrightnessAdjustment;
Jeff Brown96307042012-07-27 15:51:34 -07001657 mDisplayPowerRequest.useAutoBrightness = autoBrightness;
1658
1659 mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
1660
Jeff Brownc38c9be2012-10-04 13:16:19 -07001661 mDisplayPowerRequest.blockScreenOn = mScreenOnBlocker.isHeld();
1662
Jeff Brown96307042012-07-27 15:51:34 -07001663 mDisplayReady = mDisplayPowerController.requestPowerState(mDisplayPowerRequest,
1664 mRequestWaitForNegativeProximity);
1665 mRequestWaitForNegativeProximity = false;
1666
1667 if (DEBUG_SPEW) {
Jeff Brownc38c9be2012-10-04 13:16:19 -07001668 Slog.d(TAG, "updateScreenStateLocked: mDisplayReady=" + mDisplayReady
Jeff Brown96307042012-07-27 15:51:34 -07001669 + ", newScreenState=" + newScreenState
1670 + ", mWakefulness=" + mWakefulness
1671 + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary)
1672 + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
1673 + ", mBootCompleted=" + mBootCompleted);
1674 }
1675 }
1676 }
1677
1678 private static boolean isValidBrightness(int value) {
1679 return value >= 0 && value <= 255;
1680 }
1681
Jeff Brown330560f2012-08-21 22:10:57 -07001682 private static boolean isValidAutoBrightnessAdjustment(float value) {
Jeff Brown5d03a532012-08-22 13:22:02 -07001683 // Handles NaN by always returning false.
1684 return value >= -1.0f && value <= 1.0f;
Jeff Brown330560f2012-08-21 22:10:57 -07001685 }
1686
Jeff Brownc38c9be2012-10-04 13:16:19 -07001687 private int getDesiredScreenPowerStateLocked() {
Jeff Brown96307042012-07-27 15:51:34 -07001688 if (mWakefulness == WAKEFULNESS_ASLEEP) {
1689 return DisplayPowerRequest.SCREEN_STATE_OFF;
1690 }
1691
1692 if ((mWakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0
1693 || (mUserActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0
1694 || !mBootCompleted) {
1695 return DisplayPowerRequest.SCREEN_STATE_BRIGHT;
1696 }
1697
1698 return DisplayPowerRequest.SCREEN_STATE_DIM;
1699 }
1700
1701 private final DisplayPowerController.Callbacks mDisplayPowerControllerCallbacks =
1702 new DisplayPowerController.Callbacks() {
1703 @Override
1704 public void onStateChanged() {
Jeff Brownba8a5412013-07-16 15:18:19 -07001705 synchronized (mLock) {
1706 mDirty |= DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED;
1707 updatePowerStateLocked();
1708 }
Jim Miller92e66dd2012-02-21 18:57:12 -08001709 }
1710
1711 @Override
Jeff Brown93cbbb22012-10-04 13:18:36 -07001712 public void onProximityPositive() {
Jeff Brownba8a5412013-07-16 15:18:19 -07001713 synchronized (mLock) {
1714 mProximityPositive = true;
1715 mDirty |= DIRTY_PROXIMITY_POSITIVE;
1716 updatePowerStateLocked();
1717 }
Jeff Brown93cbbb22012-10-04 13:18:36 -07001718 }
1719
1720 @Override
Jeff Brown96307042012-07-27 15:51:34 -07001721 public void onProximityNegative() {
Jeff Brownba8a5412013-07-16 15:18:19 -07001722 synchronized (mLock) {
1723 mProximityPositive = false;
1724 mDirty |= DIRTY_PROXIMITY_POSITIVE;
1725 userActivityNoUpdateLocked(SystemClock.uptimeMillis(),
1726 PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
1727 updatePowerStateLocked();
1728 }
Jeff Brown96307042012-07-27 15:51:34 -07001729 }
1730 };
Jim Miller92e66dd2012-02-21 18:57:12 -08001731
Jeff Brown96307042012-07-27 15:51:34 -07001732 private boolean shouldUseProximitySensorLocked() {
1733 return (mWakeLockSummary & WAKE_LOCK_PROXIMITY_SCREEN_OFF) != 0;
1734 }
Jim Miller92e66dd2012-02-21 18:57:12 -08001735
Jeff Brown96307042012-07-27 15:51:34 -07001736 /**
1737 * Updates the suspend blocker that keeps the CPU alive.
1738 *
1739 * This function must have no other side-effects.
1740 */
1741 private void updateSuspendBlockerLocked() {
Jeff Brown27f7a862012-12-12 15:43:31 -08001742 final boolean needWakeLockSuspendBlocker = (mWakeLockSummary != 0);
1743 final boolean needDisplaySuspendBlocker = (mUserActivitySummary != 0
Jeff Brown96307042012-07-27 15:51:34 -07001744 || mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF
Jeff Brown27f7a862012-12-12 15:43:31 -08001745 || !mDisplayReady || !mBootCompleted);
1746
1747 // First acquire suspend blockers if needed.
1748 if (needWakeLockSuspendBlocker && !mHoldingWakeLockSuspendBlocker) {
1749 mWakeLockSuspendBlocker.acquire();
1750 mHoldingWakeLockSuspendBlocker = true;
1751 }
1752 if (needDisplaySuspendBlocker && !mHoldingDisplaySuspendBlocker) {
1753 mDisplaySuspendBlocker.acquire();
1754 mHoldingDisplaySuspendBlocker = true;
1755 }
1756
1757 // Then release suspend blockers if needed.
1758 if (!needWakeLockSuspendBlocker && mHoldingWakeLockSuspendBlocker) {
1759 mWakeLockSuspendBlocker.release();
1760 mHoldingWakeLockSuspendBlocker = false;
1761 }
1762 if (!needDisplaySuspendBlocker && mHoldingDisplaySuspendBlocker) {
1763 mDisplaySuspendBlocker.release();
1764 mHoldingDisplaySuspendBlocker = false;
1765 }
Jeff Brown96307042012-07-27 15:51:34 -07001766 }
1767
1768 @Override // Binder call
1769 public boolean isScreenOn() {
1770 final long ident = Binder.clearCallingIdentity();
Mike Lockwoodd7786b42009-10-15 17:09:16 -07001771 try {
Jeff Brown96307042012-07-27 15:51:34 -07001772 return isScreenOnInternal();
1773 } finally {
1774 Binder.restoreCallingIdentity(ident);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07001775 }
1776 }
1777
Jeff Brown96307042012-07-27 15:51:34 -07001778 private boolean isScreenOnInternal() {
1779 synchronized (mLock) {
1780 return !mSystemReady
1781 || mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF;
Mike Lockwoodb2865412010-02-02 22:40:33 -05001782 }
1783 }
1784
Jeff Brown96307042012-07-27 15:51:34 -07001785 private void handleBatteryStateChangedLocked() {
1786 mDirty |= DIRTY_BATTERY_STATE;
1787 updatePowerStateLocked();
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001788 }
1789
Jeff Brown20767b22012-10-09 18:57:07 -07001790 private void startWatchingForBootAnimationFinished() {
1791 mHandler.sendEmptyMessage(MSG_CHECK_IF_BOOT_ANIMATION_FINISHED);
1792 }
1793
1794 private void checkIfBootAnimationFinished() {
1795 if (DEBUG) {
1796 Slog.d(TAG, "Check if boot animation finished...");
1797 }
1798
1799 if (SystemService.isRunning(BOOT_ANIMATION_SERVICE)) {
1800 mHandler.sendEmptyMessageDelayed(MSG_CHECK_IF_BOOT_ANIMATION_FINISHED,
1801 BOOT_ANIMATION_POLL_INTERVAL);
1802 return;
1803 }
1804
1805 synchronized (mLock) {
1806 if (!mBootCompleted) {
1807 Slog.i(TAG, "Boot animation finished.");
1808 handleBootCompletedLocked();
1809 }
1810 }
1811 }
1812
Jeff Brown96307042012-07-27 15:51:34 -07001813 private void handleBootCompletedLocked() {
1814 final long now = SystemClock.uptimeMillis();
1815 mBootCompleted = true;
1816 mDirty |= DIRTY_BOOT_COMPLETED;
1817 userActivityNoUpdateLocked(
1818 now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
1819 updatePowerStateLocked();
Dianne Hackborn254cb442010-01-27 19:23:59 -08001820 }
1821
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001822 /**
Jeff Brownab887a02012-10-15 16:00:40 -07001823 * Reboots the device.
1824 *
1825 * @param confirm If true, shows a reboot confirmation dialog.
1826 * @param reason The reason for the reboot, or null if none.
1827 * @param wait If true, this call waits for the reboot to complete and does not return.
Doug Zongker50a21f42009-11-19 12:49:53 -08001828 */
Jeff Brown96307042012-07-27 15:51:34 -07001829 @Override // Binder call
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001830 public void reboot(boolean confirm, String reason, boolean wait) {
Doug Zongker50a21f42009-11-19 12:49:53 -08001831 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
San Mehat14e69af2010-01-06 14:58:18 -08001832
Jeff Brown96307042012-07-27 15:51:34 -07001833 final long ident = Binder.clearCallingIdentity();
1834 try {
Jeff Brownab887a02012-10-15 16:00:40 -07001835 shutdownOrRebootInternal(false, confirm, reason, wait);
Jeff Brown96307042012-07-27 15:51:34 -07001836 } finally {
1837 Binder.restoreCallingIdentity(ident);
1838 }
1839 }
1840
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001841 /**
Jeff Brownab887a02012-10-15 16:00:40 -07001842 * Shuts down the device.
1843 *
1844 * @param confirm If true, shows a shutdown confirmation dialog.
1845 * @param wait If true, this call waits for the shutdown to complete and does not return.
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001846 */
1847 @Override // Binder call
1848 public void shutdown(boolean confirm, boolean wait) {
1849 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
1850
1851 final long ident = Binder.clearCallingIdentity();
1852 try {
Jeff Brownab887a02012-10-15 16:00:40 -07001853 shutdownOrRebootInternal(true, confirm, null, wait);
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001854 } finally {
1855 Binder.restoreCallingIdentity(ident);
1856 }
1857 }
1858
Jeff Brownab887a02012-10-15 16:00:40 -07001859 private void shutdownOrRebootInternal(final boolean shutdown, final boolean confirm,
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001860 final String reason, boolean wait) {
Jeff Brown96307042012-07-27 15:51:34 -07001861 if (mHandler == null || !mSystemReady) {
Jeff Brownab887a02012-10-15 16:00:40 -07001862 throw new IllegalStateException("Too early to call shutdown() or reboot()");
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001863 }
Mike Lockwoodb62f9592010-03-12 07:55:23 -05001864
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001865 Runnable runnable = new Runnable() {
Jeff Brownab887a02012-10-15 16:00:40 -07001866 @Override
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001867 public void run() {
1868 synchronized (this) {
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001869 if (shutdown) {
1870 ShutdownThread.shutdown(mContext, confirm);
1871 } else {
1872 ShutdownThread.reboot(mContext, reason, confirm);
1873 }
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001874 }
San Mehat1e512792010-01-07 10:40:29 -08001875 }
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001876 };
Jeff Brown96307042012-07-27 15:51:34 -07001877
Mike Lockwoodb62f9592010-03-12 07:55:23 -05001878 // ShutdownThread must run on a looper capable of displaying the UI.
Jeff Brown96307042012-07-27 15:51:34 -07001879 Message msg = Message.obtain(mHandler, runnable);
1880 msg.setAsynchronous(true);
1881 mHandler.sendMessage(msg);
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001882
Mike Lockwoodb62f9592010-03-12 07:55:23 -05001883 // PowerManager.reboot() is documented not to return so just wait for the inevitable.
Dianne Hackbornc428aae2012-10-03 16:38:22 -07001884 if (wait) {
1885 synchronized (runnable) {
1886 while (true) {
1887 try {
1888 runnable.wait();
1889 } catch (InterruptedException e) {
1890 }
Mike Lockwoodb62f9592010-03-12 07:55:23 -05001891 }
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08001892 }
Doug Zongker50a21f42009-11-19 12:49:53 -08001893 }
1894 }
1895
Dan Egnor60d87622009-12-16 16:32:58 -08001896 /**
1897 * Crash the runtime (causing a complete restart of the Android framework).
1898 * Requires REBOOT permission. Mostly for testing. Should not return.
1899 */
Jeff Brown96307042012-07-27 15:51:34 -07001900 @Override // Binder call
1901 public void crash(String message) {
Dan Egnor60d87622009-12-16 16:32:58 -08001902 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
Jeff Brown96307042012-07-27 15:51:34 -07001903
1904 final long ident = Binder.clearCallingIdentity();
1905 try {
1906 crashInternal(message);
1907 } finally {
1908 Binder.restoreCallingIdentity(ident);
1909 }
1910 }
1911
1912 private void crashInternal(final String message) {
Dan Egnor60d87622009-12-16 16:32:58 -08001913 Thread t = new Thread("PowerManagerService.crash()") {
Jeff Brownab887a02012-10-15 16:00:40 -07001914 @Override
Jeff Brown96307042012-07-27 15:51:34 -07001915 public void run() {
1916 throw new RuntimeException(message);
1917 }
Dan Egnor60d87622009-12-16 16:32:58 -08001918 };
1919 try {
1920 t.start();
1921 t.join();
1922 } catch (InterruptedException e) {
1923 Log.wtf(TAG, e);
1924 }
1925 }
1926
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001927 /**
Jeff Brown96307042012-07-27 15:51:34 -07001928 * Set the setting that determines whether the device stays on when plugged in.
1929 * The argument is a bit string, with each bit specifying a power source that,
1930 * when the device is connected to that source, causes the device to stay on.
1931 * See {@link android.os.BatteryManager} for the list of power sources that
1932 * can be specified. Current values include {@link android.os.BatteryManager#BATTERY_PLUGGED_AC}
1933 * and {@link android.os.BatteryManager#BATTERY_PLUGGED_USB}
1934 *
1935 * Used by "adb shell svc power stayon ..."
1936 *
1937 * @param val an {@code int} containing the bits that specify which power sources
1938 * should cause the device to stay on.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001939 */
Jeff Brown96307042012-07-27 15:51:34 -07001940 @Override // Binder call
1941 public void setStayOnSetting(int val) {
1942 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS, null);
1943
1944 final long ident = Binder.clearCallingIdentity();
1945 try {
1946 setStayOnSettingInternal(val);
1947 } finally {
1948 Binder.restoreCallingIdentity(ident);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001949 }
1950 }
1951
Jeff Brown96307042012-07-27 15:51:34 -07001952 private void setStayOnSettingInternal(int val) {
Christopher Tatead735322012-09-07 14:19:43 -07001953 Settings.Global.putInt(mContext.getContentResolver(),
1954 Settings.Global.STAY_ON_WHILE_PLUGGED_IN, val);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001955 }
1956
1957 /**
Jeff Brown96307042012-07-27 15:51:34 -07001958 * Used by device administration to set the maximum screen off timeout.
1959 *
1960 * This method must only be called by the device administration policy manager.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001961 */
Jeff Brown96307042012-07-27 15:51:34 -07001962 @Override // Binder call
1963 public void setMaximumScreenOffTimeoutFromDeviceAdmin(int timeMs) {
1964 final long ident = Binder.clearCallingIdentity();
1965 try {
1966 setMaximumScreenOffTimeoutFromDeviceAdminInternal(timeMs);
1967 } finally {
1968 Binder.restoreCallingIdentity(ident);
Michael Chane96440f2009-05-06 10:27:36 -07001969 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001970 }
1971
Jeff Brown96307042012-07-27 15:51:34 -07001972 private void setMaximumScreenOffTimeoutFromDeviceAdminInternal(int timeMs) {
1973 synchronized (mLock) {
1974 mMaximumScreenOffTimeoutFromDeviceAdmin = timeMs;
1975 mDirty |= DIRTY_SETTINGS;
1976 updatePowerStateLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001977 }
1978 }
1979
Jeff Brown96307042012-07-27 15:51:34 -07001980 private boolean isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked() {
1981 return mMaximumScreenOffTimeoutFromDeviceAdmin >= 0
1982 && mMaximumScreenOffTimeoutFromDeviceAdmin < Integer.MAX_VALUE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001983 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001984
Jeff Brown96307042012-07-27 15:51:34 -07001985 /**
1986 * Used by the phone application to make the attention LED flash when ringing.
1987 */
1988 @Override // Binder call
Mike Lockwoodb11832d2009-11-25 15:25:55 -05001989 public void setAttentionLight(boolean on, int color) {
1990 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
Jeff Brown96307042012-07-27 15:51:34 -07001991
1992 final long ident = Binder.clearCallingIdentity();
1993 try {
1994 setAttentionLightInternal(on, color);
1995 } finally {
1996 Binder.restoreCallingIdentity(ident);
1997 }
Mike Lockwoodb11832d2009-11-25 15:25:55 -05001998 }
1999
Jeff Brown96307042012-07-27 15:51:34 -07002000 private void setAttentionLightInternal(boolean on, int color) {
2001 LightsService.Light light;
2002 synchronized (mLock) {
2003 if (!mSystemReady) {
2004 return;
2005 }
2006 light = mAttentionLight;
Mike Lockwood36fc3022009-08-25 16:49:06 -07002007 }
Jeff Brown96307042012-07-27 15:51:34 -07002008
2009 // Control light outside of lock.
2010 light.setFlashing(color, LightsService.LIGHT_FLASH_HARDWARE, (on ? 3 : 0), 0);
2011 }
2012
2013 /**
2014 * Used by the Watchdog.
2015 */
2016 public long timeSinceScreenWasLastOn() {
2017 synchronized (mLock) {
2018 if (mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF) {
2019 return 0;
2020 }
2021 return SystemClock.elapsedRealtime() - mLastScreenOffEventElapsedRealTime;
2022 }
2023 }
2024
2025 /**
2026 * Used by the window manager to override the screen brightness based on the
2027 * current foreground activity.
2028 *
2029 * This method must only be called by the window manager.
2030 *
2031 * @param brightness The overridden brightness, or -1 to disable the override.
2032 */
2033 public void setScreenBrightnessOverrideFromWindowManager(int brightness) {
2034 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
2035
2036 final long ident = Binder.clearCallingIdentity();
2037 try {
2038 setScreenBrightnessOverrideFromWindowManagerInternal(brightness);
2039 } finally {
2040 Binder.restoreCallingIdentity(ident);
2041 }
2042 }
2043
2044 private void setScreenBrightnessOverrideFromWindowManagerInternal(int brightness) {
2045 synchronized (mLock) {
2046 if (mScreenBrightnessOverrideFromWindowManager != brightness) {
2047 mScreenBrightnessOverrideFromWindowManager = brightness;
2048 mDirty |= DIRTY_SETTINGS;
2049 updatePowerStateLocked();
Mike Lockwoodee2b0942009-11-09 14:09:02 -05002050 }
Mike Lockwood809ad0f2009-10-26 22:10:33 -04002051 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07002052 }
2053
Jeff Brown96307042012-07-27 15:51:34 -07002054 /**
2055 * Used by the window manager to override the button brightness based on the
2056 * current foreground activity.
2057 *
2058 * This method must only be called by the window manager.
2059 *
2060 * @param brightness The overridden brightness, or -1 to disable the override.
2061 */
2062 public void setButtonBrightnessOverrideFromWindowManager(int brightness) {
2063 // Do nothing.
2064 // Button lights are not currently supported in the new implementation.
2065 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
2066 }
2067
2068 /**
Jeff Brown1e3b98d2012-09-30 18:58:59 -07002069 * Used by the window manager to override the user activity timeout based on the
2070 * current foreground activity. It can only be used to make the timeout shorter
2071 * than usual, not longer.
2072 *
2073 * This method must only be called by the window manager.
2074 *
2075 * @param timeoutMillis The overridden timeout, or -1 to disable the override.
2076 */
2077 public void setUserActivityTimeoutOverrideFromWindowManager(long timeoutMillis) {
2078 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
2079
2080 final long ident = Binder.clearCallingIdentity();
2081 try {
2082 setUserActivityTimeoutOverrideFromWindowManagerInternal(timeoutMillis);
2083 } finally {
2084 Binder.restoreCallingIdentity(ident);
2085 }
2086 }
2087
2088 private void setUserActivityTimeoutOverrideFromWindowManagerInternal(long timeoutMillis) {
2089 synchronized (mLock) {
2090 if (mUserActivityTimeoutOverrideFromWindowManager != timeoutMillis) {
2091 mUserActivityTimeoutOverrideFromWindowManager = timeoutMillis;
2092 mDirty |= DIRTY_SETTINGS;
2093 updatePowerStateLocked();
2094 }
2095 }
2096 }
2097
2098 /**
Jeff Brown96307042012-07-27 15:51:34 -07002099 * Used by the settings application and brightness control widgets to
2100 * temporarily override the current screen brightness setting so that the
2101 * user can observe the effect of an intended settings change without applying
2102 * it immediately.
2103 *
2104 * The override will be canceled when the setting value is next updated.
2105 *
2106 * @param brightness The overridden brightness.
2107 *
2108 * @see Settings.System#SCREEN_BRIGHTNESS
2109 */
2110 @Override // Binder call
2111 public void setTemporaryScreenBrightnessSettingOverride(int brightness) {
2112 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
2113
2114 final long ident = Binder.clearCallingIdentity();
2115 try {
2116 setTemporaryScreenBrightnessSettingOverrideInternal(brightness);
2117 } finally {
2118 Binder.restoreCallingIdentity(ident);
Mike Lockwood36fc3022009-08-25 16:49:06 -07002119 }
Jeff Brown96307042012-07-27 15:51:34 -07002120 }
2121
2122 private void setTemporaryScreenBrightnessSettingOverrideInternal(int brightness) {
2123 synchronized (mLock) {
2124 if (mTemporaryScreenBrightnessSettingOverride != brightness) {
2125 mTemporaryScreenBrightnessSettingOverride = brightness;
2126 mDirty |= DIRTY_SETTINGS;
2127 updatePowerStateLocked();
Mike Lockwoodee2b0942009-11-09 14:09:02 -05002128 }
Mike Lockwood200b30b2009-09-20 00:23:59 -04002129 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07002130 }
2131
Jeff Brown96307042012-07-27 15:51:34 -07002132 /**
2133 * Used by the settings application and brightness control widgets to
2134 * temporarily override the current screen auto-brightness adjustment setting so that the
2135 * user can observe the effect of an intended settings change without applying
2136 * it immediately.
2137 *
2138 * The override will be canceled when the setting value is next updated.
2139 *
Jeff Brown330560f2012-08-21 22:10:57 -07002140 * @param adj The overridden brightness, or Float.NaN to disable the override.
Jeff Brown96307042012-07-27 15:51:34 -07002141 *
2142 * @see Settings.System#SCREEN_AUTO_BRIGHTNESS_ADJ
2143 */
2144 @Override // Binder call
2145 public void setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(float adj) {
Jeff Brown96307042012-07-27 15:51:34 -07002146 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
Jeff Brown330560f2012-08-21 22:10:57 -07002147
2148 final long ident = Binder.clearCallingIdentity();
2149 try {
2150 setTemporaryScreenAutoBrightnessAdjustmentSettingOverrideInternal(adj);
2151 } finally {
2152 Binder.restoreCallingIdentity(ident);
2153 }
2154 }
2155
2156 private void setTemporaryScreenAutoBrightnessAdjustmentSettingOverrideInternal(float adj) {
2157 synchronized (mLock) {
2158 // Note: This condition handles NaN because NaN is not equal to any other
2159 // value, including itself.
2160 if (mTemporaryScreenAutoBrightnessAdjustmentSettingOverride != adj) {
2161 mTemporaryScreenAutoBrightnessAdjustmentSettingOverride = adj;
2162 mDirty |= DIRTY_SETTINGS;
2163 updatePowerStateLocked();
2164 }
2165 }
Jeff Brown96307042012-07-27 15:51:34 -07002166 }
2167
2168 /**
2169 * Low-level function turn the device off immediately, without trying
2170 * to be clean. Most people should use {@link ShutdownThread} for a clean shutdown.
2171 */
2172 public static void lowLevelShutdown() {
2173 nativeShutdown();
2174 }
2175
2176 /**
2177 * Low-level function to reboot the device.
2178 *
2179 * @param reason code to pass to the kernel (e.g. "recovery"), or null.
2180 * @throws IOException if reboot fails for some reason (eg, lack of
2181 * permission)
2182 */
2183 public static void lowLevelReboot(String reason) throws IOException {
2184 nativeReboot(reason);
2185 }
2186
2187 @Override // Watchdog.Monitor implementation
2188 public void monitor() {
2189 // Grab and release lock for watchdog monitor to detect deadlocks.
2190 synchronized (mLock) {
Mike Lockwood20f87d72009-11-05 16:08:51 -05002191 }
Jeff Brown96307042012-07-27 15:51:34 -07002192 }
2193
2194 @Override // Binder call
2195 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2196 if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
2197 != PackageManager.PERMISSION_GRANTED) {
2198 pw.println("Permission Denial: can't dump PowerManager from from pid="
2199 + Binder.getCallingPid()
2200 + ", uid=" + Binder.getCallingUid());
Mike Lockwood0d72f7e2009-11-05 20:53:00 -05002201 return;
2202 }
Jeff Brown96307042012-07-27 15:51:34 -07002203
2204 pw.println("POWER MANAGER (dumpsys power)\n");
2205
2206 final DisplayPowerController dpc;
Jeff Brown3b971592013-01-09 18:46:37 -08002207 final WirelessChargerDetector wcd;
Jeff Brown96307042012-07-27 15:51:34 -07002208 synchronized (mLock) {
2209 pw.println("Power Manager State:");
2210 pw.println(" mDirty=0x" + Integer.toHexString(mDirty));
2211 pw.println(" mWakefulness=" + wakefulnessToString(mWakefulness));
2212 pw.println(" mIsPowered=" + mIsPowered);
Jeff Brownf3fb8952012-10-02 20:57:05 -07002213 pw.println(" mPlugType=" + mPlugType);
Jeff Brown016ff142012-10-15 16:47:22 -07002214 pw.println(" mBatteryLevel=" + mBatteryLevel);
2215 pw.println(" mBatteryLevelWhenDreamStarted=" + mBatteryLevelWhenDreamStarted);
Jeff Brownec6aa592012-10-17 20:30:25 -07002216 pw.println(" mDockState=" + mDockState);
Jeff Brown96307042012-07-27 15:51:34 -07002217 pw.println(" mStayOn=" + mStayOn);
Jeff Brown93cbbb22012-10-04 13:18:36 -07002218 pw.println(" mProximityPositive=" + mProximityPositive);
Jeff Brown96307042012-07-27 15:51:34 -07002219 pw.println(" mBootCompleted=" + mBootCompleted);
2220 pw.println(" mSystemReady=" + mSystemReady);
2221 pw.println(" mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary));
2222 pw.println(" mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary));
2223 pw.println(" mRequestWaitForNegativeProximity=" + mRequestWaitForNegativeProximity);
2224 pw.println(" mSandmanScheduled=" + mSandmanScheduled);
2225 pw.println(" mLastWakeTime=" + TimeUtils.formatUptime(mLastWakeTime));
2226 pw.println(" mLastSleepTime=" + TimeUtils.formatUptime(mLastSleepTime));
2227 pw.println(" mSendWakeUpFinishedNotificationWhenReady="
2228 + mSendWakeUpFinishedNotificationWhenReady);
2229 pw.println(" mSendGoToSleepFinishedNotificationWhenReady="
2230 + mSendGoToSleepFinishedNotificationWhenReady);
2231 pw.println(" mLastUserActivityTime=" + TimeUtils.formatUptime(mLastUserActivityTime));
2232 pw.println(" mLastUserActivityTimeNoChangeLights="
2233 + TimeUtils.formatUptime(mLastUserActivityTimeNoChangeLights));
2234 pw.println(" mDisplayReady=" + mDisplayReady);
2235 pw.println(" mHoldingWakeLockSuspendBlocker=" + mHoldingWakeLockSuspendBlocker);
Jeff Brown27f7a862012-12-12 15:43:31 -08002236 pw.println(" mHoldingDisplaySuspendBlocker=" + mHoldingDisplaySuspendBlocker);
Jeff Brown96307042012-07-27 15:51:34 -07002237
2238 pw.println();
2239 pw.println("Settings and Configuration:");
2240 pw.println(" mDreamsSupportedConfig=" + mDreamsSupportedConfig);
2241 pw.println(" mDreamsEnabledSetting=" + mDreamsEnabledSetting);
John Spurlock1a868b72012-08-22 09:56:51 -04002242 pw.println(" mDreamsActivateOnSleepSetting=" + mDreamsActivateOnSleepSetting);
Jeff Brownec6aa592012-10-17 20:30:25 -07002243 pw.println(" mDreamsActivateOnDockSetting=" + mDreamsActivateOnDockSetting);
Jeff Brown96307042012-07-27 15:51:34 -07002244 pw.println(" mScreenOffTimeoutSetting=" + mScreenOffTimeoutSetting);
2245 pw.println(" mMaximumScreenOffTimeoutFromDeviceAdmin="
2246 + mMaximumScreenOffTimeoutFromDeviceAdmin + " (enforced="
2247 + isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked() + ")");
2248 pw.println(" mStayOnWhilePluggedInSetting=" + mStayOnWhilePluggedInSetting);
2249 pw.println(" mScreenBrightnessSetting=" + mScreenBrightnessSetting);
Jeff Brown330560f2012-08-21 22:10:57 -07002250 pw.println(" mScreenAutoBrightnessAdjustmentSetting="
2251 + mScreenAutoBrightnessAdjustmentSetting);
Jeff Brown96307042012-07-27 15:51:34 -07002252 pw.println(" mScreenBrightnessModeSetting=" + mScreenBrightnessModeSetting);
2253 pw.println(" mScreenBrightnessOverrideFromWindowManager="
2254 + mScreenBrightnessOverrideFromWindowManager);
Jeff Brown1e3b98d2012-09-30 18:58:59 -07002255 pw.println(" mUserActivityTimeoutOverrideFromWindowManager="
2256 + mUserActivityTimeoutOverrideFromWindowManager);
Jeff Brown96307042012-07-27 15:51:34 -07002257 pw.println(" mTemporaryScreenBrightnessSettingOverride="
2258 + mTemporaryScreenBrightnessSettingOverride);
Jeff Brown330560f2012-08-21 22:10:57 -07002259 pw.println(" mTemporaryScreenAutoBrightnessAdjustmentSettingOverride="
2260 + mTemporaryScreenAutoBrightnessAdjustmentSettingOverride);
Jeff Brown96307042012-07-27 15:51:34 -07002261 pw.println(" mScreenBrightnessSettingMinimum=" + mScreenBrightnessSettingMinimum);
2262 pw.println(" mScreenBrightnessSettingMaximum=" + mScreenBrightnessSettingMaximum);
2263 pw.println(" mScreenBrightnessSettingDefault=" + mScreenBrightnessSettingDefault);
2264
Jeff Brownff532542012-10-02 21:18:04 -07002265 final int screenOffTimeout = getScreenOffTimeoutLocked();
2266 final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
2267 pw.println();
2268 pw.println("Screen off timeout: " + screenOffTimeout + " ms");
2269 pw.println("Screen dim duration: " + screenDimDuration + " ms");
2270
Jeff Brown96307042012-07-27 15:51:34 -07002271 pw.println();
2272 pw.println("Wake Locks: size=" + mWakeLocks.size());
2273 for (WakeLock wl : mWakeLocks) {
2274 pw.println(" " + wl);
Joe Onorato8274a0e2010-10-05 17:38:09 -04002275 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05002276
Jeff Brown96307042012-07-27 15:51:34 -07002277 pw.println();
2278 pw.println("Suspend Blockers: size=" + mSuspendBlockers.size());
2279 for (SuspendBlocker sb : mSuspendBlockers) {
2280 pw.println(" " + sb);
2281 }
2282
Jeff Brownc38c9be2012-10-04 13:16:19 -07002283 pw.println();
2284 pw.println("Screen On Blocker: " + mScreenOnBlocker);
2285
Jeff Brown9e316a12012-10-08 19:17:06 -07002286 pw.println();
2287 pw.println("Display Blanker: " + mDisplayBlanker);
2288
Jeff Brown96307042012-07-27 15:51:34 -07002289 dpc = mDisplayPowerController;
Jeff Brown3b971592013-01-09 18:46:37 -08002290 wcd = mWirelessChargerDetector;
Jeff Brown96307042012-07-27 15:51:34 -07002291 }
2292
2293 if (dpc != null) {
2294 dpc.dump(pw);
2295 }
Jeff Brown3b971592013-01-09 18:46:37 -08002296
2297 if (wcd != null) {
2298 wcd.dump(pw);
2299 }
Jeff Brown96307042012-07-27 15:51:34 -07002300 }
2301
2302 private SuspendBlocker createSuspendBlockerLocked(String name) {
2303 SuspendBlocker suspendBlocker = new SuspendBlockerImpl(name);
2304 mSuspendBlockers.add(suspendBlocker);
2305 return suspendBlocker;
2306 }
2307
2308 private static String wakefulnessToString(int wakefulness) {
2309 switch (wakefulness) {
2310 case WAKEFULNESS_ASLEEP:
2311 return "Asleep";
2312 case WAKEFULNESS_AWAKE:
2313 return "Awake";
2314 case WAKEFULNESS_DREAMING:
2315 return "Dreaming";
2316 case WAKEFULNESS_NAPPING:
2317 return "Napping";
2318 default:
2319 return Integer.toString(wakefulness);
2320 }
2321 }
2322
2323 private static WorkSource copyWorkSource(WorkSource workSource) {
2324 return workSource != null ? new WorkSource(workSource) : null;
2325 }
2326
2327 private final class BatteryReceiver extends BroadcastReceiver {
2328 @Override
2329 public void onReceive(Context context, Intent intent) {
2330 synchronized (mLock) {
2331 handleBatteryStateChangedLocked();
Mike Lockwoodee2b0942009-11-09 14:09:02 -05002332 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05002333 }
2334 }
2335
Jeff Brown96307042012-07-27 15:51:34 -07002336 private final class BootCompletedReceiver extends BroadcastReceiver {
2337 @Override
2338 public void onReceive(Context context, Intent intent) {
Jeff Brown20767b22012-10-09 18:57:07 -07002339 // This is our early signal that the system thinks it has finished booting.
2340 // However, the boot animation may still be running for a few more seconds
2341 // since it is ultimately in charge of when it terminates.
2342 // Defer transitioning into the boot completed state until the animation exits.
2343 // We do this so that the screen does not start to dim prematurely before
2344 // the user has actually had a chance to interact with the device.
2345 startWatchingForBootAnimationFinished();
Joe Onoratod28f7532010-11-06 12:56:53 -07002346 }
Jeff Brown96307042012-07-27 15:51:34 -07002347 }
2348
John Spurlockf4f6b4c2012-08-25 12:08:03 -04002349 private final class DreamReceiver extends BroadcastReceiver {
2350 @Override
2351 public void onReceive(Context context, Intent intent) {
2352 synchronized (mLock) {
Jeff Brown62c82e42012-09-26 01:30:41 -07002353 scheduleSandmanLocked();
John Spurlockf4f6b4c2012-08-25 12:08:03 -04002354 }
2355 }
2356 }
2357
Jeff Brownd4935962012-09-25 13:27:20 -07002358 private final class UserSwitchedReceiver extends BroadcastReceiver {
2359 @Override
2360 public void onReceive(Context context, Intent intent) {
2361 synchronized (mLock) {
2362 handleSettingsChangedLocked();
2363 }
2364 }
2365 }
2366
Jeff Brownec6aa592012-10-17 20:30:25 -07002367 private final class DockReceiver extends BroadcastReceiver {
2368 @Override
2369 public void onReceive(Context context, Intent intent) {
2370 synchronized (mLock) {
2371 int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
2372 Intent.EXTRA_DOCK_STATE_UNDOCKED);
2373 if (mDockState != dockState) {
2374 mDockState = dockState;
2375 mDirty |= DIRTY_DOCK_STATE;
2376 updatePowerStateLocked();
2377 }
2378 }
2379 }
2380 }
2381
Jeff Brown96307042012-07-27 15:51:34 -07002382 private final class SettingsObserver extends ContentObserver {
2383 public SettingsObserver(Handler handler) {
2384 super(handler);
2385 }
2386
2387 @Override
2388 public void onChange(boolean selfChange, Uri uri) {
2389 synchronized (mLock) {
2390 handleSettingsChangedLocked();
2391 }
2392 }
2393 }
2394
Jeff Brown96307042012-07-27 15:51:34 -07002395 /**
2396 * Handler for asynchronous operations performed by the power manager.
2397 */
2398 private final class PowerManagerHandler extends Handler {
2399 public PowerManagerHandler(Looper looper) {
Jeff Browna2910d02012-08-25 12:29:46 -07002400 super(looper, null, true /*async*/);
Jeff Brown96307042012-07-27 15:51:34 -07002401 }
2402
2403 @Override
2404 public void handleMessage(Message msg) {
2405 switch (msg.what) {
2406 case MSG_USER_ACTIVITY_TIMEOUT:
2407 handleUserActivityTimeout();
2408 break;
2409 case MSG_SANDMAN:
2410 handleSandman();
2411 break;
Jeff Brownc38c9be2012-10-04 13:16:19 -07002412 case MSG_SCREEN_ON_BLOCKER_RELEASED:
2413 handleScreenOnBlockerReleased();
2414 break;
Jeff Brown20767b22012-10-09 18:57:07 -07002415 case MSG_CHECK_IF_BOOT_ANIMATION_FINISHED:
2416 checkIfBootAnimationFinished();
2417 break;
Jeff Brown96307042012-07-27 15:51:34 -07002418 }
2419 }
2420 }
2421
2422 /**
2423 * Represents a wake lock that has been acquired by an application.
2424 */
2425 private final class WakeLock implements IBinder.DeathRecipient {
2426 public final IBinder mLock;
2427 public int mFlags;
2428 public String mTag;
2429 public WorkSource mWorkSource;
2430 public int mOwnerUid;
2431 public int mOwnerPid;
2432
2433 public WakeLock(IBinder lock, int flags, String tag, WorkSource workSource,
2434 int ownerUid, int ownerPid) {
2435 mLock = lock;
2436 mFlags = flags;
2437 mTag = tag;
2438 mWorkSource = copyWorkSource(workSource);
2439 mOwnerUid = ownerUid;
2440 mOwnerPid = ownerPid;
2441 }
2442
2443 @Override
2444 public void binderDied() {
2445 PowerManagerService.this.handleWakeLockDeath(this);
2446 }
2447
2448 public boolean hasSameProperties(int flags, String tag, WorkSource workSource,
2449 int ownerUid, int ownerPid) {
2450 return mFlags == flags
2451 && mTag.equals(tag)
2452 && hasSameWorkSource(workSource)
2453 && mOwnerUid == ownerUid
2454 && mOwnerPid == ownerPid;
2455 }
2456
2457 public void updateProperties(int flags, String tag, WorkSource workSource,
2458 int ownerUid, int ownerPid) {
2459 mFlags = flags;
2460 mTag = tag;
2461 updateWorkSource(workSource);
2462 mOwnerUid = ownerUid;
2463 mOwnerPid = ownerPid;
2464 }
2465
2466 public boolean hasSameWorkSource(WorkSource workSource) {
2467 return Objects.equal(mWorkSource, workSource);
2468 }
2469
2470 public void updateWorkSource(WorkSource workSource) {
2471 mWorkSource = copyWorkSource(workSource);
2472 }
2473
2474 @Override
2475 public String toString() {
2476 return getLockLevelString()
2477 + " '" + mTag + "'" + getLockFlagsString()
2478 + " (uid=" + mOwnerUid + ", pid=" + mOwnerPid + ", ws=" + mWorkSource + ")";
2479 }
2480
2481 private String getLockLevelString() {
2482 switch (mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
2483 case PowerManager.FULL_WAKE_LOCK:
2484 return "FULL_WAKE_LOCK ";
2485 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
2486 return "SCREEN_BRIGHT_WAKE_LOCK ";
2487 case PowerManager.SCREEN_DIM_WAKE_LOCK:
2488 return "SCREEN_DIM_WAKE_LOCK ";
2489 case PowerManager.PARTIAL_WAKE_LOCK:
2490 return "PARTIAL_WAKE_LOCK ";
2491 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
2492 return "PROXIMITY_SCREEN_OFF_WAKE_LOCK";
2493 default:
2494 return "??? ";
2495 }
2496 }
2497
2498 private String getLockFlagsString() {
2499 String result = "";
2500 if ((mFlags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {
2501 result += " ACQUIRE_CAUSES_WAKEUP";
2502 }
2503 if ((mFlags & PowerManager.ON_AFTER_RELEASE) != 0) {
2504 result += " ON_AFTER_RELEASE";
2505 }
2506 return result;
2507 }
2508 }
2509
2510 private final class SuspendBlockerImpl implements SuspendBlocker {
2511 private final String mName;
2512 private int mReferenceCount;
2513
2514 public SuspendBlockerImpl(String name) {
2515 mName = name;
2516 }
2517
2518 @Override
2519 protected void finalize() throws Throwable {
Mike Lockwood809ad0f2009-10-26 22:10:33 -04002520 try {
Jeff Brown96307042012-07-27 15:51:34 -07002521 if (mReferenceCount != 0) {
2522 Log.wtf(TAG, "Suspend blocker \"" + mName
2523 + "\" was finalized without being released!");
2524 mReferenceCount = 0;
2525 nativeReleaseSuspendBlocker(mName);
Mike Lockwood809ad0f2009-10-26 22:10:33 -04002526 }
2527 } finally {
Jeff Brown96307042012-07-27 15:51:34 -07002528 super.finalize();
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002529 }
2530 }
2531
Craig Mautner75fc9de2012-06-18 16:53:27 -07002532 @Override
Jeff Brown96307042012-07-27 15:51:34 -07002533 public void acquire() {
2534 synchronized (this) {
2535 mReferenceCount += 1;
2536 if (mReferenceCount == 1) {
Jeff Brown27f7a862012-12-12 15:43:31 -08002537 if (DEBUG_SPEW) {
2538 Slog.d(TAG, "Acquiring suspend blocker \"" + mName + "\".");
2539 }
Jeff Brown96307042012-07-27 15:51:34 -07002540 nativeAcquireSuspendBlocker(mName);
Craig Mautner37933682012-06-06 14:13:39 -07002541 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002542 }
2543 }
2544
Craig Mautner75fc9de2012-06-18 16:53:27 -07002545 @Override
Jeff Brown96307042012-07-27 15:51:34 -07002546 public void release() {
2547 synchronized (this) {
2548 mReferenceCount -= 1;
2549 if (mReferenceCount == 0) {
Jeff Brown27f7a862012-12-12 15:43:31 -08002550 if (DEBUG_SPEW) {
2551 Slog.d(TAG, "Releasing suspend blocker \"" + mName + "\".");
2552 }
Jeff Brown96307042012-07-27 15:51:34 -07002553 nativeReleaseSuspendBlocker(mName);
2554 } else if (mReferenceCount < 0) {
2555 Log.wtf(TAG, "Suspend blocker \"" + mName
2556 + "\" was released without being acquired!", new Throwable());
2557 mReferenceCount = 0;
2558 }
2559 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002560 }
Jeff Brown96307042012-07-27 15:51:34 -07002561
2562 @Override
2563 public String toString() {
2564 synchronized (this) {
2565 return mName + ": ref count=" + mReferenceCount;
2566 }
2567 }
2568 }
Jeff Brownc38c9be2012-10-04 13:16:19 -07002569
2570 private final class ScreenOnBlockerImpl implements ScreenOnBlocker {
2571 private int mNestCount;
2572
2573 public boolean isHeld() {
2574 synchronized (this) {
2575 return mNestCount != 0;
2576 }
2577 }
2578
2579 @Override
2580 public void acquire() {
2581 synchronized (this) {
2582 mNestCount += 1;
2583 if (DEBUG) {
2584 Slog.d(TAG, "Screen on blocked: mNestCount=" + mNestCount);
2585 }
2586 }
2587 }
2588
2589 @Override
2590 public void release() {
2591 synchronized (this) {
2592 mNestCount -= 1;
2593 if (mNestCount < 0) {
2594 Log.wtf(TAG, "Screen on blocker was released without being acquired!",
2595 new Throwable());
2596 mNestCount = 0;
2597 }
2598 if (mNestCount == 0) {
2599 mHandler.sendEmptyMessage(MSG_SCREEN_ON_BLOCKER_RELEASED);
2600 }
2601 if (DEBUG) {
2602 Slog.d(TAG, "Screen on unblocked: mNestCount=" + mNestCount);
2603 }
2604 }
2605 }
2606
2607 @Override
2608 public String toString() {
2609 synchronized (this) {
2610 return "held=" + (mNestCount != 0) + ", mNestCount=" + mNestCount;
2611 }
2612 }
Jeff Brown9e316a12012-10-08 19:17:06 -07002613 }
2614
2615 private final class DisplayBlankerImpl implements DisplayBlanker {
2616 private boolean mBlanked;
2617
2618 @Override
2619 public void blankAllDisplays() {
2620 synchronized (this) {
2621 mBlanked = true;
2622 mDisplayManagerService.blankAllDisplaysFromPowerManager();
2623 nativeSetInteractive(false);
2624 nativeSetAutoSuspend(true);
2625 }
2626 }
2627
2628 @Override
2629 public void unblankAllDisplays() {
2630 synchronized (this) {
2631 nativeSetAutoSuspend(false);
2632 nativeSetInteractive(true);
2633 mDisplayManagerService.unblankAllDisplaysFromPowerManager();
2634 mBlanked = false;
2635 }
2636 }
2637
2638 @Override
2639 public String toString() {
2640 synchronized (this) {
2641 return "blanked=" + mBlanked;
2642 }
2643 }
2644 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002645}