blob: fbdd7aa0b5e8f073dd6578af0a8a03851a0813b0 [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
Dianne Hackborn2fe8fb22012-06-15 17:05:25 -0700480 int getStayOnConditionsLocked() {
481 return mMaximumScreenOffTimeout <= 0 || mMaximumScreenOffTimeout == Integer.MAX_VALUE
482 ? mStayOnConditions : 0;
483 }
484
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800485 private class SettingsObserver implements Observer {
Amith Yamasani8b619832010-09-22 16:11:59 -0700486 private int getInt(String name, int defValue) {
487 ContentValues values = mSettings.getValues(name);
488 Integer iVal = values != null ? values.getAsInteger(Settings.System.VALUE) : null;
489 return iVal != null ? iVal : defValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800490 }
491
Joe Onorato609695d2010-10-14 14:57:49 -0700492 private float getFloat(String name, float defValue) {
493 ContentValues values = mSettings.getValues(name);
494 Float fVal = values != null ? values.getAsFloat(Settings.System.VALUE) : null;
495 return fVal != null ? fVal : defValue;
496 }
497
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800498 public void update(Observable o, Object arg) {
499 synchronized (mLocks) {
Amith Yamasani8b619832010-09-22 16:11:59 -0700500 // STAY_ON_WHILE_PLUGGED_IN, default to when plugged into AC
501 mStayOnConditions = getInt(STAY_ON_WHILE_PLUGGED_IN,
502 BatteryManager.BATTERY_PLUGGED_AC);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800503 updateWakeLockLocked();
504
Amith Yamasani8b619832010-09-22 16:11:59 -0700505 // SCREEN_OFF_TIMEOUT, default to 15 seconds
506 mScreenOffTimeoutSetting = getInt(SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800507
Joe Onorato609695d2010-10-14 14:57:49 -0700508 // DIM_SCREEN
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800509 //mDimScreen = getInt(DIM_SCREEN) != 0;
510
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800511 mScreenBrightnessSetting = getInt(SCREEN_BRIGHTNESS, DEFAULT_SCREEN_BRIGHTNESS);
Dianne Hackborn518a3d82012-05-09 16:30:49 -0700512 mLightSensorAdjustSetting = 0; //getFloat(SCREEN_AUTO_BRIGHTNESS_ADJ, 0);
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800513
Amith Yamasani8b619832010-09-22 16:11:59 -0700514 // SCREEN_BRIGHTNESS_MODE, default to manual
515 setScreenBrightnessMode(getInt(SCREEN_BRIGHTNESS_MODE,
516 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL));
Mike Lockwooddc3494e2009-10-14 21:17:09 -0700517
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800518 // recalculate everything
519 setScreenOffTimeoutsLocked();
Joe Onorato609695d2010-10-14 14:57:49 -0700520
Jim Miller92e66dd2012-02-21 18:57:12 -0800521 mWindowScaleAnimation = getFloat(WINDOW_ANIMATION_SCALE, 1.0f);
Joe Onorato609695d2010-10-14 14:57:49 -0700522 final float transitionScale = getFloat(TRANSITION_ANIMATION_SCALE, 1.0f);
523 mAnimationSetting = 0;
Jim Miller92e66dd2012-02-21 18:57:12 -0800524 if (mWindowScaleAnimation > 0.5f) {
Joe Onorato609695d2010-10-14 14:57:49 -0700525 mAnimationSetting |= ANIM_SETTING_OFF;
526 }
527 if (transitionScale > 0.5f) {
528 // Uncomment this if you want the screen-on animation.
529 // mAnimationSetting |= ANIM_SETTING_ON;
530 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800531 }
532 }
533 }
534
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700535 PowerManagerService() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800536 // Hack to get our uid... should have a func for this.
537 long token = Binder.clearCallingIdentity();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700538 MY_UID = Process.myUid();
539 MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800540 Binder.restoreCallingIdentity(token);
541
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800542 // assume nothing is on yet
543 mUserState = mPowerState = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800544
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800545 // Add ourself to the Watchdog monitors.
546 Watchdog.getInstance().addMonitor(this);
Jeff Brown7304c342012-05-11 18:42:42 -0700547
548 nativeInit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800549 }
550
551 private ContentQueryMap mSettings;
552
Mike Lockwood3a322132009-11-24 00:30:52 -0500553 void init(Context context, LightsService lights, IActivityManager activity,
The Android Open Source Project10592532009-03-18 17:39:46 -0700554 BatteryService battery) {
Mike Lockwood3a322132009-11-24 00:30:52 -0500555 mLightsService = lights;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800556 mContext = context;
557 mActivityService = activity;
558 mBatteryStats = BatteryStatsService.getService();
559 mBatteryService = battery;
560
Mike Lockwood3cb67a32009-11-27 14:25:58 -0500561 mLcdLight = lights.getLight(LightsService.LIGHT_ID_BACKLIGHT);
562 mButtonLight = lights.getLight(LightsService.LIGHT_ID_BUTTONS);
563 mKeyboardLight = lights.getLight(LightsService.LIGHT_ID_KEYBOARD);
564 mAttentionLight = lights.getLight(LightsService.LIGHT_ID_ATTENTION);
Mike Lockwood3a74bd32011-08-12 13:55:22 -0700565 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
Mike Lockwood3cb67a32009-11-27 14:25:58 -0500566
Joe Onoratob08a1af2010-10-11 19:28:58 -0700567 mInitComplete = false;
Jim Miller92e66dd2012-02-21 18:57:12 -0800568 mScreenBrightnessAnimator = new ScreenBrightnessAnimator("mScreenBrightnessUpdaterThread",
569 Process.THREAD_PRIORITY_DISPLAY);
570 mScreenBrightnessAnimator.start();
Joe Onoratob08a1af2010-10-11 19:28:58 -0700571
Jim Miller92e66dd2012-02-21 18:57:12 -0800572 synchronized (mScreenBrightnessAnimator) {
Joe Onoratob08a1af2010-10-11 19:28:58 -0700573 while (!mInitComplete) {
574 try {
Jim Miller92e66dd2012-02-21 18:57:12 -0800575 mScreenBrightnessAnimator.wait();
Joe Onoratob08a1af2010-10-11 19:28:58 -0700576 } catch (InterruptedException e) {
577 // Ignore
578 }
579 }
580 }
Jim Miller92e66dd2012-02-21 18:57:12 -0800581
Joe Onoratob08a1af2010-10-11 19:28:58 -0700582 mInitComplete = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800583 mHandlerThread = new HandlerThread("PowerManagerService") {
584 @Override
585 protected void onLooperPrepared() {
586 super.onLooperPrepared();
587 initInThread();
588 }
589 };
590 mHandlerThread.start();
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800591
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800592 synchronized (mHandlerThread) {
593 while (!mInitComplete) {
594 try {
595 mHandlerThread.wait();
596 } catch (InterruptedException e) {
597 // Ignore
598 }
599 }
600 }
Jim Miller92e66dd2012-02-21 18:57:12 -0800601
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700602 synchronized (mLocks) {
603 updateNativePowerStateLocked();
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700604 // We make sure to start out with the screen on due to user activity.
605 // (They did just boot their device, after all.)
606 forceUserActivityLocked();
Dianne Hackborn40011092011-09-22 13:37:48 -0700607 mInitialized = true;
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700608 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800609 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800610
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800611 void initInThread() {
612 mHandler = new Handler();
613
614 mBroadcastWakeLock = new UnsynchronizedWakeLock(
Joe Onorato128e7292009-03-24 18:41:31 -0700615 PowerManager.PARTIAL_WAKE_LOCK, "sleep_broadcast", true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800616 mStayOnWhilePluggedInScreenDimLock = new UnsynchronizedWakeLock(
617 PowerManager.SCREEN_DIM_WAKE_LOCK, "StayOnWhilePluggedIn Screen Dim", false);
618 mStayOnWhilePluggedInPartialLock = new UnsynchronizedWakeLock(
619 PowerManager.PARTIAL_WAKE_LOCK, "StayOnWhilePluggedIn Partial", false);
620 mPreventScreenOnPartialLock = new UnsynchronizedWakeLock(
621 PowerManager.PARTIAL_WAKE_LOCK, "PreventScreenOn Partial", false);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -0500622 mProximityPartialLock = new UnsynchronizedWakeLock(
623 PowerManager.PARTIAL_WAKE_LOCK, "Proximity Partial", false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800624
625 mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
Christopher Tate2cb13572012-06-14 17:00:48 -0700626 mScreenOnIntent.addFlags(
627 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800628 mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF);
Christopher Tate2cb13572012-06-14 17:00:48 -0700629 mScreenOffIntent.addFlags(
630 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800631
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700632 Resources resources = mContext.getResources();
Mike Lockwoodaa66ea82009-10-31 16:31:27 -0400633
Joe Onoratob08a1af2010-10-11 19:28:58 -0700634 mAnimateScreenLights = resources.getBoolean(
635 com.android.internal.R.bool.config_animateScreenLights);
636
Joe Onorato6d747652010-10-11 15:15:31 -0700637 mUnplugTurnsOnScreen = resources.getBoolean(
638 com.android.internal.R.bool.config_unplugTurnsOnScreen);
639
Mike Lockwoodeb6456b2011-09-13 15:24:02 -0400640 mScreenBrightnessDim = resources.getInteger(
641 com.android.internal.R.integer.config_screenBrightnessDim);
642
Mike Lockwoodaa66ea82009-10-31 16:31:27 -0400643 // read settings for auto-brightness
644 mUseSoftwareAutoBrightness = resources.getBoolean(
645 com.android.internal.R.bool.config_automatic_brightness_available);
Mike Lockwoodaa66ea82009-10-31 16:31:27 -0400646 if (mUseSoftwareAutoBrightness) {
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700647 mAutoBrightnessLevels = resources.getIntArray(
648 com.android.internal.R.array.config_autoBrightnessLevels);
649 mLcdBacklightValues = resources.getIntArray(
650 com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
651 mButtonBacklightValues = resources.getIntArray(
652 com.android.internal.R.array.config_autoBrightnessButtonBacklightValues);
653 mKeyboardBacklightValues = resources.getIntArray(
654 com.android.internal.R.array.config_autoBrightnessKeyboardBacklightValues);
Mike Lockwood20ee6f22009-11-07 20:33:47 -0500655 mLightSensorWarmupTime = resources.getInteger(
656 com.android.internal.R.integer.config_lightSensorWarmupTime);
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700657 }
Mike Lockwooddc3494e2009-10-14 21:17:09 -0700658
659 ContentResolver resolver = mContext.getContentResolver();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800660 Cursor settingsCursor = resolver.query(Settings.System.CONTENT_URI, null,
661 "(" + Settings.System.NAME + "=?) or ("
662 + Settings.System.NAME + "=?) or ("
Mike Lockwooddc3494e2009-10-14 21:17:09 -0700663 + Settings.System.NAME + "=?) or ("
Joe Onorato609695d2010-10-14 14:57:49 -0700664 + Settings.System.NAME + "=?) or ("
665 + Settings.System.NAME + "=?) or ("
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800666 + Settings.System.NAME + "=?) or ("
667 + Settings.System.NAME + "=?) or ("
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800668 + Settings.System.NAME + "=?)",
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800669 new String[]{STAY_ON_WHILE_PLUGGED_IN, SCREEN_OFF_TIMEOUT, DIM_SCREEN, SCREEN_BRIGHTNESS,
Dianne Hackborn518a3d82012-05-09 16:30:49 -0700670 SCREEN_BRIGHTNESS_MODE, /*SCREEN_AUTO_BRIGHTNESS_ADJ,*/
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800671 WINDOW_ANIMATION_SCALE, TRANSITION_ANIMATION_SCALE},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800672 null);
673 mSettings = new ContentQueryMap(settingsCursor, Settings.System.NAME, true, mHandler);
674 SettingsObserver settingsObserver = new SettingsObserver();
675 mSettings.addObserver(settingsObserver);
676
677 // pretend that the settings changed so we will get their initial state
678 settingsObserver.update(mSettings, null);
679
680 // register for the battery changed notifications
681 IntentFilter filter = new IntentFilter();
682 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
683 mContext.registerReceiver(new BatteryReceiver(), filter);
Mike Lockwood2d7bb812009-11-15 18:12:22 -0500684 filter = new IntentFilter();
685 filter.addAction(Intent.ACTION_BOOT_COMPLETED);
686 mContext.registerReceiver(new BootCompletedReceiver(), filter);
Mike Lockwoodb2865412010-02-02 22:40:33 -0500687 filter = new IntentFilter();
688 filter.addAction(Intent.ACTION_DOCK_EVENT);
689 mContext.registerReceiver(new DockReceiver(), filter);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800690
Doug Zongker43866e02010-01-07 12:09:54 -0800691 // Listen for secure settings changes
692 mContext.getContentResolver().registerContentObserver(
693 Settings.Secure.CONTENT_URI, true,
694 new ContentObserver(new Handler()) {
695 public void onChange(boolean selfChange) {
696 updateSettingsValues();
697 }
698 });
699 updateSettingsValues();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800700
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800701 synchronized (mHandlerThread) {
702 mInitComplete = true;
703 mHandlerThread.notifyAll();
704 }
705 }
706
Jeff Brown7304c342012-05-11 18:42:42 -0700707 /**
708 * Low-level function turn the device off immediately, without trying
709 * to be clean. Most people should use
710 * {@link com.android.server.pm.internal.app.ShutdownThread} for a clean shutdown.
711 */
712 public static void lowLevelShutdown() {
713 nativeShutdown();
714 }
715
716 /**
717 * Low-level function to reboot the device.
718 *
719 * @param reason code to pass to the kernel (e.g. "recovery"), or null.
720 * @throws IOException if reboot fails for some reason (eg, lack of
721 * permission)
722 */
723 public static void lowLevelReboot(String reason) throws IOException {
724 nativeReboot(reason);
725 }
726
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800727 private class WakeLock implements IBinder.DeathRecipient
728 {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700729 WakeLock(int f, IBinder b, String t, int u, int p) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800730 super();
731 flags = f;
732 binder = b;
733 tag = t;
734 uid = u == MY_UID ? Process.SYSTEM_UID : u;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700735 pid = p;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800736 if (u != MY_UID || (
737 !"KEEP_SCREEN_ON_FLAG".equals(tag)
738 && !"KeyInputQueue".equals(tag))) {
739 monitorType = (f & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK
740 ? BatteryStats.WAKE_TYPE_PARTIAL
741 : BatteryStats.WAKE_TYPE_FULL;
742 } else {
743 monitorType = -1;
744 }
745 try {
746 b.linkToDeath(this, 0);
747 } catch (RemoteException e) {
748 binderDied();
749 }
750 }
751 public void binderDied() {
752 synchronized (mLocks) {
Mike Lockwood0e39ea82009-11-18 15:37:10 -0500753 releaseWakeLockLocked(this.binder, 0, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800754 }
755 }
756 final int flags;
757 final IBinder binder;
758 final String tag;
759 final int uid;
Mike Lockwoodf5bd0922010-03-22 17:10:15 -0400760 final int pid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800761 final int monitorType;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700762 WorkSource ws;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800763 boolean activated = true;
764 int minState;
765 }
766
767 private void updateWakeLockLocked() {
Dianne Hackborn2fe8fb22012-06-15 17:05:25 -0700768 final int stayOnConditions = getStayOnConditionsLocked();
769 if (stayOnConditions != 0 && mBatteryService.isPowered(stayOnConditions)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800770 // keep the device on if we're plugged in and mStayOnWhilePluggedIn is set.
771 mStayOnWhilePluggedInScreenDimLock.acquire();
772 mStayOnWhilePluggedInPartialLock.acquire();
773 } else {
774 mStayOnWhilePluggedInScreenDimLock.release();
775 mStayOnWhilePluggedInPartialLock.release();
776 }
777 }
778
779 private boolean isScreenLock(int flags)
780 {
781 int n = flags & LOCK_MASK;
782 return n == PowerManager.FULL_WAKE_LOCK
783 || n == PowerManager.SCREEN_BRIGHT_WAKE_LOCK
Joe Onorato8274a0e2010-10-05 17:38:09 -0400784 || n == PowerManager.SCREEN_DIM_WAKE_LOCK
785 || n == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800786 }
787
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700788 void enforceWakeSourcePermission(int uid, int pid) {
789 if (uid == Process.myUid()) {
790 return;
791 }
792 mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
793 pid, uid, null);
794 }
795
796 public void acquireWakeLock(int flags, IBinder lock, String tag, WorkSource ws) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800797 int uid = Binder.getCallingUid();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700798 int pid = Binder.getCallingPid();
Michael Chane96440f2009-05-06 10:27:36 -0700799 if (uid != Process.myUid()) {
800 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
801 }
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700802 if (ws != null) {
803 enforceWakeSourcePermission(uid, pid);
804 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800805 long ident = Binder.clearCallingIdentity();
806 try {
807 synchronized (mLocks) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700808 acquireWakeLockLocked(flags, lock, uid, pid, tag, ws);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800809 }
810 } finally {
811 Binder.restoreCallingIdentity(ident);
812 }
813 }
814
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700815 void noteStartWakeLocked(WakeLock wl, WorkSource ws) {
Dianne Hackborn70be1672010-09-14 11:13:03 -0700816 if (wl.monitorType >= 0) {
817 long origId = Binder.clearCallingIdentity();
818 try {
819 if (ws != null) {
820 mBatteryStats.noteStartWakelockFromSource(ws, wl.pid, wl.tag,
821 wl.monitorType);
822 } else {
823 mBatteryStats.noteStartWakelock(wl.uid, wl.pid, wl.tag, wl.monitorType);
824 }
825 } catch (RemoteException e) {
826 // Ignore
827 } finally {
828 Binder.restoreCallingIdentity(origId);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700829 }
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700830 }
831 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800832
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700833 void noteStopWakeLocked(WakeLock wl, WorkSource ws) {
Dianne Hackborn70be1672010-09-14 11:13:03 -0700834 if (wl.monitorType >= 0) {
835 long origId = Binder.clearCallingIdentity();
836 try {
837 if (ws != null) {
838 mBatteryStats.noteStopWakelockFromSource(ws, wl.pid, wl.tag,
839 wl.monitorType);
840 } else {
841 mBatteryStats.noteStopWakelock(wl.uid, wl.pid, wl.tag, wl.monitorType);
842 }
843 } catch (RemoteException e) {
844 // Ignore
845 } finally {
846 Binder.restoreCallingIdentity(origId);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700847 }
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700848 }
849 }
850
851 public void acquireWakeLockLocked(int flags, IBinder lock, int uid, int pid, String tag,
852 WorkSource ws) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800853 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800854 Slog.d(TAG, "acquireWakeLock flags=0x" + Integer.toHexString(flags) + " tag=" + tag);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800855 }
856
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700857 if (ws != null && ws.size() == 0) {
858 ws = null;
859 }
860
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800861 int index = mLocks.getIndex(lock);
862 WakeLock wl;
863 boolean newlock;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700864 boolean diffsource;
865 WorkSource oldsource;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800866 if (index < 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700867 wl = new WakeLock(flags, lock, tag, uid, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800868 switch (wl.flags & LOCK_MASK)
869 {
870 case PowerManager.FULL_WAKE_LOCK:
Mike Lockwood4984e732009-11-01 08:16:33 -0500871 if (mUseSoftwareAutoBrightness) {
Mike Lockwood3333fa42009-10-26 14:50:42 -0400872 wl.minState = SCREEN_BRIGHT;
873 } else {
874 wl.minState = (mKeyboardVisible ? ALL_BRIGHT : SCREEN_BUTTON_BRIGHT);
875 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800876 break;
877 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
878 wl.minState = SCREEN_BRIGHT;
879 break;
880 case PowerManager.SCREEN_DIM_WAKE_LOCK:
881 wl.minState = SCREEN_DIM;
882 break;
883 case PowerManager.PARTIAL_WAKE_LOCK:
Mike Lockwoodbc706a02009-07-27 13:50:57 -0700884 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800885 break;
886 default:
887 // just log and bail. we're in the server, so don't
888 // throw an exception.
Joe Onorato8a9b2202010-02-26 18:56:32 -0800889 Slog.e(TAG, "bad wakelock type for lock '" + tag + "' "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800890 + " flags=" + flags);
891 return;
892 }
893 mLocks.addLock(wl);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700894 if (ws != null) {
895 wl.ws = new WorkSource(ws);
896 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800897 newlock = true;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700898 diffsource = false;
899 oldsource = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800900 } else {
901 wl = mLocks.get(index);
902 newlock = false;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700903 oldsource = wl.ws;
904 if (oldsource != null) {
905 if (ws == null) {
906 wl.ws = null;
907 diffsource = true;
908 } else {
909 diffsource = oldsource.diff(ws);
910 }
911 } else if (ws != null) {
912 diffsource = true;
913 } else {
914 diffsource = false;
915 }
916 if (diffsource) {
917 wl.ws = new WorkSource(ws);
918 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800919 }
920 if (isScreenLock(flags)) {
921 // if this causes a wakeup, we reactivate all of the locks and
922 // set it to whatever they want. otherwise, we modulate that
923 // by the current state so we never turn it more on than
924 // it already is.
Joe Onorato8274a0e2010-10-05 17:38:09 -0400925 if ((flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) {
926 mProximityWakeLockCount++;
927 if (mProximityWakeLockCount == 1) {
928 enableProximityLockLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800929 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800930 } else {
Joe Onorato8274a0e2010-10-05 17:38:09 -0400931 if ((wl.flags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {
932 int oldWakeLockState = mWakeLockState;
933 mWakeLockState = mLocks.reactivateScreenLocksLocked();
Mike Lockwooddb97f602011-09-02 11:59:08 -0400934
935 // Disable proximity sensor if if user presses power key while we are in the
936 // "waiting for proximity sensor to go negative" state.
937 if ((mWakeLockState & SCREEN_ON_BIT) != 0
938 && mProximitySensorActive && mProximityWakeLockCount == 0) {
939 mProximitySensorActive = false;
940 }
941
Joe Onorato8274a0e2010-10-05 17:38:09 -0400942 if (mSpew) {
943 Slog.d(TAG, "wakeup here mUserState=0x" + Integer.toHexString(mUserState)
944 + " mWakeLockState=0x"
945 + Integer.toHexString(mWakeLockState)
946 + " previous wakeLockState=0x"
947 + Integer.toHexString(oldWakeLockState));
948 }
949 } else {
950 if (mSpew) {
951 Slog.d(TAG, "here mUserState=0x" + Integer.toHexString(mUserState)
952 + " mLocks.gatherState()=0x"
953 + Integer.toHexString(mLocks.gatherState())
954 + " mWakeLockState=0x" + Integer.toHexString(mWakeLockState));
955 }
956 mWakeLockState = (mUserState | mWakeLockState) & mLocks.gatherState();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800957 }
Joe Onorato8274a0e2010-10-05 17:38:09 -0400958 setPowerState(mWakeLockState | mUserState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800959 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800960 }
961 else if ((flags & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK) {
962 if (newlock) {
963 mPartialCount++;
964 if (mPartialCount == 1) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800965 if (LOG_PARTIAL_WL) EventLog.writeEvent(EventLogTags.POWER_PARTIAL_WAKE_STATE, 1, tag);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800966 }
967 }
Jeff Brown7304c342012-05-11 18:42:42 -0700968 nativeAcquireWakeLock(PARTIAL_WAKE_LOCK_ID, PARTIAL_NAME);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800969 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800970
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700971 if (diffsource) {
972 // If the lock sources have changed, need to first release the
973 // old ones.
974 noteStopWakeLocked(wl, oldsource);
975 }
976 if (newlock || diffsource) {
977 noteStartWakeLocked(wl, ws);
978 }
979 }
980
981 public void updateWakeLockWorkSource(IBinder lock, WorkSource ws) {
982 int uid = Binder.getCallingUid();
983 int pid = Binder.getCallingPid();
984 if (ws != null && ws.size() == 0) {
985 ws = null;
986 }
987 if (ws != null) {
988 enforceWakeSourcePermission(uid, pid);
989 }
Dianne Hackborn70be1672010-09-14 11:13:03 -0700990 synchronized (mLocks) {
991 int index = mLocks.getIndex(lock);
992 if (index < 0) {
993 throw new IllegalArgumentException("Wake lock not active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800994 }
Dianne Hackborn70be1672010-09-14 11:13:03 -0700995 WakeLock wl = mLocks.get(index);
996 WorkSource oldsource = wl.ws;
997 wl.ws = ws != null ? new WorkSource(ws) : null;
998 noteStopWakeLocked(wl, oldsource);
999 noteStartWakeLocked(wl, ws);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001000 }
1001 }
1002
Mike Lockwood0e39ea82009-11-18 15:37:10 -05001003 public void releaseWakeLock(IBinder lock, int flags) {
Michael Chane96440f2009-05-06 10:27:36 -07001004 int uid = Binder.getCallingUid();
1005 if (uid != Process.myUid()) {
1006 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
1007 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001008
1009 synchronized (mLocks) {
Mike Lockwood0e39ea82009-11-18 15:37:10 -05001010 releaseWakeLockLocked(lock, flags, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001011 }
1012 }
1013
Mike Lockwood0e39ea82009-11-18 15:37:10 -05001014 private void releaseWakeLockLocked(IBinder lock, int flags, boolean death) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001015 WakeLock wl = mLocks.removeLock(lock);
1016 if (wl == null) {
1017 return;
1018 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001019
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001020 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001021 Slog.d(TAG, "releaseWakeLock flags=0x"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001022 + Integer.toHexString(wl.flags) + " tag=" + wl.tag);
1023 }
1024
1025 if (isScreenLock(wl.flags)) {
Joe Onorato8274a0e2010-10-05 17:38:09 -04001026 if ((wl.flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) {
1027 mProximityWakeLockCount--;
1028 if (mProximityWakeLockCount == 0) {
1029 if (mProximitySensorActive &&
1030 ((flags & PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE) != 0)) {
1031 // wait for proximity sensor to go negative before disabling sensor
1032 if (mDebugProximitySensor) {
1033 Slog.d(TAG, "waiting for proximity sensor to go negative");
1034 }
1035 } else {
1036 disableProximityLockLocked();
1037 }
1038 }
1039 } else {
1040 mWakeLockState = mLocks.gatherState();
1041 // goes in the middle to reduce flicker
1042 if ((wl.flags & PowerManager.ON_AFTER_RELEASE) != 0) {
1043 userActivity(SystemClock.uptimeMillis(), -1, false, OTHER_EVENT, false);
1044 }
1045 setPowerState(mWakeLockState | mUserState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001046 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001047 }
1048 else if ((wl.flags & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK) {
1049 mPartialCount--;
1050 if (mPartialCount == 0) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001051 if (LOG_PARTIAL_WL) EventLog.writeEvent(EventLogTags.POWER_PARTIAL_WAKE_STATE, 0, wl.tag);
Jeff Brown7304c342012-05-11 18:42:42 -07001052 nativeReleaseWakeLock(PARTIAL_NAME);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001053 }
1054 }
1055 // Unlink the lock from the binder.
1056 wl.binder.unlinkToDeath(wl, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001057
Dianne Hackborn70be1672010-09-14 11:13:03 -07001058 noteStopWakeLocked(wl, wl.ws);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001059 }
1060
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001061 private class PokeLock implements IBinder.DeathRecipient
1062 {
1063 PokeLock(int p, IBinder b, String t) {
1064 super();
1065 this.pokey = p;
1066 this.binder = b;
1067 this.tag = t;
1068 try {
1069 b.linkToDeath(this, 0);
1070 } catch (RemoteException e) {
1071 binderDied();
1072 }
1073 }
1074 public void binderDied() {
1075 setPokeLock(0, this.binder, this.tag);
1076 }
1077 int pokey;
1078 IBinder binder;
1079 String tag;
1080 boolean awakeOnSet;
1081 }
1082
1083 public void setPokeLock(int pokey, IBinder token, String tag) {
1084 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1085 if (token == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001086 Slog.e(TAG, "setPokeLock got null token for tag='" + tag + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001087 return;
1088 }
1089
1090 if ((pokey & POKE_LOCK_TIMEOUT_MASK) == POKE_LOCK_TIMEOUT_MASK) {
1091 throw new IllegalArgumentException("setPokeLock can't have both POKE_LOCK_SHORT_TIMEOUT"
1092 + " and POKE_LOCK_MEDIUM_TIMEOUT");
1093 }
1094
1095 synchronized (mLocks) {
1096 if (pokey != 0) {
1097 PokeLock p = mPokeLocks.get(token);
1098 int oldPokey = 0;
1099 if (p != null) {
1100 oldPokey = p.pokey;
1101 p.pokey = pokey;
1102 } else {
1103 p = new PokeLock(pokey, token, tag);
1104 mPokeLocks.put(token, p);
1105 }
1106 int oldTimeout = oldPokey & POKE_LOCK_TIMEOUT_MASK;
1107 int newTimeout = pokey & POKE_LOCK_TIMEOUT_MASK;
1108 if (((mPowerState & SCREEN_ON_BIT) == 0) && (oldTimeout != newTimeout)) {
1109 p.awakeOnSet = true;
1110 }
1111 } else {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07001112 PokeLock rLock = mPokeLocks.remove(token);
1113 if (rLock != null) {
1114 token.unlinkToDeath(rLock, 0);
1115 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001116 }
1117
1118 int oldPokey = mPokey;
1119 int cumulative = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001120 boolean awakeOnSet = false;
1121 for (PokeLock p: mPokeLocks.values()) {
1122 cumulative |= p.pokey;
1123 if (p.awakeOnSet) {
1124 awakeOnSet = true;
1125 }
1126 }
1127 mPokey = cumulative;
1128 mPokeAwakeOnSet = awakeOnSet;
1129
1130 int oldCumulativeTimeout = oldPokey & POKE_LOCK_TIMEOUT_MASK;
1131 int newCumulativeTimeout = pokey & POKE_LOCK_TIMEOUT_MASK;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001132
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001133 if (oldCumulativeTimeout != newCumulativeTimeout) {
1134 setScreenOffTimeoutsLocked();
1135 // reset the countdown timer, but use the existing nextState so it doesn't
1136 // change anything
1137 setTimeoutLocked(SystemClock.uptimeMillis(), mTimeoutTask.nextState);
1138 }
1139 }
1140 }
1141
1142 private static String lockType(int type)
1143 {
1144 switch (type)
1145 {
1146 case PowerManager.FULL_WAKE_LOCK:
David Brown251faa62009-08-02 22:04:36 -07001147 return "FULL_WAKE_LOCK ";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001148 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
David Brown251faa62009-08-02 22:04:36 -07001149 return "SCREEN_BRIGHT_WAKE_LOCK ";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001150 case PowerManager.SCREEN_DIM_WAKE_LOCK:
David Brown251faa62009-08-02 22:04:36 -07001151 return "SCREEN_DIM_WAKE_LOCK ";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001152 case PowerManager.PARTIAL_WAKE_LOCK:
David Brown251faa62009-08-02 22:04:36 -07001153 return "PARTIAL_WAKE_LOCK ";
1154 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
1155 return "PROXIMITY_SCREEN_OFF_WAKE_LOCK";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001156 default:
David Brown251faa62009-08-02 22:04:36 -07001157 return "??? ";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001158 }
1159 }
1160
1161 private static String dumpPowerState(int state) {
1162 return (((state & KEYBOARD_BRIGHT_BIT) != 0)
1163 ? "KEYBOARD_BRIGHT_BIT " : "")
1164 + (((state & SCREEN_BRIGHT_BIT) != 0)
1165 ? "SCREEN_BRIGHT_BIT " : "")
1166 + (((state & SCREEN_ON_BIT) != 0)
1167 ? "SCREEN_ON_BIT " : "")
1168 + (((state & BATTERY_LOW_BIT) != 0)
1169 ? "BATTERY_LOW_BIT " : "");
1170 }
1171
1172 @Override
1173 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1174 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
1175 != PackageManager.PERMISSION_GRANTED) {
1176 pw.println("Permission Denial: can't dump PowerManager from from pid="
1177 + Binder.getCallingPid()
1178 + ", uid=" + Binder.getCallingUid());
1179 return;
1180 }
1181
1182 long now = SystemClock.uptimeMillis();
1183
Mike Lockwoodca44df82010-02-25 13:48:49 -05001184 synchronized (mLocks) {
1185 pw.println("Power Manager State:");
1186 pw.println(" mIsPowered=" + mIsPowered
1187 + " mPowerState=" + mPowerState
1188 + " mScreenOffTime=" + (SystemClock.elapsedRealtime()-mScreenOffTime)
1189 + " ms");
1190 pw.println(" mPartialCount=" + mPartialCount);
1191 pw.println(" mWakeLockState=" + dumpPowerState(mWakeLockState));
1192 pw.println(" mUserState=" + dumpPowerState(mUserState));
1193 pw.println(" mPowerState=" + dumpPowerState(mPowerState));
1194 pw.println(" mLocks.gather=" + dumpPowerState(mLocks.gatherState()));
1195 pw.println(" mNextTimeout=" + mNextTimeout + " now=" + now
1196 + " " + ((mNextTimeout-now)/1000) + "s from now");
1197 pw.println(" mDimScreen=" + mDimScreen
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001198 + " mStayOnConditions=" + mStayOnConditions
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001199 + " mPreparingForScreenOn=" + mPreparingForScreenOn
1200 + " mSkippedScreenOn=" + mSkippedScreenOn);
Mike Lockwoodca44df82010-02-25 13:48:49 -05001201 pw.println(" mScreenOffReason=" + mScreenOffReason
1202 + " mUserState=" + mUserState);
1203 pw.println(" mBroadcastQueue={" + mBroadcastQueue[0] + ',' + mBroadcastQueue[1]
1204 + ',' + mBroadcastQueue[2] + "}");
1205 pw.println(" mBroadcastWhy={" + mBroadcastWhy[0] + ',' + mBroadcastWhy[1]
1206 + ',' + mBroadcastWhy[2] + "}");
1207 pw.println(" mPokey=" + mPokey + " mPokeAwakeonSet=" + mPokeAwakeOnSet);
1208 pw.println(" mKeyboardVisible=" + mKeyboardVisible
1209 + " mUserActivityAllowed=" + mUserActivityAllowed);
1210 pw.println(" mKeylightDelay=" + mKeylightDelay + " mDimDelay=" + mDimDelay
1211 + " mScreenOffDelay=" + mScreenOffDelay);
1212 pw.println(" mPreventScreenOn=" + mPreventScreenOn
1213 + " mScreenBrightnessOverride=" + mScreenBrightnessOverride
1214 + " mButtonBrightnessOverride=" + mButtonBrightnessOverride);
1215 pw.println(" mScreenOffTimeoutSetting=" + mScreenOffTimeoutSetting
1216 + " mMaximumScreenOffTimeout=" + mMaximumScreenOffTimeout);
1217 pw.println(" mLastScreenOnTime=" + mLastScreenOnTime);
1218 pw.println(" mBroadcastWakeLock=" + mBroadcastWakeLock);
1219 pw.println(" mStayOnWhilePluggedInScreenDimLock=" + mStayOnWhilePluggedInScreenDimLock);
1220 pw.println(" mStayOnWhilePluggedInPartialLock=" + mStayOnWhilePluggedInPartialLock);
1221 pw.println(" mPreventScreenOnPartialLock=" + mPreventScreenOnPartialLock);
1222 pw.println(" mProximityPartialLock=" + mProximityPartialLock);
1223 pw.println(" mProximityWakeLockCount=" + mProximityWakeLockCount);
1224 pw.println(" mProximitySensorEnabled=" + mProximitySensorEnabled);
1225 pw.println(" mProximitySensorActive=" + mProximitySensorActive);
1226 pw.println(" mProximityPendingValue=" + mProximityPendingValue);
1227 pw.println(" mLastProximityEventTime=" + mLastProximityEventTime);
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08001228 pw.println(" mLightSensorEnabled=" + mLightSensorEnabled
1229 + " mLightSensorAdjustSetting=" + mLightSensorAdjustSetting);
Mike Lockwoodca44df82010-02-25 13:48:49 -05001230 pw.println(" mLightSensorValue=" + mLightSensorValue
1231 + " mLightSensorPendingValue=" + mLightSensorPendingValue);
Craig Mautner291576e2012-06-07 19:58:58 -07001232 pw.println(" mHighestLightSensorValue=" + mHighestLightSensorValue
1233 + " mWaitingForFirstLightSensor=" + mWaitingForFirstLightSensor);
Jim Rodovichd102fea2010-09-02 12:30:49 -05001234 pw.println(" mLightSensorPendingDecrease=" + mLightSensorPendingDecrease
1235 + " mLightSensorPendingIncrease=" + mLightSensorPendingIncrease);
Mike Lockwoodca44df82010-02-25 13:48:49 -05001236 pw.println(" mLightSensorScreenBrightness=" + mLightSensorScreenBrightness
1237 + " mLightSensorButtonBrightness=" + mLightSensorButtonBrightness
1238 + " mLightSensorKeyboardBrightness=" + mLightSensorKeyboardBrightness);
1239 pw.println(" mUseSoftwareAutoBrightness=" + mUseSoftwareAutoBrightness);
1240 pw.println(" mAutoBrightessEnabled=" + mAutoBrightessEnabled);
Jim Miller92e66dd2012-02-21 18:57:12 -08001241 mScreenBrightnessAnimator.dump(pw, " mScreenBrightnessAnimator: ");
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001242
Mike Lockwoodca44df82010-02-25 13:48:49 -05001243 int N = mLocks.size();
1244 pw.println();
1245 pw.println("mLocks.size=" + N + ":");
1246 for (int i=0; i<N; i++) {
1247 WakeLock wl = mLocks.get(i);
1248 String type = lockType(wl.flags & LOCK_MASK);
1249 String acquireCausesWakeup = "";
1250 if ((wl.flags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {
1251 acquireCausesWakeup = "ACQUIRE_CAUSES_WAKEUP ";
1252 }
1253 String activated = "";
1254 if (wl.activated) {
1255 activated = " activated";
1256 }
1257 pw.println(" " + type + " '" + wl.tag + "'" + acquireCausesWakeup
Mike Lockwoodf5bd0922010-03-22 17:10:15 -04001258 + activated + " (minState=" + wl.minState + ", uid=" + wl.uid
1259 + ", pid=" + wl.pid + ")");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001260 }
Mike Lockwoodca44df82010-02-25 13:48:49 -05001261
1262 pw.println();
1263 pw.println("mPokeLocks.size=" + mPokeLocks.size() + ":");
1264 for (PokeLock p: mPokeLocks.values()) {
1265 pw.println(" poke lock '" + p.tag + "':"
Joe Onorato1a542c72010-11-08 09:48:20 -08001266 + ((p.pokey & POKE_LOCK_IGNORE_TOUCH_EVENTS) != 0
1267 ? " POKE_LOCK_IGNORE_TOUCH_EVENTS" : "")
Mike Lockwoodca44df82010-02-25 13:48:49 -05001268 + ((p.pokey & POKE_LOCK_SHORT_TIMEOUT) != 0
1269 ? " POKE_LOCK_SHORT_TIMEOUT" : "")
1270 + ((p.pokey & POKE_LOCK_MEDIUM_TIMEOUT) != 0
1271 ? " POKE_LOCK_MEDIUM_TIMEOUT" : ""));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001272 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001273
Mike Lockwoodca44df82010-02-25 13:48:49 -05001274 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001275 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001276 }
1277
Joe Onorato7999bff2010-07-24 11:50:05 -04001278 private void setTimeoutLocked(long now, int nextState) {
1279 setTimeoutLocked(now, -1, nextState);
1280 }
1281
1282 // If they gave a timeoutOverride it is the number of seconds
1283 // to screen-off. Figure out where in the countdown cycle we
1284 // should jump to.
Joe Onorato797e6882010-08-26 14:46:01 -04001285 private void setTimeoutLocked(long now, final long originalTimeoutOverride, int nextState) {
1286 long timeoutOverride = originalTimeoutOverride;
Mike Lockwood2d7bb812009-11-15 18:12:22 -05001287 if (mBootCompleted) {
Joe Onorato7999bff2010-07-24 11:50:05 -04001288 synchronized (mLocks) {
Joe Onorato7999bff2010-07-24 11:50:05 -04001289 long when = 0;
1290 if (timeoutOverride <= 0) {
1291 switch (nextState)
1292 {
1293 case SCREEN_BRIGHT:
1294 when = now + mKeylightDelay;
1295 break;
1296 case SCREEN_DIM:
1297 if (mDimDelay >= 0) {
1298 when = now + mDimDelay;
Andreas Huber84047bc2010-07-27 16:49:10 -07001299 break;
Joe Onorato7999bff2010-07-24 11:50:05 -04001300 } else {
1301 Slog.w(TAG, "mDimDelay=" + mDimDelay + " while trying to dim");
1302 }
1303 case SCREEN_OFF:
1304 synchronized (mLocks) {
1305 when = now + mScreenOffDelay;
1306 }
1307 break;
Andreas Huber84047bc2010-07-27 16:49:10 -07001308 default:
1309 when = now;
1310 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001311 }
Joe Onorato7999bff2010-07-24 11:50:05 -04001312 } else {
1313 override: {
1314 if (timeoutOverride <= mScreenOffDelay) {
1315 when = now + timeoutOverride;
1316 nextState = SCREEN_OFF;
1317 break override;
1318 }
1319 timeoutOverride -= mScreenOffDelay;
1320
1321 if (mDimDelay >= 0) {
1322 if (timeoutOverride <= mDimDelay) {
1323 when = now + timeoutOverride;
1324 nextState = SCREEN_DIM;
1325 break override;
1326 }
1327 timeoutOverride -= mDimDelay;
1328 }
1329
1330 when = now + timeoutOverride;
1331 nextState = SCREEN_BRIGHT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001332 }
Joe Onorato7999bff2010-07-24 11:50:05 -04001333 }
1334 if (mSpew) {
1335 Slog.d(TAG, "setTimeoutLocked now=" + now
1336 + " timeoutOverride=" + timeoutOverride
1337 + " nextState=" + nextState + " when=" + when);
1338 }
Joe Onorato797e6882010-08-26 14:46:01 -04001339
1340 mHandler.removeCallbacks(mTimeoutTask);
1341 mTimeoutTask.nextState = nextState;
1342 mTimeoutTask.remainingTimeoutOverride = timeoutOverride > 0
1343 ? (originalTimeoutOverride - timeoutOverride)
1344 : -1;
Joe Onorato7999bff2010-07-24 11:50:05 -04001345 mHandler.postAtTime(mTimeoutTask, when);
1346 mNextTimeout = when; // for debugging
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001347 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001348 }
1349 }
1350
1351 private void cancelTimerLocked()
1352 {
1353 mHandler.removeCallbacks(mTimeoutTask);
1354 mTimeoutTask.nextState = -1;
1355 }
1356
1357 private class TimeoutTask implements Runnable
1358 {
1359 int nextState; // access should be synchronized on mLocks
Joe Onorato797e6882010-08-26 14:46:01 -04001360 long remainingTimeoutOverride;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001361 public void run()
1362 {
1363 synchronized (mLocks) {
1364 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001365 Slog.d(TAG, "user activity timeout timed out nextState=" + this.nextState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001366 }
1367
1368 if (nextState == -1) {
1369 return;
1370 }
1371
1372 mUserState = this.nextState;
1373 setPowerState(this.nextState | mWakeLockState);
1374
1375 long now = SystemClock.uptimeMillis();
1376
1377 switch (this.nextState)
1378 {
1379 case SCREEN_BRIGHT:
1380 if (mDimDelay >= 0) {
Joe Onorato797e6882010-08-26 14:46:01 -04001381 setTimeoutLocked(now, remainingTimeoutOverride, SCREEN_DIM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001382 break;
1383 }
1384 case SCREEN_DIM:
Joe Onorato797e6882010-08-26 14:46:01 -04001385 setTimeoutLocked(now, remainingTimeoutOverride, SCREEN_OFF);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001386 break;
1387 }
1388 }
1389 }
1390 }
1391
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001392 private void sendNotificationLocked(boolean on, int why) {
1393 if (!mInitialized) {
1394 // No notifications sent until first initialization is done.
1395 // This is so that when we are moving from our initial state
1396 // which looks like the screen was off to it being on, we do not
1397 // go through the process of waiting for the higher-level user
1398 // space to be ready before turning up the display brightness.
1399 // (And also do not send needless broadcasts about the screen.)
1400 return;
1401 }
Dianne Hackborn40011092011-09-22 13:37:48 -07001402
1403 if (DEBUG_SCREEN_ON) {
1404 RuntimeException here = new RuntimeException("here");
1405 here.fillInStackTrace();
1406 Slog.i(TAG, "sendNotificationLocked: " + on, here);
1407 }
1408
Joe Onorato64c62ba2009-03-24 20:13:57 -07001409 if (!on) {
1410 mStillNeedSleepNotification = false;
1411 }
1412
Joe Onorato128e7292009-03-24 18:41:31 -07001413 // Add to the queue.
1414 int index = 0;
1415 while (mBroadcastQueue[index] != -1) {
1416 index++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001417 }
Joe Onorato128e7292009-03-24 18:41:31 -07001418 mBroadcastQueue[index] = on ? 1 : 0;
1419 mBroadcastWhy[index] = why;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001420
Joe Onorato128e7292009-03-24 18:41:31 -07001421 // If we added it position 2, then there is a pair that can be stripped.
1422 // If we added it position 1 and we're turning the screen off, we can strip
1423 // the pair and do nothing, because the screen is already off, and therefore
1424 // keyguard has already been enabled.
1425 // However, if we added it at position 1 and we're turning it on, then position
1426 // 0 was to turn it off, and we can't strip that, because keyguard needs to come
1427 // on, so have to run the queue then.
1428 if (index == 2) {
Dianne Hackborn254cb442010-01-27 19:23:59 -08001429 // While we're collapsing them, if it's going off, and the new reason
1430 // is more significant than the first, then use the new one.
1431 if (!on && mBroadcastWhy[0] > why) {
1432 mBroadcastWhy[0] = why;
Joe Onorato128e7292009-03-24 18:41:31 -07001433 }
1434 mBroadcastQueue[0] = on ? 1 : 0;
1435 mBroadcastQueue[1] = -1;
1436 mBroadcastQueue[2] = -1;
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001437 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount);
Mike Lockwood9c90a372010-04-13 15:40:27 -04001438 mBroadcastWakeLock.release();
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001439 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount);
Mike Lockwood9c90a372010-04-13 15:40:27 -04001440 mBroadcastWakeLock.release();
Joe Onorato128e7292009-03-24 18:41:31 -07001441 index = 0;
1442 }
1443 if (index == 1 && !on) {
1444 mBroadcastQueue[0] = -1;
1445 mBroadcastQueue[1] = -1;
1446 index = -1;
1447 // The wake lock was being held, but we're not actually going to do any
1448 // broadcasts, so release the wake lock.
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001449 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001450 mBroadcastWakeLock.release();
Joe Onorato128e7292009-03-24 18:41:31 -07001451 }
1452
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07001453 // The broadcast queue has changed; make sure the screen is on if it
1454 // is now possible for it to be.
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001455 if (mSkippedScreenOn) {
1456 updateLightsLocked(mPowerState, SCREEN_ON_BIT);
1457 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07001458
Joe Onorato128e7292009-03-24 18:41:31 -07001459 // Now send the message.
1460 if (index >= 0) {
1461 // Acquire the broadcast wake lock before changing the power
1462 // state. It will be release after the broadcast is sent.
1463 // We always increment the ref count for each notification in the queue
1464 // and always decrement when that notification is handled.
1465 mBroadcastWakeLock.acquire();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001466 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND, mBroadcastWakeLock.mCount);
Joe Onorato128e7292009-03-24 18:41:31 -07001467 mHandler.post(mNotificationTask);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001468 }
1469 }
1470
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001471 private WindowManagerPolicy.ScreenOnListener mScreenOnListener =
1472 new WindowManagerPolicy.ScreenOnListener() {
Jim Miller92e66dd2012-02-21 18:57:12 -08001473 public void onScreenOn() {
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001474 synchronized (mLocks) {
1475 if (mPreparingForScreenOn) {
1476 mPreparingForScreenOn = false;
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001477 updateLightsLocked(mPowerState, SCREEN_ON_BIT);
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001478 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP,
1479 4, mBroadcastWakeLock.mCount);
1480 mBroadcastWakeLock.release();
1481 }
1482 }
1483 }
1484 };
1485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001486 private Runnable mNotificationTask = new Runnable()
1487 {
1488 public void run()
1489 {
Joe Onorato128e7292009-03-24 18:41:31 -07001490 while (true) {
1491 int value;
1492 int why;
1493 WindowManagerPolicy policy;
1494 synchronized (mLocks) {
1495 value = mBroadcastQueue[0];
1496 why = mBroadcastWhy[0];
1497 for (int i=0; i<2; i++) {
1498 mBroadcastQueue[i] = mBroadcastQueue[i+1];
1499 mBroadcastWhy[i] = mBroadcastWhy[i+1];
1500 }
1501 policy = getPolicyLocked();
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001502 if (value == 1 && !mPreparingForScreenOn) {
1503 mPreparingForScreenOn = true;
1504 mBroadcastWakeLock.acquire();
1505 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND,
1506 mBroadcastWakeLock.mCount);
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07001507 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001508 }
Joe Onorato128e7292009-03-24 18:41:31 -07001509 if (value == 1) {
1510 mScreenOnStart = SystemClock.uptimeMillis();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001511
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001512 policy.screenTurningOn(mScreenOnListener);
Joe Onorato128e7292009-03-24 18:41:31 -07001513 try {
1514 ActivityManagerNative.getDefault().wakingUp();
1515 } catch (RemoteException e) {
1516 // ignore it
1517 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001518
Joe Onorato128e7292009-03-24 18:41:31 -07001519 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001520 Slog.d(TAG, "mBroadcastWakeLock=" + mBroadcastWakeLock);
Joe Onorato128e7292009-03-24 18:41:31 -07001521 }
1522 if (mContext != null && ActivityManagerNative.isSystemReady()) {
1523 mContext.sendOrderedBroadcast(mScreenOnIntent, null,
1524 mScreenOnBroadcastDone, mHandler, 0, null, null);
1525 } else {
1526 synchronized (mLocks) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001527 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 2,
Joe Onorato128e7292009-03-24 18:41:31 -07001528 mBroadcastWakeLock.mCount);
1529 mBroadcastWakeLock.release();
1530 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001531 }
1532 }
Joe Onorato128e7292009-03-24 18:41:31 -07001533 else if (value == 0) {
1534 mScreenOffStart = SystemClock.uptimeMillis();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001535
Joe Onorato128e7292009-03-24 18:41:31 -07001536 policy.screenTurnedOff(why);
1537 try {
1538 ActivityManagerNative.getDefault().goingToSleep();
1539 } catch (RemoteException e) {
1540 // ignore it.
1541 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001542
Joe Onorato128e7292009-03-24 18:41:31 -07001543 if (mContext != null && ActivityManagerNative.isSystemReady()) {
1544 mContext.sendOrderedBroadcast(mScreenOffIntent, null,
1545 mScreenOffBroadcastDone, mHandler, 0, null, null);
1546 } else {
1547 synchronized (mLocks) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001548 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 3,
Joe Onorato128e7292009-03-24 18:41:31 -07001549 mBroadcastWakeLock.mCount);
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001550 updateLightsLocked(mPowerState, SCREEN_ON_BIT);
Joe Onorato128e7292009-03-24 18:41:31 -07001551 mBroadcastWakeLock.release();
1552 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001553 }
1554 }
Joe Onorato128e7292009-03-24 18:41:31 -07001555 else {
1556 // If we're in this case, then this handler is running for a previous
1557 // paired transaction. mBroadcastWakeLock will already have been released.
1558 break;
1559 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001560 }
1561 }
1562 };
1563
1564 long mScreenOnStart;
1565 private BroadcastReceiver mScreenOnBroadcastDone = new BroadcastReceiver() {
1566 public void onReceive(Context context, Intent intent) {
1567 synchronized (mLocks) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001568 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001569 SystemClock.uptimeMillis() - mScreenOnStart, mBroadcastWakeLock.mCount);
1570 mBroadcastWakeLock.release();
1571 }
1572 }
1573 };
1574
1575 long mScreenOffStart;
1576 private BroadcastReceiver mScreenOffBroadcastDone = new BroadcastReceiver() {
1577 public void onReceive(Context context, Intent intent) {
1578 synchronized (mLocks) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001579 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 0,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001580 SystemClock.uptimeMillis() - mScreenOffStart, mBroadcastWakeLock.mCount);
1581 mBroadcastWakeLock.release();
1582 }
1583 }
1584 };
1585
1586 void logPointerUpEvent() {
1587 if (LOG_TOUCH_DOWNS) {
1588 mTotalTouchDownTime += SystemClock.elapsedRealtime() - mLastTouchDown;
1589 mLastTouchDown = 0;
1590 }
1591 }
1592
1593 void logPointerDownEvent() {
1594 if (LOG_TOUCH_DOWNS) {
1595 // If we are not already timing a down/up sequence
1596 if (mLastTouchDown == 0) {
1597 mLastTouchDown = SystemClock.elapsedRealtime();
1598 mTouchCycles++;
1599 }
1600 }
1601 }
1602
1603 /**
1604 * Prevents the screen from turning on even if it *should* turn on due
1605 * to a subsequent full wake lock being acquired.
1606 * <p>
1607 * This is a temporary hack that allows an activity to "cover up" any
1608 * display glitches that happen during the activity's startup
1609 * sequence. (Specifically, this API was added to work around a
1610 * cosmetic bug in the "incoming call" sequence, where the lock screen
1611 * would flicker briefly before the incoming call UI became visible.)
1612 * TODO: There ought to be a more elegant way of doing this,
1613 * probably by having the PowerManager and ActivityManager
1614 * work together to let apps specify that the screen on/off
1615 * state should be synchronized with the Activity lifecycle.
1616 * <p>
1617 * Note that calling preventScreenOn(true) will NOT turn the screen
1618 * off if it's currently on. (This API only affects *future*
1619 * acquisitions of full wake locks.)
1620 * But calling preventScreenOn(false) WILL turn the screen on if
1621 * it's currently off because of a prior preventScreenOn(true) call.
1622 * <p>
1623 * Any call to preventScreenOn(true) MUST be followed promptly by a call
1624 * to preventScreenOn(false). In fact, if the preventScreenOn(false)
1625 * call doesn't occur within 5 seconds, we'll turn the screen back on
1626 * ourselves (and log a warning about it); this prevents a buggy app
1627 * from disabling the screen forever.)
1628 * <p>
1629 * TODO: this feature should really be controlled by a new type of poke
1630 * lock (rather than an IPowerManager call).
1631 */
1632 public void preventScreenOn(boolean prevent) {
1633 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1634
1635 synchronized (mLocks) {
1636 if (prevent) {
1637 // First of all, grab a partial wake lock to
1638 // make sure the CPU stays on during the entire
1639 // preventScreenOn(true) -> preventScreenOn(false) sequence.
1640 mPreventScreenOnPartialLock.acquire();
1641
1642 // Post a forceReenableScreen() call (for 5 seconds in the
1643 // future) to make sure the matching preventScreenOn(false) call
1644 // has happened by then.
1645 mHandler.removeCallbacks(mForceReenableScreenTask);
1646 mHandler.postDelayed(mForceReenableScreenTask, 5000);
1647
1648 // Finally, set the flag that prevents the screen from turning on.
1649 // (Below, in setPowerState(), we'll check mPreventScreenOn and
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001650 // we *won't* call setScreenStateLocked(true) if it's set.)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001651 mPreventScreenOn = true;
1652 } else {
1653 // (Re)enable the screen.
1654 mPreventScreenOn = false;
1655
1656 // We're "undoing" a the prior preventScreenOn(true) call, so we
1657 // no longer need the 5-second safeguard.
1658 mHandler.removeCallbacks(mForceReenableScreenTask);
1659
1660 // Forcibly turn on the screen if it's supposed to be on. (This
1661 // handles the case where the screen is currently off because of
1662 // a prior preventScreenOn(true) call.)
Mike Lockwoode090281422009-11-14 21:02:56 -05001663 if (!mProximitySensorActive && (mPowerState & SCREEN_ON_BIT) != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001664 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001665 Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001666 "preventScreenOn: turning on after a prior preventScreenOn(true)!");
1667 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001668 int err = setScreenStateLocked(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001669 if (err != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001670 Slog.w(TAG, "preventScreenOn: error from setScreenStateLocked(): " + err);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001671 }
1672 }
1673
1674 // Release the partial wake lock that we held during the
1675 // preventScreenOn(true) -> preventScreenOn(false) sequence.
1676 mPreventScreenOnPartialLock.release();
1677 }
1678 }
1679 }
1680
1681 public void setScreenBrightnessOverride(int brightness) {
1682 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1683
Mike Lockwoodf527c712010-06-10 14:12:33 -04001684 if (mSpew) Slog.d(TAG, "setScreenBrightnessOverride " + brightness);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001685 synchronized (mLocks) {
1686 if (mScreenBrightnessOverride != brightness) {
1687 mScreenBrightnessOverride = brightness;
Mike Lockwoodf527c712010-06-10 14:12:33 -04001688 if (isScreenOn()) {
1689 updateLightsLocked(mPowerState, SCREEN_ON_BIT);
1690 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001691 }
1692 }
1693 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05001694
1695 public void setButtonBrightnessOverride(int brightness) {
1696 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1697
Mike Lockwoodf527c712010-06-10 14:12:33 -04001698 if (mSpew) Slog.d(TAG, "setButtonBrightnessOverride " + brightness);
Mike Lockwoodfb73f792009-11-20 11:31:18 -05001699 synchronized (mLocks) {
1700 if (mButtonBrightnessOverride != brightness) {
1701 mButtonBrightnessOverride = brightness;
Mike Lockwoodf527c712010-06-10 14:12:33 -04001702 if (isScreenOn()) {
1703 updateLightsLocked(mPowerState, BUTTON_BRIGHT_BIT | KEYBOARD_BRIGHT_BIT);
1704 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05001705 }
1706 }
1707 }
1708
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001709 /**
1710 * Sanity-check that gets called 5 seconds after any call to
1711 * preventScreenOn(true). This ensures that the original call
1712 * is followed promptly by a call to preventScreenOn(false).
1713 */
1714 private void forceReenableScreen() {
1715 // We shouldn't get here at all if mPreventScreenOn is false, since
1716 // we should have already removed any existing
1717 // mForceReenableScreenTask messages...
1718 if (!mPreventScreenOn) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001719 Slog.w(TAG, "forceReenableScreen: mPreventScreenOn is false, nothing to do");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001720 return;
1721 }
1722
1723 // Uh oh. It's been 5 seconds since a call to
1724 // preventScreenOn(true) and we haven't re-enabled the screen yet.
1725 // This means the app that called preventScreenOn(true) is either
1726 // slow (i.e. it took more than 5 seconds to call preventScreenOn(false)),
1727 // or buggy (i.e. it forgot to call preventScreenOn(false), or
1728 // crashed before doing so.)
1729
1730 // Log a warning, and forcibly turn the screen back on.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001731 Slog.w(TAG, "App called preventScreenOn(true) but didn't promptly reenable the screen! "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001732 + "Forcing the screen back on...");
1733 preventScreenOn(false);
1734 }
1735
1736 private Runnable mForceReenableScreenTask = new Runnable() {
1737 public void run() {
1738 forceReenableScreen();
1739 }
1740 };
1741
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001742 private int setScreenStateLocked(boolean on) {
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001743 if (DEBUG_SCREEN_ON) {
1744 RuntimeException e = new RuntimeException("here");
1745 e.fillInStackTrace();
1746 Slog.i(TAG, "Set screen state: " + on, e);
1747 }
Dianne Hackborn474fd742011-10-10 18:40:22 -07001748 if (on) {
1749 if ((mPowerState & SCREEN_ON_BIT) == 0 || mSkippedScreenOn) {
1750 // If we are turning the screen state on, but the screen
1751 // light is currently off, then make sure that we set the
1752 // light at this point to 0. This is the case where we are
1753 // turning on the screen and waiting for the UI to be drawn
1754 // before showing it to the user. We want the light off
1755 // until it is ready to be shown to the user, not it using
1756 // whatever the last value it had.
Dianne Hackborn81de8b92011-11-28 16:54:31 -08001757 if (DEBUG_SCREEN_ON) {
1758 Slog.i(TAG, "Forcing brightness 0: mPowerState=0x"
1759 + Integer.toHexString(mPowerState)
1760 + " mSkippedScreenOn=" + mSkippedScreenOn);
1761 }
Jeff Brown7304c342012-05-11 18:42:42 -07001762 mScreenBrightnessAnimator.animateTo(PowerManager.BRIGHTNESS_OFF, SCREEN_BRIGHT_BIT, 0);
Dianne Hackborn474fd742011-10-10 18:40:22 -07001763 }
1764 }
Jeff Brown7304c342012-05-11 18:42:42 -07001765 int err = nativeSetScreenState(on);
Mike Lockwood20ee6f22009-11-07 20:33:47 -05001766 if (err == 0) {
1767 mLastScreenOnTime = (on ? SystemClock.elapsedRealtime() : 0);
1768 if (mUseSoftwareAutoBrightness) {
Joe Onoratod28f7532010-11-06 12:56:53 -07001769 enableLightSensorLocked(on);
Craig Mautner37933682012-06-06 14:13:39 -07001770 if (on) {
1771 // If AutoBrightness is enabled, set the brightness immediately after the
1772 // next sensor value is received.
1773 mWaitingForFirstLightSensor = mAutoBrightessEnabled;
1774 } else {
Mike Lockwood20ee6f22009-11-07 20:33:47 -05001775 // make sure button and key backlights are off too
Mike Lockwood3cb67a32009-11-27 14:25:58 -05001776 mButtonLight.turnOff();
1777 mKeyboardLight.turnOff();
Mike Lockwood20ee6f22009-11-07 20:33:47 -05001778 }
Mike Lockwoodd7786b42009-10-15 17:09:16 -07001779 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001780 }
1781 return err;
1782 }
1783
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001784 private void setPowerState(int state)
1785 {
Mike Lockwood435eb642009-12-03 08:40:18 -05001786 setPowerState(state, false, WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001787 }
1788
Mike Lockwood435eb642009-12-03 08:40:18 -05001789 private void setPowerState(int newState, boolean noChangeLights, int reason)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001790 {
1791 synchronized (mLocks) {
1792 int err;
1793
1794 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001795 Slog.d(TAG, "setPowerState: mPowerState=0x" + Integer.toHexString(mPowerState)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001796 + " newState=0x" + Integer.toHexString(newState)
Mike Lockwood435eb642009-12-03 08:40:18 -05001797 + " noChangeLights=" + noChangeLights
1798 + " reason=" + reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001799 }
Daniel Sandler7d276c32012-01-30 14:33:52 -05001800
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001801 if (noChangeLights) {
1802 newState = (newState & ~LIGHTS_MASK) | (mPowerState & LIGHTS_MASK);
1803 }
Mike Lockwood36fc3022009-08-25 16:49:06 -07001804 if (mProximitySensorActive) {
1805 // don't turn on the screen when the proximity sensor lock is held
1806 newState = (newState & ~SCREEN_BRIGHT);
1807 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001808
1809 if (batteryIsLow()) {
1810 newState |= BATTERY_LOW_BIT;
1811 } else {
1812 newState &= ~BATTERY_LOW_BIT;
1813 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001814 if (newState == mPowerState && mInitialized) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001815 return;
1816 }
Mike Lockwood3333fa42009-10-26 14:50:42 -04001817
Mike Lockwood2d7bb812009-11-15 18:12:22 -05001818 if (!mBootCompleted && !mUseSoftwareAutoBrightness) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001819 newState |= ALL_BRIGHT;
1820 }
1821
1822 boolean oldScreenOn = (mPowerState & SCREEN_ON_BIT) != 0;
1823 boolean newScreenOn = (newState & SCREEN_ON_BIT) != 0;
1824
Mike Lockwood51b844962009-11-16 21:51:18 -05001825 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001826 Slog.d(TAG, "setPowerState: mPowerState=" + mPowerState
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001827 + " newState=" + newState + " noChangeLights=" + noChangeLights);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001828 Slog.d(TAG, " oldKeyboardBright=" + ((mPowerState & KEYBOARD_BRIGHT_BIT) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001829 + " newKeyboardBright=" + ((newState & KEYBOARD_BRIGHT_BIT) != 0));
Joe Onorato8a9b2202010-02-26 18:56:32 -08001830 Slog.d(TAG, " oldScreenBright=" + ((mPowerState & SCREEN_BRIGHT_BIT) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001831 + " newScreenBright=" + ((newState & SCREEN_BRIGHT_BIT) != 0));
Joe Onorato8a9b2202010-02-26 18:56:32 -08001832 Slog.d(TAG, " oldButtonBright=" + ((mPowerState & BUTTON_BRIGHT_BIT) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001833 + " newButtonBright=" + ((newState & BUTTON_BRIGHT_BIT) != 0));
Joe Onorato8a9b2202010-02-26 18:56:32 -08001834 Slog.d(TAG, " oldScreenOn=" + oldScreenOn
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001835 + " newScreenOn=" + newScreenOn);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001836 Slog.d(TAG, " oldBatteryLow=" + ((mPowerState & BATTERY_LOW_BIT) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001837 + " newBatteryLow=" + ((newState & BATTERY_LOW_BIT) != 0));
1838 }
1839
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001840 final boolean stateChanged = mPowerState != newState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001841
Daniel Sandler7d276c32012-01-30 14:33:52 -05001842 if (stateChanged && reason == WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT) {
Daniel Sandler0af48952012-04-10 15:14:35 -04001843 if (mPolicy != null && mPolicy.isScreenSaverEnabled()) {
Daniel Sandler7d276c32012-01-30 14:33:52 -05001844 if (mSpew) {
1845 Slog.d(TAG, "setPowerState: running screen saver instead of turning off screen");
1846 }
1847 if (mPolicy.startScreenSaver()) {
1848 // was successful
1849 return;
1850 }
1851 }
1852 }
1853
1854
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001855 if (oldScreenOn != newScreenOn) {
1856 if (newScreenOn) {
Joe Onorato128e7292009-03-24 18:41:31 -07001857 // When the user presses the power button, we need to always send out the
1858 // notification that it's going to sleep so the keyguard goes on. But
1859 // we can't do that until the screen fades out, so we don't show the keyguard
1860 // too early.
1861 if (mStillNeedSleepNotification) {
1862 sendNotificationLocked(false, WindowManagerPolicy.OFF_BECAUSE_OF_USER);
1863 }
1864
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001865 // Turn on the screen UNLESS there was a prior
1866 // preventScreenOn(true) request. (Note that the lifetime
1867 // of a single preventScreenOn() request is limited to 5
1868 // seconds to prevent a buggy app from disabling the
1869 // screen forever; see forceReenableScreen().)
1870 boolean reallyTurnScreenOn = true;
1871 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001872 Slog.d(TAG, "- turning screen on... mPreventScreenOn = "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001873 + mPreventScreenOn);
1874 }
1875
1876 if (mPreventScreenOn) {
1877 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001878 Slog.d(TAG, "- PREVENTING screen from really turning on!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001879 }
1880 reallyTurnScreenOn = false;
1881 }
1882 if (reallyTurnScreenOn) {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001883 err = setScreenStateLocked(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001884 long identity = Binder.clearCallingIdentity();
1885 try {
Mike Lockwoodfb73f792009-11-20 11:31:18 -05001886 mBatteryStats.noteScreenBrightness(getPreferredBrightness());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001887 mBatteryStats.noteScreenOn();
1888 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001889 Slog.w(TAG, "RemoteException calling noteScreenOn on BatteryStatsService", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001890 } finally {
1891 Binder.restoreCallingIdentity(identity);
1892 }
1893 } else {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001894 setScreenStateLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001895 // But continue as if we really did turn the screen on...
1896 err = 0;
1897 }
1898
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001899 mLastTouchDown = 0;
1900 mTotalTouchDownTime = 0;
1901 mTouchCycles = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001902 EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, reason,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001903 mTotalTouchDownTime, mTouchCycles);
1904 if (err == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001905 sendNotificationLocked(true, -1);
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001906 // Update the lights *after* taking care of turning the
1907 // screen on, so we do this after our notifications are
1908 // enqueued and thus will delay turning on the screen light
1909 // until the windows are correctly displayed.
1910 if (stateChanged) {
1911 updateLightsLocked(newState, 0);
1912 }
1913 mPowerState |= SCREEN_ON_BIT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001914 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001915
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001916 } else {
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001917 // Update the lights *before* taking care of turning the
1918 // screen off, so we can initiate any animations that are desired.
Craig Mautner44bf70f2012-03-13 11:38:38 -07001919 mScreenOffReason = reason;
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001920 if (stateChanged) {
1921 updateLightsLocked(newState, 0);
1922 }
1923
Mike Lockwood497087e32009-11-08 18:33:03 -05001924 // cancel light sensor task
1925 mHandler.removeCallbacks(mAutoBrightnessTask);
Jim Rodovichd102fea2010-09-02 12:30:49 -05001926 mLightSensorPendingDecrease = false;
1927 mLightSensorPendingIncrease = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001928 mScreenOffTime = SystemClock.elapsedRealtime();
1929 long identity = Binder.clearCallingIdentity();
1930 try {
1931 mBatteryStats.noteScreenOff();
1932 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001933 Slog.w(TAG, "RemoteException calling noteScreenOff on BatteryStatsService", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001934 } finally {
1935 Binder.restoreCallingIdentity(identity);
1936 }
1937 mPowerState &= ~SCREEN_ON_BIT;
Jim Miller92e66dd2012-02-21 18:57:12 -08001938 if (!mScreenBrightnessAnimator.isAnimating()) {
Mike Lockwood435eb642009-12-03 08:40:18 -05001939 err = screenOffFinishedAnimatingLocked(reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001940 } else {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001941 err = 0;
1942 mLastTouchDown = 0;
1943 }
1944 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001945 } else if (stateChanged) {
1946 // Screen on/off didn't change, but lights may have.
1947 updateLightsLocked(newState, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001948 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001949
1950 mPowerState = (mPowerState & ~LIGHTS_MASK) | (newState & LIGHTS_MASK);
1951
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001952 updateNativePowerStateLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001953 }
1954 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001955
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001956 private void updateNativePowerStateLocked() {
Mike Lockwood3a74bd32011-08-12 13:55:22 -07001957 if (!mHeadless) {
1958 nativeSetPowerState(
1959 (mPowerState & SCREEN_ON_BIT) != 0,
1960 (mPowerState & SCREEN_BRIGHT) == SCREEN_BRIGHT);
1961 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001962 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001963
Mike Lockwood435eb642009-12-03 08:40:18 -05001964 private int screenOffFinishedAnimatingLocked(int reason) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001965 // I don't think we need to check the current state here because all of these
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001966 // Power.setScreenState and sendNotificationLocked can both handle being
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001967 // called multiple times in the same state. -joeo
Joe Onoratob08a1af2010-10-11 19:28:58 -07001968 EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, reason, mTotalTouchDownTime,
1969 mTouchCycles);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001970 mLastTouchDown = 0;
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001971 int err = setScreenStateLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001972 if (err == 0) {
Mike Lockwood435eb642009-12-03 08:40:18 -05001973 mScreenOffReason = reason;
1974 sendNotificationLocked(false, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001975 }
1976 return err;
1977 }
1978
1979 private boolean batteryIsLow() {
1980 return (!mIsPowered &&
Jeff Brown7304c342012-05-11 18:42:42 -07001981 mBatteryService.getBatteryLevel() <= LOW_BATTERY_THRESHOLD);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001982 }
1983
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001984 private boolean shouldDeferScreenOnLocked() {
1985 if (mPreparingForScreenOn) {
1986 // Currently waiting for confirmation from the policy that it
1987 // is okay to turn on the screen. Don't allow the screen to go
1988 // on until that is done.
1989 if (DEBUG_SCREEN_ON) Slog.i(TAG,
1990 "updateLights: delaying screen on due to mPreparingForScreenOn");
1991 return true;
1992 } else {
1993 // If there is a screen-on command in the notification queue, we
1994 // can't turn the screen on until it has been processed (and we
1995 // have set mPreparingForScreenOn) or it has been dropped.
1996 for (int i=0; i<mBroadcastQueue.length; i++) {
1997 if (mBroadcastQueue[i] == 1) {
1998 if (DEBUG_SCREEN_ON) Slog.i(TAG,
1999 "updateLights: delaying screen on due to notification queue");
2000 return true;
2001 }
2002 }
2003 }
2004 return false;
2005 }
2006
The Android Open Source Project10592532009-03-18 17:39:46 -07002007 private void updateLightsLocked(int newState, int forceState) {
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07002008 final int oldState = mPowerState;
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07002009
2010 // If the screen is not currently on, we will want to delay actually
2011 // turning the lights on if we are still getting the UI put up.
Jim Miller92e66dd2012-02-21 18:57:12 -08002012 if ((oldState & SCREEN_ON_BIT) == 0 || mSkippedScreenOn) {
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07002013 // Don't turn screen on until we know we are really ready to.
2014 // This is to avoid letting the screen go on before things like the
2015 // lock screen have been displayed.
Jim Miller92e66dd2012-02-21 18:57:12 -08002016 if ((mSkippedScreenOn = shouldDeferScreenOnLocked())) {
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07002017 newState &= ~(SCREEN_ON_BIT|SCREEN_BRIGHT_BIT);
2018 }
2019 }
2020
Joe Onorato60607a902010-10-23 14:49:30 -07002021 if ((newState & SCREEN_ON_BIT) != 0) {
2022 // Only turn on the buttons or keyboard if the screen is also on.
2023 // We should never see the buttons on but not the screen.
2024 newState = applyButtonState(newState);
2025 newState = applyKeyboardState(newState);
2026 }
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07002027 final int realDifference = (newState ^ oldState);
2028 final int difference = realDifference | forceState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002029 if (difference == 0) {
The Android Open Source Project10592532009-03-18 17:39:46 -07002030 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002031 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002032
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002033 int offMask = 0;
2034 int dimMask = 0;
2035 int onMask = 0;
2036
2037 int preferredBrightness = getPreferredBrightness();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002038
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002039 if ((difference & KEYBOARD_BRIGHT_BIT) != 0) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002040 if ((newState & KEYBOARD_BRIGHT_BIT) == 0) {
2041 offMask |= KEYBOARD_BRIGHT_BIT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002042 } else {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002043 onMask |= KEYBOARD_BRIGHT_BIT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002044 }
2045 }
2046
2047 if ((difference & BUTTON_BRIGHT_BIT) != 0) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002048 if ((newState & BUTTON_BRIGHT_BIT) == 0) {
2049 offMask |= BUTTON_BRIGHT_BIT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002050 } else {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002051 onMask |= BUTTON_BRIGHT_BIT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002052 }
2053 }
2054
2055 if ((difference & (SCREEN_ON_BIT | SCREEN_BRIGHT_BIT)) != 0) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002056 int nominalCurrentValue = -1;
2057 // If there was an actual difference in the light state, then
2058 // figure out the "ideal" current value based on the previous
2059 // state. Otherwise, this is a change due to the brightness
2060 // override, so we want to animate from whatever the current
2061 // value is.
2062 if ((realDifference & (SCREEN_ON_BIT | SCREEN_BRIGHT_BIT)) != 0) {
2063 switch (oldState & (SCREEN_BRIGHT_BIT|SCREEN_ON_BIT)) {
2064 case SCREEN_BRIGHT_BIT | SCREEN_ON_BIT:
2065 nominalCurrentValue = preferredBrightness;
2066 break;
2067 case SCREEN_ON_BIT:
Mike Lockwoodeb6456b2011-09-13 15:24:02 -04002068 nominalCurrentValue = mScreenBrightnessDim;
Joe Onoratob08a1af2010-10-11 19:28:58 -07002069 break;
2070 case 0:
Jeff Brown7304c342012-05-11 18:42:42 -07002071 nominalCurrentValue = PowerManager.BRIGHTNESS_OFF;
Joe Onoratob08a1af2010-10-11 19:28:58 -07002072 break;
2073 case SCREEN_BRIGHT_BIT:
2074 default:
2075 // not possible
Jim Miller92e66dd2012-02-21 18:57:12 -08002076 nominalCurrentValue = (int)mScreenBrightnessAnimator.getCurrentBrightness();
Joe Onoratob08a1af2010-10-11 19:28:58 -07002077 break;
Joe Onorato128e7292009-03-24 18:41:31 -07002078 }
Joe Onoratob08a1af2010-10-11 19:28:58 -07002079 }
2080 int brightness = preferredBrightness;
2081 int steps = ANIM_STEPS;
2082 if ((newState & SCREEN_BRIGHT_BIT) == 0) {
2083 // dim or turn off backlight, depending on if the screen is on
2084 // the scale is because the brightness ramp isn't linear and this biases
2085 // it so the later parts take longer.
2086 final float scale = 1.5f;
Mike Lockwoodeb6456b2011-09-13 15:24:02 -04002087 float ratio = (((float)mScreenBrightnessDim)/preferredBrightness);
Joe Onoratob08a1af2010-10-11 19:28:58 -07002088 if (ratio > 1.0f) ratio = 1.0f;
2089 if ((newState & SCREEN_ON_BIT) == 0) {
2090 if ((oldState & SCREEN_BRIGHT_BIT) != 0) {
2091 // was bright
2092 steps = ANIM_STEPS;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002093 } else {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002094 // was dim
2095 steps = (int)(ANIM_STEPS*ratio*scale);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002096 }
Jeff Brown7304c342012-05-11 18:42:42 -07002097 brightness = PowerManager.BRIGHTNESS_OFF;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002098 } else {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002099 if ((oldState & SCREEN_ON_BIT) != 0) {
2100 // was bright
2101 steps = (int)(ANIM_STEPS*(1.0f-ratio)*scale);
2102 } else {
2103 // was dim
2104 steps = (int)(ANIM_STEPS*ratio);
2105 }
Dianne Hackborn2fe8fb22012-06-15 17:05:25 -07002106 final int stayOnConditions = getStayOnConditionsLocked();
2107 if (stayOnConditions != 0 && mBatteryService.isPowered(stayOnConditions)) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002108 // If the "stay on while plugged in" option is
2109 // turned on, then the screen will often not
2110 // automatically turn off while plugged in. To
2111 // still have a sense of when it is inactive, we
2112 // will then count going dim as turning off.
2113 mScreenOffTime = SystemClock.elapsedRealtime();
2114 }
Mike Lockwoodeb6456b2011-09-13 15:24:02 -04002115 brightness = mScreenBrightnessDim;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002116 }
2117 }
Joe Onoratob08a1af2010-10-11 19:28:58 -07002118 long identity = Binder.clearCallingIdentity();
2119 try {
2120 mBatteryStats.noteScreenBrightness(brightness);
2121 } catch (RemoteException e) {
2122 // Nothing interesting to do.
2123 } finally {
2124 Binder.restoreCallingIdentity(identity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002125 }
Dianne Hackborn81de8b92011-11-28 16:54:31 -08002126 if (!mSkippedScreenOn) {
Jim Miller92e66dd2012-02-21 18:57:12 -08002127 int dt = steps * NOMINAL_FRAME_TIME_MS;
2128 mScreenBrightnessAnimator.animateTo(brightness, SCREEN_BRIGHT_BIT, dt);
Dianne Hackborn81de8b92011-11-28 16:54:31 -08002129 if (DEBUG_SCREEN_ON) {
2130 RuntimeException e = new RuntimeException("here");
2131 e.fillInStackTrace();
2132 Slog.i(TAG, "Setting screen brightness: " + brightness, e);
2133 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07002134 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002135 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002136
Joe Onorato60607a902010-10-23 14:49:30 -07002137 if (mSpew) {
2138 Slog.d(TAG, "offMask=0x" + Integer.toHexString(offMask)
2139 + " dimMask=0x" + Integer.toHexString(dimMask)
2140 + " onMask=0x" + Integer.toHexString(onMask)
2141 + " difference=0x" + Integer.toHexString(difference)
2142 + " realDifference=0x" + Integer.toHexString(realDifference)
2143 + " forceState=0x" + Integer.toHexString(forceState)
2144 );
2145 }
2146
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002147 if (offMask != 0) {
Mike Lockwood48358bd2010-04-17 22:29:20 -04002148 if (mSpew) Slog.i(TAG, "Setting brightess off: " + offMask);
Jeff Brown7304c342012-05-11 18:42:42 -07002149 setLightBrightness(offMask, PowerManager.BRIGHTNESS_OFF);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002150 }
2151 if (dimMask != 0) {
Mike Lockwoodeb6456b2011-09-13 15:24:02 -04002152 int brightness = mScreenBrightnessDim;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002153 if ((newState & BATTERY_LOW_BIT) != 0 &&
Jeff Brown7304c342012-05-11 18:42:42 -07002154 brightness > PowerManager.BRIGHTNESS_LOW_BATTERY) {
2155 brightness = PowerManager.BRIGHTNESS_LOW_BATTERY;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002156 }
Mike Lockwood48358bd2010-04-17 22:29:20 -04002157 if (mSpew) Slog.i(TAG, "Setting brightess dim " + brightness + ": " + dimMask);
The Android Open Source Project10592532009-03-18 17:39:46 -07002158 setLightBrightness(dimMask, brightness);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002159 }
2160 if (onMask != 0) {
2161 int brightness = getPreferredBrightness();
2162 if ((newState & BATTERY_LOW_BIT) != 0 &&
Jeff Brown7304c342012-05-11 18:42:42 -07002163 brightness > PowerManager.BRIGHTNESS_LOW_BATTERY) {
2164 brightness = PowerManager.BRIGHTNESS_LOW_BATTERY;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002165 }
Mike Lockwood48358bd2010-04-17 22:29:20 -04002166 if (mSpew) Slog.i(TAG, "Setting brightess on " + brightness + ": " + onMask);
The Android Open Source Project10592532009-03-18 17:39:46 -07002167 setLightBrightness(onMask, brightness);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002168 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002169 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002170
Jim Miller92e66dd2012-02-21 18:57:12 -08002171 /**
2172 * Note: by design this class does not hold mLocks while calling native methods.
2173 * Nor should it. Ever.
2174 */
2175 class ScreenBrightnessAnimator extends HandlerThread {
2176 static final int ANIMATE_LIGHTS = 10;
Jim Miller46f31c32012-03-01 14:36:07 -08002177 static final int ANIMATE_POWER_OFF = 11;
Jim Miller92e66dd2012-02-21 18:57:12 -08002178 volatile int startValue;
2179 volatile int endValue;
Craig Mautner196943f2012-05-15 08:10:35 -07002180 volatile int startSensorValue;
2181 volatile int endSensorValue;
Jim Miller92e66dd2012-02-21 18:57:12 -08002182 volatile int currentValue;
2183 private int currentMask;
2184 private int duration;
2185 private long startTimeMillis;
2186 private final String prefix;
2187
2188 public ScreenBrightnessAnimator(String name, int priority) {
2189 super(name, priority);
2190 prefix = name;
2191 }
2192
2193 @Override
2194 protected void onLooperPrepared() {
2195 mScreenBrightnessHandler = new Handler() {
2196 public void handleMessage(Message msg) {
2197 int brightnessMode = (mAutoBrightessEnabled && !mInitialAnimation
Mike Lockwood3a322132009-11-24 00:30:52 -05002198 ? LightsService.BRIGHTNESS_MODE_SENSOR
2199 : LightsService.BRIGHTNESS_MODE_USER);
Jim Miller92e66dd2012-02-21 18:57:12 -08002200 if (msg.what == ANIMATE_LIGHTS) {
2201 final int mask = msg.arg1;
2202 int value = msg.arg2;
2203 long tStart = SystemClock.uptimeMillis();
2204 if ((mask & SCREEN_BRIGHT_BIT) != 0) {
Craig Mautner196943f2012-05-15 08:10:35 -07002205 if (mDebugLightAnimation) Slog.v(TAG, "Set brightness: " + value);
Jim Miller92e66dd2012-02-21 18:57:12 -08002206 mLcdLight.setBrightness(value, brightnessMode);
2207 }
2208 long elapsed = SystemClock.uptimeMillis() - tStart;
2209 if ((mask & BUTTON_BRIGHT_BIT) != 0) {
2210 mButtonLight.setBrightness(value);
2211 }
2212 if ((mask & KEYBOARD_BRIGHT_BIT) != 0) {
2213 mKeyboardLight.setBrightness(value);
2214 }
2215
2216 if (elapsed > 100) {
Craig Mautner196943f2012-05-15 08:10:35 -07002217 Slog.e(TAG, "Excessive delay setting brightness: " + elapsed
Jim Miller92e66dd2012-02-21 18:57:12 -08002218 + "ms, mask=" + mask);
2219 }
2220
2221 // Throttle brightness updates to frame refresh rate
Craig Mautner196943f2012-05-15 08:10:35 -07002222 int delay = elapsed < NOMINAL_FRAME_TIME_MS ? NOMINAL_FRAME_TIME_MS : 1;
Jim Miller92e66dd2012-02-21 18:57:12 -08002223 synchronized(this) {
2224 currentValue = value;
2225 }
2226 animateInternal(mask, false, delay);
Jim Miller46f31c32012-03-01 14:36:07 -08002227 } else if (msg.what == ANIMATE_POWER_OFF) {
2228 int mode = msg.arg1;
2229 nativeStartSurfaceFlingerAnimation(mode);
Jim Miller92e66dd2012-02-21 18:57:12 -08002230 }
2231 }
2232 };
2233 synchronized (this) {
2234 mInitComplete = true;
2235 notifyAll();
Dianne Hackborn81de8b92011-11-28 16:54:31 -08002236 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002237 }
Jim Miller92e66dd2012-02-21 18:57:12 -08002238
2239 private void animateInternal(int mask, boolean turningOff, int delay) {
2240 synchronized (this) {
2241 if (currentValue != endValue) {
2242 final long now = SystemClock.elapsedRealtime();
2243 final int elapsed = (int) (now - startTimeMillis);
2244 int newValue;
2245 if (elapsed < duration) {
2246 int delta = endValue - startValue;
2247 newValue = startValue + delta * elapsed / duration;
Jeff Brown7304c342012-05-11 18:42:42 -07002248 newValue = Math.max(PowerManager.BRIGHTNESS_OFF, newValue);
2249 newValue = Math.min(PowerManager.BRIGHTNESS_ON, newValue);
Craig Mautner196943f2012-05-15 08:10:35 -07002250 // Optimization to delay next step until a change will occur.
2251 if (delay > 0 && newValue == currentValue) {
2252 final int timePerStep = duration / Math.abs(delta);
2253 delay = Math.min(duration - elapsed, timePerStep);
2254 newValue += delta < 0 ? -1 : 1;
2255 }
2256 // adjust the peak sensor value until we get to the target sensor value
2257 delta = endSensorValue - startSensorValue;
2258 mHighestLightSensorValue = startSensorValue + delta * elapsed / duration;
Jim Miller92e66dd2012-02-21 18:57:12 -08002259 } else {
2260 newValue = endValue;
Craig Mautner196943f2012-05-15 08:10:35 -07002261 mHighestLightSensorValue = endSensorValue;
Craig Mautneraf01fe02012-05-31 10:03:32 -07002262 if (endValue > 0) {
2263 mInitialAnimation = false;
2264 }
Jim Miller92e66dd2012-02-21 18:57:12 -08002265 }
2266
2267 if (mDebugLightAnimation) {
Craig Mautner196943f2012-05-15 08:10:35 -07002268 Slog.v(TAG, "Animating light: " + "start:" + startValue
Jim Miller92e66dd2012-02-21 18:57:12 -08002269 + ", end:" + endValue + ", elapsed:" + elapsed
2270 + ", duration:" + duration + ", current:" + currentValue
Craig Mautner196943f2012-05-15 08:10:35 -07002271 + ", newValue:" + newValue
2272 + ", delay:" + delay
2273 + ", highestSensor:" + mHighestLightSensorValue);
Jim Miller92e66dd2012-02-21 18:57:12 -08002274 }
2275
Jim Miller46f31c32012-03-01 14:36:07 -08002276 if (turningOff && !mHeadless && !mAnimateScreenLights) {
Jim Miller92e66dd2012-02-21 18:57:12 -08002277 int mode = mScreenOffReason == OFF_BECAUSE_OF_PROX_SENSOR
2278 ? 0 : mAnimationSetting;
Craig Mautner196943f2012-05-15 08:10:35 -07002279 if (mDebugLightAnimation) {
2280 Slog.v(TAG, "Doing power-off anim, mode=" + mode);
2281 }
Jim Miller46f31c32012-03-01 14:36:07 -08002282 mScreenBrightnessHandler.obtainMessage(ANIMATE_POWER_OFF, mode, 0)
2283 .sendToTarget();
Jim Miller92e66dd2012-02-21 18:57:12 -08002284 }
Craig Mautner196943f2012-05-15 08:10:35 -07002285 mScreenBrightnessHandler.removeMessages(
2286 ScreenBrightnessAnimator.ANIMATE_LIGHTS);
Jim Miller92e66dd2012-02-21 18:57:12 -08002287 Message msg = mScreenBrightnessHandler
2288 .obtainMessage(ANIMATE_LIGHTS, mask, newValue);
2289 mScreenBrightnessHandler.sendMessageDelayed(msg, delay);
2290 }
2291 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002292 }
Jim Miller92e66dd2012-02-21 18:57:12 -08002293
2294 public void dump(PrintWriter pw, String string) {
Craig Mautner291576e2012-06-07 19:58:58 -07002295 pw.println(string);
2296 pw.println(" animating: " + "start:" + startValue + ", end:" + endValue
Jim Miller92e66dd2012-02-21 18:57:12 -08002297 + ", duration:" + duration + ", current:" + currentValue);
Craig Mautner291576e2012-06-07 19:58:58 -07002298 pw.println(" startSensorValue:" + startSensorValue
2299 + " endSensorValue:" + endSensorValue);
2300 pw.println(" startSensorValue:" + startSensorValue
2301 + " endSensorValue:" + endSensorValue);
Jim Miller92e66dd2012-02-21 18:57:12 -08002302 }
2303
2304 public void animateTo(int target, int mask, int animationDuration) {
Craig Mautner196943f2012-05-15 08:10:35 -07002305 animateTo(target, mHighestLightSensorValue, mask, animationDuration);
2306 }
2307
2308 public void animateTo(int target, int sensorTarget, int mask, int animationDuration) {
Jim Miller92e66dd2012-02-21 18:57:12 -08002309 synchronized(this) {
Craig Mautner291576e2012-06-07 19:58:58 -07002310 if ((mask & SCREEN_BRIGHT_BIT) == 0) {
2311 // We only animate keyboard and button when passed in with SCREEN_BRIGHT_BIT.
2312 if ((mask & BUTTON_BRIGHT_BIT) != 0) {
2313 mButtonLight.setBrightness(target);
2314 }
2315 if ((mask & KEYBOARD_BRIGHT_BIT) != 0) {
2316 mKeyboardLight.setBrightness(target);
2317 }
2318 return;
2319 }
Craig Mautnerd29568c2012-06-01 16:02:47 -07002320 if (isAnimating() && (mask ^ currentMask) != 0) {
2321 // current animation is unrelated to new animation, jump to final values
2322 cancelAnimation();
2323 }
Jim Miller92e66dd2012-02-21 18:57:12 -08002324 startValue = currentValue;
2325 endValue = target;
Craig Mautner196943f2012-05-15 08:10:35 -07002326 startSensorValue = mHighestLightSensorValue;
2327 endSensorValue = sensorTarget;
Jim Miller92e66dd2012-02-21 18:57:12 -08002328 currentMask = mask;
2329 duration = (int) (mWindowScaleAnimation * animationDuration);
2330 startTimeMillis = SystemClock.elapsedRealtime();
Craig Mautneraf01fe02012-05-31 10:03:32 -07002331 mInitialAnimation = mInitialAnimation && target > 0;
Jim Miller92e66dd2012-02-21 18:57:12 -08002332
2333 if (mDebugLightAnimation) {
Craig Mautner196943f2012-05-15 08:10:35 -07002334 Slog.v(TAG, "animateTo(target=" + target
2335 + ", sensor=" + sensorTarget
2336 + ", mask=" + mask
Jim Miller92e66dd2012-02-21 18:57:12 -08002337 + ", duration=" + animationDuration +")"
2338 + ", currentValue=" + currentValue
2339 + ", startTime=" + startTimeMillis);
2340 }
2341
2342 if (target != currentValue) {
Jim Miller18651802012-03-07 14:19:56 -08002343 final boolean doScreenAnim = (mask & (SCREEN_BRIGHT_BIT | SCREEN_ON_BIT)) != 0;
Jeff Brown7304c342012-05-11 18:42:42 -07002344 final boolean turningOff = endValue == PowerManager.BRIGHTNESS_OFF;
Jim Miller18651802012-03-07 14:19:56 -08002345 if (turningOff && doScreenAnim) {
Jim Miller92e66dd2012-02-21 18:57:12 -08002346 // Cancel all pending animations since we're turning off
2347 mScreenBrightnessHandler.removeCallbacksAndMessages(null);
2348 screenOffFinishedAnimatingLocked(mScreenOffReason);
2349 duration = 200; // TODO: how long should this be?
2350 }
Jim Miller18651802012-03-07 14:19:56 -08002351 if (doScreenAnim) {
2352 animateInternal(mask, turningOff, 0);
2353 }
2354 // TODO: Handle keyboard light animation when we have devices that support it
Jim Miller92e66dd2012-02-21 18:57:12 -08002355 }
2356 }
2357 }
2358
2359 public int getCurrentBrightness() {
2360 synchronized (this) {
2361 return currentValue;
2362 }
2363 }
2364
2365 public boolean isAnimating() {
2366 synchronized (this) {
2367 return currentValue != endValue;
2368 }
2369 }
2370
2371 public void cancelAnimation() {
2372 animateTo(endValue, currentMask, 0);
The Android Open Source Project10592532009-03-18 17:39:46 -07002373 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002374 }
2375
Jim Miller92e66dd2012-02-21 18:57:12 -08002376 private void setLightBrightness(int mask, int value) {
2377 mScreenBrightnessAnimator.animateTo(value, mask, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002378 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002379
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002380 private int getPreferredBrightness() {
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002381 if (mScreenBrightnessOverride >= 0) {
2382 return mScreenBrightnessOverride;
2383 } else if (mLightSensorScreenBrightness >= 0 && mUseSoftwareAutoBrightness
2384 && mAutoBrightessEnabled) {
2385 return mLightSensorScreenBrightness;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002386 }
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002387 final int brightness = mScreenBrightnessSetting;
2388 // Don't let applications turn the screen all the way off
2389 return Math.max(brightness, mScreenBrightnessDim);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002390 }
2391
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002392 private int applyButtonState(int state) {
2393 int brightness = -1;
Mike Lockwood48358bd2010-04-17 22:29:20 -04002394 if ((state & BATTERY_LOW_BIT) != 0) {
2395 // do not override brightness if the battery is low
2396 return state;
2397 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002398 if (mButtonBrightnessOverride >= 0) {
2399 brightness = mButtonBrightnessOverride;
2400 } else if (mLightSensorButtonBrightness >= 0 && mUseSoftwareAutoBrightness) {
2401 brightness = mLightSensorButtonBrightness;
2402 }
2403 if (brightness > 0) {
2404 return state | BUTTON_BRIGHT_BIT;
2405 } else if (brightness == 0) {
2406 return state & ~BUTTON_BRIGHT_BIT;
2407 } else {
2408 return state;
2409 }
2410 }
2411
2412 private int applyKeyboardState(int state) {
2413 int brightness = -1;
Mike Lockwood48358bd2010-04-17 22:29:20 -04002414 if ((state & BATTERY_LOW_BIT) != 0) {
2415 // do not override brightness if the battery is low
2416 return state;
2417 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002418 if (!mKeyboardVisible) {
2419 brightness = 0;
2420 } else if (mButtonBrightnessOverride >= 0) {
2421 brightness = mButtonBrightnessOverride;
2422 } else if (mLightSensorKeyboardBrightness >= 0 && mUseSoftwareAutoBrightness) {
2423 brightness = mLightSensorKeyboardBrightness;
2424 }
2425 if (brightness > 0) {
2426 return state | KEYBOARD_BRIGHT_BIT;
2427 } else if (brightness == 0) {
2428 return state & ~KEYBOARD_BRIGHT_BIT;
2429 } else {
2430 return state;
2431 }
2432 }
2433
Charles Mendis322591c2009-10-29 11:06:59 -07002434 public boolean isScreenOn() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002435 synchronized (mLocks) {
2436 return (mPowerState & SCREEN_ON_BIT) != 0;
2437 }
2438 }
2439
Charles Mendis322591c2009-10-29 11:06:59 -07002440 boolean isScreenBright() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002441 synchronized (mLocks) {
2442 return (mPowerState & SCREEN_BRIGHT) == SCREEN_BRIGHT;
2443 }
2444 }
2445
Mike Lockwood497087e32009-11-08 18:33:03 -05002446 private boolean isScreenTurningOffLocked() {
Jim Miller92e66dd2012-02-21 18:57:12 -08002447 return (mScreenBrightnessAnimator.isAnimating()
Craig Mautnerd29568c2012-06-01 16:02:47 -07002448 && mScreenBrightnessAnimator.endValue == PowerManager.BRIGHTNESS_OFF
2449 && (mScreenBrightnessAnimator.currentMask & SCREEN_BRIGHT_BIT) != 0);
Mike Lockwood497087e32009-11-08 18:33:03 -05002450 }
2451
Joe Onorato4b9f62d2010-10-11 13:41:35 -07002452 private boolean shouldLog(long time) {
2453 synchronized (mLocks) {
2454 if (time > (mWarningSpewThrottleTime + (60*60*1000))) {
2455 mWarningSpewThrottleTime = time;
2456 mWarningSpewThrottleCount = 0;
2457 return true;
2458 } else if (mWarningSpewThrottleCount < 30) {
2459 mWarningSpewThrottleCount++;
2460 return true;
2461 } else {
2462 return false;
2463 }
2464 }
2465 }
2466
Mike Lockwood200b30b2009-09-20 00:23:59 -04002467 private void forceUserActivityLocked() {
Mike Lockwoode090281422009-11-14 21:02:56 -05002468 if (isScreenTurningOffLocked()) {
2469 // cancel animation so userActivity will succeed
Jim Miller92e66dd2012-02-21 18:57:12 -08002470 mScreenBrightnessAnimator.cancelAnimation();
Mike Lockwoode090281422009-11-14 21:02:56 -05002471 }
Mike Lockwood200b30b2009-09-20 00:23:59 -04002472 boolean savedActivityAllowed = mUserActivityAllowed;
2473 mUserActivityAllowed = true;
2474 userActivity(SystemClock.uptimeMillis(), false);
2475 mUserActivityAllowed = savedActivityAllowed;
2476 }
2477
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002478 public void userActivityWithForce(long time, boolean noChangeLights, boolean force) {
2479 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
Joe Onorato7999bff2010-07-24 11:50:05 -04002480 userActivity(time, -1, noChangeLights, OTHER_EVENT, force);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002481 }
2482
2483 public void userActivity(long time, boolean noChangeLights) {
Joe Onorato4b9f62d2010-10-11 13:41:35 -07002484 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER)
2485 != PackageManager.PERMISSION_GRANTED) {
2486 if (shouldLog(time)) {
2487 Slog.w(TAG, "Caller does not have DEVICE_POWER permission. pid="
2488 + Binder.getCallingPid() + " uid=" + Binder.getCallingUid());
2489 }
2490 return;
2491 }
2492
Joe Onorato7999bff2010-07-24 11:50:05 -04002493 userActivity(time, -1, noChangeLights, OTHER_EVENT, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002494 }
2495
2496 public void userActivity(long time, boolean noChangeLights, int eventType) {
Joe Onorato7999bff2010-07-24 11:50:05 -04002497 userActivity(time, -1, noChangeLights, eventType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002498 }
2499
2500 public void userActivity(long time, boolean noChangeLights, int eventType, boolean force) {
Joe Onorato7999bff2010-07-24 11:50:05 -04002501 userActivity(time, -1, noChangeLights, eventType, force);
2502 }
2503
2504 /*
2505 * Reset the user activity timeout to now + timeout. This overrides whatever else is going
2506 * on with user activity. Don't use this function.
2507 */
2508 public void clearUserActivityTimeout(long now, long timeout) {
2509 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
2510 Slog.i(TAG, "clearUserActivity for " + timeout + "ms from now");
2511 userActivity(now, timeout, false, OTHER_EVENT, false);
2512 }
2513
2514 private void userActivity(long time, long timeoutOverride, boolean noChangeLights,
2515 int eventType, boolean force) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002516
Joe Onorato1a542c72010-11-08 09:48:20 -08002517 if (((mPokey & POKE_LOCK_IGNORE_TOUCH_EVENTS) != 0) && (eventType == TOUCH_EVENT)) {
Joe Onoratoe68ffcb2009-03-24 19:11:13 -07002518 if (false) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002519 Slog.d(TAG, "dropping touch mPokey=0x" + Integer.toHexString(mPokey));
Joe Onoratoe68ffcb2009-03-24 19:11:13 -07002520 }
2521 return;
2522 }
2523
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002524 synchronized (mLocks) {
2525 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002526 Slog.d(TAG, "userActivity mLastEventTime=" + mLastEventTime + " time=" + time
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002527 + " mUserActivityAllowed=" + mUserActivityAllowed
2528 + " mUserState=0x" + Integer.toHexString(mUserState)
Mike Lockwood36fc3022009-08-25 16:49:06 -07002529 + " mWakeLockState=0x" + Integer.toHexString(mWakeLockState)
2530 + " mProximitySensorActive=" + mProximitySensorActive
Joe Onorato797e6882010-08-26 14:46:01 -04002531 + " timeoutOverride=" + timeoutOverride
Mike Lockwood36fc3022009-08-25 16:49:06 -07002532 + " force=" + force);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002533 }
Mike Lockwood05067122009-10-27 23:07:25 -04002534 // ignore user activity if we are in the process of turning off the screen
Mike Lockwood497087e32009-11-08 18:33:03 -05002535 if (isScreenTurningOffLocked()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002536 Slog.d(TAG, "ignoring user activity while turning off screen");
Mike Lockwood05067122009-10-27 23:07:25 -04002537 return;
2538 }
Mike Lockwood0e39ea82009-11-18 15:37:10 -05002539 // Disable proximity sensor if if user presses power key while we are in the
2540 // "waiting for proximity sensor to go negative" state.
2541 if (mProximitySensorActive && mProximityWakeLockCount == 0) {
2542 mProximitySensorActive = false;
2543 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002544 if (mLastEventTime <= time || force) {
2545 mLastEventTime = time;
Mike Lockwood36fc3022009-08-25 16:49:06 -07002546 if ((mUserActivityAllowed && !mProximitySensorActive) || force) {
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002547 // Only turn on button backlights if a button was pressed
2548 // and auto brightness is disabled
Mike Lockwood4984e732009-11-01 08:16:33 -05002549 if (eventType == BUTTON_EVENT && !mUseSoftwareAutoBrightness) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002550 mUserState = (mKeyboardVisible ? ALL_BRIGHT : SCREEN_BUTTON_BRIGHT);
2551 } else {
2552 // don't clear button/keyboard backlights when the screen is touched.
2553 mUserState |= SCREEN_BRIGHT;
2554 }
2555
Dianne Hackborn617f8772009-03-31 15:04:46 -07002556 int uid = Binder.getCallingUid();
2557 long ident = Binder.clearCallingIdentity();
2558 try {
2559 mBatteryStats.noteUserActivity(uid, eventType);
2560 } catch (RemoteException e) {
2561 // Ignore
2562 } finally {
2563 Binder.restoreCallingIdentity(ident);
2564 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002565
Michael Chane96440f2009-05-06 10:27:36 -07002566 mWakeLockState = mLocks.reactivateScreenLocksLocked();
Mike Lockwood435eb642009-12-03 08:40:18 -05002567 setPowerState(mUserState | mWakeLockState, noChangeLights,
2568 WindowManagerPolicy.OFF_BECAUSE_OF_USER);
Joe Onorato7999bff2010-07-24 11:50:05 -04002569 setTimeoutLocked(time, timeoutOverride, SCREEN_BRIGHT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002570 }
2571 }
2572 }
Mike Lockwoodef731622010-01-27 17:51:34 -05002573
2574 if (mPolicy != null) {
2575 mPolicy.userActivity();
2576 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002577 }
2578
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002579 private int getAutoBrightnessValue(int sensorValue, int[] values) {
2580 try {
2581 int i;
2582 for (i = 0; i < mAutoBrightnessLevels.length; i++) {
2583 if (sensorValue < mAutoBrightnessLevels[i]) {
2584 break;
2585 }
2586 }
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002587 // This is the range of brightness values that we can use.
2588 final int minval = values[0];
2589 final int maxval = values[mAutoBrightnessLevels.length];
2590 // This is the range we will be scaling. We put some padding
2591 // at the low and high end to give the adjustment a little better
2592 // impact on the actual observed value.
2593 final int range = (maxval-minval) + LIGHT_SENSOR_RANGE_EXPANSION;
2594 // This is the desired brightness value from 0.0 to 1.0.
2595 float valf = ((values[i]-minval+(LIGHT_SENSOR_RANGE_EXPANSION/2))/(float)range);
2596 // Apply a scaling to the value based on the adjustment.
2597 if (mLightSensorAdjustSetting > 0 && mLightSensorAdjustSetting <= 1) {
2598 float adj = (float)Math.sqrt(1.0f-mLightSensorAdjustSetting);
2599 if (adj <= .00001) {
2600 valf = 1;
2601 } else {
2602 valf /= adj;
2603 }
2604 } else if (mLightSensorAdjustSetting < 0 && mLightSensorAdjustSetting >= -1) {
2605 float adj = (float)Math.sqrt(1.0f+mLightSensorAdjustSetting);
2606 valf *= adj;
2607 }
2608 // Apply an additional offset to the value based on the adjustment.
2609 valf += mLightSensorAdjustSetting/LIGHT_SENSOR_OFFSET_SCALE;
2610 // Convert the 0.0-1.0 value back to a brightness integer.
2611 int val = (int)((valf*range)+minval) - (LIGHT_SENSOR_RANGE_EXPANSION/2);
2612 if (val < minval) val = minval;
2613 else if (val > maxval) val = maxval;
2614 return val;
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002615 } catch (Exception e) {
2616 // guard against null pointer or index out of bounds errors
Jeff Browndaa37532012-05-01 15:54:03 -07002617 Slog.e(TAG, "Values array must be non-empty and must be one element longer than "
2618 + "the auto-brightness levels array. Check config.xml.", e);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002619 return 255;
2620 }
2621 }
2622
Mike Lockwood20f87d72009-11-05 16:08:51 -05002623 private Runnable mProximityTask = new Runnable() {
2624 public void run() {
2625 synchronized (mLocks) {
2626 if (mProximityPendingValue != -1) {
2627 proximityChangedLocked(mProximityPendingValue == 1);
2628 mProximityPendingValue = -1;
2629 }
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -05002630 if (mProximityPartialLock.isHeld()) {
2631 mProximityPartialLock.release();
2632 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05002633 }
2634 }
2635 };
2636
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002637 private Runnable mAutoBrightnessTask = new Runnable() {
2638 public void run() {
Mike Lockwoodfa68ab42009-10-20 11:08:49 -04002639 synchronized (mLocks) {
Jim Rodovichd102fea2010-09-02 12:30:49 -05002640 if (mLightSensorPendingDecrease || mLightSensorPendingIncrease) {
2641 int value = (int)mLightSensorPendingValue;
2642 mLightSensorPendingDecrease = false;
2643 mLightSensorPendingIncrease = false;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002644 lightSensorChangedLocked(value, false);
Mike Lockwoodfa68ab42009-10-20 11:08:49 -04002645 }
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002646 }
2647 }
2648 };
2649
Craig Mautneraf01fe02012-05-31 10:03:32 -07002650 /** used to prevent lightsensor changes while turning on. */
2651 private boolean mInitialAnimation = true;
Jim Miller92e66dd2012-02-21 18:57:12 -08002652
Mike Lockwoodb2865412010-02-02 22:40:33 -05002653 private void dockStateChanged(int state) {
2654 synchronized (mLocks) {
2655 mIsDocked = (state != Intent.EXTRA_DOCK_STATE_UNDOCKED);
2656 if (mIsDocked) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04002657 // allow brightness to decrease when docked
Mike Lockwoodb2865412010-02-02 22:40:33 -05002658 mHighestLightSensorValue = -1;
2659 }
2660 if ((mPowerState & SCREEN_ON_BIT) != 0) {
2661 // force lights recalculation
2662 int value = (int)mLightSensorValue;
2663 mLightSensorValue = -1;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002664 lightSensorChangedLocked(value, false);
Mike Lockwoodb2865412010-02-02 22:40:33 -05002665 }
2666 }
2667 }
2668
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002669 private void lightSensorChangedLocked(int value, boolean immediate) {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002670 if (mDebugLightSensor) {
Craig Mautner37933682012-06-06 14:13:39 -07002671 Slog.d(TAG, "lightSensorChangedLocked value=" + value + " immediate=" + immediate);
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002672 }
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002673
Joe Onorato06eb33a2010-10-25 14:09:21 -07002674 // Don't do anything if the screen is off.
2675 if ((mPowerState & SCREEN_ON_BIT) == 0) {
2676 if (mDebugLightSensor) {
2677 Slog.d(TAG, "dropping lightSensorChangedLocked because screen is off");
2678 }
2679 return;
2680 }
2681
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002682 if (mLightSensorValue != value) {
2683 mLightSensorValue = value;
2684 if ((mPowerState & BATTERY_LOW_BIT) == 0) {
Mike Lockwoodb2865412010-02-02 22:40:33 -05002685 // use maximum light sensor value seen since screen went on for LCD to avoid flicker
2686 // we only do this if we are undocked, since lighting should be stable when
2687 // stationary in a dock.
Craig Mautner196943f2012-05-15 08:10:35 -07002688 int lcdValue = getAutoBrightnessValue(value, mLcdBacklightValues);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002689 int buttonValue = getAutoBrightnessValue(value, mButtonBacklightValues);
Mike Lockwooddf024922009-10-29 21:29:15 -04002690 int keyboardValue;
2691 if (mKeyboardVisible) {
2692 keyboardValue = getAutoBrightnessValue(value, mKeyboardBacklightValues);
2693 } else {
2694 keyboardValue = 0;
2695 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002696 mLightSensorScreenBrightness = lcdValue;
2697 mLightSensorButtonBrightness = buttonValue;
2698 mLightSensorKeyboardBrightness = keyboardValue;
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002699
2700 if (mDebugLightSensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002701 Slog.d(TAG, "lcdValue " + lcdValue);
2702 Slog.d(TAG, "buttonValue " + buttonValue);
2703 Slog.d(TAG, "keyboardValue " + keyboardValue);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002704 }
2705
Mike Lockwood4984e732009-11-01 08:16:33 -05002706 if (mAutoBrightessEnabled && mScreenBrightnessOverride < 0) {
Jim Miller92e66dd2012-02-21 18:57:12 -08002707 if (!mSkippedScreenOn && !mInitialAnimation) {
Craig Mautner291576e2012-06-07 19:58:58 -07002708 final int steps;
2709 if (immediate) {
2710 steps = IMMEDIATE_ANIM_STEPS;
2711 } else {
2712 synchronized (mScreenBrightnessAnimator) {
2713 if (mScreenBrightnessAnimator.currentValue <= lcdValue) {
2714 steps = AUTOBRIGHTNESS_ANIM_STEPS;
2715 } else {
2716 steps = AUTODIMNESS_ANIM_STEPS;
2717 }
2718 }
2719 }
Craig Mautner196943f2012-05-15 08:10:35 -07002720 mScreenBrightnessAnimator.animateTo(lcdValue, value,
Jim Miller92e66dd2012-02-21 18:57:12 -08002721 SCREEN_BRIGHT_BIT, steps * NOMINAL_FRAME_TIME_MS);
Dianne Hackborn81de8b92011-11-28 16:54:31 -08002722 }
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002723 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002724 if (mButtonBrightnessOverride < 0) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002725 mButtonLight.setBrightness(buttonValue);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002726 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002727 if (mButtonBrightnessOverride < 0 || !mKeyboardVisible) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002728 mKeyboardLight.setBrightness(keyboardValue);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002729 }
2730 }
2731 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002732 }
2733
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002734 /**
2735 * The user requested that we go to sleep (probably with the power button).
2736 * This overrides all wake locks that are held.
2737 */
2738 public void goToSleep(long time)
2739 {
Dianne Hackborn254cb442010-01-27 19:23:59 -08002740 goToSleepWithReason(time, WindowManagerPolicy.OFF_BECAUSE_OF_USER);
2741 }
2742
2743 /**
2744 * The user requested that we go to sleep (probably with the power button).
2745 * This overrides all wake locks that are held.
2746 */
2747 public void goToSleepWithReason(long time, int reason)
2748 {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002749 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
2750 synchronized (mLocks) {
Dianne Hackborn254cb442010-01-27 19:23:59 -08002751 goToSleepLocked(time, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002752 }
2753 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002754
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002755 /**
Doug Zongker50a21f42009-11-19 12:49:53 -08002756 * Reboot the device immediately, passing 'reason' (may be null)
2757 * to the underlying __reboot system call. Should not return.
2758 */
2759 public void reboot(String reason)
2760 {
2761 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
San Mehat14e69af2010-01-06 14:58:18 -08002762
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002763 if (mHandler == null || !ActivityManagerNative.isSystemReady()) {
2764 throw new IllegalStateException("Too early to call reboot()");
2765 }
Mike Lockwoodb62f9592010-03-12 07:55:23 -05002766
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002767 final String finalReason = reason;
2768 Runnable runnable = new Runnable() {
2769 public void run() {
2770 synchronized (this) {
2771 ShutdownThread.reboot(mContext, finalReason, false);
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002772 }
Jim Miller92e66dd2012-02-21 18:57:12 -08002773
San Mehat1e512792010-01-07 10:40:29 -08002774 }
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002775 };
Mike Lockwoodb62f9592010-03-12 07:55:23 -05002776 // ShutdownThread must run on a looper capable of displaying the UI.
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002777 mHandler.post(runnable);
2778
Mike Lockwoodb62f9592010-03-12 07:55:23 -05002779 // PowerManager.reboot() is documented not to return so just wait for the inevitable.
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002780 synchronized (runnable) {
Mike Lockwoodb62f9592010-03-12 07:55:23 -05002781 while (true) {
2782 try {
2783 runnable.wait();
2784 } catch (InterruptedException e) {
2785 }
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002786 }
Doug Zongker50a21f42009-11-19 12:49:53 -08002787 }
2788 }
2789
Dan Egnor60d87622009-12-16 16:32:58 -08002790 /**
2791 * Crash the runtime (causing a complete restart of the Android framework).
2792 * Requires REBOOT permission. Mostly for testing. Should not return.
2793 */
2794 public void crash(final String message)
2795 {
2796 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
2797 Thread t = new Thread("PowerManagerService.crash()") {
2798 public void run() { throw new RuntimeException(message); }
2799 };
2800 try {
2801 t.start();
2802 t.join();
2803 } catch (InterruptedException e) {
2804 Log.wtf(TAG, e);
2805 }
2806 }
2807
Mike Lockwood435eb642009-12-03 08:40:18 -05002808 private void goToSleepLocked(long time, int reason) {
Jeff Browna75fe052012-05-01 18:41:26 -07002809 if (mSpew) {
2810 Exception ex = new Exception();
2811 ex.fillInStackTrace();
2812 Slog.d(TAG, "goToSleep mLastEventTime=" + mLastEventTime + " time=" + time
2813 + " reason=" + reason, ex);
2814 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002815
2816 if (mLastEventTime <= time) {
2817 mLastEventTime = time;
2818 // cancel all of the wake locks
2819 mWakeLockState = SCREEN_OFF;
2820 int N = mLocks.size();
2821 int numCleared = 0;
Joe Onorato8274a0e2010-10-05 17:38:09 -04002822 boolean proxLock = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002823 for (int i=0; i<N; i++) {
2824 WakeLock wl = mLocks.get(i);
2825 if (isScreenLock(wl.flags)) {
Joe Onorato8274a0e2010-10-05 17:38:09 -04002826 if (((wl.flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)
2827 && reason == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR) {
2828 proxLock = true;
2829 } else {
2830 mLocks.get(i).activated = false;
2831 numCleared++;
2832 }
2833 }
2834 }
2835 if (!proxLock) {
2836 mProxIgnoredBecauseScreenTurnedOff = true;
2837 if (mDebugProximitySensor) {
2838 Slog.d(TAG, "setting mProxIgnoredBecauseScreenTurnedOff");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002839 }
2840 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002841 EventLog.writeEvent(EventLogTags.POWER_SLEEP_REQUESTED, numCleared);
Joe Onorato128e7292009-03-24 18:41:31 -07002842 mStillNeedSleepNotification = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002843 mUserState = SCREEN_OFF;
Mike Lockwood435eb642009-12-03 08:40:18 -05002844 setPowerState(SCREEN_OFF, false, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002845 cancelTimerLocked();
2846 }
2847 }
2848
2849 public long timeSinceScreenOn() {
2850 synchronized (mLocks) {
2851 if ((mPowerState & SCREEN_ON_BIT) != 0) {
2852 return 0;
2853 }
2854 return SystemClock.elapsedRealtime() - mScreenOffTime;
2855 }
2856 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002857
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002858 public void setKeyboardVisibility(boolean visible) {
Mike Lockwooda625b382009-09-12 17:36:03 -07002859 synchronized (mLocks) {
2860 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002861 Slog.d(TAG, "setKeyboardVisibility: " + visible);
Mike Lockwooda625b382009-09-12 17:36:03 -07002862 }
Mike Lockwood3c9435a2009-10-22 15:45:37 -04002863 if (mKeyboardVisible != visible) {
2864 mKeyboardVisible = visible;
2865 // don't signal user activity if the screen is off; other code
2866 // will take care of turning on due to a true change to the lid
2867 // switch and synchronized with the lock screen.
2868 if ((mPowerState & SCREEN_ON_BIT) != 0) {
Mike Lockwood4984e732009-11-01 08:16:33 -05002869 if (mUseSoftwareAutoBrightness) {
Mike Lockwooddf024922009-10-29 21:29:15 -04002870 // force recompute of backlight values
2871 if (mLightSensorValue >= 0) {
2872 int value = (int)mLightSensorValue;
2873 mLightSensorValue = -1;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002874 lightSensorChangedLocked(value, false);
Mike Lockwooddf024922009-10-29 21:29:15 -04002875 }
2876 }
Mike Lockwood3c9435a2009-10-22 15:45:37 -04002877 userActivity(SystemClock.uptimeMillis(), false, BUTTON_EVENT, true);
2878 }
Mike Lockwooda625b382009-09-12 17:36:03 -07002879 }
2880 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002881 }
2882
2883 /**
2884 * When the keyguard is up, it manages the power state, and userActivity doesn't do anything.
Mike Lockwood50c548d2009-11-09 16:02:06 -05002885 * When disabling user activity we also reset user power state so the keyguard can reset its
2886 * short screen timeout when keyguard is unhidden.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002887 */
2888 public void enableUserActivity(boolean enabled) {
Mike Lockwood50c548d2009-11-09 16:02:06 -05002889 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002890 Slog.d(TAG, "enableUserActivity " + enabled);
Mike Lockwood50c548d2009-11-09 16:02:06 -05002891 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002892 synchronized (mLocks) {
2893 mUserActivityAllowed = enabled;
Mike Lockwood50c548d2009-11-09 16:02:06 -05002894 if (!enabled) {
2895 // cancel timeout and clear mUserState so the keyguard can set a short timeout
2896 setTimeoutLocked(SystemClock.uptimeMillis(), 0);
2897 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002898 }
2899 }
2900
Mike Lockwooddc3494e2009-10-14 21:17:09 -07002901 private void setScreenBrightnessMode(int mode) {
Joe Onoratod28f7532010-11-06 12:56:53 -07002902 synchronized (mLocks) {
2903 boolean enabled = (mode == SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
2904 if (mUseSoftwareAutoBrightness && mAutoBrightessEnabled != enabled) {
2905 mAutoBrightessEnabled = enabled;
2906 // This will get us a new value
2907 enableLightSensorLocked(mAutoBrightessEnabled && isScreenOn());
Mike Lockwood2d155d22009-10-27 09:32:30 -04002908 }
Mike Lockwooddc3494e2009-10-14 21:17:09 -07002909 }
2910 }
2911
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002912 /** Sets the screen off timeouts:
2913 * mKeylightDelay
2914 * mDimDelay
2915 * mScreenOffDelay
2916 * */
2917 private void setScreenOffTimeoutsLocked() {
2918 if ((mPokey & POKE_LOCK_SHORT_TIMEOUT) != 0) {
Doug Zongker43866e02010-01-07 12:09:54 -08002919 mKeylightDelay = mShortKeylightDelay; // Configurable via secure settings
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002920 mDimDelay = -1;
2921 mScreenOffDelay = 0;
2922 } else if ((mPokey & POKE_LOCK_MEDIUM_TIMEOUT) != 0) {
2923 mKeylightDelay = MEDIUM_KEYLIGHT_DELAY;
2924 mDimDelay = -1;
2925 mScreenOffDelay = 0;
2926 } else {
Dianne Hackborndf83afa2010-01-20 13:37:26 -08002927 int totalDelay = mScreenOffTimeoutSetting;
2928 if (totalDelay > mMaximumScreenOffTimeout) {
2929 totalDelay = mMaximumScreenOffTimeout;
2930 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002931 mKeylightDelay = LONG_KEYLIGHT_DELAY;
2932 if (totalDelay < 0) {
Jim Millerbc4603b2010-08-30 21:21:34 -07002933 // negative number means stay on as long as possible.
2934 mScreenOffDelay = mMaximumScreenOffTimeout;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002935 } else if (mKeylightDelay < totalDelay) {
2936 // subtract the time that the keylight delay. This will give us the
2937 // remainder of the time that we need to sleep to get the accurate
2938 // screen off timeout.
2939 mScreenOffDelay = totalDelay - mKeylightDelay;
2940 } else {
2941 mScreenOffDelay = 0;
2942 }
2943 if (mDimScreen && totalDelay >= (LONG_KEYLIGHT_DELAY + LONG_DIM_TIME)) {
2944 mDimDelay = mScreenOffDelay - LONG_DIM_TIME;
2945 mScreenOffDelay = LONG_DIM_TIME;
2946 } else {
2947 mDimDelay = -1;
2948 }
2949 }
2950 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002951 Slog.d(TAG, "setScreenOffTimeouts mKeylightDelay=" + mKeylightDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002952 + " mDimDelay=" + mDimDelay + " mScreenOffDelay=" + mScreenOffDelay
2953 + " mDimScreen=" + mDimScreen);
2954 }
2955 }
2956
2957 /**
Doug Zongker43866e02010-01-07 12:09:54 -08002958 * Refreshes cached secure settings. Called once on startup, and
2959 * on subsequent changes to secure settings.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002960 */
Doug Zongker43866e02010-01-07 12:09:54 -08002961 private void updateSettingsValues() {
2962 mShortKeylightDelay = Settings.Secure.getInt(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002963 mContext.getContentResolver(),
Doug Zongker43866e02010-01-07 12:09:54 -08002964 Settings.Secure.SHORT_KEYLIGHT_DELAY_MS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002965 SHORT_KEYLIGHT_DELAY_DEFAULT);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002966 // Slog.i(TAG, "updateSettingsValues(): mShortKeylightDelay now " + mShortKeylightDelay);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002967 }
2968
2969 private class LockList extends ArrayList<WakeLock>
2970 {
2971 void addLock(WakeLock wl)
2972 {
2973 int index = getIndex(wl.binder);
2974 if (index < 0) {
2975 this.add(wl);
2976 }
2977 }
2978
2979 WakeLock removeLock(IBinder binder)
2980 {
2981 int index = getIndex(binder);
2982 if (index >= 0) {
2983 return this.remove(index);
2984 } else {
2985 return null;
2986 }
2987 }
2988
2989 int getIndex(IBinder binder)
2990 {
2991 int N = this.size();
2992 for (int i=0; i<N; i++) {
2993 if (this.get(i).binder == binder) {
2994 return i;
2995 }
2996 }
2997 return -1;
2998 }
2999
3000 int gatherState()
3001 {
3002 int result = 0;
3003 int N = this.size();
3004 for (int i=0; i<N; i++) {
3005 WakeLock wl = this.get(i);
3006 if (wl.activated) {
3007 if (isScreenLock(wl.flags)) {
3008 result |= wl.minState;
3009 }
3010 }
3011 }
3012 return result;
3013 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003014
Michael Chane96440f2009-05-06 10:27:36 -07003015 int reactivateScreenLocksLocked()
3016 {
3017 int result = 0;
3018 int N = this.size();
3019 for (int i=0; i<N; i++) {
3020 WakeLock wl = this.get(i);
3021 if (isScreenLock(wl.flags)) {
3022 wl.activated = true;
3023 result |= wl.minState;
3024 }
3025 }
Joe Onorato8274a0e2010-10-05 17:38:09 -04003026 if (mDebugProximitySensor) {
3027 Slog.d(TAG, "reactivateScreenLocksLocked mProxIgnoredBecauseScreenTurnedOff="
3028 + mProxIgnoredBecauseScreenTurnedOff);
3029 }
3030 mProxIgnoredBecauseScreenTurnedOff = false;
Michael Chane96440f2009-05-06 10:27:36 -07003031 return result;
3032 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003033 }
3034
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08003035 public void setPolicy(WindowManagerPolicy p) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003036 synchronized (mLocks) {
3037 mPolicy = p;
3038 mLocks.notifyAll();
3039 }
3040 }
3041
3042 WindowManagerPolicy getPolicyLocked() {
3043 while (mPolicy == null || !mDoneBooting) {
3044 try {
3045 mLocks.wait();
3046 } catch (InterruptedException e) {
3047 // Ignore
3048 }
3049 }
3050 return mPolicy;
3051 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003052
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003053 void systemReady() {
Jeff Brown25157e42012-04-16 12:13:05 -07003054 mSensorManager = new SystemSensorManager(mHandlerThread.getLooper());
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003055 mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
3056 // don't bother with the light sensor if auto brightness is handled in hardware
Mike Lockwoodaa66ea82009-10-31 16:31:27 -04003057 if (mUseSoftwareAutoBrightness) {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003058 mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003059 }
3060
Mike Lockwoodb42ab0f2010-03-04 08:02:44 -05003061 // wait until sensors are enabled before turning on screen.
3062 // some devices will not activate the light sensor properly on boot
3063 // unless we do this.
3064 if (mUseSoftwareAutoBrightness) {
3065 // turn the screen on
3066 setPowerState(SCREEN_BRIGHT);
3067 } else {
3068 // turn everything on
3069 setPowerState(ALL_BRIGHT);
3070 }
3071
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003072 synchronized (mLocks) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003073 Slog.d(TAG, "system ready!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003074 mDoneBooting = true;
Mike Lockwoodb42ab0f2010-03-04 08:02:44 -05003075
Joe Onoratod28f7532010-11-06 12:56:53 -07003076 enableLightSensorLocked(mUseSoftwareAutoBrightness && mAutoBrightessEnabled);
3077
Dianne Hackborn617f8772009-03-31 15:04:46 -07003078 long identity = Binder.clearCallingIdentity();
3079 try {
3080 mBatteryStats.noteScreenBrightness(getPreferredBrightness());
3081 mBatteryStats.noteScreenOn();
3082 } catch (RemoteException e) {
3083 // Nothing interesting to do.
3084 } finally {
3085 Binder.restoreCallingIdentity(identity);
3086 }
Mike Lockwood2d7bb812009-11-15 18:12:22 -05003087 }
3088 }
3089
3090 void bootCompleted() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003091 Slog.d(TAG, "bootCompleted");
Mike Lockwood2d7bb812009-11-15 18:12:22 -05003092 synchronized (mLocks) {
3093 mBootCompleted = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003094 userActivity(SystemClock.uptimeMillis(), false, BUTTON_EVENT, true);
3095 updateWakeLockLocked();
3096 mLocks.notifyAll();
3097 }
3098 }
3099
Joe Onoratob08a1af2010-10-11 19:28:58 -07003100 // for watchdog
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003101 public void monitor() {
3102 synchronized (mLocks) { }
3103 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003104
3105 public int getSupportedWakeLockFlags() {
3106 int result = PowerManager.PARTIAL_WAKE_LOCK
3107 | PowerManager.FULL_WAKE_LOCK
3108 | PowerManager.SCREEN_DIM_WAKE_LOCK;
3109
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003110 if (mProximitySensor != null) {
3111 result |= PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK;
3112 }
3113
3114 return result;
3115 }
3116
Mike Lockwood237a2992009-09-15 14:42:16 -04003117 public void setBacklightBrightness(int brightness) {
3118 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
3119 // Don't let applications turn the screen all the way off
Joe Onoratob08a1af2010-10-11 19:28:58 -07003120 synchronized (mLocks) {
Mike Lockwoodeb6456b2011-09-13 15:24:02 -04003121 brightness = Math.max(brightness, mScreenBrightnessDim);
Joe Onoratob08a1af2010-10-11 19:28:58 -07003122 mLcdLight.setBrightness(brightness);
3123 mKeyboardLight.setBrightness(mKeyboardVisible ? brightness : 0);
3124 mButtonLight.setBrightness(brightness);
3125 long identity = Binder.clearCallingIdentity();
3126 try {
3127 mBatteryStats.noteScreenBrightness(brightness);
3128 } catch (RemoteException e) {
3129 Slog.w(TAG, "RemoteException calling noteScreenBrightness on BatteryStatsService", e);
3130 } finally {
3131 Binder.restoreCallingIdentity(identity);
3132 }
Jim Miller92e66dd2012-02-21 18:57:12 -08003133 mScreenBrightnessAnimator.animateTo(brightness, SCREEN_BRIGHT_BIT, 0);
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08003134 }
3135 }
3136
3137 public void setAutoBrightnessAdjustment(float adj) {
3138 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
3139 synchronized (mLocks) {
3140 mLightSensorAdjustSetting = adj;
3141 if (mSensorManager != null && mLightSensorEnabled) {
3142 // clear calling identity so sensor manager battery stats are accurate
3143 long identity = Binder.clearCallingIdentity();
3144 try {
3145 // force recompute of backlight values
3146 if (mLightSensorValue >= 0) {
3147 int value = (int)mLightSensorValue;
3148 mLightSensorValue = -1;
3149 handleLightSensorValue(value, true);
3150 }
3151 } finally {
3152 Binder.restoreCallingIdentity(identity);
3153 }
Joe Onorato3d3db602010-10-18 16:08:16 -04003154 }
Mike Lockwood237a2992009-09-15 14:42:16 -04003155 }
3156 }
3157
Mike Lockwoodb11832d2009-11-25 15:25:55 -05003158 public void setAttentionLight(boolean on, int color) {
3159 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
Mike Lockwood3cb67a32009-11-27 14:25:58 -05003160 mAttentionLight.setFlashing(color, LightsService.LIGHT_FLASH_HARDWARE, (on ? 3 : 0), 0);
Mike Lockwoodb11832d2009-11-25 15:25:55 -05003161 }
3162
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003163 private void enableProximityLockLocked() {
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003164 if (mDebugProximitySensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003165 Slog.d(TAG, "enableProximityLockLocked");
Mike Lockwood36fc3022009-08-25 16:49:06 -07003166 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003167 if (!mProximitySensorEnabled) {
3168 // clear calling identity so sensor manager battery stats are accurate
3169 long identity = Binder.clearCallingIdentity();
3170 try {
3171 mSensorManager.registerListener(mProximityListener, mProximitySensor,
3172 SensorManager.SENSOR_DELAY_NORMAL);
3173 mProximitySensorEnabled = true;
3174 } finally {
3175 Binder.restoreCallingIdentity(identity);
3176 }
Mike Lockwood809ad0f2009-10-26 22:10:33 -04003177 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003178 }
3179
3180 private void disableProximityLockLocked() {
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003181 if (mDebugProximitySensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003182 Slog.d(TAG, "disableProximityLockLocked");
Mike Lockwood36fc3022009-08-25 16:49:06 -07003183 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003184 if (mProximitySensorEnabled) {
3185 // clear calling identity so sensor manager battery stats are accurate
3186 long identity = Binder.clearCallingIdentity();
3187 try {
3188 mSensorManager.unregisterListener(mProximityListener);
3189 mHandler.removeCallbacks(mProximityTask);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -05003190 if (mProximityPartialLock.isHeld()) {
3191 mProximityPartialLock.release();
3192 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003193 mProximitySensorEnabled = false;
3194 } finally {
3195 Binder.restoreCallingIdentity(identity);
3196 }
3197 if (mProximitySensorActive) {
3198 mProximitySensorActive = false;
Joe Onorato8274a0e2010-10-05 17:38:09 -04003199 if (mDebugProximitySensor) {
3200 Slog.d(TAG, "disableProximityLockLocked mProxIgnoredBecauseScreenTurnedOff="
3201 + mProxIgnoredBecauseScreenTurnedOff);
3202 }
3203 if (!mProxIgnoredBecauseScreenTurnedOff) {
3204 forceUserActivityLocked();
3205 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003206 }
Mike Lockwood200b30b2009-09-20 00:23:59 -04003207 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003208 }
3209
Mike Lockwood20f87d72009-11-05 16:08:51 -05003210 private void proximityChangedLocked(boolean active) {
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003211 if (mDebugProximitySensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003212 Slog.d(TAG, "proximityChangedLocked, active: " + active);
Mike Lockwood20f87d72009-11-05 16:08:51 -05003213 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003214 if (!mProximitySensorEnabled) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003215 Slog.d(TAG, "Ignoring proximity change after sensor is disabled");
Mike Lockwood0d72f7e2009-11-05 20:53:00 -05003216 return;
3217 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05003218 if (active) {
Joe Onorato8274a0e2010-10-05 17:38:09 -04003219 if (mDebugProximitySensor) {
3220 Slog.d(TAG, "b mProxIgnoredBecauseScreenTurnedOff="
3221 + mProxIgnoredBecauseScreenTurnedOff);
3222 }
3223 if (!mProxIgnoredBecauseScreenTurnedOff) {
3224 goToSleepLocked(SystemClock.uptimeMillis(),
3225 WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR);
3226 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05003227 mProximitySensorActive = true;
3228 } else {
3229 // proximity sensor negative events trigger as user activity.
3230 // temporarily set mUserActivityAllowed to true so this will work
3231 // even when the keyguard is on.
3232 mProximitySensorActive = false;
Joe Onorato8274a0e2010-10-05 17:38:09 -04003233 if (mDebugProximitySensor) {
3234 Slog.d(TAG, "b mProxIgnoredBecauseScreenTurnedOff="
3235 + mProxIgnoredBecauseScreenTurnedOff);
3236 }
3237 if (!mProxIgnoredBecauseScreenTurnedOff) {
3238 forceUserActivityLocked();
3239 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003240
3241 if (mProximityWakeLockCount == 0) {
3242 // disable sensor if we have no listeners left after proximity negative
3243 disableProximityLockLocked();
3244 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05003245 }
3246 }
3247
Joe Onoratod28f7532010-11-06 12:56:53 -07003248 private void enableLightSensorLocked(boolean enable) {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003249 if (mDebugLightSensor) {
Joe Onoratod28f7532010-11-06 12:56:53 -07003250 Slog.d(TAG, "enableLightSensorLocked enable=" + enable
Craig Mautner37933682012-06-06 14:13:39 -07003251 + " mLightSensorEnabled=" + mLightSensorEnabled
3252 + " mAutoBrightessEnabled=" + mAutoBrightessEnabled
3253 + " mWaitingForFirstLightSensor=" + mWaitingForFirstLightSensor);
Joe Onoratod28f7532010-11-06 12:56:53 -07003254 }
3255 if (!mAutoBrightessEnabled) {
3256 enable = false;
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003257 }
3258 if (mSensorManager != null && mLightSensorEnabled != enable) {
3259 mLightSensorEnabled = enable;
Mike Lockwood809ad0f2009-10-26 22:10:33 -04003260 // clear calling identity so sensor manager battery stats are accurate
3261 long identity = Binder.clearCallingIdentity();
3262 try {
3263 if (enable) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003264 // reset our highest value when reenabling
3265 mHighestLightSensorValue = -1;
3266 // force recompute of backlight values
Craig Mautner37933682012-06-06 14:13:39 -07003267 final int value = (int)mLightSensorValue;
3268 if (value >= 0) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003269 mLightSensorValue = -1;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08003270 handleLightSensorValue(value, true);
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003271 }
Mike Lockwood809ad0f2009-10-26 22:10:33 -04003272 mSensorManager.registerListener(mLightListener, mLightSensor,
Mathias Agopian47f1fe52011-11-08 17:18:41 -08003273 LIGHT_SENSOR_RATE);
Mike Lockwood809ad0f2009-10-26 22:10:33 -04003274 } else {
3275 mSensorManager.unregisterListener(mLightListener);
3276 mHandler.removeCallbacks(mAutoBrightnessTask);
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003277 mLightSensorPendingDecrease = false;
3278 mLightSensorPendingIncrease = false;
Mike Lockwood809ad0f2009-10-26 22:10:33 -04003279 }
3280 } finally {
3281 Binder.restoreCallingIdentity(identity);
Mike Lockwood06952d92009-08-13 16:05:38 -04003282 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003283 }
3284 }
3285
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003286 SensorEventListener mProximityListener = new SensorEventListener() {
3287 public void onSensorChanged(SensorEvent event) {
Mike Lockwoodba8eb1e2009-11-08 19:31:18 -05003288 long milliseconds = SystemClock.elapsedRealtime();
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003289 synchronized (mLocks) {
3290 float distance = event.values[0];
Mike Lockwood20f87d72009-11-05 16:08:51 -05003291 long timeSinceLastEvent = milliseconds - mLastProximityEventTime;
3292 mLastProximityEventTime = milliseconds;
3293 mHandler.removeCallbacks(mProximityTask);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -05003294 boolean proximityTaskQueued = false;
Mike Lockwood20f87d72009-11-05 16:08:51 -05003295
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003296 // compare against getMaximumRange to support sensors that only return 0 or 1
Mike Lockwood20f87d72009-11-05 16:08:51 -05003297 boolean active = (distance >= 0.0 && distance < PROXIMITY_THRESHOLD &&
3298 distance < mProximitySensor.getMaximumRange());
3299
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003300 if (mDebugProximitySensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003301 Slog.d(TAG, "mProximityListener.onSensorChanged active: " + active);
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003302 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05003303 if (timeSinceLastEvent < PROXIMITY_SENSOR_DELAY) {
3304 // enforce delaying atleast PROXIMITY_SENSOR_DELAY before processing
3305 mProximityPendingValue = (active ? 1 : 0);
3306 mHandler.postDelayed(mProximityTask, PROXIMITY_SENSOR_DELAY - timeSinceLastEvent);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -05003307 proximityTaskQueued = true;
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003308 } else {
Mike Lockwood20f87d72009-11-05 16:08:51 -05003309 // process the value immediately
3310 mProximityPendingValue = -1;
3311 proximityChangedLocked(active);
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003312 }
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -05003313
3314 // update mProximityPartialLock state
3315 boolean held = mProximityPartialLock.isHeld();
3316 if (!held && proximityTaskQueued) {
3317 // hold wakelock until mProximityTask runs
3318 mProximityPartialLock.acquire();
3319 } else if (held && !proximityTaskQueued) {
3320 mProximityPartialLock.release();
3321 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003322 }
3323 }
3324
3325 public void onAccuracyChanged(Sensor sensor, int accuracy) {
3326 // ignore
3327 }
3328 };
3329
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08003330 private void handleLightSensorValue(int value, boolean immediate) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003331 long milliseconds = SystemClock.elapsedRealtime();
Craig Mautner37933682012-06-06 14:13:39 -07003332 if (mLightSensorValue == -1
3333 || milliseconds < mLastScreenOnTime + mLightSensorWarmupTime
3334 || mWaitingForFirstLightSensor) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003335 // process the value immediately if screen has just turned on
3336 mHandler.removeCallbacks(mAutoBrightnessTask);
3337 mLightSensorPendingDecrease = false;
3338 mLightSensorPendingIncrease = false;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08003339 lightSensorChangedLocked(value, immediate);
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003340 } else {
3341 if ((value > mLightSensorValue && mLightSensorPendingDecrease) ||
3342 (value < mLightSensorValue && mLightSensorPendingIncrease) ||
3343 (value == mLightSensorValue) ||
3344 (!mLightSensorPendingDecrease && !mLightSensorPendingIncrease)) {
3345 // delay processing to debounce the sensor
3346 mHandler.removeCallbacks(mAutoBrightnessTask);
3347 mLightSensorPendingDecrease = (value < mLightSensorValue);
3348 mLightSensorPendingIncrease = (value > mLightSensorValue);
3349 if (mLightSensorPendingDecrease || mLightSensorPendingIncrease) {
3350 mLightSensorPendingValue = value;
3351 mHandler.postDelayed(mAutoBrightnessTask, LIGHT_SENSOR_DELAY);
3352 }
3353 } else {
3354 mLightSensorPendingValue = value;
3355 }
3356 }
3357 }
3358
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003359 SensorEventListener mLightListener = new SensorEventListener() {
3360 public void onSensorChanged(SensorEvent event) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003361 if (mDebugLightSensor) {
3362 Slog.d(TAG, "onSensorChanged: light value: " + event.values[0]);
3363 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003364 synchronized (mLocks) {
Mike Lockwood497087e32009-11-08 18:33:03 -05003365 // ignore light sensor while screen is turning off
3366 if (isScreenTurningOffLocked()) {
3367 return;
3368 }
Craig Mautner37933682012-06-06 14:13:39 -07003369 handleLightSensorValue((int)event.values[0], mWaitingForFirstLightSensor);
3370 if (mWaitingForFirstLightSensor) {
3371 mWaitingForFirstLightSensor = false;
3372 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003373 }
3374 }
3375
3376 public void onAccuracyChanged(Sensor sensor, int accuracy) {
3377 // ignore
3378 }
3379 };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003380}