blob: 2318049965b629bb3e009d3636b4eb1c52e8fe8d [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server;
18
19import com.android.internal.app.IBatteryStats;
20import com.android.server.am.BatteryStatsService;
Jeff Brown7304c342012-05-11 18:42:42 -070021import com.android.server.pm.ShutdownThread;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022
23import android.app.ActivityManagerNative;
24import android.app.IActivityManager;
25import android.content.BroadcastReceiver;
26import android.content.ContentQueryMap;
27import android.content.ContentResolver;
Amith Yamasani8b619832010-09-22 16:11:59 -070028import android.content.ContentValues;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029import android.content.Context;
30import android.content.Intent;
31import android.content.IntentFilter;
32import android.content.pm.PackageManager;
Mike Lockwoodd7786b42009-10-15 17:09:16 -070033import android.content.res.Resources;
Doug Zongker43866e02010-01-07 12:09:54 -080034import android.database.ContentObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035import android.database.Cursor;
Mike Lockwoodbc706a02009-07-27 13:50:57 -070036import android.hardware.Sensor;
37import android.hardware.SensorEvent;
38import android.hardware.SensorEventListener;
39import android.hardware.SensorManager;
Jeff Brown25157e42012-04-16 12:13:05 -070040import android.hardware.SystemSensorManager;
Amith Yamasani8b619832010-09-22 16:11:59 -070041import android.os.BatteryManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042import android.os.BatteryStats;
43import android.os.Binder;
44import android.os.Handler;
45import android.os.HandlerThread;
46import android.os.IBinder;
47import android.os.IPowerManager;
48import android.os.LocalPowerManager;
Jim Miller92e66dd2012-02-21 18:57:12 -080049import android.os.Message;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050import android.os.PowerManager;
51import android.os.Process;
52import android.os.RemoteException;
53import android.os.SystemClock;
Mike Lockwood3a74bd32011-08-12 13:55:22 -070054import android.os.SystemProperties;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070055import android.os.WorkSource;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056import android.provider.Settings;
57import android.util.EventLog;
58import android.util.Log;
Joe Onorato8a9b2202010-02-26 18:56:32 -080059import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060import android.view.WindowManagerPolicy;
Jim Miller92e66dd2012-02-21 18:57:12 -080061import static android.view.WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062import static android.provider.Settings.System.DIM_SCREEN;
63import static android.provider.Settings.System.SCREEN_BRIGHTNESS;
Dan Murphy951764b2009-08-27 14:59:03 -050064import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -080065import static android.provider.Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ;
Mike Lockwooddc3494e2009-10-14 21:17:09 -070066import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
68import static android.provider.Settings.System.STAY_ON_WHILE_PLUGGED_IN;
Joe Onorato609695d2010-10-14 14:57:49 -070069import static android.provider.Settings.System.WINDOW_ANIMATION_SCALE;
70import static android.provider.Settings.System.TRANSITION_ANIMATION_SCALE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071
72import java.io.FileDescriptor;
Jeff Brown7304c342012-05-11 18:42:42 -070073import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074import java.io.PrintWriter;
75import java.util.ArrayList;
76import java.util.HashMap;
77import java.util.Observable;
78import java.util.Observer;
79
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080080public class PowerManagerService extends IPowerManager.Stub
Mike Lockwood8738e0c2009-10-04 08:44:47 -040081 implements LocalPowerManager, Watchdog.Monitor {
Jim Miller92e66dd2012-02-21 18:57:12 -080082 private static final int NOMINAL_FRAME_TIME_MS = 1000/60;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083
84 private static final String TAG = "PowerManagerService";
85 static final String PARTIAL_NAME = "PowerManagerService";
86
Jeff Brown7304c342012-05-11 18:42:42 -070087 // Wake lock that ensures that the CPU is running. The screen might not be on.
88 private static final int PARTIAL_WAKE_LOCK_ID = 1;
89
90 // Wake lock that ensures that the screen is on.
91 private static final int FULL_WAKE_LOCK_ID = 2;
92
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -070093 static final boolean DEBUG_SCREEN_ON = false;
94
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095 private static final boolean LOG_PARTIAL_WL = false;
96
97 // Indicates whether touch-down cycles should be logged as part of the
98 // LOG_POWER_SCREEN_STATE log events
99 private static final boolean LOG_TOUCH_DOWNS = true;
100
101 private static final int LOCK_MASK = PowerManager.PARTIAL_WAKE_LOCK
102 | PowerManager.SCREEN_DIM_WAKE_LOCK
103 | PowerManager.SCREEN_BRIGHT_WAKE_LOCK
Mike Lockwoodbc706a02009-07-27 13:50:57 -0700104 | PowerManager.FULL_WAKE_LOCK
105 | PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106
107 // time since last state: time since last event:
Doug Zongker43866e02010-01-07 12:09:54 -0800108 // The short keylight delay comes from secure settings; this is the default.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109 private static final int SHORT_KEYLIGHT_DELAY_DEFAULT = 6000; // t+6 sec
110 private static final int MEDIUM_KEYLIGHT_DELAY = 15000; // t+15 sec
111 private static final int LONG_KEYLIGHT_DELAY = 6000; // t+6 sec
112 private static final int LONG_DIM_TIME = 7000; // t+N-5 sec
113
Mathias Agopian47f1fe52011-11-08 17:18:41 -0800114 // How long to wait to debounce light sensor changes in milliseconds
Mike Lockwood9b8136922009-11-06 15:53:59 -0500115 private static final int LIGHT_SENSOR_DELAY = 2000;
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700116
Mathias Agopian47f1fe52011-11-08 17:18:41 -0800117 // light sensor events rate in microseconds
118 private static final int LIGHT_SENSOR_RATE = 1000000;
119
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800120 // Expansion of range of light values when applying scale from light
121 // sensor brightness setting, in the [0..255] brightness range.
122 private static final int LIGHT_SENSOR_RANGE_EXPANSION = 20;
123
124 // Scaling factor of the light sensor brightness setting when applying
125 // it to the final brightness.
126 private static final int LIGHT_SENSOR_OFFSET_SCALE = 8;
127
Mathias Agopian47f1fe52011-11-08 17:18:41 -0800128 // For debouncing the proximity sensor in milliseconds
Mike Lockwood20f87d72009-11-05 16:08:51 -0500129 private static final int PROXIMITY_SENSOR_DELAY = 1000;
130
Mike Lockwoodd20ea362009-09-15 00:13:38 -0400131 // trigger proximity if distance is less than 5 cm
132 private static final float PROXIMITY_THRESHOLD = 5.0f;
133
Doug Zongker43866e02010-01-07 12:09:54 -0800134 // Cached secure settings; see updateSettingsValues()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135 private int mShortKeylightDelay = SHORT_KEYLIGHT_DELAY_DEFAULT;
136
Amith Yamasani8b619832010-09-22 16:11:59 -0700137 // Default timeout for screen off, if not found in settings database = 15 seconds.
138 private static final int DEFAULT_SCREEN_OFF_TIMEOUT = 15000;
139
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800140 // Screen brightness should always have a value, but just in case...
141 private static final int DEFAULT_SCREEN_BRIGHTNESS = 192;
142
Jeff Brown7304c342012-05-11 18:42:42 -0700143 // Threshold for BRIGHTNESS_LOW_BATTERY (percentage)
144 // Screen will stay dim if battery level is <= LOW_BATTERY_THRESHOLD
145 private static final int LOW_BATTERY_THRESHOLD = 10;
146
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 // flags for setPowerState
Jim Miller92e66dd2012-02-21 18:57:12 -0800148 private static final int ALL_LIGHTS_OFF = 0x00000000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 private static final int SCREEN_ON_BIT = 0x00000001;
150 private static final int SCREEN_BRIGHT_BIT = 0x00000002;
151 private static final int BUTTON_BRIGHT_BIT = 0x00000004;
152 private static final int KEYBOARD_BRIGHT_BIT = 0x00000008;
153 private static final int BATTERY_LOW_BIT = 0x00000010;
154
155 // values for setPowerState
156
157 // SCREEN_OFF == everything off
158 private static final int SCREEN_OFF = 0x00000000;
159
160 // SCREEN_DIM == screen on, screen backlight dim
161 private static final int SCREEN_DIM = SCREEN_ON_BIT;
162
163 // SCREEN_BRIGHT == screen on, screen backlight bright
164 private static final int SCREEN_BRIGHT = SCREEN_ON_BIT | SCREEN_BRIGHT_BIT;
165
166 // SCREEN_BUTTON_BRIGHT == screen on, screen and button backlights bright
167 private static final int SCREEN_BUTTON_BRIGHT = SCREEN_BRIGHT | BUTTON_BRIGHT_BIT;
168
169 // SCREEN_BUTTON_BRIGHT == screen on, screen, button and keyboard backlights bright
170 private static final int ALL_BRIGHT = SCREEN_BUTTON_BRIGHT | KEYBOARD_BRIGHT_BIT;
171
172 // used for noChangeLights in setPowerState()
173 private static final int LIGHTS_MASK = SCREEN_BRIGHT_BIT | BUTTON_BRIGHT_BIT | KEYBOARD_BRIGHT_BIT;
174
Jim Miller46f31c32012-03-01 14:36:07 -0800175 // animate screen lights in PowerManager (as opposed to SurfaceFlinger)
Joe Onoratob08a1af2010-10-11 19:28:58 -0700176 boolean mAnimateScreenLights = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800177
Jim Miller92e66dd2012-02-21 18:57:12 -0800178 static final int ANIM_STEPS = 60; // nominal # of frames at 60Hz
Mike Lockwooddd9668e2009-10-27 15:47:02 -0400179 // Slower animation for autobrightness changes
Jim Miller92e66dd2012-02-21 18:57:12 -0800180 static final int AUTOBRIGHTNESS_ANIM_STEPS = 2 * ANIM_STEPS;
Craig Mautnera4e96d52012-06-06 14:49:44 -0700181 // Even slower animation for autodimness changes. Set to max to effectively disable dimming.
182 // Note 100 is used to keep the mWindowScaleAnimation scaling below from overflowing an int.
183 static final int AUTODIMNESS_ANIM_STEPS = Integer.MAX_VALUE / (NOMINAL_FRAME_TIME_MS * 100);
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800184 // Number of steps when performing a more immediate brightness change.
185 static final int IMMEDIATE_ANIM_STEPS = 4;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186
187 // These magic numbers are the initial state of the LEDs at boot. Ideally
188 // we should read them from the driver, but our current hardware returns 0
189 // for the initial value. Oops!
190 static final int INITIAL_SCREEN_BRIGHTNESS = 255;
Jeff Brown7304c342012-05-11 18:42:42 -0700191 static final int INITIAL_BUTTON_BRIGHTNESS = PowerManager.BRIGHTNESS_OFF;
192 static final int INITIAL_KEYBOARD_BRIGHTNESS = PowerManager.BRIGHTNESS_OFF;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800193
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800194 private final int MY_UID;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700195 private final int MY_PID;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800196
197 private boolean mDoneBooting = false;
Mike Lockwood2d7bb812009-11-15 18:12:22 -0500198 private boolean mBootCompleted = false;
Mike Lockwood3a74bd32011-08-12 13:55:22 -0700199 private boolean mHeadless = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800200 private int mStayOnConditions = 0;
Mike Lockwoodca44df82010-02-25 13:48:49 -0500201 private final int[] mBroadcastQueue = new int[] { -1, -1, -1 };
202 private final int[] mBroadcastWhy = new int[3];
Dianne Hackborn38e29a62011-09-18 14:43:08 -0700203 private boolean mPreparingForScreenOn = false;
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700204 private boolean mSkippedScreenOn = false;
205 private boolean mInitialized = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206 private int mPartialCount = 0;
207 private int mPowerState;
Mike Lockwood435eb642009-12-03 08:40:18 -0500208 // mScreenOffReason can be WindowManagerPolicy.OFF_BECAUSE_OF_USER,
209 // WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT or WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR
210 private int mScreenOffReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211 private int mUserState;
212 private boolean mKeyboardVisible = false;
213 private boolean mUserActivityAllowed = true;
Mike Lockwoodee2b0942009-11-09 14:09:02 -0500214 private int mProximityWakeLockCount = 0;
215 private boolean mProximitySensorEnabled = false;
Mike Lockwood36fc3022009-08-25 16:49:06 -0700216 private boolean mProximitySensorActive = false;
Mike Lockwood20f87d72009-11-05 16:08:51 -0500217 private int mProximityPendingValue = -1; // -1 == nothing, 0 == inactive, 1 == active
218 private long mLastProximityEventTime;
Dianne Hackborndf83afa2010-01-20 13:37:26 -0800219 private int mScreenOffTimeoutSetting;
220 private int mMaximumScreenOffTimeout = Integer.MAX_VALUE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221 private int mKeylightDelay;
222 private int mDimDelay;
223 private int mScreenOffDelay;
224 private int mWakeLockState;
225 private long mLastEventTime = 0;
226 private long mScreenOffTime;
227 private volatile WindowManagerPolicy mPolicy;
228 private final LockList mLocks = new LockList();
229 private Intent mScreenOffIntent;
230 private Intent mScreenOnIntent;
Mike Lockwood3a322132009-11-24 00:30:52 -0500231 private LightsService mLightsService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800232 private Context mContext;
Mike Lockwood3cb67a32009-11-27 14:25:58 -0500233 private LightsService.Light mLcdLight;
234 private LightsService.Light mButtonLight;
235 private LightsService.Light mKeyboardLight;
236 private LightsService.Light mAttentionLight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800237 private UnsynchronizedWakeLock mBroadcastWakeLock;
238 private UnsynchronizedWakeLock mStayOnWhilePluggedInScreenDimLock;
239 private UnsynchronizedWakeLock mStayOnWhilePluggedInPartialLock;
240 private UnsynchronizedWakeLock mPreventScreenOnPartialLock;
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -0500241 private UnsynchronizedWakeLock mProximityPartialLock;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800242 private HandlerThread mHandlerThread;
Joe Onoratob08a1af2010-10-11 19:28:58 -0700243 private Handler mScreenOffHandler;
Jim Miller92e66dd2012-02-21 18:57:12 -0800244 private Handler mScreenBrightnessHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800245 private Handler mHandler;
Mike Lockwoodca44df82010-02-25 13:48:49 -0500246 private final TimeoutTask mTimeoutTask = new TimeoutTask();
Jim Miller92e66dd2012-02-21 18:57:12 -0800247 private ScreenBrightnessAnimator mScreenBrightnessAnimator;
Craig Mautner37933682012-06-06 14:13:39 -0700248 private boolean mWaitingForFirstLightSensor = false;
Joe Onorato128e7292009-03-24 18:41:31 -0700249 private boolean mStillNeedSleepNotification;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250 private boolean mIsPowered = false;
251 private IActivityManager mActivityService;
252 private IBatteryStats mBatteryStats;
253 private BatteryService mBatteryService;
Mike Lockwoodbc706a02009-07-27 13:50:57 -0700254 private SensorManager mSensorManager;
255 private Sensor mProximitySensor;
Mike Lockwood8738e0c2009-10-04 08:44:47 -0400256 private Sensor mLightSensor;
257 private boolean mLightSensorEnabled;
258 private float mLightSensorValue = -1;
Joe Onorato8274a0e2010-10-05 17:38:09 -0400259 private boolean mProxIgnoredBecauseScreenTurnedOff = false;
Mike Lockwoodb2865412010-02-02 22:40:33 -0500260 private int mHighestLightSensorValue = -1;
Jim Rodovichd102fea2010-09-02 12:30:49 -0500261 private boolean mLightSensorPendingDecrease = false;
262 private boolean mLightSensorPendingIncrease = false;
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700263 private float mLightSensorPendingValue = -1;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800264 private float mLightSensorAdjustSetting = 0;
Mike Lockwoodfb73f792009-11-20 11:31:18 -0500265 private int mLightSensorScreenBrightness = -1;
266 private int mLightSensorButtonBrightness = -1;
267 private int mLightSensorKeyboardBrightness = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800268 private boolean mDimScreen = true;
Mike Lockwoodb2865412010-02-02 22:40:33 -0500269 private boolean mIsDocked = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800270 private long mNextTimeout;
271 private volatile int mPokey = 0;
272 private volatile boolean mPokeAwakeOnSet = false;
273 private volatile boolean mInitComplete = false;
Mike Lockwoodca44df82010-02-25 13:48:49 -0500274 private final HashMap<IBinder,PokeLock> mPokeLocks = new HashMap<IBinder,PokeLock>();
Mike Lockwood20ee6f22009-11-07 20:33:47 -0500275 // mLastScreenOnTime is the time the screen was last turned on
276 private long mLastScreenOnTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277 private boolean mPreventScreenOn;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800278 private int mScreenBrightnessSetting = DEFAULT_SCREEN_BRIGHTNESS;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 private int mScreenBrightnessOverride = -1;
Mike Lockwoodfb73f792009-11-20 11:31:18 -0500280 private int mButtonBrightnessOverride = -1;
Mike Lockwoodeb6456b2011-09-13 15:24:02 -0400281 private int mScreenBrightnessDim;
Mike Lockwoodaa66ea82009-10-31 16:31:27 -0400282 private boolean mUseSoftwareAutoBrightness;
Mike Lockwooddc3494e2009-10-14 21:17:09 -0700283 private boolean mAutoBrightessEnabled;
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700284 private int[] mAutoBrightnessLevels;
285 private int[] mLcdBacklightValues;
286 private int[] mButtonBacklightValues;
287 private int[] mKeyboardBacklightValues;
Mike Lockwood20ee6f22009-11-07 20:33:47 -0500288 private int mLightSensorWarmupTime;
Joe Onorato6d747652010-10-11 15:15:31 -0700289 boolean mUnplugTurnsOnScreen;
Joe Onorato4b9f62d2010-10-11 13:41:35 -0700290 private int mWarningSpewThrottleCount;
291 private long mWarningSpewThrottleTime;
Joe Onorato609695d2010-10-14 14:57:49 -0700292 private int mAnimationSetting = ANIM_SETTING_OFF;
Jim Miller92e66dd2012-02-21 18:57:12 -0800293 private float mWindowScaleAnimation;
Joe Onorato609695d2010-10-14 14:57:49 -0700294
295 // Must match with the ISurfaceComposer constants in C++.
296 private static final int ANIM_SETTING_ON = 0x01;
297 private static final int ANIM_SETTING_OFF = 0x10;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800298
299 // Used when logging number and duration of touch-down cycles
300 private long mTotalTouchDownTime;
301 private long mLastTouchDown;
302 private int mTouchCycles;
303
304 // could be either static or controllable at runtime
305 private static final boolean mSpew = false;
Joe Onorato8274a0e2010-10-05 17:38:09 -0400306 private static final boolean mDebugProximitySensor = (false || mSpew);
Mike Lockwoodae92eb32011-10-25 10:11:46 -0400307 private static final boolean mDebugLightSensor = (false || mSpew);
Jim Miller92e66dd2012-02-21 18:57:12 -0800308 private static final boolean mDebugLightAnimation = (false || mSpew);
309
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700310 private native void nativeInit();
311 private native void nativeSetPowerState(boolean screenOn, boolean screenBright);
Joe Onorato609695d2010-10-14 14:57:49 -0700312 private native void nativeStartSurfaceFlingerAnimation(int mode);
Jeff Brown7304c342012-05-11 18:42:42 -0700313 private static native void nativeAcquireWakeLock(int lock, String id);
314 private static native void nativeReleaseWakeLock(String id);
315 private static native int nativeSetScreenState(boolean on);
316 private static native void nativeShutdown();
317 private static native void nativeReboot(String reason) throws IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800318
319 /*
320 static PrintStream mLog;
321 static {
322 try {
323 mLog = new PrintStream("/data/power.log");
324 }
325 catch (FileNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800326 android.util.Slog.e(TAG, "Life is hard", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800327 }
328 }
329 static class Log {
330 static void d(String tag, String s) {
331 mLog.println(s);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800332 android.util.Slog.d(tag, s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800333 }
334 static void i(String tag, String s) {
335 mLog.println(s);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800336 android.util.Slog.i(tag, s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337 }
338 static void w(String tag, String s) {
339 mLog.println(s);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800340 android.util.Slog.w(tag, s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800341 }
342 static void e(String tag, String s) {
343 mLog.println(s);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800344 android.util.Slog.e(tag, s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800345 }
346 }
347 */
348
349 /**
350 * This class works around a deadlock between the lock in PowerManager.WakeLock
351 * and our synchronizing on mLocks. PowerManager.WakeLock synchronizes on its
352 * mToken object so it can be accessed from any thread, but it calls into here
353 * with its lock held. This class is essentially a reimplementation of
354 * PowerManager.WakeLock, but without that extra synchronized block, because we'll
355 * only call it with our own locks held.
356 */
357 private class UnsynchronizedWakeLock {
358 int mFlags;
359 String mTag;
360 IBinder mToken;
361 int mCount = 0;
362 boolean mRefCounted;
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -0500363 boolean mHeld;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800364
365 UnsynchronizedWakeLock(int flags, String tag, boolean refCounted) {
366 mFlags = flags;
367 mTag = tag;
368 mToken = new Binder();
369 mRefCounted = refCounted;
370 }
371
372 public void acquire() {
373 if (!mRefCounted || mCount++ == 0) {
374 long ident = Binder.clearCallingIdentity();
375 try {
376 PowerManagerService.this.acquireWakeLockLocked(mFlags, mToken,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700377 MY_UID, MY_PID, mTag, null);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -0500378 mHeld = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800379 } finally {
380 Binder.restoreCallingIdentity(ident);
381 }
382 }
383 }
384
385 public void release() {
386 if (!mRefCounted || --mCount == 0) {
Mike Lockwood0e39ea82009-11-18 15:37:10 -0500387 PowerManagerService.this.releaseWakeLockLocked(mToken, 0, false);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -0500388 mHeld = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389 }
390 if (mCount < 0) {
391 throw new RuntimeException("WakeLock under-locked " + mTag);
392 }
393 }
394
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -0500395 public boolean isHeld()
396 {
397 return mHeld;
398 }
399
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800400 public String toString() {
401 return "UnsynchronizedWakeLock(mFlags=0x" + Integer.toHexString(mFlags)
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -0500402 + " mCount=" + mCount + " mHeld=" + mHeld + ")";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800403 }
404 }
405
406 private final class BatteryReceiver extends BroadcastReceiver {
407 @Override
408 public void onReceive(Context context, Intent intent) {
409 synchronized (mLocks) {
410 boolean wasPowered = mIsPowered;
411 mIsPowered = mBatteryService.isPowered();
412
413 if (mIsPowered != wasPowered) {
414 // update mStayOnWhilePluggedIn wake lock
415 updateWakeLockLocked();
416
417 // treat plugging and unplugging the devices as a user activity.
418 // users find it disconcerting when they unplug the device
419 // and it shuts off right away.
Mike Lockwood84a89342010-03-01 21:28:58 -0500420 // to avoid turning on the screen when unplugging, we only trigger
421 // user activity when screen was already on.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800422 // temporarily set mUserActivityAllowed to true so this will work
423 // even when the keyguard is on.
Joe Onorato6d747652010-10-11 15:15:31 -0700424 // However, you can also set config_unplugTurnsOnScreen to have it
425 // turn on. Some devices want this because they don't have a
426 // charging LED.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800427 synchronized (mLocks) {
Joe Onorato6d747652010-10-11 15:15:31 -0700428 if (!wasPowered || (mPowerState & SCREEN_ON_BIT) != 0 ||
429 mUnplugTurnsOnScreen) {
Mike Lockwood84a89342010-03-01 21:28:58 -0500430 forceUserActivityLocked();
431 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800432 }
433 }
434 }
435 }
436 }
437
Mike Lockwood2d7bb812009-11-15 18:12:22 -0500438 private final class BootCompletedReceiver extends BroadcastReceiver {
439 @Override
440 public void onReceive(Context context, Intent intent) {
441 bootCompleted();
442 }
443 }
444
Mike Lockwoodb2865412010-02-02 22:40:33 -0500445 private final class DockReceiver extends BroadcastReceiver {
446 @Override
447 public void onReceive(Context context, Intent intent) {
448 int state = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
449 Intent.EXTRA_DOCK_STATE_UNDOCKED);
450 dockStateChanged(state);
451 }
452 }
453
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800454 /**
455 * Set the setting that determines whether the device stays on when plugged in.
456 * The argument is a bit string, with each bit specifying a power source that,
457 * when the device is connected to that source, causes the device to stay on.
458 * See {@link android.os.BatteryManager} for the list of power sources that
459 * can be specified. Current values include {@link android.os.BatteryManager#BATTERY_PLUGGED_AC}
460 * and {@link android.os.BatteryManager#BATTERY_PLUGGED_USB}
461 * @param val an {@code int} containing the bits that specify which power sources
462 * should cause the device to stay on.
463 */
464 public void setStayOnSetting(int val) {
465 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS, null);
466 Settings.System.putInt(mContext.getContentResolver(),
467 Settings.System.STAY_ON_WHILE_PLUGGED_IN, val);
468 }
469
Dianne Hackborndf83afa2010-01-20 13:37:26 -0800470 public void setMaximumScreenOffTimeount(int timeMs) {
471 mContext.enforceCallingOrSelfPermission(
472 android.Manifest.permission.WRITE_SECURE_SETTINGS, null);
473 synchronized (mLocks) {
474 mMaximumScreenOffTimeout = timeMs;
475 // recalculate everything
476 setScreenOffTimeoutsLocked();
477 }
478 }
479
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800480 private class SettingsObserver implements Observer {
Amith Yamasani8b619832010-09-22 16:11:59 -0700481 private int getInt(String name, int defValue) {
482 ContentValues values = mSettings.getValues(name);
483 Integer iVal = values != null ? values.getAsInteger(Settings.System.VALUE) : null;
484 return iVal != null ? iVal : defValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800485 }
486
Joe Onorato609695d2010-10-14 14:57:49 -0700487 private float getFloat(String name, float defValue) {
488 ContentValues values = mSettings.getValues(name);
489 Float fVal = values != null ? values.getAsFloat(Settings.System.VALUE) : null;
490 return fVal != null ? fVal : defValue;
491 }
492
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800493 public void update(Observable o, Object arg) {
494 synchronized (mLocks) {
Amith Yamasani8b619832010-09-22 16:11:59 -0700495 // STAY_ON_WHILE_PLUGGED_IN, default to when plugged into AC
496 mStayOnConditions = getInt(STAY_ON_WHILE_PLUGGED_IN,
497 BatteryManager.BATTERY_PLUGGED_AC);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800498 updateWakeLockLocked();
499
Amith Yamasani8b619832010-09-22 16:11:59 -0700500 // SCREEN_OFF_TIMEOUT, default to 15 seconds
501 mScreenOffTimeoutSetting = getInt(SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800502
Joe Onorato609695d2010-10-14 14:57:49 -0700503 // DIM_SCREEN
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800504 //mDimScreen = getInt(DIM_SCREEN) != 0;
505
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800506 mScreenBrightnessSetting = getInt(SCREEN_BRIGHTNESS, DEFAULT_SCREEN_BRIGHTNESS);
Dianne Hackborn518a3d82012-05-09 16:30:49 -0700507 mLightSensorAdjustSetting = 0; //getFloat(SCREEN_AUTO_BRIGHTNESS_ADJ, 0);
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800508
Amith Yamasani8b619832010-09-22 16:11:59 -0700509 // SCREEN_BRIGHTNESS_MODE, default to manual
510 setScreenBrightnessMode(getInt(SCREEN_BRIGHTNESS_MODE,
511 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL));
Mike Lockwooddc3494e2009-10-14 21:17:09 -0700512
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800513 // recalculate everything
514 setScreenOffTimeoutsLocked();
Joe Onorato609695d2010-10-14 14:57:49 -0700515
Jim Miller92e66dd2012-02-21 18:57:12 -0800516 mWindowScaleAnimation = getFloat(WINDOW_ANIMATION_SCALE, 1.0f);
Joe Onorato609695d2010-10-14 14:57:49 -0700517 final float transitionScale = getFloat(TRANSITION_ANIMATION_SCALE, 1.0f);
518 mAnimationSetting = 0;
Jim Miller92e66dd2012-02-21 18:57:12 -0800519 if (mWindowScaleAnimation > 0.5f) {
Joe Onorato609695d2010-10-14 14:57:49 -0700520 mAnimationSetting |= ANIM_SETTING_OFF;
521 }
522 if (transitionScale > 0.5f) {
523 // Uncomment this if you want the screen-on animation.
524 // mAnimationSetting |= ANIM_SETTING_ON;
525 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800526 }
527 }
528 }
529
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700530 PowerManagerService() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800531 // Hack to get our uid... should have a func for this.
532 long token = Binder.clearCallingIdentity();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700533 MY_UID = Process.myUid();
534 MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800535 Binder.restoreCallingIdentity(token);
536
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800537 // assume nothing is on yet
538 mUserState = mPowerState = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800539
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800540 // Add ourself to the Watchdog monitors.
541 Watchdog.getInstance().addMonitor(this);
Jeff Brown7304c342012-05-11 18:42:42 -0700542
543 nativeInit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800544 }
545
546 private ContentQueryMap mSettings;
547
Mike Lockwood3a322132009-11-24 00:30:52 -0500548 void init(Context context, LightsService lights, IActivityManager activity,
The Android Open Source Project10592532009-03-18 17:39:46 -0700549 BatteryService battery) {
Mike Lockwood3a322132009-11-24 00:30:52 -0500550 mLightsService = lights;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800551 mContext = context;
552 mActivityService = activity;
553 mBatteryStats = BatteryStatsService.getService();
554 mBatteryService = battery;
555
Mike Lockwood3cb67a32009-11-27 14:25:58 -0500556 mLcdLight = lights.getLight(LightsService.LIGHT_ID_BACKLIGHT);
557 mButtonLight = lights.getLight(LightsService.LIGHT_ID_BUTTONS);
558 mKeyboardLight = lights.getLight(LightsService.LIGHT_ID_KEYBOARD);
559 mAttentionLight = lights.getLight(LightsService.LIGHT_ID_ATTENTION);
Mike Lockwood3a74bd32011-08-12 13:55:22 -0700560 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
Mike Lockwood3cb67a32009-11-27 14:25:58 -0500561
Joe Onoratob08a1af2010-10-11 19:28:58 -0700562 mInitComplete = false;
Jim Miller92e66dd2012-02-21 18:57:12 -0800563 mScreenBrightnessAnimator = new ScreenBrightnessAnimator("mScreenBrightnessUpdaterThread",
564 Process.THREAD_PRIORITY_DISPLAY);
565 mScreenBrightnessAnimator.start();
Joe Onoratob08a1af2010-10-11 19:28:58 -0700566
Jim Miller92e66dd2012-02-21 18:57:12 -0800567 synchronized (mScreenBrightnessAnimator) {
Joe Onoratob08a1af2010-10-11 19:28:58 -0700568 while (!mInitComplete) {
569 try {
Jim Miller92e66dd2012-02-21 18:57:12 -0800570 mScreenBrightnessAnimator.wait();
Joe Onoratob08a1af2010-10-11 19:28:58 -0700571 } catch (InterruptedException e) {
572 // Ignore
573 }
574 }
575 }
Jim Miller92e66dd2012-02-21 18:57:12 -0800576
Joe Onoratob08a1af2010-10-11 19:28:58 -0700577 mInitComplete = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800578 mHandlerThread = new HandlerThread("PowerManagerService") {
579 @Override
580 protected void onLooperPrepared() {
581 super.onLooperPrepared();
582 initInThread();
583 }
584 };
585 mHandlerThread.start();
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800586
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800587 synchronized (mHandlerThread) {
588 while (!mInitComplete) {
589 try {
590 mHandlerThread.wait();
591 } catch (InterruptedException e) {
592 // Ignore
593 }
594 }
595 }
Jim Miller92e66dd2012-02-21 18:57:12 -0800596
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700597 synchronized (mLocks) {
598 updateNativePowerStateLocked();
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700599 // We make sure to start out with the screen on due to user activity.
600 // (They did just boot their device, after all.)
601 forceUserActivityLocked();
Dianne Hackborn40011092011-09-22 13:37:48 -0700602 mInitialized = true;
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700603 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800604 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800606 void initInThread() {
607 mHandler = new Handler();
608
609 mBroadcastWakeLock = new UnsynchronizedWakeLock(
Joe Onorato128e7292009-03-24 18:41:31 -0700610 PowerManager.PARTIAL_WAKE_LOCK, "sleep_broadcast", true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800611 mStayOnWhilePluggedInScreenDimLock = new UnsynchronizedWakeLock(
612 PowerManager.SCREEN_DIM_WAKE_LOCK, "StayOnWhilePluggedIn Screen Dim", false);
613 mStayOnWhilePluggedInPartialLock = new UnsynchronizedWakeLock(
614 PowerManager.PARTIAL_WAKE_LOCK, "StayOnWhilePluggedIn Partial", false);
615 mPreventScreenOnPartialLock = new UnsynchronizedWakeLock(
616 PowerManager.PARTIAL_WAKE_LOCK, "PreventScreenOn Partial", false);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -0500617 mProximityPartialLock = new UnsynchronizedWakeLock(
618 PowerManager.PARTIAL_WAKE_LOCK, "Proximity Partial", false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800619
620 mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
621 mScreenOnIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
622 mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF);
623 mScreenOffIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
624
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700625 Resources resources = mContext.getResources();
Mike Lockwoodaa66ea82009-10-31 16:31:27 -0400626
Joe Onoratob08a1af2010-10-11 19:28:58 -0700627 mAnimateScreenLights = resources.getBoolean(
628 com.android.internal.R.bool.config_animateScreenLights);
629
Joe Onorato6d747652010-10-11 15:15:31 -0700630 mUnplugTurnsOnScreen = resources.getBoolean(
631 com.android.internal.R.bool.config_unplugTurnsOnScreen);
632
Mike Lockwoodeb6456b2011-09-13 15:24:02 -0400633 mScreenBrightnessDim = resources.getInteger(
634 com.android.internal.R.integer.config_screenBrightnessDim);
635
Mike Lockwoodaa66ea82009-10-31 16:31:27 -0400636 // read settings for auto-brightness
637 mUseSoftwareAutoBrightness = resources.getBoolean(
638 com.android.internal.R.bool.config_automatic_brightness_available);
Mike Lockwoodaa66ea82009-10-31 16:31:27 -0400639 if (mUseSoftwareAutoBrightness) {
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700640 mAutoBrightnessLevels = resources.getIntArray(
641 com.android.internal.R.array.config_autoBrightnessLevels);
642 mLcdBacklightValues = resources.getIntArray(
643 com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
644 mButtonBacklightValues = resources.getIntArray(
645 com.android.internal.R.array.config_autoBrightnessButtonBacklightValues);
646 mKeyboardBacklightValues = resources.getIntArray(
647 com.android.internal.R.array.config_autoBrightnessKeyboardBacklightValues);
Mike Lockwood20ee6f22009-11-07 20:33:47 -0500648 mLightSensorWarmupTime = resources.getInteger(
649 com.android.internal.R.integer.config_lightSensorWarmupTime);
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700650 }
Mike Lockwooddc3494e2009-10-14 21:17:09 -0700651
652 ContentResolver resolver = mContext.getContentResolver();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800653 Cursor settingsCursor = resolver.query(Settings.System.CONTENT_URI, null,
654 "(" + Settings.System.NAME + "=?) or ("
655 + Settings.System.NAME + "=?) or ("
Mike Lockwooddc3494e2009-10-14 21:17:09 -0700656 + Settings.System.NAME + "=?) or ("
Joe Onorato609695d2010-10-14 14:57:49 -0700657 + Settings.System.NAME + "=?) or ("
658 + Settings.System.NAME + "=?) or ("
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800659 + Settings.System.NAME + "=?) or ("
660 + Settings.System.NAME + "=?) or ("
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800661 + Settings.System.NAME + "=?)",
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800662 new String[]{STAY_ON_WHILE_PLUGGED_IN, SCREEN_OFF_TIMEOUT, DIM_SCREEN, SCREEN_BRIGHTNESS,
Dianne Hackborn518a3d82012-05-09 16:30:49 -0700663 SCREEN_BRIGHTNESS_MODE, /*SCREEN_AUTO_BRIGHTNESS_ADJ,*/
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800664 WINDOW_ANIMATION_SCALE, TRANSITION_ANIMATION_SCALE},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800665 null);
666 mSettings = new ContentQueryMap(settingsCursor, Settings.System.NAME, true, mHandler);
667 SettingsObserver settingsObserver = new SettingsObserver();
668 mSettings.addObserver(settingsObserver);
669
670 // pretend that the settings changed so we will get their initial state
671 settingsObserver.update(mSettings, null);
672
673 // register for the battery changed notifications
674 IntentFilter filter = new IntentFilter();
675 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
676 mContext.registerReceiver(new BatteryReceiver(), filter);
Mike Lockwood2d7bb812009-11-15 18:12:22 -0500677 filter = new IntentFilter();
678 filter.addAction(Intent.ACTION_BOOT_COMPLETED);
679 mContext.registerReceiver(new BootCompletedReceiver(), filter);
Mike Lockwoodb2865412010-02-02 22:40:33 -0500680 filter = new IntentFilter();
681 filter.addAction(Intent.ACTION_DOCK_EVENT);
682 mContext.registerReceiver(new DockReceiver(), filter);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800683
Doug Zongker43866e02010-01-07 12:09:54 -0800684 // Listen for secure settings changes
685 mContext.getContentResolver().registerContentObserver(
686 Settings.Secure.CONTENT_URI, true,
687 new ContentObserver(new Handler()) {
688 public void onChange(boolean selfChange) {
689 updateSettingsValues();
690 }
691 });
692 updateSettingsValues();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800693
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800694 synchronized (mHandlerThread) {
695 mInitComplete = true;
696 mHandlerThread.notifyAll();
697 }
698 }
699
Jeff Brown7304c342012-05-11 18:42:42 -0700700 /**
701 * Low-level function turn the device off immediately, without trying
702 * to be clean. Most people should use
703 * {@link com.android.server.pm.internal.app.ShutdownThread} for a clean shutdown.
704 */
705 public static void lowLevelShutdown() {
706 nativeShutdown();
707 }
708
709 /**
710 * Low-level function to reboot the device.
711 *
712 * @param reason code to pass to the kernel (e.g. "recovery"), or null.
713 * @throws IOException if reboot fails for some reason (eg, lack of
714 * permission)
715 */
716 public static void lowLevelReboot(String reason) throws IOException {
717 nativeReboot(reason);
718 }
719
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800720 private class WakeLock implements IBinder.DeathRecipient
721 {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700722 WakeLock(int f, IBinder b, String t, int u, int p) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800723 super();
724 flags = f;
725 binder = b;
726 tag = t;
727 uid = u == MY_UID ? Process.SYSTEM_UID : u;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700728 pid = p;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800729 if (u != MY_UID || (
730 !"KEEP_SCREEN_ON_FLAG".equals(tag)
731 && !"KeyInputQueue".equals(tag))) {
732 monitorType = (f & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK
733 ? BatteryStats.WAKE_TYPE_PARTIAL
734 : BatteryStats.WAKE_TYPE_FULL;
735 } else {
736 monitorType = -1;
737 }
738 try {
739 b.linkToDeath(this, 0);
740 } catch (RemoteException e) {
741 binderDied();
742 }
743 }
744 public void binderDied() {
745 synchronized (mLocks) {
Mike Lockwood0e39ea82009-11-18 15:37:10 -0500746 releaseWakeLockLocked(this.binder, 0, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800747 }
748 }
749 final int flags;
750 final IBinder binder;
751 final String tag;
752 final int uid;
Mike Lockwoodf5bd0922010-03-22 17:10:15 -0400753 final int pid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800754 final int monitorType;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700755 WorkSource ws;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800756 boolean activated = true;
757 int minState;
758 }
759
760 private void updateWakeLockLocked() {
761 if (mStayOnConditions != 0 && mBatteryService.isPowered(mStayOnConditions)) {
762 // keep the device on if we're plugged in and mStayOnWhilePluggedIn is set.
763 mStayOnWhilePluggedInScreenDimLock.acquire();
764 mStayOnWhilePluggedInPartialLock.acquire();
765 } else {
766 mStayOnWhilePluggedInScreenDimLock.release();
767 mStayOnWhilePluggedInPartialLock.release();
768 }
769 }
770
771 private boolean isScreenLock(int flags)
772 {
773 int n = flags & LOCK_MASK;
774 return n == PowerManager.FULL_WAKE_LOCK
775 || n == PowerManager.SCREEN_BRIGHT_WAKE_LOCK
Joe Onorato8274a0e2010-10-05 17:38:09 -0400776 || n == PowerManager.SCREEN_DIM_WAKE_LOCK
777 || n == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800778 }
779
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700780 void enforceWakeSourcePermission(int uid, int pid) {
781 if (uid == Process.myUid()) {
782 return;
783 }
784 mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
785 pid, uid, null);
786 }
787
788 public void acquireWakeLock(int flags, IBinder lock, String tag, WorkSource ws) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800789 int uid = Binder.getCallingUid();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700790 int pid = Binder.getCallingPid();
Michael Chane96440f2009-05-06 10:27:36 -0700791 if (uid != Process.myUid()) {
792 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
793 }
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700794 if (ws != null) {
795 enforceWakeSourcePermission(uid, pid);
796 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800797 long ident = Binder.clearCallingIdentity();
798 try {
799 synchronized (mLocks) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700800 acquireWakeLockLocked(flags, lock, uid, pid, tag, ws);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800801 }
802 } finally {
803 Binder.restoreCallingIdentity(ident);
804 }
805 }
806
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700807 void noteStartWakeLocked(WakeLock wl, WorkSource ws) {
Dianne Hackborn70be1672010-09-14 11:13:03 -0700808 if (wl.monitorType >= 0) {
809 long origId = Binder.clearCallingIdentity();
810 try {
811 if (ws != null) {
812 mBatteryStats.noteStartWakelockFromSource(ws, wl.pid, wl.tag,
813 wl.monitorType);
814 } else {
815 mBatteryStats.noteStartWakelock(wl.uid, wl.pid, wl.tag, wl.monitorType);
816 }
817 } catch (RemoteException e) {
818 // Ignore
819 } finally {
820 Binder.restoreCallingIdentity(origId);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700821 }
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700822 }
823 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800824
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700825 void noteStopWakeLocked(WakeLock wl, WorkSource ws) {
Dianne Hackborn70be1672010-09-14 11:13:03 -0700826 if (wl.monitorType >= 0) {
827 long origId = Binder.clearCallingIdentity();
828 try {
829 if (ws != null) {
830 mBatteryStats.noteStopWakelockFromSource(ws, wl.pid, wl.tag,
831 wl.monitorType);
832 } else {
833 mBatteryStats.noteStopWakelock(wl.uid, wl.pid, wl.tag, wl.monitorType);
834 }
835 } catch (RemoteException e) {
836 // Ignore
837 } finally {
838 Binder.restoreCallingIdentity(origId);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700839 }
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700840 }
841 }
842
843 public void acquireWakeLockLocked(int flags, IBinder lock, int uid, int pid, String tag,
844 WorkSource ws) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800845 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800846 Slog.d(TAG, "acquireWakeLock flags=0x" + Integer.toHexString(flags) + " tag=" + tag);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800847 }
848
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700849 if (ws != null && ws.size() == 0) {
850 ws = null;
851 }
852
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800853 int index = mLocks.getIndex(lock);
854 WakeLock wl;
855 boolean newlock;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700856 boolean diffsource;
857 WorkSource oldsource;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800858 if (index < 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700859 wl = new WakeLock(flags, lock, tag, uid, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800860 switch (wl.flags & LOCK_MASK)
861 {
862 case PowerManager.FULL_WAKE_LOCK:
Mike Lockwood4984e732009-11-01 08:16:33 -0500863 if (mUseSoftwareAutoBrightness) {
Mike Lockwood3333fa42009-10-26 14:50:42 -0400864 wl.minState = SCREEN_BRIGHT;
865 } else {
866 wl.minState = (mKeyboardVisible ? ALL_BRIGHT : SCREEN_BUTTON_BRIGHT);
867 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800868 break;
869 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
870 wl.minState = SCREEN_BRIGHT;
871 break;
872 case PowerManager.SCREEN_DIM_WAKE_LOCK:
873 wl.minState = SCREEN_DIM;
874 break;
875 case PowerManager.PARTIAL_WAKE_LOCK:
Mike Lockwoodbc706a02009-07-27 13:50:57 -0700876 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800877 break;
878 default:
879 // just log and bail. we're in the server, so don't
880 // throw an exception.
Joe Onorato8a9b2202010-02-26 18:56:32 -0800881 Slog.e(TAG, "bad wakelock type for lock '" + tag + "' "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800882 + " flags=" + flags);
883 return;
884 }
885 mLocks.addLock(wl);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700886 if (ws != null) {
887 wl.ws = new WorkSource(ws);
888 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800889 newlock = true;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700890 diffsource = false;
891 oldsource = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800892 } else {
893 wl = mLocks.get(index);
894 newlock = false;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700895 oldsource = wl.ws;
896 if (oldsource != null) {
897 if (ws == null) {
898 wl.ws = null;
899 diffsource = true;
900 } else {
901 diffsource = oldsource.diff(ws);
902 }
903 } else if (ws != null) {
904 diffsource = true;
905 } else {
906 diffsource = false;
907 }
908 if (diffsource) {
909 wl.ws = new WorkSource(ws);
910 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800911 }
912 if (isScreenLock(flags)) {
913 // if this causes a wakeup, we reactivate all of the locks and
914 // set it to whatever they want. otherwise, we modulate that
915 // by the current state so we never turn it more on than
916 // it already is.
Joe Onorato8274a0e2010-10-05 17:38:09 -0400917 if ((flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) {
918 mProximityWakeLockCount++;
919 if (mProximityWakeLockCount == 1) {
920 enableProximityLockLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800921 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800922 } else {
Joe Onorato8274a0e2010-10-05 17:38:09 -0400923 if ((wl.flags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {
924 int oldWakeLockState = mWakeLockState;
925 mWakeLockState = mLocks.reactivateScreenLocksLocked();
Mike Lockwooddb97f602011-09-02 11:59:08 -0400926
927 // Disable proximity sensor if if user presses power key while we are in the
928 // "waiting for proximity sensor to go negative" state.
929 if ((mWakeLockState & SCREEN_ON_BIT) != 0
930 && mProximitySensorActive && mProximityWakeLockCount == 0) {
931 mProximitySensorActive = false;
932 }
933
Joe Onorato8274a0e2010-10-05 17:38:09 -0400934 if (mSpew) {
935 Slog.d(TAG, "wakeup here mUserState=0x" + Integer.toHexString(mUserState)
936 + " mWakeLockState=0x"
937 + Integer.toHexString(mWakeLockState)
938 + " previous wakeLockState=0x"
939 + Integer.toHexString(oldWakeLockState));
940 }
941 } else {
942 if (mSpew) {
943 Slog.d(TAG, "here mUserState=0x" + Integer.toHexString(mUserState)
944 + " mLocks.gatherState()=0x"
945 + Integer.toHexString(mLocks.gatherState())
946 + " mWakeLockState=0x" + Integer.toHexString(mWakeLockState));
947 }
948 mWakeLockState = (mUserState | mWakeLockState) & mLocks.gatherState();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800949 }
Joe Onorato8274a0e2010-10-05 17:38:09 -0400950 setPowerState(mWakeLockState | mUserState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800951 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800952 }
953 else if ((flags & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK) {
954 if (newlock) {
955 mPartialCount++;
956 if (mPartialCount == 1) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800957 if (LOG_PARTIAL_WL) EventLog.writeEvent(EventLogTags.POWER_PARTIAL_WAKE_STATE, 1, tag);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800958 }
959 }
Jeff Brown7304c342012-05-11 18:42:42 -0700960 nativeAcquireWakeLock(PARTIAL_WAKE_LOCK_ID, PARTIAL_NAME);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800961 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800962
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700963 if (diffsource) {
964 // If the lock sources have changed, need to first release the
965 // old ones.
966 noteStopWakeLocked(wl, oldsource);
967 }
968 if (newlock || diffsource) {
969 noteStartWakeLocked(wl, ws);
970 }
971 }
972
973 public void updateWakeLockWorkSource(IBinder lock, WorkSource ws) {
974 int uid = Binder.getCallingUid();
975 int pid = Binder.getCallingPid();
976 if (ws != null && ws.size() == 0) {
977 ws = null;
978 }
979 if (ws != null) {
980 enforceWakeSourcePermission(uid, pid);
981 }
Dianne Hackborn70be1672010-09-14 11:13:03 -0700982 synchronized (mLocks) {
983 int index = mLocks.getIndex(lock);
984 if (index < 0) {
985 throw new IllegalArgumentException("Wake lock not active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800986 }
Dianne Hackborn70be1672010-09-14 11:13:03 -0700987 WakeLock wl = mLocks.get(index);
988 WorkSource oldsource = wl.ws;
989 wl.ws = ws != null ? new WorkSource(ws) : null;
990 noteStopWakeLocked(wl, oldsource);
991 noteStartWakeLocked(wl, ws);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800992 }
993 }
994
Mike Lockwood0e39ea82009-11-18 15:37:10 -0500995 public void releaseWakeLock(IBinder lock, int flags) {
Michael Chane96440f2009-05-06 10:27:36 -0700996 int uid = Binder.getCallingUid();
997 if (uid != Process.myUid()) {
998 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
999 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001000
1001 synchronized (mLocks) {
Mike Lockwood0e39ea82009-11-18 15:37:10 -05001002 releaseWakeLockLocked(lock, flags, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001003 }
1004 }
1005
Mike Lockwood0e39ea82009-11-18 15:37:10 -05001006 private void releaseWakeLockLocked(IBinder lock, int flags, boolean death) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001007 WakeLock wl = mLocks.removeLock(lock);
1008 if (wl == null) {
1009 return;
1010 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001011
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001012 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001013 Slog.d(TAG, "releaseWakeLock flags=0x"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001014 + Integer.toHexString(wl.flags) + " tag=" + wl.tag);
1015 }
1016
1017 if (isScreenLock(wl.flags)) {
Joe Onorato8274a0e2010-10-05 17:38:09 -04001018 if ((wl.flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) {
1019 mProximityWakeLockCount--;
1020 if (mProximityWakeLockCount == 0) {
1021 if (mProximitySensorActive &&
1022 ((flags & PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE) != 0)) {
1023 // wait for proximity sensor to go negative before disabling sensor
1024 if (mDebugProximitySensor) {
1025 Slog.d(TAG, "waiting for proximity sensor to go negative");
1026 }
1027 } else {
1028 disableProximityLockLocked();
1029 }
1030 }
1031 } else {
1032 mWakeLockState = mLocks.gatherState();
1033 // goes in the middle to reduce flicker
1034 if ((wl.flags & PowerManager.ON_AFTER_RELEASE) != 0) {
1035 userActivity(SystemClock.uptimeMillis(), -1, false, OTHER_EVENT, false);
1036 }
1037 setPowerState(mWakeLockState | mUserState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001038 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001039 }
1040 else if ((wl.flags & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK) {
1041 mPartialCount--;
1042 if (mPartialCount == 0) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001043 if (LOG_PARTIAL_WL) EventLog.writeEvent(EventLogTags.POWER_PARTIAL_WAKE_STATE, 0, wl.tag);
Jeff Brown7304c342012-05-11 18:42:42 -07001044 nativeReleaseWakeLock(PARTIAL_NAME);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001045 }
1046 }
1047 // Unlink the lock from the binder.
1048 wl.binder.unlinkToDeath(wl, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001049
Dianne Hackborn70be1672010-09-14 11:13:03 -07001050 noteStopWakeLocked(wl, wl.ws);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001051 }
1052
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001053 private class PokeLock implements IBinder.DeathRecipient
1054 {
1055 PokeLock(int p, IBinder b, String t) {
1056 super();
1057 this.pokey = p;
1058 this.binder = b;
1059 this.tag = t;
1060 try {
1061 b.linkToDeath(this, 0);
1062 } catch (RemoteException e) {
1063 binderDied();
1064 }
1065 }
1066 public void binderDied() {
1067 setPokeLock(0, this.binder, this.tag);
1068 }
1069 int pokey;
1070 IBinder binder;
1071 String tag;
1072 boolean awakeOnSet;
1073 }
1074
1075 public void setPokeLock(int pokey, IBinder token, String tag) {
1076 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1077 if (token == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001078 Slog.e(TAG, "setPokeLock got null token for tag='" + tag + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001079 return;
1080 }
1081
1082 if ((pokey & POKE_LOCK_TIMEOUT_MASK) == POKE_LOCK_TIMEOUT_MASK) {
1083 throw new IllegalArgumentException("setPokeLock can't have both POKE_LOCK_SHORT_TIMEOUT"
1084 + " and POKE_LOCK_MEDIUM_TIMEOUT");
1085 }
1086
1087 synchronized (mLocks) {
1088 if (pokey != 0) {
1089 PokeLock p = mPokeLocks.get(token);
1090 int oldPokey = 0;
1091 if (p != null) {
1092 oldPokey = p.pokey;
1093 p.pokey = pokey;
1094 } else {
1095 p = new PokeLock(pokey, token, tag);
1096 mPokeLocks.put(token, p);
1097 }
1098 int oldTimeout = oldPokey & POKE_LOCK_TIMEOUT_MASK;
1099 int newTimeout = pokey & POKE_LOCK_TIMEOUT_MASK;
1100 if (((mPowerState & SCREEN_ON_BIT) == 0) && (oldTimeout != newTimeout)) {
1101 p.awakeOnSet = true;
1102 }
1103 } else {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07001104 PokeLock rLock = mPokeLocks.remove(token);
1105 if (rLock != null) {
1106 token.unlinkToDeath(rLock, 0);
1107 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001108 }
1109
1110 int oldPokey = mPokey;
1111 int cumulative = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001112 boolean awakeOnSet = false;
1113 for (PokeLock p: mPokeLocks.values()) {
1114 cumulative |= p.pokey;
1115 if (p.awakeOnSet) {
1116 awakeOnSet = true;
1117 }
1118 }
1119 mPokey = cumulative;
1120 mPokeAwakeOnSet = awakeOnSet;
1121
1122 int oldCumulativeTimeout = oldPokey & POKE_LOCK_TIMEOUT_MASK;
1123 int newCumulativeTimeout = pokey & POKE_LOCK_TIMEOUT_MASK;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001124
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001125 if (oldCumulativeTimeout != newCumulativeTimeout) {
1126 setScreenOffTimeoutsLocked();
1127 // reset the countdown timer, but use the existing nextState so it doesn't
1128 // change anything
1129 setTimeoutLocked(SystemClock.uptimeMillis(), mTimeoutTask.nextState);
1130 }
1131 }
1132 }
1133
1134 private static String lockType(int type)
1135 {
1136 switch (type)
1137 {
1138 case PowerManager.FULL_WAKE_LOCK:
David Brown251faa62009-08-02 22:04:36 -07001139 return "FULL_WAKE_LOCK ";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001140 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
David Brown251faa62009-08-02 22:04:36 -07001141 return "SCREEN_BRIGHT_WAKE_LOCK ";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001142 case PowerManager.SCREEN_DIM_WAKE_LOCK:
David Brown251faa62009-08-02 22:04:36 -07001143 return "SCREEN_DIM_WAKE_LOCK ";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001144 case PowerManager.PARTIAL_WAKE_LOCK:
David Brown251faa62009-08-02 22:04:36 -07001145 return "PARTIAL_WAKE_LOCK ";
1146 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
1147 return "PROXIMITY_SCREEN_OFF_WAKE_LOCK";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001148 default:
David Brown251faa62009-08-02 22:04:36 -07001149 return "??? ";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001150 }
1151 }
1152
1153 private static String dumpPowerState(int state) {
1154 return (((state & KEYBOARD_BRIGHT_BIT) != 0)
1155 ? "KEYBOARD_BRIGHT_BIT " : "")
1156 + (((state & SCREEN_BRIGHT_BIT) != 0)
1157 ? "SCREEN_BRIGHT_BIT " : "")
1158 + (((state & SCREEN_ON_BIT) != 0)
1159 ? "SCREEN_ON_BIT " : "")
jaiyoung.park15415f52012-06-01 15:06:22 +09001160 + (((state & BUTTON_BRIGHT_BIT) != 0)
1161 ? "BUTTON_BRIGHT_BIT " : "")
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001162 + (((state & BATTERY_LOW_BIT) != 0)
1163 ? "BATTERY_LOW_BIT " : "");
1164 }
1165
1166 @Override
1167 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1168 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
1169 != PackageManager.PERMISSION_GRANTED) {
1170 pw.println("Permission Denial: can't dump PowerManager from from pid="
1171 + Binder.getCallingPid()
1172 + ", uid=" + Binder.getCallingUid());
1173 return;
1174 }
1175
1176 long now = SystemClock.uptimeMillis();
1177
Mike Lockwoodca44df82010-02-25 13:48:49 -05001178 synchronized (mLocks) {
1179 pw.println("Power Manager State:");
1180 pw.println(" mIsPowered=" + mIsPowered
1181 + " mPowerState=" + mPowerState
1182 + " mScreenOffTime=" + (SystemClock.elapsedRealtime()-mScreenOffTime)
1183 + " ms");
1184 pw.println(" mPartialCount=" + mPartialCount);
1185 pw.println(" mWakeLockState=" + dumpPowerState(mWakeLockState));
1186 pw.println(" mUserState=" + dumpPowerState(mUserState));
1187 pw.println(" mPowerState=" + dumpPowerState(mPowerState));
1188 pw.println(" mLocks.gather=" + dumpPowerState(mLocks.gatherState()));
1189 pw.println(" mNextTimeout=" + mNextTimeout + " now=" + now
1190 + " " + ((mNextTimeout-now)/1000) + "s from now");
1191 pw.println(" mDimScreen=" + mDimScreen
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001192 + " mStayOnConditions=" + mStayOnConditions
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001193 + " mPreparingForScreenOn=" + mPreparingForScreenOn
1194 + " mSkippedScreenOn=" + mSkippedScreenOn);
Mike Lockwoodca44df82010-02-25 13:48:49 -05001195 pw.println(" mScreenOffReason=" + mScreenOffReason
1196 + " mUserState=" + mUserState);
1197 pw.println(" mBroadcastQueue={" + mBroadcastQueue[0] + ',' + mBroadcastQueue[1]
1198 + ',' + mBroadcastQueue[2] + "}");
1199 pw.println(" mBroadcastWhy={" + mBroadcastWhy[0] + ',' + mBroadcastWhy[1]
1200 + ',' + mBroadcastWhy[2] + "}");
1201 pw.println(" mPokey=" + mPokey + " mPokeAwakeonSet=" + mPokeAwakeOnSet);
1202 pw.println(" mKeyboardVisible=" + mKeyboardVisible
1203 + " mUserActivityAllowed=" + mUserActivityAllowed);
1204 pw.println(" mKeylightDelay=" + mKeylightDelay + " mDimDelay=" + mDimDelay
1205 + " mScreenOffDelay=" + mScreenOffDelay);
1206 pw.println(" mPreventScreenOn=" + mPreventScreenOn
1207 + " mScreenBrightnessOverride=" + mScreenBrightnessOverride
1208 + " mButtonBrightnessOverride=" + mButtonBrightnessOverride);
1209 pw.println(" mScreenOffTimeoutSetting=" + mScreenOffTimeoutSetting
1210 + " mMaximumScreenOffTimeout=" + mMaximumScreenOffTimeout);
1211 pw.println(" mLastScreenOnTime=" + mLastScreenOnTime);
1212 pw.println(" mBroadcastWakeLock=" + mBroadcastWakeLock);
1213 pw.println(" mStayOnWhilePluggedInScreenDimLock=" + mStayOnWhilePluggedInScreenDimLock);
1214 pw.println(" mStayOnWhilePluggedInPartialLock=" + mStayOnWhilePluggedInPartialLock);
1215 pw.println(" mPreventScreenOnPartialLock=" + mPreventScreenOnPartialLock);
1216 pw.println(" mProximityPartialLock=" + mProximityPartialLock);
1217 pw.println(" mProximityWakeLockCount=" + mProximityWakeLockCount);
1218 pw.println(" mProximitySensorEnabled=" + mProximitySensorEnabled);
1219 pw.println(" mProximitySensorActive=" + mProximitySensorActive);
1220 pw.println(" mProximityPendingValue=" + mProximityPendingValue);
1221 pw.println(" mLastProximityEventTime=" + mLastProximityEventTime);
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08001222 pw.println(" mLightSensorEnabled=" + mLightSensorEnabled
1223 + " mLightSensorAdjustSetting=" + mLightSensorAdjustSetting);
Mike Lockwoodca44df82010-02-25 13:48:49 -05001224 pw.println(" mLightSensorValue=" + mLightSensorValue
1225 + " mLightSensorPendingValue=" + mLightSensorPendingValue);
Craig Mautner291576e2012-06-07 19:58:58 -07001226 pw.println(" mHighestLightSensorValue=" + mHighestLightSensorValue
1227 + " mWaitingForFirstLightSensor=" + mWaitingForFirstLightSensor);
Jim Rodovichd102fea2010-09-02 12:30:49 -05001228 pw.println(" mLightSensorPendingDecrease=" + mLightSensorPendingDecrease
1229 + " mLightSensorPendingIncrease=" + mLightSensorPendingIncrease);
Mike Lockwoodca44df82010-02-25 13:48:49 -05001230 pw.println(" mLightSensorScreenBrightness=" + mLightSensorScreenBrightness
1231 + " mLightSensorButtonBrightness=" + mLightSensorButtonBrightness
1232 + " mLightSensorKeyboardBrightness=" + mLightSensorKeyboardBrightness);
1233 pw.println(" mUseSoftwareAutoBrightness=" + mUseSoftwareAutoBrightness);
1234 pw.println(" mAutoBrightessEnabled=" + mAutoBrightessEnabled);
Jim Miller92e66dd2012-02-21 18:57:12 -08001235 mScreenBrightnessAnimator.dump(pw, " mScreenBrightnessAnimator: ");
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001236
Mike Lockwoodca44df82010-02-25 13:48:49 -05001237 int N = mLocks.size();
1238 pw.println();
1239 pw.println("mLocks.size=" + N + ":");
1240 for (int i=0; i<N; i++) {
1241 WakeLock wl = mLocks.get(i);
1242 String type = lockType(wl.flags & LOCK_MASK);
1243 String acquireCausesWakeup = "";
1244 if ((wl.flags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {
1245 acquireCausesWakeup = "ACQUIRE_CAUSES_WAKEUP ";
1246 }
1247 String activated = "";
1248 if (wl.activated) {
1249 activated = " activated";
1250 }
1251 pw.println(" " + type + " '" + wl.tag + "'" + acquireCausesWakeup
Mike Lockwoodf5bd0922010-03-22 17:10:15 -04001252 + activated + " (minState=" + wl.minState + ", uid=" + wl.uid
1253 + ", pid=" + wl.pid + ")");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001254 }
Mike Lockwoodca44df82010-02-25 13:48:49 -05001255
1256 pw.println();
1257 pw.println("mPokeLocks.size=" + mPokeLocks.size() + ":");
1258 for (PokeLock p: mPokeLocks.values()) {
1259 pw.println(" poke lock '" + p.tag + "':"
Joe Onorato1a542c72010-11-08 09:48:20 -08001260 + ((p.pokey & POKE_LOCK_IGNORE_TOUCH_EVENTS) != 0
1261 ? " POKE_LOCK_IGNORE_TOUCH_EVENTS" : "")
Mike Lockwoodca44df82010-02-25 13:48:49 -05001262 + ((p.pokey & POKE_LOCK_SHORT_TIMEOUT) != 0
1263 ? " POKE_LOCK_SHORT_TIMEOUT" : "")
1264 + ((p.pokey & POKE_LOCK_MEDIUM_TIMEOUT) != 0
1265 ? " POKE_LOCK_MEDIUM_TIMEOUT" : ""));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001266 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001267
Mike Lockwoodca44df82010-02-25 13:48:49 -05001268 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001269 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001270 }
1271
Joe Onorato7999bff2010-07-24 11:50:05 -04001272 private void setTimeoutLocked(long now, int nextState) {
1273 setTimeoutLocked(now, -1, nextState);
1274 }
1275
1276 // If they gave a timeoutOverride it is the number of seconds
1277 // to screen-off. Figure out where in the countdown cycle we
1278 // should jump to.
Joe Onorato797e6882010-08-26 14:46:01 -04001279 private void setTimeoutLocked(long now, final long originalTimeoutOverride, int nextState) {
1280 long timeoutOverride = originalTimeoutOverride;
Mike Lockwood2d7bb812009-11-15 18:12:22 -05001281 if (mBootCompleted) {
Joe Onorato7999bff2010-07-24 11:50:05 -04001282 synchronized (mLocks) {
Joe Onorato7999bff2010-07-24 11:50:05 -04001283 long when = 0;
1284 if (timeoutOverride <= 0) {
1285 switch (nextState)
1286 {
1287 case SCREEN_BRIGHT:
1288 when = now + mKeylightDelay;
1289 break;
1290 case SCREEN_DIM:
1291 if (mDimDelay >= 0) {
1292 when = now + mDimDelay;
Andreas Huber84047bc2010-07-27 16:49:10 -07001293 break;
Joe Onorato7999bff2010-07-24 11:50:05 -04001294 } else {
1295 Slog.w(TAG, "mDimDelay=" + mDimDelay + " while trying to dim");
1296 }
1297 case SCREEN_OFF:
1298 synchronized (mLocks) {
1299 when = now + mScreenOffDelay;
1300 }
1301 break;
Andreas Huber84047bc2010-07-27 16:49:10 -07001302 default:
1303 when = now;
1304 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001305 }
Joe Onorato7999bff2010-07-24 11:50:05 -04001306 } else {
1307 override: {
1308 if (timeoutOverride <= mScreenOffDelay) {
1309 when = now + timeoutOverride;
1310 nextState = SCREEN_OFF;
1311 break override;
1312 }
1313 timeoutOverride -= mScreenOffDelay;
1314
1315 if (mDimDelay >= 0) {
1316 if (timeoutOverride <= mDimDelay) {
1317 when = now + timeoutOverride;
1318 nextState = SCREEN_DIM;
1319 break override;
1320 }
1321 timeoutOverride -= mDimDelay;
1322 }
1323
1324 when = now + timeoutOverride;
1325 nextState = SCREEN_BRIGHT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001326 }
Joe Onorato7999bff2010-07-24 11:50:05 -04001327 }
1328 if (mSpew) {
1329 Slog.d(TAG, "setTimeoutLocked now=" + now
1330 + " timeoutOverride=" + timeoutOverride
1331 + " nextState=" + nextState + " when=" + when);
1332 }
Joe Onorato797e6882010-08-26 14:46:01 -04001333
1334 mHandler.removeCallbacks(mTimeoutTask);
1335 mTimeoutTask.nextState = nextState;
1336 mTimeoutTask.remainingTimeoutOverride = timeoutOverride > 0
1337 ? (originalTimeoutOverride - timeoutOverride)
1338 : -1;
Joe Onorato7999bff2010-07-24 11:50:05 -04001339 mHandler.postAtTime(mTimeoutTask, when);
1340 mNextTimeout = when; // for debugging
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001341 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001342 }
1343 }
1344
1345 private void cancelTimerLocked()
1346 {
1347 mHandler.removeCallbacks(mTimeoutTask);
1348 mTimeoutTask.nextState = -1;
1349 }
1350
1351 private class TimeoutTask implements Runnable
1352 {
1353 int nextState; // access should be synchronized on mLocks
Joe Onorato797e6882010-08-26 14:46:01 -04001354 long remainingTimeoutOverride;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001355 public void run()
1356 {
1357 synchronized (mLocks) {
1358 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001359 Slog.d(TAG, "user activity timeout timed out nextState=" + this.nextState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001360 }
1361
1362 if (nextState == -1) {
1363 return;
1364 }
1365
1366 mUserState = this.nextState;
1367 setPowerState(this.nextState | mWakeLockState);
1368
1369 long now = SystemClock.uptimeMillis();
1370
1371 switch (this.nextState)
1372 {
1373 case SCREEN_BRIGHT:
1374 if (mDimDelay >= 0) {
Joe Onorato797e6882010-08-26 14:46:01 -04001375 setTimeoutLocked(now, remainingTimeoutOverride, SCREEN_DIM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001376 break;
1377 }
1378 case SCREEN_DIM:
Joe Onorato797e6882010-08-26 14:46:01 -04001379 setTimeoutLocked(now, remainingTimeoutOverride, SCREEN_OFF);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001380 break;
1381 }
1382 }
1383 }
1384 }
1385
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001386 private void sendNotificationLocked(boolean on, int why) {
1387 if (!mInitialized) {
1388 // No notifications sent until first initialization is done.
1389 // This is so that when we are moving from our initial state
1390 // which looks like the screen was off to it being on, we do not
1391 // go through the process of waiting for the higher-level user
1392 // space to be ready before turning up the display brightness.
1393 // (And also do not send needless broadcasts about the screen.)
1394 return;
1395 }
Dianne Hackborn40011092011-09-22 13:37:48 -07001396
1397 if (DEBUG_SCREEN_ON) {
1398 RuntimeException here = new RuntimeException("here");
1399 here.fillInStackTrace();
1400 Slog.i(TAG, "sendNotificationLocked: " + on, here);
1401 }
1402
Joe Onorato64c62ba2009-03-24 20:13:57 -07001403 if (!on) {
1404 mStillNeedSleepNotification = false;
1405 }
1406
Joe Onorato128e7292009-03-24 18:41:31 -07001407 // Add to the queue.
1408 int index = 0;
1409 while (mBroadcastQueue[index] != -1) {
1410 index++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001411 }
Joe Onorato128e7292009-03-24 18:41:31 -07001412 mBroadcastQueue[index] = on ? 1 : 0;
1413 mBroadcastWhy[index] = why;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001414
Joe Onorato128e7292009-03-24 18:41:31 -07001415 // If we added it position 2, then there is a pair that can be stripped.
1416 // If we added it position 1 and we're turning the screen off, we can strip
1417 // the pair and do nothing, because the screen is already off, and therefore
1418 // keyguard has already been enabled.
1419 // However, if we added it at position 1 and we're turning it on, then position
1420 // 0 was to turn it off, and we can't strip that, because keyguard needs to come
1421 // on, so have to run the queue then.
1422 if (index == 2) {
Dianne Hackborn254cb442010-01-27 19:23:59 -08001423 // While we're collapsing them, if it's going off, and the new reason
1424 // is more significant than the first, then use the new one.
1425 if (!on && mBroadcastWhy[0] > why) {
1426 mBroadcastWhy[0] = why;
Joe Onorato128e7292009-03-24 18:41:31 -07001427 }
1428 mBroadcastQueue[0] = on ? 1 : 0;
1429 mBroadcastQueue[1] = -1;
1430 mBroadcastQueue[2] = -1;
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001431 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount);
Mike Lockwood9c90a372010-04-13 15:40:27 -04001432 mBroadcastWakeLock.release();
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001433 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount);
Mike Lockwood9c90a372010-04-13 15:40:27 -04001434 mBroadcastWakeLock.release();
Joe Onorato128e7292009-03-24 18:41:31 -07001435 index = 0;
1436 }
1437 if (index == 1 && !on) {
1438 mBroadcastQueue[0] = -1;
1439 mBroadcastQueue[1] = -1;
1440 index = -1;
1441 // The wake lock was being held, but we're not actually going to do any
1442 // broadcasts, so release the wake lock.
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001443 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001444 mBroadcastWakeLock.release();
Joe Onorato128e7292009-03-24 18:41:31 -07001445 }
1446
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07001447 // The broadcast queue has changed; make sure the screen is on if it
1448 // is now possible for it to be.
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001449 if (mSkippedScreenOn) {
1450 updateLightsLocked(mPowerState, SCREEN_ON_BIT);
1451 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07001452
Joe Onorato128e7292009-03-24 18:41:31 -07001453 // Now send the message.
1454 if (index >= 0) {
1455 // Acquire the broadcast wake lock before changing the power
1456 // state. It will be release after the broadcast is sent.
1457 // We always increment the ref count for each notification in the queue
1458 // and always decrement when that notification is handled.
1459 mBroadcastWakeLock.acquire();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001460 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND, mBroadcastWakeLock.mCount);
Joe Onorato128e7292009-03-24 18:41:31 -07001461 mHandler.post(mNotificationTask);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001462 }
1463 }
1464
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001465 private WindowManagerPolicy.ScreenOnListener mScreenOnListener =
1466 new WindowManagerPolicy.ScreenOnListener() {
Jim Miller92e66dd2012-02-21 18:57:12 -08001467 public void onScreenOn() {
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001468 synchronized (mLocks) {
1469 if (mPreparingForScreenOn) {
1470 mPreparingForScreenOn = false;
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001471 updateLightsLocked(mPowerState, SCREEN_ON_BIT);
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001472 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP,
1473 4, mBroadcastWakeLock.mCount);
1474 mBroadcastWakeLock.release();
1475 }
1476 }
1477 }
1478 };
1479
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001480 private Runnable mNotificationTask = new Runnable()
1481 {
1482 public void run()
1483 {
Joe Onorato128e7292009-03-24 18:41:31 -07001484 while (true) {
1485 int value;
1486 int why;
1487 WindowManagerPolicy policy;
1488 synchronized (mLocks) {
1489 value = mBroadcastQueue[0];
1490 why = mBroadcastWhy[0];
1491 for (int i=0; i<2; i++) {
1492 mBroadcastQueue[i] = mBroadcastQueue[i+1];
1493 mBroadcastWhy[i] = mBroadcastWhy[i+1];
1494 }
1495 policy = getPolicyLocked();
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001496 if (value == 1 && !mPreparingForScreenOn) {
1497 mPreparingForScreenOn = true;
1498 mBroadcastWakeLock.acquire();
1499 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND,
1500 mBroadcastWakeLock.mCount);
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07001501 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001502 }
Joe Onorato128e7292009-03-24 18:41:31 -07001503 if (value == 1) {
1504 mScreenOnStart = SystemClock.uptimeMillis();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001505
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001506 policy.screenTurningOn(mScreenOnListener);
Joe Onorato128e7292009-03-24 18:41:31 -07001507 try {
1508 ActivityManagerNative.getDefault().wakingUp();
1509 } catch (RemoteException e) {
1510 // ignore it
1511 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001512
Joe Onorato128e7292009-03-24 18:41:31 -07001513 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001514 Slog.d(TAG, "mBroadcastWakeLock=" + mBroadcastWakeLock);
Joe Onorato128e7292009-03-24 18:41:31 -07001515 }
1516 if (mContext != null && ActivityManagerNative.isSystemReady()) {
1517 mContext.sendOrderedBroadcast(mScreenOnIntent, null,
1518 mScreenOnBroadcastDone, mHandler, 0, null, null);
1519 } else {
1520 synchronized (mLocks) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001521 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 2,
Joe Onorato128e7292009-03-24 18:41:31 -07001522 mBroadcastWakeLock.mCount);
1523 mBroadcastWakeLock.release();
1524 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001525 }
1526 }
Joe Onorato128e7292009-03-24 18:41:31 -07001527 else if (value == 0) {
1528 mScreenOffStart = SystemClock.uptimeMillis();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001529
Joe Onorato128e7292009-03-24 18:41:31 -07001530 policy.screenTurnedOff(why);
1531 try {
1532 ActivityManagerNative.getDefault().goingToSleep();
1533 } catch (RemoteException e) {
1534 // ignore it.
1535 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001536
Joe Onorato128e7292009-03-24 18:41:31 -07001537 if (mContext != null && ActivityManagerNative.isSystemReady()) {
1538 mContext.sendOrderedBroadcast(mScreenOffIntent, null,
1539 mScreenOffBroadcastDone, mHandler, 0, null, null);
1540 } else {
1541 synchronized (mLocks) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001542 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 3,
Joe Onorato128e7292009-03-24 18:41:31 -07001543 mBroadcastWakeLock.mCount);
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001544 updateLightsLocked(mPowerState, SCREEN_ON_BIT);
Joe Onorato128e7292009-03-24 18:41:31 -07001545 mBroadcastWakeLock.release();
1546 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001547 }
1548 }
Joe Onorato128e7292009-03-24 18:41:31 -07001549 else {
1550 // If we're in this case, then this handler is running for a previous
1551 // paired transaction. mBroadcastWakeLock will already have been released.
1552 break;
1553 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001554 }
1555 }
1556 };
1557
1558 long mScreenOnStart;
1559 private BroadcastReceiver mScreenOnBroadcastDone = new BroadcastReceiver() {
1560 public void onReceive(Context context, Intent intent) {
1561 synchronized (mLocks) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001562 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001563 SystemClock.uptimeMillis() - mScreenOnStart, mBroadcastWakeLock.mCount);
1564 mBroadcastWakeLock.release();
1565 }
1566 }
1567 };
1568
1569 long mScreenOffStart;
1570 private BroadcastReceiver mScreenOffBroadcastDone = new BroadcastReceiver() {
1571 public void onReceive(Context context, Intent intent) {
1572 synchronized (mLocks) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001573 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 0,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001574 SystemClock.uptimeMillis() - mScreenOffStart, mBroadcastWakeLock.mCount);
1575 mBroadcastWakeLock.release();
1576 }
1577 }
1578 };
1579
1580 void logPointerUpEvent() {
1581 if (LOG_TOUCH_DOWNS) {
1582 mTotalTouchDownTime += SystemClock.elapsedRealtime() - mLastTouchDown;
1583 mLastTouchDown = 0;
1584 }
1585 }
1586
1587 void logPointerDownEvent() {
1588 if (LOG_TOUCH_DOWNS) {
1589 // If we are not already timing a down/up sequence
1590 if (mLastTouchDown == 0) {
1591 mLastTouchDown = SystemClock.elapsedRealtime();
1592 mTouchCycles++;
1593 }
1594 }
1595 }
1596
1597 /**
1598 * Prevents the screen from turning on even if it *should* turn on due
1599 * to a subsequent full wake lock being acquired.
1600 * <p>
1601 * This is a temporary hack that allows an activity to "cover up" any
1602 * display glitches that happen during the activity's startup
1603 * sequence. (Specifically, this API was added to work around a
1604 * cosmetic bug in the "incoming call" sequence, where the lock screen
1605 * would flicker briefly before the incoming call UI became visible.)
1606 * TODO: There ought to be a more elegant way of doing this,
1607 * probably by having the PowerManager and ActivityManager
1608 * work together to let apps specify that the screen on/off
1609 * state should be synchronized with the Activity lifecycle.
1610 * <p>
1611 * Note that calling preventScreenOn(true) will NOT turn the screen
1612 * off if it's currently on. (This API only affects *future*
1613 * acquisitions of full wake locks.)
1614 * But calling preventScreenOn(false) WILL turn the screen on if
1615 * it's currently off because of a prior preventScreenOn(true) call.
1616 * <p>
1617 * Any call to preventScreenOn(true) MUST be followed promptly by a call
1618 * to preventScreenOn(false). In fact, if the preventScreenOn(false)
1619 * call doesn't occur within 5 seconds, we'll turn the screen back on
1620 * ourselves (and log a warning about it); this prevents a buggy app
1621 * from disabling the screen forever.)
1622 * <p>
1623 * TODO: this feature should really be controlled by a new type of poke
1624 * lock (rather than an IPowerManager call).
1625 */
1626 public void preventScreenOn(boolean prevent) {
1627 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1628
1629 synchronized (mLocks) {
1630 if (prevent) {
1631 // First of all, grab a partial wake lock to
1632 // make sure the CPU stays on during the entire
1633 // preventScreenOn(true) -> preventScreenOn(false) sequence.
1634 mPreventScreenOnPartialLock.acquire();
1635
1636 // Post a forceReenableScreen() call (for 5 seconds in the
1637 // future) to make sure the matching preventScreenOn(false) call
1638 // has happened by then.
1639 mHandler.removeCallbacks(mForceReenableScreenTask);
1640 mHandler.postDelayed(mForceReenableScreenTask, 5000);
1641
1642 // Finally, set the flag that prevents the screen from turning on.
1643 // (Below, in setPowerState(), we'll check mPreventScreenOn and
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001644 // we *won't* call setScreenStateLocked(true) if it's set.)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001645 mPreventScreenOn = true;
1646 } else {
1647 // (Re)enable the screen.
1648 mPreventScreenOn = false;
1649
1650 // We're "undoing" a the prior preventScreenOn(true) call, so we
1651 // no longer need the 5-second safeguard.
1652 mHandler.removeCallbacks(mForceReenableScreenTask);
1653
1654 // Forcibly turn on the screen if it's supposed to be on. (This
1655 // handles the case where the screen is currently off because of
1656 // a prior preventScreenOn(true) call.)
Mike Lockwoode090281422009-11-14 21:02:56 -05001657 if (!mProximitySensorActive && (mPowerState & SCREEN_ON_BIT) != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001658 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001659 Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001660 "preventScreenOn: turning on after a prior preventScreenOn(true)!");
1661 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001662 int err = setScreenStateLocked(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001663 if (err != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001664 Slog.w(TAG, "preventScreenOn: error from setScreenStateLocked(): " + err);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001665 }
1666 }
1667
1668 // Release the partial wake lock that we held during the
1669 // preventScreenOn(true) -> preventScreenOn(false) sequence.
1670 mPreventScreenOnPartialLock.release();
1671 }
1672 }
1673 }
1674
1675 public void setScreenBrightnessOverride(int brightness) {
1676 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1677
Mike Lockwoodf527c712010-06-10 14:12:33 -04001678 if (mSpew) Slog.d(TAG, "setScreenBrightnessOverride " + brightness);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001679 synchronized (mLocks) {
1680 if (mScreenBrightnessOverride != brightness) {
1681 mScreenBrightnessOverride = brightness;
Mike Lockwoodf527c712010-06-10 14:12:33 -04001682 if (isScreenOn()) {
1683 updateLightsLocked(mPowerState, SCREEN_ON_BIT);
1684 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001685 }
1686 }
1687 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05001688
1689 public void setButtonBrightnessOverride(int brightness) {
1690 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1691
Mike Lockwoodf527c712010-06-10 14:12:33 -04001692 if (mSpew) Slog.d(TAG, "setButtonBrightnessOverride " + brightness);
Mike Lockwoodfb73f792009-11-20 11:31:18 -05001693 synchronized (mLocks) {
1694 if (mButtonBrightnessOverride != brightness) {
1695 mButtonBrightnessOverride = brightness;
Mike Lockwoodf527c712010-06-10 14:12:33 -04001696 if (isScreenOn()) {
1697 updateLightsLocked(mPowerState, BUTTON_BRIGHT_BIT | KEYBOARD_BRIGHT_BIT);
1698 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05001699 }
1700 }
1701 }
1702
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001703 /**
1704 * Sanity-check that gets called 5 seconds after any call to
1705 * preventScreenOn(true). This ensures that the original call
1706 * is followed promptly by a call to preventScreenOn(false).
1707 */
1708 private void forceReenableScreen() {
1709 // We shouldn't get here at all if mPreventScreenOn is false, since
1710 // we should have already removed any existing
1711 // mForceReenableScreenTask messages...
1712 if (!mPreventScreenOn) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001713 Slog.w(TAG, "forceReenableScreen: mPreventScreenOn is false, nothing to do");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001714 return;
1715 }
1716
1717 // Uh oh. It's been 5 seconds since a call to
1718 // preventScreenOn(true) and we haven't re-enabled the screen yet.
1719 // This means the app that called preventScreenOn(true) is either
1720 // slow (i.e. it took more than 5 seconds to call preventScreenOn(false)),
1721 // or buggy (i.e. it forgot to call preventScreenOn(false), or
1722 // crashed before doing so.)
1723
1724 // Log a warning, and forcibly turn the screen back on.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001725 Slog.w(TAG, "App called preventScreenOn(true) but didn't promptly reenable the screen! "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001726 + "Forcing the screen back on...");
1727 preventScreenOn(false);
1728 }
1729
1730 private Runnable mForceReenableScreenTask = new Runnable() {
1731 public void run() {
1732 forceReenableScreen();
1733 }
1734 };
1735
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001736 private int setScreenStateLocked(boolean on) {
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001737 if (DEBUG_SCREEN_ON) {
1738 RuntimeException e = new RuntimeException("here");
1739 e.fillInStackTrace();
1740 Slog.i(TAG, "Set screen state: " + on, e);
1741 }
Dianne Hackborn474fd742011-10-10 18:40:22 -07001742 if (on) {
1743 if ((mPowerState & SCREEN_ON_BIT) == 0 || mSkippedScreenOn) {
1744 // If we are turning the screen state on, but the screen
1745 // light is currently off, then make sure that we set the
1746 // light at this point to 0. This is the case where we are
1747 // turning on the screen and waiting for the UI to be drawn
1748 // before showing it to the user. We want the light off
1749 // until it is ready to be shown to the user, not it using
1750 // whatever the last value it had.
Dianne Hackborn81de8b92011-11-28 16:54:31 -08001751 if (DEBUG_SCREEN_ON) {
1752 Slog.i(TAG, "Forcing brightness 0: mPowerState=0x"
1753 + Integer.toHexString(mPowerState)
1754 + " mSkippedScreenOn=" + mSkippedScreenOn);
1755 }
Jeff Brown7304c342012-05-11 18:42:42 -07001756 mScreenBrightnessAnimator.animateTo(PowerManager.BRIGHTNESS_OFF, SCREEN_BRIGHT_BIT, 0);
Dianne Hackborn474fd742011-10-10 18:40:22 -07001757 }
1758 }
Jeff Brown7304c342012-05-11 18:42:42 -07001759 int err = nativeSetScreenState(on);
Mike Lockwood20ee6f22009-11-07 20:33:47 -05001760 if (err == 0) {
1761 mLastScreenOnTime = (on ? SystemClock.elapsedRealtime() : 0);
1762 if (mUseSoftwareAutoBrightness) {
Joe Onoratod28f7532010-11-06 12:56:53 -07001763 enableLightSensorLocked(on);
Craig Mautner37933682012-06-06 14:13:39 -07001764 if (on) {
1765 // If AutoBrightness is enabled, set the brightness immediately after the
1766 // next sensor value is received.
1767 mWaitingForFirstLightSensor = mAutoBrightessEnabled;
1768 } else {
Mike Lockwood20ee6f22009-11-07 20:33:47 -05001769 // make sure button and key backlights are off too
Mike Lockwood3cb67a32009-11-27 14:25:58 -05001770 mButtonLight.turnOff();
1771 mKeyboardLight.turnOff();
Mike Lockwood20ee6f22009-11-07 20:33:47 -05001772 }
Mike Lockwoodd7786b42009-10-15 17:09:16 -07001773 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001774 }
1775 return err;
1776 }
1777
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001778 private void setPowerState(int state)
1779 {
Mike Lockwood435eb642009-12-03 08:40:18 -05001780 setPowerState(state, false, WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001781 }
1782
Mike Lockwood435eb642009-12-03 08:40:18 -05001783 private void setPowerState(int newState, boolean noChangeLights, int reason)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001784 {
1785 synchronized (mLocks) {
1786 int err;
1787
1788 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001789 Slog.d(TAG, "setPowerState: mPowerState=0x" + Integer.toHexString(mPowerState)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001790 + " newState=0x" + Integer.toHexString(newState)
Mike Lockwood435eb642009-12-03 08:40:18 -05001791 + " noChangeLights=" + noChangeLights
1792 + " reason=" + reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001793 }
Daniel Sandler7d276c32012-01-30 14:33:52 -05001794
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001795 if (noChangeLights) {
1796 newState = (newState & ~LIGHTS_MASK) | (mPowerState & LIGHTS_MASK);
1797 }
Mike Lockwood36fc3022009-08-25 16:49:06 -07001798 if (mProximitySensorActive) {
1799 // don't turn on the screen when the proximity sensor lock is held
1800 newState = (newState & ~SCREEN_BRIGHT);
1801 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001802
1803 if (batteryIsLow()) {
1804 newState |= BATTERY_LOW_BIT;
1805 } else {
1806 newState &= ~BATTERY_LOW_BIT;
1807 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001808 if (newState == mPowerState && mInitialized) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001809 return;
1810 }
Mike Lockwood3333fa42009-10-26 14:50:42 -04001811
Mike Lockwood2d7bb812009-11-15 18:12:22 -05001812 if (!mBootCompleted && !mUseSoftwareAutoBrightness) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001813 newState |= ALL_BRIGHT;
1814 }
1815
1816 boolean oldScreenOn = (mPowerState & SCREEN_ON_BIT) != 0;
1817 boolean newScreenOn = (newState & SCREEN_ON_BIT) != 0;
1818
Mike Lockwood51b844962009-11-16 21:51:18 -05001819 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001820 Slog.d(TAG, "setPowerState: mPowerState=" + mPowerState
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001821 + " newState=" + newState + " noChangeLights=" + noChangeLights);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001822 Slog.d(TAG, " oldKeyboardBright=" + ((mPowerState & KEYBOARD_BRIGHT_BIT) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001823 + " newKeyboardBright=" + ((newState & KEYBOARD_BRIGHT_BIT) != 0));
Joe Onorato8a9b2202010-02-26 18:56:32 -08001824 Slog.d(TAG, " oldScreenBright=" + ((mPowerState & SCREEN_BRIGHT_BIT) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001825 + " newScreenBright=" + ((newState & SCREEN_BRIGHT_BIT) != 0));
Joe Onorato8a9b2202010-02-26 18:56:32 -08001826 Slog.d(TAG, " oldButtonBright=" + ((mPowerState & BUTTON_BRIGHT_BIT) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001827 + " newButtonBright=" + ((newState & BUTTON_BRIGHT_BIT) != 0));
Joe Onorato8a9b2202010-02-26 18:56:32 -08001828 Slog.d(TAG, " oldScreenOn=" + oldScreenOn
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001829 + " newScreenOn=" + newScreenOn);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001830 Slog.d(TAG, " oldBatteryLow=" + ((mPowerState & BATTERY_LOW_BIT) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001831 + " newBatteryLow=" + ((newState & BATTERY_LOW_BIT) != 0));
1832 }
1833
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001834 final boolean stateChanged = mPowerState != newState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001835
Daniel Sandler7d276c32012-01-30 14:33:52 -05001836 if (stateChanged && reason == WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT) {
Daniel Sandler0af48952012-04-10 15:14:35 -04001837 if (mPolicy != null && mPolicy.isScreenSaverEnabled()) {
Daniel Sandler7d276c32012-01-30 14:33:52 -05001838 if (mSpew) {
1839 Slog.d(TAG, "setPowerState: running screen saver instead of turning off screen");
1840 }
1841 if (mPolicy.startScreenSaver()) {
1842 // was successful
1843 return;
1844 }
1845 }
1846 }
1847
1848
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001849 if (oldScreenOn != newScreenOn) {
1850 if (newScreenOn) {
Joe Onorato128e7292009-03-24 18:41:31 -07001851 // When the user presses the power button, we need to always send out the
1852 // notification that it's going to sleep so the keyguard goes on. But
1853 // we can't do that until the screen fades out, so we don't show the keyguard
1854 // too early.
1855 if (mStillNeedSleepNotification) {
1856 sendNotificationLocked(false, WindowManagerPolicy.OFF_BECAUSE_OF_USER);
1857 }
1858
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001859 // Turn on the screen UNLESS there was a prior
1860 // preventScreenOn(true) request. (Note that the lifetime
1861 // of a single preventScreenOn() request is limited to 5
1862 // seconds to prevent a buggy app from disabling the
1863 // screen forever; see forceReenableScreen().)
1864 boolean reallyTurnScreenOn = true;
1865 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001866 Slog.d(TAG, "- turning screen on... mPreventScreenOn = "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001867 + mPreventScreenOn);
1868 }
1869
1870 if (mPreventScreenOn) {
1871 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001872 Slog.d(TAG, "- PREVENTING screen from really turning on!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001873 }
1874 reallyTurnScreenOn = false;
1875 }
1876 if (reallyTurnScreenOn) {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001877 err = setScreenStateLocked(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001878 long identity = Binder.clearCallingIdentity();
1879 try {
Mike Lockwoodfb73f792009-11-20 11:31:18 -05001880 mBatteryStats.noteScreenBrightness(getPreferredBrightness());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001881 mBatteryStats.noteScreenOn();
1882 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001883 Slog.w(TAG, "RemoteException calling noteScreenOn on BatteryStatsService", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001884 } finally {
1885 Binder.restoreCallingIdentity(identity);
1886 }
1887 } else {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001888 setScreenStateLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001889 // But continue as if we really did turn the screen on...
1890 err = 0;
1891 }
1892
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001893 mLastTouchDown = 0;
1894 mTotalTouchDownTime = 0;
1895 mTouchCycles = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001896 EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, reason,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001897 mTotalTouchDownTime, mTouchCycles);
1898 if (err == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001899 sendNotificationLocked(true, -1);
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001900 // Update the lights *after* taking care of turning the
1901 // screen on, so we do this after our notifications are
1902 // enqueued and thus will delay turning on the screen light
1903 // until the windows are correctly displayed.
1904 if (stateChanged) {
1905 updateLightsLocked(newState, 0);
1906 }
1907 mPowerState |= SCREEN_ON_BIT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001908 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001909
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001910 } else {
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001911 // Update the lights *before* taking care of turning the
1912 // screen off, so we can initiate any animations that are desired.
Craig Mautner44bf70f2012-03-13 11:38:38 -07001913 mScreenOffReason = reason;
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001914 if (stateChanged) {
1915 updateLightsLocked(newState, 0);
1916 }
1917
Mike Lockwood497087e32009-11-08 18:33:03 -05001918 // cancel light sensor task
1919 mHandler.removeCallbacks(mAutoBrightnessTask);
Jim Rodovichd102fea2010-09-02 12:30:49 -05001920 mLightSensorPendingDecrease = false;
1921 mLightSensorPendingIncrease = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001922 mScreenOffTime = SystemClock.elapsedRealtime();
1923 long identity = Binder.clearCallingIdentity();
1924 try {
1925 mBatteryStats.noteScreenOff();
1926 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001927 Slog.w(TAG, "RemoteException calling noteScreenOff on BatteryStatsService", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001928 } finally {
1929 Binder.restoreCallingIdentity(identity);
1930 }
1931 mPowerState &= ~SCREEN_ON_BIT;
Jim Miller92e66dd2012-02-21 18:57:12 -08001932 if (!mScreenBrightnessAnimator.isAnimating()) {
Mike Lockwood435eb642009-12-03 08:40:18 -05001933 err = screenOffFinishedAnimatingLocked(reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001934 } else {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001935 err = 0;
1936 mLastTouchDown = 0;
1937 }
1938 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001939 } else if (stateChanged) {
1940 // Screen on/off didn't change, but lights may have.
1941 updateLightsLocked(newState, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001942 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001943
1944 mPowerState = (mPowerState & ~LIGHTS_MASK) | (newState & LIGHTS_MASK);
1945
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001946 updateNativePowerStateLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001947 }
1948 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001949
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001950 private void updateNativePowerStateLocked() {
Mike Lockwood3a74bd32011-08-12 13:55:22 -07001951 if (!mHeadless) {
1952 nativeSetPowerState(
1953 (mPowerState & SCREEN_ON_BIT) != 0,
1954 (mPowerState & SCREEN_BRIGHT) == SCREEN_BRIGHT);
1955 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001956 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001957
Mike Lockwood435eb642009-12-03 08:40:18 -05001958 private int screenOffFinishedAnimatingLocked(int reason) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001959 // I don't think we need to check the current state here because all of these
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001960 // Power.setScreenState and sendNotificationLocked can both handle being
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001961 // called multiple times in the same state. -joeo
Joe Onoratob08a1af2010-10-11 19:28:58 -07001962 EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, reason, mTotalTouchDownTime,
1963 mTouchCycles);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001964 mLastTouchDown = 0;
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001965 int err = setScreenStateLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001966 if (err == 0) {
Mike Lockwood435eb642009-12-03 08:40:18 -05001967 mScreenOffReason = reason;
1968 sendNotificationLocked(false, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001969 }
1970 return err;
1971 }
1972
1973 private boolean batteryIsLow() {
1974 return (!mIsPowered &&
Jeff Brown7304c342012-05-11 18:42:42 -07001975 mBatteryService.getBatteryLevel() <= LOW_BATTERY_THRESHOLD);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001976 }
1977
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001978 private boolean shouldDeferScreenOnLocked() {
1979 if (mPreparingForScreenOn) {
1980 // Currently waiting for confirmation from the policy that it
1981 // is okay to turn on the screen. Don't allow the screen to go
1982 // on until that is done.
1983 if (DEBUG_SCREEN_ON) Slog.i(TAG,
1984 "updateLights: delaying screen on due to mPreparingForScreenOn");
1985 return true;
1986 } else {
1987 // If there is a screen-on command in the notification queue, we
1988 // can't turn the screen on until it has been processed (and we
1989 // have set mPreparingForScreenOn) or it has been dropped.
1990 for (int i=0; i<mBroadcastQueue.length; i++) {
1991 if (mBroadcastQueue[i] == 1) {
1992 if (DEBUG_SCREEN_ON) Slog.i(TAG,
1993 "updateLights: delaying screen on due to notification queue");
1994 return true;
1995 }
1996 }
1997 }
1998 return false;
1999 }
2000
The Android Open Source Project10592532009-03-18 17:39:46 -07002001 private void updateLightsLocked(int newState, int forceState) {
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07002002 final int oldState = mPowerState;
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07002003
2004 // If the screen is not currently on, we will want to delay actually
2005 // turning the lights on if we are still getting the UI put up.
Jim Miller92e66dd2012-02-21 18:57:12 -08002006 if ((oldState & SCREEN_ON_BIT) == 0 || mSkippedScreenOn) {
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07002007 // Don't turn screen on until we know we are really ready to.
2008 // This is to avoid letting the screen go on before things like the
2009 // lock screen have been displayed.
Jim Miller92e66dd2012-02-21 18:57:12 -08002010 if ((mSkippedScreenOn = shouldDeferScreenOnLocked())) {
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07002011 newState &= ~(SCREEN_ON_BIT|SCREEN_BRIGHT_BIT);
2012 }
2013 }
2014
Joe Onorato60607a902010-10-23 14:49:30 -07002015 if ((newState & SCREEN_ON_BIT) != 0) {
2016 // Only turn on the buttons or keyboard if the screen is also on.
2017 // We should never see the buttons on but not the screen.
2018 newState = applyButtonState(newState);
2019 newState = applyKeyboardState(newState);
2020 }
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07002021 final int realDifference = (newState ^ oldState);
2022 final int difference = realDifference | forceState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002023 if (difference == 0) {
The Android Open Source Project10592532009-03-18 17:39:46 -07002024 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002025 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002026
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002027 int offMask = 0;
2028 int dimMask = 0;
2029 int onMask = 0;
2030
2031 int preferredBrightness = getPreferredBrightness();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002032
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002033 if ((difference & KEYBOARD_BRIGHT_BIT) != 0) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002034 if ((newState & KEYBOARD_BRIGHT_BIT) == 0) {
2035 offMask |= KEYBOARD_BRIGHT_BIT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002036 } else {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002037 onMask |= KEYBOARD_BRIGHT_BIT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002038 }
2039 }
2040
2041 if ((difference & BUTTON_BRIGHT_BIT) != 0) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002042 if ((newState & BUTTON_BRIGHT_BIT) == 0) {
2043 offMask |= BUTTON_BRIGHT_BIT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002044 } else {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002045 onMask |= BUTTON_BRIGHT_BIT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002046 }
2047 }
2048
2049 if ((difference & (SCREEN_ON_BIT | SCREEN_BRIGHT_BIT)) != 0) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002050 int nominalCurrentValue = -1;
2051 // If there was an actual difference in the light state, then
2052 // figure out the "ideal" current value based on the previous
2053 // state. Otherwise, this is a change due to the brightness
2054 // override, so we want to animate from whatever the current
2055 // value is.
2056 if ((realDifference & (SCREEN_ON_BIT | SCREEN_BRIGHT_BIT)) != 0) {
2057 switch (oldState & (SCREEN_BRIGHT_BIT|SCREEN_ON_BIT)) {
2058 case SCREEN_BRIGHT_BIT | SCREEN_ON_BIT:
2059 nominalCurrentValue = preferredBrightness;
2060 break;
2061 case SCREEN_ON_BIT:
Mike Lockwoodeb6456b2011-09-13 15:24:02 -04002062 nominalCurrentValue = mScreenBrightnessDim;
Joe Onoratob08a1af2010-10-11 19:28:58 -07002063 break;
2064 case 0:
Jeff Brown7304c342012-05-11 18:42:42 -07002065 nominalCurrentValue = PowerManager.BRIGHTNESS_OFF;
Joe Onoratob08a1af2010-10-11 19:28:58 -07002066 break;
2067 case SCREEN_BRIGHT_BIT:
2068 default:
2069 // not possible
Jim Miller92e66dd2012-02-21 18:57:12 -08002070 nominalCurrentValue = (int)mScreenBrightnessAnimator.getCurrentBrightness();
Joe Onoratob08a1af2010-10-11 19:28:58 -07002071 break;
Joe Onorato128e7292009-03-24 18:41:31 -07002072 }
Joe Onoratob08a1af2010-10-11 19:28:58 -07002073 }
2074 int brightness = preferredBrightness;
2075 int steps = ANIM_STEPS;
2076 if ((newState & SCREEN_BRIGHT_BIT) == 0) {
2077 // dim or turn off backlight, depending on if the screen is on
2078 // the scale is because the brightness ramp isn't linear and this biases
2079 // it so the later parts take longer.
2080 final float scale = 1.5f;
Mike Lockwoodeb6456b2011-09-13 15:24:02 -04002081 float ratio = (((float)mScreenBrightnessDim)/preferredBrightness);
Joe Onoratob08a1af2010-10-11 19:28:58 -07002082 if (ratio > 1.0f) ratio = 1.0f;
2083 if ((newState & SCREEN_ON_BIT) == 0) {
2084 if ((oldState & SCREEN_BRIGHT_BIT) != 0) {
2085 // was bright
2086 steps = ANIM_STEPS;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002087 } else {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002088 // was dim
2089 steps = (int)(ANIM_STEPS*ratio*scale);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002090 }
Jeff Brown7304c342012-05-11 18:42:42 -07002091 brightness = PowerManager.BRIGHTNESS_OFF;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002092 } else {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002093 if ((oldState & SCREEN_ON_BIT) != 0) {
2094 // was bright
2095 steps = (int)(ANIM_STEPS*(1.0f-ratio)*scale);
2096 } else {
2097 // was dim
2098 steps = (int)(ANIM_STEPS*ratio);
2099 }
2100 if (mStayOnConditions != 0 && mBatteryService.isPowered(mStayOnConditions)) {
2101 // If the "stay on while plugged in" option is
2102 // turned on, then the screen will often not
2103 // automatically turn off while plugged in. To
2104 // still have a sense of when it is inactive, we
2105 // will then count going dim as turning off.
2106 mScreenOffTime = SystemClock.elapsedRealtime();
2107 }
Mike Lockwoodeb6456b2011-09-13 15:24:02 -04002108 brightness = mScreenBrightnessDim;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002109 }
2110 }
Joe Onoratob08a1af2010-10-11 19:28:58 -07002111 long identity = Binder.clearCallingIdentity();
2112 try {
2113 mBatteryStats.noteScreenBrightness(brightness);
2114 } catch (RemoteException e) {
2115 // Nothing interesting to do.
2116 } finally {
2117 Binder.restoreCallingIdentity(identity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002118 }
Dianne Hackborn81de8b92011-11-28 16:54:31 -08002119 if (!mSkippedScreenOn) {
Jim Miller92e66dd2012-02-21 18:57:12 -08002120 int dt = steps * NOMINAL_FRAME_TIME_MS;
2121 mScreenBrightnessAnimator.animateTo(brightness, SCREEN_BRIGHT_BIT, dt);
Dianne Hackborn81de8b92011-11-28 16:54:31 -08002122 if (DEBUG_SCREEN_ON) {
2123 RuntimeException e = new RuntimeException("here");
2124 e.fillInStackTrace();
2125 Slog.i(TAG, "Setting screen brightness: " + brightness, e);
2126 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07002127 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002128 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002129
Joe Onorato60607a902010-10-23 14:49:30 -07002130 if (mSpew) {
2131 Slog.d(TAG, "offMask=0x" + Integer.toHexString(offMask)
2132 + " dimMask=0x" + Integer.toHexString(dimMask)
2133 + " onMask=0x" + Integer.toHexString(onMask)
2134 + " difference=0x" + Integer.toHexString(difference)
2135 + " realDifference=0x" + Integer.toHexString(realDifference)
2136 + " forceState=0x" + Integer.toHexString(forceState)
2137 );
2138 }
2139
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002140 if (offMask != 0) {
Mike Lockwood48358bd2010-04-17 22:29:20 -04002141 if (mSpew) Slog.i(TAG, "Setting brightess off: " + offMask);
Jeff Brown7304c342012-05-11 18:42:42 -07002142 setLightBrightness(offMask, PowerManager.BRIGHTNESS_OFF);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002143 }
2144 if (dimMask != 0) {
Mike Lockwoodeb6456b2011-09-13 15:24:02 -04002145 int brightness = mScreenBrightnessDim;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002146 if ((newState & BATTERY_LOW_BIT) != 0 &&
Jeff Brown7304c342012-05-11 18:42:42 -07002147 brightness > PowerManager.BRIGHTNESS_LOW_BATTERY) {
2148 brightness = PowerManager.BRIGHTNESS_LOW_BATTERY;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002149 }
Mike Lockwood48358bd2010-04-17 22:29:20 -04002150 if (mSpew) Slog.i(TAG, "Setting brightess dim " + brightness + ": " + dimMask);
The Android Open Source Project10592532009-03-18 17:39:46 -07002151 setLightBrightness(dimMask, brightness);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002152 }
2153 if (onMask != 0) {
2154 int brightness = getPreferredBrightness();
2155 if ((newState & BATTERY_LOW_BIT) != 0 &&
Jeff Brown7304c342012-05-11 18:42:42 -07002156 brightness > PowerManager.BRIGHTNESS_LOW_BATTERY) {
2157 brightness = PowerManager.BRIGHTNESS_LOW_BATTERY;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002158 }
Mike Lockwood48358bd2010-04-17 22:29:20 -04002159 if (mSpew) Slog.i(TAG, "Setting brightess on " + brightness + ": " + onMask);
The Android Open Source Project10592532009-03-18 17:39:46 -07002160 setLightBrightness(onMask, brightness);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002161 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002162 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002163
Jim Miller92e66dd2012-02-21 18:57:12 -08002164 /**
2165 * Note: by design this class does not hold mLocks while calling native methods.
2166 * Nor should it. Ever.
2167 */
2168 class ScreenBrightnessAnimator extends HandlerThread {
2169 static final int ANIMATE_LIGHTS = 10;
Jim Miller46f31c32012-03-01 14:36:07 -08002170 static final int ANIMATE_POWER_OFF = 11;
Jim Miller92e66dd2012-02-21 18:57:12 -08002171 volatile int startValue;
2172 volatile int endValue;
Craig Mautner196943f2012-05-15 08:10:35 -07002173 volatile int startSensorValue;
2174 volatile int endSensorValue;
Jim Miller92e66dd2012-02-21 18:57:12 -08002175 volatile int currentValue;
2176 private int currentMask;
2177 private int duration;
2178 private long startTimeMillis;
2179 private final String prefix;
2180
2181 public ScreenBrightnessAnimator(String name, int priority) {
2182 super(name, priority);
2183 prefix = name;
2184 }
2185
2186 @Override
2187 protected void onLooperPrepared() {
2188 mScreenBrightnessHandler = new Handler() {
2189 public void handleMessage(Message msg) {
2190 int brightnessMode = (mAutoBrightessEnabled && !mInitialAnimation
Mike Lockwood3a322132009-11-24 00:30:52 -05002191 ? LightsService.BRIGHTNESS_MODE_SENSOR
2192 : LightsService.BRIGHTNESS_MODE_USER);
Jim Miller92e66dd2012-02-21 18:57:12 -08002193 if (msg.what == ANIMATE_LIGHTS) {
2194 final int mask = msg.arg1;
2195 int value = msg.arg2;
2196 long tStart = SystemClock.uptimeMillis();
2197 if ((mask & SCREEN_BRIGHT_BIT) != 0) {
Craig Mautner196943f2012-05-15 08:10:35 -07002198 if (mDebugLightAnimation) Slog.v(TAG, "Set brightness: " + value);
Jim Miller92e66dd2012-02-21 18:57:12 -08002199 mLcdLight.setBrightness(value, brightnessMode);
2200 }
2201 long elapsed = SystemClock.uptimeMillis() - tStart;
2202 if ((mask & BUTTON_BRIGHT_BIT) != 0) {
2203 mButtonLight.setBrightness(value);
2204 }
2205 if ((mask & KEYBOARD_BRIGHT_BIT) != 0) {
2206 mKeyboardLight.setBrightness(value);
2207 }
2208
2209 if (elapsed > 100) {
Craig Mautner196943f2012-05-15 08:10:35 -07002210 Slog.e(TAG, "Excessive delay setting brightness: " + elapsed
Jim Miller92e66dd2012-02-21 18:57:12 -08002211 + "ms, mask=" + mask);
2212 }
2213
2214 // Throttle brightness updates to frame refresh rate
Craig Mautner196943f2012-05-15 08:10:35 -07002215 int delay = elapsed < NOMINAL_FRAME_TIME_MS ? NOMINAL_FRAME_TIME_MS : 1;
Jim Miller92e66dd2012-02-21 18:57:12 -08002216 synchronized(this) {
2217 currentValue = value;
2218 }
2219 animateInternal(mask, false, delay);
Jim Miller46f31c32012-03-01 14:36:07 -08002220 } else if (msg.what == ANIMATE_POWER_OFF) {
2221 int mode = msg.arg1;
2222 nativeStartSurfaceFlingerAnimation(mode);
Jim Miller92e66dd2012-02-21 18:57:12 -08002223 }
2224 }
2225 };
2226 synchronized (this) {
2227 mInitComplete = true;
2228 notifyAll();
Dianne Hackborn81de8b92011-11-28 16:54:31 -08002229 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002230 }
Jim Miller92e66dd2012-02-21 18:57:12 -08002231
2232 private void animateInternal(int mask, boolean turningOff, int delay) {
2233 synchronized (this) {
2234 if (currentValue != endValue) {
2235 final long now = SystemClock.elapsedRealtime();
2236 final int elapsed = (int) (now - startTimeMillis);
2237 int newValue;
2238 if (elapsed < duration) {
2239 int delta = endValue - startValue;
2240 newValue = startValue + delta * elapsed / duration;
Jeff Brown7304c342012-05-11 18:42:42 -07002241 newValue = Math.max(PowerManager.BRIGHTNESS_OFF, newValue);
2242 newValue = Math.min(PowerManager.BRIGHTNESS_ON, newValue);
Craig Mautner196943f2012-05-15 08:10:35 -07002243 // Optimization to delay next step until a change will occur.
2244 if (delay > 0 && newValue == currentValue) {
2245 final int timePerStep = duration / Math.abs(delta);
2246 delay = Math.min(duration - elapsed, timePerStep);
2247 newValue += delta < 0 ? -1 : 1;
2248 }
2249 // adjust the peak sensor value until we get to the target sensor value
2250 delta = endSensorValue - startSensorValue;
2251 mHighestLightSensorValue = startSensorValue + delta * elapsed / duration;
Jim Miller92e66dd2012-02-21 18:57:12 -08002252 } else {
2253 newValue = endValue;
Craig Mautner196943f2012-05-15 08:10:35 -07002254 mHighestLightSensorValue = endSensorValue;
Craig Mautneraf01fe02012-05-31 10:03:32 -07002255 if (endValue > 0) {
2256 mInitialAnimation = false;
2257 }
Jim Miller92e66dd2012-02-21 18:57:12 -08002258 }
2259
2260 if (mDebugLightAnimation) {
Craig Mautner196943f2012-05-15 08:10:35 -07002261 Slog.v(TAG, "Animating light: " + "start:" + startValue
Jim Miller92e66dd2012-02-21 18:57:12 -08002262 + ", end:" + endValue + ", elapsed:" + elapsed
2263 + ", duration:" + duration + ", current:" + currentValue
Craig Mautner196943f2012-05-15 08:10:35 -07002264 + ", newValue:" + newValue
2265 + ", delay:" + delay
2266 + ", highestSensor:" + mHighestLightSensorValue);
Jim Miller92e66dd2012-02-21 18:57:12 -08002267 }
2268
Jim Miller46f31c32012-03-01 14:36:07 -08002269 if (turningOff && !mHeadless && !mAnimateScreenLights) {
Jim Miller92e66dd2012-02-21 18:57:12 -08002270 int mode = mScreenOffReason == OFF_BECAUSE_OF_PROX_SENSOR
2271 ? 0 : mAnimationSetting;
Craig Mautner196943f2012-05-15 08:10:35 -07002272 if (mDebugLightAnimation) {
2273 Slog.v(TAG, "Doing power-off anim, mode=" + mode);
2274 }
Jim Miller46f31c32012-03-01 14:36:07 -08002275 mScreenBrightnessHandler.obtainMessage(ANIMATE_POWER_OFF, mode, 0)
2276 .sendToTarget();
Jim Miller92e66dd2012-02-21 18:57:12 -08002277 }
Craig Mautner196943f2012-05-15 08:10:35 -07002278 mScreenBrightnessHandler.removeMessages(
2279 ScreenBrightnessAnimator.ANIMATE_LIGHTS);
Jim Miller92e66dd2012-02-21 18:57:12 -08002280 Message msg = mScreenBrightnessHandler
2281 .obtainMessage(ANIMATE_LIGHTS, mask, newValue);
2282 mScreenBrightnessHandler.sendMessageDelayed(msg, delay);
2283 }
2284 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002285 }
Jim Miller92e66dd2012-02-21 18:57:12 -08002286
2287 public void dump(PrintWriter pw, String string) {
Craig Mautner291576e2012-06-07 19:58:58 -07002288 pw.println(string);
2289 pw.println(" animating: " + "start:" + startValue + ", end:" + endValue
Jim Miller92e66dd2012-02-21 18:57:12 -08002290 + ", duration:" + duration + ", current:" + currentValue);
Craig Mautner291576e2012-06-07 19:58:58 -07002291 pw.println(" startSensorValue:" + startSensorValue
2292 + " endSensorValue:" + endSensorValue);
2293 pw.println(" startSensorValue:" + startSensorValue
2294 + " endSensorValue:" + endSensorValue);
Jim Miller92e66dd2012-02-21 18:57:12 -08002295 }
2296
2297 public void animateTo(int target, int mask, int animationDuration) {
Craig Mautner196943f2012-05-15 08:10:35 -07002298 animateTo(target, mHighestLightSensorValue, mask, animationDuration);
2299 }
2300
2301 public void animateTo(int target, int sensorTarget, int mask, int animationDuration) {
Jim Miller92e66dd2012-02-21 18:57:12 -08002302 synchronized(this) {
Craig Mautner291576e2012-06-07 19:58:58 -07002303 if ((mask & SCREEN_BRIGHT_BIT) == 0) {
2304 // We only animate keyboard and button when passed in with SCREEN_BRIGHT_BIT.
2305 if ((mask & BUTTON_BRIGHT_BIT) != 0) {
2306 mButtonLight.setBrightness(target);
2307 }
2308 if ((mask & KEYBOARD_BRIGHT_BIT) != 0) {
2309 mKeyboardLight.setBrightness(target);
2310 }
2311 return;
2312 }
Craig Mautnerd29568c2012-06-01 16:02:47 -07002313 if (isAnimating() && (mask ^ currentMask) != 0) {
2314 // current animation is unrelated to new animation, jump to final values
2315 cancelAnimation();
2316 }
Jim Miller92e66dd2012-02-21 18:57:12 -08002317 startValue = currentValue;
2318 endValue = target;
Craig Mautner196943f2012-05-15 08:10:35 -07002319 startSensorValue = mHighestLightSensorValue;
2320 endSensorValue = sensorTarget;
Jim Miller92e66dd2012-02-21 18:57:12 -08002321 currentMask = mask;
2322 duration = (int) (mWindowScaleAnimation * animationDuration);
2323 startTimeMillis = SystemClock.elapsedRealtime();
Craig Mautneraf01fe02012-05-31 10:03:32 -07002324 mInitialAnimation = mInitialAnimation && target > 0;
Jim Miller92e66dd2012-02-21 18:57:12 -08002325
2326 if (mDebugLightAnimation) {
Craig Mautner196943f2012-05-15 08:10:35 -07002327 Slog.v(TAG, "animateTo(target=" + target
2328 + ", sensor=" + sensorTarget
2329 + ", mask=" + mask
Jim Miller92e66dd2012-02-21 18:57:12 -08002330 + ", duration=" + animationDuration +")"
2331 + ", currentValue=" + currentValue
2332 + ", startTime=" + startTimeMillis);
2333 }
2334
2335 if (target != currentValue) {
Jim Miller18651802012-03-07 14:19:56 -08002336 final boolean doScreenAnim = (mask & (SCREEN_BRIGHT_BIT | SCREEN_ON_BIT)) != 0;
Jeff Brown7304c342012-05-11 18:42:42 -07002337 final boolean turningOff = endValue == PowerManager.BRIGHTNESS_OFF;
Jim Miller18651802012-03-07 14:19:56 -08002338 if (turningOff && doScreenAnim) {
Jim Miller92e66dd2012-02-21 18:57:12 -08002339 // Cancel all pending animations since we're turning off
2340 mScreenBrightnessHandler.removeCallbacksAndMessages(null);
2341 screenOffFinishedAnimatingLocked(mScreenOffReason);
2342 duration = 200; // TODO: how long should this be?
2343 }
Jim Miller18651802012-03-07 14:19:56 -08002344 if (doScreenAnim) {
2345 animateInternal(mask, turningOff, 0);
2346 }
2347 // TODO: Handle keyboard light animation when we have devices that support it
Jim Miller92e66dd2012-02-21 18:57:12 -08002348 }
2349 }
2350 }
2351
2352 public int getCurrentBrightness() {
2353 synchronized (this) {
2354 return currentValue;
2355 }
2356 }
2357
2358 public boolean isAnimating() {
2359 synchronized (this) {
2360 return currentValue != endValue;
2361 }
2362 }
2363
2364 public void cancelAnimation() {
2365 animateTo(endValue, currentMask, 0);
The Android Open Source Project10592532009-03-18 17:39:46 -07002366 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002367 }
2368
Jim Miller92e66dd2012-02-21 18:57:12 -08002369 private void setLightBrightness(int mask, int value) {
2370 mScreenBrightnessAnimator.animateTo(value, mask, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002371 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002372
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002373 private int getPreferredBrightness() {
Jeff Brownf2ba1322012-05-31 18:04:14 -07002374 int brightness = mScreenBrightnessSetting;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002375 if (mScreenBrightnessOverride >= 0) {
Jeff Brownf2ba1322012-05-31 18:04:14 -07002376 brightness = mScreenBrightnessOverride;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002377 } else if (mLightSensorScreenBrightness >= 0 && mUseSoftwareAutoBrightness
2378 && mAutoBrightessEnabled) {
Jeff Brownf2ba1322012-05-31 18:04:14 -07002379 brightness = mLightSensorScreenBrightness;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002380 }
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002381 // Don't let applications turn the screen all the way off
2382 return Math.max(brightness, mScreenBrightnessDim);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002383 }
2384
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002385 private int applyButtonState(int state) {
2386 int brightness = -1;
Mike Lockwood48358bd2010-04-17 22:29:20 -04002387 if ((state & BATTERY_LOW_BIT) != 0) {
2388 // do not override brightness if the battery is low
2389 return state;
2390 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002391 if (mButtonBrightnessOverride >= 0) {
2392 brightness = mButtonBrightnessOverride;
2393 } else if (mLightSensorButtonBrightness >= 0 && mUseSoftwareAutoBrightness) {
2394 brightness = mLightSensorButtonBrightness;
2395 }
2396 if (brightness > 0) {
2397 return state | BUTTON_BRIGHT_BIT;
2398 } else if (brightness == 0) {
2399 return state & ~BUTTON_BRIGHT_BIT;
2400 } else {
2401 return state;
2402 }
2403 }
2404
2405 private int applyKeyboardState(int state) {
2406 int brightness = -1;
Mike Lockwood48358bd2010-04-17 22:29:20 -04002407 if ((state & BATTERY_LOW_BIT) != 0) {
2408 // do not override brightness if the battery is low
2409 return state;
2410 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002411 if (!mKeyboardVisible) {
2412 brightness = 0;
2413 } else if (mButtonBrightnessOverride >= 0) {
2414 brightness = mButtonBrightnessOverride;
2415 } else if (mLightSensorKeyboardBrightness >= 0 && mUseSoftwareAutoBrightness) {
2416 brightness = mLightSensorKeyboardBrightness;
2417 }
2418 if (brightness > 0) {
2419 return state | KEYBOARD_BRIGHT_BIT;
2420 } else if (brightness == 0) {
2421 return state & ~KEYBOARD_BRIGHT_BIT;
2422 } else {
2423 return state;
2424 }
2425 }
2426
Charles Mendis322591c2009-10-29 11:06:59 -07002427 public boolean isScreenOn() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002428 synchronized (mLocks) {
2429 return (mPowerState & SCREEN_ON_BIT) != 0;
2430 }
2431 }
2432
Charles Mendis322591c2009-10-29 11:06:59 -07002433 boolean isScreenBright() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002434 synchronized (mLocks) {
2435 return (mPowerState & SCREEN_BRIGHT) == SCREEN_BRIGHT;
2436 }
2437 }
2438
Mike Lockwood497087e32009-11-08 18:33:03 -05002439 private boolean isScreenTurningOffLocked() {
Jim Miller92e66dd2012-02-21 18:57:12 -08002440 return (mScreenBrightnessAnimator.isAnimating()
Craig Mautnerd29568c2012-06-01 16:02:47 -07002441 && mScreenBrightnessAnimator.endValue == PowerManager.BRIGHTNESS_OFF
2442 && (mScreenBrightnessAnimator.currentMask & SCREEN_BRIGHT_BIT) != 0);
Mike Lockwood497087e32009-11-08 18:33:03 -05002443 }
2444
Joe Onorato4b9f62d2010-10-11 13:41:35 -07002445 private boolean shouldLog(long time) {
2446 synchronized (mLocks) {
2447 if (time > (mWarningSpewThrottleTime + (60*60*1000))) {
2448 mWarningSpewThrottleTime = time;
2449 mWarningSpewThrottleCount = 0;
2450 return true;
2451 } else if (mWarningSpewThrottleCount < 30) {
2452 mWarningSpewThrottleCount++;
2453 return true;
2454 } else {
2455 return false;
2456 }
2457 }
2458 }
2459
Mike Lockwood200b30b2009-09-20 00:23:59 -04002460 private void forceUserActivityLocked() {
Mike Lockwoode090281422009-11-14 21:02:56 -05002461 if (isScreenTurningOffLocked()) {
2462 // cancel animation so userActivity will succeed
Jim Miller92e66dd2012-02-21 18:57:12 -08002463 mScreenBrightnessAnimator.cancelAnimation();
Mike Lockwoode090281422009-11-14 21:02:56 -05002464 }
Mike Lockwood200b30b2009-09-20 00:23:59 -04002465 boolean savedActivityAllowed = mUserActivityAllowed;
2466 mUserActivityAllowed = true;
2467 userActivity(SystemClock.uptimeMillis(), false);
2468 mUserActivityAllowed = savedActivityAllowed;
2469 }
2470
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002471 public void userActivityWithForce(long time, boolean noChangeLights, boolean force) {
2472 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
Joe Onorato7999bff2010-07-24 11:50:05 -04002473 userActivity(time, -1, noChangeLights, OTHER_EVENT, force);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002474 }
2475
2476 public void userActivity(long time, boolean noChangeLights) {
Joe Onorato4b9f62d2010-10-11 13:41:35 -07002477 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER)
2478 != PackageManager.PERMISSION_GRANTED) {
2479 if (shouldLog(time)) {
2480 Slog.w(TAG, "Caller does not have DEVICE_POWER permission. pid="
2481 + Binder.getCallingPid() + " uid=" + Binder.getCallingUid());
2482 }
2483 return;
2484 }
2485
Joe Onorato7999bff2010-07-24 11:50:05 -04002486 userActivity(time, -1, noChangeLights, OTHER_EVENT, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002487 }
2488
2489 public void userActivity(long time, boolean noChangeLights, int eventType) {
Joe Onorato7999bff2010-07-24 11:50:05 -04002490 userActivity(time, -1, noChangeLights, eventType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002491 }
2492
2493 public void userActivity(long time, boolean noChangeLights, int eventType, boolean force) {
Joe Onorato7999bff2010-07-24 11:50:05 -04002494 userActivity(time, -1, noChangeLights, eventType, force);
2495 }
2496
2497 /*
2498 * Reset the user activity timeout to now + timeout. This overrides whatever else is going
2499 * on with user activity. Don't use this function.
2500 */
2501 public void clearUserActivityTimeout(long now, long timeout) {
2502 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
2503 Slog.i(TAG, "clearUserActivity for " + timeout + "ms from now");
2504 userActivity(now, timeout, false, OTHER_EVENT, false);
2505 }
2506
2507 private void userActivity(long time, long timeoutOverride, boolean noChangeLights,
2508 int eventType, boolean force) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002509
Joe Onorato1a542c72010-11-08 09:48:20 -08002510 if (((mPokey & POKE_LOCK_IGNORE_TOUCH_EVENTS) != 0) && (eventType == TOUCH_EVENT)) {
Joe Onoratoe68ffcb2009-03-24 19:11:13 -07002511 if (false) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002512 Slog.d(TAG, "dropping touch mPokey=0x" + Integer.toHexString(mPokey));
Joe Onoratoe68ffcb2009-03-24 19:11:13 -07002513 }
2514 return;
2515 }
2516
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002517 synchronized (mLocks) {
2518 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002519 Slog.d(TAG, "userActivity mLastEventTime=" + mLastEventTime + " time=" + time
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002520 + " mUserActivityAllowed=" + mUserActivityAllowed
2521 + " mUserState=0x" + Integer.toHexString(mUserState)
Mike Lockwood36fc3022009-08-25 16:49:06 -07002522 + " mWakeLockState=0x" + Integer.toHexString(mWakeLockState)
2523 + " mProximitySensorActive=" + mProximitySensorActive
Joe Onorato797e6882010-08-26 14:46:01 -04002524 + " timeoutOverride=" + timeoutOverride
Mike Lockwood36fc3022009-08-25 16:49:06 -07002525 + " force=" + force);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002526 }
Mike Lockwood05067122009-10-27 23:07:25 -04002527 // ignore user activity if we are in the process of turning off the screen
Mike Lockwood497087e32009-11-08 18:33:03 -05002528 if (isScreenTurningOffLocked()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002529 Slog.d(TAG, "ignoring user activity while turning off screen");
Mike Lockwood05067122009-10-27 23:07:25 -04002530 return;
2531 }
Mike Lockwood0e39ea82009-11-18 15:37:10 -05002532 // Disable proximity sensor if if user presses power key while we are in the
2533 // "waiting for proximity sensor to go negative" state.
2534 if (mProximitySensorActive && mProximityWakeLockCount == 0) {
2535 mProximitySensorActive = false;
2536 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002537 if (mLastEventTime <= time || force) {
2538 mLastEventTime = time;
Mike Lockwood36fc3022009-08-25 16:49:06 -07002539 if ((mUserActivityAllowed && !mProximitySensorActive) || force) {
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002540 // Only turn on button backlights if a button was pressed
2541 // and auto brightness is disabled
Mike Lockwood4984e732009-11-01 08:16:33 -05002542 if (eventType == BUTTON_EVENT && !mUseSoftwareAutoBrightness) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002543 mUserState = (mKeyboardVisible ? ALL_BRIGHT : SCREEN_BUTTON_BRIGHT);
2544 } else {
2545 // don't clear button/keyboard backlights when the screen is touched.
2546 mUserState |= SCREEN_BRIGHT;
2547 }
2548
Dianne Hackborn617f8772009-03-31 15:04:46 -07002549 int uid = Binder.getCallingUid();
2550 long ident = Binder.clearCallingIdentity();
2551 try {
2552 mBatteryStats.noteUserActivity(uid, eventType);
2553 } catch (RemoteException e) {
2554 // Ignore
2555 } finally {
2556 Binder.restoreCallingIdentity(ident);
2557 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002558
Michael Chane96440f2009-05-06 10:27:36 -07002559 mWakeLockState = mLocks.reactivateScreenLocksLocked();
Mike Lockwood435eb642009-12-03 08:40:18 -05002560 setPowerState(mUserState | mWakeLockState, noChangeLights,
2561 WindowManagerPolicy.OFF_BECAUSE_OF_USER);
Joe Onorato7999bff2010-07-24 11:50:05 -04002562 setTimeoutLocked(time, timeoutOverride, SCREEN_BRIGHT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002563 }
2564 }
2565 }
Mike Lockwoodef731622010-01-27 17:51:34 -05002566
2567 if (mPolicy != null) {
2568 mPolicy.userActivity();
2569 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002570 }
2571
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002572 private int getAutoBrightnessValue(int sensorValue, int[] values) {
2573 try {
2574 int i;
2575 for (i = 0; i < mAutoBrightnessLevels.length; i++) {
2576 if (sensorValue < mAutoBrightnessLevels[i]) {
2577 break;
2578 }
2579 }
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002580 // This is the range of brightness values that we can use.
2581 final int minval = values[0];
2582 final int maxval = values[mAutoBrightnessLevels.length];
2583 // This is the range we will be scaling. We put some padding
2584 // at the low and high end to give the adjustment a little better
2585 // impact on the actual observed value.
2586 final int range = (maxval-minval) + LIGHT_SENSOR_RANGE_EXPANSION;
2587 // This is the desired brightness value from 0.0 to 1.0.
2588 float valf = ((values[i]-minval+(LIGHT_SENSOR_RANGE_EXPANSION/2))/(float)range);
2589 // Apply a scaling to the value based on the adjustment.
2590 if (mLightSensorAdjustSetting > 0 && mLightSensorAdjustSetting <= 1) {
2591 float adj = (float)Math.sqrt(1.0f-mLightSensorAdjustSetting);
2592 if (adj <= .00001) {
2593 valf = 1;
2594 } else {
2595 valf /= adj;
2596 }
2597 } else if (mLightSensorAdjustSetting < 0 && mLightSensorAdjustSetting >= -1) {
2598 float adj = (float)Math.sqrt(1.0f+mLightSensorAdjustSetting);
2599 valf *= adj;
2600 }
2601 // Apply an additional offset to the value based on the adjustment.
2602 valf += mLightSensorAdjustSetting/LIGHT_SENSOR_OFFSET_SCALE;
2603 // Convert the 0.0-1.0 value back to a brightness integer.
2604 int val = (int)((valf*range)+minval) - (LIGHT_SENSOR_RANGE_EXPANSION/2);
2605 if (val < minval) val = minval;
2606 else if (val > maxval) val = maxval;
2607 return val;
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002608 } catch (Exception e) {
2609 // guard against null pointer or index out of bounds errors
Jeff Browndaa37532012-05-01 15:54:03 -07002610 Slog.e(TAG, "Values array must be non-empty and must be one element longer than "
2611 + "the auto-brightness levels array. Check config.xml.", e);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002612 return 255;
2613 }
2614 }
2615
Mike Lockwood20f87d72009-11-05 16:08:51 -05002616 private Runnable mProximityTask = new Runnable() {
2617 public void run() {
2618 synchronized (mLocks) {
2619 if (mProximityPendingValue != -1) {
2620 proximityChangedLocked(mProximityPendingValue == 1);
2621 mProximityPendingValue = -1;
2622 }
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -05002623 if (mProximityPartialLock.isHeld()) {
2624 mProximityPartialLock.release();
2625 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05002626 }
2627 }
2628 };
2629
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002630 private Runnable mAutoBrightnessTask = new Runnable() {
2631 public void run() {
Mike Lockwoodfa68ab42009-10-20 11:08:49 -04002632 synchronized (mLocks) {
Jim Rodovichd102fea2010-09-02 12:30:49 -05002633 if (mLightSensorPendingDecrease || mLightSensorPendingIncrease) {
2634 int value = (int)mLightSensorPendingValue;
2635 mLightSensorPendingDecrease = false;
2636 mLightSensorPendingIncrease = false;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002637 lightSensorChangedLocked(value, false);
Mike Lockwoodfa68ab42009-10-20 11:08:49 -04002638 }
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002639 }
2640 }
2641 };
2642
Craig Mautneraf01fe02012-05-31 10:03:32 -07002643 /** used to prevent lightsensor changes while turning on. */
2644 private boolean mInitialAnimation = true;
Jim Miller92e66dd2012-02-21 18:57:12 -08002645
Mike Lockwoodb2865412010-02-02 22:40:33 -05002646 private void dockStateChanged(int state) {
2647 synchronized (mLocks) {
2648 mIsDocked = (state != Intent.EXTRA_DOCK_STATE_UNDOCKED);
2649 if (mIsDocked) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04002650 // allow brightness to decrease when docked
Mike Lockwoodb2865412010-02-02 22:40:33 -05002651 mHighestLightSensorValue = -1;
2652 }
2653 if ((mPowerState & SCREEN_ON_BIT) != 0) {
2654 // force lights recalculation
2655 int value = (int)mLightSensorValue;
2656 mLightSensorValue = -1;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002657 lightSensorChangedLocked(value, false);
Mike Lockwoodb2865412010-02-02 22:40:33 -05002658 }
2659 }
2660 }
2661
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002662 private void lightSensorChangedLocked(int value, boolean immediate) {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002663 if (mDebugLightSensor) {
Craig Mautner37933682012-06-06 14:13:39 -07002664 Slog.d(TAG, "lightSensorChangedLocked value=" + value + " immediate=" + immediate);
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002665 }
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002666
Joe Onorato06eb33a2010-10-25 14:09:21 -07002667 // Don't do anything if the screen is off.
2668 if ((mPowerState & SCREEN_ON_BIT) == 0) {
2669 if (mDebugLightSensor) {
2670 Slog.d(TAG, "dropping lightSensorChangedLocked because screen is off");
2671 }
2672 return;
2673 }
2674
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002675 if (mLightSensorValue != value) {
2676 mLightSensorValue = value;
2677 if ((mPowerState & BATTERY_LOW_BIT) == 0) {
Mike Lockwoodb2865412010-02-02 22:40:33 -05002678 // use maximum light sensor value seen since screen went on for LCD to avoid flicker
2679 // we only do this if we are undocked, since lighting should be stable when
2680 // stationary in a dock.
Craig Mautner196943f2012-05-15 08:10:35 -07002681 int lcdValue = getAutoBrightnessValue(value, mLcdBacklightValues);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002682 int buttonValue = getAutoBrightnessValue(value, mButtonBacklightValues);
Mike Lockwooddf024922009-10-29 21:29:15 -04002683 int keyboardValue;
2684 if (mKeyboardVisible) {
2685 keyboardValue = getAutoBrightnessValue(value, mKeyboardBacklightValues);
2686 } else {
2687 keyboardValue = 0;
2688 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002689 mLightSensorScreenBrightness = lcdValue;
2690 mLightSensorButtonBrightness = buttonValue;
2691 mLightSensorKeyboardBrightness = keyboardValue;
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002692
2693 if (mDebugLightSensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002694 Slog.d(TAG, "lcdValue " + lcdValue);
2695 Slog.d(TAG, "buttonValue " + buttonValue);
2696 Slog.d(TAG, "keyboardValue " + keyboardValue);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002697 }
2698
Mike Lockwood4984e732009-11-01 08:16:33 -05002699 if (mAutoBrightessEnabled && mScreenBrightnessOverride < 0) {
Jim Miller92e66dd2012-02-21 18:57:12 -08002700 if (!mSkippedScreenOn && !mInitialAnimation) {
Craig Mautner291576e2012-06-07 19:58:58 -07002701 final int steps;
2702 if (immediate) {
2703 steps = IMMEDIATE_ANIM_STEPS;
2704 } else {
2705 synchronized (mScreenBrightnessAnimator) {
2706 if (mScreenBrightnessAnimator.currentValue <= lcdValue) {
2707 steps = AUTOBRIGHTNESS_ANIM_STEPS;
2708 } else {
2709 steps = AUTODIMNESS_ANIM_STEPS;
2710 }
2711 }
2712 }
Craig Mautner196943f2012-05-15 08:10:35 -07002713 mScreenBrightnessAnimator.animateTo(lcdValue, value,
Jim Miller92e66dd2012-02-21 18:57:12 -08002714 SCREEN_BRIGHT_BIT, steps * NOMINAL_FRAME_TIME_MS);
Dianne Hackborn81de8b92011-11-28 16:54:31 -08002715 }
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002716 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002717 if (mButtonBrightnessOverride < 0) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002718 mButtonLight.setBrightness(buttonValue);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002719 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002720 if (mButtonBrightnessOverride < 0 || !mKeyboardVisible) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002721 mKeyboardLight.setBrightness(keyboardValue);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002722 }
2723 }
2724 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002725 }
2726
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002727 /**
2728 * The user requested that we go to sleep (probably with the power button).
2729 * This overrides all wake locks that are held.
2730 */
2731 public void goToSleep(long time)
2732 {
Dianne Hackborn254cb442010-01-27 19:23:59 -08002733 goToSleepWithReason(time, WindowManagerPolicy.OFF_BECAUSE_OF_USER);
2734 }
2735
2736 /**
2737 * The user requested that we go to sleep (probably with the power button).
2738 * This overrides all wake locks that are held.
2739 */
2740 public void goToSleepWithReason(long time, int reason)
2741 {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002742 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
2743 synchronized (mLocks) {
Dianne Hackborn254cb442010-01-27 19:23:59 -08002744 goToSleepLocked(time, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002745 }
2746 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002747
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002748 /**
Doug Zongker50a21f42009-11-19 12:49:53 -08002749 * Reboot the device immediately, passing 'reason' (may be null)
2750 * to the underlying __reboot system call. Should not return.
2751 */
2752 public void reboot(String reason)
2753 {
2754 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
San Mehat14e69af2010-01-06 14:58:18 -08002755
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002756 if (mHandler == null || !ActivityManagerNative.isSystemReady()) {
2757 throw new IllegalStateException("Too early to call reboot()");
2758 }
Mike Lockwoodb62f9592010-03-12 07:55:23 -05002759
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002760 final String finalReason = reason;
2761 Runnable runnable = new Runnable() {
2762 public void run() {
2763 synchronized (this) {
2764 ShutdownThread.reboot(mContext, finalReason, false);
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002765 }
Jim Miller92e66dd2012-02-21 18:57:12 -08002766
San Mehat1e512792010-01-07 10:40:29 -08002767 }
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002768 };
Mike Lockwoodb62f9592010-03-12 07:55:23 -05002769 // ShutdownThread must run on a looper capable of displaying the UI.
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002770 mHandler.post(runnable);
2771
Mike Lockwoodb62f9592010-03-12 07:55:23 -05002772 // PowerManager.reboot() is documented not to return so just wait for the inevitable.
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002773 synchronized (runnable) {
Mike Lockwoodb62f9592010-03-12 07:55:23 -05002774 while (true) {
2775 try {
2776 runnable.wait();
2777 } catch (InterruptedException e) {
2778 }
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002779 }
Doug Zongker50a21f42009-11-19 12:49:53 -08002780 }
2781 }
2782
Dan Egnor60d87622009-12-16 16:32:58 -08002783 /**
2784 * Crash the runtime (causing a complete restart of the Android framework).
2785 * Requires REBOOT permission. Mostly for testing. Should not return.
2786 */
2787 public void crash(final String message)
2788 {
2789 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
2790 Thread t = new Thread("PowerManagerService.crash()") {
2791 public void run() { throw new RuntimeException(message); }
2792 };
2793 try {
2794 t.start();
2795 t.join();
2796 } catch (InterruptedException e) {
2797 Log.wtf(TAG, e);
2798 }
2799 }
2800
Mike Lockwood435eb642009-12-03 08:40:18 -05002801 private void goToSleepLocked(long time, int reason) {
Jeff Browna75fe052012-05-01 18:41:26 -07002802 if (mSpew) {
2803 Exception ex = new Exception();
2804 ex.fillInStackTrace();
2805 Slog.d(TAG, "goToSleep mLastEventTime=" + mLastEventTime + " time=" + time
2806 + " reason=" + reason, ex);
2807 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002808
2809 if (mLastEventTime <= time) {
2810 mLastEventTime = time;
2811 // cancel all of the wake locks
2812 mWakeLockState = SCREEN_OFF;
2813 int N = mLocks.size();
2814 int numCleared = 0;
Joe Onorato8274a0e2010-10-05 17:38:09 -04002815 boolean proxLock = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002816 for (int i=0; i<N; i++) {
2817 WakeLock wl = mLocks.get(i);
2818 if (isScreenLock(wl.flags)) {
Joe Onorato8274a0e2010-10-05 17:38:09 -04002819 if (((wl.flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)
2820 && reason == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR) {
2821 proxLock = true;
2822 } else {
2823 mLocks.get(i).activated = false;
2824 numCleared++;
2825 }
2826 }
2827 }
2828 if (!proxLock) {
2829 mProxIgnoredBecauseScreenTurnedOff = true;
2830 if (mDebugProximitySensor) {
2831 Slog.d(TAG, "setting mProxIgnoredBecauseScreenTurnedOff");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002832 }
2833 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002834 EventLog.writeEvent(EventLogTags.POWER_SLEEP_REQUESTED, numCleared);
Joe Onorato128e7292009-03-24 18:41:31 -07002835 mStillNeedSleepNotification = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002836 mUserState = SCREEN_OFF;
Mike Lockwood435eb642009-12-03 08:40:18 -05002837 setPowerState(SCREEN_OFF, false, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002838 cancelTimerLocked();
2839 }
2840 }
2841
2842 public long timeSinceScreenOn() {
2843 synchronized (mLocks) {
2844 if ((mPowerState & SCREEN_ON_BIT) != 0) {
2845 return 0;
2846 }
2847 return SystemClock.elapsedRealtime() - mScreenOffTime;
2848 }
2849 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002850
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002851 public void setKeyboardVisibility(boolean visible) {
Mike Lockwooda625b382009-09-12 17:36:03 -07002852 synchronized (mLocks) {
2853 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002854 Slog.d(TAG, "setKeyboardVisibility: " + visible);
Mike Lockwooda625b382009-09-12 17:36:03 -07002855 }
Mike Lockwood3c9435a2009-10-22 15:45:37 -04002856 if (mKeyboardVisible != visible) {
2857 mKeyboardVisible = visible;
2858 // don't signal user activity if the screen is off; other code
2859 // will take care of turning on due to a true change to the lid
2860 // switch and synchronized with the lock screen.
2861 if ((mPowerState & SCREEN_ON_BIT) != 0) {
Mike Lockwood4984e732009-11-01 08:16:33 -05002862 if (mUseSoftwareAutoBrightness) {
Mike Lockwooddf024922009-10-29 21:29:15 -04002863 // force recompute of backlight values
2864 if (mLightSensorValue >= 0) {
2865 int value = (int)mLightSensorValue;
2866 mLightSensorValue = -1;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002867 lightSensorChangedLocked(value, false);
Mike Lockwooddf024922009-10-29 21:29:15 -04002868 }
2869 }
Mike Lockwood3c9435a2009-10-22 15:45:37 -04002870 userActivity(SystemClock.uptimeMillis(), false, BUTTON_EVENT, true);
2871 }
Mike Lockwooda625b382009-09-12 17:36:03 -07002872 }
2873 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002874 }
2875
2876 /**
2877 * When the keyguard is up, it manages the power state, and userActivity doesn't do anything.
Mike Lockwood50c548d2009-11-09 16:02:06 -05002878 * When disabling user activity we also reset user power state so the keyguard can reset its
2879 * short screen timeout when keyguard is unhidden.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002880 */
2881 public void enableUserActivity(boolean enabled) {
Mike Lockwood50c548d2009-11-09 16:02:06 -05002882 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002883 Slog.d(TAG, "enableUserActivity " + enabled);
Mike Lockwood50c548d2009-11-09 16:02:06 -05002884 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002885 synchronized (mLocks) {
2886 mUserActivityAllowed = enabled;
Mike Lockwood50c548d2009-11-09 16:02:06 -05002887 if (!enabled) {
2888 // cancel timeout and clear mUserState so the keyguard can set a short timeout
2889 setTimeoutLocked(SystemClock.uptimeMillis(), 0);
2890 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002891 }
2892 }
2893
Mike Lockwooddc3494e2009-10-14 21:17:09 -07002894 private void setScreenBrightnessMode(int mode) {
Joe Onoratod28f7532010-11-06 12:56:53 -07002895 synchronized (mLocks) {
2896 boolean enabled = (mode == SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
2897 if (mUseSoftwareAutoBrightness && mAutoBrightessEnabled != enabled) {
2898 mAutoBrightessEnabled = enabled;
2899 // This will get us a new value
2900 enableLightSensorLocked(mAutoBrightessEnabled && isScreenOn());
Mike Lockwood2d155d22009-10-27 09:32:30 -04002901 }
Mike Lockwooddc3494e2009-10-14 21:17:09 -07002902 }
2903 }
2904
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002905 /** Sets the screen off timeouts:
2906 * mKeylightDelay
2907 * mDimDelay
2908 * mScreenOffDelay
2909 * */
2910 private void setScreenOffTimeoutsLocked() {
2911 if ((mPokey & POKE_LOCK_SHORT_TIMEOUT) != 0) {
Doug Zongker43866e02010-01-07 12:09:54 -08002912 mKeylightDelay = mShortKeylightDelay; // Configurable via secure settings
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002913 mDimDelay = -1;
2914 mScreenOffDelay = 0;
2915 } else if ((mPokey & POKE_LOCK_MEDIUM_TIMEOUT) != 0) {
2916 mKeylightDelay = MEDIUM_KEYLIGHT_DELAY;
2917 mDimDelay = -1;
2918 mScreenOffDelay = 0;
2919 } else {
Dianne Hackborndf83afa2010-01-20 13:37:26 -08002920 int totalDelay = mScreenOffTimeoutSetting;
2921 if (totalDelay > mMaximumScreenOffTimeout) {
2922 totalDelay = mMaximumScreenOffTimeout;
2923 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002924 mKeylightDelay = LONG_KEYLIGHT_DELAY;
2925 if (totalDelay < 0) {
Jim Millerbc4603b2010-08-30 21:21:34 -07002926 // negative number means stay on as long as possible.
2927 mScreenOffDelay = mMaximumScreenOffTimeout;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002928 } else if (mKeylightDelay < totalDelay) {
2929 // subtract the time that the keylight delay. This will give us the
2930 // remainder of the time that we need to sleep to get the accurate
2931 // screen off timeout.
2932 mScreenOffDelay = totalDelay - mKeylightDelay;
2933 } else {
2934 mScreenOffDelay = 0;
2935 }
2936 if (mDimScreen && totalDelay >= (LONG_KEYLIGHT_DELAY + LONG_DIM_TIME)) {
2937 mDimDelay = mScreenOffDelay - LONG_DIM_TIME;
2938 mScreenOffDelay = LONG_DIM_TIME;
2939 } else {
2940 mDimDelay = -1;
2941 }
2942 }
2943 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002944 Slog.d(TAG, "setScreenOffTimeouts mKeylightDelay=" + mKeylightDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002945 + " mDimDelay=" + mDimDelay + " mScreenOffDelay=" + mScreenOffDelay
2946 + " mDimScreen=" + mDimScreen);
2947 }
2948 }
2949
2950 /**
Doug Zongker43866e02010-01-07 12:09:54 -08002951 * Refreshes cached secure settings. Called once on startup, and
2952 * on subsequent changes to secure settings.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002953 */
Doug Zongker43866e02010-01-07 12:09:54 -08002954 private void updateSettingsValues() {
2955 mShortKeylightDelay = Settings.Secure.getInt(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002956 mContext.getContentResolver(),
Doug Zongker43866e02010-01-07 12:09:54 -08002957 Settings.Secure.SHORT_KEYLIGHT_DELAY_MS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002958 SHORT_KEYLIGHT_DELAY_DEFAULT);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002959 // Slog.i(TAG, "updateSettingsValues(): mShortKeylightDelay now " + mShortKeylightDelay);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002960 }
2961
2962 private class LockList extends ArrayList<WakeLock>
2963 {
2964 void addLock(WakeLock wl)
2965 {
2966 int index = getIndex(wl.binder);
2967 if (index < 0) {
2968 this.add(wl);
2969 }
2970 }
2971
2972 WakeLock removeLock(IBinder binder)
2973 {
2974 int index = getIndex(binder);
2975 if (index >= 0) {
2976 return this.remove(index);
2977 } else {
2978 return null;
2979 }
2980 }
2981
2982 int getIndex(IBinder binder)
2983 {
2984 int N = this.size();
2985 for (int i=0; i<N; i++) {
2986 if (this.get(i).binder == binder) {
2987 return i;
2988 }
2989 }
2990 return -1;
2991 }
2992
2993 int gatherState()
2994 {
2995 int result = 0;
2996 int N = this.size();
2997 for (int i=0; i<N; i++) {
2998 WakeLock wl = this.get(i);
2999 if (wl.activated) {
3000 if (isScreenLock(wl.flags)) {
3001 result |= wl.minState;
3002 }
3003 }
3004 }
3005 return result;
3006 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003007
Michael Chane96440f2009-05-06 10:27:36 -07003008 int reactivateScreenLocksLocked()
3009 {
3010 int result = 0;
3011 int N = this.size();
3012 for (int i=0; i<N; i++) {
3013 WakeLock wl = this.get(i);
3014 if (isScreenLock(wl.flags)) {
3015 wl.activated = true;
3016 result |= wl.minState;
3017 }
3018 }
Joe Onorato8274a0e2010-10-05 17:38:09 -04003019 if (mDebugProximitySensor) {
3020 Slog.d(TAG, "reactivateScreenLocksLocked mProxIgnoredBecauseScreenTurnedOff="
3021 + mProxIgnoredBecauseScreenTurnedOff);
3022 }
3023 mProxIgnoredBecauseScreenTurnedOff = false;
Michael Chane96440f2009-05-06 10:27:36 -07003024 return result;
3025 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003026 }
3027
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08003028 public void setPolicy(WindowManagerPolicy p) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003029 synchronized (mLocks) {
3030 mPolicy = p;
3031 mLocks.notifyAll();
3032 }
3033 }
3034
3035 WindowManagerPolicy getPolicyLocked() {
3036 while (mPolicy == null || !mDoneBooting) {
3037 try {
3038 mLocks.wait();
3039 } catch (InterruptedException e) {
3040 // Ignore
3041 }
3042 }
3043 return mPolicy;
3044 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003045
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003046 void systemReady() {
Jeff Brown25157e42012-04-16 12:13:05 -07003047 mSensorManager = new SystemSensorManager(mHandlerThread.getLooper());
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003048 mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
3049 // don't bother with the light sensor if auto brightness is handled in hardware
Mike Lockwoodaa66ea82009-10-31 16:31:27 -04003050 if (mUseSoftwareAutoBrightness) {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003051 mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003052 }
3053
Mike Lockwoodb42ab0f2010-03-04 08:02:44 -05003054 // wait until sensors are enabled before turning on screen.
3055 // some devices will not activate the light sensor properly on boot
3056 // unless we do this.
3057 if (mUseSoftwareAutoBrightness) {
3058 // turn the screen on
3059 setPowerState(SCREEN_BRIGHT);
3060 } else {
3061 // turn everything on
3062 setPowerState(ALL_BRIGHT);
3063 }
3064
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003065 synchronized (mLocks) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003066 Slog.d(TAG, "system ready!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003067 mDoneBooting = true;
Mike Lockwoodb42ab0f2010-03-04 08:02:44 -05003068
Joe Onoratod28f7532010-11-06 12:56:53 -07003069 enableLightSensorLocked(mUseSoftwareAutoBrightness && mAutoBrightessEnabled);
3070
Dianne Hackborn617f8772009-03-31 15:04:46 -07003071 long identity = Binder.clearCallingIdentity();
3072 try {
3073 mBatteryStats.noteScreenBrightness(getPreferredBrightness());
3074 mBatteryStats.noteScreenOn();
3075 } catch (RemoteException e) {
3076 // Nothing interesting to do.
3077 } finally {
3078 Binder.restoreCallingIdentity(identity);
3079 }
Mike Lockwood2d7bb812009-11-15 18:12:22 -05003080 }
3081 }
3082
3083 void bootCompleted() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003084 Slog.d(TAG, "bootCompleted");
Mike Lockwood2d7bb812009-11-15 18:12:22 -05003085 synchronized (mLocks) {
3086 mBootCompleted = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003087 userActivity(SystemClock.uptimeMillis(), false, BUTTON_EVENT, true);
3088 updateWakeLockLocked();
3089 mLocks.notifyAll();
3090 }
3091 }
3092
Joe Onoratob08a1af2010-10-11 19:28:58 -07003093 // for watchdog
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003094 public void monitor() {
3095 synchronized (mLocks) { }
3096 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003097
3098 public int getSupportedWakeLockFlags() {
3099 int result = PowerManager.PARTIAL_WAKE_LOCK
3100 | PowerManager.FULL_WAKE_LOCK
3101 | PowerManager.SCREEN_DIM_WAKE_LOCK;
3102
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003103 if (mProximitySensor != null) {
3104 result |= PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK;
3105 }
3106
3107 return result;
3108 }
3109
Mike Lockwood237a2992009-09-15 14:42:16 -04003110 public void setBacklightBrightness(int brightness) {
3111 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
3112 // Don't let applications turn the screen all the way off
Joe Onoratob08a1af2010-10-11 19:28:58 -07003113 synchronized (mLocks) {
Mike Lockwoodeb6456b2011-09-13 15:24:02 -04003114 brightness = Math.max(brightness, mScreenBrightnessDim);
Joe Onoratob08a1af2010-10-11 19:28:58 -07003115 mLcdLight.setBrightness(brightness);
3116 mKeyboardLight.setBrightness(mKeyboardVisible ? brightness : 0);
3117 mButtonLight.setBrightness(brightness);
3118 long identity = Binder.clearCallingIdentity();
3119 try {
3120 mBatteryStats.noteScreenBrightness(brightness);
3121 } catch (RemoteException e) {
3122 Slog.w(TAG, "RemoteException calling noteScreenBrightness on BatteryStatsService", e);
3123 } finally {
3124 Binder.restoreCallingIdentity(identity);
3125 }
Jim Miller92e66dd2012-02-21 18:57:12 -08003126 mScreenBrightnessAnimator.animateTo(brightness, SCREEN_BRIGHT_BIT, 0);
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08003127 }
3128 }
3129
3130 public void setAutoBrightnessAdjustment(float adj) {
3131 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
3132 synchronized (mLocks) {
3133 mLightSensorAdjustSetting = adj;
3134 if (mSensorManager != null && mLightSensorEnabled) {
3135 // clear calling identity so sensor manager battery stats are accurate
3136 long identity = Binder.clearCallingIdentity();
3137 try {
3138 // force recompute of backlight values
3139 if (mLightSensorValue >= 0) {
3140 int value = (int)mLightSensorValue;
3141 mLightSensorValue = -1;
3142 handleLightSensorValue(value, true);
3143 }
3144 } finally {
3145 Binder.restoreCallingIdentity(identity);
3146 }
Joe Onorato3d3db602010-10-18 16:08:16 -04003147 }
Mike Lockwood237a2992009-09-15 14:42:16 -04003148 }
3149 }
3150
Mike Lockwoodb11832d2009-11-25 15:25:55 -05003151 public void setAttentionLight(boolean on, int color) {
3152 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
Mike Lockwood3cb67a32009-11-27 14:25:58 -05003153 mAttentionLight.setFlashing(color, LightsService.LIGHT_FLASH_HARDWARE, (on ? 3 : 0), 0);
Mike Lockwoodb11832d2009-11-25 15:25:55 -05003154 }
3155
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003156 private void enableProximityLockLocked() {
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003157 if (mDebugProximitySensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003158 Slog.d(TAG, "enableProximityLockLocked");
Mike Lockwood36fc3022009-08-25 16:49:06 -07003159 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003160 if (!mProximitySensorEnabled) {
3161 // clear calling identity so sensor manager battery stats are accurate
3162 long identity = Binder.clearCallingIdentity();
3163 try {
3164 mSensorManager.registerListener(mProximityListener, mProximitySensor,
3165 SensorManager.SENSOR_DELAY_NORMAL);
3166 mProximitySensorEnabled = true;
3167 } finally {
3168 Binder.restoreCallingIdentity(identity);
3169 }
Mike Lockwood809ad0f2009-10-26 22:10:33 -04003170 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003171 }
3172
3173 private void disableProximityLockLocked() {
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003174 if (mDebugProximitySensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003175 Slog.d(TAG, "disableProximityLockLocked");
Mike Lockwood36fc3022009-08-25 16:49:06 -07003176 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003177 if (mProximitySensorEnabled) {
3178 // clear calling identity so sensor manager battery stats are accurate
3179 long identity = Binder.clearCallingIdentity();
3180 try {
3181 mSensorManager.unregisterListener(mProximityListener);
3182 mHandler.removeCallbacks(mProximityTask);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -05003183 if (mProximityPartialLock.isHeld()) {
3184 mProximityPartialLock.release();
3185 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003186 mProximitySensorEnabled = false;
3187 } finally {
3188 Binder.restoreCallingIdentity(identity);
3189 }
3190 if (mProximitySensorActive) {
3191 mProximitySensorActive = false;
Joe Onorato8274a0e2010-10-05 17:38:09 -04003192 if (mDebugProximitySensor) {
3193 Slog.d(TAG, "disableProximityLockLocked mProxIgnoredBecauseScreenTurnedOff="
3194 + mProxIgnoredBecauseScreenTurnedOff);
3195 }
3196 if (!mProxIgnoredBecauseScreenTurnedOff) {
3197 forceUserActivityLocked();
3198 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003199 }
Mike Lockwood200b30b2009-09-20 00:23:59 -04003200 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003201 }
3202
Mike Lockwood20f87d72009-11-05 16:08:51 -05003203 private void proximityChangedLocked(boolean active) {
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003204 if (mDebugProximitySensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003205 Slog.d(TAG, "proximityChangedLocked, active: " + active);
Mike Lockwood20f87d72009-11-05 16:08:51 -05003206 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003207 if (!mProximitySensorEnabled) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003208 Slog.d(TAG, "Ignoring proximity change after sensor is disabled");
Mike Lockwood0d72f7e2009-11-05 20:53:00 -05003209 return;
3210 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05003211 if (active) {
Joe Onorato8274a0e2010-10-05 17:38:09 -04003212 if (mDebugProximitySensor) {
3213 Slog.d(TAG, "b mProxIgnoredBecauseScreenTurnedOff="
3214 + mProxIgnoredBecauseScreenTurnedOff);
3215 }
3216 if (!mProxIgnoredBecauseScreenTurnedOff) {
3217 goToSleepLocked(SystemClock.uptimeMillis(),
3218 WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR);
3219 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05003220 mProximitySensorActive = true;
3221 } else {
3222 // proximity sensor negative events trigger as user activity.
3223 // temporarily set mUserActivityAllowed to true so this will work
3224 // even when the keyguard is on.
3225 mProximitySensorActive = false;
Joe Onorato8274a0e2010-10-05 17:38:09 -04003226 if (mDebugProximitySensor) {
3227 Slog.d(TAG, "b mProxIgnoredBecauseScreenTurnedOff="
3228 + mProxIgnoredBecauseScreenTurnedOff);
3229 }
3230 if (!mProxIgnoredBecauseScreenTurnedOff) {
3231 forceUserActivityLocked();
3232 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003233
3234 if (mProximityWakeLockCount == 0) {
3235 // disable sensor if we have no listeners left after proximity negative
3236 disableProximityLockLocked();
3237 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05003238 }
3239 }
3240
Joe Onoratod28f7532010-11-06 12:56:53 -07003241 private void enableLightSensorLocked(boolean enable) {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003242 if (mDebugLightSensor) {
Joe Onoratod28f7532010-11-06 12:56:53 -07003243 Slog.d(TAG, "enableLightSensorLocked enable=" + enable
Craig Mautner37933682012-06-06 14:13:39 -07003244 + " mLightSensorEnabled=" + mLightSensorEnabled
3245 + " mAutoBrightessEnabled=" + mAutoBrightessEnabled
3246 + " mWaitingForFirstLightSensor=" + mWaitingForFirstLightSensor);
Joe Onoratod28f7532010-11-06 12:56:53 -07003247 }
3248 if (!mAutoBrightessEnabled) {
3249 enable = false;
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003250 }
3251 if (mSensorManager != null && mLightSensorEnabled != enable) {
3252 mLightSensorEnabled = enable;
Mike Lockwood809ad0f2009-10-26 22:10:33 -04003253 // clear calling identity so sensor manager battery stats are accurate
3254 long identity = Binder.clearCallingIdentity();
3255 try {
3256 if (enable) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003257 // reset our highest value when reenabling
3258 mHighestLightSensorValue = -1;
3259 // force recompute of backlight values
Craig Mautner37933682012-06-06 14:13:39 -07003260 final int value = (int)mLightSensorValue;
3261 if (value >= 0) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003262 mLightSensorValue = -1;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08003263 handleLightSensorValue(value, true);
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003264 }
Mike Lockwood809ad0f2009-10-26 22:10:33 -04003265 mSensorManager.registerListener(mLightListener, mLightSensor,
Mathias Agopian47f1fe52011-11-08 17:18:41 -08003266 LIGHT_SENSOR_RATE);
Mike Lockwood809ad0f2009-10-26 22:10:33 -04003267 } else {
3268 mSensorManager.unregisterListener(mLightListener);
3269 mHandler.removeCallbacks(mAutoBrightnessTask);
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003270 mLightSensorPendingDecrease = false;
3271 mLightSensorPendingIncrease = false;
Mike Lockwood809ad0f2009-10-26 22:10:33 -04003272 }
3273 } finally {
3274 Binder.restoreCallingIdentity(identity);
Mike Lockwood06952d92009-08-13 16:05:38 -04003275 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003276 }
3277 }
3278
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003279 SensorEventListener mProximityListener = new SensorEventListener() {
3280 public void onSensorChanged(SensorEvent event) {
Mike Lockwoodba8eb1e2009-11-08 19:31:18 -05003281 long milliseconds = SystemClock.elapsedRealtime();
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003282 synchronized (mLocks) {
3283 float distance = event.values[0];
Mike Lockwood20f87d72009-11-05 16:08:51 -05003284 long timeSinceLastEvent = milliseconds - mLastProximityEventTime;
3285 mLastProximityEventTime = milliseconds;
3286 mHandler.removeCallbacks(mProximityTask);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -05003287 boolean proximityTaskQueued = false;
Mike Lockwood20f87d72009-11-05 16:08:51 -05003288
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003289 // compare against getMaximumRange to support sensors that only return 0 or 1
Mike Lockwood20f87d72009-11-05 16:08:51 -05003290 boolean active = (distance >= 0.0 && distance < PROXIMITY_THRESHOLD &&
3291 distance < mProximitySensor.getMaximumRange());
3292
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003293 if (mDebugProximitySensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003294 Slog.d(TAG, "mProximityListener.onSensorChanged active: " + active);
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003295 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05003296 if (timeSinceLastEvent < PROXIMITY_SENSOR_DELAY) {
3297 // enforce delaying atleast PROXIMITY_SENSOR_DELAY before processing
3298 mProximityPendingValue = (active ? 1 : 0);
3299 mHandler.postDelayed(mProximityTask, PROXIMITY_SENSOR_DELAY - timeSinceLastEvent);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -05003300 proximityTaskQueued = true;
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003301 } else {
Mike Lockwood20f87d72009-11-05 16:08:51 -05003302 // process the value immediately
3303 mProximityPendingValue = -1;
3304 proximityChangedLocked(active);
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003305 }
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -05003306
3307 // update mProximityPartialLock state
3308 boolean held = mProximityPartialLock.isHeld();
3309 if (!held && proximityTaskQueued) {
3310 // hold wakelock until mProximityTask runs
3311 mProximityPartialLock.acquire();
3312 } else if (held && !proximityTaskQueued) {
3313 mProximityPartialLock.release();
3314 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003315 }
3316 }
3317
3318 public void onAccuracyChanged(Sensor sensor, int accuracy) {
3319 // ignore
3320 }
3321 };
3322
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08003323 private void handleLightSensorValue(int value, boolean immediate) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003324 long milliseconds = SystemClock.elapsedRealtime();
Craig Mautner37933682012-06-06 14:13:39 -07003325 if (mLightSensorValue == -1
3326 || milliseconds < mLastScreenOnTime + mLightSensorWarmupTime
3327 || mWaitingForFirstLightSensor) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003328 // process the value immediately if screen has just turned on
3329 mHandler.removeCallbacks(mAutoBrightnessTask);
3330 mLightSensorPendingDecrease = false;
3331 mLightSensorPendingIncrease = false;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08003332 lightSensorChangedLocked(value, immediate);
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003333 } else {
3334 if ((value > mLightSensorValue && mLightSensorPendingDecrease) ||
3335 (value < mLightSensorValue && mLightSensorPendingIncrease) ||
3336 (value == mLightSensorValue) ||
3337 (!mLightSensorPendingDecrease && !mLightSensorPendingIncrease)) {
3338 // delay processing to debounce the sensor
3339 mHandler.removeCallbacks(mAutoBrightnessTask);
3340 mLightSensorPendingDecrease = (value < mLightSensorValue);
3341 mLightSensorPendingIncrease = (value > mLightSensorValue);
3342 if (mLightSensorPendingDecrease || mLightSensorPendingIncrease) {
3343 mLightSensorPendingValue = value;
3344 mHandler.postDelayed(mAutoBrightnessTask, LIGHT_SENSOR_DELAY);
3345 }
3346 } else {
3347 mLightSensorPendingValue = value;
3348 }
3349 }
3350 }
3351
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003352 SensorEventListener mLightListener = new SensorEventListener() {
3353 public void onSensorChanged(SensorEvent event) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003354 if (mDebugLightSensor) {
3355 Slog.d(TAG, "onSensorChanged: light value: " + event.values[0]);
3356 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003357 synchronized (mLocks) {
Mike Lockwood497087e32009-11-08 18:33:03 -05003358 // ignore light sensor while screen is turning off
3359 if (isScreenTurningOffLocked()) {
3360 return;
3361 }
Craig Mautner37933682012-06-06 14:13:39 -07003362 handleLightSensorValue((int)event.values[0], mWaitingForFirstLightSensor);
3363 if (mWaitingForFirstLightSensor) {
3364 mWaitingForFirstLightSensor = false;
3365 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003366 }
3367 }
3368
3369 public void onAccuracyChanged(Sensor sensor, int accuracy) {
3370 // ignore
3371 }
3372 };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003373}