blob: bb0ac3efcc61668e1f6a9612aa82719b1da7acdb [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;
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -080020import com.android.internal.app.ShutdownThread;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021import com.android.server.am.BatteryStatsService;
22
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;
Amith Yamasani8b619832010-09-22 16:11:59 -070040import android.os.BatteryManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.os.BatteryStats;
42import android.os.Binder;
43import android.os.Handler;
44import android.os.HandlerThread;
45import android.os.IBinder;
46import android.os.IPowerManager;
47import android.os.LocalPowerManager;
48import android.os.Power;
49import android.os.PowerManager;
50import android.os.Process;
51import android.os.RemoteException;
52import android.os.SystemClock;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070053import android.os.WorkSource;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054import android.provider.Settings;
55import android.util.EventLog;
56import android.util.Log;
Joe Onorato8a9b2202010-02-26 18:56:32 -080057import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058import android.view.WindowManagerPolicy;
59import static android.provider.Settings.System.DIM_SCREEN;
60import static android.provider.Settings.System.SCREEN_BRIGHTNESS;
Dan Murphy951764b2009-08-27 14:59:03 -050061import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -080062import static android.provider.Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ;
Mike Lockwooddc3494e2009-10-14 21:17:09 -070063import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
65import static android.provider.Settings.System.STAY_ON_WHILE_PLUGGED_IN;
Joe Onorato609695d2010-10-14 14:57:49 -070066import static android.provider.Settings.System.WINDOW_ANIMATION_SCALE;
67import static android.provider.Settings.System.TRANSITION_ANIMATION_SCALE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068
69import java.io.FileDescriptor;
70import java.io.PrintWriter;
71import java.util.ArrayList;
72import java.util.HashMap;
73import java.util.Observable;
74import java.util.Observer;
75
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080076public class PowerManagerService extends IPowerManager.Stub
Mike Lockwood8738e0c2009-10-04 08:44:47 -040077 implements LocalPowerManager, Watchdog.Monitor {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078
79 private static final String TAG = "PowerManagerService";
80 static final String PARTIAL_NAME = "PowerManagerService";
81
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -070082 static final boolean DEBUG_SCREEN_ON = false;
83
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084 private static final boolean LOG_PARTIAL_WL = false;
85
86 // Indicates whether touch-down cycles should be logged as part of the
87 // LOG_POWER_SCREEN_STATE log events
88 private static final boolean LOG_TOUCH_DOWNS = true;
89
90 private static final int LOCK_MASK = PowerManager.PARTIAL_WAKE_LOCK
91 | PowerManager.SCREEN_DIM_WAKE_LOCK
92 | PowerManager.SCREEN_BRIGHT_WAKE_LOCK
Mike Lockwoodbc706a02009-07-27 13:50:57 -070093 | PowerManager.FULL_WAKE_LOCK
94 | PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095
96 // time since last state: time since last event:
Doug Zongker43866e02010-01-07 12:09:54 -080097 // The short keylight delay comes from secure settings; this is the default.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098 private static final int SHORT_KEYLIGHT_DELAY_DEFAULT = 6000; // t+6 sec
99 private static final int MEDIUM_KEYLIGHT_DELAY = 15000; // t+15 sec
100 private static final int LONG_KEYLIGHT_DELAY = 6000; // t+6 sec
101 private static final int LONG_DIM_TIME = 7000; // t+N-5 sec
102
Mathias Agopian47f1fe52011-11-08 17:18:41 -0800103 // How long to wait to debounce light sensor changes in milliseconds
Mike Lockwood9b8136922009-11-06 15:53:59 -0500104 private static final int LIGHT_SENSOR_DELAY = 2000;
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700105
Mathias Agopian47f1fe52011-11-08 17:18:41 -0800106 // light sensor events rate in microseconds
107 private static final int LIGHT_SENSOR_RATE = 1000000;
108
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800109 // Expansion of range of light values when applying scale from light
110 // sensor brightness setting, in the [0..255] brightness range.
111 private static final int LIGHT_SENSOR_RANGE_EXPANSION = 20;
112
113 // Scaling factor of the light sensor brightness setting when applying
114 // it to the final brightness.
115 private static final int LIGHT_SENSOR_OFFSET_SCALE = 8;
116
Mathias Agopian47f1fe52011-11-08 17:18:41 -0800117 // For debouncing the proximity sensor in milliseconds
Mike Lockwood20f87d72009-11-05 16:08:51 -0500118 private static final int PROXIMITY_SENSOR_DELAY = 1000;
119
Mike Lockwoodd20ea362009-09-15 00:13:38 -0400120 // trigger proximity if distance is less than 5 cm
121 private static final float PROXIMITY_THRESHOLD = 5.0f;
122
Doug Zongker43866e02010-01-07 12:09:54 -0800123 // Cached secure settings; see updateSettingsValues()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124 private int mShortKeylightDelay = SHORT_KEYLIGHT_DELAY_DEFAULT;
125
Amith Yamasani8b619832010-09-22 16:11:59 -0700126 // Default timeout for screen off, if not found in settings database = 15 seconds.
127 private static final int DEFAULT_SCREEN_OFF_TIMEOUT = 15000;
128
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800129 // Screen brightness should always have a value, but just in case...
130 private static final int DEFAULT_SCREEN_BRIGHTNESS = 192;
131
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132 // flags for setPowerState
133 private static final int SCREEN_ON_BIT = 0x00000001;
134 private static final int SCREEN_BRIGHT_BIT = 0x00000002;
135 private static final int BUTTON_BRIGHT_BIT = 0x00000004;
136 private static final int KEYBOARD_BRIGHT_BIT = 0x00000008;
137 private static final int BATTERY_LOW_BIT = 0x00000010;
138
139 // values for setPowerState
140
141 // SCREEN_OFF == everything off
142 private static final int SCREEN_OFF = 0x00000000;
143
144 // SCREEN_DIM == screen on, screen backlight dim
145 private static final int SCREEN_DIM = SCREEN_ON_BIT;
146
147 // SCREEN_BRIGHT == screen on, screen backlight bright
148 private static final int SCREEN_BRIGHT = SCREEN_ON_BIT | SCREEN_BRIGHT_BIT;
149
150 // SCREEN_BUTTON_BRIGHT == screen on, screen and button backlights bright
151 private static final int SCREEN_BUTTON_BRIGHT = SCREEN_BRIGHT | BUTTON_BRIGHT_BIT;
152
153 // SCREEN_BUTTON_BRIGHT == screen on, screen, button and keyboard backlights bright
154 private static final int ALL_BRIGHT = SCREEN_BUTTON_BRIGHT | KEYBOARD_BRIGHT_BIT;
155
156 // used for noChangeLights in setPowerState()
157 private static final int LIGHTS_MASK = SCREEN_BRIGHT_BIT | BUTTON_BRIGHT_BIT | KEYBOARD_BRIGHT_BIT;
158
Joe Onoratob08a1af2010-10-11 19:28:58 -0700159 boolean mAnimateScreenLights = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800160
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161 static final int ANIM_STEPS = 60/4;
Mike Lockwooddd9668e2009-10-27 15:47:02 -0400162 // Slower animation for autobrightness changes
163 static final int AUTOBRIGHTNESS_ANIM_STEPS = 60;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800164 // Number of steps when performing a more immediate brightness change.
165 static final int IMMEDIATE_ANIM_STEPS = 4;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800166
167 // These magic numbers are the initial state of the LEDs at boot. Ideally
168 // we should read them from the driver, but our current hardware returns 0
169 // for the initial value. Oops!
170 static final int INITIAL_SCREEN_BRIGHTNESS = 255;
171 static final int INITIAL_BUTTON_BRIGHTNESS = Power.BRIGHTNESS_OFF;
172 static final int INITIAL_KEYBOARD_BRIGHTNESS = Power.BRIGHTNESS_OFF;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800173
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 private final int MY_UID;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700175 private final int MY_PID;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800176
177 private boolean mDoneBooting = false;
Mike Lockwood2d7bb812009-11-15 18:12:22 -0500178 private boolean mBootCompleted = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800179 private int mStayOnConditions = 0;
Mike Lockwoodca44df82010-02-25 13:48:49 -0500180 private final int[] mBroadcastQueue = new int[] { -1, -1, -1 };
181 private final int[] mBroadcastWhy = new int[3];
Dianne Hackborn38e29a62011-09-18 14:43:08 -0700182 private boolean mPreparingForScreenOn = false;
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700183 private boolean mSkippedScreenOn = false;
184 private boolean mInitialized = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800185 private int mPartialCount = 0;
186 private int mPowerState;
Mike Lockwood435eb642009-12-03 08:40:18 -0500187 // mScreenOffReason can be WindowManagerPolicy.OFF_BECAUSE_OF_USER,
188 // WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT or WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR
189 private int mScreenOffReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800190 private int mUserState;
191 private boolean mKeyboardVisible = false;
192 private boolean mUserActivityAllowed = true;
Mike Lockwoodee2b0942009-11-09 14:09:02 -0500193 private int mProximityWakeLockCount = 0;
194 private boolean mProximitySensorEnabled = false;
Mike Lockwood36fc3022009-08-25 16:49:06 -0700195 private boolean mProximitySensorActive = false;
Mike Lockwood20f87d72009-11-05 16:08:51 -0500196 private int mProximityPendingValue = -1; // -1 == nothing, 0 == inactive, 1 == active
197 private long mLastProximityEventTime;
Dianne Hackborndf83afa2010-01-20 13:37:26 -0800198 private int mScreenOffTimeoutSetting;
199 private int mMaximumScreenOffTimeout = Integer.MAX_VALUE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800200 private int mKeylightDelay;
201 private int mDimDelay;
202 private int mScreenOffDelay;
203 private int mWakeLockState;
204 private long mLastEventTime = 0;
205 private long mScreenOffTime;
206 private volatile WindowManagerPolicy mPolicy;
207 private final LockList mLocks = new LockList();
208 private Intent mScreenOffIntent;
209 private Intent mScreenOnIntent;
Mike Lockwood3a322132009-11-24 00:30:52 -0500210 private LightsService mLightsService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211 private Context mContext;
Mike Lockwood3cb67a32009-11-27 14:25:58 -0500212 private LightsService.Light mLcdLight;
213 private LightsService.Light mButtonLight;
214 private LightsService.Light mKeyboardLight;
215 private LightsService.Light mAttentionLight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800216 private UnsynchronizedWakeLock mBroadcastWakeLock;
217 private UnsynchronizedWakeLock mStayOnWhilePluggedInScreenDimLock;
218 private UnsynchronizedWakeLock mStayOnWhilePluggedInPartialLock;
219 private UnsynchronizedWakeLock mPreventScreenOnPartialLock;
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -0500220 private UnsynchronizedWakeLock mProximityPartialLock;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221 private HandlerThread mHandlerThread;
Joe Onoratob08a1af2010-10-11 19:28:58 -0700222 private HandlerThread mScreenOffThread;
223 private Handler mScreenOffHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224 private Handler mHandler;
Mike Lockwoodca44df82010-02-25 13:48:49 -0500225 private final TimeoutTask mTimeoutTask = new TimeoutTask();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226 private final BrightnessState mScreenBrightness
The Android Open Source Project10592532009-03-18 17:39:46 -0700227 = new BrightnessState(SCREEN_BRIGHT_BIT);
Joe Onorato128e7292009-03-24 18:41:31 -0700228 private boolean mStillNeedSleepNotification;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800229 private boolean mIsPowered = false;
230 private IActivityManager mActivityService;
231 private IBatteryStats mBatteryStats;
232 private BatteryService mBatteryService;
Mike Lockwoodbc706a02009-07-27 13:50:57 -0700233 private SensorManager mSensorManager;
234 private Sensor mProximitySensor;
Mike Lockwood8738e0c2009-10-04 08:44:47 -0400235 private Sensor mLightSensor;
236 private boolean mLightSensorEnabled;
237 private float mLightSensorValue = -1;
Joe Onorato8274a0e2010-10-05 17:38:09 -0400238 private boolean mProxIgnoredBecauseScreenTurnedOff = false;
Mike Lockwoodb2865412010-02-02 22:40:33 -0500239 private int mHighestLightSensorValue = -1;
Jim Rodovichd102fea2010-09-02 12:30:49 -0500240 private boolean mLightSensorPendingDecrease = false;
241 private boolean mLightSensorPendingIncrease = false;
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700242 private float mLightSensorPendingValue = -1;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800243 private float mLightSensorAdjustSetting = 0;
Mike Lockwoodfb73f792009-11-20 11:31:18 -0500244 private int mLightSensorScreenBrightness = -1;
245 private int mLightSensorButtonBrightness = -1;
246 private int mLightSensorKeyboardBrightness = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247 private boolean mDimScreen = true;
Mike Lockwoodb2865412010-02-02 22:40:33 -0500248 private boolean mIsDocked = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800249 private long mNextTimeout;
250 private volatile int mPokey = 0;
251 private volatile boolean mPokeAwakeOnSet = false;
252 private volatile boolean mInitComplete = false;
Mike Lockwoodca44df82010-02-25 13:48:49 -0500253 private final HashMap<IBinder,PokeLock> mPokeLocks = new HashMap<IBinder,PokeLock>();
Mike Lockwood20ee6f22009-11-07 20:33:47 -0500254 // mLastScreenOnTime is the time the screen was last turned on
255 private long mLastScreenOnTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800256 private boolean mPreventScreenOn;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800257 private int mScreenBrightnessSetting = DEFAULT_SCREEN_BRIGHTNESS;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800258 private int mScreenBrightnessOverride = -1;
Mike Lockwoodfb73f792009-11-20 11:31:18 -0500259 private int mButtonBrightnessOverride = -1;
Mike Lockwoodeb6456b2011-09-13 15:24:02 -0400260 private int mScreenBrightnessDim;
Mike Lockwoodaa66ea82009-10-31 16:31:27 -0400261 private boolean mUseSoftwareAutoBrightness;
Mike Lockwooddc3494e2009-10-14 21:17:09 -0700262 private boolean mAutoBrightessEnabled;
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700263 private int[] mAutoBrightnessLevels;
264 private int[] mLcdBacklightValues;
265 private int[] mButtonBacklightValues;
266 private int[] mKeyboardBacklightValues;
Mike Lockwood20ee6f22009-11-07 20:33:47 -0500267 private int mLightSensorWarmupTime;
Joe Onorato6d747652010-10-11 15:15:31 -0700268 boolean mUnplugTurnsOnScreen;
Joe Onorato4b9f62d2010-10-11 13:41:35 -0700269 private int mWarningSpewThrottleCount;
270 private long mWarningSpewThrottleTime;
Joe Onorato609695d2010-10-14 14:57:49 -0700271 private int mAnimationSetting = ANIM_SETTING_OFF;
272
273 // Must match with the ISurfaceComposer constants in C++.
274 private static final int ANIM_SETTING_ON = 0x01;
275 private static final int ANIM_SETTING_OFF = 0x10;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800276
277 // Used when logging number and duration of touch-down cycles
278 private long mTotalTouchDownTime;
279 private long mLastTouchDown;
280 private int mTouchCycles;
281
282 // could be either static or controllable at runtime
283 private static final boolean mSpew = false;
Joe Onorato8274a0e2010-10-05 17:38:09 -0400284 private static final boolean mDebugProximitySensor = (false || mSpew);
Mike Lockwoodae92eb32011-10-25 10:11:46 -0400285 private static final boolean mDebugLightSensor = (false || mSpew);
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700286
287 private native void nativeInit();
288 private native void nativeSetPowerState(boolean screenOn, boolean screenBright);
Joe Onorato609695d2010-10-14 14:57:49 -0700289 private native void nativeStartSurfaceFlingerAnimation(int mode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800290
291 /*
292 static PrintStream mLog;
293 static {
294 try {
295 mLog = new PrintStream("/data/power.log");
296 }
297 catch (FileNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800298 android.util.Slog.e(TAG, "Life is hard", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800299 }
300 }
301 static class Log {
302 static void d(String tag, String s) {
303 mLog.println(s);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800304 android.util.Slog.d(tag, s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305 }
306 static void i(String tag, String s) {
307 mLog.println(s);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800308 android.util.Slog.i(tag, s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800309 }
310 static void w(String tag, String s) {
311 mLog.println(s);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800312 android.util.Slog.w(tag, s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313 }
314 static void e(String tag, String s) {
315 mLog.println(s);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800316 android.util.Slog.e(tag, s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800317 }
318 }
319 */
320
321 /**
322 * This class works around a deadlock between the lock in PowerManager.WakeLock
323 * and our synchronizing on mLocks. PowerManager.WakeLock synchronizes on its
324 * mToken object so it can be accessed from any thread, but it calls into here
325 * with its lock held. This class is essentially a reimplementation of
326 * PowerManager.WakeLock, but without that extra synchronized block, because we'll
327 * only call it with our own locks held.
328 */
329 private class UnsynchronizedWakeLock {
330 int mFlags;
331 String mTag;
332 IBinder mToken;
333 int mCount = 0;
334 boolean mRefCounted;
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -0500335 boolean mHeld;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800336
337 UnsynchronizedWakeLock(int flags, String tag, boolean refCounted) {
338 mFlags = flags;
339 mTag = tag;
340 mToken = new Binder();
341 mRefCounted = refCounted;
342 }
343
344 public void acquire() {
345 if (!mRefCounted || mCount++ == 0) {
346 long ident = Binder.clearCallingIdentity();
347 try {
348 PowerManagerService.this.acquireWakeLockLocked(mFlags, mToken,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700349 MY_UID, MY_PID, mTag, null);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -0500350 mHeld = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800351 } finally {
352 Binder.restoreCallingIdentity(ident);
353 }
354 }
355 }
356
357 public void release() {
358 if (!mRefCounted || --mCount == 0) {
Mike Lockwood0e39ea82009-11-18 15:37:10 -0500359 PowerManagerService.this.releaseWakeLockLocked(mToken, 0, false);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -0500360 mHeld = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800361 }
362 if (mCount < 0) {
363 throw new RuntimeException("WakeLock under-locked " + mTag);
364 }
365 }
366
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -0500367 public boolean isHeld()
368 {
369 return mHeld;
370 }
371
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800372 public String toString() {
373 return "UnsynchronizedWakeLock(mFlags=0x" + Integer.toHexString(mFlags)
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -0500374 + " mCount=" + mCount + " mHeld=" + mHeld + ")";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800375 }
376 }
377
378 private final class BatteryReceiver extends BroadcastReceiver {
379 @Override
380 public void onReceive(Context context, Intent intent) {
381 synchronized (mLocks) {
382 boolean wasPowered = mIsPowered;
383 mIsPowered = mBatteryService.isPowered();
384
385 if (mIsPowered != wasPowered) {
386 // update mStayOnWhilePluggedIn wake lock
387 updateWakeLockLocked();
388
389 // treat plugging and unplugging the devices as a user activity.
390 // users find it disconcerting when they unplug the device
391 // and it shuts off right away.
Mike Lockwood84a89342010-03-01 21:28:58 -0500392 // to avoid turning on the screen when unplugging, we only trigger
393 // user activity when screen was already on.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800394 // temporarily set mUserActivityAllowed to true so this will work
395 // even when the keyguard is on.
Joe Onorato6d747652010-10-11 15:15:31 -0700396 // However, you can also set config_unplugTurnsOnScreen to have it
397 // turn on. Some devices want this because they don't have a
398 // charging LED.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800399 synchronized (mLocks) {
Joe Onorato6d747652010-10-11 15:15:31 -0700400 if (!wasPowered || (mPowerState & SCREEN_ON_BIT) != 0 ||
401 mUnplugTurnsOnScreen) {
Mike Lockwood84a89342010-03-01 21:28:58 -0500402 forceUserActivityLocked();
403 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800404 }
405 }
406 }
407 }
408 }
409
Mike Lockwood2d7bb812009-11-15 18:12:22 -0500410 private final class BootCompletedReceiver extends BroadcastReceiver {
411 @Override
412 public void onReceive(Context context, Intent intent) {
413 bootCompleted();
414 }
415 }
416
Mike Lockwoodb2865412010-02-02 22:40:33 -0500417 private final class DockReceiver extends BroadcastReceiver {
418 @Override
419 public void onReceive(Context context, Intent intent) {
420 int state = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
421 Intent.EXTRA_DOCK_STATE_UNDOCKED);
422 dockStateChanged(state);
423 }
424 }
425
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800426 /**
427 * Set the setting that determines whether the device stays on when plugged in.
428 * The argument is a bit string, with each bit specifying a power source that,
429 * when the device is connected to that source, causes the device to stay on.
430 * See {@link android.os.BatteryManager} for the list of power sources that
431 * can be specified. Current values include {@link android.os.BatteryManager#BATTERY_PLUGGED_AC}
432 * and {@link android.os.BatteryManager#BATTERY_PLUGGED_USB}
433 * @param val an {@code int} containing the bits that specify which power sources
434 * should cause the device to stay on.
435 */
436 public void setStayOnSetting(int val) {
437 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS, null);
438 Settings.System.putInt(mContext.getContentResolver(),
439 Settings.System.STAY_ON_WHILE_PLUGGED_IN, val);
440 }
441
Dianne Hackborndf83afa2010-01-20 13:37:26 -0800442 public void setMaximumScreenOffTimeount(int timeMs) {
443 mContext.enforceCallingOrSelfPermission(
444 android.Manifest.permission.WRITE_SECURE_SETTINGS, null);
445 synchronized (mLocks) {
446 mMaximumScreenOffTimeout = timeMs;
447 // recalculate everything
448 setScreenOffTimeoutsLocked();
449 }
450 }
451
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800452 private class SettingsObserver implements Observer {
Amith Yamasani8b619832010-09-22 16:11:59 -0700453 private int getInt(String name, int defValue) {
454 ContentValues values = mSettings.getValues(name);
455 Integer iVal = values != null ? values.getAsInteger(Settings.System.VALUE) : null;
456 return iVal != null ? iVal : defValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800457 }
458
Joe Onorato609695d2010-10-14 14:57:49 -0700459 private float getFloat(String name, float defValue) {
460 ContentValues values = mSettings.getValues(name);
461 Float fVal = values != null ? values.getAsFloat(Settings.System.VALUE) : null;
462 return fVal != null ? fVal : defValue;
463 }
464
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800465 public void update(Observable o, Object arg) {
466 synchronized (mLocks) {
Amith Yamasani8b619832010-09-22 16:11:59 -0700467 // STAY_ON_WHILE_PLUGGED_IN, default to when plugged into AC
468 mStayOnConditions = getInt(STAY_ON_WHILE_PLUGGED_IN,
469 BatteryManager.BATTERY_PLUGGED_AC);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800470 updateWakeLockLocked();
471
Amith Yamasani8b619832010-09-22 16:11:59 -0700472 // SCREEN_OFF_TIMEOUT, default to 15 seconds
473 mScreenOffTimeoutSetting = getInt(SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800474
Joe Onorato609695d2010-10-14 14:57:49 -0700475 // DIM_SCREEN
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800476 //mDimScreen = getInt(DIM_SCREEN) != 0;
477
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800478 mScreenBrightnessSetting = getInt(SCREEN_BRIGHTNESS, DEFAULT_SCREEN_BRIGHTNESS);
479 mLightSensorAdjustSetting = getFloat(SCREEN_AUTO_BRIGHTNESS_ADJ, 0);
480
Amith Yamasani8b619832010-09-22 16:11:59 -0700481 // SCREEN_BRIGHTNESS_MODE, default to manual
482 setScreenBrightnessMode(getInt(SCREEN_BRIGHTNESS_MODE,
483 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL));
Mike Lockwooddc3494e2009-10-14 21:17:09 -0700484
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800485 // recalculate everything
486 setScreenOffTimeoutsLocked();
Joe Onorato609695d2010-10-14 14:57:49 -0700487
488 final float windowScale = getFloat(WINDOW_ANIMATION_SCALE, 1.0f);
489 final float transitionScale = getFloat(TRANSITION_ANIMATION_SCALE, 1.0f);
490 mAnimationSetting = 0;
491 if (windowScale > 0.5f) {
492 mAnimationSetting |= ANIM_SETTING_OFF;
493 }
494 if (transitionScale > 0.5f) {
495 // Uncomment this if you want the screen-on animation.
496 // mAnimationSetting |= ANIM_SETTING_ON;
497 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800498 }
499 }
500 }
501
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700502 PowerManagerService() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800503 // Hack to get our uid... should have a func for this.
504 long token = Binder.clearCallingIdentity();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700505 MY_UID = Process.myUid();
506 MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800507 Binder.restoreCallingIdentity(token);
508
509 // XXX remove this when the kernel doesn't timeout wake locks
510 Power.setLastUserActivityTimeout(7*24*3600*1000); // one week
511
512 // assume nothing is on yet
513 mUserState = mPowerState = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800514
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800515 // Add ourself to the Watchdog monitors.
516 Watchdog.getInstance().addMonitor(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800517 }
518
519 private ContentQueryMap mSettings;
520
Mike Lockwood3a322132009-11-24 00:30:52 -0500521 void init(Context context, LightsService lights, IActivityManager activity,
The Android Open Source Project10592532009-03-18 17:39:46 -0700522 BatteryService battery) {
Mike Lockwood3a322132009-11-24 00:30:52 -0500523 mLightsService = lights;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800524 mContext = context;
525 mActivityService = activity;
526 mBatteryStats = BatteryStatsService.getService();
527 mBatteryService = battery;
528
Mike Lockwood3cb67a32009-11-27 14:25:58 -0500529 mLcdLight = lights.getLight(LightsService.LIGHT_ID_BACKLIGHT);
530 mButtonLight = lights.getLight(LightsService.LIGHT_ID_BUTTONS);
531 mKeyboardLight = lights.getLight(LightsService.LIGHT_ID_KEYBOARD);
532 mAttentionLight = lights.getLight(LightsService.LIGHT_ID_ATTENTION);
533
Joe Onoratob08a1af2010-10-11 19:28:58 -0700534 nativeInit();
535 synchronized (mLocks) {
536 updateNativePowerStateLocked();
537 }
538
539 mInitComplete = false;
540 mScreenOffThread = new HandlerThread("PowerManagerService.mScreenOffThread") {
541 @Override
542 protected void onLooperPrepared() {
543 mScreenOffHandler = new Handler();
544 synchronized (mScreenOffThread) {
545 mInitComplete = true;
546 mScreenOffThread.notifyAll();
547 }
548 }
549 };
550 mScreenOffThread.start();
551
552 synchronized (mScreenOffThread) {
553 while (!mInitComplete) {
554 try {
555 mScreenOffThread.wait();
556 } catch (InterruptedException e) {
557 // Ignore
558 }
559 }
560 }
561
562 mInitComplete = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800563 mHandlerThread = new HandlerThread("PowerManagerService") {
564 @Override
565 protected void onLooperPrepared() {
566 super.onLooperPrepared();
567 initInThread();
568 }
569 };
570 mHandlerThread.start();
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800571
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800572 synchronized (mHandlerThread) {
573 while (!mInitComplete) {
574 try {
575 mHandlerThread.wait();
576 } catch (InterruptedException e) {
577 // Ignore
578 }
579 }
580 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700581
582 nativeInit();
583 synchronized (mLocks) {
584 updateNativePowerStateLocked();
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -0700585 // We make sure to start out with the screen on due to user activity.
586 // (They did just boot their device, after all.)
587 forceUserActivityLocked();
Dianne Hackborn40011092011-09-22 13:37:48 -0700588 mInitialized = true;
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700589 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800590 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800591
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800592 void initInThread() {
593 mHandler = new Handler();
594
595 mBroadcastWakeLock = new UnsynchronizedWakeLock(
Joe Onorato128e7292009-03-24 18:41:31 -0700596 PowerManager.PARTIAL_WAKE_LOCK, "sleep_broadcast", true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800597 mStayOnWhilePluggedInScreenDimLock = new UnsynchronizedWakeLock(
598 PowerManager.SCREEN_DIM_WAKE_LOCK, "StayOnWhilePluggedIn Screen Dim", false);
599 mStayOnWhilePluggedInPartialLock = new UnsynchronizedWakeLock(
600 PowerManager.PARTIAL_WAKE_LOCK, "StayOnWhilePluggedIn Partial", false);
601 mPreventScreenOnPartialLock = new UnsynchronizedWakeLock(
602 PowerManager.PARTIAL_WAKE_LOCK, "PreventScreenOn Partial", false);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -0500603 mProximityPartialLock = new UnsynchronizedWakeLock(
604 PowerManager.PARTIAL_WAKE_LOCK, "Proximity Partial", false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800605
606 mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
607 mScreenOnIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
608 mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF);
609 mScreenOffIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
610
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700611 Resources resources = mContext.getResources();
Mike Lockwoodaa66ea82009-10-31 16:31:27 -0400612
Joe Onoratob08a1af2010-10-11 19:28:58 -0700613 mAnimateScreenLights = resources.getBoolean(
614 com.android.internal.R.bool.config_animateScreenLights);
615
Joe Onorato6d747652010-10-11 15:15:31 -0700616 mUnplugTurnsOnScreen = resources.getBoolean(
617 com.android.internal.R.bool.config_unplugTurnsOnScreen);
618
Mike Lockwoodeb6456b2011-09-13 15:24:02 -0400619 mScreenBrightnessDim = resources.getInteger(
620 com.android.internal.R.integer.config_screenBrightnessDim);
621
Mike Lockwoodaa66ea82009-10-31 16:31:27 -0400622 // read settings for auto-brightness
623 mUseSoftwareAutoBrightness = resources.getBoolean(
624 com.android.internal.R.bool.config_automatic_brightness_available);
Mike Lockwoodaa66ea82009-10-31 16:31:27 -0400625 if (mUseSoftwareAutoBrightness) {
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700626 mAutoBrightnessLevels = resources.getIntArray(
627 com.android.internal.R.array.config_autoBrightnessLevels);
628 mLcdBacklightValues = resources.getIntArray(
629 com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
630 mButtonBacklightValues = resources.getIntArray(
631 com.android.internal.R.array.config_autoBrightnessButtonBacklightValues);
632 mKeyboardBacklightValues = resources.getIntArray(
633 com.android.internal.R.array.config_autoBrightnessKeyboardBacklightValues);
Mike Lockwood20ee6f22009-11-07 20:33:47 -0500634 mLightSensorWarmupTime = resources.getInteger(
635 com.android.internal.R.integer.config_lightSensorWarmupTime);
Mike Lockwoodd7786b42009-10-15 17:09:16 -0700636 }
Mike Lockwooddc3494e2009-10-14 21:17:09 -0700637
638 ContentResolver resolver = mContext.getContentResolver();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800639 Cursor settingsCursor = resolver.query(Settings.System.CONTENT_URI, null,
640 "(" + Settings.System.NAME + "=?) or ("
641 + Settings.System.NAME + "=?) or ("
Mike Lockwooddc3494e2009-10-14 21:17:09 -0700642 + Settings.System.NAME + "=?) or ("
Joe Onorato609695d2010-10-14 14:57:49 -0700643 + Settings.System.NAME + "=?) or ("
644 + Settings.System.NAME + "=?) or ("
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800645 + Settings.System.NAME + "=?) or ("
646 + Settings.System.NAME + "=?) or ("
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800647 + Settings.System.NAME + "=?)",
Dianne Hackbornd9ea4682012-01-20 18:36:40 -0800648 new String[]{STAY_ON_WHILE_PLUGGED_IN, SCREEN_OFF_TIMEOUT, DIM_SCREEN, SCREEN_BRIGHTNESS,
649 SCREEN_BRIGHTNESS_MODE, SCREEN_AUTO_BRIGHTNESS_ADJ,
650 WINDOW_ANIMATION_SCALE, TRANSITION_ANIMATION_SCALE},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800651 null);
652 mSettings = new ContentQueryMap(settingsCursor, Settings.System.NAME, true, mHandler);
653 SettingsObserver settingsObserver = new SettingsObserver();
654 mSettings.addObserver(settingsObserver);
655
656 // pretend that the settings changed so we will get their initial state
657 settingsObserver.update(mSettings, null);
658
659 // register for the battery changed notifications
660 IntentFilter filter = new IntentFilter();
661 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
662 mContext.registerReceiver(new BatteryReceiver(), filter);
Mike Lockwood2d7bb812009-11-15 18:12:22 -0500663 filter = new IntentFilter();
664 filter.addAction(Intent.ACTION_BOOT_COMPLETED);
665 mContext.registerReceiver(new BootCompletedReceiver(), filter);
Mike Lockwoodb2865412010-02-02 22:40:33 -0500666 filter = new IntentFilter();
667 filter.addAction(Intent.ACTION_DOCK_EVENT);
668 mContext.registerReceiver(new DockReceiver(), filter);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800669
Doug Zongker43866e02010-01-07 12:09:54 -0800670 // Listen for secure settings changes
671 mContext.getContentResolver().registerContentObserver(
672 Settings.Secure.CONTENT_URI, true,
673 new ContentObserver(new Handler()) {
674 public void onChange(boolean selfChange) {
675 updateSettingsValues();
676 }
677 });
678 updateSettingsValues();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800679
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800680 synchronized (mHandlerThread) {
681 mInitComplete = true;
682 mHandlerThread.notifyAll();
683 }
684 }
685
686 private class WakeLock implements IBinder.DeathRecipient
687 {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700688 WakeLock(int f, IBinder b, String t, int u, int p) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800689 super();
690 flags = f;
691 binder = b;
692 tag = t;
693 uid = u == MY_UID ? Process.SYSTEM_UID : u;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700694 pid = p;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800695 if (u != MY_UID || (
696 !"KEEP_SCREEN_ON_FLAG".equals(tag)
697 && !"KeyInputQueue".equals(tag))) {
698 monitorType = (f & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK
699 ? BatteryStats.WAKE_TYPE_PARTIAL
700 : BatteryStats.WAKE_TYPE_FULL;
701 } else {
702 monitorType = -1;
703 }
704 try {
705 b.linkToDeath(this, 0);
706 } catch (RemoteException e) {
707 binderDied();
708 }
709 }
710 public void binderDied() {
711 synchronized (mLocks) {
Mike Lockwood0e39ea82009-11-18 15:37:10 -0500712 releaseWakeLockLocked(this.binder, 0, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800713 }
714 }
715 final int flags;
716 final IBinder binder;
717 final String tag;
718 final int uid;
Mike Lockwoodf5bd0922010-03-22 17:10:15 -0400719 final int pid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800720 final int monitorType;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700721 WorkSource ws;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800722 boolean activated = true;
723 int minState;
724 }
725
726 private void updateWakeLockLocked() {
727 if (mStayOnConditions != 0 && mBatteryService.isPowered(mStayOnConditions)) {
728 // keep the device on if we're plugged in and mStayOnWhilePluggedIn is set.
729 mStayOnWhilePluggedInScreenDimLock.acquire();
730 mStayOnWhilePluggedInPartialLock.acquire();
731 } else {
732 mStayOnWhilePluggedInScreenDimLock.release();
733 mStayOnWhilePluggedInPartialLock.release();
734 }
735 }
736
737 private boolean isScreenLock(int flags)
738 {
739 int n = flags & LOCK_MASK;
740 return n == PowerManager.FULL_WAKE_LOCK
741 || n == PowerManager.SCREEN_BRIGHT_WAKE_LOCK
Joe Onorato8274a0e2010-10-05 17:38:09 -0400742 || n == PowerManager.SCREEN_DIM_WAKE_LOCK
743 || n == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800744 }
745
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700746 void enforceWakeSourcePermission(int uid, int pid) {
747 if (uid == Process.myUid()) {
748 return;
749 }
750 mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
751 pid, uid, null);
752 }
753
754 public void acquireWakeLock(int flags, IBinder lock, String tag, WorkSource ws) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800755 int uid = Binder.getCallingUid();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700756 int pid = Binder.getCallingPid();
Michael Chane96440f2009-05-06 10:27:36 -0700757 if (uid != Process.myUid()) {
758 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
759 }
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700760 if (ws != null) {
761 enforceWakeSourcePermission(uid, pid);
762 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800763 long ident = Binder.clearCallingIdentity();
764 try {
765 synchronized (mLocks) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700766 acquireWakeLockLocked(flags, lock, uid, pid, tag, ws);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800767 }
768 } finally {
769 Binder.restoreCallingIdentity(ident);
770 }
771 }
772
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700773 void noteStartWakeLocked(WakeLock wl, WorkSource ws) {
Dianne Hackborn70be1672010-09-14 11:13:03 -0700774 if (wl.monitorType >= 0) {
775 long origId = Binder.clearCallingIdentity();
776 try {
777 if (ws != null) {
778 mBatteryStats.noteStartWakelockFromSource(ws, wl.pid, wl.tag,
779 wl.monitorType);
780 } else {
781 mBatteryStats.noteStartWakelock(wl.uid, wl.pid, wl.tag, wl.monitorType);
782 }
783 } catch (RemoteException e) {
784 // Ignore
785 } finally {
786 Binder.restoreCallingIdentity(origId);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700787 }
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700788 }
789 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800790
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700791 void noteStopWakeLocked(WakeLock wl, WorkSource ws) {
Dianne Hackborn70be1672010-09-14 11:13:03 -0700792 if (wl.monitorType >= 0) {
793 long origId = Binder.clearCallingIdentity();
794 try {
795 if (ws != null) {
796 mBatteryStats.noteStopWakelockFromSource(ws, wl.pid, wl.tag,
797 wl.monitorType);
798 } else {
799 mBatteryStats.noteStopWakelock(wl.uid, wl.pid, wl.tag, wl.monitorType);
800 }
801 } catch (RemoteException e) {
802 // Ignore
803 } finally {
804 Binder.restoreCallingIdentity(origId);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700805 }
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700806 }
807 }
808
809 public void acquireWakeLockLocked(int flags, IBinder lock, int uid, int pid, String tag,
810 WorkSource ws) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800811 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800812 Slog.d(TAG, "acquireWakeLock flags=0x" + Integer.toHexString(flags) + " tag=" + tag);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800813 }
814
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700815 if (ws != null && ws.size() == 0) {
816 ws = null;
817 }
818
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800819 int index = mLocks.getIndex(lock);
820 WakeLock wl;
821 boolean newlock;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700822 boolean diffsource;
823 WorkSource oldsource;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800824 if (index < 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700825 wl = new WakeLock(flags, lock, tag, uid, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800826 switch (wl.flags & LOCK_MASK)
827 {
828 case PowerManager.FULL_WAKE_LOCK:
Mike Lockwood4984e732009-11-01 08:16:33 -0500829 if (mUseSoftwareAutoBrightness) {
Mike Lockwood3333fa42009-10-26 14:50:42 -0400830 wl.minState = SCREEN_BRIGHT;
831 } else {
832 wl.minState = (mKeyboardVisible ? ALL_BRIGHT : SCREEN_BUTTON_BRIGHT);
833 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800834 break;
835 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
836 wl.minState = SCREEN_BRIGHT;
837 break;
838 case PowerManager.SCREEN_DIM_WAKE_LOCK:
839 wl.minState = SCREEN_DIM;
840 break;
841 case PowerManager.PARTIAL_WAKE_LOCK:
Mike Lockwoodbc706a02009-07-27 13:50:57 -0700842 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800843 break;
844 default:
845 // just log and bail. we're in the server, so don't
846 // throw an exception.
Joe Onorato8a9b2202010-02-26 18:56:32 -0800847 Slog.e(TAG, "bad wakelock type for lock '" + tag + "' "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800848 + " flags=" + flags);
849 return;
850 }
851 mLocks.addLock(wl);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700852 if (ws != null) {
853 wl.ws = new WorkSource(ws);
854 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800855 newlock = true;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700856 diffsource = false;
857 oldsource = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800858 } else {
859 wl = mLocks.get(index);
860 newlock = false;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700861 oldsource = wl.ws;
862 if (oldsource != null) {
863 if (ws == null) {
864 wl.ws = null;
865 diffsource = true;
866 } else {
867 diffsource = oldsource.diff(ws);
868 }
869 } else if (ws != null) {
870 diffsource = true;
871 } else {
872 diffsource = false;
873 }
874 if (diffsource) {
875 wl.ws = new WorkSource(ws);
876 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800877 }
878 if (isScreenLock(flags)) {
879 // if this causes a wakeup, we reactivate all of the locks and
880 // set it to whatever they want. otherwise, we modulate that
881 // by the current state so we never turn it more on than
882 // it already is.
Joe Onorato8274a0e2010-10-05 17:38:09 -0400883 if ((flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) {
884 mProximityWakeLockCount++;
885 if (mProximityWakeLockCount == 1) {
886 enableProximityLockLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800887 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800888 } else {
Joe Onorato8274a0e2010-10-05 17:38:09 -0400889 if ((wl.flags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {
890 int oldWakeLockState = mWakeLockState;
891 mWakeLockState = mLocks.reactivateScreenLocksLocked();
Mike Lockwooddb97f602011-09-02 11:59:08 -0400892
893 // Disable proximity sensor if if user presses power key while we are in the
894 // "waiting for proximity sensor to go negative" state.
895 if ((mWakeLockState & SCREEN_ON_BIT) != 0
896 && mProximitySensorActive && mProximityWakeLockCount == 0) {
897 mProximitySensorActive = false;
898 }
899
Joe Onorato8274a0e2010-10-05 17:38:09 -0400900 if (mSpew) {
901 Slog.d(TAG, "wakeup here mUserState=0x" + Integer.toHexString(mUserState)
902 + " mWakeLockState=0x"
903 + Integer.toHexString(mWakeLockState)
904 + " previous wakeLockState=0x"
905 + Integer.toHexString(oldWakeLockState));
906 }
907 } else {
908 if (mSpew) {
909 Slog.d(TAG, "here mUserState=0x" + Integer.toHexString(mUserState)
910 + " mLocks.gatherState()=0x"
911 + Integer.toHexString(mLocks.gatherState())
912 + " mWakeLockState=0x" + Integer.toHexString(mWakeLockState));
913 }
914 mWakeLockState = (mUserState | mWakeLockState) & mLocks.gatherState();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800915 }
Joe Onorato8274a0e2010-10-05 17:38:09 -0400916 setPowerState(mWakeLockState | mUserState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800917 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800918 }
919 else if ((flags & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK) {
920 if (newlock) {
921 mPartialCount++;
922 if (mPartialCount == 1) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800923 if (LOG_PARTIAL_WL) EventLog.writeEvent(EventLogTags.POWER_PARTIAL_WAKE_STATE, 1, tag);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800924 }
925 }
926 Power.acquireWakeLock(Power.PARTIAL_WAKE_LOCK,PARTIAL_NAME);
927 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800928
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700929 if (diffsource) {
930 // If the lock sources have changed, need to first release the
931 // old ones.
932 noteStopWakeLocked(wl, oldsource);
933 }
934 if (newlock || diffsource) {
935 noteStartWakeLocked(wl, ws);
936 }
937 }
938
939 public void updateWakeLockWorkSource(IBinder lock, WorkSource ws) {
940 int uid = Binder.getCallingUid();
941 int pid = Binder.getCallingPid();
942 if (ws != null && ws.size() == 0) {
943 ws = null;
944 }
945 if (ws != null) {
946 enforceWakeSourcePermission(uid, pid);
947 }
Dianne Hackborn70be1672010-09-14 11:13:03 -0700948 synchronized (mLocks) {
949 int index = mLocks.getIndex(lock);
950 if (index < 0) {
951 throw new IllegalArgumentException("Wake lock not active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800952 }
Dianne Hackborn70be1672010-09-14 11:13:03 -0700953 WakeLock wl = mLocks.get(index);
954 WorkSource oldsource = wl.ws;
955 wl.ws = ws != null ? new WorkSource(ws) : null;
956 noteStopWakeLocked(wl, oldsource);
957 noteStartWakeLocked(wl, ws);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800958 }
959 }
960
Mike Lockwood0e39ea82009-11-18 15:37:10 -0500961 public void releaseWakeLock(IBinder lock, int flags) {
Michael Chane96440f2009-05-06 10:27:36 -0700962 int uid = Binder.getCallingUid();
963 if (uid != Process.myUid()) {
964 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
965 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800966
967 synchronized (mLocks) {
Mike Lockwood0e39ea82009-11-18 15:37:10 -0500968 releaseWakeLockLocked(lock, flags, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800969 }
970 }
971
Mike Lockwood0e39ea82009-11-18 15:37:10 -0500972 private void releaseWakeLockLocked(IBinder lock, int flags, boolean death) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800973 WakeLock wl = mLocks.removeLock(lock);
974 if (wl == null) {
975 return;
976 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800977
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800978 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800979 Slog.d(TAG, "releaseWakeLock flags=0x"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800980 + Integer.toHexString(wl.flags) + " tag=" + wl.tag);
981 }
982
983 if (isScreenLock(wl.flags)) {
Joe Onorato8274a0e2010-10-05 17:38:09 -0400984 if ((wl.flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) {
985 mProximityWakeLockCount--;
986 if (mProximityWakeLockCount == 0) {
987 if (mProximitySensorActive &&
988 ((flags & PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE) != 0)) {
989 // wait for proximity sensor to go negative before disabling sensor
990 if (mDebugProximitySensor) {
991 Slog.d(TAG, "waiting for proximity sensor to go negative");
992 }
993 } else {
994 disableProximityLockLocked();
995 }
996 }
997 } else {
998 mWakeLockState = mLocks.gatherState();
999 // goes in the middle to reduce flicker
1000 if ((wl.flags & PowerManager.ON_AFTER_RELEASE) != 0) {
1001 userActivity(SystemClock.uptimeMillis(), -1, false, OTHER_EVENT, false);
1002 }
1003 setPowerState(mWakeLockState | mUserState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001004 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001005 }
1006 else if ((wl.flags & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK) {
1007 mPartialCount--;
1008 if (mPartialCount == 0) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001009 if (LOG_PARTIAL_WL) EventLog.writeEvent(EventLogTags.POWER_PARTIAL_WAKE_STATE, 0, wl.tag);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001010 Power.releaseWakeLock(PARTIAL_NAME);
1011 }
1012 }
1013 // Unlink the lock from the binder.
1014 wl.binder.unlinkToDeath(wl, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001015
Dianne Hackborn70be1672010-09-14 11:13:03 -07001016 noteStopWakeLocked(wl, wl.ws);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001017 }
1018
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001019 private class PokeLock implements IBinder.DeathRecipient
1020 {
1021 PokeLock(int p, IBinder b, String t) {
1022 super();
1023 this.pokey = p;
1024 this.binder = b;
1025 this.tag = t;
1026 try {
1027 b.linkToDeath(this, 0);
1028 } catch (RemoteException e) {
1029 binderDied();
1030 }
1031 }
1032 public void binderDied() {
1033 setPokeLock(0, this.binder, this.tag);
1034 }
1035 int pokey;
1036 IBinder binder;
1037 String tag;
1038 boolean awakeOnSet;
1039 }
1040
1041 public void setPokeLock(int pokey, IBinder token, String tag) {
1042 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1043 if (token == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001044 Slog.e(TAG, "setPokeLock got null token for tag='" + tag + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001045 return;
1046 }
1047
1048 if ((pokey & POKE_LOCK_TIMEOUT_MASK) == POKE_LOCK_TIMEOUT_MASK) {
1049 throw new IllegalArgumentException("setPokeLock can't have both POKE_LOCK_SHORT_TIMEOUT"
1050 + " and POKE_LOCK_MEDIUM_TIMEOUT");
1051 }
1052
1053 synchronized (mLocks) {
1054 if (pokey != 0) {
1055 PokeLock p = mPokeLocks.get(token);
1056 int oldPokey = 0;
1057 if (p != null) {
1058 oldPokey = p.pokey;
1059 p.pokey = pokey;
1060 } else {
1061 p = new PokeLock(pokey, token, tag);
1062 mPokeLocks.put(token, p);
1063 }
1064 int oldTimeout = oldPokey & POKE_LOCK_TIMEOUT_MASK;
1065 int newTimeout = pokey & POKE_LOCK_TIMEOUT_MASK;
1066 if (((mPowerState & SCREEN_ON_BIT) == 0) && (oldTimeout != newTimeout)) {
1067 p.awakeOnSet = true;
1068 }
1069 } else {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07001070 PokeLock rLock = mPokeLocks.remove(token);
1071 if (rLock != null) {
1072 token.unlinkToDeath(rLock, 0);
1073 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001074 }
1075
1076 int oldPokey = mPokey;
1077 int cumulative = 0;
1078 boolean oldAwakeOnSet = mPokeAwakeOnSet;
1079 boolean awakeOnSet = false;
1080 for (PokeLock p: mPokeLocks.values()) {
1081 cumulative |= p.pokey;
1082 if (p.awakeOnSet) {
1083 awakeOnSet = true;
1084 }
1085 }
1086 mPokey = cumulative;
1087 mPokeAwakeOnSet = awakeOnSet;
1088
1089 int oldCumulativeTimeout = oldPokey & POKE_LOCK_TIMEOUT_MASK;
1090 int newCumulativeTimeout = pokey & POKE_LOCK_TIMEOUT_MASK;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001091
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001092 if (oldCumulativeTimeout != newCumulativeTimeout) {
1093 setScreenOffTimeoutsLocked();
1094 // reset the countdown timer, but use the existing nextState so it doesn't
1095 // change anything
1096 setTimeoutLocked(SystemClock.uptimeMillis(), mTimeoutTask.nextState);
1097 }
1098 }
1099 }
1100
1101 private static String lockType(int type)
1102 {
1103 switch (type)
1104 {
1105 case PowerManager.FULL_WAKE_LOCK:
David Brown251faa62009-08-02 22:04:36 -07001106 return "FULL_WAKE_LOCK ";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001107 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
David Brown251faa62009-08-02 22:04:36 -07001108 return "SCREEN_BRIGHT_WAKE_LOCK ";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001109 case PowerManager.SCREEN_DIM_WAKE_LOCK:
David Brown251faa62009-08-02 22:04:36 -07001110 return "SCREEN_DIM_WAKE_LOCK ";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001111 case PowerManager.PARTIAL_WAKE_LOCK:
David Brown251faa62009-08-02 22:04:36 -07001112 return "PARTIAL_WAKE_LOCK ";
1113 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
1114 return "PROXIMITY_SCREEN_OFF_WAKE_LOCK";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001115 default:
David Brown251faa62009-08-02 22:04:36 -07001116 return "??? ";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001117 }
1118 }
1119
1120 private static String dumpPowerState(int state) {
1121 return (((state & KEYBOARD_BRIGHT_BIT) != 0)
1122 ? "KEYBOARD_BRIGHT_BIT " : "")
1123 + (((state & SCREEN_BRIGHT_BIT) != 0)
1124 ? "SCREEN_BRIGHT_BIT " : "")
1125 + (((state & SCREEN_ON_BIT) != 0)
1126 ? "SCREEN_ON_BIT " : "")
1127 + (((state & BATTERY_LOW_BIT) != 0)
1128 ? "BATTERY_LOW_BIT " : "");
1129 }
1130
1131 @Override
1132 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1133 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
1134 != PackageManager.PERMISSION_GRANTED) {
1135 pw.println("Permission Denial: can't dump PowerManager from from pid="
1136 + Binder.getCallingPid()
1137 + ", uid=" + Binder.getCallingUid());
1138 return;
1139 }
1140
1141 long now = SystemClock.uptimeMillis();
1142
Mike Lockwoodca44df82010-02-25 13:48:49 -05001143 synchronized (mLocks) {
1144 pw.println("Power Manager State:");
1145 pw.println(" mIsPowered=" + mIsPowered
1146 + " mPowerState=" + mPowerState
1147 + " mScreenOffTime=" + (SystemClock.elapsedRealtime()-mScreenOffTime)
1148 + " ms");
1149 pw.println(" mPartialCount=" + mPartialCount);
1150 pw.println(" mWakeLockState=" + dumpPowerState(mWakeLockState));
1151 pw.println(" mUserState=" + dumpPowerState(mUserState));
1152 pw.println(" mPowerState=" + dumpPowerState(mPowerState));
1153 pw.println(" mLocks.gather=" + dumpPowerState(mLocks.gatherState()));
1154 pw.println(" mNextTimeout=" + mNextTimeout + " now=" + now
1155 + " " + ((mNextTimeout-now)/1000) + "s from now");
1156 pw.println(" mDimScreen=" + mDimScreen
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001157 + " mStayOnConditions=" + mStayOnConditions
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001158 + " mPreparingForScreenOn=" + mPreparingForScreenOn
1159 + " mSkippedScreenOn=" + mSkippedScreenOn);
Mike Lockwoodca44df82010-02-25 13:48:49 -05001160 pw.println(" mScreenOffReason=" + mScreenOffReason
1161 + " mUserState=" + mUserState);
1162 pw.println(" mBroadcastQueue={" + mBroadcastQueue[0] + ',' + mBroadcastQueue[1]
1163 + ',' + mBroadcastQueue[2] + "}");
1164 pw.println(" mBroadcastWhy={" + mBroadcastWhy[0] + ',' + mBroadcastWhy[1]
1165 + ',' + mBroadcastWhy[2] + "}");
1166 pw.println(" mPokey=" + mPokey + " mPokeAwakeonSet=" + mPokeAwakeOnSet);
1167 pw.println(" mKeyboardVisible=" + mKeyboardVisible
1168 + " mUserActivityAllowed=" + mUserActivityAllowed);
1169 pw.println(" mKeylightDelay=" + mKeylightDelay + " mDimDelay=" + mDimDelay
1170 + " mScreenOffDelay=" + mScreenOffDelay);
1171 pw.println(" mPreventScreenOn=" + mPreventScreenOn
1172 + " mScreenBrightnessOverride=" + mScreenBrightnessOverride
1173 + " mButtonBrightnessOverride=" + mButtonBrightnessOverride);
1174 pw.println(" mScreenOffTimeoutSetting=" + mScreenOffTimeoutSetting
1175 + " mMaximumScreenOffTimeout=" + mMaximumScreenOffTimeout);
1176 pw.println(" mLastScreenOnTime=" + mLastScreenOnTime);
1177 pw.println(" mBroadcastWakeLock=" + mBroadcastWakeLock);
1178 pw.println(" mStayOnWhilePluggedInScreenDimLock=" + mStayOnWhilePluggedInScreenDimLock);
1179 pw.println(" mStayOnWhilePluggedInPartialLock=" + mStayOnWhilePluggedInPartialLock);
1180 pw.println(" mPreventScreenOnPartialLock=" + mPreventScreenOnPartialLock);
1181 pw.println(" mProximityPartialLock=" + mProximityPartialLock);
1182 pw.println(" mProximityWakeLockCount=" + mProximityWakeLockCount);
1183 pw.println(" mProximitySensorEnabled=" + mProximitySensorEnabled);
1184 pw.println(" mProximitySensorActive=" + mProximitySensorActive);
1185 pw.println(" mProximityPendingValue=" + mProximityPendingValue);
1186 pw.println(" mLastProximityEventTime=" + mLastProximityEventTime);
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08001187 pw.println(" mLightSensorEnabled=" + mLightSensorEnabled
1188 + " mLightSensorAdjustSetting=" + mLightSensorAdjustSetting);
Mike Lockwoodca44df82010-02-25 13:48:49 -05001189 pw.println(" mLightSensorValue=" + mLightSensorValue
1190 + " mLightSensorPendingValue=" + mLightSensorPendingValue);
Jim Rodovichd102fea2010-09-02 12:30:49 -05001191 pw.println(" mLightSensorPendingDecrease=" + mLightSensorPendingDecrease
1192 + " mLightSensorPendingIncrease=" + mLightSensorPendingIncrease);
Mike Lockwoodca44df82010-02-25 13:48:49 -05001193 pw.println(" mLightSensorScreenBrightness=" + mLightSensorScreenBrightness
1194 + " mLightSensorButtonBrightness=" + mLightSensorButtonBrightness
1195 + " mLightSensorKeyboardBrightness=" + mLightSensorKeyboardBrightness);
1196 pw.println(" mUseSoftwareAutoBrightness=" + mUseSoftwareAutoBrightness);
1197 pw.println(" mAutoBrightessEnabled=" + mAutoBrightessEnabled);
1198 mScreenBrightness.dump(pw, " mScreenBrightness: ");
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001199
Mike Lockwoodca44df82010-02-25 13:48:49 -05001200 int N = mLocks.size();
1201 pw.println();
1202 pw.println("mLocks.size=" + N + ":");
1203 for (int i=0; i<N; i++) {
1204 WakeLock wl = mLocks.get(i);
1205 String type = lockType(wl.flags & LOCK_MASK);
1206 String acquireCausesWakeup = "";
1207 if ((wl.flags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {
1208 acquireCausesWakeup = "ACQUIRE_CAUSES_WAKEUP ";
1209 }
1210 String activated = "";
1211 if (wl.activated) {
1212 activated = " activated";
1213 }
1214 pw.println(" " + type + " '" + wl.tag + "'" + acquireCausesWakeup
Mike Lockwoodf5bd0922010-03-22 17:10:15 -04001215 + activated + " (minState=" + wl.minState + ", uid=" + wl.uid
1216 + ", pid=" + wl.pid + ")");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001217 }
Mike Lockwoodca44df82010-02-25 13:48:49 -05001218
1219 pw.println();
1220 pw.println("mPokeLocks.size=" + mPokeLocks.size() + ":");
1221 for (PokeLock p: mPokeLocks.values()) {
1222 pw.println(" poke lock '" + p.tag + "':"
Joe Onorato1a542c72010-11-08 09:48:20 -08001223 + ((p.pokey & POKE_LOCK_IGNORE_TOUCH_EVENTS) != 0
1224 ? " POKE_LOCK_IGNORE_TOUCH_EVENTS" : "")
Mike Lockwoodca44df82010-02-25 13:48:49 -05001225 + ((p.pokey & POKE_LOCK_SHORT_TIMEOUT) != 0
1226 ? " POKE_LOCK_SHORT_TIMEOUT" : "")
1227 + ((p.pokey & POKE_LOCK_MEDIUM_TIMEOUT) != 0
1228 ? " POKE_LOCK_MEDIUM_TIMEOUT" : ""));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001229 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001230
Mike Lockwoodca44df82010-02-25 13:48:49 -05001231 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001232 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001233 }
1234
Joe Onorato7999bff2010-07-24 11:50:05 -04001235 private void setTimeoutLocked(long now, int nextState) {
1236 setTimeoutLocked(now, -1, nextState);
1237 }
1238
1239 // If they gave a timeoutOverride it is the number of seconds
1240 // to screen-off. Figure out where in the countdown cycle we
1241 // should jump to.
Joe Onorato797e6882010-08-26 14:46:01 -04001242 private void setTimeoutLocked(long now, final long originalTimeoutOverride, int nextState) {
1243 long timeoutOverride = originalTimeoutOverride;
Mike Lockwood2d7bb812009-11-15 18:12:22 -05001244 if (mBootCompleted) {
Joe Onorato7999bff2010-07-24 11:50:05 -04001245 synchronized (mLocks) {
Joe Onorato7999bff2010-07-24 11:50:05 -04001246 long when = 0;
1247 if (timeoutOverride <= 0) {
1248 switch (nextState)
1249 {
1250 case SCREEN_BRIGHT:
1251 when = now + mKeylightDelay;
1252 break;
1253 case SCREEN_DIM:
1254 if (mDimDelay >= 0) {
1255 when = now + mDimDelay;
Andreas Huber84047bc2010-07-27 16:49:10 -07001256 break;
Joe Onorato7999bff2010-07-24 11:50:05 -04001257 } else {
1258 Slog.w(TAG, "mDimDelay=" + mDimDelay + " while trying to dim");
1259 }
1260 case SCREEN_OFF:
1261 synchronized (mLocks) {
1262 when = now + mScreenOffDelay;
1263 }
1264 break;
Andreas Huber84047bc2010-07-27 16:49:10 -07001265 default:
1266 when = now;
1267 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001268 }
Joe Onorato7999bff2010-07-24 11:50:05 -04001269 } else {
1270 override: {
1271 if (timeoutOverride <= mScreenOffDelay) {
1272 when = now + timeoutOverride;
1273 nextState = SCREEN_OFF;
1274 break override;
1275 }
1276 timeoutOverride -= mScreenOffDelay;
1277
1278 if (mDimDelay >= 0) {
1279 if (timeoutOverride <= mDimDelay) {
1280 when = now + timeoutOverride;
1281 nextState = SCREEN_DIM;
1282 break override;
1283 }
1284 timeoutOverride -= mDimDelay;
1285 }
1286
1287 when = now + timeoutOverride;
1288 nextState = SCREEN_BRIGHT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001289 }
Joe Onorato7999bff2010-07-24 11:50:05 -04001290 }
1291 if (mSpew) {
1292 Slog.d(TAG, "setTimeoutLocked now=" + now
1293 + " timeoutOverride=" + timeoutOverride
1294 + " nextState=" + nextState + " when=" + when);
1295 }
Joe Onorato797e6882010-08-26 14:46:01 -04001296
1297 mHandler.removeCallbacks(mTimeoutTask);
1298 mTimeoutTask.nextState = nextState;
1299 mTimeoutTask.remainingTimeoutOverride = timeoutOverride > 0
1300 ? (originalTimeoutOverride - timeoutOverride)
1301 : -1;
Joe Onorato7999bff2010-07-24 11:50:05 -04001302 mHandler.postAtTime(mTimeoutTask, when);
1303 mNextTimeout = when; // for debugging
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001304 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001305 }
1306 }
1307
1308 private void cancelTimerLocked()
1309 {
1310 mHandler.removeCallbacks(mTimeoutTask);
1311 mTimeoutTask.nextState = -1;
1312 }
1313
1314 private class TimeoutTask implements Runnable
1315 {
1316 int nextState; // access should be synchronized on mLocks
Joe Onorato797e6882010-08-26 14:46:01 -04001317 long remainingTimeoutOverride;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001318 public void run()
1319 {
1320 synchronized (mLocks) {
1321 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001322 Slog.d(TAG, "user activity timeout timed out nextState=" + this.nextState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001323 }
1324
1325 if (nextState == -1) {
1326 return;
1327 }
1328
1329 mUserState = this.nextState;
1330 setPowerState(this.nextState | mWakeLockState);
1331
1332 long now = SystemClock.uptimeMillis();
1333
1334 switch (this.nextState)
1335 {
1336 case SCREEN_BRIGHT:
1337 if (mDimDelay >= 0) {
Joe Onorato797e6882010-08-26 14:46:01 -04001338 setTimeoutLocked(now, remainingTimeoutOverride, SCREEN_DIM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001339 break;
1340 }
1341 case SCREEN_DIM:
Joe Onorato797e6882010-08-26 14:46:01 -04001342 setTimeoutLocked(now, remainingTimeoutOverride, SCREEN_OFF);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001343 break;
1344 }
1345 }
1346 }
1347 }
1348
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001349 private void sendNotificationLocked(boolean on, int why) {
1350 if (!mInitialized) {
1351 // No notifications sent until first initialization is done.
1352 // This is so that when we are moving from our initial state
1353 // which looks like the screen was off to it being on, we do not
1354 // go through the process of waiting for the higher-level user
1355 // space to be ready before turning up the display brightness.
1356 // (And also do not send needless broadcasts about the screen.)
1357 return;
1358 }
Dianne Hackborn40011092011-09-22 13:37:48 -07001359
1360 if (DEBUG_SCREEN_ON) {
1361 RuntimeException here = new RuntimeException("here");
1362 here.fillInStackTrace();
1363 Slog.i(TAG, "sendNotificationLocked: " + on, here);
1364 }
1365
Joe Onorato64c62ba2009-03-24 20:13:57 -07001366 if (!on) {
1367 mStillNeedSleepNotification = false;
1368 }
1369
Joe Onorato128e7292009-03-24 18:41:31 -07001370 // Add to the queue.
1371 int index = 0;
1372 while (mBroadcastQueue[index] != -1) {
1373 index++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001374 }
Joe Onorato128e7292009-03-24 18:41:31 -07001375 mBroadcastQueue[index] = on ? 1 : 0;
1376 mBroadcastWhy[index] = why;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001377
Joe Onorato128e7292009-03-24 18:41:31 -07001378 // If we added it position 2, then there is a pair that can be stripped.
1379 // If we added it position 1 and we're turning the screen off, we can strip
1380 // the pair and do nothing, because the screen is already off, and therefore
1381 // keyguard has already been enabled.
1382 // However, if we added it at position 1 and we're turning it on, then position
1383 // 0 was to turn it off, and we can't strip that, because keyguard needs to come
1384 // on, so have to run the queue then.
1385 if (index == 2) {
Dianne Hackborn254cb442010-01-27 19:23:59 -08001386 // While we're collapsing them, if it's going off, and the new reason
1387 // is more significant than the first, then use the new one.
1388 if (!on && mBroadcastWhy[0] > why) {
1389 mBroadcastWhy[0] = why;
Joe Onorato128e7292009-03-24 18:41:31 -07001390 }
1391 mBroadcastQueue[0] = on ? 1 : 0;
1392 mBroadcastQueue[1] = -1;
1393 mBroadcastQueue[2] = -1;
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001394 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount);
Mike Lockwood9c90a372010-04-13 15:40:27 -04001395 mBroadcastWakeLock.release();
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001396 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount);
Mike Lockwood9c90a372010-04-13 15:40:27 -04001397 mBroadcastWakeLock.release();
Joe Onorato128e7292009-03-24 18:41:31 -07001398 index = 0;
1399 }
1400 if (index == 1 && !on) {
1401 mBroadcastQueue[0] = -1;
1402 mBroadcastQueue[1] = -1;
1403 index = -1;
1404 // The wake lock was being held, but we're not actually going to do any
1405 // broadcasts, so release the wake lock.
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001406 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001407 mBroadcastWakeLock.release();
Joe Onorato128e7292009-03-24 18:41:31 -07001408 }
1409
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07001410 // The broadcast queue has changed; make sure the screen is on if it
1411 // is now possible for it to be.
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001412 if (mSkippedScreenOn) {
1413 updateLightsLocked(mPowerState, SCREEN_ON_BIT);
1414 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07001415
Joe Onorato128e7292009-03-24 18:41:31 -07001416 // Now send the message.
1417 if (index >= 0) {
1418 // Acquire the broadcast wake lock before changing the power
1419 // state. It will be release after the broadcast is sent.
1420 // We always increment the ref count for each notification in the queue
1421 // and always decrement when that notification is handled.
1422 mBroadcastWakeLock.acquire();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001423 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND, mBroadcastWakeLock.mCount);
Joe Onorato128e7292009-03-24 18:41:31 -07001424 mHandler.post(mNotificationTask);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001425 }
1426 }
1427
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001428 private WindowManagerPolicy.ScreenOnListener mScreenOnListener =
1429 new WindowManagerPolicy.ScreenOnListener() {
1430 @Override public void onScreenOn() {
1431 synchronized (mLocks) {
1432 if (mPreparingForScreenOn) {
1433 mPreparingForScreenOn = false;
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001434 updateLightsLocked(mPowerState, SCREEN_ON_BIT);
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001435 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP,
1436 4, mBroadcastWakeLock.mCount);
1437 mBroadcastWakeLock.release();
1438 }
1439 }
1440 }
1441 };
1442
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001443 private Runnable mNotificationTask = new Runnable()
1444 {
1445 public void run()
1446 {
Joe Onorato128e7292009-03-24 18:41:31 -07001447 while (true) {
1448 int value;
1449 int why;
1450 WindowManagerPolicy policy;
1451 synchronized (mLocks) {
1452 value = mBroadcastQueue[0];
1453 why = mBroadcastWhy[0];
1454 for (int i=0; i<2; i++) {
1455 mBroadcastQueue[i] = mBroadcastQueue[i+1];
1456 mBroadcastWhy[i] = mBroadcastWhy[i+1];
1457 }
1458 policy = getPolicyLocked();
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001459 if (value == 1 && !mPreparingForScreenOn) {
1460 mPreparingForScreenOn = true;
1461 mBroadcastWakeLock.acquire();
1462 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND,
1463 mBroadcastWakeLock.mCount);
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07001464 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001465 }
Joe Onorato128e7292009-03-24 18:41:31 -07001466 if (value == 1) {
1467 mScreenOnStart = SystemClock.uptimeMillis();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001468
Dianne Hackborn38e29a62011-09-18 14:43:08 -07001469 policy.screenTurningOn(mScreenOnListener);
Joe Onorato128e7292009-03-24 18:41:31 -07001470 try {
1471 ActivityManagerNative.getDefault().wakingUp();
1472 } catch (RemoteException e) {
1473 // ignore it
1474 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001475
Joe Onorato128e7292009-03-24 18:41:31 -07001476 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001477 Slog.d(TAG, "mBroadcastWakeLock=" + mBroadcastWakeLock);
Joe Onorato128e7292009-03-24 18:41:31 -07001478 }
1479 if (mContext != null && ActivityManagerNative.isSystemReady()) {
1480 mContext.sendOrderedBroadcast(mScreenOnIntent, null,
1481 mScreenOnBroadcastDone, mHandler, 0, null, null);
1482 } else {
1483 synchronized (mLocks) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001484 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 2,
Joe Onorato128e7292009-03-24 18:41:31 -07001485 mBroadcastWakeLock.mCount);
1486 mBroadcastWakeLock.release();
1487 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001488 }
1489 }
Joe Onorato128e7292009-03-24 18:41:31 -07001490 else if (value == 0) {
1491 mScreenOffStart = SystemClock.uptimeMillis();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001492
Joe Onorato128e7292009-03-24 18:41:31 -07001493 policy.screenTurnedOff(why);
1494 try {
1495 ActivityManagerNative.getDefault().goingToSleep();
1496 } catch (RemoteException e) {
1497 // ignore it.
1498 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001499
Joe Onorato128e7292009-03-24 18:41:31 -07001500 if (mContext != null && ActivityManagerNative.isSystemReady()) {
1501 mContext.sendOrderedBroadcast(mScreenOffIntent, null,
1502 mScreenOffBroadcastDone, mHandler, 0, null, null);
1503 } else {
1504 synchronized (mLocks) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001505 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 3,
Joe Onorato128e7292009-03-24 18:41:31 -07001506 mBroadcastWakeLock.mCount);
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001507 updateLightsLocked(mPowerState, SCREEN_ON_BIT);
Joe Onorato128e7292009-03-24 18:41:31 -07001508 mBroadcastWakeLock.release();
1509 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001510 }
1511 }
Joe Onorato128e7292009-03-24 18:41:31 -07001512 else {
1513 // If we're in this case, then this handler is running for a previous
1514 // paired transaction. mBroadcastWakeLock will already have been released.
1515 break;
1516 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001517 }
1518 }
1519 };
1520
1521 long mScreenOnStart;
1522 private BroadcastReceiver mScreenOnBroadcastDone = new BroadcastReceiver() {
1523 public void onReceive(Context context, Intent intent) {
1524 synchronized (mLocks) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001525 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001526 SystemClock.uptimeMillis() - mScreenOnStart, mBroadcastWakeLock.mCount);
1527 mBroadcastWakeLock.release();
1528 }
1529 }
1530 };
1531
1532 long mScreenOffStart;
1533 private BroadcastReceiver mScreenOffBroadcastDone = new BroadcastReceiver() {
1534 public void onReceive(Context context, Intent intent) {
1535 synchronized (mLocks) {
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001536 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 0,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001537 SystemClock.uptimeMillis() - mScreenOffStart, mBroadcastWakeLock.mCount);
1538 mBroadcastWakeLock.release();
1539 }
1540 }
1541 };
1542
1543 void logPointerUpEvent() {
1544 if (LOG_TOUCH_DOWNS) {
1545 mTotalTouchDownTime += SystemClock.elapsedRealtime() - mLastTouchDown;
1546 mLastTouchDown = 0;
1547 }
1548 }
1549
1550 void logPointerDownEvent() {
1551 if (LOG_TOUCH_DOWNS) {
1552 // If we are not already timing a down/up sequence
1553 if (mLastTouchDown == 0) {
1554 mLastTouchDown = SystemClock.elapsedRealtime();
1555 mTouchCycles++;
1556 }
1557 }
1558 }
1559
1560 /**
1561 * Prevents the screen from turning on even if it *should* turn on due
1562 * to a subsequent full wake lock being acquired.
1563 * <p>
1564 * This is a temporary hack that allows an activity to "cover up" any
1565 * display glitches that happen during the activity's startup
1566 * sequence. (Specifically, this API was added to work around a
1567 * cosmetic bug in the "incoming call" sequence, where the lock screen
1568 * would flicker briefly before the incoming call UI became visible.)
1569 * TODO: There ought to be a more elegant way of doing this,
1570 * probably by having the PowerManager and ActivityManager
1571 * work together to let apps specify that the screen on/off
1572 * state should be synchronized with the Activity lifecycle.
1573 * <p>
1574 * Note that calling preventScreenOn(true) will NOT turn the screen
1575 * off if it's currently on. (This API only affects *future*
1576 * acquisitions of full wake locks.)
1577 * But calling preventScreenOn(false) WILL turn the screen on if
1578 * it's currently off because of a prior preventScreenOn(true) call.
1579 * <p>
1580 * Any call to preventScreenOn(true) MUST be followed promptly by a call
1581 * to preventScreenOn(false). In fact, if the preventScreenOn(false)
1582 * call doesn't occur within 5 seconds, we'll turn the screen back on
1583 * ourselves (and log a warning about it); this prevents a buggy app
1584 * from disabling the screen forever.)
1585 * <p>
1586 * TODO: this feature should really be controlled by a new type of poke
1587 * lock (rather than an IPowerManager call).
1588 */
1589 public void preventScreenOn(boolean prevent) {
1590 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1591
1592 synchronized (mLocks) {
1593 if (prevent) {
1594 // First of all, grab a partial wake lock to
1595 // make sure the CPU stays on during the entire
1596 // preventScreenOn(true) -> preventScreenOn(false) sequence.
1597 mPreventScreenOnPartialLock.acquire();
1598
1599 // Post a forceReenableScreen() call (for 5 seconds in the
1600 // future) to make sure the matching preventScreenOn(false) call
1601 // has happened by then.
1602 mHandler.removeCallbacks(mForceReenableScreenTask);
1603 mHandler.postDelayed(mForceReenableScreenTask, 5000);
1604
1605 // Finally, set the flag that prevents the screen from turning on.
1606 // (Below, in setPowerState(), we'll check mPreventScreenOn and
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001607 // we *won't* call setScreenStateLocked(true) if it's set.)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001608 mPreventScreenOn = true;
1609 } else {
1610 // (Re)enable the screen.
1611 mPreventScreenOn = false;
1612
1613 // We're "undoing" a the prior preventScreenOn(true) call, so we
1614 // no longer need the 5-second safeguard.
1615 mHandler.removeCallbacks(mForceReenableScreenTask);
1616
1617 // Forcibly turn on the screen if it's supposed to be on. (This
1618 // handles the case where the screen is currently off because of
1619 // a prior preventScreenOn(true) call.)
Mike Lockwoode090281422009-11-14 21:02:56 -05001620 if (!mProximitySensorActive && (mPowerState & SCREEN_ON_BIT) != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001621 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001622 Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001623 "preventScreenOn: turning on after a prior preventScreenOn(true)!");
1624 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001625 int err = setScreenStateLocked(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001626 if (err != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001627 Slog.w(TAG, "preventScreenOn: error from setScreenStateLocked(): " + err);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001628 }
1629 }
1630
1631 // Release the partial wake lock that we held during the
1632 // preventScreenOn(true) -> preventScreenOn(false) sequence.
1633 mPreventScreenOnPartialLock.release();
1634 }
1635 }
1636 }
1637
1638 public void setScreenBrightnessOverride(int brightness) {
1639 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1640
Mike Lockwoodf527c712010-06-10 14:12:33 -04001641 if (mSpew) Slog.d(TAG, "setScreenBrightnessOverride " + brightness);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001642 synchronized (mLocks) {
1643 if (mScreenBrightnessOverride != brightness) {
1644 mScreenBrightnessOverride = brightness;
Mike Lockwoodf527c712010-06-10 14:12:33 -04001645 if (isScreenOn()) {
1646 updateLightsLocked(mPowerState, SCREEN_ON_BIT);
1647 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001648 }
1649 }
1650 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05001651
1652 public void setButtonBrightnessOverride(int brightness) {
1653 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
1654
Mike Lockwoodf527c712010-06-10 14:12:33 -04001655 if (mSpew) Slog.d(TAG, "setButtonBrightnessOverride " + brightness);
Mike Lockwoodfb73f792009-11-20 11:31:18 -05001656 synchronized (mLocks) {
1657 if (mButtonBrightnessOverride != brightness) {
1658 mButtonBrightnessOverride = brightness;
Mike Lockwoodf527c712010-06-10 14:12:33 -04001659 if (isScreenOn()) {
1660 updateLightsLocked(mPowerState, BUTTON_BRIGHT_BIT | KEYBOARD_BRIGHT_BIT);
1661 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05001662 }
1663 }
1664 }
1665
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001666 /**
1667 * Sanity-check that gets called 5 seconds after any call to
1668 * preventScreenOn(true). This ensures that the original call
1669 * is followed promptly by a call to preventScreenOn(false).
1670 */
1671 private void forceReenableScreen() {
1672 // We shouldn't get here at all if mPreventScreenOn is false, since
1673 // we should have already removed any existing
1674 // mForceReenableScreenTask messages...
1675 if (!mPreventScreenOn) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001676 Slog.w(TAG, "forceReenableScreen: mPreventScreenOn is false, nothing to do");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001677 return;
1678 }
1679
1680 // Uh oh. It's been 5 seconds since a call to
1681 // preventScreenOn(true) and we haven't re-enabled the screen yet.
1682 // This means the app that called preventScreenOn(true) is either
1683 // slow (i.e. it took more than 5 seconds to call preventScreenOn(false)),
1684 // or buggy (i.e. it forgot to call preventScreenOn(false), or
1685 // crashed before doing so.)
1686
1687 // Log a warning, and forcibly turn the screen back on.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001688 Slog.w(TAG, "App called preventScreenOn(true) but didn't promptly reenable the screen! "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001689 + "Forcing the screen back on...");
1690 preventScreenOn(false);
1691 }
1692
1693 private Runnable mForceReenableScreenTask = new Runnable() {
1694 public void run() {
1695 forceReenableScreen();
1696 }
1697 };
1698
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001699 private int setScreenStateLocked(boolean on) {
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001700 if (DEBUG_SCREEN_ON) {
1701 RuntimeException e = new RuntimeException("here");
1702 e.fillInStackTrace();
1703 Slog.i(TAG, "Set screen state: " + on, e);
1704 }
Dianne Hackborn474fd742011-10-10 18:40:22 -07001705 if (on) {
1706 if ((mPowerState & SCREEN_ON_BIT) == 0 || mSkippedScreenOn) {
1707 // If we are turning the screen state on, but the screen
1708 // light is currently off, then make sure that we set the
1709 // light at this point to 0. This is the case where we are
1710 // turning on the screen and waiting for the UI to be drawn
1711 // before showing it to the user. We want the light off
1712 // until it is ready to be shown to the user, not it using
1713 // whatever the last value it had.
Dianne Hackborn81de8b92011-11-28 16:54:31 -08001714 if (DEBUG_SCREEN_ON) {
1715 Slog.i(TAG, "Forcing brightness 0: mPowerState=0x"
1716 + Integer.toHexString(mPowerState)
1717 + " mSkippedScreenOn=" + mSkippedScreenOn);
1718 }
Dianne Hackborn474fd742011-10-10 18:40:22 -07001719 mScreenBrightness.forceValueLocked(Power.BRIGHTNESS_OFF);
1720 }
1721 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001722 int err = Power.setScreenState(on);
Mike Lockwood20ee6f22009-11-07 20:33:47 -05001723 if (err == 0) {
1724 mLastScreenOnTime = (on ? SystemClock.elapsedRealtime() : 0);
1725 if (mUseSoftwareAutoBrightness) {
Joe Onoratod28f7532010-11-06 12:56:53 -07001726 enableLightSensorLocked(on);
Mike Lockwood20ee6f22009-11-07 20:33:47 -05001727 if (!on) {
1728 // make sure button and key backlights are off too
Mike Lockwood3cb67a32009-11-27 14:25:58 -05001729 mButtonLight.turnOff();
1730 mKeyboardLight.turnOff();
Mike Lockwood20ee6f22009-11-07 20:33:47 -05001731 }
Mike Lockwoodd7786b42009-10-15 17:09:16 -07001732 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001733 }
1734 return err;
1735 }
1736
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001737 private void setPowerState(int state)
1738 {
Mike Lockwood435eb642009-12-03 08:40:18 -05001739 setPowerState(state, false, WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001740 }
1741
Mike Lockwood435eb642009-12-03 08:40:18 -05001742 private void setPowerState(int newState, boolean noChangeLights, int reason)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001743 {
1744 synchronized (mLocks) {
1745 int err;
1746
1747 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001748 Slog.d(TAG, "setPowerState: mPowerState=0x" + Integer.toHexString(mPowerState)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001749 + " newState=0x" + Integer.toHexString(newState)
Mike Lockwood435eb642009-12-03 08:40:18 -05001750 + " noChangeLights=" + noChangeLights
1751 + " reason=" + reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001752 }
1753
1754 if (noChangeLights) {
1755 newState = (newState & ~LIGHTS_MASK) | (mPowerState & LIGHTS_MASK);
1756 }
Mike Lockwood36fc3022009-08-25 16:49:06 -07001757 if (mProximitySensorActive) {
1758 // don't turn on the screen when the proximity sensor lock is held
1759 newState = (newState & ~SCREEN_BRIGHT);
1760 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001761
1762 if (batteryIsLow()) {
1763 newState |= BATTERY_LOW_BIT;
1764 } else {
1765 newState &= ~BATTERY_LOW_BIT;
1766 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001767 if (newState == mPowerState && mInitialized) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001768 return;
1769 }
Mike Lockwood3333fa42009-10-26 14:50:42 -04001770
Mike Lockwood2d7bb812009-11-15 18:12:22 -05001771 if (!mBootCompleted && !mUseSoftwareAutoBrightness) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001772 newState |= ALL_BRIGHT;
1773 }
1774
1775 boolean oldScreenOn = (mPowerState & SCREEN_ON_BIT) != 0;
1776 boolean newScreenOn = (newState & SCREEN_ON_BIT) != 0;
1777
Mike Lockwood51b844962009-11-16 21:51:18 -05001778 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001779 Slog.d(TAG, "setPowerState: mPowerState=" + mPowerState
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001780 + " newState=" + newState + " noChangeLights=" + noChangeLights);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001781 Slog.d(TAG, " oldKeyboardBright=" + ((mPowerState & KEYBOARD_BRIGHT_BIT) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001782 + " newKeyboardBright=" + ((newState & KEYBOARD_BRIGHT_BIT) != 0));
Joe Onorato8a9b2202010-02-26 18:56:32 -08001783 Slog.d(TAG, " oldScreenBright=" + ((mPowerState & SCREEN_BRIGHT_BIT) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001784 + " newScreenBright=" + ((newState & SCREEN_BRIGHT_BIT) != 0));
Joe Onorato8a9b2202010-02-26 18:56:32 -08001785 Slog.d(TAG, " oldButtonBright=" + ((mPowerState & BUTTON_BRIGHT_BIT) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001786 + " newButtonBright=" + ((newState & BUTTON_BRIGHT_BIT) != 0));
Joe Onorato8a9b2202010-02-26 18:56:32 -08001787 Slog.d(TAG, " oldScreenOn=" + oldScreenOn
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001788 + " newScreenOn=" + newScreenOn);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001789 Slog.d(TAG, " oldBatteryLow=" + ((mPowerState & BATTERY_LOW_BIT) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001790 + " newBatteryLow=" + ((newState & BATTERY_LOW_BIT) != 0));
1791 }
1792
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001793 final boolean stateChanged = mPowerState != newState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001794
1795 if (oldScreenOn != newScreenOn) {
1796 if (newScreenOn) {
Joe Onorato128e7292009-03-24 18:41:31 -07001797 // When the user presses the power button, we need to always send out the
1798 // notification that it's going to sleep so the keyguard goes on. But
1799 // we can't do that until the screen fades out, so we don't show the keyguard
1800 // too early.
1801 if (mStillNeedSleepNotification) {
1802 sendNotificationLocked(false, WindowManagerPolicy.OFF_BECAUSE_OF_USER);
1803 }
1804
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001805 // Turn on the screen UNLESS there was a prior
1806 // preventScreenOn(true) request. (Note that the lifetime
1807 // of a single preventScreenOn() request is limited to 5
1808 // seconds to prevent a buggy app from disabling the
1809 // screen forever; see forceReenableScreen().)
1810 boolean reallyTurnScreenOn = true;
1811 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001812 Slog.d(TAG, "- turning screen on... mPreventScreenOn = "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001813 + mPreventScreenOn);
1814 }
1815
1816 if (mPreventScreenOn) {
1817 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001818 Slog.d(TAG, "- PREVENTING screen from really turning on!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001819 }
1820 reallyTurnScreenOn = false;
1821 }
1822 if (reallyTurnScreenOn) {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001823 err = setScreenStateLocked(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001824 long identity = Binder.clearCallingIdentity();
1825 try {
Mike Lockwoodfb73f792009-11-20 11:31:18 -05001826 mBatteryStats.noteScreenBrightness(getPreferredBrightness());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001827 mBatteryStats.noteScreenOn();
1828 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001829 Slog.w(TAG, "RemoteException calling noteScreenOn on BatteryStatsService", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001830 } finally {
1831 Binder.restoreCallingIdentity(identity);
1832 }
1833 } else {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001834 setScreenStateLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001835 // But continue as if we really did turn the screen on...
1836 err = 0;
1837 }
1838
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001839 mLastTouchDown = 0;
1840 mTotalTouchDownTime = 0;
1841 mTouchCycles = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001842 EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, reason,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001843 mTotalTouchDownTime, mTouchCycles);
1844 if (err == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001845 sendNotificationLocked(true, -1);
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001846 // Update the lights *after* taking care of turning the
1847 // screen on, so we do this after our notifications are
1848 // enqueued and thus will delay turning on the screen light
1849 // until the windows are correctly displayed.
1850 if (stateChanged) {
1851 updateLightsLocked(newState, 0);
1852 }
1853 mPowerState |= SCREEN_ON_BIT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001854 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001855
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001856 } else {
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001857 // Update the lights *before* taking care of turning the
1858 // screen off, so we can initiate any animations that are desired.
1859 if (stateChanged) {
1860 updateLightsLocked(newState, 0);
1861 }
1862
Mike Lockwood497087e32009-11-08 18:33:03 -05001863 // cancel light sensor task
1864 mHandler.removeCallbacks(mAutoBrightnessTask);
Jim Rodovichd102fea2010-09-02 12:30:49 -05001865 mLightSensorPendingDecrease = false;
1866 mLightSensorPendingIncrease = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001867 mScreenOffTime = SystemClock.elapsedRealtime();
1868 long identity = Binder.clearCallingIdentity();
1869 try {
1870 mBatteryStats.noteScreenOff();
1871 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001872 Slog.w(TAG, "RemoteException calling noteScreenOff on BatteryStatsService", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001873 } finally {
1874 Binder.restoreCallingIdentity(identity);
1875 }
1876 mPowerState &= ~SCREEN_ON_BIT;
Mike Lockwood435eb642009-12-03 08:40:18 -05001877 mScreenOffReason = reason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001878 if (!mScreenBrightness.animating) {
Mike Lockwood435eb642009-12-03 08:40:18 -05001879 err = screenOffFinishedAnimatingLocked(reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001880 } else {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001881 err = 0;
1882 mLastTouchDown = 0;
1883 }
1884 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001885 } else if (stateChanged) {
1886 // Screen on/off didn't change, but lights may have.
1887 updateLightsLocked(newState, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001888 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001889
1890 mPowerState = (mPowerState & ~LIGHTS_MASK) | (newState & LIGHTS_MASK);
1891
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001892 updateNativePowerStateLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001893 }
1894 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001895
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001896 private void updateNativePowerStateLocked() {
1897 nativeSetPowerState(
1898 (mPowerState & SCREEN_ON_BIT) != 0,
1899 (mPowerState & SCREEN_BRIGHT) == SCREEN_BRIGHT);
1900 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001901
Mike Lockwood435eb642009-12-03 08:40:18 -05001902 private int screenOffFinishedAnimatingLocked(int reason) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001903 // I don't think we need to check the current state here because all of these
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001904 // Power.setScreenState and sendNotificationLocked can both handle being
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001905 // called multiple times in the same state. -joeo
Joe Onoratob08a1af2010-10-11 19:28:58 -07001906 EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, reason, mTotalTouchDownTime,
1907 mTouchCycles);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001908 mLastTouchDown = 0;
Mike Lockwood8738e0c2009-10-04 08:44:47 -04001909 int err = setScreenStateLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001910 if (err == 0) {
Mike Lockwood435eb642009-12-03 08:40:18 -05001911 mScreenOffReason = reason;
1912 sendNotificationLocked(false, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001913 }
1914 return err;
1915 }
1916
1917 private boolean batteryIsLow() {
1918 return (!mIsPowered &&
1919 mBatteryService.getBatteryLevel() <= Power.LOW_BATTERY_THRESHOLD);
1920 }
1921
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001922 private boolean shouldDeferScreenOnLocked() {
1923 if (mPreparingForScreenOn) {
1924 // Currently waiting for confirmation from the policy that it
1925 // is okay to turn on the screen. Don't allow the screen to go
1926 // on until that is done.
1927 if (DEBUG_SCREEN_ON) Slog.i(TAG,
1928 "updateLights: delaying screen on due to mPreparingForScreenOn");
1929 return true;
1930 } else {
1931 // If there is a screen-on command in the notification queue, we
1932 // can't turn the screen on until it has been processed (and we
1933 // have set mPreparingForScreenOn) or it has been dropped.
1934 for (int i=0; i<mBroadcastQueue.length; i++) {
1935 if (mBroadcastQueue[i] == 1) {
1936 if (DEBUG_SCREEN_ON) Slog.i(TAG,
1937 "updateLights: delaying screen on due to notification queue");
1938 return true;
1939 }
1940 }
1941 }
1942 return false;
1943 }
1944
The Android Open Source Project10592532009-03-18 17:39:46 -07001945 private void updateLightsLocked(int newState, int forceState) {
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07001946 final int oldState = mPowerState;
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07001947
1948 // If the screen is not currently on, we will want to delay actually
1949 // turning the lights on if we are still getting the UI put up.
1950 if ((oldState&SCREEN_ON_BIT) == 0 || mSkippedScreenOn) {
1951 // Don't turn screen on until we know we are really ready to.
1952 // This is to avoid letting the screen go on before things like the
1953 // lock screen have been displayed.
1954 if ((mSkippedScreenOn=shouldDeferScreenOnLocked())) {
1955 newState &= ~(SCREEN_ON_BIT|SCREEN_BRIGHT_BIT);
1956 }
1957 }
1958
Joe Onorato60607a902010-10-23 14:49:30 -07001959 if ((newState & SCREEN_ON_BIT) != 0) {
1960 // Only turn on the buttons or keyboard if the screen is also on.
1961 // We should never see the buttons on but not the screen.
1962 newState = applyButtonState(newState);
1963 newState = applyKeyboardState(newState);
1964 }
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07001965 final int realDifference = (newState ^ oldState);
1966 final int difference = realDifference | forceState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001967 if (difference == 0) {
The Android Open Source Project10592532009-03-18 17:39:46 -07001968 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001969 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001970
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001971 int offMask = 0;
1972 int dimMask = 0;
1973 int onMask = 0;
1974
1975 int preferredBrightness = getPreferredBrightness();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001976
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001977 if ((difference & KEYBOARD_BRIGHT_BIT) != 0) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07001978 if ((newState & KEYBOARD_BRIGHT_BIT) == 0) {
1979 offMask |= KEYBOARD_BRIGHT_BIT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001980 } else {
Joe Onoratob08a1af2010-10-11 19:28:58 -07001981 onMask |= KEYBOARD_BRIGHT_BIT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001982 }
1983 }
1984
1985 if ((difference & BUTTON_BRIGHT_BIT) != 0) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07001986 if ((newState & BUTTON_BRIGHT_BIT) == 0) {
1987 offMask |= BUTTON_BRIGHT_BIT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001988 } else {
Joe Onoratob08a1af2010-10-11 19:28:58 -07001989 onMask |= BUTTON_BRIGHT_BIT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001990 }
1991 }
1992
1993 if ((difference & (SCREEN_ON_BIT | SCREEN_BRIGHT_BIT)) != 0) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07001994 int nominalCurrentValue = -1;
1995 // If there was an actual difference in the light state, then
1996 // figure out the "ideal" current value based on the previous
1997 // state. Otherwise, this is a change due to the brightness
1998 // override, so we want to animate from whatever the current
1999 // value is.
2000 if ((realDifference & (SCREEN_ON_BIT | SCREEN_BRIGHT_BIT)) != 0) {
2001 switch (oldState & (SCREEN_BRIGHT_BIT|SCREEN_ON_BIT)) {
2002 case SCREEN_BRIGHT_BIT | SCREEN_ON_BIT:
2003 nominalCurrentValue = preferredBrightness;
2004 break;
2005 case SCREEN_ON_BIT:
Mike Lockwoodeb6456b2011-09-13 15:24:02 -04002006 nominalCurrentValue = mScreenBrightnessDim;
Joe Onoratob08a1af2010-10-11 19:28:58 -07002007 break;
2008 case 0:
2009 nominalCurrentValue = Power.BRIGHTNESS_OFF;
2010 break;
2011 case SCREEN_BRIGHT_BIT:
2012 default:
2013 // not possible
2014 nominalCurrentValue = (int)mScreenBrightness.curValue;
2015 break;
Joe Onorato128e7292009-03-24 18:41:31 -07002016 }
Joe Onoratob08a1af2010-10-11 19:28:58 -07002017 }
2018 int brightness = preferredBrightness;
2019 int steps = ANIM_STEPS;
2020 if ((newState & SCREEN_BRIGHT_BIT) == 0) {
2021 // dim or turn off backlight, depending on if the screen is on
2022 // the scale is because the brightness ramp isn't linear and this biases
2023 // it so the later parts take longer.
2024 final float scale = 1.5f;
Mike Lockwoodeb6456b2011-09-13 15:24:02 -04002025 float ratio = (((float)mScreenBrightnessDim)/preferredBrightness);
Joe Onoratob08a1af2010-10-11 19:28:58 -07002026 if (ratio > 1.0f) ratio = 1.0f;
2027 if ((newState & SCREEN_ON_BIT) == 0) {
2028 if ((oldState & SCREEN_BRIGHT_BIT) != 0) {
2029 // was bright
2030 steps = ANIM_STEPS;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002031 } else {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002032 // was dim
2033 steps = (int)(ANIM_STEPS*ratio*scale);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002034 }
Joe Onoratob08a1af2010-10-11 19:28:58 -07002035 brightness = Power.BRIGHTNESS_OFF;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002036 } else {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002037 if ((oldState & SCREEN_ON_BIT) != 0) {
2038 // was bright
2039 steps = (int)(ANIM_STEPS*(1.0f-ratio)*scale);
2040 } else {
2041 // was dim
2042 steps = (int)(ANIM_STEPS*ratio);
2043 }
2044 if (mStayOnConditions != 0 && mBatteryService.isPowered(mStayOnConditions)) {
2045 // If the "stay on while plugged in" option is
2046 // turned on, then the screen will often not
2047 // automatically turn off while plugged in. To
2048 // still have a sense of when it is inactive, we
2049 // will then count going dim as turning off.
2050 mScreenOffTime = SystemClock.elapsedRealtime();
2051 }
Mike Lockwoodeb6456b2011-09-13 15:24:02 -04002052 brightness = mScreenBrightnessDim;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002053 }
2054 }
Joe Onoratob08a1af2010-10-11 19:28:58 -07002055 long identity = Binder.clearCallingIdentity();
2056 try {
2057 mBatteryStats.noteScreenBrightness(brightness);
2058 } catch (RemoteException e) {
2059 // Nothing interesting to do.
2060 } finally {
2061 Binder.restoreCallingIdentity(identity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002062 }
Dianne Hackborn81de8b92011-11-28 16:54:31 -08002063 if (!mSkippedScreenOn) {
2064 mScreenBrightness.setTargetLocked(brightness, steps,
2065 INITIAL_SCREEN_BRIGHTNESS, nominalCurrentValue);
2066 if (DEBUG_SCREEN_ON) {
2067 RuntimeException e = new RuntimeException("here");
2068 e.fillInStackTrace();
2069 Slog.i(TAG, "Setting screen brightness: " + brightness, e);
2070 }
Dianne Hackbornbeae3bd2011-09-21 10:55:12 -07002071 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002072 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002073
Joe Onorato60607a902010-10-23 14:49:30 -07002074 if (mSpew) {
2075 Slog.d(TAG, "offMask=0x" + Integer.toHexString(offMask)
2076 + " dimMask=0x" + Integer.toHexString(dimMask)
2077 + " onMask=0x" + Integer.toHexString(onMask)
2078 + " difference=0x" + Integer.toHexString(difference)
2079 + " realDifference=0x" + Integer.toHexString(realDifference)
2080 + " forceState=0x" + Integer.toHexString(forceState)
2081 );
2082 }
2083
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002084 if (offMask != 0) {
Mike Lockwood48358bd2010-04-17 22:29:20 -04002085 if (mSpew) Slog.i(TAG, "Setting brightess off: " + offMask);
The Android Open Source Project10592532009-03-18 17:39:46 -07002086 setLightBrightness(offMask, Power.BRIGHTNESS_OFF);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002087 }
2088 if (dimMask != 0) {
Mike Lockwoodeb6456b2011-09-13 15:24:02 -04002089 int brightness = mScreenBrightnessDim;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002090 if ((newState & BATTERY_LOW_BIT) != 0 &&
2091 brightness > Power.BRIGHTNESS_LOW_BATTERY) {
2092 brightness = Power.BRIGHTNESS_LOW_BATTERY;
2093 }
Mike Lockwood48358bd2010-04-17 22:29:20 -04002094 if (mSpew) Slog.i(TAG, "Setting brightess dim " + brightness + ": " + dimMask);
The Android Open Source Project10592532009-03-18 17:39:46 -07002095 setLightBrightness(dimMask, brightness);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002096 }
2097 if (onMask != 0) {
2098 int brightness = getPreferredBrightness();
2099 if ((newState & BATTERY_LOW_BIT) != 0 &&
2100 brightness > Power.BRIGHTNESS_LOW_BATTERY) {
2101 brightness = Power.BRIGHTNESS_LOW_BATTERY;
2102 }
Mike Lockwood48358bd2010-04-17 22:29:20 -04002103 if (mSpew) Slog.i(TAG, "Setting brightess on " + brightness + ": " + onMask);
The Android Open Source Project10592532009-03-18 17:39:46 -07002104 setLightBrightness(onMask, brightness);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002105 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002106 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002107
The Android Open Source Project10592532009-03-18 17:39:46 -07002108 private void setLightBrightness(int mask, int value) {
Mike Lockwoodcc9a63d2009-11-10 07:50:28 -05002109 int brightnessMode = (mAutoBrightessEnabled
Mike Lockwood3a322132009-11-24 00:30:52 -05002110 ? LightsService.BRIGHTNESS_MODE_SENSOR
2111 : LightsService.BRIGHTNESS_MODE_USER);
The Android Open Source Project10592532009-03-18 17:39:46 -07002112 if ((mask & SCREEN_BRIGHT_BIT) != 0) {
Dianne Hackborn81de8b92011-11-28 16:54:31 -08002113 if (DEBUG_SCREEN_ON) {
2114 RuntimeException e = new RuntimeException("here");
2115 e.fillInStackTrace();
2116 Slog.i(TAG, "Set LCD brightness: " + value, e);
2117 }
Mike Lockwood3cb67a32009-11-27 14:25:58 -05002118 mLcdLight.setBrightness(value, brightnessMode);
The Android Open Source Project10592532009-03-18 17:39:46 -07002119 }
2120 if ((mask & BUTTON_BRIGHT_BIT) != 0) {
Mike Lockwood3cb67a32009-11-27 14:25:58 -05002121 mButtonLight.setBrightness(value);
The Android Open Source Project10592532009-03-18 17:39:46 -07002122 }
2123 if ((mask & KEYBOARD_BRIGHT_BIT) != 0) {
Mike Lockwood3cb67a32009-11-27 14:25:58 -05002124 mKeyboardLight.setBrightness(value);
The Android Open Source Project10592532009-03-18 17:39:46 -07002125 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002126 }
2127
Joe Onoratob08a1af2010-10-11 19:28:58 -07002128 class BrightnessState implements Runnable {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002129 final int mask;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002130
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002131 boolean initialized;
2132 int targetValue;
2133 float curValue;
2134 float delta;
2135 boolean animating;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002136
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002137 BrightnessState(int m) {
2138 mask = m;
2139 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002140
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002141 public void dump(PrintWriter pw, String prefix) {
2142 pw.println(prefix + "animating=" + animating
2143 + " targetValue=" + targetValue
2144 + " curValue=" + curValue
2145 + " delta=" + delta);
2146 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002147
Dianne Hackborn474fd742011-10-10 18:40:22 -07002148 void forceValueLocked(int value) {
2149 targetValue = -1;
2150 curValue = value;
2151 setLightBrightness(mask, value);
2152 if (animating) {
2153 finishAnimationLocked(false, value);
2154 }
2155 }
2156
Joe Onoratob08a1af2010-10-11 19:28:58 -07002157 void setTargetLocked(int target, int stepsToTarget, int initialValue,
Joe Onorato128e7292009-03-24 18:41:31 -07002158 int nominalCurrentValue) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002159 if (!initialized) {
2160 initialized = true;
2161 curValue = (float)initialValue;
Dianne Hackbornaa80b602009-10-09 17:38:26 -07002162 } else if (targetValue == target) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002163 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002164 }
2165 targetValue = target;
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07002166 delta = (targetValue -
2167 (nominalCurrentValue >= 0 ? nominalCurrentValue : curValue))
2168 / stepsToTarget;
Dianne Hackborn81de8b92011-11-28 16:54:31 -08002169 if (mSpew || DEBUG_SCREEN_ON) {
Joe Onorato128e7292009-03-24 18:41:31 -07002170 String noticeMe = nominalCurrentValue == curValue ? "" : " ******************";
Joe Onorato3d3db602010-10-18 16:08:16 -04002171 Slog.i(TAG, "setTargetLocked mask=" + mask + " curValue=" + curValue
2172 + " target=" + target + " targetValue=" + targetValue + " delta=" + delta
Joe Onorato128e7292009-03-24 18:41:31 -07002173 + " nominalCurrentValue=" + nominalCurrentValue
2174 + noticeMe);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002175 }
2176 animating = true;
Joe Onoratob08a1af2010-10-11 19:28:58 -07002177
2178 if (mSpew) {
2179 Slog.i(TAG, "scheduling light animator");
2180 }
2181 mScreenOffHandler.removeCallbacks(this);
2182 mScreenOffHandler.post(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002183 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002184
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002185 boolean stepLocked() {
2186 if (!animating) return false;
2187 if (false && mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002188 Slog.i(TAG, "Step target " + mask + ": cur=" + curValue
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002189 + " target=" + targetValue + " delta=" + delta);
2190 }
2191 curValue += delta;
2192 int curIntValue = (int)curValue;
2193 boolean more = true;
2194 if (delta == 0) {
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07002195 curValue = curIntValue = targetValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002196 more = false;
2197 } else if (delta > 0) {
2198 if (curIntValue >= targetValue) {
2199 curValue = curIntValue = targetValue;
2200 more = false;
2201 }
2202 } else {
2203 if (curIntValue <= targetValue) {
2204 curValue = curIntValue = targetValue;
2205 more = false;
2206 }
2207 }
Joe Onoratob08a1af2010-10-11 19:28:58 -07002208 if (mSpew) Slog.d(TAG, "Animating curIntValue=" + curIntValue + ": " + mask);
The Android Open Source Project10592532009-03-18 17:39:46 -07002209 setLightBrightness(mask, curIntValue);
Joe Onorato3d3db602010-10-18 16:08:16 -04002210 finishAnimationLocked(more, curIntValue);
Joe Onoratob08a1af2010-10-11 19:28:58 -07002211 return more;
2212 }
2213
Joe Onorato3d3db602010-10-18 16:08:16 -04002214 void jumpToTargetLocked() {
2215 if (mSpew) Slog.d(TAG, "jumpToTargetLocked targetValue=" + targetValue + ": " + mask);
Joe Onoratob08a1af2010-10-11 19:28:58 -07002216 setLightBrightness(mask, targetValue);
2217 final int tv = targetValue;
2218 curValue = tv;
2219 targetValue = -1;
Joe Onorato3d3db602010-10-18 16:08:16 -04002220 finishAnimationLocked(false, tv);
Joe Onoratob08a1af2010-10-11 19:28:58 -07002221 }
2222
Joe Onorato3d3db602010-10-18 16:08:16 -04002223 private void finishAnimationLocked(boolean more, int curIntValue) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002224 animating = more;
2225 if (!more) {
The Android Open Source Project10592532009-03-18 17:39:46 -07002226 if (mask == SCREEN_BRIGHT_BIT && curIntValue == Power.BRIGHTNESS_OFF) {
Mike Lockwood435eb642009-12-03 08:40:18 -05002227 screenOffFinishedAnimatingLocked(mScreenOffReason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002228 }
2229 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002230 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002231
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002232 public void run() {
Dianne Hackborne02c88a2011-10-28 13:58:15 -07002233 synchronized (mLocks) {
2234 // we're turning off
2235 final boolean turningOff = animating && targetValue == Power.BRIGHTNESS_OFF;
2236 if (mAnimateScreenLights || !turningOff) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002237 long now = SystemClock.uptimeMillis();
2238 boolean more = mScreenBrightness.stepLocked();
2239 if (more) {
2240 mScreenOffHandler.postAtTime(this, now+(1000/60));
2241 }
Dianne Hackborne02c88a2011-10-28 13:58:15 -07002242 } else {
2243 // It's pretty scary to hold mLocks for this long, and we should
2244 // redesign this, but it works for now.
2245 nativeStartSurfaceFlingerAnimation(
2246 mScreenOffReason == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR
2247 ? 0 : mAnimationSetting);
Joe Onorato3d3db602010-10-18 16:08:16 -04002248 mScreenBrightness.jumpToTargetLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002249 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002250 }
2251 }
2252 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002253
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002254 private int getPreferredBrightness() {
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002255 if (mScreenBrightnessOverride >= 0) {
2256 return mScreenBrightnessOverride;
2257 } else if (mLightSensorScreenBrightness >= 0 && mUseSoftwareAutoBrightness
2258 && mAutoBrightessEnabled) {
2259 return mLightSensorScreenBrightness;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002260 }
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002261 final int brightness = mScreenBrightnessSetting;
2262 // Don't let applications turn the screen all the way off
2263 return Math.max(brightness, mScreenBrightnessDim);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002264 }
2265
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002266 private int applyButtonState(int state) {
2267 int brightness = -1;
Mike Lockwood48358bd2010-04-17 22:29:20 -04002268 if ((state & BATTERY_LOW_BIT) != 0) {
2269 // do not override brightness if the battery is low
2270 return state;
2271 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002272 if (mButtonBrightnessOverride >= 0) {
2273 brightness = mButtonBrightnessOverride;
2274 } else if (mLightSensorButtonBrightness >= 0 && mUseSoftwareAutoBrightness) {
2275 brightness = mLightSensorButtonBrightness;
2276 }
2277 if (brightness > 0) {
2278 return state | BUTTON_BRIGHT_BIT;
2279 } else if (brightness == 0) {
2280 return state & ~BUTTON_BRIGHT_BIT;
2281 } else {
2282 return state;
2283 }
2284 }
2285
2286 private int applyKeyboardState(int state) {
2287 int brightness = -1;
Mike Lockwood48358bd2010-04-17 22:29:20 -04002288 if ((state & BATTERY_LOW_BIT) != 0) {
2289 // do not override brightness if the battery is low
2290 return state;
2291 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002292 if (!mKeyboardVisible) {
2293 brightness = 0;
2294 } else if (mButtonBrightnessOverride >= 0) {
2295 brightness = mButtonBrightnessOverride;
2296 } else if (mLightSensorKeyboardBrightness >= 0 && mUseSoftwareAutoBrightness) {
2297 brightness = mLightSensorKeyboardBrightness;
2298 }
2299 if (brightness > 0) {
2300 return state | KEYBOARD_BRIGHT_BIT;
2301 } else if (brightness == 0) {
2302 return state & ~KEYBOARD_BRIGHT_BIT;
2303 } else {
2304 return state;
2305 }
2306 }
2307
Charles Mendis322591c2009-10-29 11:06:59 -07002308 public boolean isScreenOn() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002309 synchronized (mLocks) {
2310 return (mPowerState & SCREEN_ON_BIT) != 0;
2311 }
2312 }
2313
Charles Mendis322591c2009-10-29 11:06:59 -07002314 boolean isScreenBright() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002315 synchronized (mLocks) {
2316 return (mPowerState & SCREEN_BRIGHT) == SCREEN_BRIGHT;
2317 }
2318 }
2319
Mike Lockwood497087e32009-11-08 18:33:03 -05002320 private boolean isScreenTurningOffLocked() {
2321 return (mScreenBrightness.animating && mScreenBrightness.targetValue == 0);
2322 }
2323
Joe Onorato4b9f62d2010-10-11 13:41:35 -07002324 private boolean shouldLog(long time) {
2325 synchronized (mLocks) {
2326 if (time > (mWarningSpewThrottleTime + (60*60*1000))) {
2327 mWarningSpewThrottleTime = time;
2328 mWarningSpewThrottleCount = 0;
2329 return true;
2330 } else if (mWarningSpewThrottleCount < 30) {
2331 mWarningSpewThrottleCount++;
2332 return true;
2333 } else {
2334 return false;
2335 }
2336 }
2337 }
2338
Mike Lockwood200b30b2009-09-20 00:23:59 -04002339 private void forceUserActivityLocked() {
Mike Lockwoode090281422009-11-14 21:02:56 -05002340 if (isScreenTurningOffLocked()) {
2341 // cancel animation so userActivity will succeed
2342 mScreenBrightness.animating = false;
2343 }
Mike Lockwood200b30b2009-09-20 00:23:59 -04002344 boolean savedActivityAllowed = mUserActivityAllowed;
2345 mUserActivityAllowed = true;
2346 userActivity(SystemClock.uptimeMillis(), false);
2347 mUserActivityAllowed = savedActivityAllowed;
2348 }
2349
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002350 public void userActivityWithForce(long time, boolean noChangeLights, boolean force) {
2351 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
Joe Onorato7999bff2010-07-24 11:50:05 -04002352 userActivity(time, -1, noChangeLights, OTHER_EVENT, force);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002353 }
2354
2355 public void userActivity(long time, boolean noChangeLights) {
Joe Onorato4b9f62d2010-10-11 13:41:35 -07002356 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER)
2357 != PackageManager.PERMISSION_GRANTED) {
2358 if (shouldLog(time)) {
2359 Slog.w(TAG, "Caller does not have DEVICE_POWER permission. pid="
2360 + Binder.getCallingPid() + " uid=" + Binder.getCallingUid());
2361 }
2362 return;
2363 }
2364
Joe Onorato7999bff2010-07-24 11:50:05 -04002365 userActivity(time, -1, noChangeLights, OTHER_EVENT, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002366 }
2367
2368 public void userActivity(long time, boolean noChangeLights, int eventType) {
Joe Onorato7999bff2010-07-24 11:50:05 -04002369 userActivity(time, -1, noChangeLights, eventType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002370 }
2371
2372 public void userActivity(long time, boolean noChangeLights, int eventType, boolean force) {
Joe Onorato7999bff2010-07-24 11:50:05 -04002373 userActivity(time, -1, noChangeLights, eventType, force);
2374 }
2375
2376 /*
2377 * Reset the user activity timeout to now + timeout. This overrides whatever else is going
2378 * on with user activity. Don't use this function.
2379 */
2380 public void clearUserActivityTimeout(long now, long timeout) {
2381 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
2382 Slog.i(TAG, "clearUserActivity for " + timeout + "ms from now");
2383 userActivity(now, timeout, false, OTHER_EVENT, false);
2384 }
2385
2386 private void userActivity(long time, long timeoutOverride, boolean noChangeLights,
2387 int eventType, boolean force) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002388
Joe Onorato1a542c72010-11-08 09:48:20 -08002389 if (((mPokey & POKE_LOCK_IGNORE_TOUCH_EVENTS) != 0) && (eventType == TOUCH_EVENT)) {
Joe Onoratoe68ffcb2009-03-24 19:11:13 -07002390 if (false) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002391 Slog.d(TAG, "dropping touch mPokey=0x" + Integer.toHexString(mPokey));
Joe Onoratoe68ffcb2009-03-24 19:11:13 -07002392 }
2393 return;
2394 }
2395
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002396 synchronized (mLocks) {
2397 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002398 Slog.d(TAG, "userActivity mLastEventTime=" + mLastEventTime + " time=" + time
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002399 + " mUserActivityAllowed=" + mUserActivityAllowed
2400 + " mUserState=0x" + Integer.toHexString(mUserState)
Mike Lockwood36fc3022009-08-25 16:49:06 -07002401 + " mWakeLockState=0x" + Integer.toHexString(mWakeLockState)
2402 + " mProximitySensorActive=" + mProximitySensorActive
Joe Onorato797e6882010-08-26 14:46:01 -04002403 + " timeoutOverride=" + timeoutOverride
Mike Lockwood36fc3022009-08-25 16:49:06 -07002404 + " force=" + force);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002405 }
Mike Lockwood05067122009-10-27 23:07:25 -04002406 // ignore user activity if we are in the process of turning off the screen
Mike Lockwood497087e32009-11-08 18:33:03 -05002407 if (isScreenTurningOffLocked()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002408 Slog.d(TAG, "ignoring user activity while turning off screen");
Mike Lockwood05067122009-10-27 23:07:25 -04002409 return;
2410 }
Mike Lockwood0e39ea82009-11-18 15:37:10 -05002411 // Disable proximity sensor if if user presses power key while we are in the
2412 // "waiting for proximity sensor to go negative" state.
2413 if (mProximitySensorActive && mProximityWakeLockCount == 0) {
2414 mProximitySensorActive = false;
2415 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002416 if (mLastEventTime <= time || force) {
2417 mLastEventTime = time;
Mike Lockwood36fc3022009-08-25 16:49:06 -07002418 if ((mUserActivityAllowed && !mProximitySensorActive) || force) {
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002419 // Only turn on button backlights if a button was pressed
2420 // and auto brightness is disabled
Mike Lockwood4984e732009-11-01 08:16:33 -05002421 if (eventType == BUTTON_EVENT && !mUseSoftwareAutoBrightness) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002422 mUserState = (mKeyboardVisible ? ALL_BRIGHT : SCREEN_BUTTON_BRIGHT);
2423 } else {
2424 // don't clear button/keyboard backlights when the screen is touched.
2425 mUserState |= SCREEN_BRIGHT;
2426 }
2427
Dianne Hackborn617f8772009-03-31 15:04:46 -07002428 int uid = Binder.getCallingUid();
2429 long ident = Binder.clearCallingIdentity();
2430 try {
2431 mBatteryStats.noteUserActivity(uid, eventType);
2432 } catch (RemoteException e) {
2433 // Ignore
2434 } finally {
2435 Binder.restoreCallingIdentity(ident);
2436 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002437
Michael Chane96440f2009-05-06 10:27:36 -07002438 mWakeLockState = mLocks.reactivateScreenLocksLocked();
Mike Lockwood435eb642009-12-03 08:40:18 -05002439 setPowerState(mUserState | mWakeLockState, noChangeLights,
2440 WindowManagerPolicy.OFF_BECAUSE_OF_USER);
Joe Onorato7999bff2010-07-24 11:50:05 -04002441 setTimeoutLocked(time, timeoutOverride, SCREEN_BRIGHT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002442 }
2443 }
2444 }
Mike Lockwoodef731622010-01-27 17:51:34 -05002445
2446 if (mPolicy != null) {
2447 mPolicy.userActivity();
2448 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002449 }
2450
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002451 private int getAutoBrightnessValue(int sensorValue, int[] values) {
2452 try {
2453 int i;
2454 for (i = 0; i < mAutoBrightnessLevels.length; i++) {
2455 if (sensorValue < mAutoBrightnessLevels[i]) {
2456 break;
2457 }
2458 }
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002459 // This is the range of brightness values that we can use.
2460 final int minval = values[0];
2461 final int maxval = values[mAutoBrightnessLevels.length];
2462 // This is the range we will be scaling. We put some padding
2463 // at the low and high end to give the adjustment a little better
2464 // impact on the actual observed value.
2465 final int range = (maxval-minval) + LIGHT_SENSOR_RANGE_EXPANSION;
2466 // This is the desired brightness value from 0.0 to 1.0.
2467 float valf = ((values[i]-minval+(LIGHT_SENSOR_RANGE_EXPANSION/2))/(float)range);
2468 // Apply a scaling to the value based on the adjustment.
2469 if (mLightSensorAdjustSetting > 0 && mLightSensorAdjustSetting <= 1) {
2470 float adj = (float)Math.sqrt(1.0f-mLightSensorAdjustSetting);
2471 if (adj <= .00001) {
2472 valf = 1;
2473 } else {
2474 valf /= adj;
2475 }
2476 } else if (mLightSensorAdjustSetting < 0 && mLightSensorAdjustSetting >= -1) {
2477 float adj = (float)Math.sqrt(1.0f+mLightSensorAdjustSetting);
2478 valf *= adj;
2479 }
2480 // Apply an additional offset to the value based on the adjustment.
2481 valf += mLightSensorAdjustSetting/LIGHT_SENSOR_OFFSET_SCALE;
2482 // Convert the 0.0-1.0 value back to a brightness integer.
2483 int val = (int)((valf*range)+minval) - (LIGHT_SENSOR_RANGE_EXPANSION/2);
2484 if (val < minval) val = minval;
2485 else if (val > maxval) val = maxval;
2486 return val;
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002487 } catch (Exception e) {
2488 // guard against null pointer or index out of bounds errors
Joe Onorato8a9b2202010-02-26 18:56:32 -08002489 Slog.e(TAG, "getAutoBrightnessValue", e);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002490 return 255;
2491 }
2492 }
2493
Mike Lockwood20f87d72009-11-05 16:08:51 -05002494 private Runnable mProximityTask = new Runnable() {
2495 public void run() {
2496 synchronized (mLocks) {
2497 if (mProximityPendingValue != -1) {
2498 proximityChangedLocked(mProximityPendingValue == 1);
2499 mProximityPendingValue = -1;
2500 }
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -05002501 if (mProximityPartialLock.isHeld()) {
2502 mProximityPartialLock.release();
2503 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05002504 }
2505 }
2506 };
2507
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002508 private Runnable mAutoBrightnessTask = new Runnable() {
2509 public void run() {
Mike Lockwoodfa68ab42009-10-20 11:08:49 -04002510 synchronized (mLocks) {
Jim Rodovichd102fea2010-09-02 12:30:49 -05002511 if (mLightSensorPendingDecrease || mLightSensorPendingIncrease) {
2512 int value = (int)mLightSensorPendingValue;
2513 mLightSensorPendingDecrease = false;
2514 mLightSensorPendingIncrease = false;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002515 lightSensorChangedLocked(value, false);
Mike Lockwoodfa68ab42009-10-20 11:08:49 -04002516 }
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002517 }
2518 }
2519 };
2520
Mike Lockwoodb2865412010-02-02 22:40:33 -05002521 private void dockStateChanged(int state) {
2522 synchronized (mLocks) {
2523 mIsDocked = (state != Intent.EXTRA_DOCK_STATE_UNDOCKED);
2524 if (mIsDocked) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04002525 // allow brightness to decrease when docked
Mike Lockwoodb2865412010-02-02 22:40:33 -05002526 mHighestLightSensorValue = -1;
2527 }
2528 if ((mPowerState & SCREEN_ON_BIT) != 0) {
2529 // force lights recalculation
2530 int value = (int)mLightSensorValue;
2531 mLightSensorValue = -1;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002532 lightSensorChangedLocked(value, false);
Mike Lockwoodb2865412010-02-02 22:40:33 -05002533 }
2534 }
2535 }
2536
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002537 private void lightSensorChangedLocked(int value, boolean immediate) {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002538 if (mDebugLightSensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002539 Slog.d(TAG, "lightSensorChangedLocked " + value);
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002540 }
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002541
Joe Onorato06eb33a2010-10-25 14:09:21 -07002542 // Don't do anything if the screen is off.
2543 if ((mPowerState & SCREEN_ON_BIT) == 0) {
2544 if (mDebugLightSensor) {
2545 Slog.d(TAG, "dropping lightSensorChangedLocked because screen is off");
2546 }
2547 return;
2548 }
2549
Mike Lockwoodb2865412010-02-02 22:40:33 -05002550 // do not allow light sensor value to decrease
2551 if (mHighestLightSensorValue < value) {
2552 mHighestLightSensorValue = value;
2553 }
2554
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002555 if (mLightSensorValue != value) {
2556 mLightSensorValue = value;
2557 if ((mPowerState & BATTERY_LOW_BIT) == 0) {
Mike Lockwoodb2865412010-02-02 22:40:33 -05002558 // use maximum light sensor value seen since screen went on for LCD to avoid flicker
2559 // we only do this if we are undocked, since lighting should be stable when
2560 // stationary in a dock.
2561 int lcdValue = getAutoBrightnessValue(
2562 (mIsDocked ? value : mHighestLightSensorValue),
2563 mLcdBacklightValues);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002564 int buttonValue = getAutoBrightnessValue(value, mButtonBacklightValues);
Mike Lockwooddf024922009-10-29 21:29:15 -04002565 int keyboardValue;
2566 if (mKeyboardVisible) {
2567 keyboardValue = getAutoBrightnessValue(value, mKeyboardBacklightValues);
2568 } else {
2569 keyboardValue = 0;
2570 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002571 mLightSensorScreenBrightness = lcdValue;
2572 mLightSensorButtonBrightness = buttonValue;
2573 mLightSensorKeyboardBrightness = keyboardValue;
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002574
2575 if (mDebugLightSensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002576 Slog.d(TAG, "lcdValue " + lcdValue);
2577 Slog.d(TAG, "buttonValue " + buttonValue);
2578 Slog.d(TAG, "keyboardValue " + keyboardValue);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002579 }
2580
Mike Lockwood4984e732009-11-01 08:16:33 -05002581 if (mAutoBrightessEnabled && mScreenBrightnessOverride < 0) {
Dianne Hackborn81de8b92011-11-28 16:54:31 -08002582 if (!mSkippedScreenOn) {
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002583 mScreenBrightness.setTargetLocked(lcdValue,
2584 immediate ? IMMEDIATE_ANIM_STEPS : AUTOBRIGHTNESS_ANIM_STEPS,
Dianne Hackborn81de8b92011-11-28 16:54:31 -08002585 INITIAL_SCREEN_BRIGHTNESS, (int)mScreenBrightness.curValue);
2586 }
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002587 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002588 if (mButtonBrightnessOverride < 0) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002589 mButtonLight.setBrightness(buttonValue);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002590 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05002591 if (mButtonBrightnessOverride < 0 || !mKeyboardVisible) {
Joe Onoratob08a1af2010-10-11 19:28:58 -07002592 mKeyboardLight.setBrightness(keyboardValue);
Mike Lockwoodd7786b42009-10-15 17:09:16 -07002593 }
2594 }
2595 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002596 }
2597
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002598 /**
2599 * The user requested that we go to sleep (probably with the power button).
2600 * This overrides all wake locks that are held.
2601 */
2602 public void goToSleep(long time)
2603 {
Dianne Hackborn254cb442010-01-27 19:23:59 -08002604 goToSleepWithReason(time, WindowManagerPolicy.OFF_BECAUSE_OF_USER);
2605 }
2606
2607 /**
2608 * The user requested that we go to sleep (probably with the power button).
2609 * This overrides all wake locks that are held.
2610 */
2611 public void goToSleepWithReason(long time, int reason)
2612 {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002613 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
2614 synchronized (mLocks) {
Dianne Hackborn254cb442010-01-27 19:23:59 -08002615 goToSleepLocked(time, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002616 }
2617 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002618
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002619 /**
Doug Zongker50a21f42009-11-19 12:49:53 -08002620 * Reboot the device immediately, passing 'reason' (may be null)
2621 * to the underlying __reboot system call. Should not return.
2622 */
2623 public void reboot(String reason)
2624 {
2625 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
San Mehat14e69af2010-01-06 14:58:18 -08002626
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002627 if (mHandler == null || !ActivityManagerNative.isSystemReady()) {
2628 throw new IllegalStateException("Too early to call reboot()");
2629 }
Mike Lockwoodb62f9592010-03-12 07:55:23 -05002630
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002631 final String finalReason = reason;
2632 Runnable runnable = new Runnable() {
2633 public void run() {
2634 synchronized (this) {
2635 ShutdownThread.reboot(mContext, finalReason, false);
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002636 }
2637
San Mehat1e512792010-01-07 10:40:29 -08002638 }
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002639 };
Mike Lockwoodb62f9592010-03-12 07:55:23 -05002640 // ShutdownThread must run on a looper capable of displaying the UI.
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002641 mHandler.post(runnable);
2642
Mike Lockwoodb62f9592010-03-12 07:55:23 -05002643 // PowerManager.reboot() is documented not to return so just wait for the inevitable.
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002644 synchronized (runnable) {
Mike Lockwoodb62f9592010-03-12 07:55:23 -05002645 while (true) {
2646 try {
2647 runnable.wait();
2648 } catch (InterruptedException e) {
2649 }
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -08002650 }
Doug Zongker50a21f42009-11-19 12:49:53 -08002651 }
2652 }
2653
Dan Egnor60d87622009-12-16 16:32:58 -08002654 /**
2655 * Crash the runtime (causing a complete restart of the Android framework).
2656 * Requires REBOOT permission. Mostly for testing. Should not return.
2657 */
2658 public void crash(final String message)
2659 {
2660 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
2661 Thread t = new Thread("PowerManagerService.crash()") {
2662 public void run() { throw new RuntimeException(message); }
2663 };
2664 try {
2665 t.start();
2666 t.join();
2667 } catch (InterruptedException e) {
2668 Log.wtf(TAG, e);
2669 }
2670 }
2671
Mike Lockwood435eb642009-12-03 08:40:18 -05002672 private void goToSleepLocked(long time, int reason) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002673
2674 if (mLastEventTime <= time) {
2675 mLastEventTime = time;
2676 // cancel all of the wake locks
2677 mWakeLockState = SCREEN_OFF;
2678 int N = mLocks.size();
2679 int numCleared = 0;
Joe Onorato8274a0e2010-10-05 17:38:09 -04002680 boolean proxLock = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002681 for (int i=0; i<N; i++) {
2682 WakeLock wl = mLocks.get(i);
2683 if (isScreenLock(wl.flags)) {
Joe Onorato8274a0e2010-10-05 17:38:09 -04002684 if (((wl.flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)
2685 && reason == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR) {
2686 proxLock = true;
2687 } else {
2688 mLocks.get(i).activated = false;
2689 numCleared++;
2690 }
2691 }
2692 }
2693 if (!proxLock) {
2694 mProxIgnoredBecauseScreenTurnedOff = true;
2695 if (mDebugProximitySensor) {
2696 Slog.d(TAG, "setting mProxIgnoredBecauseScreenTurnedOff");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002697 }
2698 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002699 EventLog.writeEvent(EventLogTags.POWER_SLEEP_REQUESTED, numCleared);
Joe Onorato128e7292009-03-24 18:41:31 -07002700 mStillNeedSleepNotification = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002701 mUserState = SCREEN_OFF;
Mike Lockwood435eb642009-12-03 08:40:18 -05002702 setPowerState(SCREEN_OFF, false, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002703 cancelTimerLocked();
2704 }
2705 }
2706
2707 public long timeSinceScreenOn() {
2708 synchronized (mLocks) {
2709 if ((mPowerState & SCREEN_ON_BIT) != 0) {
2710 return 0;
2711 }
2712 return SystemClock.elapsedRealtime() - mScreenOffTime;
2713 }
2714 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002715
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002716 public void setKeyboardVisibility(boolean visible) {
Mike Lockwooda625b382009-09-12 17:36:03 -07002717 synchronized (mLocks) {
2718 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002719 Slog.d(TAG, "setKeyboardVisibility: " + visible);
Mike Lockwooda625b382009-09-12 17:36:03 -07002720 }
Mike Lockwood3c9435a2009-10-22 15:45:37 -04002721 if (mKeyboardVisible != visible) {
2722 mKeyboardVisible = visible;
2723 // don't signal user activity if the screen is off; other code
2724 // will take care of turning on due to a true change to the lid
2725 // switch and synchronized with the lock screen.
2726 if ((mPowerState & SCREEN_ON_BIT) != 0) {
Mike Lockwood4984e732009-11-01 08:16:33 -05002727 if (mUseSoftwareAutoBrightness) {
Mike Lockwooddf024922009-10-29 21:29:15 -04002728 // force recompute of backlight values
2729 if (mLightSensorValue >= 0) {
2730 int value = (int)mLightSensorValue;
2731 mLightSensorValue = -1;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002732 lightSensorChangedLocked(value, false);
Mike Lockwooddf024922009-10-29 21:29:15 -04002733 }
2734 }
Mike Lockwood3c9435a2009-10-22 15:45:37 -04002735 userActivity(SystemClock.uptimeMillis(), false, BUTTON_EVENT, true);
2736 }
Mike Lockwooda625b382009-09-12 17:36:03 -07002737 }
2738 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002739 }
2740
2741 /**
2742 * When the keyguard is up, it manages the power state, and userActivity doesn't do anything.
Mike Lockwood50c548d2009-11-09 16:02:06 -05002743 * When disabling user activity we also reset user power state so the keyguard can reset its
2744 * short screen timeout when keyguard is unhidden.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002745 */
2746 public void enableUserActivity(boolean enabled) {
Mike Lockwood50c548d2009-11-09 16:02:06 -05002747 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002748 Slog.d(TAG, "enableUserActivity " + enabled);
Mike Lockwood50c548d2009-11-09 16:02:06 -05002749 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002750 synchronized (mLocks) {
2751 mUserActivityAllowed = enabled;
Mike Lockwood50c548d2009-11-09 16:02:06 -05002752 if (!enabled) {
2753 // cancel timeout and clear mUserState so the keyguard can set a short timeout
2754 setTimeoutLocked(SystemClock.uptimeMillis(), 0);
2755 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002756 }
2757 }
2758
Mike Lockwooddc3494e2009-10-14 21:17:09 -07002759 private void setScreenBrightnessMode(int mode) {
Joe Onoratod28f7532010-11-06 12:56:53 -07002760 synchronized (mLocks) {
2761 boolean enabled = (mode == SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
2762 if (mUseSoftwareAutoBrightness && mAutoBrightessEnabled != enabled) {
2763 mAutoBrightessEnabled = enabled;
2764 // This will get us a new value
2765 enableLightSensorLocked(mAutoBrightessEnabled && isScreenOn());
Mike Lockwood2d155d22009-10-27 09:32:30 -04002766 }
Mike Lockwooddc3494e2009-10-14 21:17:09 -07002767 }
2768 }
2769
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002770 /** Sets the screen off timeouts:
2771 * mKeylightDelay
2772 * mDimDelay
2773 * mScreenOffDelay
2774 * */
2775 private void setScreenOffTimeoutsLocked() {
2776 if ((mPokey & POKE_LOCK_SHORT_TIMEOUT) != 0) {
Doug Zongker43866e02010-01-07 12:09:54 -08002777 mKeylightDelay = mShortKeylightDelay; // Configurable via secure settings
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002778 mDimDelay = -1;
2779 mScreenOffDelay = 0;
2780 } else if ((mPokey & POKE_LOCK_MEDIUM_TIMEOUT) != 0) {
2781 mKeylightDelay = MEDIUM_KEYLIGHT_DELAY;
2782 mDimDelay = -1;
2783 mScreenOffDelay = 0;
2784 } else {
Dianne Hackborndf83afa2010-01-20 13:37:26 -08002785 int totalDelay = mScreenOffTimeoutSetting;
2786 if (totalDelay > mMaximumScreenOffTimeout) {
2787 totalDelay = mMaximumScreenOffTimeout;
2788 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002789 mKeylightDelay = LONG_KEYLIGHT_DELAY;
2790 if (totalDelay < 0) {
Jim Millerbc4603b2010-08-30 21:21:34 -07002791 // negative number means stay on as long as possible.
2792 mScreenOffDelay = mMaximumScreenOffTimeout;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002793 } else if (mKeylightDelay < totalDelay) {
2794 // subtract the time that the keylight delay. This will give us the
2795 // remainder of the time that we need to sleep to get the accurate
2796 // screen off timeout.
2797 mScreenOffDelay = totalDelay - mKeylightDelay;
2798 } else {
2799 mScreenOffDelay = 0;
2800 }
2801 if (mDimScreen && totalDelay >= (LONG_KEYLIGHT_DELAY + LONG_DIM_TIME)) {
2802 mDimDelay = mScreenOffDelay - LONG_DIM_TIME;
2803 mScreenOffDelay = LONG_DIM_TIME;
2804 } else {
2805 mDimDelay = -1;
2806 }
2807 }
2808 if (mSpew) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002809 Slog.d(TAG, "setScreenOffTimeouts mKeylightDelay=" + mKeylightDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002810 + " mDimDelay=" + mDimDelay + " mScreenOffDelay=" + mScreenOffDelay
2811 + " mDimScreen=" + mDimScreen);
2812 }
2813 }
2814
2815 /**
Doug Zongker43866e02010-01-07 12:09:54 -08002816 * Refreshes cached secure settings. Called once on startup, and
2817 * on subsequent changes to secure settings.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002818 */
Doug Zongker43866e02010-01-07 12:09:54 -08002819 private void updateSettingsValues() {
2820 mShortKeylightDelay = Settings.Secure.getInt(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002821 mContext.getContentResolver(),
Doug Zongker43866e02010-01-07 12:09:54 -08002822 Settings.Secure.SHORT_KEYLIGHT_DELAY_MS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002823 SHORT_KEYLIGHT_DELAY_DEFAULT);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002824 // Slog.i(TAG, "updateSettingsValues(): mShortKeylightDelay now " + mShortKeylightDelay);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002825 }
2826
2827 private class LockList extends ArrayList<WakeLock>
2828 {
2829 void addLock(WakeLock wl)
2830 {
2831 int index = getIndex(wl.binder);
2832 if (index < 0) {
2833 this.add(wl);
2834 }
2835 }
2836
2837 WakeLock removeLock(IBinder binder)
2838 {
2839 int index = getIndex(binder);
2840 if (index >= 0) {
2841 return this.remove(index);
2842 } else {
2843 return null;
2844 }
2845 }
2846
2847 int getIndex(IBinder binder)
2848 {
2849 int N = this.size();
2850 for (int i=0; i<N; i++) {
2851 if (this.get(i).binder == binder) {
2852 return i;
2853 }
2854 }
2855 return -1;
2856 }
2857
2858 int gatherState()
2859 {
2860 int result = 0;
2861 int N = this.size();
2862 for (int i=0; i<N; i++) {
2863 WakeLock wl = this.get(i);
2864 if (wl.activated) {
2865 if (isScreenLock(wl.flags)) {
2866 result |= wl.minState;
2867 }
2868 }
2869 }
2870 return result;
2871 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002872
Michael Chane96440f2009-05-06 10:27:36 -07002873 int reactivateScreenLocksLocked()
2874 {
2875 int result = 0;
2876 int N = this.size();
2877 for (int i=0; i<N; i++) {
2878 WakeLock wl = this.get(i);
2879 if (isScreenLock(wl.flags)) {
2880 wl.activated = true;
2881 result |= wl.minState;
2882 }
2883 }
Joe Onorato8274a0e2010-10-05 17:38:09 -04002884 if (mDebugProximitySensor) {
2885 Slog.d(TAG, "reactivateScreenLocksLocked mProxIgnoredBecauseScreenTurnedOff="
2886 + mProxIgnoredBecauseScreenTurnedOff);
2887 }
2888 mProxIgnoredBecauseScreenTurnedOff = false;
Michael Chane96440f2009-05-06 10:27:36 -07002889 return result;
2890 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002891 }
2892
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08002893 public void setPolicy(WindowManagerPolicy p) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002894 synchronized (mLocks) {
2895 mPolicy = p;
2896 mLocks.notifyAll();
2897 }
2898 }
2899
2900 WindowManagerPolicy getPolicyLocked() {
2901 while (mPolicy == null || !mDoneBooting) {
2902 try {
2903 mLocks.wait();
2904 } catch (InterruptedException e) {
2905 // Ignore
2906 }
2907 }
2908 return mPolicy;
2909 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002910
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002911 void systemReady() {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002912 mSensorManager = new SensorManager(mHandlerThread.getLooper());
2913 mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
2914 // don't bother with the light sensor if auto brightness is handled in hardware
Mike Lockwoodaa66ea82009-10-31 16:31:27 -04002915 if (mUseSoftwareAutoBrightness) {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002916 mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
Mike Lockwood8738e0c2009-10-04 08:44:47 -04002917 }
2918
Mike Lockwoodb42ab0f2010-03-04 08:02:44 -05002919 // wait until sensors are enabled before turning on screen.
2920 // some devices will not activate the light sensor properly on boot
2921 // unless we do this.
2922 if (mUseSoftwareAutoBrightness) {
2923 // turn the screen on
2924 setPowerState(SCREEN_BRIGHT);
2925 } else {
2926 // turn everything on
2927 setPowerState(ALL_BRIGHT);
2928 }
2929
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002930 synchronized (mLocks) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002931 Slog.d(TAG, "system ready!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002932 mDoneBooting = true;
Mike Lockwoodb42ab0f2010-03-04 08:02:44 -05002933
Joe Onoratod28f7532010-11-06 12:56:53 -07002934 enableLightSensorLocked(mUseSoftwareAutoBrightness && mAutoBrightessEnabled);
2935
Dianne Hackborn617f8772009-03-31 15:04:46 -07002936 long identity = Binder.clearCallingIdentity();
2937 try {
2938 mBatteryStats.noteScreenBrightness(getPreferredBrightness());
2939 mBatteryStats.noteScreenOn();
2940 } catch (RemoteException e) {
2941 // Nothing interesting to do.
2942 } finally {
2943 Binder.restoreCallingIdentity(identity);
2944 }
Mike Lockwood2d7bb812009-11-15 18:12:22 -05002945 }
2946 }
2947
2948 void bootCompleted() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002949 Slog.d(TAG, "bootCompleted");
Mike Lockwood2d7bb812009-11-15 18:12:22 -05002950 synchronized (mLocks) {
2951 mBootCompleted = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002952 userActivity(SystemClock.uptimeMillis(), false, BUTTON_EVENT, true);
2953 updateWakeLockLocked();
2954 mLocks.notifyAll();
2955 }
2956 }
2957
Joe Onoratob08a1af2010-10-11 19:28:58 -07002958 // for watchdog
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002959 public void monitor() {
2960 synchronized (mLocks) { }
2961 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07002962
2963 public int getSupportedWakeLockFlags() {
2964 int result = PowerManager.PARTIAL_WAKE_LOCK
2965 | PowerManager.FULL_WAKE_LOCK
2966 | PowerManager.SCREEN_DIM_WAKE_LOCK;
2967
Mike Lockwoodbc706a02009-07-27 13:50:57 -07002968 if (mProximitySensor != null) {
2969 result |= PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK;
2970 }
2971
2972 return result;
2973 }
2974
Mike Lockwood237a2992009-09-15 14:42:16 -04002975 public void setBacklightBrightness(int brightness) {
2976 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
2977 // Don't let applications turn the screen all the way off
Joe Onoratob08a1af2010-10-11 19:28:58 -07002978 synchronized (mLocks) {
Mike Lockwoodeb6456b2011-09-13 15:24:02 -04002979 brightness = Math.max(brightness, mScreenBrightnessDim);
Joe Onoratob08a1af2010-10-11 19:28:58 -07002980 mLcdLight.setBrightness(brightness);
2981 mKeyboardLight.setBrightness(mKeyboardVisible ? brightness : 0);
2982 mButtonLight.setBrightness(brightness);
2983 long identity = Binder.clearCallingIdentity();
2984 try {
2985 mBatteryStats.noteScreenBrightness(brightness);
2986 } catch (RemoteException e) {
2987 Slog.w(TAG, "RemoteException calling noteScreenBrightness on BatteryStatsService", e);
2988 } finally {
2989 Binder.restoreCallingIdentity(identity);
2990 }
Mike Lockwood237a2992009-09-15 14:42:16 -04002991
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08002992 mScreenBrightness.targetValue = brightness;
2993 mScreenBrightness.jumpToTargetLocked();
2994 }
2995 }
2996
2997 public void setAutoBrightnessAdjustment(float adj) {
2998 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
2999 synchronized (mLocks) {
3000 mLightSensorAdjustSetting = adj;
3001 if (mSensorManager != null && mLightSensorEnabled) {
3002 // clear calling identity so sensor manager battery stats are accurate
3003 long identity = Binder.clearCallingIdentity();
3004 try {
3005 // force recompute of backlight values
3006 if (mLightSensorValue >= 0) {
3007 int value = (int)mLightSensorValue;
3008 mLightSensorValue = -1;
3009 handleLightSensorValue(value, true);
3010 }
3011 } finally {
3012 Binder.restoreCallingIdentity(identity);
3013 }
Joe Onorato3d3db602010-10-18 16:08:16 -04003014 }
Mike Lockwood237a2992009-09-15 14:42:16 -04003015 }
3016 }
3017
Mike Lockwoodb11832d2009-11-25 15:25:55 -05003018 public void setAttentionLight(boolean on, int color) {
3019 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
Mike Lockwood3cb67a32009-11-27 14:25:58 -05003020 mAttentionLight.setFlashing(color, LightsService.LIGHT_FLASH_HARDWARE, (on ? 3 : 0), 0);
Mike Lockwoodb11832d2009-11-25 15:25:55 -05003021 }
3022
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003023 private void enableProximityLockLocked() {
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003024 if (mDebugProximitySensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003025 Slog.d(TAG, "enableProximityLockLocked");
Mike Lockwood36fc3022009-08-25 16:49:06 -07003026 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003027 if (!mProximitySensorEnabled) {
3028 // clear calling identity so sensor manager battery stats are accurate
3029 long identity = Binder.clearCallingIdentity();
3030 try {
3031 mSensorManager.registerListener(mProximityListener, mProximitySensor,
3032 SensorManager.SENSOR_DELAY_NORMAL);
3033 mProximitySensorEnabled = true;
3034 } finally {
3035 Binder.restoreCallingIdentity(identity);
3036 }
Mike Lockwood809ad0f2009-10-26 22:10:33 -04003037 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003038 }
3039
3040 private void disableProximityLockLocked() {
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003041 if (mDebugProximitySensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003042 Slog.d(TAG, "disableProximityLockLocked");
Mike Lockwood36fc3022009-08-25 16:49:06 -07003043 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003044 if (mProximitySensorEnabled) {
3045 // clear calling identity so sensor manager battery stats are accurate
3046 long identity = Binder.clearCallingIdentity();
3047 try {
3048 mSensorManager.unregisterListener(mProximityListener);
3049 mHandler.removeCallbacks(mProximityTask);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -05003050 if (mProximityPartialLock.isHeld()) {
3051 mProximityPartialLock.release();
3052 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003053 mProximitySensorEnabled = false;
3054 } finally {
3055 Binder.restoreCallingIdentity(identity);
3056 }
3057 if (mProximitySensorActive) {
3058 mProximitySensorActive = false;
Joe Onorato8274a0e2010-10-05 17:38:09 -04003059 if (mDebugProximitySensor) {
3060 Slog.d(TAG, "disableProximityLockLocked mProxIgnoredBecauseScreenTurnedOff="
3061 + mProxIgnoredBecauseScreenTurnedOff);
3062 }
3063 if (!mProxIgnoredBecauseScreenTurnedOff) {
3064 forceUserActivityLocked();
3065 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003066 }
Mike Lockwood200b30b2009-09-20 00:23:59 -04003067 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003068 }
3069
Mike Lockwood20f87d72009-11-05 16:08:51 -05003070 private void proximityChangedLocked(boolean active) {
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003071 if (mDebugProximitySensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003072 Slog.d(TAG, "proximityChangedLocked, active: " + active);
Mike Lockwood20f87d72009-11-05 16:08:51 -05003073 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003074 if (!mProximitySensorEnabled) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003075 Slog.d(TAG, "Ignoring proximity change after sensor is disabled");
Mike Lockwood0d72f7e2009-11-05 20:53:00 -05003076 return;
3077 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05003078 if (active) {
Joe Onorato8274a0e2010-10-05 17:38:09 -04003079 if (mDebugProximitySensor) {
3080 Slog.d(TAG, "b mProxIgnoredBecauseScreenTurnedOff="
3081 + mProxIgnoredBecauseScreenTurnedOff);
3082 }
3083 if (!mProxIgnoredBecauseScreenTurnedOff) {
3084 goToSleepLocked(SystemClock.uptimeMillis(),
3085 WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR);
3086 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05003087 mProximitySensorActive = true;
3088 } else {
3089 // proximity sensor negative events trigger as user activity.
3090 // temporarily set mUserActivityAllowed to true so this will work
3091 // even when the keyguard is on.
3092 mProximitySensorActive = false;
Joe Onorato8274a0e2010-10-05 17:38:09 -04003093 if (mDebugProximitySensor) {
3094 Slog.d(TAG, "b mProxIgnoredBecauseScreenTurnedOff="
3095 + mProxIgnoredBecauseScreenTurnedOff);
3096 }
3097 if (!mProxIgnoredBecauseScreenTurnedOff) {
3098 forceUserActivityLocked();
3099 }
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003100
3101 if (mProximityWakeLockCount == 0) {
3102 // disable sensor if we have no listeners left after proximity negative
3103 disableProximityLockLocked();
3104 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05003105 }
3106 }
3107
Joe Onoratod28f7532010-11-06 12:56:53 -07003108 private void enableLightSensorLocked(boolean enable) {
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003109 if (mDebugLightSensor) {
Joe Onoratod28f7532010-11-06 12:56:53 -07003110 Slog.d(TAG, "enableLightSensorLocked enable=" + enable
3111 + " mAutoBrightessEnabled=" + mAutoBrightessEnabled);
3112 }
3113 if (!mAutoBrightessEnabled) {
3114 enable = false;
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003115 }
3116 if (mSensorManager != null && mLightSensorEnabled != enable) {
3117 mLightSensorEnabled = enable;
Mike Lockwood809ad0f2009-10-26 22:10:33 -04003118 // clear calling identity so sensor manager battery stats are accurate
3119 long identity = Binder.clearCallingIdentity();
3120 try {
3121 if (enable) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003122 // reset our highest value when reenabling
3123 mHighestLightSensorValue = -1;
3124 // force recompute of backlight values
3125 if (mLightSensorValue >= 0) {
3126 int value = (int)mLightSensorValue;
3127 mLightSensorValue = -1;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08003128 handleLightSensorValue(value, true);
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003129 }
Mike Lockwood809ad0f2009-10-26 22:10:33 -04003130 mSensorManager.registerListener(mLightListener, mLightSensor,
Mathias Agopian47f1fe52011-11-08 17:18:41 -08003131 LIGHT_SENSOR_RATE);
Mike Lockwood809ad0f2009-10-26 22:10:33 -04003132 } else {
3133 mSensorManager.unregisterListener(mLightListener);
3134 mHandler.removeCallbacks(mAutoBrightnessTask);
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003135 mLightSensorPendingDecrease = false;
3136 mLightSensorPendingIncrease = false;
Mike Lockwood809ad0f2009-10-26 22:10:33 -04003137 }
3138 } finally {
3139 Binder.restoreCallingIdentity(identity);
Mike Lockwood06952d92009-08-13 16:05:38 -04003140 }
Mike Lockwoodbc706a02009-07-27 13:50:57 -07003141 }
3142 }
3143
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003144 SensorEventListener mProximityListener = new SensorEventListener() {
3145 public void onSensorChanged(SensorEvent event) {
Mike Lockwoodba8eb1e2009-11-08 19:31:18 -05003146 long milliseconds = SystemClock.elapsedRealtime();
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003147 synchronized (mLocks) {
3148 float distance = event.values[0];
Mike Lockwood20f87d72009-11-05 16:08:51 -05003149 long timeSinceLastEvent = milliseconds - mLastProximityEventTime;
3150 mLastProximityEventTime = milliseconds;
3151 mHandler.removeCallbacks(mProximityTask);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -05003152 boolean proximityTaskQueued = false;
Mike Lockwood20f87d72009-11-05 16:08:51 -05003153
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003154 // compare against getMaximumRange to support sensors that only return 0 or 1
Mike Lockwood20f87d72009-11-05 16:08:51 -05003155 boolean active = (distance >= 0.0 && distance < PROXIMITY_THRESHOLD &&
3156 distance < mProximitySensor.getMaximumRange());
3157
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003158 if (mDebugProximitySensor) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003159 Slog.d(TAG, "mProximityListener.onSensorChanged active: " + active);
Mike Lockwoodee2b0942009-11-09 14:09:02 -05003160 }
Mike Lockwood20f87d72009-11-05 16:08:51 -05003161 if (timeSinceLastEvent < PROXIMITY_SENSOR_DELAY) {
3162 // enforce delaying atleast PROXIMITY_SENSOR_DELAY before processing
3163 mProximityPendingValue = (active ? 1 : 0);
3164 mHandler.postDelayed(mProximityTask, PROXIMITY_SENSOR_DELAY - timeSinceLastEvent);
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -05003165 proximityTaskQueued = true;
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003166 } else {
Mike Lockwood20f87d72009-11-05 16:08:51 -05003167 // process the value immediately
3168 mProximityPendingValue = -1;
3169 proximityChangedLocked(active);
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003170 }
Mike Lockwood0e5bb7f2009-11-14 06:36:31 -05003171
3172 // update mProximityPartialLock state
3173 boolean held = mProximityPartialLock.isHeld();
3174 if (!held && proximityTaskQueued) {
3175 // hold wakelock until mProximityTask runs
3176 mProximityPartialLock.acquire();
3177 } else if (held && !proximityTaskQueued) {
3178 mProximityPartialLock.release();
3179 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003180 }
3181 }
3182
3183 public void onAccuracyChanged(Sensor sensor, int accuracy) {
3184 // ignore
3185 }
3186 };
3187
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08003188 private void handleLightSensorValue(int value, boolean immediate) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003189 long milliseconds = SystemClock.elapsedRealtime();
3190 if (mLightSensorValue == -1 ||
3191 milliseconds < mLastScreenOnTime + mLightSensorWarmupTime) {
3192 // process the value immediately if screen has just turned on
3193 mHandler.removeCallbacks(mAutoBrightnessTask);
3194 mLightSensorPendingDecrease = false;
3195 mLightSensorPendingIncrease = false;
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08003196 lightSensorChangedLocked(value, immediate);
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003197 } else {
3198 if ((value > mLightSensorValue && mLightSensorPendingDecrease) ||
3199 (value < mLightSensorValue && mLightSensorPendingIncrease) ||
3200 (value == mLightSensorValue) ||
3201 (!mLightSensorPendingDecrease && !mLightSensorPendingIncrease)) {
3202 // delay processing to debounce the sensor
3203 mHandler.removeCallbacks(mAutoBrightnessTask);
3204 mLightSensorPendingDecrease = (value < mLightSensorValue);
3205 mLightSensorPendingIncrease = (value > mLightSensorValue);
3206 if (mLightSensorPendingDecrease || mLightSensorPendingIncrease) {
3207 mLightSensorPendingValue = value;
3208 mHandler.postDelayed(mAutoBrightnessTask, LIGHT_SENSOR_DELAY);
3209 }
3210 } else {
3211 mLightSensorPendingValue = value;
3212 }
3213 }
3214 }
3215
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003216 SensorEventListener mLightListener = new SensorEventListener() {
3217 public void onSensorChanged(SensorEvent event) {
Mike Lockwood5dca30a2011-10-13 16:29:29 -04003218 if (mDebugLightSensor) {
3219 Slog.d(TAG, "onSensorChanged: light value: " + event.values[0]);
3220 }
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003221 synchronized (mLocks) {
Mike Lockwood497087e32009-11-08 18:33:03 -05003222 // ignore light sensor while screen is turning off
3223 if (isScreenTurningOffLocked()) {
3224 return;
3225 }
Dianne Hackbornd9ea4682012-01-20 18:36:40 -08003226 handleLightSensorValue((int)event.values[0], false);
Mike Lockwood8738e0c2009-10-04 08:44:47 -04003227 }
3228 }
3229
3230 public void onAccuracyChanged(Sensor sensor, int accuracy) {
3231 // ignore
3232 }
3233 };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003234}