blob: 38e08ae059aa081d0e96f301f09515049c35e86b [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
17package com.android.server;
18
19import com.android.internal.app.IBatteryStats;
20import com.android.server.am.BatteryStatsService;
Jeff Brown7304c342012-05-11 18:42:42 -070021import com.android.server.pm.ShutdownThread;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022
23import android.app.ActivityManagerNative;
24import android.app.IActivityManager;
25import android.content.BroadcastReceiver;
26import android.content.ContentQueryMap;
27import android.content.ContentResolver;
Amith Yamasani8b619832010-09-22 16:11:59 -070028import android.content.ContentValues;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029import android.content.Context;
30import android.content.Intent;
31import android.content.IntentFilter;
32import android.content.pm.PackageManager;
Mike Lockwoodd7786b42009-10-15 17:09:16 -070033import android.content.res.Resources;
Doug Zongker43866e02010-01-07 12:09:54 -080034import android.database.ContentObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035import android.database.Cursor;
Mike Lockwoodbc706a02009-07-27 13:50:57 -070036import android.hardware.Sensor;
37import android.hardware.SensorEvent;
38import android.hardware.SensorEventListener;
39import android.hardware.SensorManager;
Jeff Brown25157e42012-04-16 12:13:05 -070040import android.hardware.SystemSensorManager;
Amith Yamasani8b619832010-09-22 16:11:59 -070041import android.os.BatteryManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042import android.os.BatteryStats;
43import android.os.Binder;
44import android.os.Handler;
45import android.os.HandlerThread;
46import android.os.IBinder;
47import android.os.IPowerManager;
48import android.os.LocalPowerManager;
Jim Miller92e66dd2012-02-21 18:57:12 -080049import android.os.Message;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050import android.os.PowerManager;
51import android.os.Process;
52import android.os.RemoteException;
53import android.os.SystemClock;
Mike Lockwood3a74bd32011-08-12 13:55:22 -070054import android.os.SystemProperties;
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;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060import android.view.WindowManagerPolicy;
Jim Miller92e66dd2012-02-21 18:57:12 -080061import static android.view.WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062import static android.provider.Settings.System.DIM_SCREEN;
63import static android.provider.Settings.System.SCREEN_BRIGHTNESS;
Dan Murphy951764b2009-08-27 14:59:03 -050064import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -080065import static android.provider.Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ;
Mike Lockwooddc3494e2009-10-14 21:17:09 -070066import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
68import static android.provider.Settings.System.STAY_ON_WHILE_PLUGGED_IN;
Joe Onorato609695d2010-10-14 14:57:49 -070069import static android.provider.Settings.System.WINDOW_ANIMATION_SCALE;
70import static android.provider.Settings.System.TRANSITION_ANIMATION_SCALE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071
72import java.io.FileDescriptor;
Jeff Brown7304c342012-05-11 18:42:42 -070073import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074import java.io.PrintWriter;
75import java.util.ArrayList;
76import java.util.HashMap;
77import java.util.Observable;
78import java.util.Observer;
79
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080080public class PowerManagerService extends IPowerManager.Stub
Mike Lockwood8738e0c2009-10-04 08:44:47 -040081 implements LocalPowerManager, Watchdog.Monitor {
Jim Miller92e66dd2012-02-21 18:57:12 -080082 private static final int NOMINAL_FRAME_TIME_MS = 1000/60;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083
84 private static final String TAG = "PowerManagerService";
85 static final String PARTIAL_NAME = "PowerManagerService";
86
Jeff Brown7304c342012-05-11 18:42:42 -070087 // Wake lock that ensures that the CPU is running. The screen might not be on.
88 private static final int PARTIAL_WAKE_LOCK_ID = 1;
89
90 // Wake lock that ensures that the screen is on.
91 private static final int FULL_WAKE_LOCK_ID = 2;
92
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -070093 static final boolean DEBUG_SCREEN_ON = false;
94
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095 private static final boolean LOG_PARTIAL_WL = false;
96
97 // Indicates whether touch-down cycles should be logged as part of the
98 // LOG_POWER_SCREEN_STATE log events
99 private static final boolean LOG_TOUCH_DOWNS = true;
100
101 private static final int LOCK_MASK = PowerManager.PARTIAL_WAKE_LOCK
102 | PowerManager.SCREEN_DIM_WAKE_LOCK
103 | PowerManager.SCREEN_BRIGHT_WAKE_LOCK
Mike Lockwoodbc706a02009-07-27 13:50:57 -0700104 | PowerManager.FULL_WAKE_LOCK
105 | PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106
107 // time since last state: time since last event:
Doug Zongker43866e02010-01-07 12:09:54 -0800108 // The short keylight delay comes from secure settings; this is the default.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109 private static final int SHORT_KEYLIGHT_DELAY_DEFAULT = 6000; // t+6 sec
110 private static final int MEDIUM_KEYLIGHT_DELAY = 15000; // t+15 sec
111 private static final int LONG_KEYLIGHT_DELAY = 6000; // t+6 sec
112 private static final int LONG_DIM_TIME = 7000; // t+N-5 sec
113
Mathias Agopian47f1fe52011-11-08 17:18:41 -0800114 // How long to wait to debounce light sensor changes in milliseconds
Mike Lockwood9b8136922009-11-06 15:53:59 -0500115 private static final int LIGHT_SENSOR_DELAY = 2000;
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700116
Mathias Agopian47f1fe52011-11-08 17:18:41 -0800117 // light sensor events rate in microseconds
118 private static final int LIGHT_SENSOR_RATE = 1000000;
119
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800120 // Expansion of range of light values when applying scale from light
121 // sensor brightness setting, in the [0..255] brightness range.
122 private static final int LIGHT_SENSOR_RANGE_EXPANSION = 20;
123
124 // Scaling factor of the light sensor brightness setting when applying
125 // it to the final brightness.
126 private static final int LIGHT_SENSOR_OFFSET_SCALE = 8;
127
Mathias Agopian47f1fe52011-11-08 17:18:41 -0800128 // For debouncing the proximity sensor in milliseconds
Mike Lockwood20f87d72009-11-05 16:08:51 -0500129 private static final int PROXIMITY_SENSOR_DELAY = 1000;
130
Mike Lockwoodd20ea362009-09-15 00:13:38 -0400131 // trigger proximity if distance is less than 5 cm
132 private static final float PROXIMITY_THRESHOLD = 5.0f;
133
Doug Zongker43866e02010-01-07 12:09:54 -0800134 // Cached secure settings; see updateSettingsValues()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135 private int mShortKeylightDelay = SHORT_KEYLIGHT_DELAY_DEFAULT;
136
Amith Yamasani8b619832010-09-22 16:11:59 -0700137 // Default timeout for screen off, if not found in settings database = 15 seconds.
138 private static final int DEFAULT_SCREEN_OFF_TIMEOUT = 15000;
139
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800140 // Screen brightness should always have a value, but just in case...
141 private static final int DEFAULT_SCREEN_BRIGHTNESS = 192;
142
Jeff Brown7304c342012-05-11 18:42:42 -0700143 // Threshold for BRIGHTNESS_LOW_BATTERY (percentage)
144 // Screen will stay dim if battery level is <= LOW_BATTERY_THRESHOLD
145 private static final int LOW_BATTERY_THRESHOLD = 10;
146
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 // flags for setPowerState
Jim Miller92e66dd2012-02-21 18:57:12 -0800148 private static final int ALL_LIGHTS_OFF = 0x00000000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 private static final int SCREEN_ON_BIT = 0x00000001;
150 private static final int SCREEN_BRIGHT_BIT = 0x00000002;
151 private static final int BUTTON_BRIGHT_BIT = 0x00000004;
152 private static final int KEYBOARD_BRIGHT_BIT = 0x00000008;
153 private static final int BATTERY_LOW_BIT = 0x00000010;
154
155 // values for setPowerState
156
157 // SCREEN_OFF == everything off
158 private static final int SCREEN_OFF = 0x00000000;
159
160 // SCREEN_DIM == screen on, screen backlight dim
161 private static final int SCREEN_DIM = SCREEN_ON_BIT;
162
163 // SCREEN_BRIGHT == screen on, screen backlight bright
164 private static final int SCREEN_BRIGHT = SCREEN_ON_BIT | SCREEN_BRIGHT_BIT;
165
166 // SCREEN_BUTTON_BRIGHT == screen on, screen and button backlights bright
167 private static final int SCREEN_BUTTON_BRIGHT = SCREEN_BRIGHT | BUTTON_BRIGHT_BIT;
168
169 // SCREEN_BUTTON_BRIGHT == screen on, screen, button and keyboard backlights bright
170 private static final int ALL_BRIGHT = SCREEN_BUTTON_BRIGHT | KEYBOARD_BRIGHT_BIT;
171
172 // used for noChangeLights in setPowerState()
173 private static final int LIGHTS_MASK = SCREEN_BRIGHT_BIT | BUTTON_BRIGHT_BIT | KEYBOARD_BRIGHT_BIT;
174
Jim Miller46f31c32012-03-01 14:36:07 -0800175 // animate screen lights in PowerManager (as opposed to SurfaceFlinger)
Joe Onoratob08a1af2010-10-11 19:28:58 -0700176 boolean mAnimateScreenLights = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800177
Jim Miller92e66dd2012-02-21 18:57:12 -0800178 static final int ANIM_STEPS = 60; // nominal # of frames at 60Hz
Mike Lockwooddd9668e2009-10-27 15:47:02 -0400179 // Slower animation for autobrightness changes
Jim Miller92e66dd2012-02-21 18:57:12 -0800180 static final int AUTOBRIGHTNESS_ANIM_STEPS = 2 * ANIM_STEPS;
Craig Mautner196943f2012-05-15 08:10:35 -0700181 // Even slower animation for autodimness changes
182 static final int AUTODIMNESS_ANIM_STEPS = 15 * ANIM_STEPS;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800183 // Number of steps when performing a more immediate brightness change.
184 static final int IMMEDIATE_ANIM_STEPS = 4;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800185
186 // These magic numbers are the initial state of the LEDs at boot. Ideally
187 // we should read them from the driver, but our current hardware returns 0
188 // for the initial value. Oops!
189 static final int INITIAL_SCREEN_BRIGHTNESS = 255;
Jeff Brown7304c342012-05-11 18:42:42 -0700190 static final int INITIAL_BUTTON_BRIGHTNESS = PowerManager.BRIGHTNESS_OFF;
191 static final int INITIAL_KEYBOARD_BRIGHTNESS = PowerManager.BRIGHTNESS_OFF;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800192
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800193 private final int MY_UID;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700194 private final int MY_PID;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800195
196 private boolean mDoneBooting = false;
Mike Lockwood2d7bb812009-11-15 18:12:22 -0500197 private boolean mBootCompleted = false;
Mike Lockwood3a74bd32011-08-12 13:55:22 -0700198 private boolean mHeadless = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800199 private int mStayOnConditions = 0;
Mike Lockwoodca44df82010-02-25 13:48:49 -0500200 private final int[] mBroadcastQueue = new int[] { -1, -1, -1 };
201 private final int[] mBroadcastWhy = new int[3];
Dianne Hackborn38e29a62011-09-18 14:43:08 -0700202 private boolean mPreparingForScreenOn = false;
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700203 private boolean mSkippedScreenOn = false;
204 private boolean mInitialized = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800205 private int mPartialCount = 0;
206 private int mPowerState;
Mike Lockwood435eb642009-12-03 08:40:18 -0500207 // mScreenOffReason can be WindowManagerPolicy.OFF_BECAUSE_OF_USER,
208 // WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT or WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR
209 private int mScreenOffReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800210 private int mUserState;
211 private boolean mKeyboardVisible = false;
212 private boolean mUserActivityAllowed = true;
Mike Lockwoodee2b0942009-11-09 14:09:02 -0500213 private int mProximityWakeLockCount = 0;
214 private boolean mProximitySensorEnabled = false;
Mike Lockwood36fc3022009-08-25 16:49:06 -0700215 private boolean mProximitySensorActive = false;
Mike Lockwood20f87d72009-11-05 16:08:51 -0500216 private int mProximityPendingValue = -1; // -1 == nothing, 0 == inactive, 1 == active
217 private long mLastProximityEventTime;
Dianne Hackborndf83afa2010-01-20 13:37:26 -0800218 private int mScreenOffTimeoutSetting;
219 private int mMaximumScreenOffTimeout = Integer.MAX_VALUE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800220 private int mKeylightDelay;
221 private int mDimDelay;
222 private int mScreenOffDelay;
223 private int mWakeLockState;
224 private long mLastEventTime = 0;
225 private long mScreenOffTime;
226 private volatile WindowManagerPolicy mPolicy;
227 private final LockList mLocks = new LockList();
228 private Intent mScreenOffIntent;
229 private Intent mScreenOnIntent;
Mike Lockwood3a322132009-11-24 00:30:52 -0500230 private LightsService mLightsService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800231 private Context mContext;
Mike Lockwood3cb67a32009-11-27 14:25:58 -0500232 private LightsService.Light mLcdLight;
233 private LightsService.Light mButtonLight;
234 private LightsService.Light mKeyboardLight;
235 private LightsService.Light mAttentionLight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800236 private UnsynchronizedWakeLock mBroadcastWakeLock;
237 private UnsynchronizedWakeLock mStayOnWhilePluggedInScreenDimLock;
238 private UnsynchronizedWakeLock mStayOnWhilePluggedInPartialLock;
239 private UnsynchronizedWakeLock mPreventScreenOnPartialLock;
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -0500240 private UnsynchronizedWakeLock mProximityPartialLock;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800241 private HandlerThread mHandlerThread;
Joe Onoratob08a1af2010-10-11 19:28:58 -0700242 private Handler mScreenOffHandler;
Jim Miller92e66dd2012-02-21 18:57:12 -0800243 private Handler mScreenBrightnessHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800244 private Handler mHandler;
Mike Lockwoodca44df82010-02-25 13:48:49 -0500245 private final TimeoutTask mTimeoutTask = new TimeoutTask();
Jim Miller92e66dd2012-02-21 18:57:12 -0800246 private ScreenBrightnessAnimator mScreenBrightnessAnimator;
Joe Onorato128e7292009-03-24 18:41:31 -0700247 private boolean mStillNeedSleepNotification;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800248 private boolean mIsPowered = false;
249 private IActivityManager mActivityService;
250 private IBatteryStats mBatteryStats;
251 private BatteryService mBatteryService;
Mike Lockwoodbc706a02009-07-27 13:50:57 -0700252 private SensorManager mSensorManager;
253 private Sensor mProximitySensor;
Mike Lockwood8738e0c2009-10-04 08:44:47 -0400254 private Sensor mLightSensor;
255 private boolean mLightSensorEnabled;
256 private float mLightSensorValue = -1;
Joe Onorato8274a0e2010-10-05 17:38:09 -0400257 private boolean mProxIgnoredBecauseScreenTurnedOff = false;
Mike Lockwoodb2865412010-02-02 22:40:33 -0500258 private int mHighestLightSensorValue = -1;
Jim Rodovichd102fea2010-09-02 12:30:49 -0500259 private boolean mLightSensorPendingDecrease = false;
260 private boolean mLightSensorPendingIncrease = false;
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700261 private float mLightSensorPendingValue = -1;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800262 private float mLightSensorAdjustSetting = 0;
Mike Lockwoodfb73f792009-11-20 11:31:18 -0500263 private int mLightSensorScreenBrightness = -1;
264 private int mLightSensorButtonBrightness = -1;
265 private int mLightSensorKeyboardBrightness = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800266 private boolean mDimScreen = true;
Mike Lockwoodb2865412010-02-02 22:40:33 -0500267 private boolean mIsDocked = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800268 private long mNextTimeout;
269 private volatile int mPokey = 0;
270 private volatile boolean mPokeAwakeOnSet = false;
271 private volatile boolean mInitComplete = false;
Mike Lockwoodca44df82010-02-25 13:48:49 -0500272 private final HashMap<IBinder,PokeLock> mPokeLocks = new HashMap<IBinder,PokeLock>();
Mike Lockwood20ee6f22009-11-07 20:33:47 -0500273 // mLastScreenOnTime is the time the screen was last turned on
274 private long mLastScreenOnTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800275 private boolean mPreventScreenOn;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800276 private int mScreenBrightnessSetting = DEFAULT_SCREEN_BRIGHTNESS;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277 private int mScreenBrightnessOverride = -1;
Mike Lockwoodfb73f792009-11-20 11:31:18 -0500278 private int mButtonBrightnessOverride = -1;
Mike Lockwoodeb6456b2011-09-13 15:24:02 -0400279 private int mScreenBrightnessDim;
Mike Lockwoodaa66ea82009-10-31 16:31:27 -0400280 private boolean mUseSoftwareAutoBrightness;
Mike Lockwooddc3494e2009-10-14 21:17:09 -0700281 private boolean mAutoBrightessEnabled;
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700282 private int[] mAutoBrightnessLevels;
283 private int[] mLcdBacklightValues;
284 private int[] mButtonBacklightValues;
285 private int[] mKeyboardBacklightValues;
Mike Lockwood20ee6f22009-11-07 20:33:47 -0500286 private int mLightSensorWarmupTime;
Joe Onorato6d747652010-10-11 15:15:31 -0700287 boolean mUnplugTurnsOnScreen;
Joe Onorato4b9f62d2010-10-11 13:41:35 -0700288 private int mWarningSpewThrottleCount;
289 private long mWarningSpewThrottleTime;
Joe Onorato609695d2010-10-14 14:57:49 -0700290 private int mAnimationSetting = ANIM_SETTING_OFF;
Jim Miller92e66dd2012-02-21 18:57:12 -0800291 private float mWindowScaleAnimation;
Joe Onorato609695d2010-10-14 14:57:49 -0700292
293 // Must match with the ISurfaceComposer constants in C++.
294 private static final int ANIM_SETTING_ON = 0x01;
295 private static final int ANIM_SETTING_OFF = 0x10;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800296
297 // Used when logging number and duration of touch-down cycles
298 private long mTotalTouchDownTime;
299 private long mLastTouchDown;
300 private int mTouchCycles;
301
302 // could be either static or controllable at runtime
303 private static final boolean mSpew = false;
Joe Onorato8274a0e2010-10-05 17:38:09 -0400304 private static final boolean mDebugProximitySensor = (false || mSpew);
Mike Lockwoodae92eb32011-10-25 10:11:46 -0400305 private static final boolean mDebugLightSensor = (false || mSpew);
Jim Miller92e66dd2012-02-21 18:57:12 -0800306 private static final boolean mDebugLightAnimation = (false || mSpew);
307
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700308 private native void nativeInit();
309 private native void nativeSetPowerState(boolean screenOn, boolean screenBright);
Joe Onorato609695d2010-10-14 14:57:49 -0700310 private native void nativeStartSurfaceFlingerAnimation(int mode);
Jeff Brown7304c342012-05-11 18:42:42 -0700311 private static native void nativeAcquireWakeLock(int lock, String id);
312 private static native void nativeReleaseWakeLock(String id);
313 private static native int nativeSetScreenState(boolean on);
314 private static native void nativeShutdown();
315 private static native void nativeReboot(String reason) throws IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800316
317 /*
318 static PrintStream mLog;
319 static {
320 try {
321 mLog = new PrintStream("/data/power.log");
322 }
323 catch (FileNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800324 android.util.Slog.e(TAG, "Life is hard", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800325 }
326 }
327 static class Log {
328 static void d(String tag, String s) {
329 mLog.println(s);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800330 android.util.Slog.d(tag, s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800331 }
332 static void i(String tag, String s) {
333 mLog.println(s);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800334 android.util.Slog.i(tag, s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800335 }
336 static void w(String tag, String s) {
337 mLog.println(s);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800338 android.util.Slog.w(tag, s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800339 }
340 static void e(String tag, String s) {
341 mLog.println(s);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800342 android.util.Slog.e(tag, s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800343 }
344 }
345 */
346
347 /**
348 * This class works around a deadlock between the lock in PowerManager.WakeLock
349 * and our synchronizing on mLocks. PowerManager.WakeLock synchronizes on its
350 * mToken object so it can be accessed from any thread, but it calls into here
351 * with its lock held. This class is essentially a reimplementation of
352 * PowerManager.WakeLock, but without that extra synchronized block, because we'll
353 * only call it with our own locks held.
354 */
355 private class UnsynchronizedWakeLock {
356 int mFlags;
357 String mTag;
358 IBinder mToken;
359 int mCount = 0;
360 boolean mRefCounted;
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -0500361 boolean mHeld;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800362
363 UnsynchronizedWakeLock(int flags, String tag, boolean refCounted) {
364 mFlags = flags;
365 mTag = tag;
366 mToken = new Binder();
367 mRefCounted = refCounted;
368 }
369
370 public void acquire() {
371 if (!mRefCounted || mCount++ == 0) {
372 long ident = Binder.clearCallingIdentity();
373 try {
374 PowerManagerService.this.acquireWakeLockLocked(mFlags, mToken,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700375 MY_UID, MY_PID, mTag, null);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -0500376 mHeld = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800377 } finally {
378 Binder.restoreCallingIdentity(ident);
379 }
380 }
381 }
382
383 public void release() {
384 if (!mRefCounted || --mCount == 0) {
Mike Lockwood0e39ea82009-11-18 15:37:10 -0500385 PowerManagerService.this.releaseWakeLockLocked(mToken, 0, false);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -0500386 mHeld = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800387 }
388 if (mCount < 0) {
389 throw new RuntimeException("WakeLock under-locked " + mTag);
390 }
391 }
392
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -0500393 public boolean isHeld()
394 {
395 return mHeld;
396 }
397
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 public String toString() {
399 return "UnsynchronizedWakeLock(mFlags=0x" + Integer.toHexString(mFlags)
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -0500400 + " mCount=" + mCount + " mHeld=" + mHeld + ")";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800401 }
402 }
403
404 private final class BatteryReceiver extends BroadcastReceiver {
405 @Override
406 public void onReceive(Context context, Intent intent) {
407 synchronized (mLocks) {
408 boolean wasPowered = mIsPowered;
409 mIsPowered = mBatteryService.isPowered();
410
411 if (mIsPowered != wasPowered) {
412 // update mStayOnWhilePluggedIn wake lock
413 updateWakeLockLocked();
414
415 // treat plugging and unplugging the devices as a user activity.
416 // users find it disconcerting when they unplug the device
417 // and it shuts off right away.
Mike Lockwood84a89342010-03-01 21:28:58 -0500418 // to avoid turning on the screen when unplugging, we only trigger
419 // user activity when screen was already on.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800420 // temporarily set mUserActivityAllowed to true so this will work
421 // even when the keyguard is on.
Joe Onorato6d747652010-10-11 15:15:31 -0700422 // However, you can also set config_unplugTurnsOnScreen to have it
423 // turn on. Some devices want this because they don't have a
424 // charging LED.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800425 synchronized (mLocks) {
Joe Onorato6d747652010-10-11 15:15:31 -0700426 if (!wasPowered || (mPowerState & SCREEN_ON_BIT) != 0 ||
427 mUnplugTurnsOnScreen) {
Mike Lockwood84a89342010-03-01 21:28:58 -0500428 forceUserActivityLocked();
429 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800430 }
431 }
432 }
433 }
434 }
435
Mike Lockwood2d7bb812009-11-15 18:12:22 -0500436 private final class BootCompletedReceiver extends BroadcastReceiver {
437 @Override
438 public void onReceive(Context context, Intent intent) {
439 bootCompleted();
440 }
441 }
442
Mike Lockwoodb2865412010-02-02 22:40:33 -0500443 private final class DockReceiver extends BroadcastReceiver {
444 @Override
445 public void onReceive(Context context, Intent intent) {
446 int state = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
447 Intent.EXTRA_DOCK_STATE_UNDOCKED);
448 dockStateChanged(state);
449 }
450 }
451
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800452 /**
453 * Set the setting that determines whether the device stays on when plugged in.
454 * The argument is a bit string, with each bit specifying a power source that,
455 * when the device is connected to that source, causes the device to stay on.
456 * See {@link android.os.BatteryManager} for the list of power sources that
457 * can be specified. Current values include {@link android.os.BatteryManager#BATTERY_PLUGGED_AC}
458 * and {@link android.os.BatteryManager#BATTERY_PLUGGED_USB}
459 * @param val an {@code int} containing the bits that specify which power sources
460 * should cause the device to stay on.
461 */
462 public void setStayOnSetting(int val) {
463 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS, null);
464 Settings.System.putInt(mContext.getContentResolver(),
465 Settings.System.STAY_ON_WHILE_PLUGGED_IN, val);
466 }
467
Dianne Hackborndf83afa2010-01-20 13:37:26 -0800468 public void setMaximumScreenOffTimeount(int timeMs) {
469 mContext.enforceCallingOrSelfPermission(
470 android.Manifest.permission.WRITE_SECURE_SETTINGS, null);
471 synchronized (mLocks) {
472 mMaximumScreenOffTimeout = timeMs;
473 // recalculate everything
474 setScreenOffTimeoutsLocked();
475 }
476 }
477
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800478 private class SettingsObserver implements Observer {
Amith Yamasani8b619832010-09-22 16:11:59 -0700479 private int getInt(String name, int defValue) {
480 ContentValues values = mSettings.getValues(name);
481 Integer iVal = values != null ? values.getAsInteger(Settings.System.VALUE) : null;
482 return iVal != null ? iVal : defValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800483 }
484
Joe Onorato609695d2010-10-14 14:57:49 -0700485 private float getFloat(String name, float defValue) {
486 ContentValues values = mSettings.getValues(name);
487 Float fVal = values != null ? values.getAsFloat(Settings.System.VALUE) : null;
488 return fVal != null ? fVal : defValue;
489 }
490
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800491 public void update(Observable o, Object arg) {
492 synchronized (mLocks) {
Amith Yamasani8b619832010-09-22 16:11:59 -0700493 // STAY_ON_WHILE_PLUGGED_IN, default to when plugged into AC
494 mStayOnConditions = getInt(STAY_ON_WHILE_PLUGGED_IN,
495 BatteryManager.BATTERY_PLUGGED_AC);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800496 updateWakeLockLocked();
497
Amith Yamasani8b619832010-09-22 16:11:59 -0700498 // SCREEN_OFF_TIMEOUT, default to 15 seconds
499 mScreenOffTimeoutSetting = getInt(SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800500
Joe Onorato609695d2010-10-14 14:57:49 -0700501 // DIM_SCREEN
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800502 //mDimScreen = getInt(DIM_SCREEN) != 0;
503
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800504 mScreenBrightnessSetting = getInt(SCREEN_BRIGHTNESS, DEFAULT_SCREEN_BRIGHTNESS);
Dianne Hackborn518a3d82012-05-09 16:30:49 -0700505 mLightSensorAdjustSetting = 0; //getFloat(SCREEN_AUTO_BRIGHTNESS_ADJ, 0);
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800506
Amith Yamasani8b619832010-09-22 16:11:59 -0700507 // SCREEN_BRIGHTNESS_MODE, default to manual
508 setScreenBrightnessMode(getInt(SCREEN_BRIGHTNESS_MODE,
509 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL));
Mike Lockwooddc3494e2009-10-14 21:17:09 -0700510
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800511 // recalculate everything
512 setScreenOffTimeoutsLocked();
Joe Onorato609695d2010-10-14 14:57:49 -0700513
Jim Miller92e66dd2012-02-21 18:57:12 -0800514 mWindowScaleAnimation = getFloat(WINDOW_ANIMATION_SCALE, 1.0f);
Joe Onorato609695d2010-10-14 14:57:49 -0700515 final float transitionScale = getFloat(TRANSITION_ANIMATION_SCALE, 1.0f);
516 mAnimationSetting = 0;
Jim Miller92e66dd2012-02-21 18:57:12 -0800517 if (mWindowScaleAnimation > 0.5f) {
Joe Onorato609695d2010-10-14 14:57:49 -0700518 mAnimationSetting |= ANIM_SETTING_OFF;
519 }
520 if (transitionScale > 0.5f) {
521 // Uncomment this if you want the screen-on animation.
522 // mAnimationSetting |= ANIM_SETTING_ON;
523 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800524 }
525 }
526 }
527
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700528 PowerManagerService() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800529 // Hack to get our uid... should have a func for this.
530 long token = Binder.clearCallingIdentity();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700531 MY_UID = Process.myUid();
532 MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800533 Binder.restoreCallingIdentity(token);
534
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800535 // assume nothing is on yet
536 mUserState = mPowerState = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800537
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800538 // Add ourself to the Watchdog monitors.
539 Watchdog.getInstance().addMonitor(this);
Jeff Brown7304c342012-05-11 18:42:42 -0700540
541 nativeInit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800542 }
543
544 private ContentQueryMap mSettings;
545
Mike Lockwood3a322132009-11-24 00:30:52 -0500546 void init(Context context, LightsService lights, IActivityManager activity,
The Android Open Source Project10592532009-03-18 17:39:46 -0700547 BatteryService battery) {
Mike Lockwood3a322132009-11-24 00:30:52 -0500548 mLightsService = lights;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800549 mContext = context;
550 mActivityService = activity;
551 mBatteryStats = BatteryStatsService.getService();
552 mBatteryService = battery;
553
Mike Lockwood3cb67a32009-11-27 14:25:58 -0500554 mLcdLight = lights.getLight(LightsService.LIGHT_ID_BACKLIGHT);
555 mButtonLight = lights.getLight(LightsService.LIGHT_ID_BUTTONS);
556 mKeyboardLight = lights.getLight(LightsService.LIGHT_ID_KEYBOARD);
557 mAttentionLight = lights.getLight(LightsService.LIGHT_ID_ATTENTION);
Mike Lockwood3a74bd32011-08-12 13:55:22 -0700558 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
Mike Lockwood3cb67a32009-11-27 14:25:58 -0500559
Joe Onoratob08a1af2010-10-11 19:28:58 -0700560 mInitComplete = false;
Jim Miller92e66dd2012-02-21 18:57:12 -0800561 mScreenBrightnessAnimator = new ScreenBrightnessAnimator("mScreenBrightnessUpdaterThread",
562 Process.THREAD_PRIORITY_DISPLAY);
563 mScreenBrightnessAnimator.start();
Joe Onoratob08a1af2010-10-11 19:28:58 -0700564
Jim Miller92e66dd2012-02-21 18:57:12 -0800565 synchronized (mScreenBrightnessAnimator) {
Joe Onoratob08a1af2010-10-11 19:28:58 -0700566 while (!mInitComplete) {
567 try {
Jim Miller92e66dd2012-02-21 18:57:12 -0800568 mScreenBrightnessAnimator.wait();
Joe Onoratob08a1af2010-10-11 19:28:58 -0700569 } catch (InterruptedException e) {
570 // Ignore
571 }
572 }
573 }
Jim Miller92e66dd2012-02-21 18:57:12 -0800574
Joe Onoratob08a1af2010-10-11 19:28:58 -0700575 mInitComplete = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800576 mHandlerThread = new HandlerThread("PowerManagerService") {
577 @Override
578 protected void onLooperPrepared() {
579 super.onLooperPrepared();
580 initInThread();
581 }
582 };
583 mHandlerThread.start();
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800584
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800585 synchronized (mHandlerThread) {
586 while (!mInitComplete) {
587 try {
588 mHandlerThread.wait();
589 } catch (InterruptedException e) {
590 // Ignore
591 }
592 }
593 }
Jim Miller92e66dd2012-02-21 18:57:12 -0800594
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700595 synchronized (mLocks) {
596 updateNativePowerStateLocked();
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700597 // We make sure to start out with the screen on due to user activity.
598 // (They did just boot their device, after all.)
599 forceUserActivityLocked();
Dianne Hackborn40011092011-09-22 13:37:48 -0700600 mInitialized = true;
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700601 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800602 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800603
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800604 void initInThread() {
605 mHandler = new Handler();
606
607 mBroadcastWakeLock = new UnsynchronizedWakeLock(
Joe Onorato128e7292009-03-24 18:41:31 -0700608 PowerManager.PARTIAL_WAKE_LOCK, "sleep_broadcast", true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800609 mStayOnWhilePluggedInScreenDimLock = new UnsynchronizedWakeLock(
610 PowerManager.SCREEN_DIM_WAKE_LOCK, "StayOnWhilePluggedIn Screen Dim", false);
611 mStayOnWhilePluggedInPartialLock = new UnsynchronizedWakeLock(
612 PowerManager.PARTIAL_WAKE_LOCK, "StayOnWhilePluggedIn Partial", false);
613 mPreventScreenOnPartialLock = new UnsynchronizedWakeLock(
614 PowerManager.PARTIAL_WAKE_LOCK, "PreventScreenOn Partial", false);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -0500615 mProximityPartialLock = new UnsynchronizedWakeLock(
616 PowerManager.PARTIAL_WAKE_LOCK, "Proximity Partial", false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800617
618 mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
619 mScreenOnIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
620 mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF);
621 mScreenOffIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
622
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700623 Resources resources = mContext.getResources();
Mike Lockwoodaa66ea82009-10-31 16:31:27 -0400624
Joe Onoratob08a1af2010-10-11 19:28:58 -0700625 mAnimateScreenLights = resources.getBoolean(
626 com.android.internal.R.bool.config_animateScreenLights);
627
Joe Onorato6d747652010-10-11 15:15:31 -0700628 mUnplugTurnsOnScreen = resources.getBoolean(
629 com.android.internal.R.bool.config_unplugTurnsOnScreen);
630
Mike Lockwoodeb6456b2011-09-13 15:24:02 -0400631 mScreenBrightnessDim = resources.getInteger(
632 com.android.internal.R.integer.config_screenBrightnessDim);
633
Mike Lockwoodaa66ea82009-10-31 16:31:27 -0400634 // read settings for auto-brightness
635 mUseSoftwareAutoBrightness = resources.getBoolean(
636 com.android.internal.R.bool.config_automatic_brightness_available);
Mike Lockwoodaa66ea82009-10-31 16:31:27 -0400637 if (mUseSoftwareAutoBrightness) {
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700638 mAutoBrightnessLevels = resources.getIntArray(
639 com.android.internal.R.array.config_autoBrightnessLevels);
640 mLcdBacklightValues = resources.getIntArray(
641 com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
642 mButtonBacklightValues = resources.getIntArray(
643 com.android.internal.R.array.config_autoBrightnessButtonBacklightValues);
644 mKeyboardBacklightValues = resources.getIntArray(
645 com.android.internal.R.array.config_autoBrightnessKeyboardBacklightValues);
Mike Lockwood20ee6f22009-11-07 20:33:47 -0500646 mLightSensorWarmupTime = resources.getInteger(
647 com.android.internal.R.integer.config_lightSensorWarmupTime);
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700648 }
Mike Lockwooddc3494e2009-10-14 21:17:09 -0700649
650 ContentResolver resolver = mContext.getContentResolver();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800651 Cursor settingsCursor = resolver.query(Settings.System.CONTENT_URI, null,
652 "(" + Settings.System.NAME + "=?) or ("
653 + Settings.System.NAME + "=?) or ("
Mike Lockwooddc3494e2009-10-14 21:17:09 -0700654 + Settings.System.NAME + "=?) or ("
Joe Onorato609695d2010-10-14 14:57:49 -0700655 + Settings.System.NAME + "=?) or ("
656 + Settings.System.NAME + "=?) or ("
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800657 + Settings.System.NAME + "=?) or ("
658 + Settings.System.NAME + "=?) or ("
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800659 + Settings.System.NAME + "=?)",
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800660 new String[]{STAY_ON_WHILE_PLUGGED_IN, SCREEN_OFF_TIMEOUT, DIM_SCREEN, SCREEN_BRIGHTNESS,
Dianne Hackborn518a3d82012-05-09 16:30:49 -0700661 SCREEN_BRIGHTNESS_MODE, /*SCREEN_AUTO_BRIGHTNESS_ADJ,*/
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800662 WINDOW_ANIMATION_SCALE, TRANSITION_ANIMATION_SCALE},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800663 null);
664 mSettings = new ContentQueryMap(settingsCursor, Settings.System.NAME, true, mHandler);
665 SettingsObserver settingsObserver = new SettingsObserver();
666 mSettings.addObserver(settingsObserver);
667
668 // pretend that the settings changed so we will get their initial state
669 settingsObserver.update(mSettings, null);
670
671 // register for the battery changed notifications
672 IntentFilter filter = new IntentFilter();
673 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
674 mContext.registerReceiver(new BatteryReceiver(), filter);
Mike Lockwood2d7bb812009-11-15 18:12:22 -0500675 filter = new IntentFilter();
676 filter.addAction(Intent.ACTION_BOOT_COMPLETED);
677 mContext.registerReceiver(new BootCompletedReceiver(), filter);
Mike Lockwoodb2865412010-02-02 22:40:33 -0500678 filter = new IntentFilter();
679 filter.addAction(Intent.ACTION_DOCK_EVENT);
680 mContext.registerReceiver(new DockReceiver(), filter);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800681
Doug Zongker43866e02010-01-07 12:09:54 -0800682 // Listen for secure settings changes
683 mContext.getContentResolver().registerContentObserver(
684 Settings.Secure.CONTENT_URI, true,
685 new ContentObserver(new Handler()) {
686 public void onChange(boolean selfChange) {
687 updateSettingsValues();
688 }
689 });
690 updateSettingsValues();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800691
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800692 synchronized (mHandlerThread) {
693 mInitComplete = true;
694 mHandlerThread.notifyAll();
695 }
696 }
697
Jeff Brown7304c342012-05-11 18:42:42 -0700698 /**
699 * Low-level function turn the device off immediately, without trying
700 * to be clean. Most people should use
701 * {@link com.android.server.pm.internal.app.ShutdownThread} for a clean shutdown.
702 */
703 public static void lowLevelShutdown() {
704 nativeShutdown();
705 }
706
707 /**
708 * Low-level function to reboot the device.
709 *
710 * @param reason code to pass to the kernel (e.g. "recovery"), or null.
711 * @throws IOException if reboot fails for some reason (eg, lack of
712 * permission)
713 */
714 public static void lowLevelReboot(String reason) throws IOException {
715 nativeReboot(reason);
716 }
717
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800718 private class WakeLock implements IBinder.DeathRecipient
719 {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700720 WakeLock(int f, IBinder b, String t, int u, int p) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800721 super();
722 flags = f;
723 binder = b;
724 tag = t;
725 uid = u == MY_UID ? Process.SYSTEM_UID : u;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700726 pid = p;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800727 if (u != MY_UID || (
728 !"KEEP_SCREEN_ON_FLAG".equals(tag)
729 && !"KeyInputQueue".equals(tag))) {
730 monitorType = (f & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK
731 ? BatteryStats.WAKE_TYPE_PARTIAL
732 : BatteryStats.WAKE_TYPE_FULL;
733 } else {
734 monitorType = -1;
735 }
736 try {
737 b.linkToDeath(this, 0);
738 } catch (RemoteException e) {
739 binderDied();
740 }
741 }
742 public void binderDied() {
743 synchronized (mLocks) {
Mike Lockwood0e39ea82009-11-18 15:37:10 -0500744 releaseWakeLockLocked(this.binder, 0, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800745 }
746 }
747 final int flags;
748 final IBinder binder;
749 final String tag;
750 final int uid;
Mike Lockwoodf5bd0922010-03-22 17:10:15 -0400751 final int pid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800752 final int monitorType;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700753 WorkSource ws;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800754 boolean activated = true;
755 int minState;
756 }
757
758 private void updateWakeLockLocked() {
759 if (mStayOnConditions != 0 && mBatteryService.isPowered(mStayOnConditions)) {
760 // keep the device on if we're plugged in and mStayOnWhilePluggedIn is set.
761 mStayOnWhilePluggedInScreenDimLock.acquire();
762 mStayOnWhilePluggedInPartialLock.acquire();
763 } else {
764 mStayOnWhilePluggedInScreenDimLock.release();
765 mStayOnWhilePluggedInPartialLock.release();
766 }
767 }
768
769 private boolean isScreenLock(int flags)
770 {
771 int n = flags & LOCK_MASK;
772 return n == PowerManager.FULL_WAKE_LOCK
773 || n == PowerManager.SCREEN_BRIGHT_WAKE_LOCK
Joe Onorato8274a0e2010-10-05 17:38:09 -0400774 || n == PowerManager.SCREEN_DIM_WAKE_LOCK
775 || n == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800776 }
777
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700778 void enforceWakeSourcePermission(int uid, int pid) {
779 if (uid == Process.myUid()) {
780 return;
781 }
782 mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
783 pid, uid, null);
784 }
785
786 public void acquireWakeLock(int flags, IBinder lock, String tag, WorkSource ws) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800787 int uid = Binder.getCallingUid();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700788 int pid = Binder.getCallingPid();
Michael Chane96440f2009-05-06 10:27:36 -0700789 if (uid != Process.myUid()) {
790 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
791 }
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700792 if (ws != null) {
793 enforceWakeSourcePermission(uid, pid);
794 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800795 long ident = Binder.clearCallingIdentity();
796 try {
797 synchronized (mLocks) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700798 acquireWakeLockLocked(flags, lock, uid, pid, tag, ws);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800799 }
800 } finally {
801 Binder.restoreCallingIdentity(ident);
802 }
803 }
804
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700805 void noteStartWakeLocked(WakeLock wl, WorkSource ws) {
Dianne Hackborn70be1672010-09-14 11:13:03 -0700806 if (wl.monitorType >= 0) {
807 long origId = Binder.clearCallingIdentity();
808 try {
809 if (ws != null) {
810 mBatteryStats.noteStartWakelockFromSource(ws, wl.pid, wl.tag,
811 wl.monitorType);
812 } else {
813 mBatteryStats.noteStartWakelock(wl.uid, wl.pid, wl.tag, wl.monitorType);
814 }
815 } catch (RemoteException e) {
816 // Ignore
817 } finally {
818 Binder.restoreCallingIdentity(origId);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700819 }
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700820 }
821 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800822
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700823 void noteStopWakeLocked(WakeLock wl, WorkSource ws) {
Dianne Hackborn70be1672010-09-14 11:13:03 -0700824 if (wl.monitorType >= 0) {
825 long origId = Binder.clearCallingIdentity();
826 try {
827 if (ws != null) {
828 mBatteryStats.noteStopWakelockFromSource(ws, wl.pid, wl.tag,
829 wl.monitorType);
830 } else {
831 mBatteryStats.noteStopWakelock(wl.uid, wl.pid, wl.tag, wl.monitorType);
832 }
833 } catch (RemoteException e) {
834 // Ignore
835 } finally {
836 Binder.restoreCallingIdentity(origId);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700837 }
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700838 }
839 }
840
841 public void acquireWakeLockLocked(int flags, IBinder lock, int uid, int pid, String tag,
842 WorkSource ws) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800843 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800844 Slog.d(TAG, "acquireWakeLock flags=0x" + Integer.toHexString(flags) + " tag=" + tag);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800845 }
846
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700847 if (ws != null && ws.size() == 0) {
848 ws = null;
849 }
850
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800851 int index = mLocks.getIndex(lock);
852 WakeLock wl;
853 boolean newlock;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700854 boolean diffsource;
855 WorkSource oldsource;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800856 if (index < 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700857 wl = new WakeLock(flags, lock, tag, uid, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800858 switch (wl.flags & LOCK_MASK)
859 {
860 case PowerManager.FULL_WAKE_LOCK:
Mike Lockwood4984e732009-11-01 08:16:33 -0500861 if (mUseSoftwareAutoBrightness) {
Mike Lockwood3333fa42009-10-26 14:50:42 -0400862 wl.minState = SCREEN_BRIGHT;
863 } else {
864 wl.minState = (mKeyboardVisible ? ALL_BRIGHT : SCREEN_BUTTON_BRIGHT);
865 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800866 break;
867 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
868 wl.minState = SCREEN_BRIGHT;
869 break;
870 case PowerManager.SCREEN_DIM_WAKE_LOCK:
871 wl.minState = SCREEN_DIM;
872 break;
873 case PowerManager.PARTIAL_WAKE_LOCK:
Mike Lockwoodbc706a02009-07-27 13:50:57 -0700874 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800875 break;
876 default:
877 // just log and bail. we're in the server, so don't
878 // throw an exception.
Joe Onorato8a9b2202010-02-26 18:56:32 -0800879 Slog.e(TAG, "bad wakelock type for lock '" + tag + "' "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800880 + " flags=" + flags);
881 return;
882 }
883 mLocks.addLock(wl);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700884 if (ws != null) {
885 wl.ws = new WorkSource(ws);
886 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800887 newlock = true;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700888 diffsource = false;
889 oldsource = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800890 } else {
891 wl = mLocks.get(index);
892 newlock = false;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700893 oldsource = wl.ws;
894 if (oldsource != null) {
895 if (ws == null) {
896 wl.ws = null;
897 diffsource = true;
898 } else {
899 diffsource = oldsource.diff(ws);
900 }
901 } else if (ws != null) {
902 diffsource = true;
903 } else {
904 diffsource = false;
905 }
906 if (diffsource) {
907 wl.ws = new WorkSource(ws);
908 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800909 }
910 if (isScreenLock(flags)) {
911 // if this causes a wakeup, we reactivate all of the locks and
912 // set it to whatever they want. otherwise, we modulate that
913 // by the current state so we never turn it more on than
914 // it already is.
Joe Onorato8274a0e2010-10-05 17:38:09 -0400915 if ((flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) {
916 mProximityWakeLockCount++;
917 if (mProximityWakeLockCount == 1) {
918 enableProximityLockLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800919 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800920 } else {
Joe Onorato8274a0e2010-10-05 17:38:09 -0400921 if ((wl.flags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {
922 int oldWakeLockState = mWakeLockState;
923 mWakeLockState = mLocks.reactivateScreenLocksLocked();
Mike Lockwooddb97f602011-09-02 11:59:08 -0400924
925 // Disable proximity sensor if if user presses power key while we are in the
926 // "waiting for proximity sensor to go negative" state.
927 if ((mWakeLockState & SCREEN_ON_BIT) != 0
928 && mProximitySensorActive && mProximityWakeLockCount == 0) {
929 mProximitySensorActive = false;
930 }
931
Joe Onorato8274a0e2010-10-05 17:38:09 -0400932 if (mSpew) {
933 Slog.d(TAG, "wakeup here mUserState=0x" + Integer.toHexString(mUserState)
934 + " mWakeLockState=0x"
935 + Integer.toHexString(mWakeLockState)
936 + " previous wakeLockState=0x"
937 + Integer.toHexString(oldWakeLockState));
938 }
939 } else {
940 if (mSpew) {
941 Slog.d(TAG, "here mUserState=0x" + Integer.toHexString(mUserState)
942 + " mLocks.gatherState()=0x"
943 + Integer.toHexString(mLocks.gatherState())
944 + " mWakeLockState=0x" + Integer.toHexString(mWakeLockState));
945 }
946 mWakeLockState = (mUserState | mWakeLockState) & mLocks.gatherState();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800947 }
Joe Onorato8274a0e2010-10-05 17:38:09 -0400948 setPowerState(mWakeLockState | mUserState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800949 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800950 }
951 else if ((flags & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK) {
952 if (newlock) {
953 mPartialCount++;
954 if (mPartialCount == 1) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800955 if (LOG_PARTIAL_WL) EventLog.writeEvent(EventLogTags.POWER_PARTIAL_WAKE_STATE, 1, tag);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800956 }
957 }
Jeff Brown7304c342012-05-11 18:42:42 -0700958 nativeAcquireWakeLock(PARTIAL_WAKE_LOCK_ID, PARTIAL_NAME);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800959 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800960
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700961 if (diffsource) {
962 // If the lock sources have changed, need to first release the
963 // old ones.
964 noteStopWakeLocked(wl, oldsource);
965 }
966 if (newlock || diffsource) {
967 noteStartWakeLocked(wl, ws);
968 }
969 }
970
971 public void updateWakeLockWorkSource(IBinder lock, WorkSource ws) {
972 int uid = Binder.getCallingUid();
973 int pid = Binder.getCallingPid();
974 if (ws != null && ws.size() == 0) {
975 ws = null;
976 }
977 if (ws != null) {
978 enforceWakeSourcePermission(uid, pid);
979 }
Dianne Hackborn70be1672010-09-14 11:13:03 -0700980 synchronized (mLocks) {
981 int index = mLocks.getIndex(lock);
982 if (index < 0) {
983 throw new IllegalArgumentException("Wake lock not active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800984 }
Dianne Hackborn70be1672010-09-14 11:13:03 -0700985 WakeLock wl = mLocks.get(index);
986 WorkSource oldsource = wl.ws;
987 wl.ws = ws != null ? new WorkSource(ws) : null;
988 noteStopWakeLocked(wl, oldsource);
989 noteStartWakeLocked(wl, ws);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800990 }
991 }
992
Mike Lockwood0e39ea82009-11-18 15:37:10 -0500993 public void releaseWakeLock(IBinder lock, int flags) {
Michael Chane96440f2009-05-06 10:27:36 -0700994 int uid = Binder.getCallingUid();
995 if (uid != Process.myUid()) {
996 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
997 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800998
999 synchronized (mLocks) {
Mike Lockwood0e39ea82009-11-18 15:37:10 -05001000 releaseWakeLockLocked(lock, flags, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001001 }
1002 }
1003
Mike Lockwood0e39ea82009-11-18 15:37:10 -05001004 private void releaseWakeLockLocked(IBinder lock, int flags, boolean death) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001005 WakeLock wl = mLocks.removeLock(lock);
1006 if (wl == null) {
1007 return;
1008 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001009
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001010 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001011 Slog.d(TAG, "releaseWakeLock flags=0x"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001012 + Integer.toHexString(wl.flags) + " tag=" + wl.tag);
1013 }
1014
1015 if (isScreenLock(wl.flags)) {
Joe Onorato8274a0e2010-10-05 17:38:09 -04001016 if ((wl.flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) {
1017 mProximityWakeLockCount--;
1018 if (mProximityWakeLockCount == 0) {
1019 if (mProximitySensorActive &&
1020 ((flags & PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE) != 0)) {
1021 // wait for proximity sensor to go negative before disabling sensor
1022 if (mDebugProximitySensor) {
1023 Slog.d(TAG, "waiting for proximity sensor to go negative");
1024 }
1025 } else {
1026 disableProximityLockLocked();
1027 }
1028 }
1029 } else {
1030 mWakeLockState = mLocks.gatherState();
1031 // goes in the middle to reduce flicker
1032 if ((wl.flags & PowerManager.ON_AFTER_RELEASE) != 0) {
1033 userActivity(SystemClock.uptimeMillis(), -1, false, OTHER_EVENT, false);
1034 }
1035 setPowerState(mWakeLockState | mUserState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001036 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001037 }
1038 else if ((wl.flags & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK) {
1039 mPartialCount--;
1040 if (mPartialCount == 0) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001041 if (LOG_PARTIAL_WL) EventLog.writeEvent(EventLogTags.POWER_PARTIAL_WAKE_STATE, 0, wl.tag);
Jeff Brown7304c342012-05-11 18:42:42 -07001042 nativeReleaseWakeLock(PARTIAL_NAME);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001043 }
1044 }
1045 // Unlink the lock from the binder.
1046 wl.binder.unlinkToDeath(wl, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001047
Dianne Hackborn70be1672010-09-14 11:13:03 -07001048 noteStopWakeLocked(wl, wl.ws);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001049 }
1050
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001051 private class PokeLock implements IBinder.DeathRecipient
1052 {
1053 PokeLock(int p, IBinder b, String t) {
1054 super();
1055 this.pokey = p;
1056 this.binder = b;
1057 this.tag = t;
1058 try {
1059 b.linkToDeath(this, 0);
1060 } catch (RemoteException e) {
1061 binderDied();
1062 }
1063 }
1064 public void binderDied() {
1065 setPokeLock(0, this.binder, this.tag);
1066 }
1067 int pokey;
1068 IBinder binder;
1069 String tag;
1070 boolean awakeOnSet;
1071 }
1072
1073 public void setPokeLock(int pokey, IBinder token, String tag) {
1074 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1075 if (token == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001076 Slog.e(TAG, "setPokeLock got null token for tag='" + tag + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001077 return;
1078 }
1079
1080 if ((pokey & POKE_LOCK_TIMEOUT_MASK) == POKE_LOCK_TIMEOUT_MASK) {
1081 throw new IllegalArgumentException("setPokeLock can't have both POKE_LOCK_SHORT_TIMEOUT"
1082 + " and POKE_LOCK_MEDIUM_TIMEOUT");
1083 }
1084
1085 synchronized (mLocks) {
1086 if (pokey != 0) {
1087 PokeLock p = mPokeLocks.get(token);
1088 int oldPokey = 0;
1089 if (p != null) {
1090 oldPokey = p.pokey;
1091 p.pokey = pokey;
1092 } else {
1093 p = new PokeLock(pokey, token, tag);
1094 mPokeLocks.put(token, p);
1095 }
1096 int oldTimeout = oldPokey & POKE_LOCK_TIMEOUT_MASK;
1097 int newTimeout = pokey & POKE_LOCK_TIMEOUT_MASK;
1098 if (((mPowerState & SCREEN_ON_BIT) == 0) && (oldTimeout != newTimeout)) {
1099 p.awakeOnSet = true;
1100 }
1101 } else {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07001102 PokeLock rLock = mPokeLocks.remove(token);
1103 if (rLock != null) {
1104 token.unlinkToDeath(rLock, 0);
1105 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001106 }
1107
1108 int oldPokey = mPokey;
1109 int cumulative = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001110 boolean awakeOnSet = false;
1111 for (PokeLock p: mPokeLocks.values()) {
1112 cumulative |= p.pokey;
1113 if (p.awakeOnSet) {
1114 awakeOnSet = true;
1115 }
1116 }
1117 mPokey = cumulative;
1118 mPokeAwakeOnSet = awakeOnSet;
1119
1120 int oldCumulativeTimeout = oldPokey & POKE_LOCK_TIMEOUT_MASK;
1121 int newCumulativeTimeout = pokey & POKE_LOCK_TIMEOUT_MASK;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001122
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001123 if (oldCumulativeTimeout != newCumulativeTimeout) {
1124 setScreenOffTimeoutsLocked();
1125 // reset the countdown timer, but use the existing nextState so it doesn't
1126 // change anything
1127 setTimeoutLocked(SystemClock.uptimeMillis(), mTimeoutTask.nextState);
1128 }
1129 }
1130 }
1131
1132 private static String lockType(int type)
1133 {
1134 switch (type)
1135 {
1136 case PowerManager.FULL_WAKE_LOCK:
David Brown251faa62009-08-02 22:04:36 -07001137 return "FULL_WAKE_LOCK ";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001138 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
David Brown251faa62009-08-02 22:04:36 -07001139 return "SCREEN_BRIGHT_WAKE_LOCK ";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001140 case PowerManager.SCREEN_DIM_WAKE_LOCK:
David Brown251faa62009-08-02 22:04:36 -07001141 return "SCREEN_DIM_WAKE_LOCK ";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001142 case PowerManager.PARTIAL_WAKE_LOCK:
David Brown251faa62009-08-02 22:04:36 -07001143 return "PARTIAL_WAKE_LOCK ";
1144 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
1145 return "PROXIMITY_SCREEN_OFF_WAKE_LOCK";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001146 default:
David Brown251faa62009-08-02 22:04:36 -07001147 return "??? ";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001148 }
1149 }
1150
1151 private static String dumpPowerState(int state) {
1152 return (((state & KEYBOARD_BRIGHT_BIT) != 0)
1153 ? "KEYBOARD_BRIGHT_BIT " : "")
1154 + (((state & SCREEN_BRIGHT_BIT) != 0)
1155 ? "SCREEN_BRIGHT_BIT " : "")
1156 + (((state & SCREEN_ON_BIT) != 0)
1157 ? "SCREEN_ON_BIT " : "")
1158 + (((state & BATTERY_LOW_BIT) != 0)
1159 ? "BATTERY_LOW_BIT " : "");
1160 }
1161
1162 @Override
1163 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1164 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
1165 != PackageManager.PERMISSION_GRANTED) {
1166 pw.println("Permission Denial: can't dump PowerManager from from pid="
1167 + Binder.getCallingPid()
1168 + ", uid=" + Binder.getCallingUid());
1169 return;
1170 }
1171
1172 long now = SystemClock.uptimeMillis();
1173
Mike Lockwoodca44df82010-02-25 13:48:49 -05001174 synchronized (mLocks) {
1175 pw.println("Power Manager State:");
1176 pw.println(" mIsPowered=" + mIsPowered
1177 + " mPowerState=" + mPowerState
1178 + " mScreenOffTime=" + (SystemClock.elapsedRealtime()-mScreenOffTime)
1179 + " ms");
1180 pw.println(" mPartialCount=" + mPartialCount);
1181 pw.println(" mWakeLockState=" + dumpPowerState(mWakeLockState));
1182 pw.println(" mUserState=" + dumpPowerState(mUserState));
1183 pw.println(" mPowerState=" + dumpPowerState(mPowerState));
1184 pw.println(" mLocks.gather=" + dumpPowerState(mLocks.gatherState()));
1185 pw.println(" mNextTimeout=" + mNextTimeout + " now=" + now
1186 + " " + ((mNextTimeout-now)/1000) + "s from now");
1187 pw.println(" mDimScreen=" + mDimScreen
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001188 + " mStayOnConditions=" + mStayOnConditions
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001189 + " mPreparingForScreenOn=" + mPreparingForScreenOn
1190 + " mSkippedScreenOn=" + mSkippedScreenOn);
Mike Lockwoodca44df82010-02-25 13:48:49 -05001191 pw.println(" mScreenOffReason=" + mScreenOffReason
1192 + " mUserState=" + mUserState);
1193 pw.println(" mBroadcastQueue={" + mBroadcastQueue[0] + ',' + mBroadcastQueue[1]
1194 + ',' + mBroadcastQueue[2] + "}");
1195 pw.println(" mBroadcastWhy={" + mBroadcastWhy[0] + ',' + mBroadcastWhy[1]
1196 + ',' + mBroadcastWhy[2] + "}");
1197 pw.println(" mPokey=" + mPokey + " mPokeAwakeonSet=" + mPokeAwakeOnSet);
1198 pw.println(" mKeyboardVisible=" + mKeyboardVisible
1199 + " mUserActivityAllowed=" + mUserActivityAllowed);
1200 pw.println(" mKeylightDelay=" + mKeylightDelay + " mDimDelay=" + mDimDelay
1201 + " mScreenOffDelay=" + mScreenOffDelay);
1202 pw.println(" mPreventScreenOn=" + mPreventScreenOn
1203 + " mScreenBrightnessOverride=" + mScreenBrightnessOverride
1204 + " mButtonBrightnessOverride=" + mButtonBrightnessOverride);
1205 pw.println(" mScreenOffTimeoutSetting=" + mScreenOffTimeoutSetting
1206 + " mMaximumScreenOffTimeout=" + mMaximumScreenOffTimeout);
1207 pw.println(" mLastScreenOnTime=" + mLastScreenOnTime);
1208 pw.println(" mBroadcastWakeLock=" + mBroadcastWakeLock);
1209 pw.println(" mStayOnWhilePluggedInScreenDimLock=" + mStayOnWhilePluggedInScreenDimLock);
1210 pw.println(" mStayOnWhilePluggedInPartialLock=" + mStayOnWhilePluggedInPartialLock);
1211 pw.println(" mPreventScreenOnPartialLock=" + mPreventScreenOnPartialLock);
1212 pw.println(" mProximityPartialLock=" + mProximityPartialLock);
1213 pw.println(" mProximityWakeLockCount=" + mProximityWakeLockCount);
1214 pw.println(" mProximitySensorEnabled=" + mProximitySensorEnabled);
1215 pw.println(" mProximitySensorActive=" + mProximitySensorActive);
1216 pw.println(" mProximityPendingValue=" + mProximityPendingValue);
1217 pw.println(" mLastProximityEventTime=" + mLastProximityEventTime);
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08001218 pw.println(" mLightSensorEnabled=" + mLightSensorEnabled
1219 + " mLightSensorAdjustSetting=" + mLightSensorAdjustSetting);
Mike Lockwoodca44df82010-02-25 13:48:49 -05001220 pw.println(" mLightSensorValue=" + mLightSensorValue
1221 + " mLightSensorPendingValue=" + mLightSensorPendingValue);
Jim Rodovichd102fea2010-09-02 12:30:49 -05001222 pw.println(" mLightSensorPendingDecrease=" + mLightSensorPendingDecrease
1223 + " mLightSensorPendingIncrease=" + mLightSensorPendingIncrease);
Mike Lockwoodca44df82010-02-25 13:48:49 -05001224 pw.println(" mLightSensorScreenBrightness=" + mLightSensorScreenBrightness
1225 + " mLightSensorButtonBrightness=" + mLightSensorButtonBrightness
1226 + " mLightSensorKeyboardBrightness=" + mLightSensorKeyboardBrightness);
1227 pw.println(" mUseSoftwareAutoBrightness=" + mUseSoftwareAutoBrightness);
1228 pw.println(" mAutoBrightessEnabled=" + mAutoBrightessEnabled);
Jim Miller92e66dd2012-02-21 18:57:12 -08001229 mScreenBrightnessAnimator.dump(pw, " mScreenBrightnessAnimator: ");
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001230
Mike Lockwoodca44df82010-02-25 13:48:49 -05001231 int N = mLocks.size();
1232 pw.println();
1233 pw.println("mLocks.size=" + N + ":");
1234 for (int i=0; i<N; i++) {
1235 WakeLock wl = mLocks.get(i);
1236 String type = lockType(wl.flags & LOCK_MASK);
1237 String acquireCausesWakeup = "";
1238 if ((wl.flags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {
1239 acquireCausesWakeup = "ACQUIRE_CAUSES_WAKEUP ";
1240 }
1241 String activated = "";
1242 if (wl.activated) {
1243 activated = " activated";
1244 }
1245 pw.println(" " + type + " '" + wl.tag + "'" + acquireCausesWakeup
Mike Lockwoodf5bd0922010-03-22 17:10:15 -04001246 + activated + " (minState=" + wl.minState + ", uid=" + wl.uid
1247 + ", pid=" + wl.pid + ")");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001248 }
Mike Lockwoodca44df82010-02-25 13:48:49 -05001249
1250 pw.println();
1251 pw.println("mPokeLocks.size=" + mPokeLocks.size() + ":");
1252 for (PokeLock p: mPokeLocks.values()) {
1253 pw.println(" poke lock '" + p.tag + "':"
Joe Onorato1a542c72010-11-08 09:48:20 -08001254 + ((p.pokey & POKE_LOCK_IGNORE_TOUCH_EVENTS) != 0
1255 ? " POKE_LOCK_IGNORE_TOUCH_EVENTS" : "")
Mike Lockwoodca44df82010-02-25 13:48:49 -05001256 + ((p.pokey & POKE_LOCK_SHORT_TIMEOUT) != 0
1257 ? " POKE_LOCK_SHORT_TIMEOUT" : "")
1258 + ((p.pokey & POKE_LOCK_MEDIUM_TIMEOUT) != 0
1259 ? " POKE_LOCK_MEDIUM_TIMEOUT" : ""));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001260 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001261
Mike Lockwoodca44df82010-02-25 13:48:49 -05001262 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001263 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001264 }
1265
Joe Onorato7999bff2010-07-24 11:50:05 -04001266 private void setTimeoutLocked(long now, int nextState) {
1267 setTimeoutLocked(now, -1, nextState);
1268 }
1269
1270 // If they gave a timeoutOverride it is the number of seconds
1271 // to screen-off. Figure out where in the countdown cycle we
1272 // should jump to.
Joe Onorato797e6882010-08-26 14:46:01 -04001273 private void setTimeoutLocked(long now, final long originalTimeoutOverride, int nextState) {
1274 long timeoutOverride = originalTimeoutOverride;
Mike Lockwood2d7bb812009-11-15 18:12:22 -05001275 if (mBootCompleted) {
Joe Onorato7999bff2010-07-24 11:50:05 -04001276 synchronized (mLocks) {
Joe Onorato7999bff2010-07-24 11:50:05 -04001277 long when = 0;
1278 if (timeoutOverride <= 0) {
1279 switch (nextState)
1280 {
1281 case SCREEN_BRIGHT:
1282 when = now + mKeylightDelay;
1283 break;
1284 case SCREEN_DIM:
1285 if (mDimDelay >= 0) {
1286 when = now + mDimDelay;
Andreas Huber84047bc2010-07-27 16:49:10 -07001287 break;
Joe Onorato7999bff2010-07-24 11:50:05 -04001288 } else {
1289 Slog.w(TAG, "mDimDelay=" + mDimDelay + " while trying to dim");
1290 }
1291 case SCREEN_OFF:
1292 synchronized (mLocks) {
1293 when = now + mScreenOffDelay;
1294 }
1295 break;
Andreas Huber84047bc2010-07-27 16:49:10 -07001296 default:
1297 when = now;
1298 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001299 }
Joe Onorato7999bff2010-07-24 11:50:05 -04001300 } else {
1301 override: {
1302 if (timeoutOverride <= mScreenOffDelay) {
1303 when = now + timeoutOverride;
1304 nextState = SCREEN_OFF;
1305 break override;
1306 }
1307 timeoutOverride -= mScreenOffDelay;
1308
1309 if (mDimDelay >= 0) {
1310 if (timeoutOverride <= mDimDelay) {
1311 when = now + timeoutOverride;
1312 nextState = SCREEN_DIM;
1313 break override;
1314 }
1315 timeoutOverride -= mDimDelay;
1316 }
1317
1318 when = now + timeoutOverride;
1319 nextState = SCREEN_BRIGHT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001320 }
Joe Onorato7999bff2010-07-24 11:50:05 -04001321 }
1322 if (mSpew) {
1323 Slog.d(TAG, "setTimeoutLocked now=" + now
1324 + " timeoutOverride=" + timeoutOverride
1325 + " nextState=" + nextState + " when=" + when);
1326 }
Joe Onorato797e6882010-08-26 14:46:01 -04001327
1328 mHandler.removeCallbacks(mTimeoutTask);
1329 mTimeoutTask.nextState = nextState;
1330 mTimeoutTask.remainingTimeoutOverride = timeoutOverride > 0
1331 ? (originalTimeoutOverride - timeoutOverride)
1332 : -1;
Joe Onorato7999bff2010-07-24 11:50:05 -04001333 mHandler.postAtTime(mTimeoutTask, when);
1334 mNextTimeout = when; // for debugging
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001335 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001336 }
1337 }
1338
1339 private void cancelTimerLocked()
1340 {
1341 mHandler.removeCallbacks(mTimeoutTask);
1342 mTimeoutTask.nextState = -1;
1343 }
1344
1345 private class TimeoutTask implements Runnable
1346 {
1347 int nextState; // access should be synchronized on mLocks
Joe Onorato797e6882010-08-26 14:46:01 -04001348 long remainingTimeoutOverride;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001349 public void run()
1350 {
1351 synchronized (mLocks) {
1352 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001353 Slog.d(TAG, "user activity timeout timed out nextState=" + this.nextState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001354 }
1355
1356 if (nextState == -1) {
1357 return;
1358 }
1359
1360 mUserState = this.nextState;
1361 setPowerState(this.nextState | mWakeLockState);
1362
1363 long now = SystemClock.uptimeMillis();
1364
1365 switch (this.nextState)
1366 {
1367 case SCREEN_BRIGHT:
1368 if (mDimDelay >= 0) {
Joe Onorato797e6882010-08-26 14:46:01 -04001369 setTimeoutLocked(now, remainingTimeoutOverride, SCREEN_DIM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001370 break;
1371 }
1372 case SCREEN_DIM:
Joe Onorato797e6882010-08-26 14:46:01 -04001373 setTimeoutLocked(now, remainingTimeoutOverride, SCREEN_OFF);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001374 break;
1375 }
1376 }
1377 }
1378 }
1379
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001380 private void sendNotificationLocked(boolean on, int why) {
1381 if (!mInitialized) {
1382 // No notifications sent until first initialization is done.
1383 // This is so that when we are moving from our initial state
1384 // which looks like the screen was off to it being on, we do not
1385 // go through the process of waiting for the higher-level user
1386 // space to be ready before turning up the display brightness.
1387 // (And also do not send needless broadcasts about the screen.)
1388 return;
1389 }
Dianne Hackborn40011092011-09-22 13:37:48 -07001390
1391 if (DEBUG_SCREEN_ON) {
1392 RuntimeException here = new RuntimeException("here");
1393 here.fillInStackTrace();
1394 Slog.i(TAG, "sendNotificationLocked: " + on, here);
1395 }
1396
Joe Onorato64c62ba2009-03-24 20:13:57 -07001397 if (!on) {
1398 mStillNeedSleepNotification = false;
1399 }
1400
Joe Onorato128e7292009-03-24 18:41:31 -07001401 // Add to the queue.
1402 int index = 0;
1403 while (mBroadcastQueue[index] != -1) {
1404 index++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001405 }
Joe Onorato128e7292009-03-24 18:41:31 -07001406 mBroadcastQueue[index] = on ? 1 : 0;
1407 mBroadcastWhy[index] = why;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001408
Joe Onorato128e7292009-03-24 18:41:31 -07001409 // If we added it position 2, then there is a pair that can be stripped.
1410 // If we added it position 1 and we're turning the screen off, we can strip
1411 // the pair and do nothing, because the screen is already off, and therefore
1412 // keyguard has already been enabled.
1413 // However, if we added it at position 1 and we're turning it on, then position
1414 // 0 was to turn it off, and we can't strip that, because keyguard needs to come
1415 // on, so have to run the queue then.
1416 if (index == 2) {
Dianne Hackborn254cb442010-01-27 19:23:59 -08001417 // While we're collapsing them, if it's going off, and the new reason
1418 // is more significant than the first, then use the new one.
1419 if (!on && mBroadcastWhy[0] > why) {
1420 mBroadcastWhy[0] = why;
Joe Onorato128e7292009-03-24 18:41:31 -07001421 }
1422 mBroadcastQueue[0] = on ? 1 : 0;
1423 mBroadcastQueue[1] = -1;
1424 mBroadcastQueue[2] = -1;
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001425 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount);
Mike Lockwood9c90a372010-04-13 15:40:27 -04001426 mBroadcastWakeLock.release();
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001427 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount);
Mike Lockwood9c90a372010-04-13 15:40:27 -04001428 mBroadcastWakeLock.release();
Joe Onorato128e7292009-03-24 18:41:31 -07001429 index = 0;
1430 }
1431 if (index == 1 && !on) {
1432 mBroadcastQueue[0] = -1;
1433 mBroadcastQueue[1] = -1;
1434 index = -1;
1435 // The wake lock was being held, but we're not actually going to do any
1436 // broadcasts, so release the wake lock.
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001437 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001438 mBroadcastWakeLock.release();
Joe Onorato128e7292009-03-24 18:41:31 -07001439 }
1440
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07001441 // The broadcast queue has changed; make sure the screen is on if it
1442 // is now possible for it to be.
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001443 if (mSkippedScreenOn) {
1444 updateLightsLocked(mPowerState, SCREEN_ON_BIT);
1445 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07001446
Joe Onorato128e7292009-03-24 18:41:31 -07001447 // Now send the message.
1448 if (index >= 0) {
1449 // Acquire the broadcast wake lock before changing the power
1450 // state. It will be release after the broadcast is sent.
1451 // We always increment the ref count for each notification in the queue
1452 // and always decrement when that notification is handled.
1453 mBroadcastWakeLock.acquire();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001454 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND, mBroadcastWakeLock.mCount);
Joe Onorato128e7292009-03-24 18:41:31 -07001455 mHandler.post(mNotificationTask);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001456 }
1457 }
1458
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001459 private WindowManagerPolicy.ScreenOnListener mScreenOnListener =
1460 new WindowManagerPolicy.ScreenOnListener() {
Jim Miller92e66dd2012-02-21 18:57:12 -08001461 public void onScreenOn() {
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001462 synchronized (mLocks) {
1463 if (mPreparingForScreenOn) {
1464 mPreparingForScreenOn = false;
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001465 updateLightsLocked(mPowerState, SCREEN_ON_BIT);
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001466 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP,
1467 4, mBroadcastWakeLock.mCount);
1468 mBroadcastWakeLock.release();
1469 }
1470 }
1471 }
1472 };
1473
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001474 private Runnable mNotificationTask = new Runnable()
1475 {
1476 public void run()
1477 {
Joe Onorato128e7292009-03-24 18:41:31 -07001478 while (true) {
1479 int value;
1480 int why;
1481 WindowManagerPolicy policy;
1482 synchronized (mLocks) {
1483 value = mBroadcastQueue[0];
1484 why = mBroadcastWhy[0];
1485 for (int i=0; i<2; i++) {
1486 mBroadcastQueue[i] = mBroadcastQueue[i+1];
1487 mBroadcastWhy[i] = mBroadcastWhy[i+1];
1488 }
1489 policy = getPolicyLocked();
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001490 if (value == 1 && !mPreparingForScreenOn) {
1491 mPreparingForScreenOn = true;
1492 mBroadcastWakeLock.acquire();
1493 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND,
1494 mBroadcastWakeLock.mCount);
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07001495 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001496 }
Joe Onorato128e7292009-03-24 18:41:31 -07001497 if (value == 1) {
1498 mScreenOnStart = SystemClock.uptimeMillis();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001499
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001500 policy.screenTurningOn(mScreenOnListener);
Joe Onorato128e7292009-03-24 18:41:31 -07001501 try {
1502 ActivityManagerNative.getDefault().wakingUp();
1503 } catch (RemoteException e) {
1504 // ignore it
1505 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001506
Joe Onorato128e7292009-03-24 18:41:31 -07001507 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001508 Slog.d(TAG, "mBroadcastWakeLock=" + mBroadcastWakeLock);
Joe Onorato128e7292009-03-24 18:41:31 -07001509 }
1510 if (mContext != null && ActivityManagerNative.isSystemReady()) {
1511 mContext.sendOrderedBroadcast(mScreenOnIntent, null,
1512 mScreenOnBroadcastDone, mHandler, 0, null, null);
1513 } else {
1514 synchronized (mLocks) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001515 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 2,
Joe Onorato128e7292009-03-24 18:41:31 -07001516 mBroadcastWakeLock.mCount);
1517 mBroadcastWakeLock.release();
1518 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001519 }
1520 }
Joe Onorato128e7292009-03-24 18:41:31 -07001521 else if (value == 0) {
1522 mScreenOffStart = SystemClock.uptimeMillis();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001523
Joe Onorato128e7292009-03-24 18:41:31 -07001524 policy.screenTurnedOff(why);
1525 try {
1526 ActivityManagerNative.getDefault().goingToSleep();
1527 } catch (RemoteException e) {
1528 // ignore it.
1529 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001530
Joe Onorato128e7292009-03-24 18:41:31 -07001531 if (mContext != null && ActivityManagerNative.isSystemReady()) {
1532 mContext.sendOrderedBroadcast(mScreenOffIntent, null,
1533 mScreenOffBroadcastDone, mHandler, 0, null, null);
1534 } else {
1535 synchronized (mLocks) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001536 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 3,
Joe Onorato128e7292009-03-24 18:41:31 -07001537 mBroadcastWakeLock.mCount);
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001538 updateLightsLocked(mPowerState, SCREEN_ON_BIT);
Joe Onorato128e7292009-03-24 18:41:31 -07001539 mBroadcastWakeLock.release();
1540 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001541 }
1542 }
Joe Onorato128e7292009-03-24 18:41:31 -07001543 else {
1544 // If we're in this case, then this handler is running for a previous
1545 // paired transaction. mBroadcastWakeLock will already have been released.
1546 break;
1547 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001548 }
1549 }
1550 };
1551
1552 long mScreenOnStart;
1553 private BroadcastReceiver mScreenOnBroadcastDone = new BroadcastReceiver() {
1554 public void onReceive(Context context, Intent intent) {
1555 synchronized (mLocks) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001556 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001557 SystemClock.uptimeMillis() - mScreenOnStart, mBroadcastWakeLock.mCount);
1558 mBroadcastWakeLock.release();
1559 }
1560 }
1561 };
1562
1563 long mScreenOffStart;
1564 private BroadcastReceiver mScreenOffBroadcastDone = new BroadcastReceiver() {
1565 public void onReceive(Context context, Intent intent) {
1566 synchronized (mLocks) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001567 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 0,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001568 SystemClock.uptimeMillis() - mScreenOffStart, mBroadcastWakeLock.mCount);
1569 mBroadcastWakeLock.release();
1570 }
1571 }
1572 };
1573
1574 void logPointerUpEvent() {
1575 if (LOG_TOUCH_DOWNS) {
1576 mTotalTouchDownTime += SystemClock.elapsedRealtime() - mLastTouchDown;
1577 mLastTouchDown = 0;
1578 }
1579 }
1580
1581 void logPointerDownEvent() {
1582 if (LOG_TOUCH_DOWNS) {
1583 // If we are not already timing a down/up sequence
1584 if (mLastTouchDown == 0) {
1585 mLastTouchDown = SystemClock.elapsedRealtime();
1586 mTouchCycles++;
1587 }
1588 }
1589 }
1590
1591 /**
1592 * Prevents the screen from turning on even if it *should* turn on due
1593 * to a subsequent full wake lock being acquired.
1594 * <p>
1595 * This is a temporary hack that allows an activity to "cover up" any
1596 * display glitches that happen during the activity's startup
1597 * sequence. (Specifically, this API was added to work around a
1598 * cosmetic bug in the "incoming call" sequence, where the lock screen
1599 * would flicker briefly before the incoming call UI became visible.)
1600 * TODO: There ought to be a more elegant way of doing this,
1601 * probably by having the PowerManager and ActivityManager
1602 * work together to let apps specify that the screen on/off
1603 * state should be synchronized with the Activity lifecycle.
1604 * <p>
1605 * Note that calling preventScreenOn(true) will NOT turn the screen
1606 * off if it's currently on. (This API only affects *future*
1607 * acquisitions of full wake locks.)
1608 * But calling preventScreenOn(false) WILL turn the screen on if
1609 * it's currently off because of a prior preventScreenOn(true) call.
1610 * <p>
1611 * Any call to preventScreenOn(true) MUST be followed promptly by a call
1612 * to preventScreenOn(false). In fact, if the preventScreenOn(false)
1613 * call doesn't occur within 5 seconds, we'll turn the screen back on
1614 * ourselves (and log a warning about it); this prevents a buggy app
1615 * from disabling the screen forever.)
1616 * <p>
1617 * TODO: this feature should really be controlled by a new type of poke
1618 * lock (rather than an IPowerManager call).
1619 */
1620 public void preventScreenOn(boolean prevent) {
1621 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1622
1623 synchronized (mLocks) {
1624 if (prevent) {
1625 // First of all, grab a partial wake lock to
1626 // make sure the CPU stays on during the entire
1627 // preventScreenOn(true) -> preventScreenOn(false) sequence.
1628 mPreventScreenOnPartialLock.acquire();
1629
1630 // Post a forceReenableScreen() call (for 5 seconds in the
1631 // future) to make sure the matching preventScreenOn(false) call
1632 // has happened by then.
1633 mHandler.removeCallbacks(mForceReenableScreenTask);
1634 mHandler.postDelayed(mForceReenableScreenTask, 5000);
1635
1636 // Finally, set the flag that prevents the screen from turning on.
1637 // (Below, in setPowerState(), we'll check mPreventScreenOn and
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001638 // we *won't* call setScreenStateLocked(true) if it's set.)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001639 mPreventScreenOn = true;
1640 } else {
1641 // (Re)enable the screen.
1642 mPreventScreenOn = false;
1643
1644 // We're "undoing" a the prior preventScreenOn(true) call, so we
1645 // no longer need the 5-second safeguard.
1646 mHandler.removeCallbacks(mForceReenableScreenTask);
1647
1648 // Forcibly turn on the screen if it's supposed to be on. (This
1649 // handles the case where the screen is currently off because of
1650 // a prior preventScreenOn(true) call.)
Mike Lockwoode090281422009-11-14 21:02:56 -05001651 if (!mProximitySensorActive && (mPowerState & SCREEN_ON_BIT) != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001652 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001653 Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001654 "preventScreenOn: turning on after a prior preventScreenOn(true)!");
1655 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001656 int err = setScreenStateLocked(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001657 if (err != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001658 Slog.w(TAG, "preventScreenOn: error from setScreenStateLocked(): " + err);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001659 }
1660 }
1661
1662 // Release the partial wake lock that we held during the
1663 // preventScreenOn(true) -> preventScreenOn(false) sequence.
1664 mPreventScreenOnPartialLock.release();
1665 }
1666 }
1667 }
1668
1669 public void setScreenBrightnessOverride(int brightness) {
1670 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1671
Mike Lockwoodf527c712010-06-10 14:12:33 -04001672 if (mSpew) Slog.d(TAG, "setScreenBrightnessOverride " + brightness);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001673 synchronized (mLocks) {
1674 if (mScreenBrightnessOverride != brightness) {
1675 mScreenBrightnessOverride = brightness;
Mike Lockwoodf527c712010-06-10 14:12:33 -04001676 if (isScreenOn()) {
1677 updateLightsLocked(mPowerState, SCREEN_ON_BIT);
1678 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001679 }
1680 }
1681 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05001682
1683 public void setButtonBrightnessOverride(int brightness) {
1684 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1685
Mike Lockwoodf527c712010-06-10 14:12:33 -04001686 if (mSpew) Slog.d(TAG, "setButtonBrightnessOverride " + brightness);
Mike Lockwoodfb73f792009-11-20 11:31:18 -05001687 synchronized (mLocks) {
1688 if (mButtonBrightnessOverride != brightness) {
1689 mButtonBrightnessOverride = brightness;
Mike Lockwoodf527c712010-06-10 14:12:33 -04001690 if (isScreenOn()) {
1691 updateLightsLocked(mPowerState, BUTTON_BRIGHT_BIT | KEYBOARD_BRIGHT_BIT);
1692 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05001693 }
1694 }
1695 }
1696
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001697 /**
1698 * Sanity-check that gets called 5 seconds after any call to
1699 * preventScreenOn(true). This ensures that the original call
1700 * is followed promptly by a call to preventScreenOn(false).
1701 */
1702 private void forceReenableScreen() {
1703 // We shouldn't get here at all if mPreventScreenOn is false, since
1704 // we should have already removed any existing
1705 // mForceReenableScreenTask messages...
1706 if (!mPreventScreenOn) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001707 Slog.w(TAG, "forceReenableScreen: mPreventScreenOn is false, nothing to do");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001708 return;
1709 }
1710
1711 // Uh oh. It's been 5 seconds since a call to
1712 // preventScreenOn(true) and we haven't re-enabled the screen yet.
1713 // This means the app that called preventScreenOn(true) is either
1714 // slow (i.e. it took more than 5 seconds to call preventScreenOn(false)),
1715 // or buggy (i.e. it forgot to call preventScreenOn(false), or
1716 // crashed before doing so.)
1717
1718 // Log a warning, and forcibly turn the screen back on.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001719 Slog.w(TAG, "App called preventScreenOn(true) but didn't promptly reenable the screen! "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001720 + "Forcing the screen back on...");
1721 preventScreenOn(false);
1722 }
1723
1724 private Runnable mForceReenableScreenTask = new Runnable() {
1725 public void run() {
1726 forceReenableScreen();
1727 }
1728 };
1729
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001730 private int setScreenStateLocked(boolean on) {
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001731 if (DEBUG_SCREEN_ON) {
1732 RuntimeException e = new RuntimeException("here");
1733 e.fillInStackTrace();
1734 Slog.i(TAG, "Set screen state: " + on, e);
1735 }
Dianne Hackborn474fd742011-10-10 18:40:22 -07001736 if (on) {
1737 if ((mPowerState & SCREEN_ON_BIT) == 0 || mSkippedScreenOn) {
1738 // If we are turning the screen state on, but the screen
1739 // light is currently off, then make sure that we set the
1740 // light at this point to 0. This is the case where we are
1741 // turning on the screen and waiting for the UI to be drawn
1742 // before showing it to the user. We want the light off
1743 // until it is ready to be shown to the user, not it using
1744 // whatever the last value it had.
Dianne Hackborn81de8b92011-11-28 16:54:31 -08001745 if (DEBUG_SCREEN_ON) {
1746 Slog.i(TAG, "Forcing brightness 0: mPowerState=0x"
1747 + Integer.toHexString(mPowerState)
1748 + " mSkippedScreenOn=" + mSkippedScreenOn);
1749 }
Jeff Brown7304c342012-05-11 18:42:42 -07001750 mScreenBrightnessAnimator.animateTo(PowerManager.BRIGHTNESS_OFF, SCREEN_BRIGHT_BIT, 0);
Dianne Hackborn474fd742011-10-10 18:40:22 -07001751 }
1752 }
Jeff Brown7304c342012-05-11 18:42:42 -07001753 int err = nativeSetScreenState(on);
Mike Lockwood20ee6f22009-11-07 20:33:47 -05001754 if (err == 0) {
1755 mLastScreenOnTime = (on ? SystemClock.elapsedRealtime() : 0);
1756 if (mUseSoftwareAutoBrightness) {
Joe Onoratod28f7532010-11-06 12:56:53 -07001757 enableLightSensorLocked(on);
Mike Lockwood20ee6f22009-11-07 20:33:47 -05001758 if (!on) {
1759 // make sure button and key backlights are off too
Mike Lockwood3cb67a32009-11-27 14:25:58 -05001760 mButtonLight.turnOff();
1761 mKeyboardLight.turnOff();
Mike Lockwood20ee6f22009-11-07 20:33:47 -05001762 }
Mike Lockwoodd7786b42009-10-15 17:09:16 -07001763 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001764 }
1765 return err;
1766 }
1767
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001768 private void setPowerState(int state)
1769 {
Mike Lockwood435eb642009-12-03 08:40:18 -05001770 setPowerState(state, false, WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001771 }
1772
Mike Lockwood435eb642009-12-03 08:40:18 -05001773 private void setPowerState(int newState, boolean noChangeLights, int reason)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001774 {
1775 synchronized (mLocks) {
1776 int err;
1777
1778 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001779 Slog.d(TAG, "setPowerState: mPowerState=0x" + Integer.toHexString(mPowerState)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001780 + " newState=0x" + Integer.toHexString(newState)
Mike Lockwood435eb642009-12-03 08:40:18 -05001781 + " noChangeLights=" + noChangeLights
1782 + " reason=" + reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001783 }
Daniel Sandler7d276c32012-01-30 14:33:52 -05001784
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001785 if (noChangeLights) {
1786 newState = (newState & ~LIGHTS_MASK) | (mPowerState & LIGHTS_MASK);
1787 }
Mike Lockwood36fc3022009-08-25 16:49:06 -07001788 if (mProximitySensorActive) {
1789 // don't turn on the screen when the proximity sensor lock is held
1790 newState = (newState & ~SCREEN_BRIGHT);
1791 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001792
1793 if (batteryIsLow()) {
1794 newState |= BATTERY_LOW_BIT;
1795 } else {
1796 newState &= ~BATTERY_LOW_BIT;
1797 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001798 if (newState == mPowerState && mInitialized) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001799 return;
1800 }
Mike Lockwood3333fa42009-10-26 14:50:42 -04001801
Mike Lockwood2d7bb812009-11-15 18:12:22 -05001802 if (!mBootCompleted && !mUseSoftwareAutoBrightness) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001803 newState |= ALL_BRIGHT;
1804 }
1805
1806 boolean oldScreenOn = (mPowerState & SCREEN_ON_BIT) != 0;
1807 boolean newScreenOn = (newState & SCREEN_ON_BIT) != 0;
1808
Mike Lockwood51b844962009-11-16 21:51:18 -05001809 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001810 Slog.d(TAG, "setPowerState: mPowerState=" + mPowerState
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001811 + " newState=" + newState + " noChangeLights=" + noChangeLights);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001812 Slog.d(TAG, " oldKeyboardBright=" + ((mPowerState & KEYBOARD_BRIGHT_BIT) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001813 + " newKeyboardBright=" + ((newState & KEYBOARD_BRIGHT_BIT) != 0));
Joe Onorato8a9b2202010-02-26 18:56:32 -08001814 Slog.d(TAG, " oldScreenBright=" + ((mPowerState & SCREEN_BRIGHT_BIT) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001815 + " newScreenBright=" + ((newState & SCREEN_BRIGHT_BIT) != 0));
Joe Onorato8a9b2202010-02-26 18:56:32 -08001816 Slog.d(TAG, " oldButtonBright=" + ((mPowerState & BUTTON_BRIGHT_BIT) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001817 + " newButtonBright=" + ((newState & BUTTON_BRIGHT_BIT) != 0));
Joe Onorato8a9b2202010-02-26 18:56:32 -08001818 Slog.d(TAG, " oldScreenOn=" + oldScreenOn
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001819 + " newScreenOn=" + newScreenOn);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001820 Slog.d(TAG, " oldBatteryLow=" + ((mPowerState & BATTERY_LOW_BIT) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001821 + " newBatteryLow=" + ((newState & BATTERY_LOW_BIT) != 0));
1822 }
1823
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001824 final boolean stateChanged = mPowerState != newState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001825
Daniel Sandler7d276c32012-01-30 14:33:52 -05001826 if (stateChanged && reason == WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT) {
Daniel Sandler0af48952012-04-10 15:14:35 -04001827 if (mPolicy != null && mPolicy.isScreenSaverEnabled()) {
Daniel Sandler7d276c32012-01-30 14:33:52 -05001828 if (mSpew) {
1829 Slog.d(TAG, "setPowerState: running screen saver instead of turning off screen");
1830 }
1831 if (mPolicy.startScreenSaver()) {
1832 // was successful
1833 return;
1834 }
1835 }
1836 }
1837
1838
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001839 if (oldScreenOn != newScreenOn) {
1840 if (newScreenOn) {
Joe Onorato128e7292009-03-24 18:41:31 -07001841 // When the user presses the power button, we need to always send out the
1842 // notification that it's going to sleep so the keyguard goes on. But
1843 // we can't do that until the screen fades out, so we don't show the keyguard
1844 // too early.
1845 if (mStillNeedSleepNotification) {
1846 sendNotificationLocked(false, WindowManagerPolicy.OFF_BECAUSE_OF_USER);
1847 }
1848
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001849 // Turn on the screen UNLESS there was a prior
1850 // preventScreenOn(true) request. (Note that the lifetime
1851 // of a single preventScreenOn() request is limited to 5
1852 // seconds to prevent a buggy app from disabling the
1853 // screen forever; see forceReenableScreen().)
1854 boolean reallyTurnScreenOn = true;
1855 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001856 Slog.d(TAG, "- turning screen on... mPreventScreenOn = "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001857 + mPreventScreenOn);
1858 }
1859
1860 if (mPreventScreenOn) {
1861 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001862 Slog.d(TAG, "- PREVENTING screen from really turning on!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001863 }
1864 reallyTurnScreenOn = false;
1865 }
1866 if (reallyTurnScreenOn) {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001867 err = setScreenStateLocked(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001868 long identity = Binder.clearCallingIdentity();
1869 try {
Mike Lockwoodfb73f792009-11-20 11:31:18 -05001870 mBatteryStats.noteScreenBrightness(getPreferredBrightness());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001871 mBatteryStats.noteScreenOn();
1872 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001873 Slog.w(TAG, "RemoteException calling noteScreenOn on BatteryStatsService", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001874 } finally {
1875 Binder.restoreCallingIdentity(identity);
1876 }
1877 } else {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001878 setScreenStateLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001879 // But continue as if we really did turn the screen on...
1880 err = 0;
1881 }
1882
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001883 mLastTouchDown = 0;
1884 mTotalTouchDownTime = 0;
1885 mTouchCycles = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001886 EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, reason,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001887 mTotalTouchDownTime, mTouchCycles);
1888 if (err == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001889 sendNotificationLocked(true, -1);
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001890 // Update the lights *after* taking care of turning the
1891 // screen on, so we do this after our notifications are
1892 // enqueued and thus will delay turning on the screen light
1893 // until the windows are correctly displayed.
1894 if (stateChanged) {
1895 updateLightsLocked(newState, 0);
1896 }
1897 mPowerState |= SCREEN_ON_BIT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001898 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001899
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001900 } else {
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001901 // Update the lights *before* taking care of turning the
1902 // screen off, so we can initiate any animations that are desired.
Craig Mautner44bf70f2012-03-13 11:38:38 -07001903 mScreenOffReason = reason;
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001904 if (stateChanged) {
1905 updateLightsLocked(newState, 0);
1906 }
1907
Mike Lockwood497087e32009-11-08 18:33:03 -05001908 // cancel light sensor task
1909 mHandler.removeCallbacks(mAutoBrightnessTask);
Jim Rodovichd102fea2010-09-02 12:30:49 -05001910 mLightSensorPendingDecrease = false;
1911 mLightSensorPendingIncrease = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001912 mScreenOffTime = SystemClock.elapsedRealtime();
1913 long identity = Binder.clearCallingIdentity();
1914 try {
1915 mBatteryStats.noteScreenOff();
1916 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001917 Slog.w(TAG, "RemoteException calling noteScreenOff on BatteryStatsService", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001918 } finally {
1919 Binder.restoreCallingIdentity(identity);
1920 }
1921 mPowerState &= ~SCREEN_ON_BIT;
Jim Miller92e66dd2012-02-21 18:57:12 -08001922 if (!mScreenBrightnessAnimator.isAnimating()) {
Mike Lockwood435eb642009-12-03 08:40:18 -05001923 err = screenOffFinishedAnimatingLocked(reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001924 } else {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001925 err = 0;
1926 mLastTouchDown = 0;
1927 }
1928 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001929 } else if (stateChanged) {
1930 // Screen on/off didn't change, but lights may have.
1931 updateLightsLocked(newState, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001932 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001933
1934 mPowerState = (mPowerState & ~LIGHTS_MASK) | (newState & LIGHTS_MASK);
1935
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001936 updateNativePowerStateLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001937 }
1938 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001939
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001940 private void updateNativePowerStateLocked() {
Mike Lockwood3a74bd32011-08-12 13:55:22 -07001941 if (!mHeadless) {
1942 nativeSetPowerState(
1943 (mPowerState & SCREEN_ON_BIT) != 0,
1944 (mPowerState & SCREEN_BRIGHT) == SCREEN_BRIGHT);
1945 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001946 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001947
Mike Lockwood435eb642009-12-03 08:40:18 -05001948 private int screenOffFinishedAnimatingLocked(int reason) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001949 // I don't think we need to check the current state here because all of these
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001950 // Power.setScreenState and sendNotificationLocked can both handle being
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001951 // called multiple times in the same state. -joeo
Joe Onoratob08a1af2010-10-11 19:28:58 -07001952 EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, reason, mTotalTouchDownTime,
1953 mTouchCycles);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001954 mLastTouchDown = 0;
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001955 int err = setScreenStateLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001956 if (err == 0) {
Mike Lockwood435eb642009-12-03 08:40:18 -05001957 mScreenOffReason = reason;
1958 sendNotificationLocked(false, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001959 }
1960 return err;
1961 }
1962
1963 private boolean batteryIsLow() {
1964 return (!mIsPowered &&
Jeff Brown7304c342012-05-11 18:42:42 -07001965 mBatteryService.getBatteryLevel() <= LOW_BATTERY_THRESHOLD);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001966 }
1967
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001968 private boolean shouldDeferScreenOnLocked() {
1969 if (mPreparingForScreenOn) {
1970 // Currently waiting for confirmation from the policy that it
1971 // is okay to turn on the screen. Don't allow the screen to go
1972 // on until that is done.
1973 if (DEBUG_SCREEN_ON) Slog.i(TAG,
1974 "updateLights: delaying screen on due to mPreparingForScreenOn");
1975 return true;
1976 } else {
1977 // If there is a screen-on command in the notification queue, we
1978 // can't turn the screen on until it has been processed (and we
1979 // have set mPreparingForScreenOn) or it has been dropped.
1980 for (int i=0; i<mBroadcastQueue.length; i++) {
1981 if (mBroadcastQueue[i] == 1) {
1982 if (DEBUG_SCREEN_ON) Slog.i(TAG,
1983 "updateLights: delaying screen on due to notification queue");
1984 return true;
1985 }
1986 }
1987 }
1988 return false;
1989 }
1990
The Android Open Source Project10592532009-03-18 17:39:46 -07001991 private void updateLightsLocked(int newState, int forceState) {
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07001992 final int oldState = mPowerState;
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001993
1994 // If the screen is not currently on, we will want to delay actually
1995 // turning the lights on if we are still getting the UI put up.
Jim Miller92e66dd2012-02-21 18:57:12 -08001996 if ((oldState & SCREEN_ON_BIT) == 0 || mSkippedScreenOn) {
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001997 // Don't turn screen on until we know we are really ready to.
1998 // This is to avoid letting the screen go on before things like the
1999 // lock screen have been displayed.
Jim Miller92e66dd2012-02-21 18:57:12 -08002000 if ((mSkippedScreenOn = shouldDeferScreenOnLocked())) {
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07002001 newState &= ~(SCREEN_ON_BIT|SCREEN_BRIGHT_BIT);
2002 }
2003 }
2004
Joe Onorato60607a902010-10-23 14:49:30 -07002005 if ((newState & SCREEN_ON_BIT) != 0) {
2006 // Only turn on the buttons or keyboard if the screen is also on.
2007 // We should never see the buttons on but not the screen.
2008 newState = applyButtonState(newState);
2009 newState = applyKeyboardState(newState);
2010 }
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07002011 final int realDifference = (newState ^ oldState);
2012 final int difference = realDifference | forceState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002013 if (difference == 0) {
The Android Open Source Project10592532009-03-18 17:39:46 -07002014 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002015 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002016
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002017 int offMask = 0;
2018 int dimMask = 0;
2019 int onMask = 0;
2020
2021 int preferredBrightness = getPreferredBrightness();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002022
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002023 if ((difference & KEYBOARD_BRIGHT_BIT) != 0) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002024 if ((newState & KEYBOARD_BRIGHT_BIT) == 0) {
2025 offMask |= KEYBOARD_BRIGHT_BIT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002026 } else {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002027 onMask |= KEYBOARD_BRIGHT_BIT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002028 }
2029 }
2030
2031 if ((difference & BUTTON_BRIGHT_BIT) != 0) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002032 if ((newState & BUTTON_BRIGHT_BIT) == 0) {
2033 offMask |= BUTTON_BRIGHT_BIT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002034 } else {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002035 onMask |= BUTTON_BRIGHT_BIT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002036 }
2037 }
2038
2039 if ((difference & (SCREEN_ON_BIT | SCREEN_BRIGHT_BIT)) != 0) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002040 int nominalCurrentValue = -1;
2041 // If there was an actual difference in the light state, then
2042 // figure out the "ideal" current value based on the previous
2043 // state. Otherwise, this is a change due to the brightness
2044 // override, so we want to animate from whatever the current
2045 // value is.
2046 if ((realDifference & (SCREEN_ON_BIT | SCREEN_BRIGHT_BIT)) != 0) {
2047 switch (oldState & (SCREEN_BRIGHT_BIT|SCREEN_ON_BIT)) {
2048 case SCREEN_BRIGHT_BIT | SCREEN_ON_BIT:
2049 nominalCurrentValue = preferredBrightness;
2050 break;
2051 case SCREEN_ON_BIT:
Mike Lockwoodeb6456b2011-09-13 15:24:02 -04002052 nominalCurrentValue = mScreenBrightnessDim;
Joe Onoratob08a1af2010-10-11 19:28:58 -07002053 break;
2054 case 0:
Jeff Brown7304c342012-05-11 18:42:42 -07002055 nominalCurrentValue = PowerManager.BRIGHTNESS_OFF;
Joe Onoratob08a1af2010-10-11 19:28:58 -07002056 break;
2057 case SCREEN_BRIGHT_BIT:
2058 default:
2059 // not possible
Jim Miller92e66dd2012-02-21 18:57:12 -08002060 nominalCurrentValue = (int)mScreenBrightnessAnimator.getCurrentBrightness();
Joe Onoratob08a1af2010-10-11 19:28:58 -07002061 break;
Joe Onorato128e7292009-03-24 18:41:31 -07002062 }
Joe Onoratob08a1af2010-10-11 19:28:58 -07002063 }
2064 int brightness = preferredBrightness;
2065 int steps = ANIM_STEPS;
2066 if ((newState & SCREEN_BRIGHT_BIT) == 0) {
2067 // dim or turn off backlight, depending on if the screen is on
2068 // the scale is because the brightness ramp isn't linear and this biases
2069 // it so the later parts take longer.
2070 final float scale = 1.5f;
Mike Lockwoodeb6456b2011-09-13 15:24:02 -04002071 float ratio = (((float)mScreenBrightnessDim)/preferredBrightness);
Joe Onoratob08a1af2010-10-11 19:28:58 -07002072 if (ratio > 1.0f) ratio = 1.0f;
2073 if ((newState & SCREEN_ON_BIT) == 0) {
2074 if ((oldState & SCREEN_BRIGHT_BIT) != 0) {
2075 // was bright
2076 steps = ANIM_STEPS;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002077 } else {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002078 // was dim
2079 steps = (int)(ANIM_STEPS*ratio*scale);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002080 }
Jeff Brown7304c342012-05-11 18:42:42 -07002081 brightness = PowerManager.BRIGHTNESS_OFF;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002082 } else {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002083 if ((oldState & SCREEN_ON_BIT) != 0) {
2084 // was bright
2085 steps = (int)(ANIM_STEPS*(1.0f-ratio)*scale);
2086 } else {
2087 // was dim
2088 steps = (int)(ANIM_STEPS*ratio);
2089 }
2090 if (mStayOnConditions != 0 && mBatteryService.isPowered(mStayOnConditions)) {
2091 // If the "stay on while plugged in" option is
2092 // turned on, then the screen will often not
2093 // automatically turn off while plugged in. To
2094 // still have a sense of when it is inactive, we
2095 // will then count going dim as turning off.
2096 mScreenOffTime = SystemClock.elapsedRealtime();
2097 }
Mike Lockwoodeb6456b2011-09-13 15:24:02 -04002098 brightness = mScreenBrightnessDim;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002099 }
2100 }
Joe Onoratob08a1af2010-10-11 19:28:58 -07002101 long identity = Binder.clearCallingIdentity();
2102 try {
2103 mBatteryStats.noteScreenBrightness(brightness);
2104 } catch (RemoteException e) {
2105 // Nothing interesting to do.
2106 } finally {
2107 Binder.restoreCallingIdentity(identity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002108 }
Dianne Hackborn81de8b92011-11-28 16:54:31 -08002109 if (!mSkippedScreenOn) {
Jim Miller92e66dd2012-02-21 18:57:12 -08002110 int dt = steps * NOMINAL_FRAME_TIME_MS;
2111 mScreenBrightnessAnimator.animateTo(brightness, SCREEN_BRIGHT_BIT, dt);
Dianne Hackborn81de8b92011-11-28 16:54:31 -08002112 if (DEBUG_SCREEN_ON) {
2113 RuntimeException e = new RuntimeException("here");
2114 e.fillInStackTrace();
2115 Slog.i(TAG, "Setting screen brightness: " + brightness, e);
2116 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07002117 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002118 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002119
Joe Onorato60607a902010-10-23 14:49:30 -07002120 if (mSpew) {
2121 Slog.d(TAG, "offMask=0x" + Integer.toHexString(offMask)
2122 + " dimMask=0x" + Integer.toHexString(dimMask)
2123 + " onMask=0x" + Integer.toHexString(onMask)
2124 + " difference=0x" + Integer.toHexString(difference)
2125 + " realDifference=0x" + Integer.toHexString(realDifference)
2126 + " forceState=0x" + Integer.toHexString(forceState)
2127 );
2128 }
2129
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002130 if (offMask != 0) {
Mike Lockwood48358bd2010-04-17 22:29:20 -04002131 if (mSpew) Slog.i(TAG, "Setting brightess off: " + offMask);
Jeff Brown7304c342012-05-11 18:42:42 -07002132 setLightBrightness(offMask, PowerManager.BRIGHTNESS_OFF);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002133 }
2134 if (dimMask != 0) {
Mike Lockwoodeb6456b2011-09-13 15:24:02 -04002135 int brightness = mScreenBrightnessDim;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002136 if ((newState & BATTERY_LOW_BIT) != 0 &&
Jeff Brown7304c342012-05-11 18:42:42 -07002137 brightness > PowerManager.BRIGHTNESS_LOW_BATTERY) {
2138 brightness = PowerManager.BRIGHTNESS_LOW_BATTERY;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002139 }
Mike Lockwood48358bd2010-04-17 22:29:20 -04002140 if (mSpew) Slog.i(TAG, "Setting brightess dim " + brightness + ": " + dimMask);
The Android Open Source Project10592532009-03-18 17:39:46 -07002141 setLightBrightness(dimMask, brightness);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002142 }
2143 if (onMask != 0) {
2144 int brightness = getPreferredBrightness();
2145 if ((newState & BATTERY_LOW_BIT) != 0 &&
Jeff Brown7304c342012-05-11 18:42:42 -07002146 brightness > PowerManager.BRIGHTNESS_LOW_BATTERY) {
2147 brightness = PowerManager.BRIGHTNESS_LOW_BATTERY;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002148 }
Mike Lockwood48358bd2010-04-17 22:29:20 -04002149 if (mSpew) Slog.i(TAG, "Setting brightess on " + brightness + ": " + onMask);
The Android Open Source Project10592532009-03-18 17:39:46 -07002150 setLightBrightness(onMask, brightness);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002151 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002152 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002153
Jim Miller92e66dd2012-02-21 18:57:12 -08002154 /**
2155 * Note: by design this class does not hold mLocks while calling native methods.
2156 * Nor should it. Ever.
2157 */
2158 class ScreenBrightnessAnimator extends HandlerThread {
2159 static final int ANIMATE_LIGHTS = 10;
Jim Miller46f31c32012-03-01 14:36:07 -08002160 static final int ANIMATE_POWER_OFF = 11;
Jim Miller92e66dd2012-02-21 18:57:12 -08002161 volatile int startValue;
2162 volatile int endValue;
Craig Mautner196943f2012-05-15 08:10:35 -07002163 volatile int startSensorValue;
2164 volatile int endSensorValue;
Jim Miller92e66dd2012-02-21 18:57:12 -08002165 volatile int currentValue;
2166 private int currentMask;
2167 private int duration;
2168 private long startTimeMillis;
2169 private final String prefix;
2170
2171 public ScreenBrightnessAnimator(String name, int priority) {
2172 super(name, priority);
2173 prefix = name;
2174 }
2175
2176 @Override
2177 protected void onLooperPrepared() {
2178 mScreenBrightnessHandler = new Handler() {
2179 public void handleMessage(Message msg) {
2180 int brightnessMode = (mAutoBrightessEnabled && !mInitialAnimation
Mike Lockwood3a322132009-11-24 00:30:52 -05002181 ? LightsService.BRIGHTNESS_MODE_SENSOR
2182 : LightsService.BRIGHTNESS_MODE_USER);
Jim Miller92e66dd2012-02-21 18:57:12 -08002183 if (msg.what == ANIMATE_LIGHTS) {
2184 final int mask = msg.arg1;
2185 int value = msg.arg2;
2186 long tStart = SystemClock.uptimeMillis();
2187 if ((mask & SCREEN_BRIGHT_BIT) != 0) {
Craig Mautner196943f2012-05-15 08:10:35 -07002188 if (mDebugLightAnimation) Slog.v(TAG, "Set brightness: " + value);
Jim Miller92e66dd2012-02-21 18:57:12 -08002189 mLcdLight.setBrightness(value, brightnessMode);
2190 }
2191 long elapsed = SystemClock.uptimeMillis() - tStart;
2192 if ((mask & BUTTON_BRIGHT_BIT) != 0) {
2193 mButtonLight.setBrightness(value);
2194 }
2195 if ((mask & KEYBOARD_BRIGHT_BIT) != 0) {
2196 mKeyboardLight.setBrightness(value);
2197 }
2198
2199 if (elapsed > 100) {
Craig Mautner196943f2012-05-15 08:10:35 -07002200 Slog.e(TAG, "Excessive delay setting brightness: " + elapsed
Jim Miller92e66dd2012-02-21 18:57:12 -08002201 + "ms, mask=" + mask);
2202 }
2203
2204 // Throttle brightness updates to frame refresh rate
Craig Mautner196943f2012-05-15 08:10:35 -07002205 int delay = elapsed < NOMINAL_FRAME_TIME_MS ? NOMINAL_FRAME_TIME_MS : 1;
Jim Miller92e66dd2012-02-21 18:57:12 -08002206 synchronized(this) {
2207 currentValue = value;
2208 }
2209 animateInternal(mask, false, delay);
Jim Miller46f31c32012-03-01 14:36:07 -08002210 } else if (msg.what == ANIMATE_POWER_OFF) {
2211 int mode = msg.arg1;
2212 nativeStartSurfaceFlingerAnimation(mode);
Jim Miller92e66dd2012-02-21 18:57:12 -08002213 }
2214 }
2215 };
2216 synchronized (this) {
2217 mInitComplete = true;
2218 notifyAll();
Dianne Hackborn81de8b92011-11-28 16:54:31 -08002219 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002220 }
Jim Miller92e66dd2012-02-21 18:57:12 -08002221
2222 private void animateInternal(int mask, boolean turningOff, int delay) {
2223 synchronized (this) {
2224 if (currentValue != endValue) {
2225 final long now = SystemClock.elapsedRealtime();
2226 final int elapsed = (int) (now - startTimeMillis);
2227 int newValue;
2228 if (elapsed < duration) {
2229 int delta = endValue - startValue;
2230 newValue = startValue + delta * elapsed / duration;
Jeff Brown7304c342012-05-11 18:42:42 -07002231 newValue = Math.max(PowerManager.BRIGHTNESS_OFF, newValue);
2232 newValue = Math.min(PowerManager.BRIGHTNESS_ON, newValue);
Craig Mautner196943f2012-05-15 08:10:35 -07002233 // Optimization to delay next step until a change will occur.
2234 if (delay > 0 && newValue == currentValue) {
2235 final int timePerStep = duration / Math.abs(delta);
2236 delay = Math.min(duration - elapsed, timePerStep);
2237 newValue += delta < 0 ? -1 : 1;
2238 }
2239 // adjust the peak sensor value until we get to the target sensor value
2240 delta = endSensorValue - startSensorValue;
2241 mHighestLightSensorValue = startSensorValue + delta * elapsed / duration;
Jim Miller92e66dd2012-02-21 18:57:12 -08002242 } else {
2243 newValue = endValue;
Craig Mautner196943f2012-05-15 08:10:35 -07002244 mHighestLightSensorValue = endSensorValue;
Jim Miller92e66dd2012-02-21 18:57:12 -08002245 mInitialAnimation = false;
2246 }
2247
2248 if (mDebugLightAnimation) {
Craig Mautner196943f2012-05-15 08:10:35 -07002249 Slog.v(TAG, "Animating light: " + "start:" + startValue
Jim Miller92e66dd2012-02-21 18:57:12 -08002250 + ", end:" + endValue + ", elapsed:" + elapsed
2251 + ", duration:" + duration + ", current:" + currentValue
Craig Mautner196943f2012-05-15 08:10:35 -07002252 + ", newValue:" + newValue
2253 + ", delay:" + delay
2254 + ", highestSensor:" + mHighestLightSensorValue);
Jim Miller92e66dd2012-02-21 18:57:12 -08002255 }
2256
Jim Miller46f31c32012-03-01 14:36:07 -08002257 if (turningOff && !mHeadless && !mAnimateScreenLights) {
Jim Miller92e66dd2012-02-21 18:57:12 -08002258 int mode = mScreenOffReason == OFF_BECAUSE_OF_PROX_SENSOR
2259 ? 0 : mAnimationSetting;
Craig Mautner196943f2012-05-15 08:10:35 -07002260 if (mDebugLightAnimation) {
2261 Slog.v(TAG, "Doing power-off anim, mode=" + mode);
2262 }
Jim Miller46f31c32012-03-01 14:36:07 -08002263 mScreenBrightnessHandler.obtainMessage(ANIMATE_POWER_OFF, mode, 0)
2264 .sendToTarget();
Jim Miller92e66dd2012-02-21 18:57:12 -08002265 }
Craig Mautner196943f2012-05-15 08:10:35 -07002266 mScreenBrightnessHandler.removeMessages(
2267 ScreenBrightnessAnimator.ANIMATE_LIGHTS);
Jim Miller92e66dd2012-02-21 18:57:12 -08002268 Message msg = mScreenBrightnessHandler
2269 .obtainMessage(ANIMATE_LIGHTS, mask, newValue);
2270 mScreenBrightnessHandler.sendMessageDelayed(msg, delay);
2271 }
2272 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002273 }
Jim Miller92e66dd2012-02-21 18:57:12 -08002274
2275 public void dump(PrintWriter pw, String string) {
2276 pw.println(prefix + "animating: " + "start:" + startValue + ", end:" + endValue
2277 + ", duration:" + duration + ", current:" + currentValue);
2278 }
2279
2280 public void animateTo(int target, int mask, int animationDuration) {
Craig Mautner196943f2012-05-15 08:10:35 -07002281 animateTo(target, mHighestLightSensorValue, mask, animationDuration);
2282 }
2283
2284 public void animateTo(int target, int sensorTarget, int mask, int animationDuration) {
Jim Miller92e66dd2012-02-21 18:57:12 -08002285 synchronized(this) {
2286 startValue = currentValue;
2287 endValue = target;
Craig Mautner196943f2012-05-15 08:10:35 -07002288 startSensorValue = mHighestLightSensorValue;
2289 endSensorValue = sensorTarget;
Jim Miller92e66dd2012-02-21 18:57:12 -08002290 currentMask = mask;
2291 duration = (int) (mWindowScaleAnimation * animationDuration);
2292 startTimeMillis = SystemClock.elapsedRealtime();
2293 mInitialAnimation = currentValue == 0 && target > 0;
2294
2295 if (mDebugLightAnimation) {
Craig Mautner196943f2012-05-15 08:10:35 -07002296 Slog.v(TAG, "animateTo(target=" + target
2297 + ", sensor=" + sensorTarget
2298 + ", mask=" + mask
Jim Miller92e66dd2012-02-21 18:57:12 -08002299 + ", duration=" + animationDuration +")"
2300 + ", currentValue=" + currentValue
2301 + ", startTime=" + startTimeMillis);
2302 }
2303
2304 if (target != currentValue) {
Jim Miller18651802012-03-07 14:19:56 -08002305 final boolean doScreenAnim = (mask & (SCREEN_BRIGHT_BIT | SCREEN_ON_BIT)) != 0;
Jeff Brown7304c342012-05-11 18:42:42 -07002306 final boolean turningOff = endValue == PowerManager.BRIGHTNESS_OFF;
Jim Miller18651802012-03-07 14:19:56 -08002307 if (turningOff && doScreenAnim) {
Jim Miller92e66dd2012-02-21 18:57:12 -08002308 // Cancel all pending animations since we're turning off
2309 mScreenBrightnessHandler.removeCallbacksAndMessages(null);
2310 screenOffFinishedAnimatingLocked(mScreenOffReason);
2311 duration = 200; // TODO: how long should this be?
2312 }
Jim Miller18651802012-03-07 14:19:56 -08002313 if (doScreenAnim) {
2314 animateInternal(mask, turningOff, 0);
2315 }
2316 // TODO: Handle keyboard light animation when we have devices that support it
Jim Miller92e66dd2012-02-21 18:57:12 -08002317 }
2318 }
2319 }
2320
2321 public int getCurrentBrightness() {
2322 synchronized (this) {
2323 return currentValue;
2324 }
2325 }
2326
2327 public boolean isAnimating() {
2328 synchronized (this) {
2329 return currentValue != endValue;
2330 }
2331 }
2332
2333 public void cancelAnimation() {
2334 animateTo(endValue, currentMask, 0);
The Android Open Source Project10592532009-03-18 17:39:46 -07002335 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002336 }
2337
Jim Miller92e66dd2012-02-21 18:57:12 -08002338 private void setLightBrightness(int mask, int value) {
2339 mScreenBrightnessAnimator.animateTo(value, mask, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002340 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002341
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002342 private int getPreferredBrightness() {
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002343 if (mScreenBrightnessOverride >= 0) {
2344 return mScreenBrightnessOverride;
2345 } else if (mLightSensorScreenBrightness >= 0 && mUseSoftwareAutoBrightness
2346 && mAutoBrightessEnabled) {
2347 return mLightSensorScreenBrightness;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002348 }
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002349 final int brightness = mScreenBrightnessSetting;
2350 // Don't let applications turn the screen all the way off
2351 return Math.max(brightness, mScreenBrightnessDim);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002352 }
2353
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002354 private int applyButtonState(int state) {
2355 int brightness = -1;
Mike Lockwood48358bd2010-04-17 22:29:20 -04002356 if ((state & BATTERY_LOW_BIT) != 0) {
2357 // do not override brightness if the battery is low
2358 return state;
2359 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002360 if (mButtonBrightnessOverride >= 0) {
2361 brightness = mButtonBrightnessOverride;
2362 } else if (mLightSensorButtonBrightness >= 0 && mUseSoftwareAutoBrightness) {
2363 brightness = mLightSensorButtonBrightness;
2364 }
2365 if (brightness > 0) {
2366 return state | BUTTON_BRIGHT_BIT;
2367 } else if (brightness == 0) {
2368 return state & ~BUTTON_BRIGHT_BIT;
2369 } else {
2370 return state;
2371 }
2372 }
2373
2374 private int applyKeyboardState(int state) {
2375 int brightness = -1;
Mike Lockwood48358bd2010-04-17 22:29:20 -04002376 if ((state & BATTERY_LOW_BIT) != 0) {
2377 // do not override brightness if the battery is low
2378 return state;
2379 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002380 if (!mKeyboardVisible) {
2381 brightness = 0;
2382 } else if (mButtonBrightnessOverride >= 0) {
2383 brightness = mButtonBrightnessOverride;
2384 } else if (mLightSensorKeyboardBrightness >= 0 && mUseSoftwareAutoBrightness) {
2385 brightness = mLightSensorKeyboardBrightness;
2386 }
2387 if (brightness > 0) {
2388 return state | KEYBOARD_BRIGHT_BIT;
2389 } else if (brightness == 0) {
2390 return state & ~KEYBOARD_BRIGHT_BIT;
2391 } else {
2392 return state;
2393 }
2394 }
2395
Charles Mendis322591c2009-10-29 11:06:59 -07002396 public boolean isScreenOn() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002397 synchronized (mLocks) {
2398 return (mPowerState & SCREEN_ON_BIT) != 0;
2399 }
2400 }
2401
Charles Mendis322591c2009-10-29 11:06:59 -07002402 boolean isScreenBright() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002403 synchronized (mLocks) {
2404 return (mPowerState & SCREEN_BRIGHT) == SCREEN_BRIGHT;
2405 }
2406 }
2407
Mike Lockwood497087e32009-11-08 18:33:03 -05002408 private boolean isScreenTurningOffLocked() {
Jim Miller92e66dd2012-02-21 18:57:12 -08002409 return (mScreenBrightnessAnimator.isAnimating()
Jeff Brown7304c342012-05-11 18:42:42 -07002410 && mScreenBrightnessAnimator.endValue == PowerManager.BRIGHTNESS_OFF);
Mike Lockwood497087e32009-11-08 18:33:03 -05002411 }
2412
Joe Onorato4b9f62d2010-10-11 13:41:35 -07002413 private boolean shouldLog(long time) {
2414 synchronized (mLocks) {
2415 if (time > (mWarningSpewThrottleTime + (60*60*1000))) {
2416 mWarningSpewThrottleTime = time;
2417 mWarningSpewThrottleCount = 0;
2418 return true;
2419 } else if (mWarningSpewThrottleCount < 30) {
2420 mWarningSpewThrottleCount++;
2421 return true;
2422 } else {
2423 return false;
2424 }
2425 }
2426 }
2427
Mike Lockwood200b30b2009-09-20 00:23:59 -04002428 private void forceUserActivityLocked() {
Mike Lockwoode090281422009-11-14 21:02:56 -05002429 if (isScreenTurningOffLocked()) {
2430 // cancel animation so userActivity will succeed
Jim Miller92e66dd2012-02-21 18:57:12 -08002431 mScreenBrightnessAnimator.cancelAnimation();
Mike Lockwoode090281422009-11-14 21:02:56 -05002432 }
Mike Lockwood200b30b2009-09-20 00:23:59 -04002433 boolean savedActivityAllowed = mUserActivityAllowed;
2434 mUserActivityAllowed = true;
2435 userActivity(SystemClock.uptimeMillis(), false);
2436 mUserActivityAllowed = savedActivityAllowed;
2437 }
2438
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002439 public void userActivityWithForce(long time, boolean noChangeLights, boolean force) {
2440 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
Joe Onorato7999bff2010-07-24 11:50:05 -04002441 userActivity(time, -1, noChangeLights, OTHER_EVENT, force);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002442 }
2443
2444 public void userActivity(long time, boolean noChangeLights) {
Joe Onorato4b9f62d2010-10-11 13:41:35 -07002445 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER)
2446 != PackageManager.PERMISSION_GRANTED) {
2447 if (shouldLog(time)) {
2448 Slog.w(TAG, "Caller does not have DEVICE_POWER permission. pid="
2449 + Binder.getCallingPid() + " uid=" + Binder.getCallingUid());
2450 }
2451 return;
2452 }
2453
Joe Onorato7999bff2010-07-24 11:50:05 -04002454 userActivity(time, -1, noChangeLights, OTHER_EVENT, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002455 }
2456
2457 public void userActivity(long time, boolean noChangeLights, int eventType) {
Joe Onorato7999bff2010-07-24 11:50:05 -04002458 userActivity(time, -1, noChangeLights, eventType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002459 }
2460
2461 public void userActivity(long time, boolean noChangeLights, int eventType, boolean force) {
Joe Onorato7999bff2010-07-24 11:50:05 -04002462 userActivity(time, -1, noChangeLights, eventType, force);
2463 }
2464
2465 /*
2466 * Reset the user activity timeout to now + timeout. This overrides whatever else is going
2467 * on with user activity. Don't use this function.
2468 */
2469 public void clearUserActivityTimeout(long now, long timeout) {
2470 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
2471 Slog.i(TAG, "clearUserActivity for " + timeout + "ms from now");
2472 userActivity(now, timeout, false, OTHER_EVENT, false);
2473 }
2474
2475 private void userActivity(long time, long timeoutOverride, boolean noChangeLights,
2476 int eventType, boolean force) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002477
Joe Onorato1a542c72010-11-08 09:48:20 -08002478 if (((mPokey & POKE_LOCK_IGNORE_TOUCH_EVENTS) != 0) && (eventType == TOUCH_EVENT)) {
Joe Onoratoe68ffcb2009-03-24 19:11:13 -07002479 if (false) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002480 Slog.d(TAG, "dropping touch mPokey=0x" + Integer.toHexString(mPokey));
Joe Onoratoe68ffcb2009-03-24 19:11:13 -07002481 }
2482 return;
2483 }
2484
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002485 synchronized (mLocks) {
2486 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002487 Slog.d(TAG, "userActivity mLastEventTime=" + mLastEventTime + " time=" + time
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002488 + " mUserActivityAllowed=" + mUserActivityAllowed
2489 + " mUserState=0x" + Integer.toHexString(mUserState)
Mike Lockwood36fc3022009-08-25 16:49:06 -07002490 + " mWakeLockState=0x" + Integer.toHexString(mWakeLockState)
2491 + " mProximitySensorActive=" + mProximitySensorActive
Joe Onorato797e6882010-08-26 14:46:01 -04002492 + " timeoutOverride=" + timeoutOverride
Mike Lockwood36fc3022009-08-25 16:49:06 -07002493 + " force=" + force);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002494 }
Mike Lockwood05067122009-10-27 23:07:25 -04002495 // ignore user activity if we are in the process of turning off the screen
Mike Lockwood497087e32009-11-08 18:33:03 -05002496 if (isScreenTurningOffLocked()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002497 Slog.d(TAG, "ignoring user activity while turning off screen");
Mike Lockwood05067122009-10-27 23:07:25 -04002498 return;
2499 }
Mike Lockwood0e39ea82009-11-18 15:37:10 -05002500 // Disable proximity sensor if if user presses power key while we are in the
2501 // "waiting for proximity sensor to go negative" state.
2502 if (mProximitySensorActive && mProximityWakeLockCount == 0) {
2503 mProximitySensorActive = false;
2504 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002505 if (mLastEventTime <= time || force) {
2506 mLastEventTime = time;
Mike Lockwood36fc3022009-08-25 16:49:06 -07002507 if ((mUserActivityAllowed && !mProximitySensorActive) || force) {
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002508 // Only turn on button backlights if a button was pressed
2509 // and auto brightness is disabled
Mike Lockwood4984e732009-11-01 08:16:33 -05002510 if (eventType == BUTTON_EVENT && !mUseSoftwareAutoBrightness) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002511 mUserState = (mKeyboardVisible ? ALL_BRIGHT : SCREEN_BUTTON_BRIGHT);
2512 } else {
2513 // don't clear button/keyboard backlights when the screen is touched.
2514 mUserState |= SCREEN_BRIGHT;
2515 }
2516
Dianne Hackborn617f8772009-03-31 15:04:46 -07002517 int uid = Binder.getCallingUid();
2518 long ident = Binder.clearCallingIdentity();
2519 try {
2520 mBatteryStats.noteUserActivity(uid, eventType);
2521 } catch (RemoteException e) {
2522 // Ignore
2523 } finally {
2524 Binder.restoreCallingIdentity(ident);
2525 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002526
Michael Chane96440f2009-05-06 10:27:36 -07002527 mWakeLockState = mLocks.reactivateScreenLocksLocked();
Mike Lockwood435eb642009-12-03 08:40:18 -05002528 setPowerState(mUserState | mWakeLockState, noChangeLights,
2529 WindowManagerPolicy.OFF_BECAUSE_OF_USER);
Joe Onorato7999bff2010-07-24 11:50:05 -04002530 setTimeoutLocked(time, timeoutOverride, SCREEN_BRIGHT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002531 }
2532 }
2533 }
Mike Lockwoodef731622010-01-27 17:51:34 -05002534
2535 if (mPolicy != null) {
2536 mPolicy.userActivity();
2537 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002538 }
2539
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002540 private int getAutoBrightnessValue(int sensorValue, int[] values) {
2541 try {
2542 int i;
2543 for (i = 0; i < mAutoBrightnessLevels.length; i++) {
2544 if (sensorValue < mAutoBrightnessLevels[i]) {
2545 break;
2546 }
2547 }
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002548 // This is the range of brightness values that we can use.
2549 final int minval = values[0];
2550 final int maxval = values[mAutoBrightnessLevels.length];
2551 // This is the range we will be scaling. We put some padding
2552 // at the low and high end to give the adjustment a little better
2553 // impact on the actual observed value.
2554 final int range = (maxval-minval) + LIGHT_SENSOR_RANGE_EXPANSION;
2555 // This is the desired brightness value from 0.0 to 1.0.
2556 float valf = ((values[i]-minval+(LIGHT_SENSOR_RANGE_EXPANSION/2))/(float)range);
2557 // Apply a scaling to the value based on the adjustment.
2558 if (mLightSensorAdjustSetting > 0 && mLightSensorAdjustSetting <= 1) {
2559 float adj = (float)Math.sqrt(1.0f-mLightSensorAdjustSetting);
2560 if (adj <= .00001) {
2561 valf = 1;
2562 } else {
2563 valf /= adj;
2564 }
2565 } else if (mLightSensorAdjustSetting < 0 && mLightSensorAdjustSetting >= -1) {
2566 float adj = (float)Math.sqrt(1.0f+mLightSensorAdjustSetting);
2567 valf *= adj;
2568 }
2569 // Apply an additional offset to the value based on the adjustment.
2570 valf += mLightSensorAdjustSetting/LIGHT_SENSOR_OFFSET_SCALE;
2571 // Convert the 0.0-1.0 value back to a brightness integer.
2572 int val = (int)((valf*range)+minval) - (LIGHT_SENSOR_RANGE_EXPANSION/2);
2573 if (val < minval) val = minval;
2574 else if (val > maxval) val = maxval;
2575 return val;
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002576 } catch (Exception e) {
2577 // guard against null pointer or index out of bounds errors
Jeff Browndaa37532012-05-01 15:54:03 -07002578 Slog.e(TAG, "Values array must be non-empty and must be one element longer than "
2579 + "the auto-brightness levels array. Check config.xml.", e);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002580 return 255;
2581 }
2582 }
2583
Mike Lockwood20f87d72009-11-05 16:08:51 -05002584 private Runnable mProximityTask = new Runnable() {
2585 public void run() {
2586 synchronized (mLocks) {
2587 if (mProximityPendingValue != -1) {
2588 proximityChangedLocked(mProximityPendingValue == 1);
2589 mProximityPendingValue = -1;
2590 }
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -05002591 if (mProximityPartialLock.isHeld()) {
2592 mProximityPartialLock.release();
2593 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05002594 }
2595 }
2596 };
2597
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002598 private Runnable mAutoBrightnessTask = new Runnable() {
2599 public void run() {
Mike Lockwoodfa68ab42009-10-20 11:08:49 -04002600 synchronized (mLocks) {
Jim Rodovichd102fea2010-09-02 12:30:49 -05002601 if (mLightSensorPendingDecrease || mLightSensorPendingIncrease) {
2602 int value = (int)mLightSensorPendingValue;
2603 mLightSensorPendingDecrease = false;
2604 mLightSensorPendingIncrease = false;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002605 lightSensorChangedLocked(value, false);
Mike Lockwoodfa68ab42009-10-20 11:08:49 -04002606 }
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002607 }
2608 }
2609 };
2610
Jim Miller92e66dd2012-02-21 18:57:12 -08002611 private boolean mInitialAnimation; // used to prevent lightsensor changes while turning on
2612
Mike Lockwoodb2865412010-02-02 22:40:33 -05002613 private void dockStateChanged(int state) {
2614 synchronized (mLocks) {
2615 mIsDocked = (state != Intent.EXTRA_DOCK_STATE_UNDOCKED);
2616 if (mIsDocked) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04002617 // allow brightness to decrease when docked
Mike Lockwoodb2865412010-02-02 22:40:33 -05002618 mHighestLightSensorValue = -1;
2619 }
2620 if ((mPowerState & SCREEN_ON_BIT) != 0) {
2621 // force lights recalculation
2622 int value = (int)mLightSensorValue;
2623 mLightSensorValue = -1;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002624 lightSensorChangedLocked(value, false);
Mike Lockwoodb2865412010-02-02 22:40:33 -05002625 }
2626 }
2627 }
2628
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002629 private void lightSensorChangedLocked(int value, boolean immediate) {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002630 if (mDebugLightSensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002631 Slog.d(TAG, "lightSensorChangedLocked " + value);
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002632 }
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002633
Joe Onorato06eb33a2010-10-25 14:09:21 -07002634 // Don't do anything if the screen is off.
2635 if ((mPowerState & SCREEN_ON_BIT) == 0) {
2636 if (mDebugLightSensor) {
2637 Slog.d(TAG, "dropping lightSensorChangedLocked because screen is off");
2638 }
2639 return;
2640 }
2641
Craig Mautner196943f2012-05-15 08:10:35 -07002642 final int stepsToTargetLevel;
2643 if (mHighestLightSensorValue <= value) {
2644 stepsToTargetLevel = AUTOBRIGHTNESS_ANIM_STEPS;
2645 } else {
2646 stepsToTargetLevel = AUTODIMNESS_ANIM_STEPS;
Mike Lockwoodb2865412010-02-02 22:40:33 -05002647 }
2648
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002649 if (mLightSensorValue != value) {
2650 mLightSensorValue = value;
2651 if ((mPowerState & BATTERY_LOW_BIT) == 0) {
Mike Lockwoodb2865412010-02-02 22:40:33 -05002652 // use maximum light sensor value seen since screen went on for LCD to avoid flicker
2653 // we only do this if we are undocked, since lighting should be stable when
2654 // stationary in a dock.
Craig Mautner196943f2012-05-15 08:10:35 -07002655 int lcdValue = getAutoBrightnessValue(value, mLcdBacklightValues);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002656 int buttonValue = getAutoBrightnessValue(value, mButtonBacklightValues);
Mike Lockwooddf024922009-10-29 21:29:15 -04002657 int keyboardValue;
2658 if (mKeyboardVisible) {
2659 keyboardValue = getAutoBrightnessValue(value, mKeyboardBacklightValues);
2660 } else {
2661 keyboardValue = 0;
2662 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002663 mLightSensorScreenBrightness = lcdValue;
2664 mLightSensorButtonBrightness = buttonValue;
2665 mLightSensorKeyboardBrightness = keyboardValue;
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002666
2667 if (mDebugLightSensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002668 Slog.d(TAG, "lcdValue " + lcdValue);
2669 Slog.d(TAG, "buttonValue " + buttonValue);
2670 Slog.d(TAG, "keyboardValue " + keyboardValue);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002671 }
2672
Mike Lockwood4984e732009-11-01 08:16:33 -05002673 if (mAutoBrightessEnabled && mScreenBrightnessOverride < 0) {
Jim Miller92e66dd2012-02-21 18:57:12 -08002674 if (!mSkippedScreenOn && !mInitialAnimation) {
Craig Mautner196943f2012-05-15 08:10:35 -07002675 int steps = immediate ? IMMEDIATE_ANIM_STEPS : stepsToTargetLevel;
2676 mScreenBrightnessAnimator.animateTo(lcdValue, value,
Jim Miller92e66dd2012-02-21 18:57:12 -08002677 SCREEN_BRIGHT_BIT, steps * NOMINAL_FRAME_TIME_MS);
Dianne Hackborn81de8b92011-11-28 16:54:31 -08002678 }
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002679 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002680 if (mButtonBrightnessOverride < 0) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002681 mButtonLight.setBrightness(buttonValue);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002682 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002683 if (mButtonBrightnessOverride < 0 || !mKeyboardVisible) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002684 mKeyboardLight.setBrightness(keyboardValue);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002685 }
2686 }
2687 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002688 }
2689
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002690 /**
2691 * The user requested that we go to sleep (probably with the power button).
2692 * This overrides all wake locks that are held.
2693 */
2694 public void goToSleep(long time)
2695 {
Dianne Hackborn254cb442010-01-27 19:23:59 -08002696 goToSleepWithReason(time, WindowManagerPolicy.OFF_BECAUSE_OF_USER);
2697 }
2698
2699 /**
2700 * The user requested that we go to sleep (probably with the power button).
2701 * This overrides all wake locks that are held.
2702 */
2703 public void goToSleepWithReason(long time, int reason)
2704 {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002705 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
2706 synchronized (mLocks) {
Dianne Hackborn254cb442010-01-27 19:23:59 -08002707 goToSleepLocked(time, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002708 }
2709 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002710
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002711 /**
Doug Zongker50a21f42009-11-19 12:49:53 -08002712 * Reboot the device immediately, passing 'reason' (may be null)
2713 * to the underlying __reboot system call. Should not return.
2714 */
2715 public void reboot(String reason)
2716 {
2717 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
San Mehat14e69af2010-01-06 14:58:18 -08002718
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002719 if (mHandler == null || !ActivityManagerNative.isSystemReady()) {
2720 throw new IllegalStateException("Too early to call reboot()");
2721 }
Mike Lockwoodb62f9592010-03-12 07:55:23 -05002722
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002723 final String finalReason = reason;
2724 Runnable runnable = new Runnable() {
2725 public void run() {
2726 synchronized (this) {
2727 ShutdownThread.reboot(mContext, finalReason, false);
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002728 }
Jim Miller92e66dd2012-02-21 18:57:12 -08002729
San Mehat1e512792010-01-07 10:40:29 -08002730 }
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002731 };
Mike Lockwoodb62f9592010-03-12 07:55:23 -05002732 // ShutdownThread must run on a looper capable of displaying the UI.
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002733 mHandler.post(runnable);
2734
Mike Lockwoodb62f9592010-03-12 07:55:23 -05002735 // PowerManager.reboot() is documented not to return so just wait for the inevitable.
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002736 synchronized (runnable) {
Mike Lockwoodb62f9592010-03-12 07:55:23 -05002737 while (true) {
2738 try {
2739 runnable.wait();
2740 } catch (InterruptedException e) {
2741 }
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002742 }
Doug Zongker50a21f42009-11-19 12:49:53 -08002743 }
2744 }
2745
Dan Egnor60d87622009-12-16 16:32:58 -08002746 /**
2747 * Crash the runtime (causing a complete restart of the Android framework).
2748 * Requires REBOOT permission. Mostly for testing. Should not return.
2749 */
2750 public void crash(final String message)
2751 {
2752 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
2753 Thread t = new Thread("PowerManagerService.crash()") {
2754 public void run() { throw new RuntimeException(message); }
2755 };
2756 try {
2757 t.start();
2758 t.join();
2759 } catch (InterruptedException e) {
2760 Log.wtf(TAG, e);
2761 }
2762 }
2763
Mike Lockwood435eb642009-12-03 08:40:18 -05002764 private void goToSleepLocked(long time, int reason) {
Jeff Browna75fe052012-05-01 18:41:26 -07002765 if (mSpew) {
2766 Exception ex = new Exception();
2767 ex.fillInStackTrace();
2768 Slog.d(TAG, "goToSleep mLastEventTime=" + mLastEventTime + " time=" + time
2769 + " reason=" + reason, ex);
2770 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002771
2772 if (mLastEventTime <= time) {
2773 mLastEventTime = time;
2774 // cancel all of the wake locks
2775 mWakeLockState = SCREEN_OFF;
2776 int N = mLocks.size();
2777 int numCleared = 0;
Joe Onorato8274a0e2010-10-05 17:38:09 -04002778 boolean proxLock = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002779 for (int i=0; i<N; i++) {
2780 WakeLock wl = mLocks.get(i);
2781 if (isScreenLock(wl.flags)) {
Joe Onorato8274a0e2010-10-05 17:38:09 -04002782 if (((wl.flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)
2783 && reason == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR) {
2784 proxLock = true;
2785 } else {
2786 mLocks.get(i).activated = false;
2787 numCleared++;
2788 }
2789 }
2790 }
2791 if (!proxLock) {
2792 mProxIgnoredBecauseScreenTurnedOff = true;
2793 if (mDebugProximitySensor) {
2794 Slog.d(TAG, "setting mProxIgnoredBecauseScreenTurnedOff");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002795 }
2796 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002797 EventLog.writeEvent(EventLogTags.POWER_SLEEP_REQUESTED, numCleared);
Joe Onorato128e7292009-03-24 18:41:31 -07002798 mStillNeedSleepNotification = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002799 mUserState = SCREEN_OFF;
Mike Lockwood435eb642009-12-03 08:40:18 -05002800 setPowerState(SCREEN_OFF, false, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002801 cancelTimerLocked();
2802 }
2803 }
2804
2805 public long timeSinceScreenOn() {
2806 synchronized (mLocks) {
2807 if ((mPowerState & SCREEN_ON_BIT) != 0) {
2808 return 0;
2809 }
2810 return SystemClock.elapsedRealtime() - mScreenOffTime;
2811 }
2812 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002813
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002814 public void setKeyboardVisibility(boolean visible) {
Mike Lockwooda625b382009-09-12 17:36:03 -07002815 synchronized (mLocks) {
2816 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002817 Slog.d(TAG, "setKeyboardVisibility: " + visible);
Mike Lockwooda625b382009-09-12 17:36:03 -07002818 }
Mike Lockwood3c9435a2009-10-22 15:45:37 -04002819 if (mKeyboardVisible != visible) {
2820 mKeyboardVisible = visible;
2821 // don't signal user activity if the screen is off; other code
2822 // will take care of turning on due to a true change to the lid
2823 // switch and synchronized with the lock screen.
2824 if ((mPowerState & SCREEN_ON_BIT) != 0) {
Mike Lockwood4984e732009-11-01 08:16:33 -05002825 if (mUseSoftwareAutoBrightness) {
Mike Lockwooddf024922009-10-29 21:29:15 -04002826 // force recompute of backlight values
2827 if (mLightSensorValue >= 0) {
2828 int value = (int)mLightSensorValue;
2829 mLightSensorValue = -1;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002830 lightSensorChangedLocked(value, false);
Mike Lockwooddf024922009-10-29 21:29:15 -04002831 }
2832 }
Mike Lockwood3c9435a2009-10-22 15:45:37 -04002833 userActivity(SystemClock.uptimeMillis(), false, BUTTON_EVENT, true);
2834 }
Mike Lockwooda625b382009-09-12 17:36:03 -07002835 }
2836 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002837 }
2838
2839 /**
2840 * When the keyguard is up, it manages the power state, and userActivity doesn't do anything.
Mike Lockwood50c548d2009-11-09 16:02:06 -05002841 * When disabling user activity we also reset user power state so the keyguard can reset its
2842 * short screen timeout when keyguard is unhidden.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002843 */
2844 public void enableUserActivity(boolean enabled) {
Mike Lockwood50c548d2009-11-09 16:02:06 -05002845 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002846 Slog.d(TAG, "enableUserActivity " + enabled);
Mike Lockwood50c548d2009-11-09 16:02:06 -05002847 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002848 synchronized (mLocks) {
2849 mUserActivityAllowed = enabled;
Mike Lockwood50c548d2009-11-09 16:02:06 -05002850 if (!enabled) {
2851 // cancel timeout and clear mUserState so the keyguard can set a short timeout
2852 setTimeoutLocked(SystemClock.uptimeMillis(), 0);
2853 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002854 }
2855 }
2856
Mike Lockwooddc3494e2009-10-14 21:17:09 -07002857 private void setScreenBrightnessMode(int mode) {
Joe Onoratod28f7532010-11-06 12:56:53 -07002858 synchronized (mLocks) {
2859 boolean enabled = (mode == SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
2860 if (mUseSoftwareAutoBrightness && mAutoBrightessEnabled != enabled) {
2861 mAutoBrightessEnabled = enabled;
2862 // This will get us a new value
2863 enableLightSensorLocked(mAutoBrightessEnabled && isScreenOn());
Mike Lockwood2d155d22009-10-27 09:32:30 -04002864 }
Mike Lockwooddc3494e2009-10-14 21:17:09 -07002865 }
2866 }
2867
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002868 /** Sets the screen off timeouts:
2869 * mKeylightDelay
2870 * mDimDelay
2871 * mScreenOffDelay
2872 * */
2873 private void setScreenOffTimeoutsLocked() {
2874 if ((mPokey & POKE_LOCK_SHORT_TIMEOUT) != 0) {
Doug Zongker43866e02010-01-07 12:09:54 -08002875 mKeylightDelay = mShortKeylightDelay; // Configurable via secure settings
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002876 mDimDelay = -1;
2877 mScreenOffDelay = 0;
2878 } else if ((mPokey & POKE_LOCK_MEDIUM_TIMEOUT) != 0) {
2879 mKeylightDelay = MEDIUM_KEYLIGHT_DELAY;
2880 mDimDelay = -1;
2881 mScreenOffDelay = 0;
2882 } else {
Dianne Hackborndf83afa2010-01-20 13:37:26 -08002883 int totalDelay = mScreenOffTimeoutSetting;
2884 if (totalDelay > mMaximumScreenOffTimeout) {
2885 totalDelay = mMaximumScreenOffTimeout;
2886 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002887 mKeylightDelay = LONG_KEYLIGHT_DELAY;
2888 if (totalDelay < 0) {
Jim Millerbc4603b2010-08-30 21:21:34 -07002889 // negative number means stay on as long as possible.
2890 mScreenOffDelay = mMaximumScreenOffTimeout;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002891 } else if (mKeylightDelay < totalDelay) {
2892 // subtract the time that the keylight delay. This will give us the
2893 // remainder of the time that we need to sleep to get the accurate
2894 // screen off timeout.
2895 mScreenOffDelay = totalDelay - mKeylightDelay;
2896 } else {
2897 mScreenOffDelay = 0;
2898 }
2899 if (mDimScreen && totalDelay >= (LONG_KEYLIGHT_DELAY + LONG_DIM_TIME)) {
2900 mDimDelay = mScreenOffDelay - LONG_DIM_TIME;
2901 mScreenOffDelay = LONG_DIM_TIME;
2902 } else {
2903 mDimDelay = -1;
2904 }
2905 }
2906 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002907 Slog.d(TAG, "setScreenOffTimeouts mKeylightDelay=" + mKeylightDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002908 + " mDimDelay=" + mDimDelay + " mScreenOffDelay=" + mScreenOffDelay
2909 + " mDimScreen=" + mDimScreen);
2910 }
2911 }
2912
2913 /**
Doug Zongker43866e02010-01-07 12:09:54 -08002914 * Refreshes cached secure settings. Called once on startup, and
2915 * on subsequent changes to secure settings.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002916 */
Doug Zongker43866e02010-01-07 12:09:54 -08002917 private void updateSettingsValues() {
2918 mShortKeylightDelay = Settings.Secure.getInt(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002919 mContext.getContentResolver(),
Doug Zongker43866e02010-01-07 12:09:54 -08002920 Settings.Secure.SHORT_KEYLIGHT_DELAY_MS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002921 SHORT_KEYLIGHT_DELAY_DEFAULT);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002922 // Slog.i(TAG, "updateSettingsValues(): mShortKeylightDelay now " + mShortKeylightDelay);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002923 }
2924
2925 private class LockList extends ArrayList<WakeLock>
2926 {
2927 void addLock(WakeLock wl)
2928 {
2929 int index = getIndex(wl.binder);
2930 if (index < 0) {
2931 this.add(wl);
2932 }
2933 }
2934
2935 WakeLock removeLock(IBinder binder)
2936 {
2937 int index = getIndex(binder);
2938 if (index >= 0) {
2939 return this.remove(index);
2940 } else {
2941 return null;
2942 }
2943 }
2944
2945 int getIndex(IBinder binder)
2946 {
2947 int N = this.size();
2948 for (int i=0; i<N; i++) {
2949 if (this.get(i).binder == binder) {
2950 return i;
2951 }
2952 }
2953 return -1;
2954 }
2955
2956 int gatherState()
2957 {
2958 int result = 0;
2959 int N = this.size();
2960 for (int i=0; i<N; i++) {
2961 WakeLock wl = this.get(i);
2962 if (wl.activated) {
2963 if (isScreenLock(wl.flags)) {
2964 result |= wl.minState;
2965 }
2966 }
2967 }
2968 return result;
2969 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002970
Michael Chane96440f2009-05-06 10:27:36 -07002971 int reactivateScreenLocksLocked()
2972 {
2973 int result = 0;
2974 int N = this.size();
2975 for (int i=0; i<N; i++) {
2976 WakeLock wl = this.get(i);
2977 if (isScreenLock(wl.flags)) {
2978 wl.activated = true;
2979 result |= wl.minState;
2980 }
2981 }
Joe Onorato8274a0e2010-10-05 17:38:09 -04002982 if (mDebugProximitySensor) {
2983 Slog.d(TAG, "reactivateScreenLocksLocked mProxIgnoredBecauseScreenTurnedOff="
2984 + mProxIgnoredBecauseScreenTurnedOff);
2985 }
2986 mProxIgnoredBecauseScreenTurnedOff = false;
Michael Chane96440f2009-05-06 10:27:36 -07002987 return result;
2988 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002989 }
2990
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08002991 public void setPolicy(WindowManagerPolicy p) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002992 synchronized (mLocks) {
2993 mPolicy = p;
2994 mLocks.notifyAll();
2995 }
2996 }
2997
2998 WindowManagerPolicy getPolicyLocked() {
2999 while (mPolicy == null || !mDoneBooting) {
3000 try {
3001 mLocks.wait();
3002 } catch (InterruptedException e) {
3003 // Ignore
3004 }
3005 }
3006 return mPolicy;
3007 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003008
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003009 void systemReady() {
Jeff Brown25157e42012-04-16 12:13:05 -07003010 mSensorManager = new SystemSensorManager(mHandlerThread.getLooper());
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003011 mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
3012 // don't bother with the light sensor if auto brightness is handled in hardware
Mike Lockwoodaa66ea82009-10-31 16:31:27 -04003013 if (mUseSoftwareAutoBrightness) {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003014 mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003015 }
3016
Mike Lockwoodb42ab0f2010-03-04 08:02:44 -05003017 // wait until sensors are enabled before turning on screen.
3018 // some devices will not activate the light sensor properly on boot
3019 // unless we do this.
3020 if (mUseSoftwareAutoBrightness) {
3021 // turn the screen on
3022 setPowerState(SCREEN_BRIGHT);
3023 } else {
3024 // turn everything on
3025 setPowerState(ALL_BRIGHT);
3026 }
3027
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003028 synchronized (mLocks) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003029 Slog.d(TAG, "system ready!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003030 mDoneBooting = true;
Mike Lockwoodb42ab0f2010-03-04 08:02:44 -05003031
Joe Onoratod28f7532010-11-06 12:56:53 -07003032 enableLightSensorLocked(mUseSoftwareAutoBrightness && mAutoBrightessEnabled);
3033
Dianne Hackborn617f8772009-03-31 15:04:46 -07003034 long identity = Binder.clearCallingIdentity();
3035 try {
3036 mBatteryStats.noteScreenBrightness(getPreferredBrightness());
3037 mBatteryStats.noteScreenOn();
3038 } catch (RemoteException e) {
3039 // Nothing interesting to do.
3040 } finally {
3041 Binder.restoreCallingIdentity(identity);
3042 }
Mike Lockwood2d7bb812009-11-15 18:12:22 -05003043 }
3044 }
3045
3046 void bootCompleted() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003047 Slog.d(TAG, "bootCompleted");
Mike Lockwood2d7bb812009-11-15 18:12:22 -05003048 synchronized (mLocks) {
3049 mBootCompleted = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003050 userActivity(SystemClock.uptimeMillis(), false, BUTTON_EVENT, true);
3051 updateWakeLockLocked();
3052 mLocks.notifyAll();
3053 }
3054 }
3055
Joe Onoratob08a1af2010-10-11 19:28:58 -07003056 // for watchdog
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003057 public void monitor() {
3058 synchronized (mLocks) { }
3059 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003060
3061 public int getSupportedWakeLockFlags() {
3062 int result = PowerManager.PARTIAL_WAKE_LOCK
3063 | PowerManager.FULL_WAKE_LOCK
3064 | PowerManager.SCREEN_DIM_WAKE_LOCK;
3065
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003066 if (mProximitySensor != null) {
3067 result |= PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK;
3068 }
3069
3070 return result;
3071 }
3072
Mike Lockwood237a2992009-09-15 14:42:16 -04003073 public void setBacklightBrightness(int brightness) {
3074 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
3075 // Don't let applications turn the screen all the way off
Joe Onoratob08a1af2010-10-11 19:28:58 -07003076 synchronized (mLocks) {
Mike Lockwoodeb6456b2011-09-13 15:24:02 -04003077 brightness = Math.max(brightness, mScreenBrightnessDim);
Joe Onoratob08a1af2010-10-11 19:28:58 -07003078 mLcdLight.setBrightness(brightness);
3079 mKeyboardLight.setBrightness(mKeyboardVisible ? brightness : 0);
3080 mButtonLight.setBrightness(brightness);
3081 long identity = Binder.clearCallingIdentity();
3082 try {
3083 mBatteryStats.noteScreenBrightness(brightness);
3084 } catch (RemoteException e) {
3085 Slog.w(TAG, "RemoteException calling noteScreenBrightness on BatteryStatsService", e);
3086 } finally {
3087 Binder.restoreCallingIdentity(identity);
3088 }
Jim Miller92e66dd2012-02-21 18:57:12 -08003089 mScreenBrightnessAnimator.animateTo(brightness, SCREEN_BRIGHT_BIT, 0);
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08003090 }
3091 }
3092
3093 public void setAutoBrightnessAdjustment(float adj) {
3094 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
3095 synchronized (mLocks) {
3096 mLightSensorAdjustSetting = adj;
3097 if (mSensorManager != null && mLightSensorEnabled) {
3098 // clear calling identity so sensor manager battery stats are accurate
3099 long identity = Binder.clearCallingIdentity();
3100 try {
3101 // force recompute of backlight values
3102 if (mLightSensorValue >= 0) {
3103 int value = (int)mLightSensorValue;
3104 mLightSensorValue = -1;
3105 handleLightSensorValue(value, true);
3106 }
3107 } finally {
3108 Binder.restoreCallingIdentity(identity);
3109 }
Joe Onorato3d3db602010-10-18 16:08:16 -04003110 }
Mike Lockwood237a2992009-09-15 14:42:16 -04003111 }
3112 }
3113
Mike Lockwoodb11832d2009-11-25 15:25:55 -05003114 public void setAttentionLight(boolean on, int color) {
3115 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
Mike Lockwood3cb67a32009-11-27 14:25:58 -05003116 mAttentionLight.setFlashing(color, LightsService.LIGHT_FLASH_HARDWARE, (on ? 3 : 0), 0);
Mike Lockwoodb11832d2009-11-25 15:25:55 -05003117 }
3118
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003119 private void enableProximityLockLocked() {
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003120 if (mDebugProximitySensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003121 Slog.d(TAG, "enableProximityLockLocked");
Mike Lockwood36fc3022009-08-25 16:49:06 -07003122 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003123 if (!mProximitySensorEnabled) {
3124 // clear calling identity so sensor manager battery stats are accurate
3125 long identity = Binder.clearCallingIdentity();
3126 try {
3127 mSensorManager.registerListener(mProximityListener, mProximitySensor,
3128 SensorManager.SENSOR_DELAY_NORMAL);
3129 mProximitySensorEnabled = true;
3130 } finally {
3131 Binder.restoreCallingIdentity(identity);
3132 }
Mike Lockwood809ad0f2009-10-26 22:10:33 -04003133 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003134 }
3135
3136 private void disableProximityLockLocked() {
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003137 if (mDebugProximitySensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003138 Slog.d(TAG, "disableProximityLockLocked");
Mike Lockwood36fc3022009-08-25 16:49:06 -07003139 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003140 if (mProximitySensorEnabled) {
3141 // clear calling identity so sensor manager battery stats are accurate
3142 long identity = Binder.clearCallingIdentity();
3143 try {
3144 mSensorManager.unregisterListener(mProximityListener);
3145 mHandler.removeCallbacks(mProximityTask);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -05003146 if (mProximityPartialLock.isHeld()) {
3147 mProximityPartialLock.release();
3148 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003149 mProximitySensorEnabled = false;
3150 } finally {
3151 Binder.restoreCallingIdentity(identity);
3152 }
3153 if (mProximitySensorActive) {
3154 mProximitySensorActive = false;
Joe Onorato8274a0e2010-10-05 17:38:09 -04003155 if (mDebugProximitySensor) {
3156 Slog.d(TAG, "disableProximityLockLocked mProxIgnoredBecauseScreenTurnedOff="
3157 + mProxIgnoredBecauseScreenTurnedOff);
3158 }
3159 if (!mProxIgnoredBecauseScreenTurnedOff) {
3160 forceUserActivityLocked();
3161 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003162 }
Mike Lockwood200b30b2009-09-20 00:23:59 -04003163 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003164 }
3165
Mike Lockwood20f87d72009-11-05 16:08:51 -05003166 private void proximityChangedLocked(boolean active) {
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003167 if (mDebugProximitySensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003168 Slog.d(TAG, "proximityChangedLocked, active: " + active);
Mike Lockwood20f87d72009-11-05 16:08:51 -05003169 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003170 if (!mProximitySensorEnabled) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003171 Slog.d(TAG, "Ignoring proximity change after sensor is disabled");
Mike Lockwood0d72f7e2009-11-05 20:53:00 -05003172 return;
3173 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05003174 if (active) {
Joe Onorato8274a0e2010-10-05 17:38:09 -04003175 if (mDebugProximitySensor) {
3176 Slog.d(TAG, "b mProxIgnoredBecauseScreenTurnedOff="
3177 + mProxIgnoredBecauseScreenTurnedOff);
3178 }
3179 if (!mProxIgnoredBecauseScreenTurnedOff) {
3180 goToSleepLocked(SystemClock.uptimeMillis(),
3181 WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR);
3182 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05003183 mProximitySensorActive = true;
3184 } else {
3185 // proximity sensor negative events trigger as user activity.
3186 // temporarily set mUserActivityAllowed to true so this will work
3187 // even when the keyguard is on.
3188 mProximitySensorActive = false;
Joe Onorato8274a0e2010-10-05 17:38:09 -04003189 if (mDebugProximitySensor) {
3190 Slog.d(TAG, "b mProxIgnoredBecauseScreenTurnedOff="
3191 + mProxIgnoredBecauseScreenTurnedOff);
3192 }
3193 if (!mProxIgnoredBecauseScreenTurnedOff) {
3194 forceUserActivityLocked();
3195 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003196
3197 if (mProximityWakeLockCount == 0) {
3198 // disable sensor if we have no listeners left after proximity negative
3199 disableProximityLockLocked();
3200 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05003201 }
3202 }
3203
Joe Onoratod28f7532010-11-06 12:56:53 -07003204 private void enableLightSensorLocked(boolean enable) {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003205 if (mDebugLightSensor) {
Joe Onoratod28f7532010-11-06 12:56:53 -07003206 Slog.d(TAG, "enableLightSensorLocked enable=" + enable
3207 + " mAutoBrightessEnabled=" + mAutoBrightessEnabled);
3208 }
3209 if (!mAutoBrightessEnabled) {
3210 enable = false;
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003211 }
3212 if (mSensorManager != null && mLightSensorEnabled != enable) {
3213 mLightSensorEnabled = enable;
Mike Lockwood809ad0f2009-10-26 22:10:33 -04003214 // clear calling identity so sensor manager battery stats are accurate
3215 long identity = Binder.clearCallingIdentity();
3216 try {
3217 if (enable) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003218 // reset our highest value when reenabling
3219 mHighestLightSensorValue = -1;
3220 // force recompute of backlight values
3221 if (mLightSensorValue >= 0) {
3222 int value = (int)mLightSensorValue;
3223 mLightSensorValue = -1;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08003224 handleLightSensorValue(value, true);
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003225 }
Mike Lockwood809ad0f2009-10-26 22:10:33 -04003226 mSensorManager.registerListener(mLightListener, mLightSensor,
Mathias Agopian47f1fe52011-11-08 17:18:41 -08003227 LIGHT_SENSOR_RATE);
Mike Lockwood809ad0f2009-10-26 22:10:33 -04003228 } else {
3229 mSensorManager.unregisterListener(mLightListener);
3230 mHandler.removeCallbacks(mAutoBrightnessTask);
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003231 mLightSensorPendingDecrease = false;
3232 mLightSensorPendingIncrease = false;
Mike Lockwood809ad0f2009-10-26 22:10:33 -04003233 }
3234 } finally {
3235 Binder.restoreCallingIdentity(identity);
Mike Lockwood06952d92009-08-13 16:05:38 -04003236 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003237 }
3238 }
3239
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003240 SensorEventListener mProximityListener = new SensorEventListener() {
3241 public void onSensorChanged(SensorEvent event) {
Mike Lockwoodba8eb1e2009-11-08 19:31:18 -05003242 long milliseconds = SystemClock.elapsedRealtime();
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003243 synchronized (mLocks) {
3244 float distance = event.values[0];
Mike Lockwood20f87d72009-11-05 16:08:51 -05003245 long timeSinceLastEvent = milliseconds - mLastProximityEventTime;
3246 mLastProximityEventTime = milliseconds;
3247 mHandler.removeCallbacks(mProximityTask);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -05003248 boolean proximityTaskQueued = false;
Mike Lockwood20f87d72009-11-05 16:08:51 -05003249
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003250 // compare against getMaximumRange to support sensors that only return 0 or 1
Mike Lockwood20f87d72009-11-05 16:08:51 -05003251 boolean active = (distance >= 0.0 && distance < PROXIMITY_THRESHOLD &&
3252 distance < mProximitySensor.getMaximumRange());
3253
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003254 if (mDebugProximitySensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003255 Slog.d(TAG, "mProximityListener.onSensorChanged active: " + active);
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003256 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05003257 if (timeSinceLastEvent < PROXIMITY_SENSOR_DELAY) {
3258 // enforce delaying atleast PROXIMITY_SENSOR_DELAY before processing
3259 mProximityPendingValue = (active ? 1 : 0);
3260 mHandler.postDelayed(mProximityTask, PROXIMITY_SENSOR_DELAY - timeSinceLastEvent);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -05003261 proximityTaskQueued = true;
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003262 } else {
Mike Lockwood20f87d72009-11-05 16:08:51 -05003263 // process the value immediately
3264 mProximityPendingValue = -1;
3265 proximityChangedLocked(active);
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003266 }
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -05003267
3268 // update mProximityPartialLock state
3269 boolean held = mProximityPartialLock.isHeld();
3270 if (!held && proximityTaskQueued) {
3271 // hold wakelock until mProximityTask runs
3272 mProximityPartialLock.acquire();
3273 } else if (held && !proximityTaskQueued) {
3274 mProximityPartialLock.release();
3275 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003276 }
3277 }
3278
3279 public void onAccuracyChanged(Sensor sensor, int accuracy) {
3280 // ignore
3281 }
3282 };
3283
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08003284 private void handleLightSensorValue(int value, boolean immediate) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003285 long milliseconds = SystemClock.elapsedRealtime();
3286 if (mLightSensorValue == -1 ||
3287 milliseconds < mLastScreenOnTime + mLightSensorWarmupTime) {
3288 // process the value immediately if screen has just turned on
3289 mHandler.removeCallbacks(mAutoBrightnessTask);
3290 mLightSensorPendingDecrease = false;
3291 mLightSensorPendingIncrease = false;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08003292 lightSensorChangedLocked(value, immediate);
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003293 } else {
3294 if ((value > mLightSensorValue && mLightSensorPendingDecrease) ||
3295 (value < mLightSensorValue && mLightSensorPendingIncrease) ||
3296 (value == mLightSensorValue) ||
3297 (!mLightSensorPendingDecrease && !mLightSensorPendingIncrease)) {
3298 // delay processing to debounce the sensor
3299 mHandler.removeCallbacks(mAutoBrightnessTask);
3300 mLightSensorPendingDecrease = (value < mLightSensorValue);
3301 mLightSensorPendingIncrease = (value > mLightSensorValue);
3302 if (mLightSensorPendingDecrease || mLightSensorPendingIncrease) {
3303 mLightSensorPendingValue = value;
3304 mHandler.postDelayed(mAutoBrightnessTask, LIGHT_SENSOR_DELAY);
3305 }
3306 } else {
3307 mLightSensorPendingValue = value;
3308 }
3309 }
3310 }
3311
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003312 SensorEventListener mLightListener = new SensorEventListener() {
3313 public void onSensorChanged(SensorEvent event) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003314 if (mDebugLightSensor) {
3315 Slog.d(TAG, "onSensorChanged: light value: " + event.values[0]);
3316 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003317 synchronized (mLocks) {
Mike Lockwood497087e32009-11-08 18:33:03 -05003318 // ignore light sensor while screen is turning off
3319 if (isScreenTurningOffLocked()) {
3320 return;
3321 }
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08003322 handleLightSensorValue((int)event.values[0], false);
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003323 }
3324 }
3325
3326 public void onAccuracyChanged(Sensor sensor, int accuracy) {
3327 // ignore
3328 }
3329 };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003330}