blob: 07665f4c84006c5ed7a3ee79bca09ea9345f781f [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 Mautnera4e96d52012-06-06 14:49:44 -0700181 // Even slower animation for autodimness changes. Set to max to effectively disable dimming.
182 // Note 100 is used to keep the mWindowScaleAnimation scaling below from overflowing an int.
183 static final int AUTODIMNESS_ANIM_STEPS = Integer.MAX_VALUE / (NOMINAL_FRAME_TIME_MS * 100);
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800184 // Number of steps when performing a more immediate brightness change.
185 static final int IMMEDIATE_ANIM_STEPS = 4;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186
187 // These magic numbers are the initial state of the LEDs at boot. Ideally
188 // we should read them from the driver, but our current hardware returns 0
189 // for the initial value. Oops!
190 static final int INITIAL_SCREEN_BRIGHTNESS = 255;
Jeff Brown7304c342012-05-11 18:42:42 -0700191 static final int INITIAL_BUTTON_BRIGHTNESS = PowerManager.BRIGHTNESS_OFF;
192 static final int INITIAL_KEYBOARD_BRIGHTNESS = PowerManager.BRIGHTNESS_OFF;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800193
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800194 private final int MY_UID;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700195 private final int MY_PID;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800196
197 private boolean mDoneBooting = false;
Mike Lockwood2d7bb812009-11-15 18:12:22 -0500198 private boolean mBootCompleted = false;
Mike Lockwood3a74bd32011-08-12 13:55:22 -0700199 private boolean mHeadless = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800200 private int mStayOnConditions = 0;
Mike Lockwoodca44df82010-02-25 13:48:49 -0500201 private final int[] mBroadcastQueue = new int[] { -1, -1, -1 };
202 private final int[] mBroadcastWhy = new int[3];
Dianne Hackborn38e29a62011-09-18 14:43:08 -0700203 private boolean mPreparingForScreenOn = false;
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700204 private boolean mSkippedScreenOn = false;
205 private boolean mInitialized = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206 private int mPartialCount = 0;
207 private int mPowerState;
Mike Lockwood435eb642009-12-03 08:40:18 -0500208 // mScreenOffReason can be WindowManagerPolicy.OFF_BECAUSE_OF_USER,
209 // WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT or WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR
210 private int mScreenOffReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211 private int mUserState;
212 private boolean mKeyboardVisible = false;
213 private boolean mUserActivityAllowed = true;
Mike Lockwoodee2b0942009-11-09 14:09:02 -0500214 private int mProximityWakeLockCount = 0;
215 private boolean mProximitySensorEnabled = false;
Mike Lockwood36fc3022009-08-25 16:49:06 -0700216 private boolean mProximitySensorActive = false;
Mike Lockwood20f87d72009-11-05 16:08:51 -0500217 private int mProximityPendingValue = -1; // -1 == nothing, 0 == inactive, 1 == active
218 private long mLastProximityEventTime;
Dianne Hackborndf83afa2010-01-20 13:37:26 -0800219 private int mScreenOffTimeoutSetting;
220 private int mMaximumScreenOffTimeout = Integer.MAX_VALUE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221 private int mKeylightDelay;
222 private int mDimDelay;
223 private int mScreenOffDelay;
224 private int mWakeLockState;
225 private long mLastEventTime = 0;
226 private long mScreenOffTime;
227 private volatile WindowManagerPolicy mPolicy;
228 private final LockList mLocks = new LockList();
229 private Intent mScreenOffIntent;
230 private Intent mScreenOnIntent;
Mike Lockwood3a322132009-11-24 00:30:52 -0500231 private LightsService mLightsService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800232 private Context mContext;
Mike Lockwood3cb67a32009-11-27 14:25:58 -0500233 private LightsService.Light mLcdLight;
234 private LightsService.Light mButtonLight;
235 private LightsService.Light mKeyboardLight;
236 private LightsService.Light mAttentionLight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800237 private UnsynchronizedWakeLock mBroadcastWakeLock;
238 private UnsynchronizedWakeLock mStayOnWhilePluggedInScreenDimLock;
239 private UnsynchronizedWakeLock mStayOnWhilePluggedInPartialLock;
240 private UnsynchronizedWakeLock mPreventScreenOnPartialLock;
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -0500241 private UnsynchronizedWakeLock mProximityPartialLock;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800242 private HandlerThread mHandlerThread;
Joe Onoratob08a1af2010-10-11 19:28:58 -0700243 private Handler mScreenOffHandler;
Jim Miller92e66dd2012-02-21 18:57:12 -0800244 private Handler mScreenBrightnessHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800245 private Handler mHandler;
Mike Lockwoodca44df82010-02-25 13:48:49 -0500246 private final TimeoutTask mTimeoutTask = new TimeoutTask();
Jim Miller92e66dd2012-02-21 18:57:12 -0800247 private ScreenBrightnessAnimator mScreenBrightnessAnimator;
Craig Mautner37933682012-06-06 14:13:39 -0700248 private boolean mWaitingForFirstLightSensor = false;
Joe Onorato128e7292009-03-24 18:41:31 -0700249 private boolean mStillNeedSleepNotification;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250 private boolean mIsPowered = false;
251 private IActivityManager mActivityService;
252 private IBatteryStats mBatteryStats;
253 private BatteryService mBatteryService;
Mike Lockwoodbc706a02009-07-27 13:50:57 -0700254 private SensorManager mSensorManager;
255 private Sensor mProximitySensor;
Mike Lockwood8738e0c2009-10-04 08:44:47 -0400256 private Sensor mLightSensor;
257 private boolean mLightSensorEnabled;
258 private float mLightSensorValue = -1;
Joe Onorato8274a0e2010-10-05 17:38:09 -0400259 private boolean mProxIgnoredBecauseScreenTurnedOff = false;
Mike Lockwoodb2865412010-02-02 22:40:33 -0500260 private int mHighestLightSensorValue = -1;
Jim Rodovichd102fea2010-09-02 12:30:49 -0500261 private boolean mLightSensorPendingDecrease = false;
262 private boolean mLightSensorPendingIncrease = false;
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700263 private float mLightSensorPendingValue = -1;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800264 private float mLightSensorAdjustSetting = 0;
Mike Lockwoodfb73f792009-11-20 11:31:18 -0500265 private int mLightSensorScreenBrightness = -1;
266 private int mLightSensorButtonBrightness = -1;
267 private int mLightSensorKeyboardBrightness = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800268 private boolean mDimScreen = true;
Mike Lockwoodb2865412010-02-02 22:40:33 -0500269 private boolean mIsDocked = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800270 private long mNextTimeout;
271 private volatile int mPokey = 0;
272 private volatile boolean mPokeAwakeOnSet = false;
273 private volatile boolean mInitComplete = false;
Mike Lockwoodca44df82010-02-25 13:48:49 -0500274 private final HashMap<IBinder,PokeLock> mPokeLocks = new HashMap<IBinder,PokeLock>();
Mike Lockwood20ee6f22009-11-07 20:33:47 -0500275 // mLastScreenOnTime is the time the screen was last turned on
276 private long mLastScreenOnTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277 private boolean mPreventScreenOn;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800278 private int mScreenBrightnessSetting = DEFAULT_SCREEN_BRIGHTNESS;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 private int mScreenBrightnessOverride = -1;
Mike Lockwoodfb73f792009-11-20 11:31:18 -0500280 private int mButtonBrightnessOverride = -1;
Mike Lockwoodeb6456b2011-09-13 15:24:02 -0400281 private int mScreenBrightnessDim;
Mike Lockwoodaa66ea82009-10-31 16:31:27 -0400282 private boolean mUseSoftwareAutoBrightness;
Mike Lockwooddc3494e2009-10-14 21:17:09 -0700283 private boolean mAutoBrightessEnabled;
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700284 private int[] mAutoBrightnessLevels;
285 private int[] mLcdBacklightValues;
286 private int[] mButtonBacklightValues;
287 private int[] mKeyboardBacklightValues;
Mike Lockwood20ee6f22009-11-07 20:33:47 -0500288 private int mLightSensorWarmupTime;
Joe Onorato6d747652010-10-11 15:15:31 -0700289 boolean mUnplugTurnsOnScreen;
Joe Onorato4b9f62d2010-10-11 13:41:35 -0700290 private int mWarningSpewThrottleCount;
291 private long mWarningSpewThrottleTime;
Joe Onorato609695d2010-10-14 14:57:49 -0700292 private int mAnimationSetting = ANIM_SETTING_OFF;
Jim Miller92e66dd2012-02-21 18:57:12 -0800293 private float mWindowScaleAnimation;
Joe Onorato609695d2010-10-14 14:57:49 -0700294
295 // Must match with the ISurfaceComposer constants in C++.
296 private static final int ANIM_SETTING_ON = 0x01;
297 private static final int ANIM_SETTING_OFF = 0x10;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800298
299 // Used when logging number and duration of touch-down cycles
300 private long mTotalTouchDownTime;
301 private long mLastTouchDown;
302 private int mTouchCycles;
303
304 // could be either static or controllable at runtime
305 private static final boolean mSpew = false;
Joe Onorato8274a0e2010-10-05 17:38:09 -0400306 private static final boolean mDebugProximitySensor = (false || mSpew);
Mike Lockwoodae92eb32011-10-25 10:11:46 -0400307 private static final boolean mDebugLightSensor = (false || mSpew);
Jim Miller92e66dd2012-02-21 18:57:12 -0800308 private static final boolean mDebugLightAnimation = (false || mSpew);
309
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700310 private native void nativeInit();
311 private native void nativeSetPowerState(boolean screenOn, boolean screenBright);
Joe Onorato609695d2010-10-14 14:57:49 -0700312 private native void nativeStartSurfaceFlingerAnimation(int mode);
Jeff Brown7304c342012-05-11 18:42:42 -0700313 private static native void nativeAcquireWakeLock(int lock, String id);
314 private static native void nativeReleaseWakeLock(String id);
315 private static native int nativeSetScreenState(boolean on);
316 private static native void nativeShutdown();
317 private static native void nativeReboot(String reason) throws IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800318
319 /*
320 static PrintStream mLog;
321 static {
322 try {
323 mLog = new PrintStream("/data/power.log");
324 }
325 catch (FileNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800326 android.util.Slog.e(TAG, "Life is hard", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800327 }
328 }
329 static class Log {
330 static void d(String tag, String s) {
331 mLog.println(s);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800332 android.util.Slog.d(tag, s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800333 }
334 static void i(String tag, String s) {
335 mLog.println(s);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800336 android.util.Slog.i(tag, s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337 }
338 static void w(String tag, String s) {
339 mLog.println(s);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800340 android.util.Slog.w(tag, s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800341 }
342 static void e(String tag, String s) {
343 mLog.println(s);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800344 android.util.Slog.e(tag, s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800345 }
346 }
347 */
348
349 /**
350 * This class works around a deadlock between the lock in PowerManager.WakeLock
351 * and our synchronizing on mLocks. PowerManager.WakeLock synchronizes on its
352 * mToken object so it can be accessed from any thread, but it calls into here
353 * with its lock held. This class is essentially a reimplementation of
354 * PowerManager.WakeLock, but without that extra synchronized block, because we'll
355 * only call it with our own locks held.
356 */
357 private class UnsynchronizedWakeLock {
358 int mFlags;
359 String mTag;
360 IBinder mToken;
361 int mCount = 0;
362 boolean mRefCounted;
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -0500363 boolean mHeld;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800364
365 UnsynchronizedWakeLock(int flags, String tag, boolean refCounted) {
366 mFlags = flags;
367 mTag = tag;
368 mToken = new Binder();
369 mRefCounted = refCounted;
370 }
371
372 public void acquire() {
373 if (!mRefCounted || mCount++ == 0) {
374 long ident = Binder.clearCallingIdentity();
375 try {
376 PowerManagerService.this.acquireWakeLockLocked(mFlags, mToken,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700377 MY_UID, MY_PID, mTag, null);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -0500378 mHeld = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800379 } finally {
380 Binder.restoreCallingIdentity(ident);
381 }
382 }
383 }
384
385 public void release() {
386 if (!mRefCounted || --mCount == 0) {
Mike Lockwood0e39ea82009-11-18 15:37:10 -0500387 PowerManagerService.this.releaseWakeLockLocked(mToken, 0, false);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -0500388 mHeld = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389 }
390 if (mCount < 0) {
391 throw new RuntimeException("WakeLock under-locked " + mTag);
392 }
393 }
394
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -0500395 public boolean isHeld()
396 {
397 return mHeld;
398 }
399
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800400 public String toString() {
401 return "UnsynchronizedWakeLock(mFlags=0x" + Integer.toHexString(mFlags)
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -0500402 + " mCount=" + mCount + " mHeld=" + mHeld + ")";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800403 }
404 }
405
406 private final class BatteryReceiver extends BroadcastReceiver {
407 @Override
408 public void onReceive(Context context, Intent intent) {
409 synchronized (mLocks) {
410 boolean wasPowered = mIsPowered;
411 mIsPowered = mBatteryService.isPowered();
412
413 if (mIsPowered != wasPowered) {
414 // update mStayOnWhilePluggedIn wake lock
415 updateWakeLockLocked();
416
417 // treat plugging and unplugging the devices as a user activity.
418 // users find it disconcerting when they unplug the device
419 // and it shuts off right away.
Mike Lockwood84a89342010-03-01 21:28:58 -0500420 // to avoid turning on the screen when unplugging, we only trigger
421 // user activity when screen was already on.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800422 // temporarily set mUserActivityAllowed to true so this will work
423 // even when the keyguard is on.
Joe Onorato6d747652010-10-11 15:15:31 -0700424 // However, you can also set config_unplugTurnsOnScreen to have it
425 // turn on. Some devices want this because they don't have a
426 // charging LED.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800427 synchronized (mLocks) {
Joe Onorato6d747652010-10-11 15:15:31 -0700428 if (!wasPowered || (mPowerState & SCREEN_ON_BIT) != 0 ||
429 mUnplugTurnsOnScreen) {
Mike Lockwood84a89342010-03-01 21:28:58 -0500430 forceUserActivityLocked();
431 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800432 }
433 }
434 }
435 }
436 }
437
Mike Lockwood2d7bb812009-11-15 18:12:22 -0500438 private final class BootCompletedReceiver extends BroadcastReceiver {
439 @Override
440 public void onReceive(Context context, Intent intent) {
441 bootCompleted();
442 }
443 }
444
Mike Lockwoodb2865412010-02-02 22:40:33 -0500445 private final class DockReceiver extends BroadcastReceiver {
446 @Override
447 public void onReceive(Context context, Intent intent) {
448 int state = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
449 Intent.EXTRA_DOCK_STATE_UNDOCKED);
450 dockStateChanged(state);
451 }
452 }
453
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800454 /**
455 * Set the setting that determines whether the device stays on when plugged in.
456 * The argument is a bit string, with each bit specifying a power source that,
457 * when the device is connected to that source, causes the device to stay on.
458 * See {@link android.os.BatteryManager} for the list of power sources that
459 * can be specified. Current values include {@link android.os.BatteryManager#BATTERY_PLUGGED_AC}
460 * and {@link android.os.BatteryManager#BATTERY_PLUGGED_USB}
461 * @param val an {@code int} containing the bits that specify which power sources
462 * should cause the device to stay on.
463 */
464 public void setStayOnSetting(int val) {
465 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS, null);
466 Settings.System.putInt(mContext.getContentResolver(),
467 Settings.System.STAY_ON_WHILE_PLUGGED_IN, val);
468 }
469
Dianne Hackborndf83afa2010-01-20 13:37:26 -0800470 public void setMaximumScreenOffTimeount(int timeMs) {
471 mContext.enforceCallingOrSelfPermission(
472 android.Manifest.permission.WRITE_SECURE_SETTINGS, null);
473 synchronized (mLocks) {
474 mMaximumScreenOffTimeout = timeMs;
475 // recalculate everything
476 setScreenOffTimeoutsLocked();
477 }
478 }
479
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800480 private class SettingsObserver implements Observer {
Amith Yamasani8b619832010-09-22 16:11:59 -0700481 private int getInt(String name, int defValue) {
482 ContentValues values = mSettings.getValues(name);
483 Integer iVal = values != null ? values.getAsInteger(Settings.System.VALUE) : null;
484 return iVal != null ? iVal : defValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800485 }
486
Joe Onorato609695d2010-10-14 14:57:49 -0700487 private float getFloat(String name, float defValue) {
488 ContentValues values = mSettings.getValues(name);
489 Float fVal = values != null ? values.getAsFloat(Settings.System.VALUE) : null;
490 return fVal != null ? fVal : defValue;
491 }
492
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800493 public void update(Observable o, Object arg) {
494 synchronized (mLocks) {
Amith Yamasani8b619832010-09-22 16:11:59 -0700495 // STAY_ON_WHILE_PLUGGED_IN, default to when plugged into AC
496 mStayOnConditions = getInt(STAY_ON_WHILE_PLUGGED_IN,
497 BatteryManager.BATTERY_PLUGGED_AC);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800498 updateWakeLockLocked();
499
Amith Yamasani8b619832010-09-22 16:11:59 -0700500 // SCREEN_OFF_TIMEOUT, default to 15 seconds
501 mScreenOffTimeoutSetting = getInt(SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800502
Joe Onorato609695d2010-10-14 14:57:49 -0700503 // DIM_SCREEN
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800504 //mDimScreen = getInt(DIM_SCREEN) != 0;
505
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800506 mScreenBrightnessSetting = getInt(SCREEN_BRIGHTNESS, DEFAULT_SCREEN_BRIGHTNESS);
Dianne Hackborn518a3d82012-05-09 16:30:49 -0700507 mLightSensorAdjustSetting = 0; //getFloat(SCREEN_AUTO_BRIGHTNESS_ADJ, 0);
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800508
Amith Yamasani8b619832010-09-22 16:11:59 -0700509 // SCREEN_BRIGHTNESS_MODE, default to manual
510 setScreenBrightnessMode(getInt(SCREEN_BRIGHTNESS_MODE,
511 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL));
Mike Lockwooddc3494e2009-10-14 21:17:09 -0700512
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800513 // recalculate everything
514 setScreenOffTimeoutsLocked();
Joe Onorato609695d2010-10-14 14:57:49 -0700515
Jim Miller92e66dd2012-02-21 18:57:12 -0800516 mWindowScaleAnimation = getFloat(WINDOW_ANIMATION_SCALE, 1.0f);
Joe Onorato609695d2010-10-14 14:57:49 -0700517 final float transitionScale = getFloat(TRANSITION_ANIMATION_SCALE, 1.0f);
518 mAnimationSetting = 0;
Jim Miller92e66dd2012-02-21 18:57:12 -0800519 if (mWindowScaleAnimation > 0.5f) {
Joe Onorato609695d2010-10-14 14:57:49 -0700520 mAnimationSetting |= ANIM_SETTING_OFF;
521 }
522 if (transitionScale > 0.5f) {
523 // Uncomment this if you want the screen-on animation.
524 // mAnimationSetting |= ANIM_SETTING_ON;
525 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800526 }
527 }
528 }
529
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700530 PowerManagerService() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800531 // Hack to get our uid... should have a func for this.
532 long token = Binder.clearCallingIdentity();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700533 MY_UID = Process.myUid();
534 MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800535 Binder.restoreCallingIdentity(token);
536
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800537 // assume nothing is on yet
538 mUserState = mPowerState = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800539
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800540 // Add ourself to the Watchdog monitors.
541 Watchdog.getInstance().addMonitor(this);
Jeff Brown7304c342012-05-11 18:42:42 -0700542
543 nativeInit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800544 }
545
546 private ContentQueryMap mSettings;
547
Mike Lockwood3a322132009-11-24 00:30:52 -0500548 void init(Context context, LightsService lights, IActivityManager activity,
The Android Open Source Project10592532009-03-18 17:39:46 -0700549 BatteryService battery) {
Mike Lockwood3a322132009-11-24 00:30:52 -0500550 mLightsService = lights;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800551 mContext = context;
552 mActivityService = activity;
553 mBatteryStats = BatteryStatsService.getService();
554 mBatteryService = battery;
555
Mike Lockwood3cb67a32009-11-27 14:25:58 -0500556 mLcdLight = lights.getLight(LightsService.LIGHT_ID_BACKLIGHT);
557 mButtonLight = lights.getLight(LightsService.LIGHT_ID_BUTTONS);
558 mKeyboardLight = lights.getLight(LightsService.LIGHT_ID_KEYBOARD);
559 mAttentionLight = lights.getLight(LightsService.LIGHT_ID_ATTENTION);
Mike Lockwood3a74bd32011-08-12 13:55:22 -0700560 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
Mike Lockwood3cb67a32009-11-27 14:25:58 -0500561
Joe Onoratob08a1af2010-10-11 19:28:58 -0700562 mInitComplete = false;
Jim Miller92e66dd2012-02-21 18:57:12 -0800563 mScreenBrightnessAnimator = new ScreenBrightnessAnimator("mScreenBrightnessUpdaterThread",
564 Process.THREAD_PRIORITY_DISPLAY);
565 mScreenBrightnessAnimator.start();
Joe Onoratob08a1af2010-10-11 19:28:58 -0700566
Jim Miller92e66dd2012-02-21 18:57:12 -0800567 synchronized (mScreenBrightnessAnimator) {
Joe Onoratob08a1af2010-10-11 19:28:58 -0700568 while (!mInitComplete) {
569 try {
Jim Miller92e66dd2012-02-21 18:57:12 -0800570 mScreenBrightnessAnimator.wait();
Joe Onoratob08a1af2010-10-11 19:28:58 -0700571 } catch (InterruptedException e) {
572 // Ignore
573 }
574 }
575 }
Jim Miller92e66dd2012-02-21 18:57:12 -0800576
Joe Onoratob08a1af2010-10-11 19:28:58 -0700577 mInitComplete = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800578 mHandlerThread = new HandlerThread("PowerManagerService") {
579 @Override
580 protected void onLooperPrepared() {
581 super.onLooperPrepared();
582 initInThread();
583 }
584 };
585 mHandlerThread.start();
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800586
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800587 synchronized (mHandlerThread) {
588 while (!mInitComplete) {
589 try {
590 mHandlerThread.wait();
591 } catch (InterruptedException e) {
592 // Ignore
593 }
594 }
595 }
Jim Miller92e66dd2012-02-21 18:57:12 -0800596
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700597 synchronized (mLocks) {
598 updateNativePowerStateLocked();
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700599 // We make sure to start out with the screen on due to user activity.
600 // (They did just boot their device, after all.)
601 forceUserActivityLocked();
Dianne Hackborn40011092011-09-22 13:37:48 -0700602 mInitialized = true;
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700603 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800604 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800606 void initInThread() {
607 mHandler = new Handler();
608
609 mBroadcastWakeLock = new UnsynchronizedWakeLock(
Joe Onorato128e7292009-03-24 18:41:31 -0700610 PowerManager.PARTIAL_WAKE_LOCK, "sleep_broadcast", true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800611 mStayOnWhilePluggedInScreenDimLock = new UnsynchronizedWakeLock(
612 PowerManager.SCREEN_DIM_WAKE_LOCK, "StayOnWhilePluggedIn Screen Dim", false);
613 mStayOnWhilePluggedInPartialLock = new UnsynchronizedWakeLock(
614 PowerManager.PARTIAL_WAKE_LOCK, "StayOnWhilePluggedIn Partial", false);
615 mPreventScreenOnPartialLock = new UnsynchronizedWakeLock(
616 PowerManager.PARTIAL_WAKE_LOCK, "PreventScreenOn Partial", false);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -0500617 mProximityPartialLock = new UnsynchronizedWakeLock(
618 PowerManager.PARTIAL_WAKE_LOCK, "Proximity Partial", false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800619
620 mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
621 mScreenOnIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
622 mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF);
623 mScreenOffIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
624
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700625 Resources resources = mContext.getResources();
Mike Lockwoodaa66ea82009-10-31 16:31:27 -0400626
Joe Onoratob08a1af2010-10-11 19:28:58 -0700627 mAnimateScreenLights = resources.getBoolean(
628 com.android.internal.R.bool.config_animateScreenLights);
629
Joe Onorato6d747652010-10-11 15:15:31 -0700630 mUnplugTurnsOnScreen = resources.getBoolean(
631 com.android.internal.R.bool.config_unplugTurnsOnScreen);
632
Mike Lockwoodeb6456b2011-09-13 15:24:02 -0400633 mScreenBrightnessDim = resources.getInteger(
634 com.android.internal.R.integer.config_screenBrightnessDim);
635
Mike Lockwoodaa66ea82009-10-31 16:31:27 -0400636 // read settings for auto-brightness
637 mUseSoftwareAutoBrightness = resources.getBoolean(
638 com.android.internal.R.bool.config_automatic_brightness_available);
Mike Lockwoodaa66ea82009-10-31 16:31:27 -0400639 if (mUseSoftwareAutoBrightness) {
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700640 mAutoBrightnessLevels = resources.getIntArray(
641 com.android.internal.R.array.config_autoBrightnessLevels);
642 mLcdBacklightValues = resources.getIntArray(
643 com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
644 mButtonBacklightValues = resources.getIntArray(
645 com.android.internal.R.array.config_autoBrightnessButtonBacklightValues);
646 mKeyboardBacklightValues = resources.getIntArray(
647 com.android.internal.R.array.config_autoBrightnessKeyboardBacklightValues);
Mike Lockwood20ee6f22009-11-07 20:33:47 -0500648 mLightSensorWarmupTime = resources.getInteger(
649 com.android.internal.R.integer.config_lightSensorWarmupTime);
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700650 }
Mike Lockwooddc3494e2009-10-14 21:17:09 -0700651
652 ContentResolver resolver = mContext.getContentResolver();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800653 Cursor settingsCursor = resolver.query(Settings.System.CONTENT_URI, null,
654 "(" + Settings.System.NAME + "=?) or ("
655 + Settings.System.NAME + "=?) or ("
Mike Lockwooddc3494e2009-10-14 21:17:09 -0700656 + Settings.System.NAME + "=?) or ("
Joe Onorato609695d2010-10-14 14:57:49 -0700657 + Settings.System.NAME + "=?) or ("
658 + Settings.System.NAME + "=?) or ("
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800659 + Settings.System.NAME + "=?) or ("
660 + Settings.System.NAME + "=?) or ("
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800661 + Settings.System.NAME + "=?)",
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800662 new String[]{STAY_ON_WHILE_PLUGGED_IN, SCREEN_OFF_TIMEOUT, DIM_SCREEN, SCREEN_BRIGHTNESS,
Dianne Hackborn518a3d82012-05-09 16:30:49 -0700663 SCREEN_BRIGHTNESS_MODE, /*SCREEN_AUTO_BRIGHTNESS_ADJ,*/
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800664 WINDOW_ANIMATION_SCALE, TRANSITION_ANIMATION_SCALE},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800665 null);
666 mSettings = new ContentQueryMap(settingsCursor, Settings.System.NAME, true, mHandler);
667 SettingsObserver settingsObserver = new SettingsObserver();
668 mSettings.addObserver(settingsObserver);
669
670 // pretend that the settings changed so we will get their initial state
671 settingsObserver.update(mSettings, null);
672
673 // register for the battery changed notifications
674 IntentFilter filter = new IntentFilter();
675 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
676 mContext.registerReceiver(new BatteryReceiver(), filter);
Mike Lockwood2d7bb812009-11-15 18:12:22 -0500677 filter = new IntentFilter();
678 filter.addAction(Intent.ACTION_BOOT_COMPLETED);
679 mContext.registerReceiver(new BootCompletedReceiver(), filter);
Mike Lockwoodb2865412010-02-02 22:40:33 -0500680 filter = new IntentFilter();
681 filter.addAction(Intent.ACTION_DOCK_EVENT);
682 mContext.registerReceiver(new DockReceiver(), filter);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800683
Doug Zongker43866e02010-01-07 12:09:54 -0800684 // Listen for secure settings changes
685 mContext.getContentResolver().registerContentObserver(
686 Settings.Secure.CONTENT_URI, true,
687 new ContentObserver(new Handler()) {
688 public void onChange(boolean selfChange) {
689 updateSettingsValues();
690 }
691 });
692 updateSettingsValues();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800693
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800694 synchronized (mHandlerThread) {
695 mInitComplete = true;
696 mHandlerThread.notifyAll();
697 }
698 }
699
Jeff Brown7304c342012-05-11 18:42:42 -0700700 /**
701 * Low-level function turn the device off immediately, without trying
702 * to be clean. Most people should use
703 * {@link com.android.server.pm.internal.app.ShutdownThread} for a clean shutdown.
704 */
705 public static void lowLevelShutdown() {
706 nativeShutdown();
707 }
708
709 /**
710 * Low-level function to reboot the device.
711 *
712 * @param reason code to pass to the kernel (e.g. "recovery"), or null.
713 * @throws IOException if reboot fails for some reason (eg, lack of
714 * permission)
715 */
716 public static void lowLevelReboot(String reason) throws IOException {
717 nativeReboot(reason);
718 }
719
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800720 private class WakeLock implements IBinder.DeathRecipient
721 {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700722 WakeLock(int f, IBinder b, String t, int u, int p) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800723 super();
724 flags = f;
725 binder = b;
726 tag = t;
727 uid = u == MY_UID ? Process.SYSTEM_UID : u;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700728 pid = p;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800729 if (u != MY_UID || (
730 !"KEEP_SCREEN_ON_FLAG".equals(tag)
731 && !"KeyInputQueue".equals(tag))) {
732 monitorType = (f & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK
733 ? BatteryStats.WAKE_TYPE_PARTIAL
734 : BatteryStats.WAKE_TYPE_FULL;
735 } else {
736 monitorType = -1;
737 }
738 try {
739 b.linkToDeath(this, 0);
740 } catch (RemoteException e) {
741 binderDied();
742 }
743 }
744 public void binderDied() {
745 synchronized (mLocks) {
Mike Lockwood0e39ea82009-11-18 15:37:10 -0500746 releaseWakeLockLocked(this.binder, 0, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800747 }
748 }
749 final int flags;
750 final IBinder binder;
751 final String tag;
752 final int uid;
Mike Lockwoodf5bd0922010-03-22 17:10:15 -0400753 final int pid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800754 final int monitorType;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700755 WorkSource ws;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800756 boolean activated = true;
757 int minState;
758 }
759
760 private void updateWakeLockLocked() {
761 if (mStayOnConditions != 0 && mBatteryService.isPowered(mStayOnConditions)) {
762 // keep the device on if we're plugged in and mStayOnWhilePluggedIn is set.
763 mStayOnWhilePluggedInScreenDimLock.acquire();
764 mStayOnWhilePluggedInPartialLock.acquire();
765 } else {
766 mStayOnWhilePluggedInScreenDimLock.release();
767 mStayOnWhilePluggedInPartialLock.release();
768 }
769 }
770
771 private boolean isScreenLock(int flags)
772 {
773 int n = flags & LOCK_MASK;
774 return n == PowerManager.FULL_WAKE_LOCK
775 || n == PowerManager.SCREEN_BRIGHT_WAKE_LOCK
Joe Onorato8274a0e2010-10-05 17:38:09 -0400776 || n == PowerManager.SCREEN_DIM_WAKE_LOCK
777 || n == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800778 }
779
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700780 void enforceWakeSourcePermission(int uid, int pid) {
781 if (uid == Process.myUid()) {
782 return;
783 }
784 mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
785 pid, uid, null);
786 }
787
788 public void acquireWakeLock(int flags, IBinder lock, String tag, WorkSource ws) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800789 int uid = Binder.getCallingUid();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700790 int pid = Binder.getCallingPid();
Michael Chane96440f2009-05-06 10:27:36 -0700791 if (uid != Process.myUid()) {
792 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
793 }
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700794 if (ws != null) {
795 enforceWakeSourcePermission(uid, pid);
796 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800797 long ident = Binder.clearCallingIdentity();
798 try {
799 synchronized (mLocks) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700800 acquireWakeLockLocked(flags, lock, uid, pid, tag, ws);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800801 }
802 } finally {
803 Binder.restoreCallingIdentity(ident);
804 }
805 }
806
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700807 void noteStartWakeLocked(WakeLock wl, WorkSource ws) {
Dianne Hackborn70be1672010-09-14 11:13:03 -0700808 if (wl.monitorType >= 0) {
809 long origId = Binder.clearCallingIdentity();
810 try {
811 if (ws != null) {
812 mBatteryStats.noteStartWakelockFromSource(ws, wl.pid, wl.tag,
813 wl.monitorType);
814 } else {
815 mBatteryStats.noteStartWakelock(wl.uid, wl.pid, wl.tag, wl.monitorType);
816 }
817 } catch (RemoteException e) {
818 // Ignore
819 } finally {
820 Binder.restoreCallingIdentity(origId);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700821 }
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700822 }
823 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800824
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700825 void noteStopWakeLocked(WakeLock wl, WorkSource ws) {
Dianne Hackborn70be1672010-09-14 11:13:03 -0700826 if (wl.monitorType >= 0) {
827 long origId = Binder.clearCallingIdentity();
828 try {
829 if (ws != null) {
830 mBatteryStats.noteStopWakelockFromSource(ws, wl.pid, wl.tag,
831 wl.monitorType);
832 } else {
833 mBatteryStats.noteStopWakelock(wl.uid, wl.pid, wl.tag, wl.monitorType);
834 }
835 } catch (RemoteException e) {
836 // Ignore
837 } finally {
838 Binder.restoreCallingIdentity(origId);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700839 }
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700840 }
841 }
842
843 public void acquireWakeLockLocked(int flags, IBinder lock, int uid, int pid, String tag,
844 WorkSource ws) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800845 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800846 Slog.d(TAG, "acquireWakeLock flags=0x" + Integer.toHexString(flags) + " tag=" + tag);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800847 }
848
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700849 if (ws != null && ws.size() == 0) {
850 ws = null;
851 }
852
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800853 int index = mLocks.getIndex(lock);
854 WakeLock wl;
855 boolean newlock;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700856 boolean diffsource;
857 WorkSource oldsource;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800858 if (index < 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700859 wl = new WakeLock(flags, lock, tag, uid, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800860 switch (wl.flags & LOCK_MASK)
861 {
862 case PowerManager.FULL_WAKE_LOCK:
Mike Lockwood4984e732009-11-01 08:16:33 -0500863 if (mUseSoftwareAutoBrightness) {
Mike Lockwood3333fa42009-10-26 14:50:42 -0400864 wl.minState = SCREEN_BRIGHT;
865 } else {
866 wl.minState = (mKeyboardVisible ? ALL_BRIGHT : SCREEN_BUTTON_BRIGHT);
867 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800868 break;
869 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
870 wl.minState = SCREEN_BRIGHT;
871 break;
872 case PowerManager.SCREEN_DIM_WAKE_LOCK:
873 wl.minState = SCREEN_DIM;
874 break;
875 case PowerManager.PARTIAL_WAKE_LOCK:
Mike Lockwoodbc706a02009-07-27 13:50:57 -0700876 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800877 break;
878 default:
879 // just log and bail. we're in the server, so don't
880 // throw an exception.
Joe Onorato8a9b2202010-02-26 18:56:32 -0800881 Slog.e(TAG, "bad wakelock type for lock '" + tag + "' "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800882 + " flags=" + flags);
883 return;
884 }
885 mLocks.addLock(wl);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700886 if (ws != null) {
887 wl.ws = new WorkSource(ws);
888 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800889 newlock = true;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700890 diffsource = false;
891 oldsource = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800892 } else {
893 wl = mLocks.get(index);
894 newlock = false;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700895 oldsource = wl.ws;
896 if (oldsource != null) {
897 if (ws == null) {
898 wl.ws = null;
899 diffsource = true;
900 } else {
901 diffsource = oldsource.diff(ws);
902 }
903 } else if (ws != null) {
904 diffsource = true;
905 } else {
906 diffsource = false;
907 }
908 if (diffsource) {
909 wl.ws = new WorkSource(ws);
910 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800911 }
912 if (isScreenLock(flags)) {
913 // if this causes a wakeup, we reactivate all of the locks and
914 // set it to whatever they want. otherwise, we modulate that
915 // by the current state so we never turn it more on than
916 // it already is.
Joe Onorato8274a0e2010-10-05 17:38:09 -0400917 if ((flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) {
918 mProximityWakeLockCount++;
919 if (mProximityWakeLockCount == 1) {
920 enableProximityLockLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800921 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800922 } else {
Joe Onorato8274a0e2010-10-05 17:38:09 -0400923 if ((wl.flags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {
924 int oldWakeLockState = mWakeLockState;
925 mWakeLockState = mLocks.reactivateScreenLocksLocked();
Mike Lockwooddb97f602011-09-02 11:59:08 -0400926
927 // Disable proximity sensor if if user presses power key while we are in the
928 // "waiting for proximity sensor to go negative" state.
929 if ((mWakeLockState & SCREEN_ON_BIT) != 0
930 && mProximitySensorActive && mProximityWakeLockCount == 0) {
931 mProximitySensorActive = false;
932 }
933
Joe Onorato8274a0e2010-10-05 17:38:09 -0400934 if (mSpew) {
935 Slog.d(TAG, "wakeup here mUserState=0x" + Integer.toHexString(mUserState)
936 + " mWakeLockState=0x"
937 + Integer.toHexString(mWakeLockState)
938 + " previous wakeLockState=0x"
939 + Integer.toHexString(oldWakeLockState));
940 }
941 } else {
942 if (mSpew) {
943 Slog.d(TAG, "here mUserState=0x" + Integer.toHexString(mUserState)
944 + " mLocks.gatherState()=0x"
945 + Integer.toHexString(mLocks.gatherState())
946 + " mWakeLockState=0x" + Integer.toHexString(mWakeLockState));
947 }
948 mWakeLockState = (mUserState | mWakeLockState) & mLocks.gatherState();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800949 }
Joe Onorato8274a0e2010-10-05 17:38:09 -0400950 setPowerState(mWakeLockState | mUserState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800951 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800952 }
953 else if ((flags & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK) {
954 if (newlock) {
955 mPartialCount++;
956 if (mPartialCount == 1) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800957 if (LOG_PARTIAL_WL) EventLog.writeEvent(EventLogTags.POWER_PARTIAL_WAKE_STATE, 1, tag);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800958 }
959 }
Jeff Brown7304c342012-05-11 18:42:42 -0700960 nativeAcquireWakeLock(PARTIAL_WAKE_LOCK_ID, PARTIAL_NAME);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800961 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800962
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700963 if (diffsource) {
964 // If the lock sources have changed, need to first release the
965 // old ones.
966 noteStopWakeLocked(wl, oldsource);
967 }
968 if (newlock || diffsource) {
969 noteStartWakeLocked(wl, ws);
970 }
971 }
972
973 public void updateWakeLockWorkSource(IBinder lock, WorkSource ws) {
974 int uid = Binder.getCallingUid();
975 int pid = Binder.getCallingPid();
976 if (ws != null && ws.size() == 0) {
977 ws = null;
978 }
979 if (ws != null) {
980 enforceWakeSourcePermission(uid, pid);
981 }
Dianne Hackborn70be1672010-09-14 11:13:03 -0700982 synchronized (mLocks) {
983 int index = mLocks.getIndex(lock);
984 if (index < 0) {
985 throw new IllegalArgumentException("Wake lock not active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800986 }
Dianne Hackborn70be1672010-09-14 11:13:03 -0700987 WakeLock wl = mLocks.get(index);
988 WorkSource oldsource = wl.ws;
989 wl.ws = ws != null ? new WorkSource(ws) : null;
990 noteStopWakeLocked(wl, oldsource);
991 noteStartWakeLocked(wl, ws);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800992 }
993 }
994
Mike Lockwood0e39ea82009-11-18 15:37:10 -0500995 public void releaseWakeLock(IBinder lock, int flags) {
Michael Chane96440f2009-05-06 10:27:36 -0700996 int uid = Binder.getCallingUid();
997 if (uid != Process.myUid()) {
998 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
999 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001000
1001 synchronized (mLocks) {
Mike Lockwood0e39ea82009-11-18 15:37:10 -05001002 releaseWakeLockLocked(lock, flags, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001003 }
1004 }
1005
Mike Lockwood0e39ea82009-11-18 15:37:10 -05001006 private void releaseWakeLockLocked(IBinder lock, int flags, boolean death) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001007 WakeLock wl = mLocks.removeLock(lock);
1008 if (wl == null) {
1009 return;
1010 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001011
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001012 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001013 Slog.d(TAG, "releaseWakeLock flags=0x"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001014 + Integer.toHexString(wl.flags) + " tag=" + wl.tag);
1015 }
1016
1017 if (isScreenLock(wl.flags)) {
Joe Onorato8274a0e2010-10-05 17:38:09 -04001018 if ((wl.flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) {
1019 mProximityWakeLockCount--;
1020 if (mProximityWakeLockCount == 0) {
1021 if (mProximitySensorActive &&
1022 ((flags & PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE) != 0)) {
1023 // wait for proximity sensor to go negative before disabling sensor
1024 if (mDebugProximitySensor) {
1025 Slog.d(TAG, "waiting for proximity sensor to go negative");
1026 }
1027 } else {
1028 disableProximityLockLocked();
1029 }
1030 }
1031 } else {
1032 mWakeLockState = mLocks.gatherState();
1033 // goes in the middle to reduce flicker
1034 if ((wl.flags & PowerManager.ON_AFTER_RELEASE) != 0) {
1035 userActivity(SystemClock.uptimeMillis(), -1, false, OTHER_EVENT, false);
1036 }
1037 setPowerState(mWakeLockState | mUserState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001038 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001039 }
1040 else if ((wl.flags & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK) {
1041 mPartialCount--;
1042 if (mPartialCount == 0) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001043 if (LOG_PARTIAL_WL) EventLog.writeEvent(EventLogTags.POWER_PARTIAL_WAKE_STATE, 0, wl.tag);
Jeff Brown7304c342012-05-11 18:42:42 -07001044 nativeReleaseWakeLock(PARTIAL_NAME);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001045 }
1046 }
1047 // Unlink the lock from the binder.
1048 wl.binder.unlinkToDeath(wl, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001049
Dianne Hackborn70be1672010-09-14 11:13:03 -07001050 noteStopWakeLocked(wl, wl.ws);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001051 }
1052
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001053 private class PokeLock implements IBinder.DeathRecipient
1054 {
1055 PokeLock(int p, IBinder b, String t) {
1056 super();
1057 this.pokey = p;
1058 this.binder = b;
1059 this.tag = t;
1060 try {
1061 b.linkToDeath(this, 0);
1062 } catch (RemoteException e) {
1063 binderDied();
1064 }
1065 }
1066 public void binderDied() {
1067 setPokeLock(0, this.binder, this.tag);
1068 }
1069 int pokey;
1070 IBinder binder;
1071 String tag;
1072 boolean awakeOnSet;
1073 }
1074
1075 public void setPokeLock(int pokey, IBinder token, String tag) {
1076 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1077 if (token == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001078 Slog.e(TAG, "setPokeLock got null token for tag='" + tag + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001079 return;
1080 }
1081
1082 if ((pokey & POKE_LOCK_TIMEOUT_MASK) == POKE_LOCK_TIMEOUT_MASK) {
1083 throw new IllegalArgumentException("setPokeLock can't have both POKE_LOCK_SHORT_TIMEOUT"
1084 + " and POKE_LOCK_MEDIUM_TIMEOUT");
1085 }
1086
1087 synchronized (mLocks) {
1088 if (pokey != 0) {
1089 PokeLock p = mPokeLocks.get(token);
1090 int oldPokey = 0;
1091 if (p != null) {
1092 oldPokey = p.pokey;
1093 p.pokey = pokey;
1094 } else {
1095 p = new PokeLock(pokey, token, tag);
1096 mPokeLocks.put(token, p);
1097 }
1098 int oldTimeout = oldPokey & POKE_LOCK_TIMEOUT_MASK;
1099 int newTimeout = pokey & POKE_LOCK_TIMEOUT_MASK;
1100 if (((mPowerState & SCREEN_ON_BIT) == 0) && (oldTimeout != newTimeout)) {
1101 p.awakeOnSet = true;
1102 }
1103 } else {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07001104 PokeLock rLock = mPokeLocks.remove(token);
1105 if (rLock != null) {
1106 token.unlinkToDeath(rLock, 0);
1107 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001108 }
1109
1110 int oldPokey = mPokey;
1111 int cumulative = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001112 boolean awakeOnSet = false;
1113 for (PokeLock p: mPokeLocks.values()) {
1114 cumulative |= p.pokey;
1115 if (p.awakeOnSet) {
1116 awakeOnSet = true;
1117 }
1118 }
1119 mPokey = cumulative;
1120 mPokeAwakeOnSet = awakeOnSet;
1121
1122 int oldCumulativeTimeout = oldPokey & POKE_LOCK_TIMEOUT_MASK;
1123 int newCumulativeTimeout = pokey & POKE_LOCK_TIMEOUT_MASK;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001124
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001125 if (oldCumulativeTimeout != newCumulativeTimeout) {
1126 setScreenOffTimeoutsLocked();
1127 // reset the countdown timer, but use the existing nextState so it doesn't
1128 // change anything
1129 setTimeoutLocked(SystemClock.uptimeMillis(), mTimeoutTask.nextState);
1130 }
1131 }
1132 }
1133
1134 private static String lockType(int type)
1135 {
1136 switch (type)
1137 {
1138 case PowerManager.FULL_WAKE_LOCK:
David Brown251faa62009-08-02 22:04:36 -07001139 return "FULL_WAKE_LOCK ";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001140 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
David Brown251faa62009-08-02 22:04:36 -07001141 return "SCREEN_BRIGHT_WAKE_LOCK ";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001142 case PowerManager.SCREEN_DIM_WAKE_LOCK:
David Brown251faa62009-08-02 22:04:36 -07001143 return "SCREEN_DIM_WAKE_LOCK ";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001144 case PowerManager.PARTIAL_WAKE_LOCK:
David Brown251faa62009-08-02 22:04:36 -07001145 return "PARTIAL_WAKE_LOCK ";
1146 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
1147 return "PROXIMITY_SCREEN_OFF_WAKE_LOCK";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001148 default:
David Brown251faa62009-08-02 22:04:36 -07001149 return "??? ";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001150 }
1151 }
1152
1153 private static String dumpPowerState(int state) {
1154 return (((state & KEYBOARD_BRIGHT_BIT) != 0)
1155 ? "KEYBOARD_BRIGHT_BIT " : "")
1156 + (((state & SCREEN_BRIGHT_BIT) != 0)
1157 ? "SCREEN_BRIGHT_BIT " : "")
1158 + (((state & SCREEN_ON_BIT) != 0)
1159 ? "SCREEN_ON_BIT " : "")
1160 + (((state & BATTERY_LOW_BIT) != 0)
1161 ? "BATTERY_LOW_BIT " : "");
1162 }
1163
1164 @Override
1165 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1166 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
1167 != PackageManager.PERMISSION_GRANTED) {
1168 pw.println("Permission Denial: can't dump PowerManager from from pid="
1169 + Binder.getCallingPid()
1170 + ", uid=" + Binder.getCallingUid());
1171 return;
1172 }
1173
1174 long now = SystemClock.uptimeMillis();
1175
Mike Lockwoodca44df82010-02-25 13:48:49 -05001176 synchronized (mLocks) {
1177 pw.println("Power Manager State:");
1178 pw.println(" mIsPowered=" + mIsPowered
1179 + " mPowerState=" + mPowerState
1180 + " mScreenOffTime=" + (SystemClock.elapsedRealtime()-mScreenOffTime)
1181 + " ms");
1182 pw.println(" mPartialCount=" + mPartialCount);
1183 pw.println(" mWakeLockState=" + dumpPowerState(mWakeLockState));
1184 pw.println(" mUserState=" + dumpPowerState(mUserState));
1185 pw.println(" mPowerState=" + dumpPowerState(mPowerState));
1186 pw.println(" mLocks.gather=" + dumpPowerState(mLocks.gatherState()));
1187 pw.println(" mNextTimeout=" + mNextTimeout + " now=" + now
1188 + " " + ((mNextTimeout-now)/1000) + "s from now");
1189 pw.println(" mDimScreen=" + mDimScreen
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001190 + " mStayOnConditions=" + mStayOnConditions
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001191 + " mPreparingForScreenOn=" + mPreparingForScreenOn
1192 + " mSkippedScreenOn=" + mSkippedScreenOn);
Mike Lockwoodca44df82010-02-25 13:48:49 -05001193 pw.println(" mScreenOffReason=" + mScreenOffReason
1194 + " mUserState=" + mUserState);
1195 pw.println(" mBroadcastQueue={" + mBroadcastQueue[0] + ',' + mBroadcastQueue[1]
1196 + ',' + mBroadcastQueue[2] + "}");
1197 pw.println(" mBroadcastWhy={" + mBroadcastWhy[0] + ',' + mBroadcastWhy[1]
1198 + ',' + mBroadcastWhy[2] + "}");
1199 pw.println(" mPokey=" + mPokey + " mPokeAwakeonSet=" + mPokeAwakeOnSet);
1200 pw.println(" mKeyboardVisible=" + mKeyboardVisible
1201 + " mUserActivityAllowed=" + mUserActivityAllowed);
1202 pw.println(" mKeylightDelay=" + mKeylightDelay + " mDimDelay=" + mDimDelay
1203 + " mScreenOffDelay=" + mScreenOffDelay);
1204 pw.println(" mPreventScreenOn=" + mPreventScreenOn
1205 + " mScreenBrightnessOverride=" + mScreenBrightnessOverride
1206 + " mButtonBrightnessOverride=" + mButtonBrightnessOverride);
1207 pw.println(" mScreenOffTimeoutSetting=" + mScreenOffTimeoutSetting
1208 + " mMaximumScreenOffTimeout=" + mMaximumScreenOffTimeout);
1209 pw.println(" mLastScreenOnTime=" + mLastScreenOnTime);
1210 pw.println(" mBroadcastWakeLock=" + mBroadcastWakeLock);
1211 pw.println(" mStayOnWhilePluggedInScreenDimLock=" + mStayOnWhilePluggedInScreenDimLock);
1212 pw.println(" mStayOnWhilePluggedInPartialLock=" + mStayOnWhilePluggedInPartialLock);
1213 pw.println(" mPreventScreenOnPartialLock=" + mPreventScreenOnPartialLock);
1214 pw.println(" mProximityPartialLock=" + mProximityPartialLock);
1215 pw.println(" mProximityWakeLockCount=" + mProximityWakeLockCount);
1216 pw.println(" mProximitySensorEnabled=" + mProximitySensorEnabled);
1217 pw.println(" mProximitySensorActive=" + mProximitySensorActive);
1218 pw.println(" mProximityPendingValue=" + mProximityPendingValue);
1219 pw.println(" mLastProximityEventTime=" + mLastProximityEventTime);
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08001220 pw.println(" mLightSensorEnabled=" + mLightSensorEnabled
1221 + " mLightSensorAdjustSetting=" + mLightSensorAdjustSetting);
Mike Lockwoodca44df82010-02-25 13:48:49 -05001222 pw.println(" mLightSensorValue=" + mLightSensorValue
1223 + " mLightSensorPendingValue=" + mLightSensorPendingValue);
Craig Mautner291576e2012-06-07 19:58:58 -07001224 pw.println(" mHighestLightSensorValue=" + mHighestLightSensorValue
1225 + " mWaitingForFirstLightSensor=" + mWaitingForFirstLightSensor);
Jim Rodovichd102fea2010-09-02 12:30:49 -05001226 pw.println(" mLightSensorPendingDecrease=" + mLightSensorPendingDecrease
1227 + " mLightSensorPendingIncrease=" + mLightSensorPendingIncrease);
Mike Lockwoodca44df82010-02-25 13:48:49 -05001228 pw.println(" mLightSensorScreenBrightness=" + mLightSensorScreenBrightness
1229 + " mLightSensorButtonBrightness=" + mLightSensorButtonBrightness
1230 + " mLightSensorKeyboardBrightness=" + mLightSensorKeyboardBrightness);
1231 pw.println(" mUseSoftwareAutoBrightness=" + mUseSoftwareAutoBrightness);
1232 pw.println(" mAutoBrightessEnabled=" + mAutoBrightessEnabled);
Jim Miller92e66dd2012-02-21 18:57:12 -08001233 mScreenBrightnessAnimator.dump(pw, " mScreenBrightnessAnimator: ");
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001234
Mike Lockwoodca44df82010-02-25 13:48:49 -05001235 int N = mLocks.size();
1236 pw.println();
1237 pw.println("mLocks.size=" + N + ":");
1238 for (int i=0; i<N; i++) {
1239 WakeLock wl = mLocks.get(i);
1240 String type = lockType(wl.flags & LOCK_MASK);
1241 String acquireCausesWakeup = "";
1242 if ((wl.flags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {
1243 acquireCausesWakeup = "ACQUIRE_CAUSES_WAKEUP ";
1244 }
1245 String activated = "";
1246 if (wl.activated) {
1247 activated = " activated";
1248 }
1249 pw.println(" " + type + " '" + wl.tag + "'" + acquireCausesWakeup
Mike Lockwoodf5bd0922010-03-22 17:10:15 -04001250 + activated + " (minState=" + wl.minState + ", uid=" + wl.uid
1251 + ", pid=" + wl.pid + ")");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001252 }
Mike Lockwoodca44df82010-02-25 13:48:49 -05001253
1254 pw.println();
1255 pw.println("mPokeLocks.size=" + mPokeLocks.size() + ":");
1256 for (PokeLock p: mPokeLocks.values()) {
1257 pw.println(" poke lock '" + p.tag + "':"
Joe Onorato1a542c72010-11-08 09:48:20 -08001258 + ((p.pokey & POKE_LOCK_IGNORE_TOUCH_EVENTS) != 0
1259 ? " POKE_LOCK_IGNORE_TOUCH_EVENTS" : "")
Mike Lockwoodca44df82010-02-25 13:48:49 -05001260 + ((p.pokey & POKE_LOCK_SHORT_TIMEOUT) != 0
1261 ? " POKE_LOCK_SHORT_TIMEOUT" : "")
1262 + ((p.pokey & POKE_LOCK_MEDIUM_TIMEOUT) != 0
1263 ? " POKE_LOCK_MEDIUM_TIMEOUT" : ""));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001264 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001265
Mike Lockwoodca44df82010-02-25 13:48:49 -05001266 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001267 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001268 }
1269
Joe Onorato7999bff2010-07-24 11:50:05 -04001270 private void setTimeoutLocked(long now, int nextState) {
1271 setTimeoutLocked(now, -1, nextState);
1272 }
1273
1274 // If they gave a timeoutOverride it is the number of seconds
1275 // to screen-off. Figure out where in the countdown cycle we
1276 // should jump to.
Joe Onorato797e6882010-08-26 14:46:01 -04001277 private void setTimeoutLocked(long now, final long originalTimeoutOverride, int nextState) {
1278 long timeoutOverride = originalTimeoutOverride;
Mike Lockwood2d7bb812009-11-15 18:12:22 -05001279 if (mBootCompleted) {
Joe Onorato7999bff2010-07-24 11:50:05 -04001280 synchronized (mLocks) {
Joe Onorato7999bff2010-07-24 11:50:05 -04001281 long when = 0;
1282 if (timeoutOverride <= 0) {
1283 switch (nextState)
1284 {
1285 case SCREEN_BRIGHT:
1286 when = now + mKeylightDelay;
1287 break;
1288 case SCREEN_DIM:
1289 if (mDimDelay >= 0) {
1290 when = now + mDimDelay;
Andreas Huber84047bc2010-07-27 16:49:10 -07001291 break;
Joe Onorato7999bff2010-07-24 11:50:05 -04001292 } else {
1293 Slog.w(TAG, "mDimDelay=" + mDimDelay + " while trying to dim");
1294 }
1295 case SCREEN_OFF:
1296 synchronized (mLocks) {
1297 when = now + mScreenOffDelay;
1298 }
1299 break;
Andreas Huber84047bc2010-07-27 16:49:10 -07001300 default:
1301 when = now;
1302 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001303 }
Joe Onorato7999bff2010-07-24 11:50:05 -04001304 } else {
1305 override: {
1306 if (timeoutOverride <= mScreenOffDelay) {
1307 when = now + timeoutOverride;
1308 nextState = SCREEN_OFF;
1309 break override;
1310 }
1311 timeoutOverride -= mScreenOffDelay;
1312
1313 if (mDimDelay >= 0) {
1314 if (timeoutOverride <= mDimDelay) {
1315 when = now + timeoutOverride;
1316 nextState = SCREEN_DIM;
1317 break override;
1318 }
1319 timeoutOverride -= mDimDelay;
1320 }
1321
1322 when = now + timeoutOverride;
1323 nextState = SCREEN_BRIGHT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001324 }
Joe Onorato7999bff2010-07-24 11:50:05 -04001325 }
1326 if (mSpew) {
1327 Slog.d(TAG, "setTimeoutLocked now=" + now
1328 + " timeoutOverride=" + timeoutOverride
1329 + " nextState=" + nextState + " when=" + when);
1330 }
Joe Onorato797e6882010-08-26 14:46:01 -04001331
1332 mHandler.removeCallbacks(mTimeoutTask);
1333 mTimeoutTask.nextState = nextState;
1334 mTimeoutTask.remainingTimeoutOverride = timeoutOverride > 0
1335 ? (originalTimeoutOverride - timeoutOverride)
1336 : -1;
Joe Onorato7999bff2010-07-24 11:50:05 -04001337 mHandler.postAtTime(mTimeoutTask, when);
1338 mNextTimeout = when; // for debugging
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001339 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001340 }
1341 }
1342
1343 private void cancelTimerLocked()
1344 {
1345 mHandler.removeCallbacks(mTimeoutTask);
1346 mTimeoutTask.nextState = -1;
1347 }
1348
1349 private class TimeoutTask implements Runnable
1350 {
1351 int nextState; // access should be synchronized on mLocks
Joe Onorato797e6882010-08-26 14:46:01 -04001352 long remainingTimeoutOverride;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001353 public void run()
1354 {
1355 synchronized (mLocks) {
1356 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001357 Slog.d(TAG, "user activity timeout timed out nextState=" + this.nextState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001358 }
1359
1360 if (nextState == -1) {
1361 return;
1362 }
1363
1364 mUserState = this.nextState;
1365 setPowerState(this.nextState | mWakeLockState);
1366
1367 long now = SystemClock.uptimeMillis();
1368
1369 switch (this.nextState)
1370 {
1371 case SCREEN_BRIGHT:
1372 if (mDimDelay >= 0) {
Joe Onorato797e6882010-08-26 14:46:01 -04001373 setTimeoutLocked(now, remainingTimeoutOverride, SCREEN_DIM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001374 break;
1375 }
1376 case SCREEN_DIM:
Joe Onorato797e6882010-08-26 14:46:01 -04001377 setTimeoutLocked(now, remainingTimeoutOverride, SCREEN_OFF);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001378 break;
1379 }
1380 }
1381 }
1382 }
1383
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001384 private void sendNotificationLocked(boolean on, int why) {
1385 if (!mInitialized) {
1386 // No notifications sent until first initialization is done.
1387 // This is so that when we are moving from our initial state
1388 // which looks like the screen was off to it being on, we do not
1389 // go through the process of waiting for the higher-level user
1390 // space to be ready before turning up the display brightness.
1391 // (And also do not send needless broadcasts about the screen.)
1392 return;
1393 }
Dianne Hackborn40011092011-09-22 13:37:48 -07001394
1395 if (DEBUG_SCREEN_ON) {
1396 RuntimeException here = new RuntimeException("here");
1397 here.fillInStackTrace();
1398 Slog.i(TAG, "sendNotificationLocked: " + on, here);
1399 }
1400
Joe Onorato64c62ba2009-03-24 20:13:57 -07001401 if (!on) {
1402 mStillNeedSleepNotification = false;
1403 }
1404
Joe Onorato128e7292009-03-24 18:41:31 -07001405 // Add to the queue.
1406 int index = 0;
1407 while (mBroadcastQueue[index] != -1) {
1408 index++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001409 }
Joe Onorato128e7292009-03-24 18:41:31 -07001410 mBroadcastQueue[index] = on ? 1 : 0;
1411 mBroadcastWhy[index] = why;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001412
Joe Onorato128e7292009-03-24 18:41:31 -07001413 // If we added it position 2, then there is a pair that can be stripped.
1414 // If we added it position 1 and we're turning the screen off, we can strip
1415 // the pair and do nothing, because the screen is already off, and therefore
1416 // keyguard has already been enabled.
1417 // However, if we added it at position 1 and we're turning it on, then position
1418 // 0 was to turn it off, and we can't strip that, because keyguard needs to come
1419 // on, so have to run the queue then.
1420 if (index == 2) {
Dianne Hackborn254cb442010-01-27 19:23:59 -08001421 // While we're collapsing them, if it's going off, and the new reason
1422 // is more significant than the first, then use the new one.
1423 if (!on && mBroadcastWhy[0] > why) {
1424 mBroadcastWhy[0] = why;
Joe Onorato128e7292009-03-24 18:41:31 -07001425 }
1426 mBroadcastQueue[0] = on ? 1 : 0;
1427 mBroadcastQueue[1] = -1;
1428 mBroadcastQueue[2] = -1;
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001429 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount);
Mike Lockwood9c90a372010-04-13 15:40:27 -04001430 mBroadcastWakeLock.release();
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001431 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount);
Mike Lockwood9c90a372010-04-13 15:40:27 -04001432 mBroadcastWakeLock.release();
Joe Onorato128e7292009-03-24 18:41:31 -07001433 index = 0;
1434 }
1435 if (index == 1 && !on) {
1436 mBroadcastQueue[0] = -1;
1437 mBroadcastQueue[1] = -1;
1438 index = -1;
1439 // The wake lock was being held, but we're not actually going to do any
1440 // broadcasts, so release the wake lock.
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001441 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001442 mBroadcastWakeLock.release();
Joe Onorato128e7292009-03-24 18:41:31 -07001443 }
1444
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07001445 // The broadcast queue has changed; make sure the screen is on if it
1446 // is now possible for it to be.
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001447 if (mSkippedScreenOn) {
1448 updateLightsLocked(mPowerState, SCREEN_ON_BIT);
1449 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07001450
Joe Onorato128e7292009-03-24 18:41:31 -07001451 // Now send the message.
1452 if (index >= 0) {
1453 // Acquire the broadcast wake lock before changing the power
1454 // state. It will be release after the broadcast is sent.
1455 // We always increment the ref count for each notification in the queue
1456 // and always decrement when that notification is handled.
1457 mBroadcastWakeLock.acquire();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001458 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND, mBroadcastWakeLock.mCount);
Joe Onorato128e7292009-03-24 18:41:31 -07001459 mHandler.post(mNotificationTask);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001460 }
1461 }
1462
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001463 private WindowManagerPolicy.ScreenOnListener mScreenOnListener =
1464 new WindowManagerPolicy.ScreenOnListener() {
Jim Miller92e66dd2012-02-21 18:57:12 -08001465 public void onScreenOn() {
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001466 synchronized (mLocks) {
1467 if (mPreparingForScreenOn) {
1468 mPreparingForScreenOn = false;
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001469 updateLightsLocked(mPowerState, SCREEN_ON_BIT);
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001470 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP,
1471 4, mBroadcastWakeLock.mCount);
1472 mBroadcastWakeLock.release();
1473 }
1474 }
1475 }
1476 };
1477
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001478 private Runnable mNotificationTask = new Runnable()
1479 {
1480 public void run()
1481 {
Joe Onorato128e7292009-03-24 18:41:31 -07001482 while (true) {
1483 int value;
1484 int why;
1485 WindowManagerPolicy policy;
1486 synchronized (mLocks) {
1487 value = mBroadcastQueue[0];
1488 why = mBroadcastWhy[0];
1489 for (int i=0; i<2; i++) {
1490 mBroadcastQueue[i] = mBroadcastQueue[i+1];
1491 mBroadcastWhy[i] = mBroadcastWhy[i+1];
1492 }
1493 policy = getPolicyLocked();
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001494 if (value == 1 && !mPreparingForScreenOn) {
1495 mPreparingForScreenOn = true;
1496 mBroadcastWakeLock.acquire();
1497 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND,
1498 mBroadcastWakeLock.mCount);
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07001499 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001500 }
Joe Onorato128e7292009-03-24 18:41:31 -07001501 if (value == 1) {
1502 mScreenOnStart = SystemClock.uptimeMillis();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001503
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001504 policy.screenTurningOn(mScreenOnListener);
Joe Onorato128e7292009-03-24 18:41:31 -07001505 try {
1506 ActivityManagerNative.getDefault().wakingUp();
1507 } catch (RemoteException e) {
1508 // ignore it
1509 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001510
Joe Onorato128e7292009-03-24 18:41:31 -07001511 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001512 Slog.d(TAG, "mBroadcastWakeLock=" + mBroadcastWakeLock);
Joe Onorato128e7292009-03-24 18:41:31 -07001513 }
1514 if (mContext != null && ActivityManagerNative.isSystemReady()) {
1515 mContext.sendOrderedBroadcast(mScreenOnIntent, null,
1516 mScreenOnBroadcastDone, mHandler, 0, null, null);
1517 } else {
1518 synchronized (mLocks) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001519 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 2,
Joe Onorato128e7292009-03-24 18:41:31 -07001520 mBroadcastWakeLock.mCount);
1521 mBroadcastWakeLock.release();
1522 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001523 }
1524 }
Joe Onorato128e7292009-03-24 18:41:31 -07001525 else if (value == 0) {
1526 mScreenOffStart = SystemClock.uptimeMillis();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001527
Joe Onorato128e7292009-03-24 18:41:31 -07001528 policy.screenTurnedOff(why);
1529 try {
1530 ActivityManagerNative.getDefault().goingToSleep();
1531 } catch (RemoteException e) {
1532 // ignore it.
1533 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001534
Joe Onorato128e7292009-03-24 18:41:31 -07001535 if (mContext != null && ActivityManagerNative.isSystemReady()) {
1536 mContext.sendOrderedBroadcast(mScreenOffIntent, null,
1537 mScreenOffBroadcastDone, mHandler, 0, null, null);
1538 } else {
1539 synchronized (mLocks) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001540 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 3,
Joe Onorato128e7292009-03-24 18:41:31 -07001541 mBroadcastWakeLock.mCount);
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001542 updateLightsLocked(mPowerState, SCREEN_ON_BIT);
Joe Onorato128e7292009-03-24 18:41:31 -07001543 mBroadcastWakeLock.release();
1544 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001545 }
1546 }
Joe Onorato128e7292009-03-24 18:41:31 -07001547 else {
1548 // If we're in this case, then this handler is running for a previous
1549 // paired transaction. mBroadcastWakeLock will already have been released.
1550 break;
1551 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001552 }
1553 }
1554 };
1555
1556 long mScreenOnStart;
1557 private BroadcastReceiver mScreenOnBroadcastDone = new BroadcastReceiver() {
1558 public void onReceive(Context context, Intent intent) {
1559 synchronized (mLocks) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001560 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001561 SystemClock.uptimeMillis() - mScreenOnStart, mBroadcastWakeLock.mCount);
1562 mBroadcastWakeLock.release();
1563 }
1564 }
1565 };
1566
1567 long mScreenOffStart;
1568 private BroadcastReceiver mScreenOffBroadcastDone = new BroadcastReceiver() {
1569 public void onReceive(Context context, Intent intent) {
1570 synchronized (mLocks) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001571 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 0,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001572 SystemClock.uptimeMillis() - mScreenOffStart, mBroadcastWakeLock.mCount);
1573 mBroadcastWakeLock.release();
1574 }
1575 }
1576 };
1577
1578 void logPointerUpEvent() {
1579 if (LOG_TOUCH_DOWNS) {
1580 mTotalTouchDownTime += SystemClock.elapsedRealtime() - mLastTouchDown;
1581 mLastTouchDown = 0;
1582 }
1583 }
1584
1585 void logPointerDownEvent() {
1586 if (LOG_TOUCH_DOWNS) {
1587 // If we are not already timing a down/up sequence
1588 if (mLastTouchDown == 0) {
1589 mLastTouchDown = SystemClock.elapsedRealtime();
1590 mTouchCycles++;
1591 }
1592 }
1593 }
1594
1595 /**
1596 * Prevents the screen from turning on even if it *should* turn on due
1597 * to a subsequent full wake lock being acquired.
1598 * <p>
1599 * This is a temporary hack that allows an activity to "cover up" any
1600 * display glitches that happen during the activity's startup
1601 * sequence. (Specifically, this API was added to work around a
1602 * cosmetic bug in the "incoming call" sequence, where the lock screen
1603 * would flicker briefly before the incoming call UI became visible.)
1604 * TODO: There ought to be a more elegant way of doing this,
1605 * probably by having the PowerManager and ActivityManager
1606 * work together to let apps specify that the screen on/off
1607 * state should be synchronized with the Activity lifecycle.
1608 * <p>
1609 * Note that calling preventScreenOn(true) will NOT turn the screen
1610 * off if it's currently on. (This API only affects *future*
1611 * acquisitions of full wake locks.)
1612 * But calling preventScreenOn(false) WILL turn the screen on if
1613 * it's currently off because of a prior preventScreenOn(true) call.
1614 * <p>
1615 * Any call to preventScreenOn(true) MUST be followed promptly by a call
1616 * to preventScreenOn(false). In fact, if the preventScreenOn(false)
1617 * call doesn't occur within 5 seconds, we'll turn the screen back on
1618 * ourselves (and log a warning about it); this prevents a buggy app
1619 * from disabling the screen forever.)
1620 * <p>
1621 * TODO: this feature should really be controlled by a new type of poke
1622 * lock (rather than an IPowerManager call).
1623 */
1624 public void preventScreenOn(boolean prevent) {
1625 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1626
1627 synchronized (mLocks) {
1628 if (prevent) {
1629 // First of all, grab a partial wake lock to
1630 // make sure the CPU stays on during the entire
1631 // preventScreenOn(true) -> preventScreenOn(false) sequence.
1632 mPreventScreenOnPartialLock.acquire();
1633
1634 // Post a forceReenableScreen() call (for 5 seconds in the
1635 // future) to make sure the matching preventScreenOn(false) call
1636 // has happened by then.
1637 mHandler.removeCallbacks(mForceReenableScreenTask);
1638 mHandler.postDelayed(mForceReenableScreenTask, 5000);
1639
1640 // Finally, set the flag that prevents the screen from turning on.
1641 // (Below, in setPowerState(), we'll check mPreventScreenOn and
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001642 // we *won't* call setScreenStateLocked(true) if it's set.)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001643 mPreventScreenOn = true;
1644 } else {
1645 // (Re)enable the screen.
1646 mPreventScreenOn = false;
1647
1648 // We're "undoing" a the prior preventScreenOn(true) call, so we
1649 // no longer need the 5-second safeguard.
1650 mHandler.removeCallbacks(mForceReenableScreenTask);
1651
1652 // Forcibly turn on the screen if it's supposed to be on. (This
1653 // handles the case where the screen is currently off because of
1654 // a prior preventScreenOn(true) call.)
Mike Lockwoode090281422009-11-14 21:02:56 -05001655 if (!mProximitySensorActive && (mPowerState & SCREEN_ON_BIT) != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001656 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001657 Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001658 "preventScreenOn: turning on after a prior preventScreenOn(true)!");
1659 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001660 int err = setScreenStateLocked(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001661 if (err != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001662 Slog.w(TAG, "preventScreenOn: error from setScreenStateLocked(): " + err);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001663 }
1664 }
1665
1666 // Release the partial wake lock that we held during the
1667 // preventScreenOn(true) -> preventScreenOn(false) sequence.
1668 mPreventScreenOnPartialLock.release();
1669 }
1670 }
1671 }
1672
1673 public void setScreenBrightnessOverride(int brightness) {
1674 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1675
Mike Lockwoodf527c712010-06-10 14:12:33 -04001676 if (mSpew) Slog.d(TAG, "setScreenBrightnessOverride " + brightness);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001677 synchronized (mLocks) {
1678 if (mScreenBrightnessOverride != brightness) {
1679 mScreenBrightnessOverride = brightness;
Mike Lockwoodf527c712010-06-10 14:12:33 -04001680 if (isScreenOn()) {
1681 updateLightsLocked(mPowerState, SCREEN_ON_BIT);
1682 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001683 }
1684 }
1685 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05001686
1687 public void setButtonBrightnessOverride(int brightness) {
1688 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1689
Mike Lockwoodf527c712010-06-10 14:12:33 -04001690 if (mSpew) Slog.d(TAG, "setButtonBrightnessOverride " + brightness);
Mike Lockwoodfb73f792009-11-20 11:31:18 -05001691 synchronized (mLocks) {
1692 if (mButtonBrightnessOverride != brightness) {
1693 mButtonBrightnessOverride = brightness;
Mike Lockwoodf527c712010-06-10 14:12:33 -04001694 if (isScreenOn()) {
1695 updateLightsLocked(mPowerState, BUTTON_BRIGHT_BIT | KEYBOARD_BRIGHT_BIT);
1696 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05001697 }
1698 }
1699 }
1700
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001701 /**
1702 * Sanity-check that gets called 5 seconds after any call to
1703 * preventScreenOn(true). This ensures that the original call
1704 * is followed promptly by a call to preventScreenOn(false).
1705 */
1706 private void forceReenableScreen() {
1707 // We shouldn't get here at all if mPreventScreenOn is false, since
1708 // we should have already removed any existing
1709 // mForceReenableScreenTask messages...
1710 if (!mPreventScreenOn) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001711 Slog.w(TAG, "forceReenableScreen: mPreventScreenOn is false, nothing to do");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001712 return;
1713 }
1714
1715 // Uh oh. It's been 5 seconds since a call to
1716 // preventScreenOn(true) and we haven't re-enabled the screen yet.
1717 // This means the app that called preventScreenOn(true) is either
1718 // slow (i.e. it took more than 5 seconds to call preventScreenOn(false)),
1719 // or buggy (i.e. it forgot to call preventScreenOn(false), or
1720 // crashed before doing so.)
1721
1722 // Log a warning, and forcibly turn the screen back on.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001723 Slog.w(TAG, "App called preventScreenOn(true) but didn't promptly reenable the screen! "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001724 + "Forcing the screen back on...");
1725 preventScreenOn(false);
1726 }
1727
1728 private Runnable mForceReenableScreenTask = new Runnable() {
1729 public void run() {
1730 forceReenableScreen();
1731 }
1732 };
1733
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001734 private int setScreenStateLocked(boolean on) {
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001735 if (DEBUG_SCREEN_ON) {
1736 RuntimeException e = new RuntimeException("here");
1737 e.fillInStackTrace();
1738 Slog.i(TAG, "Set screen state: " + on, e);
1739 }
Dianne Hackborn474fd742011-10-10 18:40:22 -07001740 if (on) {
1741 if ((mPowerState & SCREEN_ON_BIT) == 0 || mSkippedScreenOn) {
1742 // If we are turning the screen state on, but the screen
1743 // light is currently off, then make sure that we set the
1744 // light at this point to 0. This is the case where we are
1745 // turning on the screen and waiting for the UI to be drawn
1746 // before showing it to the user. We want the light off
1747 // until it is ready to be shown to the user, not it using
1748 // whatever the last value it had.
Dianne Hackborn81de8b92011-11-28 16:54:31 -08001749 if (DEBUG_SCREEN_ON) {
1750 Slog.i(TAG, "Forcing brightness 0: mPowerState=0x"
1751 + Integer.toHexString(mPowerState)
1752 + " mSkippedScreenOn=" + mSkippedScreenOn);
1753 }
Jeff Brown7304c342012-05-11 18:42:42 -07001754 mScreenBrightnessAnimator.animateTo(PowerManager.BRIGHTNESS_OFF, SCREEN_BRIGHT_BIT, 0);
Dianne Hackborn474fd742011-10-10 18:40:22 -07001755 }
1756 }
Jeff Brown7304c342012-05-11 18:42:42 -07001757 int err = nativeSetScreenState(on);
Mike Lockwood20ee6f22009-11-07 20:33:47 -05001758 if (err == 0) {
1759 mLastScreenOnTime = (on ? SystemClock.elapsedRealtime() : 0);
1760 if (mUseSoftwareAutoBrightness) {
Joe Onoratod28f7532010-11-06 12:56:53 -07001761 enableLightSensorLocked(on);
Craig Mautner37933682012-06-06 14:13:39 -07001762 if (on) {
1763 // If AutoBrightness is enabled, set the brightness immediately after the
1764 // next sensor value is received.
1765 mWaitingForFirstLightSensor = mAutoBrightessEnabled;
1766 } else {
Mike Lockwood20ee6f22009-11-07 20:33:47 -05001767 // make sure button and key backlights are off too
Mike Lockwood3cb67a32009-11-27 14:25:58 -05001768 mButtonLight.turnOff();
1769 mKeyboardLight.turnOff();
Mike Lockwood20ee6f22009-11-07 20:33:47 -05001770 }
Mike Lockwoodd7786b42009-10-15 17:09:16 -07001771 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001772 }
1773 return err;
1774 }
1775
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001776 private void setPowerState(int state)
1777 {
Mike Lockwood435eb642009-12-03 08:40:18 -05001778 setPowerState(state, false, WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001779 }
1780
Mike Lockwood435eb642009-12-03 08:40:18 -05001781 private void setPowerState(int newState, boolean noChangeLights, int reason)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001782 {
1783 synchronized (mLocks) {
1784 int err;
1785
1786 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001787 Slog.d(TAG, "setPowerState: mPowerState=0x" + Integer.toHexString(mPowerState)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001788 + " newState=0x" + Integer.toHexString(newState)
Mike Lockwood435eb642009-12-03 08:40:18 -05001789 + " noChangeLights=" + noChangeLights
1790 + " reason=" + reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001791 }
Daniel Sandler7d276c32012-01-30 14:33:52 -05001792
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001793 if (noChangeLights) {
1794 newState = (newState & ~LIGHTS_MASK) | (mPowerState & LIGHTS_MASK);
1795 }
Mike Lockwood36fc3022009-08-25 16:49:06 -07001796 if (mProximitySensorActive) {
1797 // don't turn on the screen when the proximity sensor lock is held
1798 newState = (newState & ~SCREEN_BRIGHT);
1799 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001800
1801 if (batteryIsLow()) {
1802 newState |= BATTERY_LOW_BIT;
1803 } else {
1804 newState &= ~BATTERY_LOW_BIT;
1805 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001806 if (newState == mPowerState && mInitialized) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001807 return;
1808 }
Mike Lockwood3333fa42009-10-26 14:50:42 -04001809
Mike Lockwood2d7bb812009-11-15 18:12:22 -05001810 if (!mBootCompleted && !mUseSoftwareAutoBrightness) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001811 newState |= ALL_BRIGHT;
1812 }
1813
1814 boolean oldScreenOn = (mPowerState & SCREEN_ON_BIT) != 0;
1815 boolean newScreenOn = (newState & SCREEN_ON_BIT) != 0;
1816
Mike Lockwood51b844962009-11-16 21:51:18 -05001817 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001818 Slog.d(TAG, "setPowerState: mPowerState=" + mPowerState
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001819 + " newState=" + newState + " noChangeLights=" + noChangeLights);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001820 Slog.d(TAG, " oldKeyboardBright=" + ((mPowerState & KEYBOARD_BRIGHT_BIT) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001821 + " newKeyboardBright=" + ((newState & KEYBOARD_BRIGHT_BIT) != 0));
Joe Onorato8a9b2202010-02-26 18:56:32 -08001822 Slog.d(TAG, " oldScreenBright=" + ((mPowerState & SCREEN_BRIGHT_BIT) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001823 + " newScreenBright=" + ((newState & SCREEN_BRIGHT_BIT) != 0));
Joe Onorato8a9b2202010-02-26 18:56:32 -08001824 Slog.d(TAG, " oldButtonBright=" + ((mPowerState & BUTTON_BRIGHT_BIT) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001825 + " newButtonBright=" + ((newState & BUTTON_BRIGHT_BIT) != 0));
Joe Onorato8a9b2202010-02-26 18:56:32 -08001826 Slog.d(TAG, " oldScreenOn=" + oldScreenOn
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001827 + " newScreenOn=" + newScreenOn);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001828 Slog.d(TAG, " oldBatteryLow=" + ((mPowerState & BATTERY_LOW_BIT) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001829 + " newBatteryLow=" + ((newState & BATTERY_LOW_BIT) != 0));
1830 }
1831
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001832 final boolean stateChanged = mPowerState != newState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001833
Daniel Sandler7d276c32012-01-30 14:33:52 -05001834 if (stateChanged && reason == WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT) {
Daniel Sandler0af48952012-04-10 15:14:35 -04001835 if (mPolicy != null && mPolicy.isScreenSaverEnabled()) {
Daniel Sandler7d276c32012-01-30 14:33:52 -05001836 if (mSpew) {
1837 Slog.d(TAG, "setPowerState: running screen saver instead of turning off screen");
1838 }
1839 if (mPolicy.startScreenSaver()) {
1840 // was successful
1841 return;
1842 }
1843 }
1844 }
1845
1846
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001847 if (oldScreenOn != newScreenOn) {
1848 if (newScreenOn) {
Joe Onorato128e7292009-03-24 18:41:31 -07001849 // When the user presses the power button, we need to always send out the
1850 // notification that it's going to sleep so the keyguard goes on. But
1851 // we can't do that until the screen fades out, so we don't show the keyguard
1852 // too early.
1853 if (mStillNeedSleepNotification) {
1854 sendNotificationLocked(false, WindowManagerPolicy.OFF_BECAUSE_OF_USER);
1855 }
1856
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001857 // Turn on the screen UNLESS there was a prior
1858 // preventScreenOn(true) request. (Note that the lifetime
1859 // of a single preventScreenOn() request is limited to 5
1860 // seconds to prevent a buggy app from disabling the
1861 // screen forever; see forceReenableScreen().)
1862 boolean reallyTurnScreenOn = true;
1863 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001864 Slog.d(TAG, "- turning screen on... mPreventScreenOn = "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001865 + mPreventScreenOn);
1866 }
1867
1868 if (mPreventScreenOn) {
1869 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001870 Slog.d(TAG, "- PREVENTING screen from really turning on!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001871 }
1872 reallyTurnScreenOn = false;
1873 }
1874 if (reallyTurnScreenOn) {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001875 err = setScreenStateLocked(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001876 long identity = Binder.clearCallingIdentity();
1877 try {
Mike Lockwoodfb73f792009-11-20 11:31:18 -05001878 mBatteryStats.noteScreenBrightness(getPreferredBrightness());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001879 mBatteryStats.noteScreenOn();
1880 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001881 Slog.w(TAG, "RemoteException calling noteScreenOn on BatteryStatsService", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001882 } finally {
1883 Binder.restoreCallingIdentity(identity);
1884 }
1885 } else {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001886 setScreenStateLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001887 // But continue as if we really did turn the screen on...
1888 err = 0;
1889 }
1890
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001891 mLastTouchDown = 0;
1892 mTotalTouchDownTime = 0;
1893 mTouchCycles = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001894 EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, reason,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001895 mTotalTouchDownTime, mTouchCycles);
1896 if (err == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001897 sendNotificationLocked(true, -1);
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001898 // Update the lights *after* taking care of turning the
1899 // screen on, so we do this after our notifications are
1900 // enqueued and thus will delay turning on the screen light
1901 // until the windows are correctly displayed.
1902 if (stateChanged) {
1903 updateLightsLocked(newState, 0);
1904 }
1905 mPowerState |= SCREEN_ON_BIT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001906 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001907
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001908 } else {
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001909 // Update the lights *before* taking care of turning the
1910 // screen off, so we can initiate any animations that are desired.
Craig Mautner44bf70f2012-03-13 11:38:38 -07001911 mScreenOffReason = reason;
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001912 if (stateChanged) {
1913 updateLightsLocked(newState, 0);
1914 }
1915
Mike Lockwood497087e32009-11-08 18:33:03 -05001916 // cancel light sensor task
1917 mHandler.removeCallbacks(mAutoBrightnessTask);
Jim Rodovichd102fea2010-09-02 12:30:49 -05001918 mLightSensorPendingDecrease = false;
1919 mLightSensorPendingIncrease = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001920 mScreenOffTime = SystemClock.elapsedRealtime();
1921 long identity = Binder.clearCallingIdentity();
1922 try {
1923 mBatteryStats.noteScreenOff();
1924 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001925 Slog.w(TAG, "RemoteException calling noteScreenOff on BatteryStatsService", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001926 } finally {
1927 Binder.restoreCallingIdentity(identity);
1928 }
1929 mPowerState &= ~SCREEN_ON_BIT;
Jim Miller92e66dd2012-02-21 18:57:12 -08001930 if (!mScreenBrightnessAnimator.isAnimating()) {
Mike Lockwood435eb642009-12-03 08:40:18 -05001931 err = screenOffFinishedAnimatingLocked(reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001932 } else {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001933 err = 0;
1934 mLastTouchDown = 0;
1935 }
1936 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001937 } else if (stateChanged) {
1938 // Screen on/off didn't change, but lights may have.
1939 updateLightsLocked(newState, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001940 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001941
1942 mPowerState = (mPowerState & ~LIGHTS_MASK) | (newState & LIGHTS_MASK);
1943
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001944 updateNativePowerStateLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001945 }
1946 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001947
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001948 private void updateNativePowerStateLocked() {
Mike Lockwood3a74bd32011-08-12 13:55:22 -07001949 if (!mHeadless) {
1950 nativeSetPowerState(
1951 (mPowerState & SCREEN_ON_BIT) != 0,
1952 (mPowerState & SCREEN_BRIGHT) == SCREEN_BRIGHT);
1953 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001954 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001955
Mike Lockwood435eb642009-12-03 08:40:18 -05001956 private int screenOffFinishedAnimatingLocked(int reason) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001957 // I don't think we need to check the current state here because all of these
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001958 // Power.setScreenState and sendNotificationLocked can both handle being
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001959 // called multiple times in the same state. -joeo
Joe Onoratob08a1af2010-10-11 19:28:58 -07001960 EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, reason, mTotalTouchDownTime,
1961 mTouchCycles);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001962 mLastTouchDown = 0;
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001963 int err = setScreenStateLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001964 if (err == 0) {
Mike Lockwood435eb642009-12-03 08:40:18 -05001965 mScreenOffReason = reason;
1966 sendNotificationLocked(false, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001967 }
1968 return err;
1969 }
1970
1971 private boolean batteryIsLow() {
1972 return (!mIsPowered &&
Jeff Brown7304c342012-05-11 18:42:42 -07001973 mBatteryService.getBatteryLevel() <= LOW_BATTERY_THRESHOLD);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001974 }
1975
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001976 private boolean shouldDeferScreenOnLocked() {
1977 if (mPreparingForScreenOn) {
1978 // Currently waiting for confirmation from the policy that it
1979 // is okay to turn on the screen. Don't allow the screen to go
1980 // on until that is done.
1981 if (DEBUG_SCREEN_ON) Slog.i(TAG,
1982 "updateLights: delaying screen on due to mPreparingForScreenOn");
1983 return true;
1984 } else {
1985 // If there is a screen-on command in the notification queue, we
1986 // can't turn the screen on until it has been processed (and we
1987 // have set mPreparingForScreenOn) or it has been dropped.
1988 for (int i=0; i<mBroadcastQueue.length; i++) {
1989 if (mBroadcastQueue[i] == 1) {
1990 if (DEBUG_SCREEN_ON) Slog.i(TAG,
1991 "updateLights: delaying screen on due to notification queue");
1992 return true;
1993 }
1994 }
1995 }
1996 return false;
1997 }
1998
The Android Open Source Project10592532009-03-18 17:39:46 -07001999 private void updateLightsLocked(int newState, int forceState) {
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07002000 final int oldState = mPowerState;
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07002001
2002 // If the screen is not currently on, we will want to delay actually
2003 // turning the lights on if we are still getting the UI put up.
Jim Miller92e66dd2012-02-21 18:57:12 -08002004 if ((oldState & SCREEN_ON_BIT) == 0 || mSkippedScreenOn) {
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07002005 // Don't turn screen on until we know we are really ready to.
2006 // This is to avoid letting the screen go on before things like the
2007 // lock screen have been displayed.
Jim Miller92e66dd2012-02-21 18:57:12 -08002008 if ((mSkippedScreenOn = shouldDeferScreenOnLocked())) {
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07002009 newState &= ~(SCREEN_ON_BIT|SCREEN_BRIGHT_BIT);
2010 }
2011 }
2012
Joe Onorato60607a902010-10-23 14:49:30 -07002013 if ((newState & SCREEN_ON_BIT) != 0) {
2014 // Only turn on the buttons or keyboard if the screen is also on.
2015 // We should never see the buttons on but not the screen.
2016 newState = applyButtonState(newState);
2017 newState = applyKeyboardState(newState);
2018 }
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07002019 final int realDifference = (newState ^ oldState);
2020 final int difference = realDifference | forceState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002021 if (difference == 0) {
The Android Open Source Project10592532009-03-18 17:39:46 -07002022 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002023 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002024
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002025 int offMask = 0;
2026 int dimMask = 0;
2027 int onMask = 0;
2028
2029 int preferredBrightness = getPreferredBrightness();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002030
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002031 if ((difference & KEYBOARD_BRIGHT_BIT) != 0) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002032 if ((newState & KEYBOARD_BRIGHT_BIT) == 0) {
2033 offMask |= KEYBOARD_BRIGHT_BIT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002034 } else {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002035 onMask |= KEYBOARD_BRIGHT_BIT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002036 }
2037 }
2038
2039 if ((difference & BUTTON_BRIGHT_BIT) != 0) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002040 if ((newState & BUTTON_BRIGHT_BIT) == 0) {
2041 offMask |= BUTTON_BRIGHT_BIT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002042 } else {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002043 onMask |= BUTTON_BRIGHT_BIT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002044 }
2045 }
2046
2047 if ((difference & (SCREEN_ON_BIT | SCREEN_BRIGHT_BIT)) != 0) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002048 int nominalCurrentValue = -1;
2049 // If there was an actual difference in the light state, then
2050 // figure out the "ideal" current value based on the previous
2051 // state. Otherwise, this is a change due to the brightness
2052 // override, so we want to animate from whatever the current
2053 // value is.
2054 if ((realDifference & (SCREEN_ON_BIT | SCREEN_BRIGHT_BIT)) != 0) {
2055 switch (oldState & (SCREEN_BRIGHT_BIT|SCREEN_ON_BIT)) {
2056 case SCREEN_BRIGHT_BIT | SCREEN_ON_BIT:
2057 nominalCurrentValue = preferredBrightness;
2058 break;
2059 case SCREEN_ON_BIT:
Mike Lockwoodeb6456b2011-09-13 15:24:02 -04002060 nominalCurrentValue = mScreenBrightnessDim;
Joe Onoratob08a1af2010-10-11 19:28:58 -07002061 break;
2062 case 0:
Jeff Brown7304c342012-05-11 18:42:42 -07002063 nominalCurrentValue = PowerManager.BRIGHTNESS_OFF;
Joe Onoratob08a1af2010-10-11 19:28:58 -07002064 break;
2065 case SCREEN_BRIGHT_BIT:
2066 default:
2067 // not possible
Jim Miller92e66dd2012-02-21 18:57:12 -08002068 nominalCurrentValue = (int)mScreenBrightnessAnimator.getCurrentBrightness();
Joe Onoratob08a1af2010-10-11 19:28:58 -07002069 break;
Joe Onorato128e7292009-03-24 18:41:31 -07002070 }
Joe Onoratob08a1af2010-10-11 19:28:58 -07002071 }
2072 int brightness = preferredBrightness;
2073 int steps = ANIM_STEPS;
2074 if ((newState & SCREEN_BRIGHT_BIT) == 0) {
2075 // dim or turn off backlight, depending on if the screen is on
2076 // the scale is because the brightness ramp isn't linear and this biases
2077 // it so the later parts take longer.
2078 final float scale = 1.5f;
Mike Lockwoodeb6456b2011-09-13 15:24:02 -04002079 float ratio = (((float)mScreenBrightnessDim)/preferredBrightness);
Joe Onoratob08a1af2010-10-11 19:28:58 -07002080 if (ratio > 1.0f) ratio = 1.0f;
2081 if ((newState & SCREEN_ON_BIT) == 0) {
2082 if ((oldState & SCREEN_BRIGHT_BIT) != 0) {
2083 // was bright
2084 steps = ANIM_STEPS;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002085 } else {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002086 // was dim
2087 steps = (int)(ANIM_STEPS*ratio*scale);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002088 }
Jeff Brown7304c342012-05-11 18:42:42 -07002089 brightness = PowerManager.BRIGHTNESS_OFF;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002090 } else {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002091 if ((oldState & SCREEN_ON_BIT) != 0) {
2092 // was bright
2093 steps = (int)(ANIM_STEPS*(1.0f-ratio)*scale);
2094 } else {
2095 // was dim
2096 steps = (int)(ANIM_STEPS*ratio);
2097 }
2098 if (mStayOnConditions != 0 && mBatteryService.isPowered(mStayOnConditions)) {
2099 // If the "stay on while plugged in" option is
2100 // turned on, then the screen will often not
2101 // automatically turn off while plugged in. To
2102 // still have a sense of when it is inactive, we
2103 // will then count going dim as turning off.
2104 mScreenOffTime = SystemClock.elapsedRealtime();
2105 }
Mike Lockwoodeb6456b2011-09-13 15:24:02 -04002106 brightness = mScreenBrightnessDim;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002107 }
2108 }
Craig Mautner75fc9de2012-06-18 16:53:27 -07002109 if (mWaitingForFirstLightSensor && (newState & SCREEN_ON_BIT) != 0) {
2110 steps = IMMEDIATE_ANIM_STEPS;
2111 }
2112
Joe Onoratob08a1af2010-10-11 19:28:58 -07002113 long identity = Binder.clearCallingIdentity();
2114 try {
2115 mBatteryStats.noteScreenBrightness(brightness);
2116 } catch (RemoteException e) {
2117 // Nothing interesting to do.
2118 } finally {
2119 Binder.restoreCallingIdentity(identity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002120 }
Dianne Hackborn81de8b92011-11-28 16:54:31 -08002121 if (!mSkippedScreenOn) {
Jim Miller92e66dd2012-02-21 18:57:12 -08002122 int dt = steps * NOMINAL_FRAME_TIME_MS;
2123 mScreenBrightnessAnimator.animateTo(brightness, SCREEN_BRIGHT_BIT, dt);
Dianne Hackborn81de8b92011-11-28 16:54:31 -08002124 if (DEBUG_SCREEN_ON) {
2125 RuntimeException e = new RuntimeException("here");
2126 e.fillInStackTrace();
2127 Slog.i(TAG, "Setting screen brightness: " + brightness, e);
2128 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07002129 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002130 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002131
Joe Onorato60607a902010-10-23 14:49:30 -07002132 if (mSpew) {
2133 Slog.d(TAG, "offMask=0x" + Integer.toHexString(offMask)
2134 + " dimMask=0x" + Integer.toHexString(dimMask)
2135 + " onMask=0x" + Integer.toHexString(onMask)
2136 + " difference=0x" + Integer.toHexString(difference)
2137 + " realDifference=0x" + Integer.toHexString(realDifference)
2138 + " forceState=0x" + Integer.toHexString(forceState)
2139 );
2140 }
2141
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002142 if (offMask != 0) {
Mike Lockwood48358bd2010-04-17 22:29:20 -04002143 if (mSpew) Slog.i(TAG, "Setting brightess off: " + offMask);
Jeff Brown7304c342012-05-11 18:42:42 -07002144 setLightBrightness(offMask, PowerManager.BRIGHTNESS_OFF);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002145 }
2146 if (dimMask != 0) {
Mike Lockwoodeb6456b2011-09-13 15:24:02 -04002147 int brightness = mScreenBrightnessDim;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002148 if ((newState & BATTERY_LOW_BIT) != 0 &&
Jeff Brown7304c342012-05-11 18:42:42 -07002149 brightness > PowerManager.BRIGHTNESS_LOW_BATTERY) {
2150 brightness = PowerManager.BRIGHTNESS_LOW_BATTERY;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002151 }
Mike Lockwood48358bd2010-04-17 22:29:20 -04002152 if (mSpew) Slog.i(TAG, "Setting brightess dim " + brightness + ": " + dimMask);
The Android Open Source Project10592532009-03-18 17:39:46 -07002153 setLightBrightness(dimMask, brightness);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002154 }
2155 if (onMask != 0) {
2156 int brightness = getPreferredBrightness();
2157 if ((newState & BATTERY_LOW_BIT) != 0 &&
Jeff Brown7304c342012-05-11 18:42:42 -07002158 brightness > PowerManager.BRIGHTNESS_LOW_BATTERY) {
2159 brightness = PowerManager.BRIGHTNESS_LOW_BATTERY;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002160 }
Mike Lockwood48358bd2010-04-17 22:29:20 -04002161 if (mSpew) Slog.i(TAG, "Setting brightess on " + brightness + ": " + onMask);
The Android Open Source Project10592532009-03-18 17:39:46 -07002162 setLightBrightness(onMask, brightness);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002163 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002164 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002165
Jim Miller92e66dd2012-02-21 18:57:12 -08002166 /**
2167 * Note: by design this class does not hold mLocks while calling native methods.
2168 * Nor should it. Ever.
2169 */
2170 class ScreenBrightnessAnimator extends HandlerThread {
2171 static final int ANIMATE_LIGHTS = 10;
Jim Miller46f31c32012-03-01 14:36:07 -08002172 static final int ANIMATE_POWER_OFF = 11;
Jim Miller92e66dd2012-02-21 18:57:12 -08002173 volatile int startValue;
2174 volatile int endValue;
Craig Mautner196943f2012-05-15 08:10:35 -07002175 volatile int startSensorValue;
2176 volatile int endSensorValue;
Jim Miller92e66dd2012-02-21 18:57:12 -08002177 volatile int currentValue;
2178 private int currentMask;
2179 private int duration;
2180 private long startTimeMillis;
2181 private final String prefix;
2182
2183 public ScreenBrightnessAnimator(String name, int priority) {
2184 super(name, priority);
2185 prefix = name;
2186 }
2187
2188 @Override
2189 protected void onLooperPrepared() {
2190 mScreenBrightnessHandler = new Handler() {
2191 public void handleMessage(Message msg) {
2192 int brightnessMode = (mAutoBrightessEnabled && !mInitialAnimation
Mike Lockwood3a322132009-11-24 00:30:52 -05002193 ? LightsService.BRIGHTNESS_MODE_SENSOR
2194 : LightsService.BRIGHTNESS_MODE_USER);
Jim Miller92e66dd2012-02-21 18:57:12 -08002195 if (msg.what == ANIMATE_LIGHTS) {
2196 final int mask = msg.arg1;
2197 int value = msg.arg2;
2198 long tStart = SystemClock.uptimeMillis();
2199 if ((mask & SCREEN_BRIGHT_BIT) != 0) {
Craig Mautner196943f2012-05-15 08:10:35 -07002200 if (mDebugLightAnimation) Slog.v(TAG, "Set brightness: " + value);
Jim Miller92e66dd2012-02-21 18:57:12 -08002201 mLcdLight.setBrightness(value, brightnessMode);
2202 }
2203 long elapsed = SystemClock.uptimeMillis() - tStart;
2204 if ((mask & BUTTON_BRIGHT_BIT) != 0) {
2205 mButtonLight.setBrightness(value);
2206 }
2207 if ((mask & KEYBOARD_BRIGHT_BIT) != 0) {
2208 mKeyboardLight.setBrightness(value);
2209 }
2210
2211 if (elapsed > 100) {
Craig Mautner196943f2012-05-15 08:10:35 -07002212 Slog.e(TAG, "Excessive delay setting brightness: " + elapsed
Jim Miller92e66dd2012-02-21 18:57:12 -08002213 + "ms, mask=" + mask);
2214 }
2215
2216 // Throttle brightness updates to frame refresh rate
Craig Mautner196943f2012-05-15 08:10:35 -07002217 int delay = elapsed < NOMINAL_FRAME_TIME_MS ? NOMINAL_FRAME_TIME_MS : 1;
Jim Miller92e66dd2012-02-21 18:57:12 -08002218 synchronized(this) {
2219 currentValue = value;
2220 }
2221 animateInternal(mask, false, delay);
Jim Miller46f31c32012-03-01 14:36:07 -08002222 } else if (msg.what == ANIMATE_POWER_OFF) {
2223 int mode = msg.arg1;
2224 nativeStartSurfaceFlingerAnimation(mode);
Jim Miller92e66dd2012-02-21 18:57:12 -08002225 }
2226 }
2227 };
2228 synchronized (this) {
2229 mInitComplete = true;
2230 notifyAll();
Dianne Hackborn81de8b92011-11-28 16:54:31 -08002231 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002232 }
Jim Miller92e66dd2012-02-21 18:57:12 -08002233
2234 private void animateInternal(int mask, boolean turningOff, int delay) {
2235 synchronized (this) {
2236 if (currentValue != endValue) {
2237 final long now = SystemClock.elapsedRealtime();
2238 final int elapsed = (int) (now - startTimeMillis);
2239 int newValue;
2240 if (elapsed < duration) {
2241 int delta = endValue - startValue;
2242 newValue = startValue + delta * elapsed / duration;
Jeff Brown7304c342012-05-11 18:42:42 -07002243 newValue = Math.max(PowerManager.BRIGHTNESS_OFF, newValue);
2244 newValue = Math.min(PowerManager.BRIGHTNESS_ON, newValue);
Craig Mautner196943f2012-05-15 08:10:35 -07002245 // Optimization to delay next step until a change will occur.
2246 if (delay > 0 && newValue == currentValue) {
2247 final int timePerStep = duration / Math.abs(delta);
2248 delay = Math.min(duration - elapsed, timePerStep);
2249 newValue += delta < 0 ? -1 : 1;
2250 }
2251 // adjust the peak sensor value until we get to the target sensor value
2252 delta = endSensorValue - startSensorValue;
2253 mHighestLightSensorValue = startSensorValue + delta * elapsed / duration;
Jim Miller92e66dd2012-02-21 18:57:12 -08002254 } else {
2255 newValue = endValue;
Craig Mautner196943f2012-05-15 08:10:35 -07002256 mHighestLightSensorValue = endSensorValue;
Craig Mautneraf01fe02012-05-31 10:03:32 -07002257 if (endValue > 0) {
2258 mInitialAnimation = false;
2259 }
Jim Miller92e66dd2012-02-21 18:57:12 -08002260 }
2261
2262 if (mDebugLightAnimation) {
Craig Mautner196943f2012-05-15 08:10:35 -07002263 Slog.v(TAG, "Animating light: " + "start:" + startValue
Jim Miller92e66dd2012-02-21 18:57:12 -08002264 + ", end:" + endValue + ", elapsed:" + elapsed
2265 + ", duration:" + duration + ", current:" + currentValue
Craig Mautner196943f2012-05-15 08:10:35 -07002266 + ", newValue:" + newValue
2267 + ", delay:" + delay
2268 + ", highestSensor:" + mHighestLightSensorValue);
Jim Miller92e66dd2012-02-21 18:57:12 -08002269 }
2270
Jim Miller46f31c32012-03-01 14:36:07 -08002271 if (turningOff && !mHeadless && !mAnimateScreenLights) {
Jim Miller92e66dd2012-02-21 18:57:12 -08002272 int mode = mScreenOffReason == OFF_BECAUSE_OF_PROX_SENSOR
2273 ? 0 : mAnimationSetting;
Craig Mautner196943f2012-05-15 08:10:35 -07002274 if (mDebugLightAnimation) {
2275 Slog.v(TAG, "Doing power-off anim, mode=" + mode);
2276 }
Jim Miller46f31c32012-03-01 14:36:07 -08002277 mScreenBrightnessHandler.obtainMessage(ANIMATE_POWER_OFF, mode, 0)
2278 .sendToTarget();
Jim Miller92e66dd2012-02-21 18:57:12 -08002279 }
Craig Mautner196943f2012-05-15 08:10:35 -07002280 mScreenBrightnessHandler.removeMessages(
2281 ScreenBrightnessAnimator.ANIMATE_LIGHTS);
Jim Miller92e66dd2012-02-21 18:57:12 -08002282 Message msg = mScreenBrightnessHandler
2283 .obtainMessage(ANIMATE_LIGHTS, mask, newValue);
2284 mScreenBrightnessHandler.sendMessageDelayed(msg, delay);
2285 }
2286 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002287 }
Jim Miller92e66dd2012-02-21 18:57:12 -08002288
2289 public void dump(PrintWriter pw, String string) {
Craig Mautner291576e2012-06-07 19:58:58 -07002290 pw.println(string);
2291 pw.println(" animating: " + "start:" + startValue + ", end:" + endValue
Jim Miller92e66dd2012-02-21 18:57:12 -08002292 + ", duration:" + duration + ", current:" + currentValue);
Craig Mautner291576e2012-06-07 19:58:58 -07002293 pw.println(" startSensorValue:" + startSensorValue
2294 + " endSensorValue:" + endSensorValue);
2295 pw.println(" startSensorValue:" + startSensorValue
2296 + " endSensorValue:" + endSensorValue);
Jim Miller92e66dd2012-02-21 18:57:12 -08002297 }
2298
2299 public void animateTo(int target, int mask, int animationDuration) {
Craig Mautner196943f2012-05-15 08:10:35 -07002300 animateTo(target, mHighestLightSensorValue, mask, animationDuration);
2301 }
2302
2303 public void animateTo(int target, int sensorTarget, int mask, int animationDuration) {
Jim Miller92e66dd2012-02-21 18:57:12 -08002304 synchronized(this) {
Craig Mautner291576e2012-06-07 19:58:58 -07002305 if ((mask & SCREEN_BRIGHT_BIT) == 0) {
2306 // We only animate keyboard and button when passed in with SCREEN_BRIGHT_BIT.
2307 if ((mask & BUTTON_BRIGHT_BIT) != 0) {
2308 mButtonLight.setBrightness(target);
2309 }
2310 if ((mask & KEYBOARD_BRIGHT_BIT) != 0) {
2311 mKeyboardLight.setBrightness(target);
2312 }
2313 return;
2314 }
Craig Mautnerd29568c2012-06-01 16:02:47 -07002315 if (isAnimating() && (mask ^ currentMask) != 0) {
2316 // current animation is unrelated to new animation, jump to final values
2317 cancelAnimation();
2318 }
Jim Miller92e66dd2012-02-21 18:57:12 -08002319 startValue = currentValue;
2320 endValue = target;
Craig Mautner196943f2012-05-15 08:10:35 -07002321 startSensorValue = mHighestLightSensorValue;
2322 endSensorValue = sensorTarget;
Jim Miller92e66dd2012-02-21 18:57:12 -08002323 currentMask = mask;
2324 duration = (int) (mWindowScaleAnimation * animationDuration);
2325 startTimeMillis = SystemClock.elapsedRealtime();
Craig Mautneraf01fe02012-05-31 10:03:32 -07002326 mInitialAnimation = mInitialAnimation && target > 0;
Jim Miller92e66dd2012-02-21 18:57:12 -08002327
2328 if (mDebugLightAnimation) {
Craig Mautner196943f2012-05-15 08:10:35 -07002329 Slog.v(TAG, "animateTo(target=" + target
2330 + ", sensor=" + sensorTarget
2331 + ", mask=" + mask
Jim Miller92e66dd2012-02-21 18:57:12 -08002332 + ", duration=" + animationDuration +")"
2333 + ", currentValue=" + currentValue
2334 + ", startTime=" + startTimeMillis);
2335 }
2336
2337 if (target != currentValue) {
Jim Miller18651802012-03-07 14:19:56 -08002338 final boolean doScreenAnim = (mask & (SCREEN_BRIGHT_BIT | SCREEN_ON_BIT)) != 0;
Jeff Brown7304c342012-05-11 18:42:42 -07002339 final boolean turningOff = endValue == PowerManager.BRIGHTNESS_OFF;
Jim Miller18651802012-03-07 14:19:56 -08002340 if (turningOff && doScreenAnim) {
Jim Miller92e66dd2012-02-21 18:57:12 -08002341 // Cancel all pending animations since we're turning off
2342 mScreenBrightnessHandler.removeCallbacksAndMessages(null);
2343 screenOffFinishedAnimatingLocked(mScreenOffReason);
2344 duration = 200; // TODO: how long should this be?
2345 }
Jim Miller18651802012-03-07 14:19:56 -08002346 if (doScreenAnim) {
2347 animateInternal(mask, turningOff, 0);
2348 }
2349 // TODO: Handle keyboard light animation when we have devices that support it
Jim Miller92e66dd2012-02-21 18:57:12 -08002350 }
2351 }
2352 }
2353
2354 public int getCurrentBrightness() {
2355 synchronized (this) {
2356 return currentValue;
2357 }
2358 }
2359
2360 public boolean isAnimating() {
2361 synchronized (this) {
2362 return currentValue != endValue;
2363 }
2364 }
2365
2366 public void cancelAnimation() {
2367 animateTo(endValue, currentMask, 0);
The Android Open Source Project10592532009-03-18 17:39:46 -07002368 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002369 }
2370
Jim Miller92e66dd2012-02-21 18:57:12 -08002371 private void setLightBrightness(int mask, int value) {
2372 mScreenBrightnessAnimator.animateTo(value, mask, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002373 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002374
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002375 private int getPreferredBrightness() {
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002376 if (mScreenBrightnessOverride >= 0) {
2377 return mScreenBrightnessOverride;
2378 } else if (mLightSensorScreenBrightness >= 0 && mUseSoftwareAutoBrightness
2379 && mAutoBrightessEnabled) {
2380 return mLightSensorScreenBrightness;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002381 }
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002382 final int brightness = mScreenBrightnessSetting;
2383 // Don't let applications turn the screen all the way off
2384 return Math.max(brightness, mScreenBrightnessDim);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002385 }
2386
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002387 private int applyButtonState(int state) {
2388 int brightness = -1;
Mike Lockwood48358bd2010-04-17 22:29:20 -04002389 if ((state & BATTERY_LOW_BIT) != 0) {
2390 // do not override brightness if the battery is low
2391 return state;
2392 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002393 if (mButtonBrightnessOverride >= 0) {
2394 brightness = mButtonBrightnessOverride;
2395 } else if (mLightSensorButtonBrightness >= 0 && mUseSoftwareAutoBrightness) {
2396 brightness = mLightSensorButtonBrightness;
2397 }
2398 if (brightness > 0) {
2399 return state | BUTTON_BRIGHT_BIT;
2400 } else if (brightness == 0) {
2401 return state & ~BUTTON_BRIGHT_BIT;
2402 } else {
2403 return state;
2404 }
2405 }
2406
2407 private int applyKeyboardState(int state) {
2408 int brightness = -1;
Mike Lockwood48358bd2010-04-17 22:29:20 -04002409 if ((state & BATTERY_LOW_BIT) != 0) {
2410 // do not override brightness if the battery is low
2411 return state;
2412 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002413 if (!mKeyboardVisible) {
2414 brightness = 0;
2415 } else if (mButtonBrightnessOverride >= 0) {
2416 brightness = mButtonBrightnessOverride;
2417 } else if (mLightSensorKeyboardBrightness >= 0 && mUseSoftwareAutoBrightness) {
2418 brightness = mLightSensorKeyboardBrightness;
2419 }
2420 if (brightness > 0) {
2421 return state | KEYBOARD_BRIGHT_BIT;
2422 } else if (brightness == 0) {
2423 return state & ~KEYBOARD_BRIGHT_BIT;
2424 } else {
2425 return state;
2426 }
2427 }
2428
Charles Mendis322591c2009-10-29 11:06:59 -07002429 public boolean isScreenOn() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002430 synchronized (mLocks) {
2431 return (mPowerState & SCREEN_ON_BIT) != 0;
2432 }
2433 }
2434
Charles Mendis322591c2009-10-29 11:06:59 -07002435 boolean isScreenBright() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002436 synchronized (mLocks) {
2437 return (mPowerState & SCREEN_BRIGHT) == SCREEN_BRIGHT;
2438 }
2439 }
2440
Mike Lockwood497087e32009-11-08 18:33:03 -05002441 private boolean isScreenTurningOffLocked() {
Jim Miller92e66dd2012-02-21 18:57:12 -08002442 return (mScreenBrightnessAnimator.isAnimating()
Craig Mautnerd29568c2012-06-01 16:02:47 -07002443 && mScreenBrightnessAnimator.endValue == PowerManager.BRIGHTNESS_OFF
2444 && (mScreenBrightnessAnimator.currentMask & SCREEN_BRIGHT_BIT) != 0);
Mike Lockwood497087e32009-11-08 18:33:03 -05002445 }
2446
Joe Onorato4b9f62d2010-10-11 13:41:35 -07002447 private boolean shouldLog(long time) {
2448 synchronized (mLocks) {
2449 if (time > (mWarningSpewThrottleTime + (60*60*1000))) {
2450 mWarningSpewThrottleTime = time;
2451 mWarningSpewThrottleCount = 0;
2452 return true;
2453 } else if (mWarningSpewThrottleCount < 30) {
2454 mWarningSpewThrottleCount++;
2455 return true;
2456 } else {
2457 return false;
2458 }
2459 }
2460 }
2461
Mike Lockwood200b30b2009-09-20 00:23:59 -04002462 private void forceUserActivityLocked() {
Mike Lockwoode090281422009-11-14 21:02:56 -05002463 if (isScreenTurningOffLocked()) {
2464 // cancel animation so userActivity will succeed
Jim Miller92e66dd2012-02-21 18:57:12 -08002465 mScreenBrightnessAnimator.cancelAnimation();
Mike Lockwoode090281422009-11-14 21:02:56 -05002466 }
Mike Lockwood200b30b2009-09-20 00:23:59 -04002467 boolean savedActivityAllowed = mUserActivityAllowed;
2468 mUserActivityAllowed = true;
2469 userActivity(SystemClock.uptimeMillis(), false);
2470 mUserActivityAllowed = savedActivityAllowed;
2471 }
2472
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002473 public void userActivityWithForce(long time, boolean noChangeLights, boolean force) {
2474 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
Joe Onorato7999bff2010-07-24 11:50:05 -04002475 userActivity(time, -1, noChangeLights, OTHER_EVENT, force);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002476 }
2477
2478 public void userActivity(long time, boolean noChangeLights) {
Joe Onorato4b9f62d2010-10-11 13:41:35 -07002479 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER)
2480 != PackageManager.PERMISSION_GRANTED) {
2481 if (shouldLog(time)) {
2482 Slog.w(TAG, "Caller does not have DEVICE_POWER permission. pid="
2483 + Binder.getCallingPid() + " uid=" + Binder.getCallingUid());
2484 }
2485 return;
2486 }
2487
Joe Onorato7999bff2010-07-24 11:50:05 -04002488 userActivity(time, -1, noChangeLights, OTHER_EVENT, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002489 }
2490
2491 public void userActivity(long time, boolean noChangeLights, int eventType) {
Joe Onorato7999bff2010-07-24 11:50:05 -04002492 userActivity(time, -1, noChangeLights, eventType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002493 }
2494
2495 public void userActivity(long time, boolean noChangeLights, int eventType, boolean force) {
Joe Onorato7999bff2010-07-24 11:50:05 -04002496 userActivity(time, -1, noChangeLights, eventType, force);
2497 }
2498
2499 /*
2500 * Reset the user activity timeout to now + timeout. This overrides whatever else is going
2501 * on with user activity. Don't use this function.
2502 */
2503 public void clearUserActivityTimeout(long now, long timeout) {
2504 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
2505 Slog.i(TAG, "clearUserActivity for " + timeout + "ms from now");
2506 userActivity(now, timeout, false, OTHER_EVENT, false);
2507 }
2508
2509 private void userActivity(long time, long timeoutOverride, boolean noChangeLights,
2510 int eventType, boolean force) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002511
Joe Onorato1a542c72010-11-08 09:48:20 -08002512 if (((mPokey & POKE_LOCK_IGNORE_TOUCH_EVENTS) != 0) && (eventType == TOUCH_EVENT)) {
Joe Onoratoe68ffcb2009-03-24 19:11:13 -07002513 if (false) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002514 Slog.d(TAG, "dropping touch mPokey=0x" + Integer.toHexString(mPokey));
Joe Onoratoe68ffcb2009-03-24 19:11:13 -07002515 }
2516 return;
2517 }
2518
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002519 synchronized (mLocks) {
2520 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002521 Slog.d(TAG, "userActivity mLastEventTime=" + mLastEventTime + " time=" + time
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002522 + " mUserActivityAllowed=" + mUserActivityAllowed
2523 + " mUserState=0x" + Integer.toHexString(mUserState)
Mike Lockwood36fc3022009-08-25 16:49:06 -07002524 + " mWakeLockState=0x" + Integer.toHexString(mWakeLockState)
2525 + " mProximitySensorActive=" + mProximitySensorActive
Joe Onorato797e6882010-08-26 14:46:01 -04002526 + " timeoutOverride=" + timeoutOverride
Mike Lockwood36fc3022009-08-25 16:49:06 -07002527 + " force=" + force);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002528 }
Mike Lockwood05067122009-10-27 23:07:25 -04002529 // ignore user activity if we are in the process of turning off the screen
Mike Lockwood497087e32009-11-08 18:33:03 -05002530 if (isScreenTurningOffLocked()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002531 Slog.d(TAG, "ignoring user activity while turning off screen");
Mike Lockwood05067122009-10-27 23:07:25 -04002532 return;
2533 }
Mike Lockwood0e39ea82009-11-18 15:37:10 -05002534 // Disable proximity sensor if if user presses power key while we are in the
2535 // "waiting for proximity sensor to go negative" state.
2536 if (mProximitySensorActive && mProximityWakeLockCount == 0) {
2537 mProximitySensorActive = false;
2538 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002539 if (mLastEventTime <= time || force) {
2540 mLastEventTime = time;
Mike Lockwood36fc3022009-08-25 16:49:06 -07002541 if ((mUserActivityAllowed && !mProximitySensorActive) || force) {
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002542 // Only turn on button backlights if a button was pressed
2543 // and auto brightness is disabled
Mike Lockwood4984e732009-11-01 08:16:33 -05002544 if (eventType == BUTTON_EVENT && !mUseSoftwareAutoBrightness) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002545 mUserState = (mKeyboardVisible ? ALL_BRIGHT : SCREEN_BUTTON_BRIGHT);
2546 } else {
2547 // don't clear button/keyboard backlights when the screen is touched.
2548 mUserState |= SCREEN_BRIGHT;
2549 }
2550
Dianne Hackborn617f8772009-03-31 15:04:46 -07002551 int uid = Binder.getCallingUid();
2552 long ident = Binder.clearCallingIdentity();
2553 try {
2554 mBatteryStats.noteUserActivity(uid, eventType);
2555 } catch (RemoteException e) {
2556 // Ignore
2557 } finally {
2558 Binder.restoreCallingIdentity(ident);
2559 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002560
Michael Chane96440f2009-05-06 10:27:36 -07002561 mWakeLockState = mLocks.reactivateScreenLocksLocked();
Mike Lockwood435eb642009-12-03 08:40:18 -05002562 setPowerState(mUserState | mWakeLockState, noChangeLights,
2563 WindowManagerPolicy.OFF_BECAUSE_OF_USER);
Joe Onorato7999bff2010-07-24 11:50:05 -04002564 setTimeoutLocked(time, timeoutOverride, SCREEN_BRIGHT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002565 }
2566 }
2567 }
Mike Lockwoodef731622010-01-27 17:51:34 -05002568
2569 if (mPolicy != null) {
2570 mPolicy.userActivity();
2571 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002572 }
2573
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002574 private int getAutoBrightnessValue(int sensorValue, int[] values) {
2575 try {
2576 int i;
2577 for (i = 0; i < mAutoBrightnessLevels.length; i++) {
2578 if (sensorValue < mAutoBrightnessLevels[i]) {
2579 break;
2580 }
2581 }
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002582 // This is the range of brightness values that we can use.
2583 final int minval = values[0];
2584 final int maxval = values[mAutoBrightnessLevels.length];
2585 // This is the range we will be scaling. We put some padding
2586 // at the low and high end to give the adjustment a little better
2587 // impact on the actual observed value.
2588 final int range = (maxval-minval) + LIGHT_SENSOR_RANGE_EXPANSION;
2589 // This is the desired brightness value from 0.0 to 1.0.
2590 float valf = ((values[i]-minval+(LIGHT_SENSOR_RANGE_EXPANSION/2))/(float)range);
2591 // Apply a scaling to the value based on the adjustment.
2592 if (mLightSensorAdjustSetting > 0 && mLightSensorAdjustSetting <= 1) {
2593 float adj = (float)Math.sqrt(1.0f-mLightSensorAdjustSetting);
2594 if (adj <= .00001) {
2595 valf = 1;
2596 } else {
2597 valf /= adj;
2598 }
2599 } else if (mLightSensorAdjustSetting < 0 && mLightSensorAdjustSetting >= -1) {
2600 float adj = (float)Math.sqrt(1.0f+mLightSensorAdjustSetting);
2601 valf *= adj;
2602 }
2603 // Apply an additional offset to the value based on the adjustment.
2604 valf += mLightSensorAdjustSetting/LIGHT_SENSOR_OFFSET_SCALE;
2605 // Convert the 0.0-1.0 value back to a brightness integer.
2606 int val = (int)((valf*range)+minval) - (LIGHT_SENSOR_RANGE_EXPANSION/2);
2607 if (val < minval) val = minval;
2608 else if (val > maxval) val = maxval;
2609 return val;
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002610 } catch (Exception e) {
2611 // guard against null pointer or index out of bounds errors
Jeff Browndaa37532012-05-01 15:54:03 -07002612 Slog.e(TAG, "Values array must be non-empty and must be one element longer than "
2613 + "the auto-brightness levels array. Check config.xml.", e);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002614 return 255;
2615 }
2616 }
2617
Mike Lockwood20f87d72009-11-05 16:08:51 -05002618 private Runnable mProximityTask = new Runnable() {
2619 public void run() {
2620 synchronized (mLocks) {
2621 if (mProximityPendingValue != -1) {
2622 proximityChangedLocked(mProximityPendingValue == 1);
2623 mProximityPendingValue = -1;
2624 }
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -05002625 if (mProximityPartialLock.isHeld()) {
2626 mProximityPartialLock.release();
2627 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05002628 }
2629 }
2630 };
2631
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002632 private Runnable mAutoBrightnessTask = new Runnable() {
2633 public void run() {
Mike Lockwoodfa68ab42009-10-20 11:08:49 -04002634 synchronized (mLocks) {
Jim Rodovichd102fea2010-09-02 12:30:49 -05002635 if (mLightSensorPendingDecrease || mLightSensorPendingIncrease) {
2636 int value = (int)mLightSensorPendingValue;
2637 mLightSensorPendingDecrease = false;
2638 mLightSensorPendingIncrease = false;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002639 lightSensorChangedLocked(value, false);
Mike Lockwoodfa68ab42009-10-20 11:08:49 -04002640 }
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002641 }
2642 }
2643 };
2644
Craig Mautneraf01fe02012-05-31 10:03:32 -07002645 /** used to prevent lightsensor changes while turning on. */
2646 private boolean mInitialAnimation = true;
Jim Miller92e66dd2012-02-21 18:57:12 -08002647
Mike Lockwoodb2865412010-02-02 22:40:33 -05002648 private void dockStateChanged(int state) {
2649 synchronized (mLocks) {
2650 mIsDocked = (state != Intent.EXTRA_DOCK_STATE_UNDOCKED);
2651 if (mIsDocked) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04002652 // allow brightness to decrease when docked
Mike Lockwoodb2865412010-02-02 22:40:33 -05002653 mHighestLightSensorValue = -1;
2654 }
2655 if ((mPowerState & SCREEN_ON_BIT) != 0) {
2656 // force lights recalculation
2657 int value = (int)mLightSensorValue;
2658 mLightSensorValue = -1;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002659 lightSensorChangedLocked(value, false);
Mike Lockwoodb2865412010-02-02 22:40:33 -05002660 }
2661 }
2662 }
2663
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002664 private void lightSensorChangedLocked(int value, boolean immediate) {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002665 if (mDebugLightSensor) {
Craig Mautner37933682012-06-06 14:13:39 -07002666 Slog.d(TAG, "lightSensorChangedLocked value=" + value + " immediate=" + immediate);
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002667 }
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002668
Joe Onorato06eb33a2010-10-25 14:09:21 -07002669 // Don't do anything if the screen is off.
2670 if ((mPowerState & SCREEN_ON_BIT) == 0) {
2671 if (mDebugLightSensor) {
2672 Slog.d(TAG, "dropping lightSensorChangedLocked because screen is off");
2673 }
2674 return;
2675 }
2676
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002677 if (mLightSensorValue != value) {
2678 mLightSensorValue = value;
2679 if ((mPowerState & BATTERY_LOW_BIT) == 0) {
Mike Lockwoodb2865412010-02-02 22:40:33 -05002680 // use maximum light sensor value seen since screen went on for LCD to avoid flicker
2681 // we only do this if we are undocked, since lighting should be stable when
2682 // stationary in a dock.
Craig Mautner196943f2012-05-15 08:10:35 -07002683 int lcdValue = getAutoBrightnessValue(value, mLcdBacklightValues);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002684 int buttonValue = getAutoBrightnessValue(value, mButtonBacklightValues);
Mike Lockwooddf024922009-10-29 21:29:15 -04002685 int keyboardValue;
2686 if (mKeyboardVisible) {
2687 keyboardValue = getAutoBrightnessValue(value, mKeyboardBacklightValues);
2688 } else {
2689 keyboardValue = 0;
2690 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002691 mLightSensorScreenBrightness = lcdValue;
2692 mLightSensorButtonBrightness = buttonValue;
2693 mLightSensorKeyboardBrightness = keyboardValue;
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002694
2695 if (mDebugLightSensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002696 Slog.d(TAG, "lcdValue " + lcdValue);
2697 Slog.d(TAG, "buttonValue " + buttonValue);
2698 Slog.d(TAG, "keyboardValue " + keyboardValue);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002699 }
2700
Mike Lockwood4984e732009-11-01 08:16:33 -05002701 if (mAutoBrightessEnabled && mScreenBrightnessOverride < 0) {
Jim Miller92e66dd2012-02-21 18:57:12 -08002702 if (!mSkippedScreenOn && !mInitialAnimation) {
Craig Mautner291576e2012-06-07 19:58:58 -07002703 final int steps;
2704 if (immediate) {
2705 steps = IMMEDIATE_ANIM_STEPS;
2706 } else {
2707 synchronized (mScreenBrightnessAnimator) {
2708 if (mScreenBrightnessAnimator.currentValue <= lcdValue) {
2709 steps = AUTOBRIGHTNESS_ANIM_STEPS;
2710 } else {
2711 steps = AUTODIMNESS_ANIM_STEPS;
2712 }
2713 }
2714 }
Craig Mautner196943f2012-05-15 08:10:35 -07002715 mScreenBrightnessAnimator.animateTo(lcdValue, value,
Jim Miller92e66dd2012-02-21 18:57:12 -08002716 SCREEN_BRIGHT_BIT, steps * NOMINAL_FRAME_TIME_MS);
Dianne Hackborn81de8b92011-11-28 16:54:31 -08002717 }
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002718 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002719 if (mButtonBrightnessOverride < 0) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002720 mButtonLight.setBrightness(buttonValue);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002721 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002722 if (mButtonBrightnessOverride < 0 || !mKeyboardVisible) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002723 mKeyboardLight.setBrightness(keyboardValue);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002724 }
2725 }
2726 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002727 }
2728
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002729 /**
2730 * The user requested that we go to sleep (probably with the power button).
2731 * This overrides all wake locks that are held.
2732 */
2733 public void goToSleep(long time)
2734 {
Dianne Hackborn254cb442010-01-27 19:23:59 -08002735 goToSleepWithReason(time, WindowManagerPolicy.OFF_BECAUSE_OF_USER);
2736 }
2737
2738 /**
2739 * The user requested that we go to sleep (probably with the power button).
2740 * This overrides all wake locks that are held.
2741 */
2742 public void goToSleepWithReason(long time, int reason)
2743 {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002744 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
2745 synchronized (mLocks) {
Dianne Hackborn254cb442010-01-27 19:23:59 -08002746 goToSleepLocked(time, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002747 }
2748 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002749
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002750 /**
Doug Zongker50a21f42009-11-19 12:49:53 -08002751 * Reboot the device immediately, passing 'reason' (may be null)
2752 * to the underlying __reboot system call. Should not return.
2753 */
2754 public void reboot(String reason)
2755 {
2756 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
San Mehat14e69af2010-01-06 14:58:18 -08002757
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002758 if (mHandler == null || !ActivityManagerNative.isSystemReady()) {
2759 throw new IllegalStateException("Too early to call reboot()");
2760 }
Mike Lockwoodb62f9592010-03-12 07:55:23 -05002761
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002762 final String finalReason = reason;
2763 Runnable runnable = new Runnable() {
2764 public void run() {
2765 synchronized (this) {
2766 ShutdownThread.reboot(mContext, finalReason, false);
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002767 }
Jim Miller92e66dd2012-02-21 18:57:12 -08002768
San Mehat1e512792010-01-07 10:40:29 -08002769 }
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002770 };
Mike Lockwoodb62f9592010-03-12 07:55:23 -05002771 // ShutdownThread must run on a looper capable of displaying the UI.
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002772 mHandler.post(runnable);
2773
Mike Lockwoodb62f9592010-03-12 07:55:23 -05002774 // PowerManager.reboot() is documented not to return so just wait for the inevitable.
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002775 synchronized (runnable) {
Mike Lockwoodb62f9592010-03-12 07:55:23 -05002776 while (true) {
2777 try {
2778 runnable.wait();
2779 } catch (InterruptedException e) {
2780 }
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002781 }
Doug Zongker50a21f42009-11-19 12:49:53 -08002782 }
2783 }
2784
Dan Egnor60d87622009-12-16 16:32:58 -08002785 /**
2786 * Crash the runtime (causing a complete restart of the Android framework).
2787 * Requires REBOOT permission. Mostly for testing. Should not return.
2788 */
2789 public void crash(final String message)
2790 {
2791 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
2792 Thread t = new Thread("PowerManagerService.crash()") {
2793 public void run() { throw new RuntimeException(message); }
2794 };
2795 try {
2796 t.start();
2797 t.join();
2798 } catch (InterruptedException e) {
2799 Log.wtf(TAG, e);
2800 }
2801 }
2802
Mike Lockwood435eb642009-12-03 08:40:18 -05002803 private void goToSleepLocked(long time, int reason) {
Jeff Browna75fe052012-05-01 18:41:26 -07002804 if (mSpew) {
2805 Exception ex = new Exception();
2806 ex.fillInStackTrace();
2807 Slog.d(TAG, "goToSleep mLastEventTime=" + mLastEventTime + " time=" + time
2808 + " reason=" + reason, ex);
2809 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002810
2811 if (mLastEventTime <= time) {
2812 mLastEventTime = time;
2813 // cancel all of the wake locks
2814 mWakeLockState = SCREEN_OFF;
2815 int N = mLocks.size();
2816 int numCleared = 0;
Joe Onorato8274a0e2010-10-05 17:38:09 -04002817 boolean proxLock = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002818 for (int i=0; i<N; i++) {
2819 WakeLock wl = mLocks.get(i);
2820 if (isScreenLock(wl.flags)) {
Joe Onorato8274a0e2010-10-05 17:38:09 -04002821 if (((wl.flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)
2822 && reason == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR) {
2823 proxLock = true;
2824 } else {
2825 mLocks.get(i).activated = false;
2826 numCleared++;
2827 }
2828 }
2829 }
2830 if (!proxLock) {
2831 mProxIgnoredBecauseScreenTurnedOff = true;
2832 if (mDebugProximitySensor) {
2833 Slog.d(TAG, "setting mProxIgnoredBecauseScreenTurnedOff");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002834 }
2835 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002836 EventLog.writeEvent(EventLogTags.POWER_SLEEP_REQUESTED, numCleared);
Joe Onorato128e7292009-03-24 18:41:31 -07002837 mStillNeedSleepNotification = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002838 mUserState = SCREEN_OFF;
Mike Lockwood435eb642009-12-03 08:40:18 -05002839 setPowerState(SCREEN_OFF, false, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002840 cancelTimerLocked();
2841 }
2842 }
2843
2844 public long timeSinceScreenOn() {
2845 synchronized (mLocks) {
2846 if ((mPowerState & SCREEN_ON_BIT) != 0) {
2847 return 0;
2848 }
2849 return SystemClock.elapsedRealtime() - mScreenOffTime;
2850 }
2851 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002852
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002853 public void setKeyboardVisibility(boolean visible) {
Mike Lockwooda625b382009-09-12 17:36:03 -07002854 synchronized (mLocks) {
2855 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002856 Slog.d(TAG, "setKeyboardVisibility: " + visible);
Mike Lockwooda625b382009-09-12 17:36:03 -07002857 }
Mike Lockwood3c9435a2009-10-22 15:45:37 -04002858 if (mKeyboardVisible != visible) {
2859 mKeyboardVisible = visible;
2860 // don't signal user activity if the screen is off; other code
2861 // will take care of turning on due to a true change to the lid
2862 // switch and synchronized with the lock screen.
2863 if ((mPowerState & SCREEN_ON_BIT) != 0) {
Mike Lockwood4984e732009-11-01 08:16:33 -05002864 if (mUseSoftwareAutoBrightness) {
Mike Lockwooddf024922009-10-29 21:29:15 -04002865 // force recompute of backlight values
2866 if (mLightSensorValue >= 0) {
2867 int value = (int)mLightSensorValue;
2868 mLightSensorValue = -1;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002869 lightSensorChangedLocked(value, false);
Mike Lockwooddf024922009-10-29 21:29:15 -04002870 }
2871 }
Mike Lockwood3c9435a2009-10-22 15:45:37 -04002872 userActivity(SystemClock.uptimeMillis(), false, BUTTON_EVENT, true);
2873 }
Mike Lockwooda625b382009-09-12 17:36:03 -07002874 }
2875 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002876 }
2877
2878 /**
2879 * When the keyguard is up, it manages the power state, and userActivity doesn't do anything.
Mike Lockwood50c548d2009-11-09 16:02:06 -05002880 * When disabling user activity we also reset user power state so the keyguard can reset its
2881 * short screen timeout when keyguard is unhidden.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002882 */
2883 public void enableUserActivity(boolean enabled) {
Mike Lockwood50c548d2009-11-09 16:02:06 -05002884 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002885 Slog.d(TAG, "enableUserActivity " + enabled);
Mike Lockwood50c548d2009-11-09 16:02:06 -05002886 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002887 synchronized (mLocks) {
2888 mUserActivityAllowed = enabled;
Mike Lockwood50c548d2009-11-09 16:02:06 -05002889 if (!enabled) {
2890 // cancel timeout and clear mUserState so the keyguard can set a short timeout
2891 setTimeoutLocked(SystemClock.uptimeMillis(), 0);
2892 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002893 }
2894 }
2895
Mike Lockwooddc3494e2009-10-14 21:17:09 -07002896 private void setScreenBrightnessMode(int mode) {
Joe Onoratod28f7532010-11-06 12:56:53 -07002897 synchronized (mLocks) {
2898 boolean enabled = (mode == SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
2899 if (mUseSoftwareAutoBrightness && mAutoBrightessEnabled != enabled) {
2900 mAutoBrightessEnabled = enabled;
2901 // This will get us a new value
2902 enableLightSensorLocked(mAutoBrightessEnabled && isScreenOn());
Mike Lockwood2d155d22009-10-27 09:32:30 -04002903 }
Mike Lockwooddc3494e2009-10-14 21:17:09 -07002904 }
2905 }
2906
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002907 /** Sets the screen off timeouts:
2908 * mKeylightDelay
2909 * mDimDelay
2910 * mScreenOffDelay
2911 * */
2912 private void setScreenOffTimeoutsLocked() {
2913 if ((mPokey & POKE_LOCK_SHORT_TIMEOUT) != 0) {
Doug Zongker43866e02010-01-07 12:09:54 -08002914 mKeylightDelay = mShortKeylightDelay; // Configurable via secure settings
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002915 mDimDelay = -1;
2916 mScreenOffDelay = 0;
2917 } else if ((mPokey & POKE_LOCK_MEDIUM_TIMEOUT) != 0) {
2918 mKeylightDelay = MEDIUM_KEYLIGHT_DELAY;
2919 mDimDelay = -1;
2920 mScreenOffDelay = 0;
2921 } else {
Dianne Hackborndf83afa2010-01-20 13:37:26 -08002922 int totalDelay = mScreenOffTimeoutSetting;
2923 if (totalDelay > mMaximumScreenOffTimeout) {
2924 totalDelay = mMaximumScreenOffTimeout;
2925 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002926 mKeylightDelay = LONG_KEYLIGHT_DELAY;
2927 if (totalDelay < 0) {
Jim Millerbc4603b2010-08-30 21:21:34 -07002928 // negative number means stay on as long as possible.
2929 mScreenOffDelay = mMaximumScreenOffTimeout;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002930 } else if (mKeylightDelay < totalDelay) {
2931 // subtract the time that the keylight delay. This will give us the
2932 // remainder of the time that we need to sleep to get the accurate
2933 // screen off timeout.
2934 mScreenOffDelay = totalDelay - mKeylightDelay;
2935 } else {
2936 mScreenOffDelay = 0;
2937 }
2938 if (mDimScreen && totalDelay >= (LONG_KEYLIGHT_DELAY + LONG_DIM_TIME)) {
2939 mDimDelay = mScreenOffDelay - LONG_DIM_TIME;
2940 mScreenOffDelay = LONG_DIM_TIME;
2941 } else {
2942 mDimDelay = -1;
2943 }
2944 }
2945 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002946 Slog.d(TAG, "setScreenOffTimeouts mKeylightDelay=" + mKeylightDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002947 + " mDimDelay=" + mDimDelay + " mScreenOffDelay=" + mScreenOffDelay
2948 + " mDimScreen=" + mDimScreen);
2949 }
2950 }
2951
2952 /**
Doug Zongker43866e02010-01-07 12:09:54 -08002953 * Refreshes cached secure settings. Called once on startup, and
2954 * on subsequent changes to secure settings.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002955 */
Doug Zongker43866e02010-01-07 12:09:54 -08002956 private void updateSettingsValues() {
2957 mShortKeylightDelay = Settings.Secure.getInt(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002958 mContext.getContentResolver(),
Doug Zongker43866e02010-01-07 12:09:54 -08002959 Settings.Secure.SHORT_KEYLIGHT_DELAY_MS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002960 SHORT_KEYLIGHT_DELAY_DEFAULT);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002961 // Slog.i(TAG, "updateSettingsValues(): mShortKeylightDelay now " + mShortKeylightDelay);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002962 }
2963
2964 private class LockList extends ArrayList<WakeLock>
2965 {
2966 void addLock(WakeLock wl)
2967 {
2968 int index = getIndex(wl.binder);
2969 if (index < 0) {
2970 this.add(wl);
2971 }
2972 }
2973
2974 WakeLock removeLock(IBinder binder)
2975 {
2976 int index = getIndex(binder);
2977 if (index >= 0) {
2978 return this.remove(index);
2979 } else {
2980 return null;
2981 }
2982 }
2983
2984 int getIndex(IBinder binder)
2985 {
2986 int N = this.size();
2987 for (int i=0; i<N; i++) {
2988 if (this.get(i).binder == binder) {
2989 return i;
2990 }
2991 }
2992 return -1;
2993 }
2994
2995 int gatherState()
2996 {
2997 int result = 0;
2998 int N = this.size();
2999 for (int i=0; i<N; i++) {
3000 WakeLock wl = this.get(i);
3001 if (wl.activated) {
3002 if (isScreenLock(wl.flags)) {
3003 result |= wl.minState;
3004 }
3005 }
3006 }
3007 return result;
3008 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003009
Michael Chane96440f2009-05-06 10:27:36 -07003010 int reactivateScreenLocksLocked()
3011 {
3012 int result = 0;
3013 int N = this.size();
3014 for (int i=0; i<N; i++) {
3015 WakeLock wl = this.get(i);
3016 if (isScreenLock(wl.flags)) {
3017 wl.activated = true;
3018 result |= wl.minState;
3019 }
3020 }
Joe Onorato8274a0e2010-10-05 17:38:09 -04003021 if (mDebugProximitySensor) {
3022 Slog.d(TAG, "reactivateScreenLocksLocked mProxIgnoredBecauseScreenTurnedOff="
3023 + mProxIgnoredBecauseScreenTurnedOff);
3024 }
3025 mProxIgnoredBecauseScreenTurnedOff = false;
Michael Chane96440f2009-05-06 10:27:36 -07003026 return result;
3027 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003028 }
3029
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08003030 public void setPolicy(WindowManagerPolicy p) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003031 synchronized (mLocks) {
3032 mPolicy = p;
3033 mLocks.notifyAll();
3034 }
3035 }
3036
3037 WindowManagerPolicy getPolicyLocked() {
3038 while (mPolicy == null || !mDoneBooting) {
3039 try {
3040 mLocks.wait();
3041 } catch (InterruptedException e) {
3042 // Ignore
3043 }
3044 }
3045 return mPolicy;
3046 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003047
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003048 void systemReady() {
Jeff Brown25157e42012-04-16 12:13:05 -07003049 mSensorManager = new SystemSensorManager(mHandlerThread.getLooper());
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003050 mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
3051 // don't bother with the light sensor if auto brightness is handled in hardware
Mike Lockwoodaa66ea82009-10-31 16:31:27 -04003052 if (mUseSoftwareAutoBrightness) {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003053 mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003054 }
3055
Mike Lockwoodb42ab0f2010-03-04 08:02:44 -05003056 // wait until sensors are enabled before turning on screen.
3057 // some devices will not activate the light sensor properly on boot
3058 // unless we do this.
3059 if (mUseSoftwareAutoBrightness) {
3060 // turn the screen on
3061 setPowerState(SCREEN_BRIGHT);
3062 } else {
3063 // turn everything on
3064 setPowerState(ALL_BRIGHT);
3065 }
3066
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003067 synchronized (mLocks) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003068 Slog.d(TAG, "system ready!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003069 mDoneBooting = true;
Mike Lockwoodb42ab0f2010-03-04 08:02:44 -05003070
Joe Onoratod28f7532010-11-06 12:56:53 -07003071 enableLightSensorLocked(mUseSoftwareAutoBrightness && mAutoBrightessEnabled);
3072
Dianne Hackborn617f8772009-03-31 15:04:46 -07003073 long identity = Binder.clearCallingIdentity();
3074 try {
3075 mBatteryStats.noteScreenBrightness(getPreferredBrightness());
3076 mBatteryStats.noteScreenOn();
3077 } catch (RemoteException e) {
3078 // Nothing interesting to do.
3079 } finally {
3080 Binder.restoreCallingIdentity(identity);
3081 }
Mike Lockwood2d7bb812009-11-15 18:12:22 -05003082 }
3083 }
3084
3085 void bootCompleted() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003086 Slog.d(TAG, "bootCompleted");
Mike Lockwood2d7bb812009-11-15 18:12:22 -05003087 synchronized (mLocks) {
3088 mBootCompleted = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003089 userActivity(SystemClock.uptimeMillis(), false, BUTTON_EVENT, true);
3090 updateWakeLockLocked();
3091 mLocks.notifyAll();
3092 }
3093 }
3094
Joe Onoratob08a1af2010-10-11 19:28:58 -07003095 // for watchdog
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003096 public void monitor() {
3097 synchronized (mLocks) { }
3098 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003099
3100 public int getSupportedWakeLockFlags() {
3101 int result = PowerManager.PARTIAL_WAKE_LOCK
3102 | PowerManager.FULL_WAKE_LOCK
3103 | PowerManager.SCREEN_DIM_WAKE_LOCK;
3104
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003105 if (mProximitySensor != null) {
3106 result |= PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK;
3107 }
3108
3109 return result;
3110 }
3111
Mike Lockwood237a2992009-09-15 14:42:16 -04003112 public void setBacklightBrightness(int brightness) {
3113 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
3114 // Don't let applications turn the screen all the way off
Joe Onoratob08a1af2010-10-11 19:28:58 -07003115 synchronized (mLocks) {
Mike Lockwoodeb6456b2011-09-13 15:24:02 -04003116 brightness = Math.max(brightness, mScreenBrightnessDim);
Joe Onoratob08a1af2010-10-11 19:28:58 -07003117 mLcdLight.setBrightness(brightness);
3118 mKeyboardLight.setBrightness(mKeyboardVisible ? brightness : 0);
3119 mButtonLight.setBrightness(brightness);
3120 long identity = Binder.clearCallingIdentity();
3121 try {
3122 mBatteryStats.noteScreenBrightness(brightness);
3123 } catch (RemoteException e) {
3124 Slog.w(TAG, "RemoteException calling noteScreenBrightness on BatteryStatsService", e);
3125 } finally {
3126 Binder.restoreCallingIdentity(identity);
3127 }
Jim Miller92e66dd2012-02-21 18:57:12 -08003128 mScreenBrightnessAnimator.animateTo(brightness, SCREEN_BRIGHT_BIT, 0);
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08003129 }
3130 }
3131
3132 public void setAutoBrightnessAdjustment(float adj) {
3133 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
3134 synchronized (mLocks) {
3135 mLightSensorAdjustSetting = adj;
3136 if (mSensorManager != null && mLightSensorEnabled) {
3137 // clear calling identity so sensor manager battery stats are accurate
3138 long identity = Binder.clearCallingIdentity();
3139 try {
3140 // force recompute of backlight values
3141 if (mLightSensorValue >= 0) {
3142 int value = (int)mLightSensorValue;
3143 mLightSensorValue = -1;
3144 handleLightSensorValue(value, true);
3145 }
3146 } finally {
3147 Binder.restoreCallingIdentity(identity);
3148 }
Joe Onorato3d3db602010-10-18 16:08:16 -04003149 }
Mike Lockwood237a2992009-09-15 14:42:16 -04003150 }
3151 }
3152
Mike Lockwoodb11832d2009-11-25 15:25:55 -05003153 public void setAttentionLight(boolean on, int color) {
3154 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
Mike Lockwood3cb67a32009-11-27 14:25:58 -05003155 mAttentionLight.setFlashing(color, LightsService.LIGHT_FLASH_HARDWARE, (on ? 3 : 0), 0);
Mike Lockwoodb11832d2009-11-25 15:25:55 -05003156 }
3157
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003158 private void enableProximityLockLocked() {
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003159 if (mDebugProximitySensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003160 Slog.d(TAG, "enableProximityLockLocked");
Mike Lockwood36fc3022009-08-25 16:49:06 -07003161 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003162 if (!mProximitySensorEnabled) {
3163 // clear calling identity so sensor manager battery stats are accurate
3164 long identity = Binder.clearCallingIdentity();
3165 try {
3166 mSensorManager.registerListener(mProximityListener, mProximitySensor,
3167 SensorManager.SENSOR_DELAY_NORMAL);
3168 mProximitySensorEnabled = true;
3169 } finally {
3170 Binder.restoreCallingIdentity(identity);
3171 }
Mike Lockwood809ad0f2009-10-26 22:10:33 -04003172 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003173 }
3174
3175 private void disableProximityLockLocked() {
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003176 if (mDebugProximitySensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003177 Slog.d(TAG, "disableProximityLockLocked");
Mike Lockwood36fc3022009-08-25 16:49:06 -07003178 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003179 if (mProximitySensorEnabled) {
3180 // clear calling identity so sensor manager battery stats are accurate
3181 long identity = Binder.clearCallingIdentity();
3182 try {
3183 mSensorManager.unregisterListener(mProximityListener);
3184 mHandler.removeCallbacks(mProximityTask);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -05003185 if (mProximityPartialLock.isHeld()) {
3186 mProximityPartialLock.release();
3187 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003188 mProximitySensorEnabled = false;
3189 } finally {
3190 Binder.restoreCallingIdentity(identity);
3191 }
3192 if (mProximitySensorActive) {
3193 mProximitySensorActive = false;
Joe Onorato8274a0e2010-10-05 17:38:09 -04003194 if (mDebugProximitySensor) {
3195 Slog.d(TAG, "disableProximityLockLocked mProxIgnoredBecauseScreenTurnedOff="
3196 + mProxIgnoredBecauseScreenTurnedOff);
3197 }
3198 if (!mProxIgnoredBecauseScreenTurnedOff) {
3199 forceUserActivityLocked();
3200 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003201 }
Mike Lockwood200b30b2009-09-20 00:23:59 -04003202 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003203 }
3204
Mike Lockwood20f87d72009-11-05 16:08:51 -05003205 private void proximityChangedLocked(boolean active) {
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003206 if (mDebugProximitySensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003207 Slog.d(TAG, "proximityChangedLocked, active: " + active);
Mike Lockwood20f87d72009-11-05 16:08:51 -05003208 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003209 if (!mProximitySensorEnabled) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003210 Slog.d(TAG, "Ignoring proximity change after sensor is disabled");
Mike Lockwood0d72f7e2009-11-05 20:53:00 -05003211 return;
3212 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05003213 if (active) {
Joe Onorato8274a0e2010-10-05 17:38:09 -04003214 if (mDebugProximitySensor) {
3215 Slog.d(TAG, "b mProxIgnoredBecauseScreenTurnedOff="
3216 + mProxIgnoredBecauseScreenTurnedOff);
3217 }
3218 if (!mProxIgnoredBecauseScreenTurnedOff) {
3219 goToSleepLocked(SystemClock.uptimeMillis(),
3220 WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR);
3221 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05003222 mProximitySensorActive = true;
3223 } else {
3224 // proximity sensor negative events trigger as user activity.
3225 // temporarily set mUserActivityAllowed to true so this will work
3226 // even when the keyguard is on.
3227 mProximitySensorActive = false;
Joe Onorato8274a0e2010-10-05 17:38:09 -04003228 if (mDebugProximitySensor) {
3229 Slog.d(TAG, "b mProxIgnoredBecauseScreenTurnedOff="
3230 + mProxIgnoredBecauseScreenTurnedOff);
3231 }
3232 if (!mProxIgnoredBecauseScreenTurnedOff) {
3233 forceUserActivityLocked();
3234 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003235
3236 if (mProximityWakeLockCount == 0) {
3237 // disable sensor if we have no listeners left after proximity negative
3238 disableProximityLockLocked();
3239 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05003240 }
3241 }
3242
Joe Onoratod28f7532010-11-06 12:56:53 -07003243 private void enableLightSensorLocked(boolean enable) {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003244 if (mDebugLightSensor) {
Joe Onoratod28f7532010-11-06 12:56:53 -07003245 Slog.d(TAG, "enableLightSensorLocked enable=" + enable
Craig Mautner37933682012-06-06 14:13:39 -07003246 + " mLightSensorEnabled=" + mLightSensorEnabled
3247 + " mAutoBrightessEnabled=" + mAutoBrightessEnabled
3248 + " mWaitingForFirstLightSensor=" + mWaitingForFirstLightSensor);
Joe Onoratod28f7532010-11-06 12:56:53 -07003249 }
3250 if (!mAutoBrightessEnabled) {
3251 enable = false;
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003252 }
3253 if (mSensorManager != null && mLightSensorEnabled != enable) {
3254 mLightSensorEnabled = enable;
Mike Lockwood809ad0f2009-10-26 22:10:33 -04003255 // clear calling identity so sensor manager battery stats are accurate
3256 long identity = Binder.clearCallingIdentity();
3257 try {
3258 if (enable) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003259 // reset our highest value when reenabling
3260 mHighestLightSensorValue = -1;
3261 // force recompute of backlight values
Craig Mautner37933682012-06-06 14:13:39 -07003262 final int value = (int)mLightSensorValue;
3263 if (value >= 0) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003264 mLightSensorValue = -1;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08003265 handleLightSensorValue(value, true);
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003266 }
Mike Lockwood809ad0f2009-10-26 22:10:33 -04003267 mSensorManager.registerListener(mLightListener, mLightSensor,
Mathias Agopian47f1fe52011-11-08 17:18:41 -08003268 LIGHT_SENSOR_RATE);
Mike Lockwood809ad0f2009-10-26 22:10:33 -04003269 } else {
3270 mSensorManager.unregisterListener(mLightListener);
3271 mHandler.removeCallbacks(mAutoBrightnessTask);
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003272 mLightSensorPendingDecrease = false;
3273 mLightSensorPendingIncrease = false;
Mike Lockwood809ad0f2009-10-26 22:10:33 -04003274 }
3275 } finally {
3276 Binder.restoreCallingIdentity(identity);
Mike Lockwood06952d92009-08-13 16:05:38 -04003277 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003278 }
3279 }
3280
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003281 SensorEventListener mProximityListener = new SensorEventListener() {
3282 public void onSensorChanged(SensorEvent event) {
Mike Lockwoodba8eb1e2009-11-08 19:31:18 -05003283 long milliseconds = SystemClock.elapsedRealtime();
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003284 synchronized (mLocks) {
3285 float distance = event.values[0];
Mike Lockwood20f87d72009-11-05 16:08:51 -05003286 long timeSinceLastEvent = milliseconds - mLastProximityEventTime;
3287 mLastProximityEventTime = milliseconds;
3288 mHandler.removeCallbacks(mProximityTask);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -05003289 boolean proximityTaskQueued = false;
Mike Lockwood20f87d72009-11-05 16:08:51 -05003290
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003291 // compare against getMaximumRange to support sensors that only return 0 or 1
Mike Lockwood20f87d72009-11-05 16:08:51 -05003292 boolean active = (distance >= 0.0 && distance < PROXIMITY_THRESHOLD &&
3293 distance < mProximitySensor.getMaximumRange());
3294
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003295 if (mDebugProximitySensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003296 Slog.d(TAG, "mProximityListener.onSensorChanged active: " + active);
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003297 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05003298 if (timeSinceLastEvent < PROXIMITY_SENSOR_DELAY) {
3299 // enforce delaying atleast PROXIMITY_SENSOR_DELAY before processing
3300 mProximityPendingValue = (active ? 1 : 0);
3301 mHandler.postDelayed(mProximityTask, PROXIMITY_SENSOR_DELAY - timeSinceLastEvent);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -05003302 proximityTaskQueued = true;
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003303 } else {
Mike Lockwood20f87d72009-11-05 16:08:51 -05003304 // process the value immediately
3305 mProximityPendingValue = -1;
3306 proximityChangedLocked(active);
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003307 }
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -05003308
3309 // update mProximityPartialLock state
3310 boolean held = mProximityPartialLock.isHeld();
3311 if (!held && proximityTaskQueued) {
3312 // hold wakelock until mProximityTask runs
3313 mProximityPartialLock.acquire();
3314 } else if (held && !proximityTaskQueued) {
3315 mProximityPartialLock.release();
3316 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003317 }
3318 }
3319
3320 public void onAccuracyChanged(Sensor sensor, int accuracy) {
3321 // ignore
3322 }
3323 };
3324
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08003325 private void handleLightSensorValue(int value, boolean immediate) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003326 long milliseconds = SystemClock.elapsedRealtime();
Craig Mautner37933682012-06-06 14:13:39 -07003327 if (mLightSensorValue == -1
3328 || milliseconds < mLastScreenOnTime + mLightSensorWarmupTime
3329 || mWaitingForFirstLightSensor) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003330 // process the value immediately if screen has just turned on
3331 mHandler.removeCallbacks(mAutoBrightnessTask);
3332 mLightSensorPendingDecrease = false;
3333 mLightSensorPendingIncrease = false;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08003334 lightSensorChangedLocked(value, immediate);
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003335 } else {
3336 if ((value > mLightSensorValue && mLightSensorPendingDecrease) ||
3337 (value < mLightSensorValue && mLightSensorPendingIncrease) ||
3338 (value == mLightSensorValue) ||
3339 (!mLightSensorPendingDecrease && !mLightSensorPendingIncrease)) {
3340 // delay processing to debounce the sensor
3341 mHandler.removeCallbacks(mAutoBrightnessTask);
3342 mLightSensorPendingDecrease = (value < mLightSensorValue);
3343 mLightSensorPendingIncrease = (value > mLightSensorValue);
3344 if (mLightSensorPendingDecrease || mLightSensorPendingIncrease) {
3345 mLightSensorPendingValue = value;
3346 mHandler.postDelayed(mAutoBrightnessTask, LIGHT_SENSOR_DELAY);
3347 }
3348 } else {
3349 mLightSensorPendingValue = value;
3350 }
3351 }
3352 }
3353
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003354 SensorEventListener mLightListener = new SensorEventListener() {
Craig Mautner75fc9de2012-06-18 16:53:27 -07003355 @Override
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003356 public void onSensorChanged(SensorEvent event) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003357 if (mDebugLightSensor) {
3358 Slog.d(TAG, "onSensorChanged: light value: " + event.values[0]);
3359 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003360 synchronized (mLocks) {
Mike Lockwood497087e32009-11-08 18:33:03 -05003361 // ignore light sensor while screen is turning off
3362 if (isScreenTurningOffLocked()) {
3363 return;
3364 }
Craig Mautner37933682012-06-06 14:13:39 -07003365 handleLightSensorValue((int)event.values[0], mWaitingForFirstLightSensor);
Craig Mautner75fc9de2012-06-18 16:53:27 -07003366 if (mWaitingForFirstLightSensor && !mPreparingForScreenOn) {
3367 if (mDebugLightAnimation) {
3368 Slog.d(TAG, "onSensorChanged: Clearing mWaitingForFirstLightSensor.");
3369 }
Craig Mautner37933682012-06-06 14:13:39 -07003370 mWaitingForFirstLightSensor = false;
3371 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003372 }
3373 }
3374
Craig Mautner75fc9de2012-06-18 16:53:27 -07003375 @Override
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003376 public void onAccuracyChanged(Sensor sensor, int accuracy) {
3377 // ignore
3378 }
3379 };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003380}