blob: 888ec695dc9d1a049ef1ef09854f93fe9bf8c47a [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) {
Dianne Hackbornea401542012-06-26 14:34:54 -07001043 userActivity(SystemClock.uptimeMillis(), -1, false, OTHER_EVENT, false, true);
Joe Onorato8274a0e2010-10-05 17:38:09 -04001044 }
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 " : "")
jaiyoung.park15415f52012-06-01 15:06:22 +09001168 + (((state & BUTTON_BRIGHT_BIT) != 0)
1169 ? "BUTTON_BRIGHT_BIT " : "")
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001170 + (((state & BATTERY_LOW_BIT) != 0)
1171 ? "BATTERY_LOW_BIT " : "");
1172 }
1173
1174 @Override
1175 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1176 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
1177 != PackageManager.PERMISSION_GRANTED) {
1178 pw.println("Permission Denial: can't dump PowerManager from from pid="
1179 + Binder.getCallingPid()
1180 + ", uid=" + Binder.getCallingUid());
1181 return;
1182 }
1183
1184 long now = SystemClock.uptimeMillis();
1185
Mike Lockwoodca44df82010-02-25 13:48:49 -05001186 synchronized (mLocks) {
1187 pw.println("Power Manager State:");
1188 pw.println(" mIsPowered=" + mIsPowered
1189 + " mPowerState=" + mPowerState
1190 + " mScreenOffTime=" + (SystemClock.elapsedRealtime()-mScreenOffTime)
1191 + " ms");
1192 pw.println(" mPartialCount=" + mPartialCount);
1193 pw.println(" mWakeLockState=" + dumpPowerState(mWakeLockState));
1194 pw.println(" mUserState=" + dumpPowerState(mUserState));
1195 pw.println(" mPowerState=" + dumpPowerState(mPowerState));
1196 pw.println(" mLocks.gather=" + dumpPowerState(mLocks.gatherState()));
1197 pw.println(" mNextTimeout=" + mNextTimeout + " now=" + now
1198 + " " + ((mNextTimeout-now)/1000) + "s from now");
1199 pw.println(" mDimScreen=" + mDimScreen
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001200 + " mStayOnConditions=" + mStayOnConditions
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001201 + " mPreparingForScreenOn=" + mPreparingForScreenOn
1202 + " mSkippedScreenOn=" + mSkippedScreenOn);
Mike Lockwoodca44df82010-02-25 13:48:49 -05001203 pw.println(" mScreenOffReason=" + mScreenOffReason
1204 + " mUserState=" + mUserState);
1205 pw.println(" mBroadcastQueue={" + mBroadcastQueue[0] + ',' + mBroadcastQueue[1]
1206 + ',' + mBroadcastQueue[2] + "}");
1207 pw.println(" mBroadcastWhy={" + mBroadcastWhy[0] + ',' + mBroadcastWhy[1]
1208 + ',' + mBroadcastWhy[2] + "}");
1209 pw.println(" mPokey=" + mPokey + " mPokeAwakeonSet=" + mPokeAwakeOnSet);
1210 pw.println(" mKeyboardVisible=" + mKeyboardVisible
1211 + " mUserActivityAllowed=" + mUserActivityAllowed);
1212 pw.println(" mKeylightDelay=" + mKeylightDelay + " mDimDelay=" + mDimDelay
1213 + " mScreenOffDelay=" + mScreenOffDelay);
1214 pw.println(" mPreventScreenOn=" + mPreventScreenOn
1215 + " mScreenBrightnessOverride=" + mScreenBrightnessOverride
1216 + " mButtonBrightnessOverride=" + mButtonBrightnessOverride);
1217 pw.println(" mScreenOffTimeoutSetting=" + mScreenOffTimeoutSetting
1218 + " mMaximumScreenOffTimeout=" + mMaximumScreenOffTimeout);
1219 pw.println(" mLastScreenOnTime=" + mLastScreenOnTime);
1220 pw.println(" mBroadcastWakeLock=" + mBroadcastWakeLock);
1221 pw.println(" mStayOnWhilePluggedInScreenDimLock=" + mStayOnWhilePluggedInScreenDimLock);
1222 pw.println(" mStayOnWhilePluggedInPartialLock=" + mStayOnWhilePluggedInPartialLock);
1223 pw.println(" mPreventScreenOnPartialLock=" + mPreventScreenOnPartialLock);
1224 pw.println(" mProximityPartialLock=" + mProximityPartialLock);
1225 pw.println(" mProximityWakeLockCount=" + mProximityWakeLockCount);
1226 pw.println(" mProximitySensorEnabled=" + mProximitySensorEnabled);
1227 pw.println(" mProximitySensorActive=" + mProximitySensorActive);
1228 pw.println(" mProximityPendingValue=" + mProximityPendingValue);
1229 pw.println(" mLastProximityEventTime=" + mLastProximityEventTime);
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08001230 pw.println(" mLightSensorEnabled=" + mLightSensorEnabled
1231 + " mLightSensorAdjustSetting=" + mLightSensorAdjustSetting);
Mike Lockwoodca44df82010-02-25 13:48:49 -05001232 pw.println(" mLightSensorValue=" + mLightSensorValue
1233 + " mLightSensorPendingValue=" + mLightSensorPendingValue);
Craig Mautner291576e2012-06-07 19:58:58 -07001234 pw.println(" mHighestLightSensorValue=" + mHighestLightSensorValue
1235 + " mWaitingForFirstLightSensor=" + mWaitingForFirstLightSensor);
Jim Rodovichd102fea2010-09-02 12:30:49 -05001236 pw.println(" mLightSensorPendingDecrease=" + mLightSensorPendingDecrease
1237 + " mLightSensorPendingIncrease=" + mLightSensorPendingIncrease);
Mike Lockwoodca44df82010-02-25 13:48:49 -05001238 pw.println(" mLightSensorScreenBrightness=" + mLightSensorScreenBrightness
1239 + " mLightSensorButtonBrightness=" + mLightSensorButtonBrightness
1240 + " mLightSensorKeyboardBrightness=" + mLightSensorKeyboardBrightness);
1241 pw.println(" mUseSoftwareAutoBrightness=" + mUseSoftwareAutoBrightness);
1242 pw.println(" mAutoBrightessEnabled=" + mAutoBrightessEnabled);
Craig Mautner672083b2012-06-26 11:49:08 -07001243 mScreenBrightnessAnimator.dump(pw, "mScreenBrightnessAnimator: ");
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001244
Mike Lockwoodca44df82010-02-25 13:48:49 -05001245 int N = mLocks.size();
1246 pw.println();
1247 pw.println("mLocks.size=" + N + ":");
1248 for (int i=0; i<N; i++) {
1249 WakeLock wl = mLocks.get(i);
1250 String type = lockType(wl.flags & LOCK_MASK);
1251 String acquireCausesWakeup = "";
1252 if ((wl.flags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {
1253 acquireCausesWakeup = "ACQUIRE_CAUSES_WAKEUP ";
1254 }
1255 String activated = "";
1256 if (wl.activated) {
1257 activated = " activated";
1258 }
1259 pw.println(" " + type + " '" + wl.tag + "'" + acquireCausesWakeup
Mike Lockwoodf5bd0922010-03-22 17:10:15 -04001260 + activated + " (minState=" + wl.minState + ", uid=" + wl.uid
1261 + ", pid=" + wl.pid + ")");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001262 }
Mike Lockwoodca44df82010-02-25 13:48:49 -05001263
1264 pw.println();
1265 pw.println("mPokeLocks.size=" + mPokeLocks.size() + ":");
1266 for (PokeLock p: mPokeLocks.values()) {
1267 pw.println(" poke lock '" + p.tag + "':"
Joe Onorato1a542c72010-11-08 09:48:20 -08001268 + ((p.pokey & POKE_LOCK_IGNORE_TOUCH_EVENTS) != 0
1269 ? " POKE_LOCK_IGNORE_TOUCH_EVENTS" : "")
Mike Lockwoodca44df82010-02-25 13:48:49 -05001270 + ((p.pokey & POKE_LOCK_SHORT_TIMEOUT) != 0
1271 ? " POKE_LOCK_SHORT_TIMEOUT" : "")
1272 + ((p.pokey & POKE_LOCK_MEDIUM_TIMEOUT) != 0
1273 ? " POKE_LOCK_MEDIUM_TIMEOUT" : ""));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001274 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001275
Mike Lockwoodca44df82010-02-25 13:48:49 -05001276 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001277 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001278 }
1279
Joe Onorato7999bff2010-07-24 11:50:05 -04001280 private void setTimeoutLocked(long now, int nextState) {
1281 setTimeoutLocked(now, -1, nextState);
1282 }
1283
1284 // If they gave a timeoutOverride it is the number of seconds
1285 // to screen-off. Figure out where in the countdown cycle we
1286 // should jump to.
Joe Onorato797e6882010-08-26 14:46:01 -04001287 private void setTimeoutLocked(long now, final long originalTimeoutOverride, int nextState) {
1288 long timeoutOverride = originalTimeoutOverride;
Mike Lockwood2d7bb812009-11-15 18:12:22 -05001289 if (mBootCompleted) {
Joe Onorato7999bff2010-07-24 11:50:05 -04001290 synchronized (mLocks) {
Joe Onorato7999bff2010-07-24 11:50:05 -04001291 long when = 0;
1292 if (timeoutOverride <= 0) {
1293 switch (nextState)
1294 {
1295 case SCREEN_BRIGHT:
1296 when = now + mKeylightDelay;
1297 break;
1298 case SCREEN_DIM:
1299 if (mDimDelay >= 0) {
1300 when = now + mDimDelay;
Andreas Huber84047bc2010-07-27 16:49:10 -07001301 break;
Joe Onorato7999bff2010-07-24 11:50:05 -04001302 } else {
1303 Slog.w(TAG, "mDimDelay=" + mDimDelay + " while trying to dim");
1304 }
1305 case SCREEN_OFF:
1306 synchronized (mLocks) {
1307 when = now + mScreenOffDelay;
1308 }
1309 break;
Andreas Huber84047bc2010-07-27 16:49:10 -07001310 default:
1311 when = now;
1312 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001313 }
Joe Onorato7999bff2010-07-24 11:50:05 -04001314 } else {
1315 override: {
1316 if (timeoutOverride <= mScreenOffDelay) {
1317 when = now + timeoutOverride;
1318 nextState = SCREEN_OFF;
1319 break override;
1320 }
1321 timeoutOverride -= mScreenOffDelay;
1322
1323 if (mDimDelay >= 0) {
1324 if (timeoutOverride <= mDimDelay) {
1325 when = now + timeoutOverride;
1326 nextState = SCREEN_DIM;
1327 break override;
1328 }
1329 timeoutOverride -= mDimDelay;
1330 }
1331
1332 when = now + timeoutOverride;
1333 nextState = SCREEN_BRIGHT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001334 }
Joe Onorato7999bff2010-07-24 11:50:05 -04001335 }
1336 if (mSpew) {
1337 Slog.d(TAG, "setTimeoutLocked now=" + now
1338 + " timeoutOverride=" + timeoutOverride
1339 + " nextState=" + nextState + " when=" + when);
1340 }
Joe Onorato797e6882010-08-26 14:46:01 -04001341
1342 mHandler.removeCallbacks(mTimeoutTask);
1343 mTimeoutTask.nextState = nextState;
1344 mTimeoutTask.remainingTimeoutOverride = timeoutOverride > 0
1345 ? (originalTimeoutOverride - timeoutOverride)
1346 : -1;
Joe Onorato7999bff2010-07-24 11:50:05 -04001347 mHandler.postAtTime(mTimeoutTask, when);
1348 mNextTimeout = when; // for debugging
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001349 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001350 }
1351 }
1352
1353 private void cancelTimerLocked()
1354 {
1355 mHandler.removeCallbacks(mTimeoutTask);
1356 mTimeoutTask.nextState = -1;
1357 }
1358
1359 private class TimeoutTask implements Runnable
1360 {
1361 int nextState; // access should be synchronized on mLocks
Joe Onorato797e6882010-08-26 14:46:01 -04001362 long remainingTimeoutOverride;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001363 public void run()
1364 {
1365 synchronized (mLocks) {
1366 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001367 Slog.d(TAG, "user activity timeout timed out nextState=" + this.nextState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001368 }
1369
1370 if (nextState == -1) {
1371 return;
1372 }
1373
1374 mUserState = this.nextState;
1375 setPowerState(this.nextState | mWakeLockState);
1376
1377 long now = SystemClock.uptimeMillis();
1378
1379 switch (this.nextState)
1380 {
1381 case SCREEN_BRIGHT:
1382 if (mDimDelay >= 0) {
Joe Onorato797e6882010-08-26 14:46:01 -04001383 setTimeoutLocked(now, remainingTimeoutOverride, SCREEN_DIM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001384 break;
1385 }
1386 case SCREEN_DIM:
Joe Onorato797e6882010-08-26 14:46:01 -04001387 setTimeoutLocked(now, remainingTimeoutOverride, SCREEN_OFF);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001388 break;
1389 }
1390 }
1391 }
1392 }
1393
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001394 private void sendNotificationLocked(boolean on, int why) {
1395 if (!mInitialized) {
1396 // No notifications sent until first initialization is done.
1397 // This is so that when we are moving from our initial state
1398 // which looks like the screen was off to it being on, we do not
1399 // go through the process of waiting for the higher-level user
1400 // space to be ready before turning up the display brightness.
1401 // (And also do not send needless broadcasts about the screen.)
1402 return;
1403 }
Dianne Hackborn40011092011-09-22 13:37:48 -07001404
1405 if (DEBUG_SCREEN_ON) {
1406 RuntimeException here = new RuntimeException("here");
1407 here.fillInStackTrace();
1408 Slog.i(TAG, "sendNotificationLocked: " + on, here);
1409 }
1410
Joe Onorato64c62ba2009-03-24 20:13:57 -07001411 if (!on) {
1412 mStillNeedSleepNotification = false;
1413 }
1414
Joe Onorato128e7292009-03-24 18:41:31 -07001415 // Add to the queue.
1416 int index = 0;
1417 while (mBroadcastQueue[index] != -1) {
1418 index++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001419 }
Joe Onorato128e7292009-03-24 18:41:31 -07001420 mBroadcastQueue[index] = on ? 1 : 0;
1421 mBroadcastWhy[index] = why;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001422
Joe Onorato128e7292009-03-24 18:41:31 -07001423 // If we added it position 2, then there is a pair that can be stripped.
1424 // If we added it position 1 and we're turning the screen off, we can strip
1425 // the pair and do nothing, because the screen is already off, and therefore
1426 // keyguard has already been enabled.
1427 // However, if we added it at position 1 and we're turning it on, then position
1428 // 0 was to turn it off, and we can't strip that, because keyguard needs to come
1429 // on, so have to run the queue then.
1430 if (index == 2) {
Dianne Hackborn254cb442010-01-27 19:23:59 -08001431 // While we're collapsing them, if it's going off, and the new reason
1432 // is more significant than the first, then use the new one.
1433 if (!on && mBroadcastWhy[0] > why) {
1434 mBroadcastWhy[0] = why;
Joe Onorato128e7292009-03-24 18:41:31 -07001435 }
1436 mBroadcastQueue[0] = on ? 1 : 0;
1437 mBroadcastQueue[1] = -1;
1438 mBroadcastQueue[2] = -1;
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();
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001441 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount);
Mike Lockwood9c90a372010-04-13 15:40:27 -04001442 mBroadcastWakeLock.release();
Joe Onorato128e7292009-03-24 18:41:31 -07001443 index = 0;
1444 }
1445 if (index == 1 && !on) {
1446 mBroadcastQueue[0] = -1;
1447 mBroadcastQueue[1] = -1;
1448 index = -1;
1449 // The wake lock was being held, but we're not actually going to do any
1450 // broadcasts, so release the wake lock.
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001451 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001452 mBroadcastWakeLock.release();
Joe Onorato128e7292009-03-24 18:41:31 -07001453 }
1454
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07001455 // The broadcast queue has changed; make sure the screen is on if it
1456 // is now possible for it to be.
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001457 if (mSkippedScreenOn) {
1458 updateLightsLocked(mPowerState, SCREEN_ON_BIT);
1459 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07001460
Joe Onorato128e7292009-03-24 18:41:31 -07001461 // Now send the message.
1462 if (index >= 0) {
1463 // Acquire the broadcast wake lock before changing the power
1464 // state. It will be release after the broadcast is sent.
1465 // We always increment the ref count for each notification in the queue
1466 // and always decrement when that notification is handled.
1467 mBroadcastWakeLock.acquire();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001468 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND, mBroadcastWakeLock.mCount);
Joe Onorato128e7292009-03-24 18:41:31 -07001469 mHandler.post(mNotificationTask);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001470 }
1471 }
1472
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001473 private WindowManagerPolicy.ScreenOnListener mScreenOnListener =
1474 new WindowManagerPolicy.ScreenOnListener() {
Jim Miller92e66dd2012-02-21 18:57:12 -08001475 public void onScreenOn() {
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001476 synchronized (mLocks) {
1477 if (mPreparingForScreenOn) {
1478 mPreparingForScreenOn = false;
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001479 updateLightsLocked(mPowerState, SCREEN_ON_BIT);
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001480 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP,
1481 4, mBroadcastWakeLock.mCount);
1482 mBroadcastWakeLock.release();
1483 }
1484 }
1485 }
1486 };
1487
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001488 private Runnable mNotificationTask = new Runnable()
1489 {
1490 public void run()
1491 {
Joe Onorato128e7292009-03-24 18:41:31 -07001492 while (true) {
1493 int value;
1494 int why;
1495 WindowManagerPolicy policy;
1496 synchronized (mLocks) {
1497 value = mBroadcastQueue[0];
1498 why = mBroadcastWhy[0];
1499 for (int i=0; i<2; i++) {
1500 mBroadcastQueue[i] = mBroadcastQueue[i+1];
1501 mBroadcastWhy[i] = mBroadcastWhy[i+1];
1502 }
1503 policy = getPolicyLocked();
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001504 if (value == 1 && !mPreparingForScreenOn) {
1505 mPreparingForScreenOn = true;
1506 mBroadcastWakeLock.acquire();
1507 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND,
1508 mBroadcastWakeLock.mCount);
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07001509 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001510 }
Joe Onorato128e7292009-03-24 18:41:31 -07001511 if (value == 1) {
1512 mScreenOnStart = SystemClock.uptimeMillis();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001513
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001514 policy.screenTurningOn(mScreenOnListener);
Joe Onorato128e7292009-03-24 18:41:31 -07001515 try {
1516 ActivityManagerNative.getDefault().wakingUp();
1517 } catch (RemoteException e) {
1518 // ignore it
1519 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001520
Joe Onorato128e7292009-03-24 18:41:31 -07001521 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001522 Slog.d(TAG, "mBroadcastWakeLock=" + mBroadcastWakeLock);
Joe Onorato128e7292009-03-24 18:41:31 -07001523 }
1524 if (mContext != null && ActivityManagerNative.isSystemReady()) {
1525 mContext.sendOrderedBroadcast(mScreenOnIntent, null,
1526 mScreenOnBroadcastDone, mHandler, 0, null, null);
1527 } else {
1528 synchronized (mLocks) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001529 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 2,
Joe Onorato128e7292009-03-24 18:41:31 -07001530 mBroadcastWakeLock.mCount);
1531 mBroadcastWakeLock.release();
1532 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001533 }
1534 }
Joe Onorato128e7292009-03-24 18:41:31 -07001535 else if (value == 0) {
1536 mScreenOffStart = SystemClock.uptimeMillis();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001537
Joe Onorato128e7292009-03-24 18:41:31 -07001538 policy.screenTurnedOff(why);
1539 try {
1540 ActivityManagerNative.getDefault().goingToSleep();
1541 } catch (RemoteException e) {
1542 // ignore it.
1543 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001544
Joe Onorato128e7292009-03-24 18:41:31 -07001545 if (mContext != null && ActivityManagerNative.isSystemReady()) {
1546 mContext.sendOrderedBroadcast(mScreenOffIntent, null,
1547 mScreenOffBroadcastDone, mHandler, 0, null, null);
1548 } else {
1549 synchronized (mLocks) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001550 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 3,
Joe Onorato128e7292009-03-24 18:41:31 -07001551 mBroadcastWakeLock.mCount);
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001552 updateLightsLocked(mPowerState, SCREEN_ON_BIT);
Joe Onorato128e7292009-03-24 18:41:31 -07001553 mBroadcastWakeLock.release();
1554 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001555 }
1556 }
Joe Onorato128e7292009-03-24 18:41:31 -07001557 else {
1558 // If we're in this case, then this handler is running for a previous
1559 // paired transaction. mBroadcastWakeLock will already have been released.
1560 break;
1561 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001562 }
1563 }
1564 };
1565
1566 long mScreenOnStart;
1567 private BroadcastReceiver mScreenOnBroadcastDone = new BroadcastReceiver() {
1568 public void onReceive(Context context, Intent intent) {
1569 synchronized (mLocks) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001570 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001571 SystemClock.uptimeMillis() - mScreenOnStart, mBroadcastWakeLock.mCount);
1572 mBroadcastWakeLock.release();
1573 }
1574 }
1575 };
1576
1577 long mScreenOffStart;
1578 private BroadcastReceiver mScreenOffBroadcastDone = new BroadcastReceiver() {
1579 public void onReceive(Context context, Intent intent) {
1580 synchronized (mLocks) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001581 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 0,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001582 SystemClock.uptimeMillis() - mScreenOffStart, mBroadcastWakeLock.mCount);
1583 mBroadcastWakeLock.release();
1584 }
1585 }
1586 };
1587
1588 void logPointerUpEvent() {
1589 if (LOG_TOUCH_DOWNS) {
1590 mTotalTouchDownTime += SystemClock.elapsedRealtime() - mLastTouchDown;
1591 mLastTouchDown = 0;
1592 }
1593 }
1594
1595 void logPointerDownEvent() {
1596 if (LOG_TOUCH_DOWNS) {
1597 // If we are not already timing a down/up sequence
1598 if (mLastTouchDown == 0) {
1599 mLastTouchDown = SystemClock.elapsedRealtime();
1600 mTouchCycles++;
1601 }
1602 }
1603 }
1604
1605 /**
1606 * Prevents the screen from turning on even if it *should* turn on due
1607 * to a subsequent full wake lock being acquired.
1608 * <p>
1609 * This is a temporary hack that allows an activity to "cover up" any
1610 * display glitches that happen during the activity's startup
1611 * sequence. (Specifically, this API was added to work around a
1612 * cosmetic bug in the "incoming call" sequence, where the lock screen
1613 * would flicker briefly before the incoming call UI became visible.)
1614 * TODO: There ought to be a more elegant way of doing this,
1615 * probably by having the PowerManager and ActivityManager
1616 * work together to let apps specify that the screen on/off
1617 * state should be synchronized with the Activity lifecycle.
1618 * <p>
1619 * Note that calling preventScreenOn(true) will NOT turn the screen
1620 * off if it's currently on. (This API only affects *future*
1621 * acquisitions of full wake locks.)
1622 * But calling preventScreenOn(false) WILL turn the screen on if
1623 * it's currently off because of a prior preventScreenOn(true) call.
1624 * <p>
1625 * Any call to preventScreenOn(true) MUST be followed promptly by a call
1626 * to preventScreenOn(false). In fact, if the preventScreenOn(false)
1627 * call doesn't occur within 5 seconds, we'll turn the screen back on
1628 * ourselves (and log a warning about it); this prevents a buggy app
1629 * from disabling the screen forever.)
1630 * <p>
1631 * TODO: this feature should really be controlled by a new type of poke
1632 * lock (rather than an IPowerManager call).
1633 */
1634 public void preventScreenOn(boolean prevent) {
1635 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1636
1637 synchronized (mLocks) {
1638 if (prevent) {
1639 // First of all, grab a partial wake lock to
1640 // make sure the CPU stays on during the entire
1641 // preventScreenOn(true) -> preventScreenOn(false) sequence.
1642 mPreventScreenOnPartialLock.acquire();
1643
1644 // Post a forceReenableScreen() call (for 5 seconds in the
1645 // future) to make sure the matching preventScreenOn(false) call
1646 // has happened by then.
1647 mHandler.removeCallbacks(mForceReenableScreenTask);
1648 mHandler.postDelayed(mForceReenableScreenTask, 5000);
1649
1650 // Finally, set the flag that prevents the screen from turning on.
1651 // (Below, in setPowerState(), we'll check mPreventScreenOn and
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001652 // we *won't* call setScreenStateLocked(true) if it's set.)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001653 mPreventScreenOn = true;
1654 } else {
1655 // (Re)enable the screen.
1656 mPreventScreenOn = false;
1657
1658 // We're "undoing" a the prior preventScreenOn(true) call, so we
1659 // no longer need the 5-second safeguard.
1660 mHandler.removeCallbacks(mForceReenableScreenTask);
1661
1662 // Forcibly turn on the screen if it's supposed to be on. (This
1663 // handles the case where the screen is currently off because of
1664 // a prior preventScreenOn(true) call.)
Mike Lockwoode090281422009-11-14 21:02:56 -05001665 if (!mProximitySensorActive && (mPowerState & SCREEN_ON_BIT) != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001666 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001667 Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001668 "preventScreenOn: turning on after a prior preventScreenOn(true)!");
1669 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001670 int err = setScreenStateLocked(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001671 if (err != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001672 Slog.w(TAG, "preventScreenOn: error from setScreenStateLocked(): " + err);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001673 }
1674 }
1675
1676 // Release the partial wake lock that we held during the
1677 // preventScreenOn(true) -> preventScreenOn(false) sequence.
1678 mPreventScreenOnPartialLock.release();
1679 }
1680 }
1681 }
1682
1683 public void setScreenBrightnessOverride(int brightness) {
1684 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1685
Mike Lockwoodf527c712010-06-10 14:12:33 -04001686 if (mSpew) Slog.d(TAG, "setScreenBrightnessOverride " + brightness);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001687 synchronized (mLocks) {
1688 if (mScreenBrightnessOverride != brightness) {
1689 mScreenBrightnessOverride = brightness;
Mike Lockwoodf527c712010-06-10 14:12:33 -04001690 if (isScreenOn()) {
1691 updateLightsLocked(mPowerState, SCREEN_ON_BIT);
1692 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001693 }
1694 }
1695 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05001696
1697 public void setButtonBrightnessOverride(int brightness) {
1698 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1699
Mike Lockwoodf527c712010-06-10 14:12:33 -04001700 if (mSpew) Slog.d(TAG, "setButtonBrightnessOverride " + brightness);
Mike Lockwoodfb73f792009-11-20 11:31:18 -05001701 synchronized (mLocks) {
1702 if (mButtonBrightnessOverride != brightness) {
1703 mButtonBrightnessOverride = brightness;
Mike Lockwoodf527c712010-06-10 14:12:33 -04001704 if (isScreenOn()) {
1705 updateLightsLocked(mPowerState, BUTTON_BRIGHT_BIT | KEYBOARD_BRIGHT_BIT);
1706 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05001707 }
1708 }
1709 }
1710
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001711 /**
1712 * Sanity-check that gets called 5 seconds after any call to
1713 * preventScreenOn(true). This ensures that the original call
1714 * is followed promptly by a call to preventScreenOn(false).
1715 */
1716 private void forceReenableScreen() {
1717 // We shouldn't get here at all if mPreventScreenOn is false, since
1718 // we should have already removed any existing
1719 // mForceReenableScreenTask messages...
1720 if (!mPreventScreenOn) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001721 Slog.w(TAG, "forceReenableScreen: mPreventScreenOn is false, nothing to do");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001722 return;
1723 }
1724
1725 // Uh oh. It's been 5 seconds since a call to
1726 // preventScreenOn(true) and we haven't re-enabled the screen yet.
1727 // This means the app that called preventScreenOn(true) is either
1728 // slow (i.e. it took more than 5 seconds to call preventScreenOn(false)),
1729 // or buggy (i.e. it forgot to call preventScreenOn(false), or
1730 // crashed before doing so.)
1731
1732 // Log a warning, and forcibly turn the screen back on.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001733 Slog.w(TAG, "App called preventScreenOn(true) but didn't promptly reenable the screen! "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001734 + "Forcing the screen back on...");
1735 preventScreenOn(false);
1736 }
1737
1738 private Runnable mForceReenableScreenTask = new Runnable() {
1739 public void run() {
1740 forceReenableScreen();
1741 }
1742 };
1743
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001744 private int setScreenStateLocked(boolean on) {
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001745 if (DEBUG_SCREEN_ON) {
1746 RuntimeException e = new RuntimeException("here");
1747 e.fillInStackTrace();
1748 Slog.i(TAG, "Set screen state: " + on, e);
1749 }
Dianne Hackborn474fd742011-10-10 18:40:22 -07001750 if (on) {
Jeff Brown8e306a62012-06-20 19:20:57 -07001751 if (mInitialized && ((mPowerState & SCREEN_ON_BIT) == 0 || mSkippedScreenOn)) {
Dianne Hackborn474fd742011-10-10 18:40:22 -07001752 // If we are turning the screen state on, but the screen
1753 // light is currently off, then make sure that we set the
1754 // light at this point to 0. This is the case where we are
1755 // turning on the screen and waiting for the UI to be drawn
1756 // before showing it to the user. We want the light off
1757 // until it is ready to be shown to the user, not it using
1758 // whatever the last value it had.
Jeff Brown8e306a62012-06-20 19:20:57 -07001759 // Skip this if the screen is being turned on for the first time
1760 // after boot (mInitialized is false).
Dianne Hackborn81de8b92011-11-28 16:54:31 -08001761 if (DEBUG_SCREEN_ON) {
1762 Slog.i(TAG, "Forcing brightness 0: mPowerState=0x"
1763 + Integer.toHexString(mPowerState)
1764 + " mSkippedScreenOn=" + mSkippedScreenOn);
1765 }
Jeff Brown7304c342012-05-11 18:42:42 -07001766 mScreenBrightnessAnimator.animateTo(PowerManager.BRIGHTNESS_OFF, SCREEN_BRIGHT_BIT, 0);
Dianne Hackborn474fd742011-10-10 18:40:22 -07001767 }
1768 }
Jeff Brown7304c342012-05-11 18:42:42 -07001769 int err = nativeSetScreenState(on);
Mike Lockwood20ee6f22009-11-07 20:33:47 -05001770 if (err == 0) {
1771 mLastScreenOnTime = (on ? SystemClock.elapsedRealtime() : 0);
1772 if (mUseSoftwareAutoBrightness) {
Joe Onoratod28f7532010-11-06 12:56:53 -07001773 enableLightSensorLocked(on);
Craig Mautner37933682012-06-06 14:13:39 -07001774 if (on) {
1775 // If AutoBrightness is enabled, set the brightness immediately after the
1776 // next sensor value is received.
1777 mWaitingForFirstLightSensor = mAutoBrightessEnabled;
1778 } else {
Mike Lockwood20ee6f22009-11-07 20:33:47 -05001779 // make sure button and key backlights are off too
Mike Lockwood3cb67a32009-11-27 14:25:58 -05001780 mButtonLight.turnOff();
1781 mKeyboardLight.turnOff();
Mike Lockwood20ee6f22009-11-07 20:33:47 -05001782 }
Mike Lockwoodd7786b42009-10-15 17:09:16 -07001783 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001784 }
1785 return err;
1786 }
1787
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001788 private void setPowerState(int state)
1789 {
Mike Lockwood435eb642009-12-03 08:40:18 -05001790 setPowerState(state, false, WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001791 }
1792
Mike Lockwood435eb642009-12-03 08:40:18 -05001793 private void setPowerState(int newState, boolean noChangeLights, int reason)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001794 {
1795 synchronized (mLocks) {
1796 int err;
1797
1798 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001799 Slog.d(TAG, "setPowerState: mPowerState=0x" + Integer.toHexString(mPowerState)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001800 + " newState=0x" + Integer.toHexString(newState)
Mike Lockwood435eb642009-12-03 08:40:18 -05001801 + " noChangeLights=" + noChangeLights
1802 + " reason=" + reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001803 }
Daniel Sandler7d276c32012-01-30 14:33:52 -05001804
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001805 if (noChangeLights) {
1806 newState = (newState & ~LIGHTS_MASK) | (mPowerState & LIGHTS_MASK);
1807 }
Mike Lockwood36fc3022009-08-25 16:49:06 -07001808 if (mProximitySensorActive) {
1809 // don't turn on the screen when the proximity sensor lock is held
1810 newState = (newState & ~SCREEN_BRIGHT);
1811 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001812
1813 if (batteryIsLow()) {
1814 newState |= BATTERY_LOW_BIT;
1815 } else {
1816 newState &= ~BATTERY_LOW_BIT;
1817 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001818 if (newState == mPowerState && mInitialized) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001819 return;
1820 }
Mike Lockwood3333fa42009-10-26 14:50:42 -04001821
Mike Lockwood2d7bb812009-11-15 18:12:22 -05001822 if (!mBootCompleted && !mUseSoftwareAutoBrightness) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001823 newState |= ALL_BRIGHT;
1824 }
1825
1826 boolean oldScreenOn = (mPowerState & SCREEN_ON_BIT) != 0;
1827 boolean newScreenOn = (newState & SCREEN_ON_BIT) != 0;
1828
Mike Lockwood51b844962009-11-16 21:51:18 -05001829 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001830 Slog.d(TAG, "setPowerState: mPowerState=" + mPowerState
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001831 + " newState=" + newState + " noChangeLights=" + noChangeLights);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001832 Slog.d(TAG, " oldKeyboardBright=" + ((mPowerState & KEYBOARD_BRIGHT_BIT) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001833 + " newKeyboardBright=" + ((newState & KEYBOARD_BRIGHT_BIT) != 0));
Joe Onorato8a9b2202010-02-26 18:56:32 -08001834 Slog.d(TAG, " oldScreenBright=" + ((mPowerState & SCREEN_BRIGHT_BIT) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001835 + " newScreenBright=" + ((newState & SCREEN_BRIGHT_BIT) != 0));
Joe Onorato8a9b2202010-02-26 18:56:32 -08001836 Slog.d(TAG, " oldButtonBright=" + ((mPowerState & BUTTON_BRIGHT_BIT) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001837 + " newButtonBright=" + ((newState & BUTTON_BRIGHT_BIT) != 0));
Joe Onorato8a9b2202010-02-26 18:56:32 -08001838 Slog.d(TAG, " oldScreenOn=" + oldScreenOn
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001839 + " newScreenOn=" + newScreenOn);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001840 Slog.d(TAG, " oldBatteryLow=" + ((mPowerState & BATTERY_LOW_BIT) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001841 + " newBatteryLow=" + ((newState & BATTERY_LOW_BIT) != 0));
1842 }
1843
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001844 final boolean stateChanged = mPowerState != newState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001845
Daniel Sandler7d276c32012-01-30 14:33:52 -05001846 if (stateChanged && reason == WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT) {
Daniel Sandler0af48952012-04-10 15:14:35 -04001847 if (mPolicy != null && mPolicy.isScreenSaverEnabled()) {
Daniel Sandler7d276c32012-01-30 14:33:52 -05001848 if (mSpew) {
1849 Slog.d(TAG, "setPowerState: running screen saver instead of turning off screen");
1850 }
1851 if (mPolicy.startScreenSaver()) {
1852 // was successful
1853 return;
1854 }
1855 }
1856 }
1857
1858
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001859 if (oldScreenOn != newScreenOn) {
1860 if (newScreenOn) {
Joe Onorato128e7292009-03-24 18:41:31 -07001861 // When the user presses the power button, we need to always send out the
1862 // notification that it's going to sleep so the keyguard goes on. But
1863 // we can't do that until the screen fades out, so we don't show the keyguard
1864 // too early.
1865 if (mStillNeedSleepNotification) {
1866 sendNotificationLocked(false, WindowManagerPolicy.OFF_BECAUSE_OF_USER);
1867 }
1868
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001869 // Turn on the screen UNLESS there was a prior
1870 // preventScreenOn(true) request. (Note that the lifetime
1871 // of a single preventScreenOn() request is limited to 5
1872 // seconds to prevent a buggy app from disabling the
1873 // screen forever; see forceReenableScreen().)
1874 boolean reallyTurnScreenOn = true;
1875 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001876 Slog.d(TAG, "- turning screen on... mPreventScreenOn = "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001877 + mPreventScreenOn);
1878 }
1879
1880 if (mPreventScreenOn) {
1881 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001882 Slog.d(TAG, "- PREVENTING screen from really turning on!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001883 }
1884 reallyTurnScreenOn = false;
1885 }
1886 if (reallyTurnScreenOn) {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001887 err = setScreenStateLocked(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001888 long identity = Binder.clearCallingIdentity();
1889 try {
Mike Lockwoodfb73f792009-11-20 11:31:18 -05001890 mBatteryStats.noteScreenBrightness(getPreferredBrightness());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001891 mBatteryStats.noteScreenOn();
1892 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001893 Slog.w(TAG, "RemoteException calling noteScreenOn on BatteryStatsService", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001894 } finally {
1895 Binder.restoreCallingIdentity(identity);
1896 }
1897 } else {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001898 setScreenStateLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001899 // But continue as if we really did turn the screen on...
1900 err = 0;
1901 }
1902
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001903 mLastTouchDown = 0;
1904 mTotalTouchDownTime = 0;
1905 mTouchCycles = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001906 EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, reason,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001907 mTotalTouchDownTime, mTouchCycles);
1908 if (err == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001909 sendNotificationLocked(true, -1);
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001910 // Update the lights *after* taking care of turning the
1911 // screen on, so we do this after our notifications are
1912 // enqueued and thus will delay turning on the screen light
1913 // until the windows are correctly displayed.
1914 if (stateChanged) {
1915 updateLightsLocked(newState, 0);
1916 }
1917 mPowerState |= SCREEN_ON_BIT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001918 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001919
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001920 } else {
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001921 // Update the lights *before* taking care of turning the
1922 // screen off, so we can initiate any animations that are desired.
Craig Mautner44bf70f2012-03-13 11:38:38 -07001923 mScreenOffReason = reason;
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001924 if (stateChanged) {
1925 updateLightsLocked(newState, 0);
1926 }
1927
Mike Lockwood497087e32009-11-08 18:33:03 -05001928 // cancel light sensor task
1929 mHandler.removeCallbacks(mAutoBrightnessTask);
Jim Rodovichd102fea2010-09-02 12:30:49 -05001930 mLightSensorPendingDecrease = false;
1931 mLightSensorPendingIncrease = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001932 mScreenOffTime = SystemClock.elapsedRealtime();
1933 long identity = Binder.clearCallingIdentity();
1934 try {
1935 mBatteryStats.noteScreenOff();
1936 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001937 Slog.w(TAG, "RemoteException calling noteScreenOff on BatteryStatsService", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001938 } finally {
1939 Binder.restoreCallingIdentity(identity);
1940 }
1941 mPowerState &= ~SCREEN_ON_BIT;
Jim Miller92e66dd2012-02-21 18:57:12 -08001942 if (!mScreenBrightnessAnimator.isAnimating()) {
Mike Lockwood435eb642009-12-03 08:40:18 -05001943 err = screenOffFinishedAnimatingLocked(reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001944 } else {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001945 err = 0;
1946 mLastTouchDown = 0;
1947 }
1948 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001949 } else if (stateChanged) {
1950 // Screen on/off didn't change, but lights may have.
1951 updateLightsLocked(newState, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001952 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001953
1954 mPowerState = (mPowerState & ~LIGHTS_MASK) | (newState & LIGHTS_MASK);
1955
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001956 updateNativePowerStateLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001957 }
1958 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001959
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001960 private void updateNativePowerStateLocked() {
Mike Lockwood3a74bd32011-08-12 13:55:22 -07001961 if (!mHeadless) {
1962 nativeSetPowerState(
1963 (mPowerState & SCREEN_ON_BIT) != 0,
1964 (mPowerState & SCREEN_BRIGHT) == SCREEN_BRIGHT);
1965 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001966 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001967
Mike Lockwood435eb642009-12-03 08:40:18 -05001968 private int screenOffFinishedAnimatingLocked(int reason) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001969 // I don't think we need to check the current state here because all of these
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001970 // Power.setScreenState and sendNotificationLocked can both handle being
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001971 // called multiple times in the same state. -joeo
Joe Onoratob08a1af2010-10-11 19:28:58 -07001972 EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, reason, mTotalTouchDownTime,
1973 mTouchCycles);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001974 mLastTouchDown = 0;
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001975 int err = setScreenStateLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001976 if (err == 0) {
Mike Lockwood435eb642009-12-03 08:40:18 -05001977 mScreenOffReason = reason;
1978 sendNotificationLocked(false, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001979 }
1980 return err;
1981 }
1982
1983 private boolean batteryIsLow() {
1984 return (!mIsPowered &&
Jeff Brown7304c342012-05-11 18:42:42 -07001985 mBatteryService.getBatteryLevel() <= LOW_BATTERY_THRESHOLD);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001986 }
1987
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001988 private boolean shouldDeferScreenOnLocked() {
1989 if (mPreparingForScreenOn) {
1990 // Currently waiting for confirmation from the policy that it
1991 // is okay to turn on the screen. Don't allow the screen to go
1992 // on until that is done.
1993 if (DEBUG_SCREEN_ON) Slog.i(TAG,
1994 "updateLights: delaying screen on due to mPreparingForScreenOn");
1995 return true;
1996 } else {
1997 // If there is a screen-on command in the notification queue, we
1998 // can't turn the screen on until it has been processed (and we
1999 // have set mPreparingForScreenOn) or it has been dropped.
2000 for (int i=0; i<mBroadcastQueue.length; i++) {
2001 if (mBroadcastQueue[i] == 1) {
2002 if (DEBUG_SCREEN_ON) Slog.i(TAG,
2003 "updateLights: delaying screen on due to notification queue");
2004 return true;
2005 }
2006 }
2007 }
2008 return false;
2009 }
2010
The Android Open Source Project10592532009-03-18 17:39:46 -07002011 private void updateLightsLocked(int newState, int forceState) {
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07002012 final int oldState = mPowerState;
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07002013
2014 // If the screen is not currently on, we will want to delay actually
2015 // turning the lights on if we are still getting the UI put up.
Jim Miller92e66dd2012-02-21 18:57:12 -08002016 if ((oldState & SCREEN_ON_BIT) == 0 || mSkippedScreenOn) {
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07002017 // Don't turn screen on until we know we are really ready to.
2018 // This is to avoid letting the screen go on before things like the
2019 // lock screen have been displayed.
Jim Miller92e66dd2012-02-21 18:57:12 -08002020 if ((mSkippedScreenOn = shouldDeferScreenOnLocked())) {
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07002021 newState &= ~(SCREEN_ON_BIT|SCREEN_BRIGHT_BIT);
2022 }
2023 }
2024
Joe Onorato60607a902010-10-23 14:49:30 -07002025 if ((newState & SCREEN_ON_BIT) != 0) {
2026 // Only turn on the buttons or keyboard if the screen is also on.
2027 // We should never see the buttons on but not the screen.
2028 newState = applyButtonState(newState);
2029 newState = applyKeyboardState(newState);
2030 }
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07002031 final int realDifference = (newState ^ oldState);
2032 final int difference = realDifference | forceState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002033 if (difference == 0) {
The Android Open Source Project10592532009-03-18 17:39:46 -07002034 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002035 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002036
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002037 int offMask = 0;
2038 int dimMask = 0;
2039 int onMask = 0;
2040
2041 int preferredBrightness = getPreferredBrightness();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002042
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002043 if ((difference & KEYBOARD_BRIGHT_BIT) != 0) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002044 if ((newState & KEYBOARD_BRIGHT_BIT) == 0) {
2045 offMask |= KEYBOARD_BRIGHT_BIT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002046 } else {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002047 onMask |= KEYBOARD_BRIGHT_BIT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002048 }
2049 }
2050
2051 if ((difference & BUTTON_BRIGHT_BIT) != 0) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002052 if ((newState & BUTTON_BRIGHT_BIT) == 0) {
2053 offMask |= BUTTON_BRIGHT_BIT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002054 } else {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002055 onMask |= BUTTON_BRIGHT_BIT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002056 }
2057 }
2058
2059 if ((difference & (SCREEN_ON_BIT | SCREEN_BRIGHT_BIT)) != 0) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002060 int nominalCurrentValue = -1;
2061 // If there was an actual difference in the light state, then
2062 // figure out the "ideal" current value based on the previous
2063 // state. Otherwise, this is a change due to the brightness
2064 // override, so we want to animate from whatever the current
2065 // value is.
2066 if ((realDifference & (SCREEN_ON_BIT | SCREEN_BRIGHT_BIT)) != 0) {
2067 switch (oldState & (SCREEN_BRIGHT_BIT|SCREEN_ON_BIT)) {
2068 case SCREEN_BRIGHT_BIT | SCREEN_ON_BIT:
2069 nominalCurrentValue = preferredBrightness;
2070 break;
2071 case SCREEN_ON_BIT:
Mike Lockwoodeb6456b2011-09-13 15:24:02 -04002072 nominalCurrentValue = mScreenBrightnessDim;
Joe Onoratob08a1af2010-10-11 19:28:58 -07002073 break;
2074 case 0:
Jeff Brown7304c342012-05-11 18:42:42 -07002075 nominalCurrentValue = PowerManager.BRIGHTNESS_OFF;
Joe Onoratob08a1af2010-10-11 19:28:58 -07002076 break;
2077 case SCREEN_BRIGHT_BIT:
2078 default:
2079 // not possible
Jim Miller92e66dd2012-02-21 18:57:12 -08002080 nominalCurrentValue = (int)mScreenBrightnessAnimator.getCurrentBrightness();
Joe Onoratob08a1af2010-10-11 19:28:58 -07002081 break;
Joe Onorato128e7292009-03-24 18:41:31 -07002082 }
Joe Onoratob08a1af2010-10-11 19:28:58 -07002083 }
2084 int brightness = preferredBrightness;
2085 int steps = ANIM_STEPS;
2086 if ((newState & SCREEN_BRIGHT_BIT) == 0) {
2087 // dim or turn off backlight, depending on if the screen is on
2088 // the scale is because the brightness ramp isn't linear and this biases
2089 // it so the later parts take longer.
2090 final float scale = 1.5f;
Mike Lockwoodeb6456b2011-09-13 15:24:02 -04002091 float ratio = (((float)mScreenBrightnessDim)/preferredBrightness);
Joe Onoratob08a1af2010-10-11 19:28:58 -07002092 if (ratio > 1.0f) ratio = 1.0f;
2093 if ((newState & SCREEN_ON_BIT) == 0) {
2094 if ((oldState & SCREEN_BRIGHT_BIT) != 0) {
2095 // was bright
2096 steps = ANIM_STEPS;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002097 } else {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002098 // was dim
2099 steps = (int)(ANIM_STEPS*ratio*scale);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002100 }
Jeff Brown7304c342012-05-11 18:42:42 -07002101 brightness = PowerManager.BRIGHTNESS_OFF;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002102 } else {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002103 if ((oldState & SCREEN_ON_BIT) != 0) {
2104 // was bright
2105 steps = (int)(ANIM_STEPS*(1.0f-ratio)*scale);
2106 } else {
2107 // was dim
2108 steps = (int)(ANIM_STEPS*ratio);
2109 }
Dianne Hackborn2fe8fb22012-06-15 17:05:25 -07002110 final int stayOnConditions = getStayOnConditionsLocked();
2111 if (stayOnConditions != 0 && mBatteryService.isPowered(stayOnConditions)) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002112 // If the "stay on while plugged in" option is
2113 // turned on, then the screen will often not
2114 // automatically turn off while plugged in. To
2115 // still have a sense of when it is inactive, we
2116 // will then count going dim as turning off.
2117 mScreenOffTime = SystemClock.elapsedRealtime();
2118 }
Mike Lockwoodeb6456b2011-09-13 15:24:02 -04002119 brightness = mScreenBrightnessDim;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002120 }
2121 }
Craig Mautner75fc9de2012-06-18 16:53:27 -07002122 if (mWaitingForFirstLightSensor && (newState & SCREEN_ON_BIT) != 0) {
2123 steps = IMMEDIATE_ANIM_STEPS;
2124 }
2125
Joe Onoratob08a1af2010-10-11 19:28:58 -07002126 long identity = Binder.clearCallingIdentity();
2127 try {
2128 mBatteryStats.noteScreenBrightness(brightness);
2129 } catch (RemoteException e) {
2130 // Nothing interesting to do.
2131 } finally {
2132 Binder.restoreCallingIdentity(identity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002133 }
Dianne Hackborn81de8b92011-11-28 16:54:31 -08002134 if (!mSkippedScreenOn) {
Jim Miller92e66dd2012-02-21 18:57:12 -08002135 int dt = steps * NOMINAL_FRAME_TIME_MS;
2136 mScreenBrightnessAnimator.animateTo(brightness, SCREEN_BRIGHT_BIT, dt);
Dianne Hackborn81de8b92011-11-28 16:54:31 -08002137 if (DEBUG_SCREEN_ON) {
2138 RuntimeException e = new RuntimeException("here");
2139 e.fillInStackTrace();
2140 Slog.i(TAG, "Setting screen brightness: " + brightness, e);
2141 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07002142 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002143 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002144
Joe Onorato60607a902010-10-23 14:49:30 -07002145 if (mSpew) {
2146 Slog.d(TAG, "offMask=0x" + Integer.toHexString(offMask)
2147 + " dimMask=0x" + Integer.toHexString(dimMask)
2148 + " onMask=0x" + Integer.toHexString(onMask)
2149 + " difference=0x" + Integer.toHexString(difference)
2150 + " realDifference=0x" + Integer.toHexString(realDifference)
2151 + " forceState=0x" + Integer.toHexString(forceState)
2152 );
2153 }
2154
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002155 if (offMask != 0) {
Mike Lockwood48358bd2010-04-17 22:29:20 -04002156 if (mSpew) Slog.i(TAG, "Setting brightess off: " + offMask);
Jeff Brown7304c342012-05-11 18:42:42 -07002157 setLightBrightness(offMask, PowerManager.BRIGHTNESS_OFF);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002158 }
2159 if (dimMask != 0) {
Mike Lockwoodeb6456b2011-09-13 15:24:02 -04002160 int brightness = mScreenBrightnessDim;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002161 if ((newState & BATTERY_LOW_BIT) != 0 &&
Jeff Brown7304c342012-05-11 18:42:42 -07002162 brightness > PowerManager.BRIGHTNESS_LOW_BATTERY) {
2163 brightness = PowerManager.BRIGHTNESS_LOW_BATTERY;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002164 }
Mike Lockwood48358bd2010-04-17 22:29:20 -04002165 if (mSpew) Slog.i(TAG, "Setting brightess dim " + brightness + ": " + dimMask);
The Android Open Source Project10592532009-03-18 17:39:46 -07002166 setLightBrightness(dimMask, brightness);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002167 }
2168 if (onMask != 0) {
2169 int brightness = getPreferredBrightness();
2170 if ((newState & BATTERY_LOW_BIT) != 0 &&
Jeff Brown7304c342012-05-11 18:42:42 -07002171 brightness > PowerManager.BRIGHTNESS_LOW_BATTERY) {
2172 brightness = PowerManager.BRIGHTNESS_LOW_BATTERY;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002173 }
Mike Lockwood48358bd2010-04-17 22:29:20 -04002174 if (mSpew) Slog.i(TAG, "Setting brightess on " + brightness + ": " + onMask);
The Android Open Source Project10592532009-03-18 17:39:46 -07002175 setLightBrightness(onMask, brightness);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002176 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002177 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002178
Jim Miller92e66dd2012-02-21 18:57:12 -08002179 /**
2180 * Note: by design this class does not hold mLocks while calling native methods.
2181 * Nor should it. Ever.
2182 */
2183 class ScreenBrightnessAnimator extends HandlerThread {
2184 static final int ANIMATE_LIGHTS = 10;
Jim Miller46f31c32012-03-01 14:36:07 -08002185 static final int ANIMATE_POWER_OFF = 11;
Jim Miller92e66dd2012-02-21 18:57:12 -08002186 volatile int startValue;
2187 volatile int endValue;
Craig Mautner196943f2012-05-15 08:10:35 -07002188 volatile int startSensorValue;
2189 volatile int endSensorValue;
Jim Miller92e66dd2012-02-21 18:57:12 -08002190 volatile int currentValue;
2191 private int currentMask;
2192 private int duration;
2193 private long startTimeMillis;
2194 private final String prefix;
2195
2196 public ScreenBrightnessAnimator(String name, int priority) {
2197 super(name, priority);
2198 prefix = name;
2199 }
2200
2201 @Override
2202 protected void onLooperPrepared() {
2203 mScreenBrightnessHandler = new Handler() {
2204 public void handleMessage(Message msg) {
2205 int brightnessMode = (mAutoBrightessEnabled && !mInitialAnimation
Mike Lockwood3a322132009-11-24 00:30:52 -05002206 ? LightsService.BRIGHTNESS_MODE_SENSOR
2207 : LightsService.BRIGHTNESS_MODE_USER);
Jim Miller92e66dd2012-02-21 18:57:12 -08002208 if (msg.what == ANIMATE_LIGHTS) {
2209 final int mask = msg.arg1;
2210 int value = msg.arg2;
2211 long tStart = SystemClock.uptimeMillis();
2212 if ((mask & SCREEN_BRIGHT_BIT) != 0) {
Craig Mautner196943f2012-05-15 08:10:35 -07002213 if (mDebugLightAnimation) Slog.v(TAG, "Set brightness: " + value);
Jim Miller92e66dd2012-02-21 18:57:12 -08002214 mLcdLight.setBrightness(value, brightnessMode);
2215 }
2216 long elapsed = SystemClock.uptimeMillis() - tStart;
2217 if ((mask & BUTTON_BRIGHT_BIT) != 0) {
2218 mButtonLight.setBrightness(value);
2219 }
2220 if ((mask & KEYBOARD_BRIGHT_BIT) != 0) {
2221 mKeyboardLight.setBrightness(value);
2222 }
2223
2224 if (elapsed > 100) {
Craig Mautner196943f2012-05-15 08:10:35 -07002225 Slog.e(TAG, "Excessive delay setting brightness: " + elapsed
Jim Miller92e66dd2012-02-21 18:57:12 -08002226 + "ms, mask=" + mask);
2227 }
2228
2229 // Throttle brightness updates to frame refresh rate
Craig Mautner196943f2012-05-15 08:10:35 -07002230 int delay = elapsed < NOMINAL_FRAME_TIME_MS ? NOMINAL_FRAME_TIME_MS : 1;
Jim Miller92e66dd2012-02-21 18:57:12 -08002231 synchronized(this) {
2232 currentValue = value;
2233 }
2234 animateInternal(mask, false, delay);
Jim Miller46f31c32012-03-01 14:36:07 -08002235 } else if (msg.what == ANIMATE_POWER_OFF) {
2236 int mode = msg.arg1;
2237 nativeStartSurfaceFlingerAnimation(mode);
Jim Miller92e66dd2012-02-21 18:57:12 -08002238 }
2239 }
2240 };
2241 synchronized (this) {
2242 mInitComplete = true;
2243 notifyAll();
Dianne Hackborn81de8b92011-11-28 16:54:31 -08002244 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002245 }
Jim Miller92e66dd2012-02-21 18:57:12 -08002246
2247 private void animateInternal(int mask, boolean turningOff, int delay) {
2248 synchronized (this) {
2249 if (currentValue != endValue) {
2250 final long now = SystemClock.elapsedRealtime();
2251 final int elapsed = (int) (now - startTimeMillis);
2252 int newValue;
2253 if (elapsed < duration) {
2254 int delta = endValue - startValue;
2255 newValue = startValue + delta * elapsed / duration;
Jeff Brown7304c342012-05-11 18:42:42 -07002256 newValue = Math.max(PowerManager.BRIGHTNESS_OFF, newValue);
2257 newValue = Math.min(PowerManager.BRIGHTNESS_ON, newValue);
Craig Mautner196943f2012-05-15 08:10:35 -07002258 // Optimization to delay next step until a change will occur.
2259 if (delay > 0 && newValue == currentValue) {
2260 final int timePerStep = duration / Math.abs(delta);
2261 delay = Math.min(duration - elapsed, timePerStep);
2262 newValue += delta < 0 ? -1 : 1;
2263 }
2264 // adjust the peak sensor value until we get to the target sensor value
2265 delta = endSensorValue - startSensorValue;
2266 mHighestLightSensorValue = startSensorValue + delta * elapsed / duration;
Jim Miller92e66dd2012-02-21 18:57:12 -08002267 } else {
2268 newValue = endValue;
Craig Mautner196943f2012-05-15 08:10:35 -07002269 mHighestLightSensorValue = endSensorValue;
Craig Mautneraf01fe02012-05-31 10:03:32 -07002270 if (endValue > 0) {
2271 mInitialAnimation = false;
2272 }
Jim Miller92e66dd2012-02-21 18:57:12 -08002273 }
2274
2275 if (mDebugLightAnimation) {
Craig Mautner196943f2012-05-15 08:10:35 -07002276 Slog.v(TAG, "Animating light: " + "start:" + startValue
Jim Miller92e66dd2012-02-21 18:57:12 -08002277 + ", end:" + endValue + ", elapsed:" + elapsed
2278 + ", duration:" + duration + ", current:" + currentValue
Craig Mautner196943f2012-05-15 08:10:35 -07002279 + ", newValue:" + newValue
2280 + ", delay:" + delay
2281 + ", highestSensor:" + mHighestLightSensorValue);
Jim Miller92e66dd2012-02-21 18:57:12 -08002282 }
2283
Jim Miller46f31c32012-03-01 14:36:07 -08002284 if (turningOff && !mHeadless && !mAnimateScreenLights) {
Jim Miller92e66dd2012-02-21 18:57:12 -08002285 int mode = mScreenOffReason == OFF_BECAUSE_OF_PROX_SENSOR
2286 ? 0 : mAnimationSetting;
Craig Mautner196943f2012-05-15 08:10:35 -07002287 if (mDebugLightAnimation) {
2288 Slog.v(TAG, "Doing power-off anim, mode=" + mode);
2289 }
Jim Miller46f31c32012-03-01 14:36:07 -08002290 mScreenBrightnessHandler.obtainMessage(ANIMATE_POWER_OFF, mode, 0)
2291 .sendToTarget();
Jim Miller92e66dd2012-02-21 18:57:12 -08002292 }
Craig Mautner196943f2012-05-15 08:10:35 -07002293 mScreenBrightnessHandler.removeMessages(
2294 ScreenBrightnessAnimator.ANIMATE_LIGHTS);
Jim Miller92e66dd2012-02-21 18:57:12 -08002295 Message msg = mScreenBrightnessHandler
2296 .obtainMessage(ANIMATE_LIGHTS, mask, newValue);
2297 mScreenBrightnessHandler.sendMessageDelayed(msg, delay);
2298 }
2299 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002300 }
Jim Miller92e66dd2012-02-21 18:57:12 -08002301
2302 public void dump(PrintWriter pw, String string) {
Craig Mautner291576e2012-06-07 19:58:58 -07002303 pw.println(string);
2304 pw.println(" animating: " + "start:" + startValue + ", end:" + endValue
Jim Miller92e66dd2012-02-21 18:57:12 -08002305 + ", duration:" + duration + ", current:" + currentValue);
Craig Mautner291576e2012-06-07 19:58:58 -07002306 pw.println(" startSensorValue:" + startSensorValue
2307 + " endSensorValue:" + endSensorValue);
Craig Mautner672083b2012-06-26 11:49:08 -07002308 pw.println(" startTimeMillis:" + startTimeMillis
2309 + " now:" + SystemClock.elapsedRealtime());
2310 pw.println(" currentMask:" + dumpPowerState(currentMask));
Jim Miller92e66dd2012-02-21 18:57:12 -08002311 }
2312
2313 public void animateTo(int target, int mask, int animationDuration) {
Craig Mautner196943f2012-05-15 08:10:35 -07002314 animateTo(target, mHighestLightSensorValue, mask, animationDuration);
2315 }
2316
2317 public void animateTo(int target, int sensorTarget, int mask, int animationDuration) {
Jim Miller92e66dd2012-02-21 18:57:12 -08002318 synchronized(this) {
Craig Mautner291576e2012-06-07 19:58:58 -07002319 if ((mask & SCREEN_BRIGHT_BIT) == 0) {
2320 // We only animate keyboard and button when passed in with SCREEN_BRIGHT_BIT.
2321 if ((mask & BUTTON_BRIGHT_BIT) != 0) {
2322 mButtonLight.setBrightness(target);
2323 }
2324 if ((mask & KEYBOARD_BRIGHT_BIT) != 0) {
2325 mKeyboardLight.setBrightness(target);
2326 }
2327 return;
2328 }
Craig Mautnerd29568c2012-06-01 16:02:47 -07002329 if (isAnimating() && (mask ^ currentMask) != 0) {
2330 // current animation is unrelated to new animation, jump to final values
2331 cancelAnimation();
2332 }
Jeff Brown8e306a62012-06-20 19:20:57 -07002333 if (mInitialAnimation) {
2334 // jump to final value in one step the first time the brightness is set
2335 animationDuration = 0;
2336 if (target > 0) {
2337 mInitialAnimation = false;
2338 }
2339 }
Jim Miller92e66dd2012-02-21 18:57:12 -08002340 startValue = currentValue;
2341 endValue = target;
Craig Mautner196943f2012-05-15 08:10:35 -07002342 startSensorValue = mHighestLightSensorValue;
2343 endSensorValue = sensorTarget;
Jim Miller92e66dd2012-02-21 18:57:12 -08002344 currentMask = mask;
2345 duration = (int) (mWindowScaleAnimation * animationDuration);
2346 startTimeMillis = SystemClock.elapsedRealtime();
Jim Miller92e66dd2012-02-21 18:57:12 -08002347
2348 if (mDebugLightAnimation) {
Craig Mautner196943f2012-05-15 08:10:35 -07002349 Slog.v(TAG, "animateTo(target=" + target
2350 + ", sensor=" + sensorTarget
2351 + ", mask=" + mask
Jim Miller92e66dd2012-02-21 18:57:12 -08002352 + ", duration=" + animationDuration +")"
2353 + ", currentValue=" + currentValue
2354 + ", startTime=" + startTimeMillis);
2355 }
2356
2357 if (target != currentValue) {
Jim Miller18651802012-03-07 14:19:56 -08002358 final boolean doScreenAnim = (mask & (SCREEN_BRIGHT_BIT | SCREEN_ON_BIT)) != 0;
Jeff Brown7304c342012-05-11 18:42:42 -07002359 final boolean turningOff = endValue == PowerManager.BRIGHTNESS_OFF;
Jim Miller18651802012-03-07 14:19:56 -08002360 if (turningOff && doScreenAnim) {
Jim Miller92e66dd2012-02-21 18:57:12 -08002361 // Cancel all pending animations since we're turning off
2362 mScreenBrightnessHandler.removeCallbacksAndMessages(null);
2363 screenOffFinishedAnimatingLocked(mScreenOffReason);
2364 duration = 200; // TODO: how long should this be?
2365 }
Jim Miller18651802012-03-07 14:19:56 -08002366 if (doScreenAnim) {
2367 animateInternal(mask, turningOff, 0);
2368 }
2369 // TODO: Handle keyboard light animation when we have devices that support it
Jim Miller92e66dd2012-02-21 18:57:12 -08002370 }
2371 }
2372 }
2373
2374 public int getCurrentBrightness() {
2375 synchronized (this) {
2376 return currentValue;
2377 }
2378 }
2379
2380 public boolean isAnimating() {
2381 synchronized (this) {
2382 return currentValue != endValue;
2383 }
2384 }
2385
2386 public void cancelAnimation() {
2387 animateTo(endValue, currentMask, 0);
The Android Open Source Project10592532009-03-18 17:39:46 -07002388 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002389 }
2390
Jim Miller92e66dd2012-02-21 18:57:12 -08002391 private void setLightBrightness(int mask, int value) {
2392 mScreenBrightnessAnimator.animateTo(value, mask, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002393 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002394
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002395 private int getPreferredBrightness() {
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002396 if (mScreenBrightnessOverride >= 0) {
2397 return mScreenBrightnessOverride;
2398 } else if (mLightSensorScreenBrightness >= 0 && mUseSoftwareAutoBrightness
2399 && mAutoBrightessEnabled) {
2400 return mLightSensorScreenBrightness;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002401 }
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002402 final int brightness = mScreenBrightnessSetting;
2403 // Don't let applications turn the screen all the way off
2404 return Math.max(brightness, mScreenBrightnessDim);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002405 }
2406
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002407 private int applyButtonState(int state) {
2408 int brightness = -1;
Mike Lockwood48358bd2010-04-17 22:29:20 -04002409 if ((state & BATTERY_LOW_BIT) != 0) {
2410 // do not override brightness if the battery is low
2411 return state;
2412 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002413 if (mButtonBrightnessOverride >= 0) {
2414 brightness = mButtonBrightnessOverride;
2415 } else if (mLightSensorButtonBrightness >= 0 && mUseSoftwareAutoBrightness) {
2416 brightness = mLightSensorButtonBrightness;
2417 }
2418 if (brightness > 0) {
2419 return state | BUTTON_BRIGHT_BIT;
2420 } else if (brightness == 0) {
2421 return state & ~BUTTON_BRIGHT_BIT;
2422 } else {
2423 return state;
2424 }
2425 }
2426
2427 private int applyKeyboardState(int state) {
2428 int brightness = -1;
Mike Lockwood48358bd2010-04-17 22:29:20 -04002429 if ((state & BATTERY_LOW_BIT) != 0) {
2430 // do not override brightness if the battery is low
2431 return state;
2432 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002433 if (!mKeyboardVisible) {
2434 brightness = 0;
2435 } else if (mButtonBrightnessOverride >= 0) {
2436 brightness = mButtonBrightnessOverride;
2437 } else if (mLightSensorKeyboardBrightness >= 0 && mUseSoftwareAutoBrightness) {
2438 brightness = mLightSensorKeyboardBrightness;
2439 }
2440 if (brightness > 0) {
2441 return state | KEYBOARD_BRIGHT_BIT;
2442 } else if (brightness == 0) {
2443 return state & ~KEYBOARD_BRIGHT_BIT;
2444 } else {
2445 return state;
2446 }
2447 }
2448
Charles Mendis322591c2009-10-29 11:06:59 -07002449 public boolean isScreenOn() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002450 synchronized (mLocks) {
2451 return (mPowerState & SCREEN_ON_BIT) != 0;
2452 }
2453 }
2454
Charles Mendis322591c2009-10-29 11:06:59 -07002455 boolean isScreenBright() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002456 synchronized (mLocks) {
2457 return (mPowerState & SCREEN_BRIGHT) == SCREEN_BRIGHT;
2458 }
2459 }
2460
Mike Lockwood497087e32009-11-08 18:33:03 -05002461 private boolean isScreenTurningOffLocked() {
Jim Miller92e66dd2012-02-21 18:57:12 -08002462 return (mScreenBrightnessAnimator.isAnimating()
Craig Mautnerd29568c2012-06-01 16:02:47 -07002463 && mScreenBrightnessAnimator.endValue == PowerManager.BRIGHTNESS_OFF
2464 && (mScreenBrightnessAnimator.currentMask & SCREEN_BRIGHT_BIT) != 0);
Mike Lockwood497087e32009-11-08 18:33:03 -05002465 }
2466
Joe Onorato4b9f62d2010-10-11 13:41:35 -07002467 private boolean shouldLog(long time) {
2468 synchronized (mLocks) {
2469 if (time > (mWarningSpewThrottleTime + (60*60*1000))) {
2470 mWarningSpewThrottleTime = time;
2471 mWarningSpewThrottleCount = 0;
2472 return true;
2473 } else if (mWarningSpewThrottleCount < 30) {
2474 mWarningSpewThrottleCount++;
2475 return true;
2476 } else {
2477 return false;
2478 }
2479 }
2480 }
2481
Mike Lockwood200b30b2009-09-20 00:23:59 -04002482 private void forceUserActivityLocked() {
Mike Lockwoode090281422009-11-14 21:02:56 -05002483 if (isScreenTurningOffLocked()) {
2484 // cancel animation so userActivity will succeed
Jim Miller92e66dd2012-02-21 18:57:12 -08002485 mScreenBrightnessAnimator.cancelAnimation();
Mike Lockwoode090281422009-11-14 21:02:56 -05002486 }
Mike Lockwood200b30b2009-09-20 00:23:59 -04002487 boolean savedActivityAllowed = mUserActivityAllowed;
2488 mUserActivityAllowed = true;
2489 userActivity(SystemClock.uptimeMillis(), false);
2490 mUserActivityAllowed = savedActivityAllowed;
2491 }
2492
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002493 public void userActivityWithForce(long time, boolean noChangeLights, boolean force) {
2494 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
Dianne Hackbornea401542012-06-26 14:34:54 -07002495 userActivity(time, -1, noChangeLights, OTHER_EVENT, force, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002496 }
2497
2498 public void userActivity(long time, boolean noChangeLights) {
Joe Onorato4b9f62d2010-10-11 13:41:35 -07002499 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER)
2500 != PackageManager.PERMISSION_GRANTED) {
2501 if (shouldLog(time)) {
2502 Slog.w(TAG, "Caller does not have DEVICE_POWER permission. pid="
2503 + Binder.getCallingPid() + " uid=" + Binder.getCallingUid());
2504 }
2505 return;
2506 }
2507
Dianne Hackbornea401542012-06-26 14:34:54 -07002508 userActivity(time, -1, noChangeLights, OTHER_EVENT, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002509 }
2510
2511 public void userActivity(long time, boolean noChangeLights, int eventType) {
Dianne Hackbornea401542012-06-26 14:34:54 -07002512 userActivity(time, -1, noChangeLights, eventType, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002513 }
2514
2515 public void userActivity(long time, boolean noChangeLights, int eventType, boolean force) {
Dianne Hackbornea401542012-06-26 14:34:54 -07002516 userActivity(time, -1, noChangeLights, eventType, force, false);
Joe Onorato7999bff2010-07-24 11:50:05 -04002517 }
2518
2519 /*
2520 * Reset the user activity timeout to now + timeout. This overrides whatever else is going
2521 * on with user activity. Don't use this function.
2522 */
2523 public void clearUserActivityTimeout(long now, long timeout) {
2524 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
2525 Slog.i(TAG, "clearUserActivity for " + timeout + "ms from now");
Dianne Hackbornea401542012-06-26 14:34:54 -07002526 userActivity(now, timeout, false, OTHER_EVENT, false, false);
Joe Onorato7999bff2010-07-24 11:50:05 -04002527 }
2528
2529 private void userActivity(long time, long timeoutOverride, boolean noChangeLights,
Dianne Hackbornea401542012-06-26 14:34:54 -07002530 int eventType, boolean force, boolean ignoreIfScreenOff) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002531
Joe Onorato1a542c72010-11-08 09:48:20 -08002532 if (((mPokey & POKE_LOCK_IGNORE_TOUCH_EVENTS) != 0) && (eventType == TOUCH_EVENT)) {
Joe Onoratoe68ffcb2009-03-24 19:11:13 -07002533 if (false) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002534 Slog.d(TAG, "dropping touch mPokey=0x" + Integer.toHexString(mPokey));
Joe Onoratoe68ffcb2009-03-24 19:11:13 -07002535 }
2536 return;
2537 }
2538
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002539 synchronized (mLocks) {
2540 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002541 Slog.d(TAG, "userActivity mLastEventTime=" + mLastEventTime + " time=" + time
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002542 + " mUserActivityAllowed=" + mUserActivityAllowed
2543 + " mUserState=0x" + Integer.toHexString(mUserState)
Mike Lockwood36fc3022009-08-25 16:49:06 -07002544 + " mWakeLockState=0x" + Integer.toHexString(mWakeLockState)
2545 + " mProximitySensorActive=" + mProximitySensorActive
Joe Onorato797e6882010-08-26 14:46:01 -04002546 + " timeoutOverride=" + timeoutOverride
Mike Lockwood36fc3022009-08-25 16:49:06 -07002547 + " force=" + force);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002548 }
Mike Lockwood05067122009-10-27 23:07:25 -04002549 // ignore user activity if we are in the process of turning off the screen
Mike Lockwood497087e32009-11-08 18:33:03 -05002550 if (isScreenTurningOffLocked()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002551 Slog.d(TAG, "ignoring user activity while turning off screen");
Mike Lockwood05067122009-10-27 23:07:25 -04002552 return;
2553 }
Dianne Hackbornea401542012-06-26 14:34:54 -07002554 // ignore if the caller doesn't want this to allow the screen to turn
2555 // on, and the screen is currently off.
2556 if (ignoreIfScreenOff && (mPowerState & SCREEN_ON_BIT) == 0) {
2557 return;
2558 }
Mike Lockwood0e39ea82009-11-18 15:37:10 -05002559 // Disable proximity sensor if if user presses power key while we are in the
2560 // "waiting for proximity sensor to go negative" state.
2561 if (mProximitySensorActive && mProximityWakeLockCount == 0) {
2562 mProximitySensorActive = false;
2563 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002564 if (mLastEventTime <= time || force) {
2565 mLastEventTime = time;
Mike Lockwood36fc3022009-08-25 16:49:06 -07002566 if ((mUserActivityAllowed && !mProximitySensorActive) || force) {
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002567 // Only turn on button backlights if a button was pressed
2568 // and auto brightness is disabled
Mike Lockwood4984e732009-11-01 08:16:33 -05002569 if (eventType == BUTTON_EVENT && !mUseSoftwareAutoBrightness) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002570 mUserState = (mKeyboardVisible ? ALL_BRIGHT : SCREEN_BUTTON_BRIGHT);
2571 } else {
2572 // don't clear button/keyboard backlights when the screen is touched.
2573 mUserState |= SCREEN_BRIGHT;
2574 }
2575
Dianne Hackborn617f8772009-03-31 15:04:46 -07002576 int uid = Binder.getCallingUid();
2577 long ident = Binder.clearCallingIdentity();
2578 try {
2579 mBatteryStats.noteUserActivity(uid, eventType);
2580 } catch (RemoteException e) {
2581 // Ignore
2582 } finally {
2583 Binder.restoreCallingIdentity(ident);
2584 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002585
Michael Chane96440f2009-05-06 10:27:36 -07002586 mWakeLockState = mLocks.reactivateScreenLocksLocked();
Mike Lockwood435eb642009-12-03 08:40:18 -05002587 setPowerState(mUserState | mWakeLockState, noChangeLights,
2588 WindowManagerPolicy.OFF_BECAUSE_OF_USER);
Joe Onorato7999bff2010-07-24 11:50:05 -04002589 setTimeoutLocked(time, timeoutOverride, SCREEN_BRIGHT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002590 }
2591 }
2592 }
Mike Lockwoodef731622010-01-27 17:51:34 -05002593
2594 if (mPolicy != null) {
2595 mPolicy.userActivity();
2596 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002597 }
2598
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002599 private int getAutoBrightnessValue(int sensorValue, int[] values) {
2600 try {
2601 int i;
2602 for (i = 0; i < mAutoBrightnessLevels.length; i++) {
2603 if (sensorValue < mAutoBrightnessLevels[i]) {
2604 break;
2605 }
2606 }
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002607 // This is the range of brightness values that we can use.
2608 final int minval = values[0];
2609 final int maxval = values[mAutoBrightnessLevels.length];
2610 // This is the range we will be scaling. We put some padding
2611 // at the low and high end to give the adjustment a little better
2612 // impact on the actual observed value.
2613 final int range = (maxval-minval) + LIGHT_SENSOR_RANGE_EXPANSION;
2614 // This is the desired brightness value from 0.0 to 1.0.
2615 float valf = ((values[i]-minval+(LIGHT_SENSOR_RANGE_EXPANSION/2))/(float)range);
2616 // Apply a scaling to the value based on the adjustment.
2617 if (mLightSensorAdjustSetting > 0 && mLightSensorAdjustSetting <= 1) {
2618 float adj = (float)Math.sqrt(1.0f-mLightSensorAdjustSetting);
2619 if (adj <= .00001) {
2620 valf = 1;
2621 } else {
2622 valf /= adj;
2623 }
2624 } else if (mLightSensorAdjustSetting < 0 && mLightSensorAdjustSetting >= -1) {
2625 float adj = (float)Math.sqrt(1.0f+mLightSensorAdjustSetting);
2626 valf *= adj;
2627 }
2628 // Apply an additional offset to the value based on the adjustment.
2629 valf += mLightSensorAdjustSetting/LIGHT_SENSOR_OFFSET_SCALE;
2630 // Convert the 0.0-1.0 value back to a brightness integer.
2631 int val = (int)((valf*range)+minval) - (LIGHT_SENSOR_RANGE_EXPANSION/2);
2632 if (val < minval) val = minval;
2633 else if (val > maxval) val = maxval;
2634 return val;
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002635 } catch (Exception e) {
2636 // guard against null pointer or index out of bounds errors
Jeff Browndaa37532012-05-01 15:54:03 -07002637 Slog.e(TAG, "Values array must be non-empty and must be one element longer than "
2638 + "the auto-brightness levels array. Check config.xml.", e);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002639 return 255;
2640 }
2641 }
2642
Mike Lockwood20f87d72009-11-05 16:08:51 -05002643 private Runnable mProximityTask = new Runnable() {
2644 public void run() {
2645 synchronized (mLocks) {
2646 if (mProximityPendingValue != -1) {
2647 proximityChangedLocked(mProximityPendingValue == 1);
2648 mProximityPendingValue = -1;
2649 }
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -05002650 if (mProximityPartialLock.isHeld()) {
2651 mProximityPartialLock.release();
2652 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05002653 }
2654 }
2655 };
2656
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002657 private Runnable mAutoBrightnessTask = new Runnable() {
2658 public void run() {
Mike Lockwoodfa68ab42009-10-20 11:08:49 -04002659 synchronized (mLocks) {
Jim Rodovichd102fea2010-09-02 12:30:49 -05002660 if (mLightSensorPendingDecrease || mLightSensorPendingIncrease) {
2661 int value = (int)mLightSensorPendingValue;
2662 mLightSensorPendingDecrease = false;
2663 mLightSensorPendingIncrease = false;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002664 lightSensorChangedLocked(value, false);
Mike Lockwoodfa68ab42009-10-20 11:08:49 -04002665 }
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002666 }
2667 }
2668 };
2669
Craig Mautneraf01fe02012-05-31 10:03:32 -07002670 /** used to prevent lightsensor changes while turning on. */
2671 private boolean mInitialAnimation = true;
Jim Miller92e66dd2012-02-21 18:57:12 -08002672
Mike Lockwoodb2865412010-02-02 22:40:33 -05002673 private void dockStateChanged(int state) {
2674 synchronized (mLocks) {
2675 mIsDocked = (state != Intent.EXTRA_DOCK_STATE_UNDOCKED);
2676 if (mIsDocked) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04002677 // allow brightness to decrease when docked
Mike Lockwoodb2865412010-02-02 22:40:33 -05002678 mHighestLightSensorValue = -1;
2679 }
2680 if ((mPowerState & SCREEN_ON_BIT) != 0) {
2681 // force lights recalculation
2682 int value = (int)mLightSensorValue;
2683 mLightSensorValue = -1;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002684 lightSensorChangedLocked(value, false);
Mike Lockwoodb2865412010-02-02 22:40:33 -05002685 }
2686 }
2687 }
2688
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002689 private void lightSensorChangedLocked(int value, boolean immediate) {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002690 if (mDebugLightSensor) {
Craig Mautner37933682012-06-06 14:13:39 -07002691 Slog.d(TAG, "lightSensorChangedLocked value=" + value + " immediate=" + immediate);
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002692 }
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002693
Joe Onorato06eb33a2010-10-25 14:09:21 -07002694 // Don't do anything if the screen is off.
2695 if ((mPowerState & SCREEN_ON_BIT) == 0) {
2696 if (mDebugLightSensor) {
2697 Slog.d(TAG, "dropping lightSensorChangedLocked because screen is off");
2698 }
2699 return;
2700 }
2701
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002702 if (mLightSensorValue != value) {
2703 mLightSensorValue = value;
2704 if ((mPowerState & BATTERY_LOW_BIT) == 0) {
Mike Lockwoodb2865412010-02-02 22:40:33 -05002705 // use maximum light sensor value seen since screen went on for LCD to avoid flicker
2706 // we only do this if we are undocked, since lighting should be stable when
2707 // stationary in a dock.
Craig Mautner196943f2012-05-15 08:10:35 -07002708 int lcdValue = getAutoBrightnessValue(value, mLcdBacklightValues);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002709 int buttonValue = getAutoBrightnessValue(value, mButtonBacklightValues);
Mike Lockwooddf024922009-10-29 21:29:15 -04002710 int keyboardValue;
2711 if (mKeyboardVisible) {
2712 keyboardValue = getAutoBrightnessValue(value, mKeyboardBacklightValues);
2713 } else {
2714 keyboardValue = 0;
2715 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002716 mLightSensorScreenBrightness = lcdValue;
2717 mLightSensorButtonBrightness = buttonValue;
2718 mLightSensorKeyboardBrightness = keyboardValue;
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002719
2720 if (mDebugLightSensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002721 Slog.d(TAG, "lcdValue " + lcdValue);
2722 Slog.d(TAG, "buttonValue " + buttonValue);
2723 Slog.d(TAG, "keyboardValue " + keyboardValue);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002724 }
2725
Mike Lockwood4984e732009-11-01 08:16:33 -05002726 if (mAutoBrightessEnabled && mScreenBrightnessOverride < 0) {
Jim Miller92e66dd2012-02-21 18:57:12 -08002727 if (!mSkippedScreenOn && !mInitialAnimation) {
Craig Mautner291576e2012-06-07 19:58:58 -07002728 final int steps;
2729 if (immediate) {
2730 steps = IMMEDIATE_ANIM_STEPS;
2731 } else {
2732 synchronized (mScreenBrightnessAnimator) {
2733 if (mScreenBrightnessAnimator.currentValue <= lcdValue) {
2734 steps = AUTOBRIGHTNESS_ANIM_STEPS;
2735 } else {
2736 steps = AUTODIMNESS_ANIM_STEPS;
2737 }
2738 }
2739 }
Craig Mautner196943f2012-05-15 08:10:35 -07002740 mScreenBrightnessAnimator.animateTo(lcdValue, value,
Jim Miller92e66dd2012-02-21 18:57:12 -08002741 SCREEN_BRIGHT_BIT, steps * NOMINAL_FRAME_TIME_MS);
Dianne Hackborn81de8b92011-11-28 16:54:31 -08002742 }
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002743 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002744 if (mButtonBrightnessOverride < 0) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002745 mButtonLight.setBrightness(buttonValue);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002746 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002747 if (mButtonBrightnessOverride < 0 || !mKeyboardVisible) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002748 mKeyboardLight.setBrightness(keyboardValue);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002749 }
2750 }
2751 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002752 }
2753
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002754 /**
2755 * The user requested that we go to sleep (probably with the power button).
2756 * This overrides all wake locks that are held.
2757 */
2758 public void goToSleep(long time)
2759 {
Dianne Hackborn254cb442010-01-27 19:23:59 -08002760 goToSleepWithReason(time, WindowManagerPolicy.OFF_BECAUSE_OF_USER);
2761 }
2762
2763 /**
2764 * The user requested that we go to sleep (probably with the power button).
2765 * This overrides all wake locks that are held.
2766 */
2767 public void goToSleepWithReason(long time, int reason)
2768 {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002769 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
2770 synchronized (mLocks) {
Dianne Hackborn254cb442010-01-27 19:23:59 -08002771 goToSleepLocked(time, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002772 }
2773 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002774
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002775 /**
Doug Zongker50a21f42009-11-19 12:49:53 -08002776 * Reboot the device immediately, passing 'reason' (may be null)
2777 * to the underlying __reboot system call. Should not return.
2778 */
2779 public void reboot(String reason)
2780 {
2781 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
San Mehat14e69af2010-01-06 14:58:18 -08002782
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002783 if (mHandler == null || !ActivityManagerNative.isSystemReady()) {
2784 throw new IllegalStateException("Too early to call reboot()");
2785 }
Mike Lockwoodb62f9592010-03-12 07:55:23 -05002786
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002787 final String finalReason = reason;
2788 Runnable runnable = new Runnable() {
2789 public void run() {
2790 synchronized (this) {
2791 ShutdownThread.reboot(mContext, finalReason, false);
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002792 }
Jim Miller92e66dd2012-02-21 18:57:12 -08002793
San Mehat1e512792010-01-07 10:40:29 -08002794 }
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002795 };
Mike Lockwoodb62f9592010-03-12 07:55:23 -05002796 // ShutdownThread must run on a looper capable of displaying the UI.
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002797 mHandler.post(runnable);
2798
Mike Lockwoodb62f9592010-03-12 07:55:23 -05002799 // PowerManager.reboot() is documented not to return so just wait for the inevitable.
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002800 synchronized (runnable) {
Mike Lockwoodb62f9592010-03-12 07:55:23 -05002801 while (true) {
2802 try {
2803 runnable.wait();
2804 } catch (InterruptedException e) {
2805 }
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002806 }
Doug Zongker50a21f42009-11-19 12:49:53 -08002807 }
2808 }
2809
Dan Egnor60d87622009-12-16 16:32:58 -08002810 /**
2811 * Crash the runtime (causing a complete restart of the Android framework).
2812 * Requires REBOOT permission. Mostly for testing. Should not return.
2813 */
2814 public void crash(final String message)
2815 {
2816 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
2817 Thread t = new Thread("PowerManagerService.crash()") {
2818 public void run() { throw new RuntimeException(message); }
2819 };
2820 try {
2821 t.start();
2822 t.join();
2823 } catch (InterruptedException e) {
2824 Log.wtf(TAG, e);
2825 }
2826 }
2827
Mike Lockwood435eb642009-12-03 08:40:18 -05002828 private void goToSleepLocked(long time, int reason) {
Jeff Browna75fe052012-05-01 18:41:26 -07002829 if (mSpew) {
2830 Exception ex = new Exception();
2831 ex.fillInStackTrace();
2832 Slog.d(TAG, "goToSleep mLastEventTime=" + mLastEventTime + " time=" + time
2833 + " reason=" + reason, ex);
2834 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002835
2836 if (mLastEventTime <= time) {
2837 mLastEventTime = time;
2838 // cancel all of the wake locks
2839 mWakeLockState = SCREEN_OFF;
2840 int N = mLocks.size();
2841 int numCleared = 0;
Joe Onorato8274a0e2010-10-05 17:38:09 -04002842 boolean proxLock = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002843 for (int i=0; i<N; i++) {
2844 WakeLock wl = mLocks.get(i);
2845 if (isScreenLock(wl.flags)) {
Joe Onorato8274a0e2010-10-05 17:38:09 -04002846 if (((wl.flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)
2847 && reason == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR) {
2848 proxLock = true;
2849 } else {
2850 mLocks.get(i).activated = false;
2851 numCleared++;
2852 }
2853 }
2854 }
2855 if (!proxLock) {
2856 mProxIgnoredBecauseScreenTurnedOff = true;
2857 if (mDebugProximitySensor) {
2858 Slog.d(TAG, "setting mProxIgnoredBecauseScreenTurnedOff");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002859 }
2860 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002861 EventLog.writeEvent(EventLogTags.POWER_SLEEP_REQUESTED, numCleared);
Joe Onorato128e7292009-03-24 18:41:31 -07002862 mStillNeedSleepNotification = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002863 mUserState = SCREEN_OFF;
Mike Lockwood435eb642009-12-03 08:40:18 -05002864 setPowerState(SCREEN_OFF, false, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002865 cancelTimerLocked();
2866 }
2867 }
2868
2869 public long timeSinceScreenOn() {
2870 synchronized (mLocks) {
2871 if ((mPowerState & SCREEN_ON_BIT) != 0) {
2872 return 0;
2873 }
2874 return SystemClock.elapsedRealtime() - mScreenOffTime;
2875 }
2876 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002877
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002878 public void setKeyboardVisibility(boolean visible) {
Mike Lockwooda625b382009-09-12 17:36:03 -07002879 synchronized (mLocks) {
2880 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002881 Slog.d(TAG, "setKeyboardVisibility: " + visible);
Mike Lockwooda625b382009-09-12 17:36:03 -07002882 }
Mike Lockwood3c9435a2009-10-22 15:45:37 -04002883 if (mKeyboardVisible != visible) {
2884 mKeyboardVisible = visible;
2885 // don't signal user activity if the screen is off; other code
2886 // will take care of turning on due to a true change to the lid
2887 // switch and synchronized with the lock screen.
2888 if ((mPowerState & SCREEN_ON_BIT) != 0) {
Mike Lockwood4984e732009-11-01 08:16:33 -05002889 if (mUseSoftwareAutoBrightness) {
Mike Lockwooddf024922009-10-29 21:29:15 -04002890 // force recompute of backlight values
2891 if (mLightSensorValue >= 0) {
2892 int value = (int)mLightSensorValue;
2893 mLightSensorValue = -1;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002894 lightSensorChangedLocked(value, false);
Mike Lockwooddf024922009-10-29 21:29:15 -04002895 }
2896 }
Mike Lockwood3c9435a2009-10-22 15:45:37 -04002897 userActivity(SystemClock.uptimeMillis(), false, BUTTON_EVENT, true);
2898 }
Mike Lockwooda625b382009-09-12 17:36:03 -07002899 }
2900 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002901 }
2902
2903 /**
2904 * When the keyguard is up, it manages the power state, and userActivity doesn't do anything.
Mike Lockwood50c548d2009-11-09 16:02:06 -05002905 * When disabling user activity we also reset user power state so the keyguard can reset its
2906 * short screen timeout when keyguard is unhidden.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002907 */
2908 public void enableUserActivity(boolean enabled) {
Mike Lockwood50c548d2009-11-09 16:02:06 -05002909 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002910 Slog.d(TAG, "enableUserActivity " + enabled);
Mike Lockwood50c548d2009-11-09 16:02:06 -05002911 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002912 synchronized (mLocks) {
2913 mUserActivityAllowed = enabled;
Mike Lockwood50c548d2009-11-09 16:02:06 -05002914 if (!enabled) {
2915 // cancel timeout and clear mUserState so the keyguard can set a short timeout
2916 setTimeoutLocked(SystemClock.uptimeMillis(), 0);
2917 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002918 }
2919 }
2920
Mike Lockwooddc3494e2009-10-14 21:17:09 -07002921 private void setScreenBrightnessMode(int mode) {
Joe Onoratod28f7532010-11-06 12:56:53 -07002922 synchronized (mLocks) {
2923 boolean enabled = (mode == SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
2924 if (mUseSoftwareAutoBrightness && mAutoBrightessEnabled != enabled) {
2925 mAutoBrightessEnabled = enabled;
2926 // This will get us a new value
2927 enableLightSensorLocked(mAutoBrightessEnabled && isScreenOn());
Mike Lockwood2d155d22009-10-27 09:32:30 -04002928 }
Mike Lockwooddc3494e2009-10-14 21:17:09 -07002929 }
2930 }
2931
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002932 /** Sets the screen off timeouts:
2933 * mKeylightDelay
2934 * mDimDelay
2935 * mScreenOffDelay
2936 * */
2937 private void setScreenOffTimeoutsLocked() {
2938 if ((mPokey & POKE_LOCK_SHORT_TIMEOUT) != 0) {
Doug Zongker43866e02010-01-07 12:09:54 -08002939 mKeylightDelay = mShortKeylightDelay; // Configurable via secure settings
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002940 mDimDelay = -1;
2941 mScreenOffDelay = 0;
2942 } else if ((mPokey & POKE_LOCK_MEDIUM_TIMEOUT) != 0) {
2943 mKeylightDelay = MEDIUM_KEYLIGHT_DELAY;
2944 mDimDelay = -1;
2945 mScreenOffDelay = 0;
2946 } else {
Dianne Hackborndf83afa2010-01-20 13:37:26 -08002947 int totalDelay = mScreenOffTimeoutSetting;
2948 if (totalDelay > mMaximumScreenOffTimeout) {
2949 totalDelay = mMaximumScreenOffTimeout;
2950 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002951 mKeylightDelay = LONG_KEYLIGHT_DELAY;
2952 if (totalDelay < 0) {
Jim Millerbc4603b2010-08-30 21:21:34 -07002953 // negative number means stay on as long as possible.
2954 mScreenOffDelay = mMaximumScreenOffTimeout;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002955 } else if (mKeylightDelay < totalDelay) {
2956 // subtract the time that the keylight delay. This will give us the
2957 // remainder of the time that we need to sleep to get the accurate
2958 // screen off timeout.
2959 mScreenOffDelay = totalDelay - mKeylightDelay;
2960 } else {
2961 mScreenOffDelay = 0;
2962 }
2963 if (mDimScreen && totalDelay >= (LONG_KEYLIGHT_DELAY + LONG_DIM_TIME)) {
2964 mDimDelay = mScreenOffDelay - LONG_DIM_TIME;
2965 mScreenOffDelay = LONG_DIM_TIME;
2966 } else {
2967 mDimDelay = -1;
2968 }
2969 }
2970 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002971 Slog.d(TAG, "setScreenOffTimeouts mKeylightDelay=" + mKeylightDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002972 + " mDimDelay=" + mDimDelay + " mScreenOffDelay=" + mScreenOffDelay
2973 + " mDimScreen=" + mDimScreen);
2974 }
2975 }
2976
2977 /**
Doug Zongker43866e02010-01-07 12:09:54 -08002978 * Refreshes cached secure settings. Called once on startup, and
2979 * on subsequent changes to secure settings.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002980 */
Doug Zongker43866e02010-01-07 12:09:54 -08002981 private void updateSettingsValues() {
2982 mShortKeylightDelay = Settings.Secure.getInt(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002983 mContext.getContentResolver(),
Doug Zongker43866e02010-01-07 12:09:54 -08002984 Settings.Secure.SHORT_KEYLIGHT_DELAY_MS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002985 SHORT_KEYLIGHT_DELAY_DEFAULT);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002986 // Slog.i(TAG, "updateSettingsValues(): mShortKeylightDelay now " + mShortKeylightDelay);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002987 }
2988
2989 private class LockList extends ArrayList<WakeLock>
2990 {
2991 void addLock(WakeLock wl)
2992 {
2993 int index = getIndex(wl.binder);
2994 if (index < 0) {
2995 this.add(wl);
2996 }
2997 }
2998
2999 WakeLock removeLock(IBinder binder)
3000 {
3001 int index = getIndex(binder);
3002 if (index >= 0) {
3003 return this.remove(index);
3004 } else {
3005 return null;
3006 }
3007 }
3008
3009 int getIndex(IBinder binder)
3010 {
3011 int N = this.size();
3012 for (int i=0; i<N; i++) {
3013 if (this.get(i).binder == binder) {
3014 return i;
3015 }
3016 }
3017 return -1;
3018 }
3019
3020 int gatherState()
3021 {
3022 int result = 0;
3023 int N = this.size();
3024 for (int i=0; i<N; i++) {
3025 WakeLock wl = this.get(i);
3026 if (wl.activated) {
3027 if (isScreenLock(wl.flags)) {
3028 result |= wl.minState;
3029 }
3030 }
3031 }
3032 return result;
3033 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003034
Michael Chane96440f2009-05-06 10:27:36 -07003035 int reactivateScreenLocksLocked()
3036 {
3037 int result = 0;
3038 int N = this.size();
3039 for (int i=0; i<N; i++) {
3040 WakeLock wl = this.get(i);
3041 if (isScreenLock(wl.flags)) {
3042 wl.activated = true;
3043 result |= wl.minState;
3044 }
3045 }
Joe Onorato8274a0e2010-10-05 17:38:09 -04003046 if (mDebugProximitySensor) {
3047 Slog.d(TAG, "reactivateScreenLocksLocked mProxIgnoredBecauseScreenTurnedOff="
3048 + mProxIgnoredBecauseScreenTurnedOff);
3049 }
3050 mProxIgnoredBecauseScreenTurnedOff = false;
Michael Chane96440f2009-05-06 10:27:36 -07003051 return result;
3052 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003053 }
3054
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08003055 public void setPolicy(WindowManagerPolicy p) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003056 synchronized (mLocks) {
3057 mPolicy = p;
3058 mLocks.notifyAll();
3059 }
3060 }
3061
3062 WindowManagerPolicy getPolicyLocked() {
3063 while (mPolicy == null || !mDoneBooting) {
3064 try {
3065 mLocks.wait();
3066 } catch (InterruptedException e) {
3067 // Ignore
3068 }
3069 }
3070 return mPolicy;
3071 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003072
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003073 void systemReady() {
Jeff Brown25157e42012-04-16 12:13:05 -07003074 mSensorManager = new SystemSensorManager(mHandlerThread.getLooper());
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003075 mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
3076 // don't bother with the light sensor if auto brightness is handled in hardware
Mike Lockwoodaa66ea82009-10-31 16:31:27 -04003077 if (mUseSoftwareAutoBrightness) {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003078 mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003079 }
3080
Mike Lockwoodb42ab0f2010-03-04 08:02:44 -05003081 // wait until sensors are enabled before turning on screen.
3082 // some devices will not activate the light sensor properly on boot
3083 // unless we do this.
3084 if (mUseSoftwareAutoBrightness) {
3085 // turn the screen on
3086 setPowerState(SCREEN_BRIGHT);
3087 } else {
3088 // turn everything on
3089 setPowerState(ALL_BRIGHT);
3090 }
3091
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003092 synchronized (mLocks) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003093 Slog.d(TAG, "system ready!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003094 mDoneBooting = true;
Mike Lockwoodb42ab0f2010-03-04 08:02:44 -05003095
Joe Onoratod28f7532010-11-06 12:56:53 -07003096 enableLightSensorLocked(mUseSoftwareAutoBrightness && mAutoBrightessEnabled);
3097
Dianne Hackborn617f8772009-03-31 15:04:46 -07003098 long identity = Binder.clearCallingIdentity();
3099 try {
3100 mBatteryStats.noteScreenBrightness(getPreferredBrightness());
3101 mBatteryStats.noteScreenOn();
3102 } catch (RemoteException e) {
3103 // Nothing interesting to do.
3104 } finally {
3105 Binder.restoreCallingIdentity(identity);
3106 }
Mike Lockwood2d7bb812009-11-15 18:12:22 -05003107 }
3108 }
3109
3110 void bootCompleted() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003111 Slog.d(TAG, "bootCompleted");
Mike Lockwood2d7bb812009-11-15 18:12:22 -05003112 synchronized (mLocks) {
3113 mBootCompleted = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003114 userActivity(SystemClock.uptimeMillis(), false, BUTTON_EVENT, true);
3115 updateWakeLockLocked();
3116 mLocks.notifyAll();
3117 }
3118 }
3119
Joe Onoratob08a1af2010-10-11 19:28:58 -07003120 // for watchdog
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003121 public void monitor() {
3122 synchronized (mLocks) { }
3123 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003124
3125 public int getSupportedWakeLockFlags() {
3126 int result = PowerManager.PARTIAL_WAKE_LOCK
3127 | PowerManager.FULL_WAKE_LOCK
3128 | PowerManager.SCREEN_DIM_WAKE_LOCK;
3129
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003130 if (mProximitySensor != null) {
3131 result |= PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK;
3132 }
3133
3134 return result;
3135 }
3136
Mike Lockwood237a2992009-09-15 14:42:16 -04003137 public void setBacklightBrightness(int brightness) {
3138 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
3139 // Don't let applications turn the screen all the way off
Joe Onoratob08a1af2010-10-11 19:28:58 -07003140 synchronized (mLocks) {
Mike Lockwoodeb6456b2011-09-13 15:24:02 -04003141 brightness = Math.max(brightness, mScreenBrightnessDim);
Joe Onoratob08a1af2010-10-11 19:28:58 -07003142 mLcdLight.setBrightness(brightness);
3143 mKeyboardLight.setBrightness(mKeyboardVisible ? brightness : 0);
3144 mButtonLight.setBrightness(brightness);
3145 long identity = Binder.clearCallingIdentity();
3146 try {
3147 mBatteryStats.noteScreenBrightness(brightness);
3148 } catch (RemoteException e) {
3149 Slog.w(TAG, "RemoteException calling noteScreenBrightness on BatteryStatsService", e);
3150 } finally {
3151 Binder.restoreCallingIdentity(identity);
3152 }
Jim Miller92e66dd2012-02-21 18:57:12 -08003153 mScreenBrightnessAnimator.animateTo(brightness, SCREEN_BRIGHT_BIT, 0);
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08003154 }
3155 }
3156
3157 public void setAutoBrightnessAdjustment(float adj) {
3158 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
3159 synchronized (mLocks) {
3160 mLightSensorAdjustSetting = adj;
3161 if (mSensorManager != null && mLightSensorEnabled) {
3162 // clear calling identity so sensor manager battery stats are accurate
3163 long identity = Binder.clearCallingIdentity();
3164 try {
3165 // force recompute of backlight values
3166 if (mLightSensorValue >= 0) {
3167 int value = (int)mLightSensorValue;
3168 mLightSensorValue = -1;
3169 handleLightSensorValue(value, true);
3170 }
3171 } finally {
3172 Binder.restoreCallingIdentity(identity);
3173 }
Joe Onorato3d3db602010-10-18 16:08:16 -04003174 }
Mike Lockwood237a2992009-09-15 14:42:16 -04003175 }
3176 }
3177
Mike Lockwoodb11832d2009-11-25 15:25:55 -05003178 public void setAttentionLight(boolean on, int color) {
3179 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
Mike Lockwood3cb67a32009-11-27 14:25:58 -05003180 mAttentionLight.setFlashing(color, LightsService.LIGHT_FLASH_HARDWARE, (on ? 3 : 0), 0);
Mike Lockwoodb11832d2009-11-25 15:25:55 -05003181 }
3182
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003183 private void enableProximityLockLocked() {
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003184 if (mDebugProximitySensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003185 Slog.d(TAG, "enableProximityLockLocked");
Mike Lockwood36fc3022009-08-25 16:49:06 -07003186 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003187 if (!mProximitySensorEnabled) {
3188 // clear calling identity so sensor manager battery stats are accurate
3189 long identity = Binder.clearCallingIdentity();
3190 try {
3191 mSensorManager.registerListener(mProximityListener, mProximitySensor,
3192 SensorManager.SENSOR_DELAY_NORMAL);
3193 mProximitySensorEnabled = true;
3194 } finally {
3195 Binder.restoreCallingIdentity(identity);
3196 }
Mike Lockwood809ad0f2009-10-26 22:10:33 -04003197 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003198 }
3199
3200 private void disableProximityLockLocked() {
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003201 if (mDebugProximitySensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003202 Slog.d(TAG, "disableProximityLockLocked");
Mike Lockwood36fc3022009-08-25 16:49:06 -07003203 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003204 if (mProximitySensorEnabled) {
3205 // clear calling identity so sensor manager battery stats are accurate
3206 long identity = Binder.clearCallingIdentity();
3207 try {
3208 mSensorManager.unregisterListener(mProximityListener);
3209 mHandler.removeCallbacks(mProximityTask);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -05003210 if (mProximityPartialLock.isHeld()) {
3211 mProximityPartialLock.release();
3212 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003213 mProximitySensorEnabled = false;
3214 } finally {
3215 Binder.restoreCallingIdentity(identity);
3216 }
3217 if (mProximitySensorActive) {
3218 mProximitySensorActive = false;
Joe Onorato8274a0e2010-10-05 17:38:09 -04003219 if (mDebugProximitySensor) {
3220 Slog.d(TAG, "disableProximityLockLocked mProxIgnoredBecauseScreenTurnedOff="
3221 + mProxIgnoredBecauseScreenTurnedOff);
3222 }
3223 if (!mProxIgnoredBecauseScreenTurnedOff) {
3224 forceUserActivityLocked();
3225 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003226 }
Mike Lockwood200b30b2009-09-20 00:23:59 -04003227 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003228 }
3229
Mike Lockwood20f87d72009-11-05 16:08:51 -05003230 private void proximityChangedLocked(boolean active) {
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003231 if (mDebugProximitySensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003232 Slog.d(TAG, "proximityChangedLocked, active: " + active);
Mike Lockwood20f87d72009-11-05 16:08:51 -05003233 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003234 if (!mProximitySensorEnabled) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003235 Slog.d(TAG, "Ignoring proximity change after sensor is disabled");
Mike Lockwood0d72f7e2009-11-05 20:53:00 -05003236 return;
3237 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05003238 if (active) {
Joe Onorato8274a0e2010-10-05 17:38:09 -04003239 if (mDebugProximitySensor) {
3240 Slog.d(TAG, "b mProxIgnoredBecauseScreenTurnedOff="
3241 + mProxIgnoredBecauseScreenTurnedOff);
3242 }
3243 if (!mProxIgnoredBecauseScreenTurnedOff) {
3244 goToSleepLocked(SystemClock.uptimeMillis(),
3245 WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR);
3246 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05003247 mProximitySensorActive = true;
3248 } else {
3249 // proximity sensor negative events trigger as user activity.
3250 // temporarily set mUserActivityAllowed to true so this will work
3251 // even when the keyguard is on.
3252 mProximitySensorActive = false;
Joe Onorato8274a0e2010-10-05 17:38:09 -04003253 if (mDebugProximitySensor) {
3254 Slog.d(TAG, "b mProxIgnoredBecauseScreenTurnedOff="
3255 + mProxIgnoredBecauseScreenTurnedOff);
3256 }
3257 if (!mProxIgnoredBecauseScreenTurnedOff) {
3258 forceUserActivityLocked();
3259 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003260
3261 if (mProximityWakeLockCount == 0) {
3262 // disable sensor if we have no listeners left after proximity negative
3263 disableProximityLockLocked();
3264 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05003265 }
3266 }
3267
Joe Onoratod28f7532010-11-06 12:56:53 -07003268 private void enableLightSensorLocked(boolean enable) {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003269 if (mDebugLightSensor) {
Joe Onoratod28f7532010-11-06 12:56:53 -07003270 Slog.d(TAG, "enableLightSensorLocked enable=" + enable
Craig Mautner37933682012-06-06 14:13:39 -07003271 + " mLightSensorEnabled=" + mLightSensorEnabled
3272 + " mAutoBrightessEnabled=" + mAutoBrightessEnabled
3273 + " mWaitingForFirstLightSensor=" + mWaitingForFirstLightSensor);
Joe Onoratod28f7532010-11-06 12:56:53 -07003274 }
3275 if (!mAutoBrightessEnabled) {
3276 enable = false;
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003277 }
3278 if (mSensorManager != null && mLightSensorEnabled != enable) {
3279 mLightSensorEnabled = enable;
Mike Lockwood809ad0f2009-10-26 22:10:33 -04003280 // clear calling identity so sensor manager battery stats are accurate
3281 long identity = Binder.clearCallingIdentity();
3282 try {
3283 if (enable) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003284 // reset our highest value when reenabling
3285 mHighestLightSensorValue = -1;
3286 // force recompute of backlight values
Craig Mautner37933682012-06-06 14:13:39 -07003287 final int value = (int)mLightSensorValue;
3288 if (value >= 0) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003289 mLightSensorValue = -1;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08003290 handleLightSensorValue(value, true);
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003291 }
Mike Lockwood809ad0f2009-10-26 22:10:33 -04003292 mSensorManager.registerListener(mLightListener, mLightSensor,
Mathias Agopian47f1fe52011-11-08 17:18:41 -08003293 LIGHT_SENSOR_RATE);
Mike Lockwood809ad0f2009-10-26 22:10:33 -04003294 } else {
3295 mSensorManager.unregisterListener(mLightListener);
3296 mHandler.removeCallbacks(mAutoBrightnessTask);
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003297 mLightSensorPendingDecrease = false;
3298 mLightSensorPendingIncrease = false;
Mike Lockwood809ad0f2009-10-26 22:10:33 -04003299 }
3300 } finally {
3301 Binder.restoreCallingIdentity(identity);
Mike Lockwood06952d92009-08-13 16:05:38 -04003302 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003303 }
3304 }
3305
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003306 SensorEventListener mProximityListener = new SensorEventListener() {
3307 public void onSensorChanged(SensorEvent event) {
Mike Lockwoodba8eb1e2009-11-08 19:31:18 -05003308 long milliseconds = SystemClock.elapsedRealtime();
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003309 synchronized (mLocks) {
3310 float distance = event.values[0];
Mike Lockwood20f87d72009-11-05 16:08:51 -05003311 long timeSinceLastEvent = milliseconds - mLastProximityEventTime;
3312 mLastProximityEventTime = milliseconds;
3313 mHandler.removeCallbacks(mProximityTask);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -05003314 boolean proximityTaskQueued = false;
Mike Lockwood20f87d72009-11-05 16:08:51 -05003315
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003316 // compare against getMaximumRange to support sensors that only return 0 or 1
Mike Lockwood20f87d72009-11-05 16:08:51 -05003317 boolean active = (distance >= 0.0 && distance < PROXIMITY_THRESHOLD &&
3318 distance < mProximitySensor.getMaximumRange());
3319
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003320 if (mDebugProximitySensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003321 Slog.d(TAG, "mProximityListener.onSensorChanged active: " + active);
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003322 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05003323 if (timeSinceLastEvent < PROXIMITY_SENSOR_DELAY) {
3324 // enforce delaying atleast PROXIMITY_SENSOR_DELAY before processing
3325 mProximityPendingValue = (active ? 1 : 0);
3326 mHandler.postDelayed(mProximityTask, PROXIMITY_SENSOR_DELAY - timeSinceLastEvent);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -05003327 proximityTaskQueued = true;
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003328 } else {
Mike Lockwood20f87d72009-11-05 16:08:51 -05003329 // process the value immediately
3330 mProximityPendingValue = -1;
3331 proximityChangedLocked(active);
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003332 }
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -05003333
3334 // update mProximityPartialLock state
3335 boolean held = mProximityPartialLock.isHeld();
3336 if (!held && proximityTaskQueued) {
3337 // hold wakelock until mProximityTask runs
3338 mProximityPartialLock.acquire();
3339 } else if (held && !proximityTaskQueued) {
3340 mProximityPartialLock.release();
3341 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003342 }
3343 }
3344
3345 public void onAccuracyChanged(Sensor sensor, int accuracy) {
3346 // ignore
3347 }
3348 };
3349
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08003350 private void handleLightSensorValue(int value, boolean immediate) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003351 long milliseconds = SystemClock.elapsedRealtime();
Craig Mautner37933682012-06-06 14:13:39 -07003352 if (mLightSensorValue == -1
3353 || milliseconds < mLastScreenOnTime + mLightSensorWarmupTime
3354 || mWaitingForFirstLightSensor) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003355 // process the value immediately if screen has just turned on
3356 mHandler.removeCallbacks(mAutoBrightnessTask);
3357 mLightSensorPendingDecrease = false;
3358 mLightSensorPendingIncrease = false;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08003359 lightSensorChangedLocked(value, immediate);
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003360 } else {
3361 if ((value > mLightSensorValue && mLightSensorPendingDecrease) ||
3362 (value < mLightSensorValue && mLightSensorPendingIncrease) ||
3363 (value == mLightSensorValue) ||
3364 (!mLightSensorPendingDecrease && !mLightSensorPendingIncrease)) {
3365 // delay processing to debounce the sensor
3366 mHandler.removeCallbacks(mAutoBrightnessTask);
3367 mLightSensorPendingDecrease = (value < mLightSensorValue);
3368 mLightSensorPendingIncrease = (value > mLightSensorValue);
3369 if (mLightSensorPendingDecrease || mLightSensorPendingIncrease) {
3370 mLightSensorPendingValue = value;
3371 mHandler.postDelayed(mAutoBrightnessTask, LIGHT_SENSOR_DELAY);
3372 }
3373 } else {
3374 mLightSensorPendingValue = value;
3375 }
3376 }
3377 }
3378
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003379 SensorEventListener mLightListener = new SensorEventListener() {
Craig Mautner75fc9de2012-06-18 16:53:27 -07003380 @Override
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003381 public void onSensorChanged(SensorEvent event) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003382 if (mDebugLightSensor) {
3383 Slog.d(TAG, "onSensorChanged: light value: " + event.values[0]);
3384 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003385 synchronized (mLocks) {
Mike Lockwood497087e32009-11-08 18:33:03 -05003386 // ignore light sensor while screen is turning off
3387 if (isScreenTurningOffLocked()) {
3388 return;
3389 }
Craig Mautner37933682012-06-06 14:13:39 -07003390 handleLightSensorValue((int)event.values[0], mWaitingForFirstLightSensor);
Craig Mautner75fc9de2012-06-18 16:53:27 -07003391 if (mWaitingForFirstLightSensor && !mPreparingForScreenOn) {
3392 if (mDebugLightAnimation) {
3393 Slog.d(TAG, "onSensorChanged: Clearing mWaitingForFirstLightSensor.");
3394 }
Craig Mautner37933682012-06-06 14:13:39 -07003395 mWaitingForFirstLightSensor = false;
3396 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003397 }
3398 }
3399
Craig Mautner75fc9de2012-06-18 16:53:27 -07003400 @Override
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003401 public void onAccuracyChanged(Sensor sensor, int accuracy) {
3402 // ignore
3403 }
3404 };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003405}