1 /* 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 17 package com.android.server; 18 19 import com.android.internal.app.IBatteryStats; 20 import com.android.internal.app.ShutdownThread; 21 import com.android.server.am.BatteryStatsService; 22 23 import android.app.ActivityManagerNative; 24 import android.app.IActivityManager; 25 import android.content.BroadcastReceiver; 26 import android.content.ContentQueryMap; 27 import android.content.ContentResolver; 28 import android.content.ContentValues; 29 import android.content.Context; 30 import android.content.Intent; 31 import android.content.IntentFilter; 32 import android.content.pm.PackageManager; 33 import android.content.res.Resources; 34 import android.database.ContentObserver; 35 import android.database.Cursor; 36 import android.hardware.Sensor; 37 import android.hardware.SensorEvent; 38 import android.hardware.SensorEventListener; 39 import android.hardware.SensorManager; 40 import android.os.BatteryManager; 41 import android.os.BatteryStats; 42 import android.os.Binder; 43 import android.os.Handler; 44 import android.os.HandlerThread; 45 import android.os.IBinder; 46 import android.os.IPowerManager; 47 import android.os.LocalPowerManager; 48 import android.os.Power; 49 import android.os.PowerManager; 50 import android.os.Process; 51 import android.os.RemoteException; 52 import android.os.SystemClock; 53 import android.os.WorkSource; 54 import android.provider.Settings.SettingNotFoundException; 55 import android.provider.Settings; 56 import android.util.EventLog; 57 import android.util.Log; 58 import android.util.Slog; 59 import android.view.WindowManagerPolicy; 60 import static android.provider.Settings.System.DIM_SCREEN; 61 import static android.provider.Settings.System.SCREEN_BRIGHTNESS; 62 import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE; 63 import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC; 64 import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT; 65 import static android.provider.Settings.System.STAY_ON_WHILE_PLUGGED_IN; 66 import static android.provider.Settings.System.WINDOW_ANIMATION_SCALE; 67 import static android.provider.Settings.System.TRANSITION_ANIMATION_SCALE; 68 69 import java.io.FileDescriptor; 70 import java.io.PrintWriter; 71 import java.util.ArrayList; 72 import java.util.HashMap; 73 import java.util.Observable; 74 import java.util.Observer; 75 76 public class PowerManagerService extends IPowerManager.Stub 77 implements LocalPowerManager, Watchdog.Monitor { 78 79 private static final String TAG = "PowerManagerService"; 80 static final String PARTIAL_NAME = "PowerManagerService"; 81 82 static final boolean DEBUG_SCREEN_ON = false; 83 84 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 93 | PowerManager.FULL_WAKE_LOCK 94 | PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK; 95 96 // time since last state: time since last event: 97 // The short keylight delay comes from secure settings; this is the default. 98 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 103 // How long to wait to debounce light sensor changes. 104 private static final int LIGHT_SENSOR_DELAY = 2000; 105 106 // For debouncing the proximity sensor. 107 private static final int PROXIMITY_SENSOR_DELAY = 1000; 108 109 // trigger proximity if distance is less than 5 cm 110 private static final float PROXIMITY_THRESHOLD = 5.0f; 111 112 // Cached secure settings; see updateSettingsValues() 113 private int mShortKeylightDelay = SHORT_KEYLIGHT_DELAY_DEFAULT; 114 115 // Default timeout for screen off, if not found in settings database = 15 seconds. 116 private static final int DEFAULT_SCREEN_OFF_TIMEOUT = 15000; 117 118 // flags for setPowerState 119 private static final int SCREEN_ON_BIT = 0x00000001; 120 private static final int SCREEN_BRIGHT_BIT = 0x00000002; 121 private static final int BUTTON_BRIGHT_BIT = 0x00000004; 122 private static final int KEYBOARD_BRIGHT_BIT = 0x00000008; 123 private static final int BATTERY_LOW_BIT = 0x00000010; 124 125 // values for setPowerState 126 127 // SCREEN_OFF == everything off 128 private static final int SCREEN_OFF = 0x00000000; 129 130 // SCREEN_DIM == screen on, screen backlight dim 131 private static final int SCREEN_DIM = SCREEN_ON_BIT; 132 133 // SCREEN_BRIGHT == screen on, screen backlight bright 134 private static final int SCREEN_BRIGHT = SCREEN_ON_BIT | SCREEN_BRIGHT_BIT; 135 136 // SCREEN_BUTTON_BRIGHT == screen on, screen and button backlights bright 137 private static final int SCREEN_BUTTON_BRIGHT = SCREEN_BRIGHT | BUTTON_BRIGHT_BIT; 138 139 // SCREEN_BUTTON_BRIGHT == screen on, screen, button and keyboard backlights bright 140 private static final int ALL_BRIGHT = SCREEN_BUTTON_BRIGHT | KEYBOARD_BRIGHT_BIT; 141 142 // used for noChangeLights in setPowerState() 143 private static final int LIGHTS_MASK = SCREEN_BRIGHT_BIT | BUTTON_BRIGHT_BIT | KEYBOARD_BRIGHT_BIT; 144 145 boolean mAnimateScreenLights = true; 146 147 static final int ANIM_STEPS = 60/4; 148 // Slower animation for autobrightness changes 149 static final int AUTOBRIGHTNESS_ANIM_STEPS = 60; 150 151 // These magic numbers are the initial state of the LEDs at boot. Ideally 152 // we should read them from the driver, but our current hardware returns 0 153 // for the initial value. Oops! 154 static final int INITIAL_SCREEN_BRIGHTNESS = 255; 155 static final int INITIAL_BUTTON_BRIGHTNESS = Power.BRIGHTNESS_OFF; 156 static final int INITIAL_KEYBOARD_BRIGHTNESS = Power.BRIGHTNESS_OFF; 157 158 private final int MY_UID; 159 private final int MY_PID; 160 161 private boolean mDoneBooting = false; 162 private boolean mBootCompleted = false; 163 private int mStayOnConditions = 0; 164 private final int[] mBroadcastQueue = new int[] { -1, -1, -1 }; 165 private final int[] mBroadcastWhy = new int[3]; 166 private boolean mPreparingForScreenOn = false; 167 private boolean mSkippedScreenOn = false; 168 private boolean mInitialized = false; 169 private int mPartialCount = 0; 170 private int mPowerState; 171 // mScreenOffReason can be WindowManagerPolicy.OFF_BECAUSE_OF_USER, 172 // WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT or WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR 173 private int mScreenOffReason; 174 private int mUserState; 175 private boolean mKeyboardVisible = false; 176 private boolean mUserActivityAllowed = true; 177 private int mProximityWakeLockCount = 0; 178 private boolean mProximitySensorEnabled = false; 179 private boolean mProximitySensorActive = false; 180 private int mProximityPendingValue = -1; // -1 == nothing, 0 == inactive, 1 == active 181 private long mLastProximityEventTime; 182 private int mScreenOffTimeoutSetting; 183 private int mMaximumScreenOffTimeout = Integer.MAX_VALUE; 184 private int mKeylightDelay; 185 private int mDimDelay; 186 private int mScreenOffDelay; 187 private int mWakeLockState; 188 private long mLastEventTime = 0; 189 private long mScreenOffTime; 190 private volatile WindowManagerPolicy mPolicy; 191 private final LockList mLocks = new LockList(); 192 private Intent mScreenOffIntent; 193 private Intent mScreenOnIntent; 194 private LightsService mLightsService; 195 private Context mContext; 196 private LightsService.Light mLcdLight; 197 private LightsService.Light mButtonLight; 198 private LightsService.Light mKeyboardLight; 199 private LightsService.Light mAttentionLight; 200 private UnsynchronizedWakeLock mBroadcastWakeLock; 201 private UnsynchronizedWakeLock mStayOnWhilePluggedInScreenDimLock; 202 private UnsynchronizedWakeLock mStayOnWhilePluggedInPartialLock; 203 private UnsynchronizedWakeLock mPreventScreenOnPartialLock; 204 private UnsynchronizedWakeLock mProximityPartialLock; 205 private HandlerThread mHandlerThread; 206 private HandlerThread mScreenOffThread; 207 private Handler mScreenOffHandler; 208 private Handler mHandler; 209 private final TimeoutTask mTimeoutTask = new TimeoutTask(); 210 private final BrightnessState mScreenBrightness 211 = new BrightnessState(SCREEN_BRIGHT_BIT); 212 private boolean mStillNeedSleepNotification; 213 private boolean mIsPowered = false; 214 private IActivityManager mActivityService; 215 private IBatteryStats mBatteryStats; 216 private BatteryService mBatteryService; 217 private SensorManager mSensorManager; 218 private Sensor mProximitySensor; 219 private Sensor mLightSensor; 220 private boolean mLightSensorEnabled; 221 private float mLightSensorValue = -1; 222 private boolean mProxIgnoredBecauseScreenTurnedOff = false; 223 private int mHighestLightSensorValue = -1; 224 private boolean mLightSensorPendingDecrease = false; 225 private boolean mLightSensorPendingIncrease = false; 226 private float mLightSensorPendingValue = -1; 227 private int mLightSensorScreenBrightness = -1; 228 private int mLightSensorButtonBrightness = -1; 229 private int mLightSensorKeyboardBrightness = -1; 230 private boolean mDimScreen = true; 231 private boolean mIsDocked = false; 232 private long mNextTimeout; 233 private volatile int mPokey = 0; 234 private volatile boolean mPokeAwakeOnSet = false; 235 private volatile boolean mInitComplete = false; 236 private final HashMap<IBinder,PokeLock> mPokeLocks = new HashMap<IBinder,PokeLock>(); 237 // mLastScreenOnTime is the time the screen was last turned on 238 private long mLastScreenOnTime; 239 private boolean mPreventScreenOn; 240 private int mScreenBrightnessOverride = -1; 241 private int mButtonBrightnessOverride = -1; 242 private int mScreenBrightnessDim; 243 private boolean mUseSoftwareAutoBrightness; 244 private boolean mAutoBrightessEnabled; 245 private int[] mAutoBrightnessLevels; 246 private int[] mLcdBacklightValues; 247 private int[] mButtonBacklightValues; 248 private int[] mKeyboardBacklightValues; 249 private int mLightSensorWarmupTime; 250 boolean mUnplugTurnsOnScreen; 251 private int mWarningSpewThrottleCount; 252 private long mWarningSpewThrottleTime; 253 private int mAnimationSetting = ANIM_SETTING_OFF; 254 255 // Must match with the ISurfaceComposer constants in C++. 256 private static final int ANIM_SETTING_ON = 0x01; 257 private static final int ANIM_SETTING_OFF = 0x10; 258 259 // Used when logging number and duration of touch-down cycles 260 private long mTotalTouchDownTime; 261 private long mLastTouchDown; 262 private int mTouchCycles; 263 264 // could be either static or controllable at runtime 265 private static final boolean mSpew = false; 266 private static final boolean mDebugProximitySensor = (false || mSpew); 267 private static final boolean mDebugLightSensor = (false || mSpew); 268 269 private native void nativeInit(); 270 private native void nativeSetPowerState(boolean screenOn, boolean screenBright); 271 private native void nativeStartSurfaceFlingerAnimation(int mode); 272 273 /* 274 static PrintStream mLog; 275 static { 276 try { 277 mLog = new PrintStream("/data/power.log"); 278 } 279 catch (FileNotFoundException e) { 280 android.util.Slog.e(TAG, "Life is hard", e); 281 } 282 } 283 static class Log { 284 static void d(String tag, String s) { 285 mLog.println(s); 286 android.util.Slog.d(tag, s); 287 } 288 static void i(String tag, String s) { 289 mLog.println(s); 290 android.util.Slog.i(tag, s); 291 } 292 static void w(String tag, String s) { 293 mLog.println(s); 294 android.util.Slog.w(tag, s); 295 } 296 static void e(String tag, String s) { 297 mLog.println(s); 298 android.util.Slog.e(tag, s); 299 } 300 } 301 */ 302 303 /** 304 * This class works around a deadlock between the lock in PowerManager.WakeLock 305 * and our synchronizing on mLocks. PowerManager.WakeLock synchronizes on its 306 * mToken object so it can be accessed from any thread, but it calls into here 307 * with its lock held. This class is essentially a reimplementation of 308 * PowerManager.WakeLock, but without that extra synchronized block, because we'll 309 * only call it with our own locks held. 310 */ 311 private class UnsynchronizedWakeLock { 312 int mFlags; 313 String mTag; 314 IBinder mToken; 315 int mCount = 0; 316 boolean mRefCounted; 317 boolean mHeld; 318 319 UnsynchronizedWakeLock(int flags, String tag, boolean refCounted) { 320 mFlags = flags; 321 mTag = tag; 322 mToken = new Binder(); 323 mRefCounted = refCounted; 324 } 325 326 public void acquire() { 327 if (!mRefCounted || mCount++ == 0) { 328 long ident = Binder.clearCallingIdentity(); 329 try { 330 PowerManagerService.this.acquireWakeLockLocked(mFlags, mToken, 331 MY_UID, MY_PID, mTag, null); 332 mHeld = true; 333 } finally { 334 Binder.restoreCallingIdentity(ident); 335 } 336 } 337 } 338 339 public void release() { 340 if (!mRefCounted || --mCount == 0) { 341 PowerManagerService.this.releaseWakeLockLocked(mToken, 0, false); 342 mHeld = false; 343 } 344 if (mCount < 0) { 345 throw new RuntimeException("WakeLock under-locked " + mTag); 346 } 347 } 348 349 public boolean isHeld() 350 { 351 return mHeld; 352 } 353 354 public String toString() { 355 return "UnsynchronizedWakeLock(mFlags=0x" + Integer.toHexString(mFlags) 356 + " mCount=" + mCount + " mHeld=" + mHeld + ")"; 357 } 358 } 359 360 private final class BatteryReceiver extends BroadcastReceiver { 361 @Override 362 public void onReceive(Context context, Intent intent) { 363 synchronized (mLocks) { 364 boolean wasPowered = mIsPowered; 365 mIsPowered = mBatteryService.isPowered(); 366 367 if (mIsPowered != wasPowered) { 368 // update mStayOnWhilePluggedIn wake lock 369 updateWakeLockLocked(); 370 371 // treat plugging and unplugging the devices as a user activity. 372 // users find it disconcerting when they unplug the device 373 // and it shuts off right away. 374 // to avoid turning on the screen when unplugging, we only trigger 375 // user activity when screen was already on. 376 // temporarily set mUserActivityAllowed to true so this will work 377 // even when the keyguard is on. 378 // However, you can also set config_unplugTurnsOnScreen to have it 379 // turn on. Some devices want this because they don't have a 380 // charging LED. 381 synchronized (mLocks) { 382 if (!wasPowered || (mPowerState & SCREEN_ON_BIT) != 0 || 383 mUnplugTurnsOnScreen) { 384 forceUserActivityLocked(); 385 } 386 } 387 } 388 } 389 } 390 } 391 392 private final class BootCompletedReceiver extends BroadcastReceiver { 393 @Override 394 public void onReceive(Context context, Intent intent) { 395 bootCompleted(); 396 } 397 } 398 399 private final class DockReceiver extends BroadcastReceiver { 400 @Override 401 public void onReceive(Context context, Intent intent) { 402 int state = intent.getIntExtra(Intent.EXTRA_DOCK_STATE, 403 Intent.EXTRA_DOCK_STATE_UNDOCKED); 404 dockStateChanged(state); 405 } 406 } 407 408 /** 409 * Set the setting that determines whether the device stays on when plugged in. 410 * The argument is a bit string, with each bit specifying a power source that, 411 * when the device is connected to that source, causes the device to stay on. 412 * See {@link android.os.BatteryManager} for the list of power sources that 413 * can be specified. Current values include {@link android.os.BatteryManager#BATTERY_PLUGGED_AC} 414 * and {@link android.os.BatteryManager#BATTERY_PLUGGED_USB} 415 * @param val an {@code int} containing the bits that specify which power sources 416 * should cause the device to stay on. 417 */ 418 public void setStayOnSetting(int val) { 419 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS, null); 420 Settings.System.putInt(mContext.getContentResolver(), 421 Settings.System.STAY_ON_WHILE_PLUGGED_IN, val); 422 } 423 424 public void setMaximumScreenOffTimeount(int timeMs) { 425 mContext.enforceCallingOrSelfPermission( 426 android.Manifest.permission.WRITE_SECURE_SETTINGS, null); 427 synchronized (mLocks) { 428 mMaximumScreenOffTimeout = timeMs; 429 // recalculate everything 430 setScreenOffTimeoutsLocked(); 431 } 432 } 433 434 private class SettingsObserver implements Observer { 435 private int getInt(String name, int defValue) { 436 ContentValues values = mSettings.getValues(name); 437 Integer iVal = values != null ? values.getAsInteger(Settings.System.VALUE) : null; 438 return iVal != null ? iVal : defValue; 439 } 440 441 private float getFloat(String name, float defValue) { 442 ContentValues values = mSettings.getValues(name); 443 Float fVal = values != null ? values.getAsFloat(Settings.System.VALUE) : null; 444 return fVal != null ? fVal : defValue; 445 } 446 447 public void update(Observable o, Object arg) { 448 synchronized (mLocks) { 449 // STAY_ON_WHILE_PLUGGED_IN, default to when plugged into AC 450 mStayOnConditions = getInt(STAY_ON_WHILE_PLUGGED_IN, 451 BatteryManager.BATTERY_PLUGGED_AC); 452 updateWakeLockLocked(); 453 454 // SCREEN_OFF_TIMEOUT, default to 15 seconds 455 mScreenOffTimeoutSetting = getInt(SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT); 456 457 // DIM_SCREEN 458 //mDimScreen = getInt(DIM_SCREEN) != 0; 459 460 // SCREEN_BRIGHTNESS_MODE, default to manual 461 setScreenBrightnessMode(getInt(SCREEN_BRIGHTNESS_MODE, 462 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL)); 463 464 // recalculate everything 465 setScreenOffTimeoutsLocked(); 466 467 final float windowScale = getFloat(WINDOW_ANIMATION_SCALE, 1.0f); 468 final float transitionScale = getFloat(TRANSITION_ANIMATION_SCALE, 1.0f); 469 mAnimationSetting = 0; 470 if (windowScale > 0.5f) { 471 mAnimationSetting |= ANIM_SETTING_OFF; 472 } 473 if (transitionScale > 0.5f) { 474 // Uncomment this if you want the screen-on animation. 475 // mAnimationSetting |= ANIM_SETTING_ON; 476 } 477 } 478 } 479 } 480 481 PowerManagerService() { 482 // Hack to get our uid... should have a func for this. 483 long token = Binder.clearCallingIdentity(); 484 MY_UID = Process.myUid(); 485 MY_PID = Process.myPid(); 486 Binder.restoreCallingIdentity(token); 487 488 // XXX remove this when the kernel doesn't timeout wake locks 489 Power.setLastUserActivityTimeout(7*24*3600*1000); // one week 490 491 // assume nothing is on yet 492 mUserState = mPowerState = 0; 493 494 // Add ourself to the Watchdog monitors. 495 Watchdog.getInstance().addMonitor(this); 496 } 497 498 private ContentQueryMap mSettings; 499 500 void init(Context context, LightsService lights, IActivityManager activity, 501 BatteryService battery) { 502 mLightsService = lights; 503 mContext = context; 504 mActivityService = activity; 505 mBatteryStats = BatteryStatsService.getService(); 506 mBatteryService = battery; 507 508 mLcdLight = lights.getLight(LightsService.LIGHT_ID_BACKLIGHT); 509 mButtonLight = lights.getLight(LightsService.LIGHT_ID_BUTTONS); 510 mKeyboardLight = lights.getLight(LightsService.LIGHT_ID_KEYBOARD); 511 mAttentionLight = lights.getLight(LightsService.LIGHT_ID_ATTENTION); 512 513 nativeInit(); 514 synchronized (mLocks) { 515 updateNativePowerStateLocked(); 516 } 517 518 mInitComplete = false; 519 mScreenOffThread = new HandlerThread("PowerManagerService.mScreenOffThread") { 520 @Override 521 protected void onLooperPrepared() { 522 mScreenOffHandler = new Handler(); 523 synchronized (mScreenOffThread) { 524 mInitComplete = true; 525 mScreenOffThread.notifyAll(); 526 } 527 } 528 }; 529 mScreenOffThread.start(); 530 531 synchronized (mScreenOffThread) { 532 while (!mInitComplete) { 533 try { 534 mScreenOffThread.wait(); 535 } catch (InterruptedException e) { 536 // Ignore 537 } 538 } 539 } 540 541 mInitComplete = false; 542 mHandlerThread = new HandlerThread("PowerManagerService") { 543 @Override 544 protected void onLooperPrepared() { 545 super.onLooperPrepared(); 546 initInThread(); 547 } 548 }; 549 mHandlerThread.start(); 550 551 synchronized (mHandlerThread) { 552 while (!mInitComplete) { 553 try { 554 mHandlerThread.wait(); 555 } catch (InterruptedException e) { 556 // Ignore 557 } 558 } 559 } 560 561 nativeInit(); 562 synchronized (mLocks) { 563 updateNativePowerStateLocked(); 564 // We make sure to start out with the screen on due to user activity. 565 // (They did just boot their device, after all.) 566 forceUserActivityLocked(); 567 mInitialized = true; 568 } 569 } 570 571 void initInThread() { 572 mHandler = new Handler(); 573 574 mBroadcastWakeLock = new UnsynchronizedWakeLock( 575 PowerManager.PARTIAL_WAKE_LOCK, "sleep_broadcast", true); 576 mStayOnWhilePluggedInScreenDimLock = new UnsynchronizedWakeLock( 577 PowerManager.SCREEN_DIM_WAKE_LOCK, "StayOnWhilePluggedIn Screen Dim", false); 578 mStayOnWhilePluggedInPartialLock = new UnsynchronizedWakeLock( 579 PowerManager.PARTIAL_WAKE_LOCK, "StayOnWhilePluggedIn Partial", false); 580 mPreventScreenOnPartialLock = new UnsynchronizedWakeLock( 581 PowerManager.PARTIAL_WAKE_LOCK, "PreventScreenOn Partial", false); 582 mProximityPartialLock = new UnsynchronizedWakeLock( 583 PowerManager.PARTIAL_WAKE_LOCK, "Proximity Partial", false); 584 585 mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON); 586 mScreenOnIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 587 mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF); 588 mScreenOffIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 589 590 Resources resources = mContext.getResources(); 591 592 mAnimateScreenLights = resources.getBoolean( 593 com.android.internal.R.bool.config_animateScreenLights); 594 595 mUnplugTurnsOnScreen = resources.getBoolean( 596 com.android.internal.R.bool.config_unplugTurnsOnScreen); 597 598 mScreenBrightnessDim = resources.getInteger( 599 com.android.internal.R.integer.config_screenBrightnessDim); 600 601 // read settings for auto-brightness 602 mUseSoftwareAutoBrightness = resources.getBoolean( 603 com.android.internal.R.bool.config_automatic_brightness_available); 604 if (mUseSoftwareAutoBrightness) { 605 mAutoBrightnessLevels = resources.getIntArray( 606 com.android.internal.R.array.config_autoBrightnessLevels); 607 mLcdBacklightValues = resources.getIntArray( 608 com.android.internal.R.array.config_autoBrightnessLcdBacklightValues); 609 mButtonBacklightValues = resources.getIntArray( 610 com.android.internal.R.array.config_autoBrightnessButtonBacklightValues); 611 mKeyboardBacklightValues = resources.getIntArray( 612 com.android.internal.R.array.config_autoBrightnessKeyboardBacklightValues); 613 mLightSensorWarmupTime = resources.getInteger( 614 com.android.internal.R.integer.config_lightSensorWarmupTime); 615 } 616 617 ContentResolver resolver = mContext.getContentResolver(); 618 Cursor settingsCursor = resolver.query(Settings.System.CONTENT_URI, null, 619 "(" + Settings.System.NAME + "=?) or (" 620 + Settings.System.NAME + "=?) or (" 621 + Settings.System.NAME + "=?) or (" 622 + Settings.System.NAME + "=?) or (" 623 + Settings.System.NAME + "=?) or (" 624 + Settings.System.NAME + "=?)", 625 new String[]{STAY_ON_WHILE_PLUGGED_IN, SCREEN_OFF_TIMEOUT, DIM_SCREEN, 626 SCREEN_BRIGHTNESS_MODE, WINDOW_ANIMATION_SCALE, TRANSITION_ANIMATION_SCALE}, 627 null); 628 mSettings = new ContentQueryMap(settingsCursor, Settings.System.NAME, true, mHandler); 629 SettingsObserver settingsObserver = new SettingsObserver(); 630 mSettings.addObserver(settingsObserver); 631 632 // pretend that the settings changed so we will get their initial state 633 settingsObserver.update(mSettings, null); 634 635 // register for the battery changed notifications 636 IntentFilter filter = new IntentFilter(); 637 filter.addAction(Intent.ACTION_BATTERY_CHANGED); 638 mContext.registerReceiver(new BatteryReceiver(), filter); 639 filter = new IntentFilter(); 640 filter.addAction(Intent.ACTION_BOOT_COMPLETED); 641 mContext.registerReceiver(new BootCompletedReceiver(), filter); 642 filter = new IntentFilter(); 643 filter.addAction(Intent.ACTION_DOCK_EVENT); 644 mContext.registerReceiver(new DockReceiver(), filter); 645 646 // Listen for secure settings changes 647 mContext.getContentResolver().registerContentObserver( 648 Settings.Secure.CONTENT_URI, true, 649 new ContentObserver(new Handler()) { 650 public void onChange(boolean selfChange) { 651 updateSettingsValues(); 652 } 653 }); 654 updateSettingsValues(); 655 656 synchronized (mHandlerThread) { 657 mInitComplete = true; 658 mHandlerThread.notifyAll(); 659 } 660 } 661 662 private class WakeLock implements IBinder.DeathRecipient 663 { 664 WakeLock(int f, IBinder b, String t, int u, int p) { 665 super(); 666 flags = f; 667 binder = b; 668 tag = t; 669 uid = u == MY_UID ? Process.SYSTEM_UID : u; 670 pid = p; 671 if (u != MY_UID || ( 672 !"KEEP_SCREEN_ON_FLAG".equals(tag) 673 && !"KeyInputQueue".equals(tag))) { 674 monitorType = (f & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK 675 ? BatteryStats.WAKE_TYPE_PARTIAL 676 : BatteryStats.WAKE_TYPE_FULL; 677 } else { 678 monitorType = -1; 679 } 680 try { 681 b.linkToDeath(this, 0); 682 } catch (RemoteException e) { 683 binderDied(); 684 } 685 } 686 public void binderDied() { 687 synchronized (mLocks) { 688 releaseWakeLockLocked(this.binder, 0, true); 689 } 690 } 691 final int flags; 692 final IBinder binder; 693 final String tag; 694 final int uid; 695 final int pid; 696 final int monitorType; 697 WorkSource ws; 698 boolean activated = true; 699 int minState; 700 } 701 702 private void updateWakeLockLocked() { 703 if (mStayOnConditions != 0 && mBatteryService.isPowered(mStayOnConditions)) { 704 // keep the device on if we're plugged in and mStayOnWhilePluggedIn is set. 705 mStayOnWhilePluggedInScreenDimLock.acquire(); 706 mStayOnWhilePluggedInPartialLock.acquire(); 707 } else { 708 mStayOnWhilePluggedInScreenDimLock.release(); 709 mStayOnWhilePluggedInPartialLock.release(); 710 } 711 } 712 713 private boolean isScreenLock(int flags) 714 { 715 int n = flags & LOCK_MASK; 716 return n == PowerManager.FULL_WAKE_LOCK 717 || n == PowerManager.SCREEN_BRIGHT_WAKE_LOCK 718 || n == PowerManager.SCREEN_DIM_WAKE_LOCK 719 || n == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK; 720 } 721 722 void enforceWakeSourcePermission(int uid, int pid) { 723 if (uid == Process.myUid()) { 724 return; 725 } 726 mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS, 727 pid, uid, null); 728 } 729 730 public void acquireWakeLock(int flags, IBinder lock, String tag, WorkSource ws) { 731 int uid = Binder.getCallingUid(); 732 int pid = Binder.getCallingPid(); 733 if (uid != Process.myUid()) { 734 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null); 735 } 736 if (ws != null) { 737 enforceWakeSourcePermission(uid, pid); 738 } 739 long ident = Binder.clearCallingIdentity(); 740 try { 741 synchronized (mLocks) { 742 acquireWakeLockLocked(flags, lock, uid, pid, tag, ws); 743 } 744 } finally { 745 Binder.restoreCallingIdentity(ident); 746 } 747 } 748 749 void noteStartWakeLocked(WakeLock wl, WorkSource ws) { 750 if (wl.monitorType >= 0) { 751 long origId = Binder.clearCallingIdentity(); 752 try { 753 if (ws != null) { 754 mBatteryStats.noteStartWakelockFromSource(ws, wl.pid, wl.tag, 755 wl.monitorType); 756 } else { 757 mBatteryStats.noteStartWakelock(wl.uid, wl.pid, wl.tag, wl.monitorType); 758 } 759 } catch (RemoteException e) { 760 // Ignore 761 } finally { 762 Binder.restoreCallingIdentity(origId); 763 } 764 } 765 } 766 767 void noteStopWakeLocked(WakeLock wl, WorkSource ws) { 768 if (wl.monitorType >= 0) { 769 long origId = Binder.clearCallingIdentity(); 770 try { 771 if (ws != null) { 772 mBatteryStats.noteStopWakelockFromSource(ws, wl.pid, wl.tag, 773 wl.monitorType); 774 } else { 775 mBatteryStats.noteStopWakelock(wl.uid, wl.pid, wl.tag, wl.monitorType); 776 } 777 } catch (RemoteException e) { 778 // Ignore 779 } finally { 780 Binder.restoreCallingIdentity(origId); 781 } 782 } 783 } 784 785 public void acquireWakeLockLocked(int flags, IBinder lock, int uid, int pid, String tag, 786 WorkSource ws) { 787 if (mSpew) { 788 Slog.d(TAG, "acquireWakeLock flags=0x" + Integer.toHexString(flags) + " tag=" + tag); 789 } 790 791 if (ws != null && ws.size() == 0) { 792 ws = null; 793 } 794 795 int index = mLocks.getIndex(lock); 796 WakeLock wl; 797 boolean newlock; 798 boolean diffsource; 799 WorkSource oldsource; 800 if (index < 0) { 801 wl = new WakeLock(flags, lock, tag, uid, pid); 802 switch (wl.flags & LOCK_MASK) 803 { 804 case PowerManager.FULL_WAKE_LOCK: 805 if (mUseSoftwareAutoBrightness) { 806 wl.minState = SCREEN_BRIGHT; 807 } else { 808 wl.minState = (mKeyboardVisible ? ALL_BRIGHT : SCREEN_BUTTON_BRIGHT); 809 } 810 break; 811 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK: 812 wl.minState = SCREEN_BRIGHT; 813 break; 814 case PowerManager.SCREEN_DIM_WAKE_LOCK: 815 wl.minState = SCREEN_DIM; 816 break; 817 case PowerManager.PARTIAL_WAKE_LOCK: 818 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK: 819 break; 820 default: 821 // just log and bail. we're in the server, so don't 822 // throw an exception. 823 Slog.e(TAG, "bad wakelock type for lock '" + tag + "' " 824 + " flags=" + flags); 825 return; 826 } 827 mLocks.addLock(wl); 828 if (ws != null) { 829 wl.ws = new WorkSource(ws); 830 } 831 newlock = true; 832 diffsource = false; 833 oldsource = null; 834 } else { 835 wl = mLocks.get(index); 836 newlock = false; 837 oldsource = wl.ws; 838 if (oldsource != null) { 839 if (ws == null) { 840 wl.ws = null; 841 diffsource = true; 842 } else { 843 diffsource = oldsource.diff(ws); 844 } 845 } else if (ws != null) { 846 diffsource = true; 847 } else { 848 diffsource = false; 849 } 850 if (diffsource) { 851 wl.ws = new WorkSource(ws); 852 } 853 } 854 if (isScreenLock(flags)) { 855 // if this causes a wakeup, we reactivate all of the locks and 856 // set it to whatever they want. otherwise, we modulate that 857 // by the current state so we never turn it more on than 858 // it already is. 859 if ((flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) { 860 mProximityWakeLockCount++; 861 if (mProximityWakeLockCount == 1) { 862 enableProximityLockLocked(); 863 } 864 } else { 865 if ((wl.flags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) { 866 int oldWakeLockState = mWakeLockState; 867 mWakeLockState = mLocks.reactivateScreenLocksLocked(); 868 869 // Disable proximity sensor if if user presses power key while we are in the 870 // "waiting for proximity sensor to go negative" state. 871 if ((mWakeLockState & SCREEN_ON_BIT) != 0 872 && mProximitySensorActive && mProximityWakeLockCount == 0) { 873 mProximitySensorActive = false; 874 } 875 876 if (mSpew) { 877 Slog.d(TAG, "wakeup here mUserState=0x" + Integer.toHexString(mUserState) 878 + " mWakeLockState=0x" 879 + Integer.toHexString(mWakeLockState) 880 + " previous wakeLockState=0x" 881 + Integer.toHexString(oldWakeLockState)); 882 } 883 } else { 884 if (mSpew) { 885 Slog.d(TAG, "here mUserState=0x" + Integer.toHexString(mUserState) 886 + " mLocks.gatherState()=0x" 887 + Integer.toHexString(mLocks.gatherState()) 888 + " mWakeLockState=0x" + Integer.toHexString(mWakeLockState)); 889 } 890 mWakeLockState = (mUserState | mWakeLockState) & mLocks.gatherState(); 891 } 892 setPowerState(mWakeLockState | mUserState); 893 } 894 } 895 else if ((flags & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK) { 896 if (newlock) { 897 mPartialCount++; 898 if (mPartialCount == 1) { 899 if (LOG_PARTIAL_WL) EventLog.writeEvent(EventLogTags.POWER_PARTIAL_WAKE_STATE, 1, tag); 900 } 901 } 902 Power.acquireWakeLock(Power.PARTIAL_WAKE_LOCK,PARTIAL_NAME); 903 } 904 905 if (diffsource) { 906 // If the lock sources have changed, need to first release the 907 // old ones. 908 noteStopWakeLocked(wl, oldsource); 909 } 910 if (newlock || diffsource) { 911 noteStartWakeLocked(wl, ws); 912 } 913 } 914 915 public void updateWakeLockWorkSource(IBinder lock, WorkSource ws) { 916 int uid = Binder.getCallingUid(); 917 int pid = Binder.getCallingPid(); 918 if (ws != null && ws.size() == 0) { 919 ws = null; 920 } 921 if (ws != null) { 922 enforceWakeSourcePermission(uid, pid); 923 } 924 synchronized (mLocks) { 925 int index = mLocks.getIndex(lock); 926 if (index < 0) { 927 throw new IllegalArgumentException("Wake lock not active"); 928 } 929 WakeLock wl = mLocks.get(index); 930 WorkSource oldsource = wl.ws; 931 wl.ws = ws != null ? new WorkSource(ws) : null; 932 noteStopWakeLocked(wl, oldsource); 933 noteStartWakeLocked(wl, ws); 934 } 935 } 936 937 public void releaseWakeLock(IBinder lock, int flags) { 938 int uid = Binder.getCallingUid(); 939 if (uid != Process.myUid()) { 940 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null); 941 } 942 943 synchronized (mLocks) { 944 releaseWakeLockLocked(lock, flags, false); 945 } 946 } 947 948 private void releaseWakeLockLocked(IBinder lock, int flags, boolean death) { 949 WakeLock wl = mLocks.removeLock(lock); 950 if (wl == null) { 951 return; 952 } 953 954 if (mSpew) { 955 Slog.d(TAG, "releaseWakeLock flags=0x" 956 + Integer.toHexString(wl.flags) + " tag=" + wl.tag); 957 } 958 959 if (isScreenLock(wl.flags)) { 960 if ((wl.flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) { 961 mProximityWakeLockCount--; 962 if (mProximityWakeLockCount == 0) { 963 if (mProximitySensorActive && 964 ((flags & PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE) != 0)) { 965 // wait for proximity sensor to go negative before disabling sensor 966 if (mDebugProximitySensor) { 967 Slog.d(TAG, "waiting for proximity sensor to go negative"); 968 } 969 } else { 970 disableProximityLockLocked(); 971 } 972 } 973 } else { 974 mWakeLockState = mLocks.gatherState(); 975 // goes in the middle to reduce flicker 976 if ((wl.flags & PowerManager.ON_AFTER_RELEASE) != 0) { 977 userActivity(SystemClock.uptimeMillis(), -1, false, OTHER_EVENT, false); 978 } 979 setPowerState(mWakeLockState | mUserState); 980 } 981 } 982 else if ((wl.flags & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK) { 983 mPartialCount--; 984 if (mPartialCount == 0) { 985 if (LOG_PARTIAL_WL) EventLog.writeEvent(EventLogTags.POWER_PARTIAL_WAKE_STATE, 0, wl.tag); 986 Power.releaseWakeLock(PARTIAL_NAME); 987 } 988 } 989 // Unlink the lock from the binder. 990 wl.binder.unlinkToDeath(wl, 0); 991 992 noteStopWakeLocked(wl, wl.ws); 993 } 994 995 private class PokeLock implements IBinder.DeathRecipient 996 { 997 PokeLock(int p, IBinder b, String t) { 998 super(); 999 this.pokey = p; 1000 this.binder = b; 1001 this.tag = t; 1002 try { 1003 b.linkToDeath(this, 0); 1004 } catch (RemoteException e) { 1005 binderDied(); 1006 } 1007 } 1008 public void binderDied() { 1009 setPokeLock(0, this.binder, this.tag); 1010 } 1011 int pokey; 1012 IBinder binder; 1013 String tag; 1014 boolean awakeOnSet; 1015 } 1016 1017 public void setPokeLock(int pokey, IBinder token, String tag) { 1018 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); 1019 if (token == null) { 1020 Slog.e(TAG, "setPokeLock got null token for tag='" + tag + "'"); 1021 return; 1022 } 1023 1024 if ((pokey & POKE_LOCK_TIMEOUT_MASK) == POKE_LOCK_TIMEOUT_MASK) { 1025 throw new IllegalArgumentException("setPokeLock can't have both POKE_LOCK_SHORT_TIMEOUT" 1026 + " and POKE_LOCK_MEDIUM_TIMEOUT"); 1027 } 1028 1029 synchronized (mLocks) { 1030 if (pokey != 0) { 1031 PokeLock p = mPokeLocks.get(token); 1032 int oldPokey = 0; 1033 if (p != null) { 1034 oldPokey = p.pokey; 1035 p.pokey = pokey; 1036 } else { 1037 p = new PokeLock(pokey, token, tag); 1038 mPokeLocks.put(token, p); 1039 } 1040 int oldTimeout = oldPokey & POKE_LOCK_TIMEOUT_MASK; 1041 int newTimeout = pokey & POKE_LOCK_TIMEOUT_MASK; 1042 if (((mPowerState & SCREEN_ON_BIT) == 0) && (oldTimeout != newTimeout)) { 1043 p.awakeOnSet = true; 1044 } 1045 } else { 1046 PokeLock rLock = mPokeLocks.remove(token); 1047 if (rLock != null) { 1048 token.unlinkToDeath(rLock, 0); 1049 } 1050 } 1051 1052 int oldPokey = mPokey; 1053 int cumulative = 0; 1054 boolean oldAwakeOnSet = mPokeAwakeOnSet; 1055 boolean awakeOnSet = false; 1056 for (PokeLock p: mPokeLocks.values()) { 1057 cumulative |= p.pokey; 1058 if (p.awakeOnSet) { 1059 awakeOnSet = true; 1060 } 1061 } 1062 mPokey = cumulative; 1063 mPokeAwakeOnSet = awakeOnSet; 1064 1065 int oldCumulativeTimeout = oldPokey & POKE_LOCK_TIMEOUT_MASK; 1066 int newCumulativeTimeout = pokey & POKE_LOCK_TIMEOUT_MASK; 1067 1068 if (oldCumulativeTimeout != newCumulativeTimeout) { 1069 setScreenOffTimeoutsLocked(); 1070 // reset the countdown timer, but use the existing nextState so it doesn't 1071 // change anything 1072 setTimeoutLocked(SystemClock.uptimeMillis(), mTimeoutTask.nextState); 1073 } 1074 } 1075 } 1076 1077 private static String lockType(int type) 1078 { 1079 switch (type) 1080 { 1081 case PowerManager.FULL_WAKE_LOCK: 1082 return "FULL_WAKE_LOCK "; 1083 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK: 1084 return "SCREEN_BRIGHT_WAKE_LOCK "; 1085 case PowerManager.SCREEN_DIM_WAKE_LOCK: 1086 return "SCREEN_DIM_WAKE_LOCK "; 1087 case PowerManager.PARTIAL_WAKE_LOCK: 1088 return "PARTIAL_WAKE_LOCK "; 1089 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK: 1090 return "PROXIMITY_SCREEN_OFF_WAKE_LOCK"; 1091 default: 1092 return "??? "; 1093 } 1094 } 1095 1096 private static String dumpPowerState(int state) { 1097 return (((state & KEYBOARD_BRIGHT_BIT) != 0) 1098 ? "KEYBOARD_BRIGHT_BIT " : "") 1099 + (((state & SCREEN_BRIGHT_BIT) != 0) 1100 ? "SCREEN_BRIGHT_BIT " : "") 1101 + (((state & SCREEN_ON_BIT) != 0) 1102 ? "SCREEN_ON_BIT " : "") 1103 + (((state & BATTERY_LOW_BIT) != 0) 1104 ? "BATTERY_LOW_BIT " : ""); 1105 } 1106 1107 @Override 1108 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1109 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 1110 != PackageManager.PERMISSION_GRANTED) { 1111 pw.println("Permission Denial: can't dump PowerManager from from pid=" 1112 + Binder.getCallingPid() 1113 + ", uid=" + Binder.getCallingUid()); 1114 return; 1115 } 1116 1117 long now = SystemClock.uptimeMillis(); 1118 1119 synchronized (mLocks) { 1120 pw.println("Power Manager State:"); 1121 pw.println(" mIsPowered=" + mIsPowered 1122 + " mPowerState=" + mPowerState 1123 + " mScreenOffTime=" + (SystemClock.elapsedRealtime()-mScreenOffTime) 1124 + " ms"); 1125 pw.println(" mPartialCount=" + mPartialCount); 1126 pw.println(" mWakeLockState=" + dumpPowerState(mWakeLockState)); 1127 pw.println(" mUserState=" + dumpPowerState(mUserState)); 1128 pw.println(" mPowerState=" + dumpPowerState(mPowerState)); 1129 pw.println(" mLocks.gather=" + dumpPowerState(mLocks.gatherState())); 1130 pw.println(" mNextTimeout=" + mNextTimeout + " now=" + now 1131 + " " + ((mNextTimeout-now)/1000) + "s from now"); 1132 pw.println(" mDimScreen=" + mDimScreen 1133 + " mStayOnConditions=" + mStayOnConditions 1134 + " mPreparingForScreenOn=" + mPreparingForScreenOn 1135 + " mSkippedScreenOn=" + mSkippedScreenOn); 1136 pw.println(" mScreenOffReason=" + mScreenOffReason 1137 + " mUserState=" + mUserState); 1138 pw.println(" mBroadcastQueue={" + mBroadcastQueue[0] + ',' + mBroadcastQueue[1] 1139 + ',' + mBroadcastQueue[2] + "}"); 1140 pw.println(" mBroadcastWhy={" + mBroadcastWhy[0] + ',' + mBroadcastWhy[1] 1141 + ',' + mBroadcastWhy[2] + "}"); 1142 pw.println(" mPokey=" + mPokey + " mPokeAwakeonSet=" + mPokeAwakeOnSet); 1143 pw.println(" mKeyboardVisible=" + mKeyboardVisible 1144 + " mUserActivityAllowed=" + mUserActivityAllowed); 1145 pw.println(" mKeylightDelay=" + mKeylightDelay + " mDimDelay=" + mDimDelay 1146 + " mScreenOffDelay=" + mScreenOffDelay); 1147 pw.println(" mPreventScreenOn=" + mPreventScreenOn 1148 + " mScreenBrightnessOverride=" + mScreenBrightnessOverride 1149 + " mButtonBrightnessOverride=" + mButtonBrightnessOverride); 1150 pw.println(" mScreenOffTimeoutSetting=" + mScreenOffTimeoutSetting 1151 + " mMaximumScreenOffTimeout=" + mMaximumScreenOffTimeout); 1152 pw.println(" mLastScreenOnTime=" + mLastScreenOnTime); 1153 pw.println(" mBroadcastWakeLock=" + mBroadcastWakeLock); 1154 pw.println(" mStayOnWhilePluggedInScreenDimLock=" + mStayOnWhilePluggedInScreenDimLock); 1155 pw.println(" mStayOnWhilePluggedInPartialLock=" + mStayOnWhilePluggedInPartialLock); 1156 pw.println(" mPreventScreenOnPartialLock=" + mPreventScreenOnPartialLock); 1157 pw.println(" mProximityPartialLock=" + mProximityPartialLock); 1158 pw.println(" mProximityWakeLockCount=" + mProximityWakeLockCount); 1159 pw.println(" mProximitySensorEnabled=" + mProximitySensorEnabled); 1160 pw.println(" mProximitySensorActive=" + mProximitySensorActive); 1161 pw.println(" mProximityPendingValue=" + mProximityPendingValue); 1162 pw.println(" mLastProximityEventTime=" + mLastProximityEventTime); 1163 pw.println(" mLightSensorEnabled=" + mLightSensorEnabled); 1164 pw.println(" mLightSensorValue=" + mLightSensorValue 1165 + " mLightSensorPendingValue=" + mLightSensorPendingValue); 1166 pw.println(" mLightSensorPendingDecrease=" + mLightSensorPendingDecrease 1167 + " mLightSensorPendingIncrease=" + mLightSensorPendingIncrease); 1168 pw.println(" mLightSensorScreenBrightness=" + mLightSensorScreenBrightness 1169 + " mLightSensorButtonBrightness=" + mLightSensorButtonBrightness 1170 + " mLightSensorKeyboardBrightness=" + mLightSensorKeyboardBrightness); 1171 pw.println(" mUseSoftwareAutoBrightness=" + mUseSoftwareAutoBrightness); 1172 pw.println(" mAutoBrightessEnabled=" + mAutoBrightessEnabled); 1173 mScreenBrightness.dump(pw, " mScreenBrightness: "); 1174 1175 int N = mLocks.size(); 1176 pw.println(); 1177 pw.println("mLocks.size=" + N + ":"); 1178 for (int i=0; i<N; i++) { 1179 WakeLock wl = mLocks.get(i); 1180 String type = lockType(wl.flags & LOCK_MASK); 1181 String acquireCausesWakeup = ""; 1182 if ((wl.flags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) { 1183 acquireCausesWakeup = "ACQUIRE_CAUSES_WAKEUP "; 1184 } 1185 String activated = ""; 1186 if (wl.activated) { 1187 activated = " activated"; 1188 } 1189 pw.println(" " + type + " '" + wl.tag + "'" + acquireCausesWakeup 1190 + activated + " (minState=" + wl.minState + ", uid=" + wl.uid 1191 + ", pid=" + wl.pid + ")"); 1192 } 1193 1194 pw.println(); 1195 pw.println("mPokeLocks.size=" + mPokeLocks.size() + ":"); 1196 for (PokeLock p: mPokeLocks.values()) { 1197 pw.println(" poke lock '" + p.tag + "':" 1198 + ((p.pokey & POKE_LOCK_IGNORE_TOUCH_EVENTS) != 0 1199 ? " POKE_LOCK_IGNORE_TOUCH_EVENTS" : "") 1200 + ((p.pokey & POKE_LOCK_SHORT_TIMEOUT) != 0 1201 ? " POKE_LOCK_SHORT_TIMEOUT" : "") 1202 + ((p.pokey & POKE_LOCK_MEDIUM_TIMEOUT) != 0 1203 ? " POKE_LOCK_MEDIUM_TIMEOUT" : "")); 1204 } 1205 1206 pw.println(); 1207 } 1208 } 1209 1210 private void setTimeoutLocked(long now, int nextState) { 1211 setTimeoutLocked(now, -1, nextState); 1212 } 1213 1214 // If they gave a timeoutOverride it is the number of seconds 1215 // to screen-off. Figure out where in the countdown cycle we 1216 // should jump to. 1217 private void setTimeoutLocked(long now, final long originalTimeoutOverride, int nextState) { 1218 long timeoutOverride = originalTimeoutOverride; 1219 if (mBootCompleted) { 1220 synchronized (mLocks) { 1221 long when = 0; 1222 if (timeoutOverride <= 0) { 1223 switch (nextState) 1224 { 1225 case SCREEN_BRIGHT: 1226 when = now + mKeylightDelay; 1227 break; 1228 case SCREEN_DIM: 1229 if (mDimDelay >= 0) { 1230 when = now + mDimDelay; 1231 break; 1232 } else { 1233 Slog.w(TAG, "mDimDelay=" + mDimDelay + " while trying to dim"); 1234 } 1235 case SCREEN_OFF: 1236 synchronized (mLocks) { 1237 when = now + mScreenOffDelay; 1238 } 1239 break; 1240 default: 1241 when = now; 1242 break; 1243 } 1244 } else { 1245 override: { 1246 if (timeoutOverride <= mScreenOffDelay) { 1247 when = now + timeoutOverride; 1248 nextState = SCREEN_OFF; 1249 break override; 1250 } 1251 timeoutOverride -= mScreenOffDelay; 1252 1253 if (mDimDelay >= 0) { 1254 if (timeoutOverride <= mDimDelay) { 1255 when = now + timeoutOverride; 1256 nextState = SCREEN_DIM; 1257 break override; 1258 } 1259 timeoutOverride -= mDimDelay; 1260 } 1261 1262 when = now + timeoutOverride; 1263 nextState = SCREEN_BRIGHT; 1264 } 1265 } 1266 if (mSpew) { 1267 Slog.d(TAG, "setTimeoutLocked now=" + now 1268 + " timeoutOverride=" + timeoutOverride 1269 + " nextState=" + nextState + " when=" + when); 1270 } 1271 1272 mHandler.removeCallbacks(mTimeoutTask); 1273 mTimeoutTask.nextState = nextState; 1274 mTimeoutTask.remainingTimeoutOverride = timeoutOverride > 0 1275 ? (originalTimeoutOverride - timeoutOverride) 1276 : -1; 1277 mHandler.postAtTime(mTimeoutTask, when); 1278 mNextTimeout = when; // for debugging 1279 } 1280 } 1281 } 1282 1283 private void cancelTimerLocked() 1284 { 1285 mHandler.removeCallbacks(mTimeoutTask); 1286 mTimeoutTask.nextState = -1; 1287 } 1288 1289 private class TimeoutTask implements Runnable 1290 { 1291 int nextState; // access should be synchronized on mLocks 1292 long remainingTimeoutOverride; 1293 public void run() 1294 { 1295 synchronized (mLocks) { 1296 if (mSpew) { 1297 Slog.d(TAG, "user activity timeout timed out nextState=" + this.nextState); 1298 } 1299 1300 if (nextState == -1) { 1301 return; 1302 } 1303 1304 mUserState = this.nextState; 1305 setPowerState(this.nextState | mWakeLockState); 1306 1307 long now = SystemClock.uptimeMillis(); 1308 1309 switch (this.nextState) 1310 { 1311 case SCREEN_BRIGHT: 1312 if (mDimDelay >= 0) { 1313 setTimeoutLocked(now, remainingTimeoutOverride, SCREEN_DIM); 1314 break; 1315 } 1316 case SCREEN_DIM: 1317 setTimeoutLocked(now, remainingTimeoutOverride, SCREEN_OFF); 1318 break; 1319 } 1320 } 1321 } 1322 } 1323 1324 private void sendNotificationLocked(boolean on, int why) { 1325 if (!mInitialized) { 1326 // No notifications sent until first initialization is done. 1327 // This is so that when we are moving from our initial state 1328 // which looks like the screen was off to it being on, we do not 1329 // go through the process of waiting for the higher-level user 1330 // space to be ready before turning up the display brightness. 1331 // (And also do not send needless broadcasts about the screen.) 1332 return; 1333 } 1334 1335 if (DEBUG_SCREEN_ON) { 1336 RuntimeException here = new RuntimeException("here"); 1337 here.fillInStackTrace(); 1338 Slog.i(TAG, "sendNotificationLocked: " + on, here); 1339 } 1340 1341 if (!on) { 1342 mStillNeedSleepNotification = false; 1343 } 1344 1345 // Add to the queue. 1346 int index = 0; 1347 while (mBroadcastQueue[index] != -1) { 1348 index++; 1349 } 1350 mBroadcastQueue[index] = on ? 1 : 0; 1351 mBroadcastWhy[index] = why; 1352 1353 // If we added it position 2, then there is a pair that can be stripped. 1354 // If we added it position 1 and we're turning the screen off, we can strip 1355 // the pair and do nothing, because the screen is already off, and therefore 1356 // keyguard has already been enabled. 1357 // However, if we added it at position 1 and we're turning it on, then position 1358 // 0 was to turn it off, and we can't strip that, because keyguard needs to come 1359 // on, so have to run the queue then. 1360 if (index == 2) { 1361 // While we're collapsing them, if it's going off, and the new reason 1362 // is more significant than the first, then use the new one. 1363 if (!on && mBroadcastWhy[0] > why) { 1364 mBroadcastWhy[0] = why; 1365 } 1366 mBroadcastQueue[0] = on ? 1 : 0; 1367 mBroadcastQueue[1] = -1; 1368 mBroadcastQueue[2] = -1; 1369 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount); 1370 mBroadcastWakeLock.release(); 1371 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount); 1372 mBroadcastWakeLock.release(); 1373 index = 0; 1374 } 1375 if (index == 1 && !on) { 1376 mBroadcastQueue[0] = -1; 1377 mBroadcastQueue[1] = -1; 1378 index = -1; 1379 // The wake lock was being held, but we're not actually going to do any 1380 // broadcasts, so release the wake lock. 1381 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount); 1382 mBroadcastWakeLock.release(); 1383 } 1384 1385 // The broadcast queue has changed; make sure the screen is on if it 1386 // is now possible for it to be. 1387 if (mSkippedScreenOn) { 1388 updateLightsLocked(mPowerState, SCREEN_ON_BIT); 1389 } 1390 1391 // Now send the message. 1392 if (index >= 0) { 1393 // Acquire the broadcast wake lock before changing the power 1394 // state. It will be release after the broadcast is sent. 1395 // We always increment the ref count for each notification in the queue 1396 // and always decrement when that notification is handled. 1397 mBroadcastWakeLock.acquire(); 1398 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND, mBroadcastWakeLock.mCount); 1399 mHandler.post(mNotificationTask); 1400 } 1401 } 1402 1403 private WindowManagerPolicy.ScreenOnListener mScreenOnListener = 1404 new WindowManagerPolicy.ScreenOnListener() { 1405 @Override public void onScreenOn() { 1406 synchronized (mLocks) { 1407 if (mPreparingForScreenOn) { 1408 mPreparingForScreenOn = false; 1409 updateLightsLocked(mPowerState, SCREEN_ON_BIT); 1410 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1411 4, mBroadcastWakeLock.mCount); 1412 mBroadcastWakeLock.release(); 1413 } 1414 } 1415 } 1416 }; 1417 1418 private Runnable mNotificationTask = new Runnable() 1419 { 1420 public void run() 1421 { 1422 while (true) { 1423 int value; 1424 int why; 1425 WindowManagerPolicy policy; 1426 synchronized (mLocks) { 1427 value = mBroadcastQueue[0]; 1428 why = mBroadcastWhy[0]; 1429 for (int i=0; i<2; i++) { 1430 mBroadcastQueue[i] = mBroadcastQueue[i+1]; 1431 mBroadcastWhy[i] = mBroadcastWhy[i+1]; 1432 } 1433 policy = getPolicyLocked(); 1434 if (value == 1 && !mPreparingForScreenOn) { 1435 mPreparingForScreenOn = true; 1436 mBroadcastWakeLock.acquire(); 1437 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND, 1438 mBroadcastWakeLock.mCount); 1439 } 1440 } 1441 if (value == 1) { 1442 mScreenOnStart = SystemClock.uptimeMillis(); 1443 1444 policy.screenTurningOn(mScreenOnListener); 1445 try { 1446 ActivityManagerNative.getDefault().wakingUp(); 1447 } catch (RemoteException e) { 1448 // ignore it 1449 } 1450 1451 if (mSpew) { 1452 Slog.d(TAG, "mBroadcastWakeLock=" + mBroadcastWakeLock); 1453 } 1454 if (mContext != null && ActivityManagerNative.isSystemReady()) { 1455 mContext.sendOrderedBroadcast(mScreenOnIntent, null, 1456 mScreenOnBroadcastDone, mHandler, 0, null, null); 1457 } else { 1458 synchronized (mLocks) { 1459 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 2, 1460 mBroadcastWakeLock.mCount); 1461 mBroadcastWakeLock.release(); 1462 } 1463 } 1464 } 1465 else if (value == 0) { 1466 mScreenOffStart = SystemClock.uptimeMillis(); 1467 1468 policy.screenTurnedOff(why); 1469 try { 1470 ActivityManagerNative.getDefault().goingToSleep(); 1471 } catch (RemoteException e) { 1472 // ignore it. 1473 } 1474 1475 if (mContext != null && ActivityManagerNative.isSystemReady()) { 1476 mContext.sendOrderedBroadcast(mScreenOffIntent, null, 1477 mScreenOffBroadcastDone, mHandler, 0, null, null); 1478 } else { 1479 synchronized (mLocks) { 1480 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 3, 1481 mBroadcastWakeLock.mCount); 1482 updateLightsLocked(mPowerState, SCREEN_ON_BIT); 1483 mBroadcastWakeLock.release(); 1484 } 1485 } 1486 } 1487 else { 1488 // If we're in this case, then this handler is running for a previous 1489 // paired transaction. mBroadcastWakeLock will already have been released. 1490 break; 1491 } 1492 } 1493 } 1494 }; 1495 1496 long mScreenOnStart; 1497 private BroadcastReceiver mScreenOnBroadcastDone = new BroadcastReceiver() { 1498 public void onReceive(Context context, Intent intent) { 1499 synchronized (mLocks) { 1500 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 1, 1501 SystemClock.uptimeMillis() - mScreenOnStart, mBroadcastWakeLock.mCount); 1502 mBroadcastWakeLock.release(); 1503 } 1504 } 1505 }; 1506 1507 long mScreenOffStart; 1508 private BroadcastReceiver mScreenOffBroadcastDone = new BroadcastReceiver() { 1509 public void onReceive(Context context, Intent intent) { 1510 synchronized (mLocks) { 1511 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 0, 1512 SystemClock.uptimeMillis() - mScreenOffStart, mBroadcastWakeLock.mCount); 1513 mBroadcastWakeLock.release(); 1514 } 1515 } 1516 }; 1517 1518 void logPointerUpEvent() { 1519 if (LOG_TOUCH_DOWNS) { 1520 mTotalTouchDownTime += SystemClock.elapsedRealtime() - mLastTouchDown; 1521 mLastTouchDown = 0; 1522 } 1523 } 1524 1525 void logPointerDownEvent() { 1526 if (LOG_TOUCH_DOWNS) { 1527 // If we are not already timing a down/up sequence 1528 if (mLastTouchDown == 0) { 1529 mLastTouchDown = SystemClock.elapsedRealtime(); 1530 mTouchCycles++; 1531 } 1532 } 1533 } 1534 1535 /** 1536 * Prevents the screen from turning on even if it *should* turn on due 1537 * to a subsequent full wake lock being acquired. 1538 * <p> 1539 * This is a temporary hack that allows an activity to "cover up" any 1540 * display glitches that happen during the activity's startup 1541 * sequence. (Specifically, this API was added to work around a 1542 * cosmetic bug in the "incoming call" sequence, where the lock screen 1543 * would flicker briefly before the incoming call UI became visible.) 1544 * TODO: There ought to be a more elegant way of doing this, 1545 * probably by having the PowerManager and ActivityManager 1546 * work together to let apps specify that the screen on/off 1547 * state should be synchronized with the Activity lifecycle. 1548 * <p> 1549 * Note that calling preventScreenOn(true) will NOT turn the screen 1550 * off if it's currently on. (This API only affects *future* 1551 * acquisitions of full wake locks.) 1552 * But calling preventScreenOn(false) WILL turn the screen on if 1553 * it's currently off because of a prior preventScreenOn(true) call. 1554 * <p> 1555 * Any call to preventScreenOn(true) MUST be followed promptly by a call 1556 * to preventScreenOn(false). In fact, if the preventScreenOn(false) 1557 * call doesn't occur within 5 seconds, we'll turn the screen back on 1558 * ourselves (and log a warning about it); this prevents a buggy app 1559 * from disabling the screen forever.) 1560 * <p> 1561 * TODO: this feature should really be controlled by a new type of poke 1562 * lock (rather than an IPowerManager call). 1563 */ 1564 public void preventScreenOn(boolean prevent) { 1565 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); 1566 1567 synchronized (mLocks) { 1568 if (prevent) { 1569 // First of all, grab a partial wake lock to 1570 // make sure the CPU stays on during the entire 1571 // preventScreenOn(true) -> preventScreenOn(false) sequence. 1572 mPreventScreenOnPartialLock.acquire(); 1573 1574 // Post a forceReenableScreen() call (for 5 seconds in the 1575 // future) to make sure the matching preventScreenOn(false) call 1576 // has happened by then. 1577 mHandler.removeCallbacks(mForceReenableScreenTask); 1578 mHandler.postDelayed(mForceReenableScreenTask, 5000); 1579 1580 // Finally, set the flag that prevents the screen from turning on. 1581 // (Below, in setPowerState(), we'll check mPreventScreenOn and 1582 // we *won't* call setScreenStateLocked(true) if it's set.) 1583 mPreventScreenOn = true; 1584 } else { 1585 // (Re)enable the screen. 1586 mPreventScreenOn = false; 1587 1588 // We're "undoing" a the prior preventScreenOn(true) call, so we 1589 // no longer need the 5-second safeguard. 1590 mHandler.removeCallbacks(mForceReenableScreenTask); 1591 1592 // Forcibly turn on the screen if it's supposed to be on. (This 1593 // handles the case where the screen is currently off because of 1594 // a prior preventScreenOn(true) call.) 1595 if (!mProximitySensorActive && (mPowerState & SCREEN_ON_BIT) != 0) { 1596 if (mSpew) { 1597 Slog.d(TAG, 1598 "preventScreenOn: turning on after a prior preventScreenOn(true)!"); 1599 } 1600 int err = setScreenStateLocked(true); 1601 if (err != 0) { 1602 Slog.w(TAG, "preventScreenOn: error from setScreenStateLocked(): " + err); 1603 } 1604 } 1605 1606 // Release the partial wake lock that we held during the 1607 // preventScreenOn(true) -> preventScreenOn(false) sequence. 1608 mPreventScreenOnPartialLock.release(); 1609 } 1610 } 1611 } 1612 1613 public void setScreenBrightnessOverride(int brightness) { 1614 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); 1615 1616 if (mSpew) Slog.d(TAG, "setScreenBrightnessOverride " + brightness); 1617 synchronized (mLocks) { 1618 if (mScreenBrightnessOverride != brightness) { 1619 mScreenBrightnessOverride = brightness; 1620 if (isScreenOn()) { 1621 updateLightsLocked(mPowerState, SCREEN_ON_BIT); 1622 } 1623 } 1624 } 1625 } 1626 1627 public void setButtonBrightnessOverride(int brightness) { 1628 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); 1629 1630 if (mSpew) Slog.d(TAG, "setButtonBrightnessOverride " + brightness); 1631 synchronized (mLocks) { 1632 if (mButtonBrightnessOverride != brightness) { 1633 mButtonBrightnessOverride = brightness; 1634 if (isScreenOn()) { 1635 updateLightsLocked(mPowerState, BUTTON_BRIGHT_BIT | KEYBOARD_BRIGHT_BIT); 1636 } 1637 } 1638 } 1639 } 1640 1641 /** 1642 * Sanity-check that gets called 5 seconds after any call to 1643 * preventScreenOn(true). This ensures that the original call 1644 * is followed promptly by a call to preventScreenOn(false). 1645 */ 1646 private void forceReenableScreen() { 1647 // We shouldn't get here at all if mPreventScreenOn is false, since 1648 // we should have already removed any existing 1649 // mForceReenableScreenTask messages... 1650 if (!mPreventScreenOn) { 1651 Slog.w(TAG, "forceReenableScreen: mPreventScreenOn is false, nothing to do"); 1652 return; 1653 } 1654 1655 // Uh oh. It's been 5 seconds since a call to 1656 // preventScreenOn(true) and we haven't re-enabled the screen yet. 1657 // This means the app that called preventScreenOn(true) is either 1658 // slow (i.e. it took more than 5 seconds to call preventScreenOn(false)), 1659 // or buggy (i.e. it forgot to call preventScreenOn(false), or 1660 // crashed before doing so.) 1661 1662 // Log a warning, and forcibly turn the screen back on. 1663 Slog.w(TAG, "App called preventScreenOn(true) but didn't promptly reenable the screen! " 1664 + "Forcing the screen back on..."); 1665 preventScreenOn(false); 1666 } 1667 1668 private Runnable mForceReenableScreenTask = new Runnable() { 1669 public void run() { 1670 forceReenableScreen(); 1671 } 1672 }; 1673 1674 private int setScreenStateLocked(boolean on) { 1675 if (DEBUG_SCREEN_ON) { 1676 RuntimeException e = new RuntimeException("here"); 1677 e.fillInStackTrace(); 1678 Slog.i(TAG, "Set screen state: " + on, e); 1679 } 1680 if (on) { 1681 if ((mPowerState & SCREEN_ON_BIT) == 0 || mSkippedScreenOn) { 1682 // If we are turning the screen state on, but the screen 1683 // light is currently off, then make sure that we set the 1684 // light at this point to 0. This is the case where we are 1685 // turning on the screen and waiting for the UI to be drawn 1686 // before showing it to the user. We want the light off 1687 // until it is ready to be shown to the user, not it using 1688 // whatever the last value it had. 1689 mScreenBrightness.forceValueLocked(Power.BRIGHTNESS_OFF); 1690 } 1691 } 1692 int err = Power.setScreenState(on); 1693 if (err == 0) { 1694 mLastScreenOnTime = (on ? SystemClock.elapsedRealtime() : 0); 1695 if (mUseSoftwareAutoBrightness) { 1696 enableLightSensorLocked(on); 1697 if (!on) { 1698 // make sure button and key backlights are off too 1699 mButtonLight.turnOff(); 1700 mKeyboardLight.turnOff(); 1701 // clear current value so we will update based on the new conditions 1702 // when the sensor is reenabled. 1703 mLightSensorValue = -1; 1704 // reset our highest light sensor value when the screen turns off 1705 mHighestLightSensorValue = -1; 1706 } 1707 } 1708 } 1709 return err; 1710 } 1711 1712 private void setPowerState(int state) 1713 { 1714 setPowerState(state, false, WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT); 1715 } 1716 1717 private void setPowerState(int newState, boolean noChangeLights, int reason) 1718 { 1719 synchronized (mLocks) { 1720 int err; 1721 1722 if (mSpew) { 1723 Slog.d(TAG, "setPowerState: mPowerState=0x" + Integer.toHexString(mPowerState) 1724 + " newState=0x" + Integer.toHexString(newState) 1725 + " noChangeLights=" + noChangeLights 1726 + " reason=" + reason); 1727 } 1728 1729 if (noChangeLights) { 1730 newState = (newState & ~LIGHTS_MASK) | (mPowerState & LIGHTS_MASK); 1731 } 1732 if (mProximitySensorActive) { 1733 // don't turn on the screen when the proximity sensor lock is held 1734 newState = (newState & ~SCREEN_BRIGHT); 1735 } 1736 1737 if (batteryIsLow()) { 1738 newState |= BATTERY_LOW_BIT; 1739 } else { 1740 newState &= ~BATTERY_LOW_BIT; 1741 } 1742 if (newState == mPowerState && mInitialized) { 1743 return; 1744 } 1745 1746 if (!mBootCompleted && !mUseSoftwareAutoBrightness) { 1747 newState |= ALL_BRIGHT; 1748 } 1749 1750 boolean oldScreenOn = (mPowerState & SCREEN_ON_BIT) != 0; 1751 boolean newScreenOn = (newState & SCREEN_ON_BIT) != 0; 1752 1753 if (mSpew) { 1754 Slog.d(TAG, "setPowerState: mPowerState=" + mPowerState 1755 + " newState=" + newState + " noChangeLights=" + noChangeLights); 1756 Slog.d(TAG, " oldKeyboardBright=" + ((mPowerState & KEYBOARD_BRIGHT_BIT) != 0) 1757 + " newKeyboardBright=" + ((newState & KEYBOARD_BRIGHT_BIT) != 0)); 1758 Slog.d(TAG, " oldScreenBright=" + ((mPowerState & SCREEN_BRIGHT_BIT) != 0) 1759 + " newScreenBright=" + ((newState & SCREEN_BRIGHT_BIT) != 0)); 1760 Slog.d(TAG, " oldButtonBright=" + ((mPowerState & BUTTON_BRIGHT_BIT) != 0) 1761 + " newButtonBright=" + ((newState & BUTTON_BRIGHT_BIT) != 0)); 1762 Slog.d(TAG, " oldScreenOn=" + oldScreenOn 1763 + " newScreenOn=" + newScreenOn); 1764 Slog.d(TAG, " oldBatteryLow=" + ((mPowerState & BATTERY_LOW_BIT) != 0) 1765 + " newBatteryLow=" + ((newState & BATTERY_LOW_BIT) != 0)); 1766 } 1767 1768 final boolean stateChanged = mPowerState != newState; 1769 1770 if (oldScreenOn != newScreenOn) { 1771 if (newScreenOn) { 1772 // When the user presses the power button, we need to always send out the 1773 // notification that it's going to sleep so the keyguard goes on. But 1774 // we can't do that until the screen fades out, so we don't show the keyguard 1775 // too early. 1776 if (mStillNeedSleepNotification) { 1777 sendNotificationLocked(false, WindowManagerPolicy.OFF_BECAUSE_OF_USER); 1778 } 1779 1780 // Turn on the screen UNLESS there was a prior 1781 // preventScreenOn(true) request. (Note that the lifetime 1782 // of a single preventScreenOn() request is limited to 5 1783 // seconds to prevent a buggy app from disabling the 1784 // screen forever; see forceReenableScreen().) 1785 boolean reallyTurnScreenOn = true; 1786 if (mSpew) { 1787 Slog.d(TAG, "- turning screen on... mPreventScreenOn = " 1788 + mPreventScreenOn); 1789 } 1790 1791 if (mPreventScreenOn) { 1792 if (mSpew) { 1793 Slog.d(TAG, "- PREVENTING screen from really turning on!"); 1794 } 1795 reallyTurnScreenOn = false; 1796 } 1797 if (reallyTurnScreenOn) { 1798 err = setScreenStateLocked(true); 1799 long identity = Binder.clearCallingIdentity(); 1800 try { 1801 mBatteryStats.noteScreenBrightness(getPreferredBrightness()); 1802 mBatteryStats.noteScreenOn(); 1803 } catch (RemoteException e) { 1804 Slog.w(TAG, "RemoteException calling noteScreenOn on BatteryStatsService", e); 1805 } finally { 1806 Binder.restoreCallingIdentity(identity); 1807 } 1808 } else { 1809 setScreenStateLocked(false); 1810 // But continue as if we really did turn the screen on... 1811 err = 0; 1812 } 1813 1814 mLastTouchDown = 0; 1815 mTotalTouchDownTime = 0; 1816 mTouchCycles = 0; 1817 EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, reason, 1818 mTotalTouchDownTime, mTouchCycles); 1819 if (err == 0) { 1820 sendNotificationLocked(true, -1); 1821 // Update the lights *after* taking care of turning the 1822 // screen on, so we do this after our notifications are 1823 // enqueued and thus will delay turning on the screen light 1824 // until the windows are correctly displayed. 1825 if (stateChanged) { 1826 updateLightsLocked(newState, 0); 1827 } 1828 mPowerState |= SCREEN_ON_BIT; 1829 } 1830 1831 } else { 1832 // Update the lights *before* taking care of turning the 1833 // screen off, so we can initiate any animations that are desired. 1834 if (stateChanged) { 1835 updateLightsLocked(newState, 0); 1836 } 1837 1838 // cancel light sensor task 1839 mHandler.removeCallbacks(mAutoBrightnessTask); 1840 mLightSensorPendingDecrease = false; 1841 mLightSensorPendingIncrease = false; 1842 mScreenOffTime = SystemClock.elapsedRealtime(); 1843 long identity = Binder.clearCallingIdentity(); 1844 try { 1845 mBatteryStats.noteScreenOff(); 1846 } catch (RemoteException e) { 1847 Slog.w(TAG, "RemoteException calling noteScreenOff on BatteryStatsService", e); 1848 } finally { 1849 Binder.restoreCallingIdentity(identity); 1850 } 1851 mPowerState &= ~SCREEN_ON_BIT; 1852 mScreenOffReason = reason; 1853 if (!mScreenBrightness.animating) { 1854 err = screenOffFinishedAnimatingLocked(reason); 1855 } else { 1856 err = 0; 1857 mLastTouchDown = 0; 1858 } 1859 } 1860 } else if (stateChanged) { 1861 // Screen on/off didn't change, but lights may have. 1862 updateLightsLocked(newState, 0); 1863 } 1864 1865 mPowerState = (mPowerState & ~LIGHTS_MASK) | (newState & LIGHTS_MASK); 1866 1867 updateNativePowerStateLocked(); 1868 } 1869 } 1870 1871 private void updateNativePowerStateLocked() { 1872 nativeSetPowerState( 1873 (mPowerState & SCREEN_ON_BIT) != 0, 1874 (mPowerState & SCREEN_BRIGHT) == SCREEN_BRIGHT); 1875 } 1876 1877 private int screenOffFinishedAnimatingLocked(int reason) { 1878 // I don't think we need to check the current state here because all of these 1879 // Power.setScreenState and sendNotificationLocked can both handle being 1880 // called multiple times in the same state. -joeo 1881 EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, reason, mTotalTouchDownTime, 1882 mTouchCycles); 1883 mLastTouchDown = 0; 1884 int err = setScreenStateLocked(false); 1885 if (err == 0) { 1886 mScreenOffReason = reason; 1887 sendNotificationLocked(false, reason); 1888 } 1889 return err; 1890 } 1891 1892 private boolean batteryIsLow() { 1893 return (!mIsPowered && 1894 mBatteryService.getBatteryLevel() <= Power.LOW_BATTERY_THRESHOLD); 1895 } 1896 1897 private boolean shouldDeferScreenOnLocked() { 1898 if (mPreparingForScreenOn) { 1899 // Currently waiting for confirmation from the policy that it 1900 // is okay to turn on the screen. Don't allow the screen to go 1901 // on until that is done. 1902 if (DEBUG_SCREEN_ON) Slog.i(TAG, 1903 "updateLights: delaying screen on due to mPreparingForScreenOn"); 1904 return true; 1905 } else { 1906 // If there is a screen-on command in the notification queue, we 1907 // can't turn the screen on until it has been processed (and we 1908 // have set mPreparingForScreenOn) or it has been dropped. 1909 for (int i=0; i<mBroadcastQueue.length; i++) { 1910 if (mBroadcastQueue[i] == 1) { 1911 if (DEBUG_SCREEN_ON) Slog.i(TAG, 1912 "updateLights: delaying screen on due to notification queue"); 1913 return true; 1914 } 1915 } 1916 } 1917 return false; 1918 } 1919 1920 private void updateLightsLocked(int newState, int forceState) { 1921 final int oldState = mPowerState; 1922 1923 // If the screen is not currently on, we will want to delay actually 1924 // turning the lights on if we are still getting the UI put up. 1925 if ((oldState&SCREEN_ON_BIT) == 0 || mSkippedScreenOn) { 1926 // Don't turn screen on until we know we are really ready to. 1927 // This is to avoid letting the screen go on before things like the 1928 // lock screen have been displayed. 1929 if ((mSkippedScreenOn=shouldDeferScreenOnLocked())) { 1930 newState &= ~(SCREEN_ON_BIT|SCREEN_BRIGHT_BIT); 1931 } 1932 } 1933 1934 if ((newState & SCREEN_ON_BIT) != 0) { 1935 // Only turn on the buttons or keyboard if the screen is also on. 1936 // We should never see the buttons on but not the screen. 1937 newState = applyButtonState(newState); 1938 newState = applyKeyboardState(newState); 1939 } 1940 final int realDifference = (newState ^ oldState); 1941 final int difference = realDifference | forceState; 1942 if (difference == 0) { 1943 return; 1944 } 1945 1946 int offMask = 0; 1947 int dimMask = 0; 1948 int onMask = 0; 1949 1950 int preferredBrightness = getPreferredBrightness(); 1951 1952 if ((difference & KEYBOARD_BRIGHT_BIT) != 0) { 1953 if ((newState & KEYBOARD_BRIGHT_BIT) == 0) { 1954 offMask |= KEYBOARD_BRIGHT_BIT; 1955 } else { 1956 onMask |= KEYBOARD_BRIGHT_BIT; 1957 } 1958 } 1959 1960 if ((difference & BUTTON_BRIGHT_BIT) != 0) { 1961 if ((newState & BUTTON_BRIGHT_BIT) == 0) { 1962 offMask |= BUTTON_BRIGHT_BIT; 1963 } else { 1964 onMask |= BUTTON_BRIGHT_BIT; 1965 } 1966 } 1967 1968 if ((difference & (SCREEN_ON_BIT | SCREEN_BRIGHT_BIT)) != 0) { 1969 int nominalCurrentValue = -1; 1970 // If there was an actual difference in the light state, then 1971 // figure out the "ideal" current value based on the previous 1972 // state. Otherwise, this is a change due to the brightness 1973 // override, so we want to animate from whatever the current 1974 // value is. 1975 if ((realDifference & (SCREEN_ON_BIT | SCREEN_BRIGHT_BIT)) != 0) { 1976 switch (oldState & (SCREEN_BRIGHT_BIT|SCREEN_ON_BIT)) { 1977 case SCREEN_BRIGHT_BIT | SCREEN_ON_BIT: 1978 nominalCurrentValue = preferredBrightness; 1979 break; 1980 case SCREEN_ON_BIT: 1981 nominalCurrentValue = mScreenBrightnessDim; 1982 break; 1983 case 0: 1984 nominalCurrentValue = Power.BRIGHTNESS_OFF; 1985 break; 1986 case SCREEN_BRIGHT_BIT: 1987 default: 1988 // not possible 1989 nominalCurrentValue = (int)mScreenBrightness.curValue; 1990 break; 1991 } 1992 } 1993 int brightness = preferredBrightness; 1994 int steps = ANIM_STEPS; 1995 if ((newState & SCREEN_BRIGHT_BIT) == 0) { 1996 // dim or turn off backlight, depending on if the screen is on 1997 // the scale is because the brightness ramp isn't linear and this biases 1998 // it so the later parts take longer. 1999 final float scale = 1.5f; 2000 float ratio = (((float)mScreenBrightnessDim)/preferredBrightness); 2001 if (ratio > 1.0f) ratio = 1.0f; 2002 if ((newState & SCREEN_ON_BIT) == 0) { 2003 if ((oldState & SCREEN_BRIGHT_BIT) != 0) { 2004 // was bright 2005 steps = ANIM_STEPS; 2006 } else { 2007 // was dim 2008 steps = (int)(ANIM_STEPS*ratio*scale); 2009 } 2010 brightness = Power.BRIGHTNESS_OFF; 2011 } else { 2012 if ((oldState & SCREEN_ON_BIT) != 0) { 2013 // was bright 2014 steps = (int)(ANIM_STEPS*(1.0f-ratio)*scale); 2015 } else { 2016 // was dim 2017 steps = (int)(ANIM_STEPS*ratio); 2018 } 2019 if (mStayOnConditions != 0 && mBatteryService.isPowered(mStayOnConditions)) { 2020 // If the "stay on while plugged in" option is 2021 // turned on, then the screen will often not 2022 // automatically turn off while plugged in. To 2023 // still have a sense of when it is inactive, we 2024 // will then count going dim as turning off. 2025 mScreenOffTime = SystemClock.elapsedRealtime(); 2026 } 2027 brightness = mScreenBrightnessDim; 2028 } 2029 } 2030 long identity = Binder.clearCallingIdentity(); 2031 try { 2032 mBatteryStats.noteScreenBrightness(brightness); 2033 } catch (RemoteException e) { 2034 // Nothing interesting to do. 2035 } finally { 2036 Binder.restoreCallingIdentity(identity); 2037 } 2038 mScreenBrightness.setTargetLocked(brightness, steps, 2039 INITIAL_SCREEN_BRIGHTNESS, nominalCurrentValue); 2040 if (DEBUG_SCREEN_ON) { 2041 RuntimeException e = new RuntimeException("here"); 2042 e.fillInStackTrace(); 2043 Slog.i(TAG, "Setting screen brightness: " + brightness, e); 2044 } 2045 } 2046 2047 if (mSpew) { 2048 Slog.d(TAG, "offMask=0x" + Integer.toHexString(offMask) 2049 + " dimMask=0x" + Integer.toHexString(dimMask) 2050 + " onMask=0x" + Integer.toHexString(onMask) 2051 + " difference=0x" + Integer.toHexString(difference) 2052 + " realDifference=0x" + Integer.toHexString(realDifference) 2053 + " forceState=0x" + Integer.toHexString(forceState) 2054 ); 2055 } 2056 2057 if (offMask != 0) { 2058 if (mSpew) Slog.i(TAG, "Setting brightess off: " + offMask); 2059 setLightBrightness(offMask, Power.BRIGHTNESS_OFF); 2060 } 2061 if (dimMask != 0) { 2062 int brightness = mScreenBrightnessDim; 2063 if ((newState & BATTERY_LOW_BIT) != 0 && 2064 brightness > Power.BRIGHTNESS_LOW_BATTERY) { 2065 brightness = Power.BRIGHTNESS_LOW_BATTERY; 2066 } 2067 if (mSpew) Slog.i(TAG, "Setting brightess dim " + brightness + ": " + dimMask); 2068 setLightBrightness(dimMask, brightness); 2069 } 2070 if (onMask != 0) { 2071 int brightness = getPreferredBrightness(); 2072 if ((newState & BATTERY_LOW_BIT) != 0 && 2073 brightness > Power.BRIGHTNESS_LOW_BATTERY) { 2074 brightness = Power.BRIGHTNESS_LOW_BATTERY; 2075 } 2076 if (mSpew) Slog.i(TAG, "Setting brightess on " + brightness + ": " + onMask); 2077 setLightBrightness(onMask, brightness); 2078 } 2079 } 2080 2081 private void setLightBrightness(int mask, int value) { 2082 int brightnessMode = (mAutoBrightessEnabled 2083 ? LightsService.BRIGHTNESS_MODE_SENSOR 2084 : LightsService.BRIGHTNESS_MODE_USER); 2085 if ((mask & SCREEN_BRIGHT_BIT) != 0) { 2086 mLcdLight.setBrightness(value, brightnessMode); 2087 } 2088 if ((mask & BUTTON_BRIGHT_BIT) != 0) { 2089 mButtonLight.setBrightness(value); 2090 } 2091 if ((mask & KEYBOARD_BRIGHT_BIT) != 0) { 2092 mKeyboardLight.setBrightness(value); 2093 } 2094 } 2095 2096 class BrightnessState implements Runnable { 2097 final int mask; 2098 2099 boolean initialized; 2100 int targetValue; 2101 float curValue; 2102 float delta; 2103 boolean animating; 2104 2105 BrightnessState(int m) { 2106 mask = m; 2107 } 2108 2109 public void dump(PrintWriter pw, String prefix) { 2110 pw.println(prefix + "animating=" + animating 2111 + " targetValue=" + targetValue 2112 + " curValue=" + curValue 2113 + " delta=" + delta); 2114 } 2115 2116 void forceValueLocked(int value) { 2117 targetValue = -1; 2118 curValue = value; 2119 setLightBrightness(mask, value); 2120 if (animating) { 2121 finishAnimationLocked(false, value); 2122 } 2123 } 2124 2125 void setTargetLocked(int target, int stepsToTarget, int initialValue, 2126 int nominalCurrentValue) { 2127 if (!initialized) { 2128 initialized = true; 2129 curValue = (float)initialValue; 2130 } else if (targetValue == target) { 2131 return; 2132 } 2133 targetValue = target; 2134 delta = (targetValue - 2135 (nominalCurrentValue >= 0 ? nominalCurrentValue : curValue)) 2136 / stepsToTarget; 2137 if (mSpew) { 2138 String noticeMe = nominalCurrentValue == curValue ? "" : " ******************"; 2139 Slog.i(TAG, "setTargetLocked mask=" + mask + " curValue=" + curValue 2140 + " target=" + target + " targetValue=" + targetValue + " delta=" + delta 2141 + " nominalCurrentValue=" + nominalCurrentValue 2142 + noticeMe); 2143 } 2144 animating = true; 2145 2146 if (mSpew) { 2147 Slog.i(TAG, "scheduling light animator"); 2148 } 2149 mScreenOffHandler.removeCallbacks(this); 2150 mScreenOffHandler.post(this); 2151 } 2152 2153 boolean stepLocked() { 2154 if (!animating) return false; 2155 if (false && mSpew) { 2156 Slog.i(TAG, "Step target " + mask + ": cur=" + curValue 2157 + " target=" + targetValue + " delta=" + delta); 2158 } 2159 curValue += delta; 2160 int curIntValue = (int)curValue; 2161 boolean more = true; 2162 if (delta == 0) { 2163 curValue = curIntValue = targetValue; 2164 more = false; 2165 } else if (delta > 0) { 2166 if (curIntValue >= targetValue) { 2167 curValue = curIntValue = targetValue; 2168 more = false; 2169 } 2170 } else { 2171 if (curIntValue <= targetValue) { 2172 curValue = curIntValue = targetValue; 2173 more = false; 2174 } 2175 } 2176 if (mSpew) Slog.d(TAG, "Animating curIntValue=" + curIntValue + ": " + mask); 2177 setLightBrightness(mask, curIntValue); 2178 finishAnimationLocked(more, curIntValue); 2179 return more; 2180 } 2181 2182 void jumpToTargetLocked() { 2183 if (mSpew) Slog.d(TAG, "jumpToTargetLocked targetValue=" + targetValue + ": " + mask); 2184 setLightBrightness(mask, targetValue); 2185 final int tv = targetValue; 2186 curValue = tv; 2187 targetValue = -1; 2188 finishAnimationLocked(false, tv); 2189 } 2190 2191 private void finishAnimationLocked(boolean more, int curIntValue) { 2192 animating = more; 2193 if (!more) { 2194 if (mask == SCREEN_BRIGHT_BIT && curIntValue == Power.BRIGHTNESS_OFF) { 2195 screenOffFinishedAnimatingLocked(mScreenOffReason); 2196 } 2197 } 2198 } 2199 2200 public void run() { 2201 if (mAnimateScreenLights) { 2202 synchronized (mLocks) { 2203 long now = SystemClock.uptimeMillis(); 2204 boolean more = mScreenBrightness.stepLocked(); 2205 if (more) { 2206 mScreenOffHandler.postAtTime(this, now+(1000/60)); 2207 } 2208 } 2209 } else { 2210 synchronized (mLocks) { 2211 // we're turning off 2212 final boolean animate = animating && targetValue == Power.BRIGHTNESS_OFF; 2213 if (animate) { 2214 // It's pretty scary to hold mLocks for this long, and we should 2215 // redesign this, but it works for now. 2216 nativeStartSurfaceFlingerAnimation( 2217 mScreenOffReason == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR 2218 ? 0 : mAnimationSetting); 2219 } 2220 mScreenBrightness.jumpToTargetLocked(); 2221 } 2222 } 2223 } 2224 } 2225 2226 private int getPreferredBrightness() { 2227 try { 2228 if (mScreenBrightnessOverride >= 0) { 2229 return mScreenBrightnessOverride; 2230 } else if (mLightSensorScreenBrightness >= 0 && mUseSoftwareAutoBrightness 2231 && mAutoBrightessEnabled) { 2232 return mLightSensorScreenBrightness; 2233 } 2234 final int brightness = Settings.System.getInt(mContext.getContentResolver(), 2235 SCREEN_BRIGHTNESS); 2236 // Don't let applications turn the screen all the way off 2237 return Math.max(brightness, mScreenBrightnessDim); 2238 } catch (SettingNotFoundException snfe) { 2239 return Power.BRIGHTNESS_ON; 2240 } 2241 } 2242 2243 private int applyButtonState(int state) { 2244 int brightness = -1; 2245 if ((state & BATTERY_LOW_BIT) != 0) { 2246 // do not override brightness if the battery is low 2247 return state; 2248 } 2249 if (mButtonBrightnessOverride >= 0) { 2250 brightness = mButtonBrightnessOverride; 2251 } else if (mLightSensorButtonBrightness >= 0 && mUseSoftwareAutoBrightness) { 2252 brightness = mLightSensorButtonBrightness; 2253 } 2254 if (brightness > 0) { 2255 return state | BUTTON_BRIGHT_BIT; 2256 } else if (brightness == 0) { 2257 return state & ~BUTTON_BRIGHT_BIT; 2258 } else { 2259 return state; 2260 } 2261 } 2262 2263 private int applyKeyboardState(int state) { 2264 int brightness = -1; 2265 if ((state & BATTERY_LOW_BIT) != 0) { 2266 // do not override brightness if the battery is low 2267 return state; 2268 } 2269 if (!mKeyboardVisible) { 2270 brightness = 0; 2271 } else if (mButtonBrightnessOverride >= 0) { 2272 brightness = mButtonBrightnessOverride; 2273 } else if (mLightSensorKeyboardBrightness >= 0 && mUseSoftwareAutoBrightness) { 2274 brightness = mLightSensorKeyboardBrightness; 2275 } 2276 if (brightness > 0) { 2277 return state | KEYBOARD_BRIGHT_BIT; 2278 } else if (brightness == 0) { 2279 return state & ~KEYBOARD_BRIGHT_BIT; 2280 } else { 2281 return state; 2282 } 2283 } 2284 2285 public boolean isScreenOn() { 2286 synchronized (mLocks) { 2287 return (mPowerState & SCREEN_ON_BIT) != 0; 2288 } 2289 } 2290 2291 boolean isScreenBright() { 2292 synchronized (mLocks) { 2293 return (mPowerState & SCREEN_BRIGHT) == SCREEN_BRIGHT; 2294 } 2295 } 2296 2297 private boolean isScreenTurningOffLocked() { 2298 return (mScreenBrightness.animating && mScreenBrightness.targetValue == 0); 2299 } 2300 2301 private boolean shouldLog(long time) { 2302 synchronized (mLocks) { 2303 if (time > (mWarningSpewThrottleTime + (60*60*1000))) { 2304 mWarningSpewThrottleTime = time; 2305 mWarningSpewThrottleCount = 0; 2306 return true; 2307 } else if (mWarningSpewThrottleCount < 30) { 2308 mWarningSpewThrottleCount++; 2309 return true; 2310 } else { 2311 return false; 2312 } 2313 } 2314 } 2315 2316 private void forceUserActivityLocked() { 2317 if (isScreenTurningOffLocked()) { 2318 // cancel animation so userActivity will succeed 2319 mScreenBrightness.animating = false; 2320 } 2321 boolean savedActivityAllowed = mUserActivityAllowed; 2322 mUserActivityAllowed = true; 2323 userActivity(SystemClock.uptimeMillis(), false); 2324 mUserActivityAllowed = savedActivityAllowed; 2325 } 2326 2327 public void userActivityWithForce(long time, boolean noChangeLights, boolean force) { 2328 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); 2329 userActivity(time, -1, noChangeLights, OTHER_EVENT, force); 2330 } 2331 2332 public void userActivity(long time, boolean noChangeLights) { 2333 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER) 2334 != PackageManager.PERMISSION_GRANTED) { 2335 if (shouldLog(time)) { 2336 Slog.w(TAG, "Caller does not have DEVICE_POWER permission. pid=" 2337 + Binder.getCallingPid() + " uid=" + Binder.getCallingUid()); 2338 } 2339 return; 2340 } 2341 2342 userActivity(time, -1, noChangeLights, OTHER_EVENT, false); 2343 } 2344 2345 public void userActivity(long time, boolean noChangeLights, int eventType) { 2346 userActivity(time, -1, noChangeLights, eventType, false); 2347 } 2348 2349 public void userActivity(long time, boolean noChangeLights, int eventType, boolean force) { 2350 userActivity(time, -1, noChangeLights, eventType, force); 2351 } 2352 2353 /* 2354 * Reset the user activity timeout to now + timeout. This overrides whatever else is going 2355 * on with user activity. Don't use this function. 2356 */ 2357 public void clearUserActivityTimeout(long now, long timeout) { 2358 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); 2359 Slog.i(TAG, "clearUserActivity for " + timeout + "ms from now"); 2360 userActivity(now, timeout, false, OTHER_EVENT, false); 2361 } 2362 2363 private void userActivity(long time, long timeoutOverride, boolean noChangeLights, 2364 int eventType, boolean force) { 2365 2366 if (((mPokey & POKE_LOCK_IGNORE_TOUCH_EVENTS) != 0) && (eventType == TOUCH_EVENT)) { 2367 if (false) { 2368 Slog.d(TAG, "dropping touch mPokey=0x" + Integer.toHexString(mPokey)); 2369 } 2370 return; 2371 } 2372 2373 synchronized (mLocks) { 2374 if (mSpew) { 2375 Slog.d(TAG, "userActivity mLastEventTime=" + mLastEventTime + " time=" + time 2376 + " mUserActivityAllowed=" + mUserActivityAllowed 2377 + " mUserState=0x" + Integer.toHexString(mUserState) 2378 + " mWakeLockState=0x" + Integer.toHexString(mWakeLockState) 2379 + " mProximitySensorActive=" + mProximitySensorActive 2380 + " timeoutOverride=" + timeoutOverride 2381 + " force=" + force); 2382 } 2383 // ignore user activity if we are in the process of turning off the screen 2384 if (isScreenTurningOffLocked()) { 2385 Slog.d(TAG, "ignoring user activity while turning off screen"); 2386 return; 2387 } 2388 // Disable proximity sensor if if user presses power key while we are in the 2389 // "waiting for proximity sensor to go negative" state. 2390 if (mProximitySensorActive && mProximityWakeLockCount == 0) { 2391 mProximitySensorActive = false; 2392 } 2393 if (mLastEventTime <= time || force) { 2394 mLastEventTime = time; 2395 if ((mUserActivityAllowed && !mProximitySensorActive) || force) { 2396 // Only turn on button backlights if a button was pressed 2397 // and auto brightness is disabled 2398 if (eventType == BUTTON_EVENT && !mUseSoftwareAutoBrightness) { 2399 mUserState = (mKeyboardVisible ? ALL_BRIGHT : SCREEN_BUTTON_BRIGHT); 2400 } else { 2401 // don't clear button/keyboard backlights when the screen is touched. 2402 mUserState |= SCREEN_BRIGHT; 2403 } 2404 2405 int uid = Binder.getCallingUid(); 2406 long ident = Binder.clearCallingIdentity(); 2407 try { 2408 mBatteryStats.noteUserActivity(uid, eventType); 2409 } catch (RemoteException e) { 2410 // Ignore 2411 } finally { 2412 Binder.restoreCallingIdentity(ident); 2413 } 2414 2415 mWakeLockState = mLocks.reactivateScreenLocksLocked(); 2416 setPowerState(mUserState | mWakeLockState, noChangeLights, 2417 WindowManagerPolicy.OFF_BECAUSE_OF_USER); 2418 setTimeoutLocked(time, timeoutOverride, SCREEN_BRIGHT); 2419 } 2420 } 2421 } 2422 2423 if (mPolicy != null) { 2424 mPolicy.userActivity(); 2425 } 2426 } 2427 2428 private int getAutoBrightnessValue(int sensorValue, int[] values) { 2429 try { 2430 int i; 2431 for (i = 0; i < mAutoBrightnessLevels.length; i++) { 2432 if (sensorValue < mAutoBrightnessLevels[i]) { 2433 break; 2434 } 2435 } 2436 return values[i]; 2437 } catch (Exception e) { 2438 // guard against null pointer or index out of bounds errors 2439 Slog.e(TAG, "getAutoBrightnessValue", e); 2440 return 255; 2441 } 2442 } 2443 2444 private Runnable mProximityTask = new Runnable() { 2445 public void run() { 2446 synchronized (mLocks) { 2447 if (mProximityPendingValue != -1) { 2448 proximityChangedLocked(mProximityPendingValue == 1); 2449 mProximityPendingValue = -1; 2450 } 2451 if (mProximityPartialLock.isHeld()) { 2452 mProximityPartialLock.release(); 2453 } 2454 } 2455 } 2456 }; 2457 2458 private Runnable mAutoBrightnessTask = new Runnable() { 2459 public void run() { 2460 synchronized (mLocks) { 2461 if (mLightSensorPendingDecrease || mLightSensorPendingIncrease) { 2462 int value = (int)mLightSensorPendingValue; 2463 mLightSensorPendingDecrease = false; 2464 mLightSensorPendingIncrease = false; 2465 lightSensorChangedLocked(value); 2466 } 2467 } 2468 } 2469 }; 2470 2471 private void dockStateChanged(int state) { 2472 synchronized (mLocks) { 2473 mIsDocked = (state != Intent.EXTRA_DOCK_STATE_UNDOCKED); 2474 if (mIsDocked) { 2475 mHighestLightSensorValue = -1; 2476 } 2477 if ((mPowerState & SCREEN_ON_BIT) != 0) { 2478 // force lights recalculation 2479 int value = (int)mLightSensorValue; 2480 mLightSensorValue = -1; 2481 lightSensorChangedLocked(value); 2482 } 2483 } 2484 } 2485 2486 private void lightSensorChangedLocked(int value) { 2487 if (mDebugLightSensor) { 2488 Slog.d(TAG, "lightSensorChangedLocked " + value); 2489 } 2490 2491 // Don't do anything if the screen is off. 2492 if ((mPowerState & SCREEN_ON_BIT) == 0) { 2493 if (mDebugLightSensor) { 2494 Slog.d(TAG, "dropping lightSensorChangedLocked because screen is off"); 2495 } 2496 return; 2497 } 2498 2499 // do not allow light sensor value to decrease 2500 if (mHighestLightSensorValue < value) { 2501 mHighestLightSensorValue = value; 2502 } 2503 2504 if (mLightSensorValue != value) { 2505 mLightSensorValue = value; 2506 if ((mPowerState & BATTERY_LOW_BIT) == 0) { 2507 // use maximum light sensor value seen since screen went on for LCD to avoid flicker 2508 // we only do this if we are undocked, since lighting should be stable when 2509 // stationary in a dock. 2510 int lcdValue = getAutoBrightnessValue( 2511 (mIsDocked ? value : mHighestLightSensorValue), 2512 mLcdBacklightValues); 2513 int buttonValue = getAutoBrightnessValue(value, mButtonBacklightValues); 2514 int keyboardValue; 2515 if (mKeyboardVisible) { 2516 keyboardValue = getAutoBrightnessValue(value, mKeyboardBacklightValues); 2517 } else { 2518 keyboardValue = 0; 2519 } 2520 mLightSensorScreenBrightness = lcdValue; 2521 mLightSensorButtonBrightness = buttonValue; 2522 mLightSensorKeyboardBrightness = keyboardValue; 2523 2524 if (mDebugLightSensor) { 2525 Slog.d(TAG, "lcdValue " + lcdValue); 2526 Slog.d(TAG, "buttonValue " + buttonValue); 2527 Slog.d(TAG, "keyboardValue " + keyboardValue); 2528 } 2529 2530 if (mAutoBrightessEnabled && mScreenBrightnessOverride < 0) { 2531 mScreenBrightness.setTargetLocked(lcdValue, AUTOBRIGHTNESS_ANIM_STEPS, 2532 INITIAL_SCREEN_BRIGHTNESS, (int)mScreenBrightness.curValue); 2533 } 2534 if (mButtonBrightnessOverride < 0) { 2535 mButtonLight.setBrightness(buttonValue); 2536 } 2537 if (mButtonBrightnessOverride < 0 || !mKeyboardVisible) { 2538 mKeyboardLight.setBrightness(keyboardValue); 2539 } 2540 } 2541 } 2542 } 2543 2544 /** 2545 * The user requested that we go to sleep (probably with the power button). 2546 * This overrides all wake locks that are held. 2547 */ 2548 public void goToSleep(long time) 2549 { 2550 goToSleepWithReason(time, WindowManagerPolicy.OFF_BECAUSE_OF_USER); 2551 } 2552 2553 /** 2554 * The user requested that we go to sleep (probably with the power button). 2555 * This overrides all wake locks that are held. 2556 */ 2557 public void goToSleepWithReason(long time, int reason) 2558 { 2559 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); 2560 synchronized (mLocks) { 2561 goToSleepLocked(time, reason); 2562 } 2563 } 2564 2565 /** 2566 * Reboot the device immediately, passing 'reason' (may be null) 2567 * to the underlying __reboot system call. Should not return. 2568 */ 2569 public void reboot(String reason) 2570 { 2571 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null); 2572 2573 if (mHandler == null || !ActivityManagerNative.isSystemReady()) { 2574 throw new IllegalStateException("Too early to call reboot()"); 2575 } 2576 2577 final String finalReason = reason; 2578 Runnable runnable = new Runnable() { 2579 public void run() { 2580 synchronized (this) { 2581 ShutdownThread.reboot(mContext, finalReason, false); 2582 } 2583 2584 } 2585 }; 2586 // ShutdownThread must run on a looper capable of displaying the UI. 2587 mHandler.post(runnable); 2588 2589 // PowerManager.reboot() is documented not to return so just wait for the inevitable. 2590 synchronized (runnable) { 2591 while (true) { 2592 try { 2593 runnable.wait(); 2594 } catch (InterruptedException e) { 2595 } 2596 } 2597 } 2598 } 2599 2600 /** 2601 * Crash the runtime (causing a complete restart of the Android framework). 2602 * Requires REBOOT permission. Mostly for testing. Should not return. 2603 */ 2604 public void crash(final String message) 2605 { 2606 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null); 2607 Thread t = new Thread("PowerManagerService.crash()") { 2608 public void run() { throw new RuntimeException(message); } 2609 }; 2610 try { 2611 t.start(); 2612 t.join(); 2613 } catch (InterruptedException e) { 2614 Log.wtf(TAG, e); 2615 } 2616 } 2617 2618 private void goToSleepLocked(long time, int reason) { 2619 2620 if (mLastEventTime <= time) { 2621 mLastEventTime = time; 2622 // cancel all of the wake locks 2623 mWakeLockState = SCREEN_OFF; 2624 int N = mLocks.size(); 2625 int numCleared = 0; 2626 boolean proxLock = false; 2627 for (int i=0; i<N; i++) { 2628 WakeLock wl = mLocks.get(i); 2629 if (isScreenLock(wl.flags)) { 2630 if (((wl.flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) 2631 && reason == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR) { 2632 proxLock = true; 2633 } else { 2634 mLocks.get(i).activated = false; 2635 numCleared++; 2636 } 2637 } 2638 } 2639 if (!proxLock) { 2640 mProxIgnoredBecauseScreenTurnedOff = true; 2641 if (mDebugProximitySensor) { 2642 Slog.d(TAG, "setting mProxIgnoredBecauseScreenTurnedOff"); 2643 } 2644 } 2645 EventLog.writeEvent(EventLogTags.POWER_SLEEP_REQUESTED, numCleared); 2646 mStillNeedSleepNotification = true; 2647 mUserState = SCREEN_OFF; 2648 setPowerState(SCREEN_OFF, false, reason); 2649 cancelTimerLocked(); 2650 } 2651 } 2652 2653 public long timeSinceScreenOn() { 2654 synchronized (mLocks) { 2655 if ((mPowerState & SCREEN_ON_BIT) != 0) { 2656 return 0; 2657 } 2658 return SystemClock.elapsedRealtime() - mScreenOffTime; 2659 } 2660 } 2661 2662 public void setKeyboardVisibility(boolean visible) { 2663 synchronized (mLocks) { 2664 if (mSpew) { 2665 Slog.d(TAG, "setKeyboardVisibility: " + visible); 2666 } 2667 if (mKeyboardVisible != visible) { 2668 mKeyboardVisible = visible; 2669 // don't signal user activity if the screen is off; other code 2670 // will take care of turning on due to a true change to the lid 2671 // switch and synchronized with the lock screen. 2672 if ((mPowerState & SCREEN_ON_BIT) != 0) { 2673 if (mUseSoftwareAutoBrightness) { 2674 // force recompute of backlight values 2675 if (mLightSensorValue >= 0) { 2676 int value = (int)mLightSensorValue; 2677 mLightSensorValue = -1; 2678 lightSensorChangedLocked(value); 2679 } 2680 } 2681 userActivity(SystemClock.uptimeMillis(), false, BUTTON_EVENT, true); 2682 } 2683 } 2684 } 2685 } 2686 2687 /** 2688 * When the keyguard is up, it manages the power state, and userActivity doesn't do anything. 2689 * When disabling user activity we also reset user power state so the keyguard can reset its 2690 * short screen timeout when keyguard is unhidden. 2691 */ 2692 public void enableUserActivity(boolean enabled) { 2693 if (mSpew) { 2694 Slog.d(TAG, "enableUserActivity " + enabled); 2695 } 2696 synchronized (mLocks) { 2697 mUserActivityAllowed = enabled; 2698 if (!enabled) { 2699 // cancel timeout and clear mUserState so the keyguard can set a short timeout 2700 setTimeoutLocked(SystemClock.uptimeMillis(), 0); 2701 } 2702 } 2703 } 2704 2705 private void setScreenBrightnessMode(int mode) { 2706 synchronized (mLocks) { 2707 boolean enabled = (mode == SCREEN_BRIGHTNESS_MODE_AUTOMATIC); 2708 if (mUseSoftwareAutoBrightness && mAutoBrightessEnabled != enabled) { 2709 mAutoBrightessEnabled = enabled; 2710 // This will get us a new value 2711 enableLightSensorLocked(mAutoBrightessEnabled && isScreenOn()); 2712 } 2713 } 2714 } 2715 2716 /** Sets the screen off timeouts: 2717 * mKeylightDelay 2718 * mDimDelay 2719 * mScreenOffDelay 2720 * */ 2721 private void setScreenOffTimeoutsLocked() { 2722 if ((mPokey & POKE_LOCK_SHORT_TIMEOUT) != 0) { 2723 mKeylightDelay = mShortKeylightDelay; // Configurable via secure settings 2724 mDimDelay = -1; 2725 mScreenOffDelay = 0; 2726 } else if ((mPokey & POKE_LOCK_MEDIUM_TIMEOUT) != 0) { 2727 mKeylightDelay = MEDIUM_KEYLIGHT_DELAY; 2728 mDimDelay = -1; 2729 mScreenOffDelay = 0; 2730 } else { 2731 int totalDelay = mScreenOffTimeoutSetting; 2732 if (totalDelay > mMaximumScreenOffTimeout) { 2733 totalDelay = mMaximumScreenOffTimeout; 2734 } 2735 mKeylightDelay = LONG_KEYLIGHT_DELAY; 2736 if (totalDelay < 0) { 2737 // negative number means stay on as long as possible. 2738 mScreenOffDelay = mMaximumScreenOffTimeout; 2739 } else if (mKeylightDelay < totalDelay) { 2740 // subtract the time that the keylight delay. This will give us the 2741 // remainder of the time that we need to sleep to get the accurate 2742 // screen off timeout. 2743 mScreenOffDelay = totalDelay - mKeylightDelay; 2744 } else { 2745 mScreenOffDelay = 0; 2746 } 2747 if (mDimScreen && totalDelay >= (LONG_KEYLIGHT_DELAY + LONG_DIM_TIME)) { 2748 mDimDelay = mScreenOffDelay - LONG_DIM_TIME; 2749 mScreenOffDelay = LONG_DIM_TIME; 2750 } else { 2751 mDimDelay = -1; 2752 } 2753 } 2754 if (mSpew) { 2755 Slog.d(TAG, "setScreenOffTimeouts mKeylightDelay=" + mKeylightDelay 2756 + " mDimDelay=" + mDimDelay + " mScreenOffDelay=" + mScreenOffDelay 2757 + " mDimScreen=" + mDimScreen); 2758 } 2759 } 2760 2761 /** 2762 * Refreshes cached secure settings. Called once on startup, and 2763 * on subsequent changes to secure settings. 2764 */ 2765 private void updateSettingsValues() { 2766 mShortKeylightDelay = Settings.Secure.getInt( 2767 mContext.getContentResolver(), 2768 Settings.Secure.SHORT_KEYLIGHT_DELAY_MS, 2769 SHORT_KEYLIGHT_DELAY_DEFAULT); 2770 // Slog.i(TAG, "updateSettingsValues(): mShortKeylightDelay now " + mShortKeylightDelay); 2771 } 2772 2773 private class LockList extends ArrayList<WakeLock> 2774 { 2775 void addLock(WakeLock wl) 2776 { 2777 int index = getIndex(wl.binder); 2778 if (index < 0) { 2779 this.add(wl); 2780 } 2781 } 2782 2783 WakeLock removeLock(IBinder binder) 2784 { 2785 int index = getIndex(binder); 2786 if (index >= 0) { 2787 return this.remove(index); 2788 } else { 2789 return null; 2790 } 2791 } 2792 2793 int getIndex(IBinder binder) 2794 { 2795 int N = this.size(); 2796 for (int i=0; i<N; i++) { 2797 if (this.get(i).binder == binder) { 2798 return i; 2799 } 2800 } 2801 return -1; 2802 } 2803 2804 int gatherState() 2805 { 2806 int result = 0; 2807 int N = this.size(); 2808 for (int i=0; i<N; i++) { 2809 WakeLock wl = this.get(i); 2810 if (wl.activated) { 2811 if (isScreenLock(wl.flags)) { 2812 result |= wl.minState; 2813 } 2814 } 2815 } 2816 return result; 2817 } 2818 2819 int reactivateScreenLocksLocked() 2820 { 2821 int result = 0; 2822 int N = this.size(); 2823 for (int i=0; i<N; i++) { 2824 WakeLock wl = this.get(i); 2825 if (isScreenLock(wl.flags)) { 2826 wl.activated = true; 2827 result |= wl.minState; 2828 } 2829 } 2830 if (mDebugProximitySensor) { 2831 Slog.d(TAG, "reactivateScreenLocksLocked mProxIgnoredBecauseScreenTurnedOff=" 2832 + mProxIgnoredBecauseScreenTurnedOff); 2833 } 2834 mProxIgnoredBecauseScreenTurnedOff = false; 2835 return result; 2836 } 2837 } 2838 2839 public void setPolicy(WindowManagerPolicy p) { 2840 synchronized (mLocks) { 2841 mPolicy = p; 2842 mLocks.notifyAll(); 2843 } 2844 } 2845 2846 WindowManagerPolicy getPolicyLocked() { 2847 while (mPolicy == null || !mDoneBooting) { 2848 try { 2849 mLocks.wait(); 2850 } catch (InterruptedException e) { 2851 // Ignore 2852 } 2853 } 2854 return mPolicy; 2855 } 2856 2857 void systemReady() { 2858 mSensorManager = new SensorManager(mHandlerThread.getLooper()); 2859 mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); 2860 // don't bother with the light sensor if auto brightness is handled in hardware 2861 if (mUseSoftwareAutoBrightness) { 2862 mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); 2863 } 2864 2865 // wait until sensors are enabled before turning on screen. 2866 // some devices will not activate the light sensor properly on boot 2867 // unless we do this. 2868 if (mUseSoftwareAutoBrightness) { 2869 // turn the screen on 2870 setPowerState(SCREEN_BRIGHT); 2871 } else { 2872 // turn everything on 2873 setPowerState(ALL_BRIGHT); 2874 } 2875 2876 synchronized (mLocks) { 2877 Slog.d(TAG, "system ready!"); 2878 mDoneBooting = true; 2879 2880 enableLightSensorLocked(mUseSoftwareAutoBrightness && mAutoBrightessEnabled); 2881 2882 long identity = Binder.clearCallingIdentity(); 2883 try { 2884 mBatteryStats.noteScreenBrightness(getPreferredBrightness()); 2885 mBatteryStats.noteScreenOn(); 2886 } catch (RemoteException e) { 2887 // Nothing interesting to do. 2888 } finally { 2889 Binder.restoreCallingIdentity(identity); 2890 } 2891 } 2892 } 2893 2894 void bootCompleted() { 2895 Slog.d(TAG, "bootCompleted"); 2896 synchronized (mLocks) { 2897 mBootCompleted = true; 2898 userActivity(SystemClock.uptimeMillis(), false, BUTTON_EVENT, true); 2899 updateWakeLockLocked(); 2900 mLocks.notifyAll(); 2901 } 2902 } 2903 2904 // for watchdog 2905 public void monitor() { 2906 synchronized (mLocks) { } 2907 } 2908 2909 public int getSupportedWakeLockFlags() { 2910 int result = PowerManager.PARTIAL_WAKE_LOCK 2911 | PowerManager.FULL_WAKE_LOCK 2912 | PowerManager.SCREEN_DIM_WAKE_LOCK; 2913 2914 if (mProximitySensor != null) { 2915 result |= PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK; 2916 } 2917 2918 return result; 2919 } 2920 2921 public void setBacklightBrightness(int brightness) { 2922 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); 2923 // Don't let applications turn the screen all the way off 2924 synchronized (mLocks) { 2925 brightness = Math.max(brightness, mScreenBrightnessDim); 2926 mLcdLight.setBrightness(brightness); 2927 mKeyboardLight.setBrightness(mKeyboardVisible ? brightness : 0); 2928 mButtonLight.setBrightness(brightness); 2929 long identity = Binder.clearCallingIdentity(); 2930 try { 2931 mBatteryStats.noteScreenBrightness(brightness); 2932 } catch (RemoteException e) { 2933 Slog.w(TAG, "RemoteException calling noteScreenBrightness on BatteryStatsService", e); 2934 } finally { 2935 Binder.restoreCallingIdentity(identity); 2936 } 2937 2938 // update our animation state 2939 synchronized (mLocks) { 2940 mScreenBrightness.targetValue = brightness; 2941 mScreenBrightness.jumpToTargetLocked(); 2942 } 2943 } 2944 } 2945 2946 public void setAttentionLight(boolean on, int color) { 2947 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); 2948 mAttentionLight.setFlashing(color, LightsService.LIGHT_FLASH_HARDWARE, (on ? 3 : 0), 0); 2949 } 2950 2951 private void enableProximityLockLocked() { 2952 if (mDebugProximitySensor) { 2953 Slog.d(TAG, "enableProximityLockLocked"); 2954 } 2955 if (!mProximitySensorEnabled) { 2956 // clear calling identity so sensor manager battery stats are accurate 2957 long identity = Binder.clearCallingIdentity(); 2958 try { 2959 mSensorManager.registerListener(mProximityListener, mProximitySensor, 2960 SensorManager.SENSOR_DELAY_NORMAL); 2961 mProximitySensorEnabled = true; 2962 } finally { 2963 Binder.restoreCallingIdentity(identity); 2964 } 2965 } 2966 } 2967 2968 private void disableProximityLockLocked() { 2969 if (mDebugProximitySensor) { 2970 Slog.d(TAG, "disableProximityLockLocked"); 2971 } 2972 if (mProximitySensorEnabled) { 2973 // clear calling identity so sensor manager battery stats are accurate 2974 long identity = Binder.clearCallingIdentity(); 2975 try { 2976 mSensorManager.unregisterListener(mProximityListener); 2977 mHandler.removeCallbacks(mProximityTask); 2978 if (mProximityPartialLock.isHeld()) { 2979 mProximityPartialLock.release(); 2980 } 2981 mProximitySensorEnabled = false; 2982 } finally { 2983 Binder.restoreCallingIdentity(identity); 2984 } 2985 if (mProximitySensorActive) { 2986 mProximitySensorActive = false; 2987 if (mDebugProximitySensor) { 2988 Slog.d(TAG, "disableProximityLockLocked mProxIgnoredBecauseScreenTurnedOff=" 2989 + mProxIgnoredBecauseScreenTurnedOff); 2990 } 2991 if (!mProxIgnoredBecauseScreenTurnedOff) { 2992 forceUserActivityLocked(); 2993 } 2994 } 2995 } 2996 } 2997 2998 private void proximityChangedLocked(boolean active) { 2999 if (mDebugProximitySensor) { 3000 Slog.d(TAG, "proximityChangedLocked, active: " + active); 3001 } 3002 if (!mProximitySensorEnabled) { 3003 Slog.d(TAG, "Ignoring proximity change after sensor is disabled"); 3004 return; 3005 } 3006 if (active) { 3007 if (mDebugProximitySensor) { 3008 Slog.d(TAG, "b mProxIgnoredBecauseScreenTurnedOff=" 3009 + mProxIgnoredBecauseScreenTurnedOff); 3010 } 3011 if (!mProxIgnoredBecauseScreenTurnedOff) { 3012 goToSleepLocked(SystemClock.uptimeMillis(), 3013 WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR); 3014 } 3015 mProximitySensorActive = true; 3016 } else { 3017 // proximity sensor negative events trigger as user activity. 3018 // temporarily set mUserActivityAllowed to true so this will work 3019 // even when the keyguard is on. 3020 mProximitySensorActive = false; 3021 if (mDebugProximitySensor) { 3022 Slog.d(TAG, "b mProxIgnoredBecauseScreenTurnedOff=" 3023 + mProxIgnoredBecauseScreenTurnedOff); 3024 } 3025 if (!mProxIgnoredBecauseScreenTurnedOff) { 3026 forceUserActivityLocked(); 3027 } 3028 3029 if (mProximityWakeLockCount == 0) { 3030 // disable sensor if we have no listeners left after proximity negative 3031 disableProximityLockLocked(); 3032 } 3033 } 3034 } 3035 3036 private void enableLightSensorLocked(boolean enable) { 3037 if (mDebugLightSensor) { 3038 Slog.d(TAG, "enableLightSensorLocked enable=" + enable 3039 + " mAutoBrightessEnabled=" + mAutoBrightessEnabled); 3040 } 3041 if (!mAutoBrightessEnabled) { 3042 enable = false; 3043 } 3044 if (mSensorManager != null && mLightSensorEnabled != enable) { 3045 mLightSensorEnabled = enable; 3046 // clear previous values so we will adjust to current brightness when 3047 // auto-brightness is reenabled 3048 mHighestLightSensorValue = -1; 3049 mLightSensorValue = -1; 3050 3051 // clear calling identity so sensor manager battery stats are accurate 3052 long identity = Binder.clearCallingIdentity(); 3053 try { 3054 if (enable) { 3055 mSensorManager.registerListener(mLightListener, mLightSensor, 3056 SensorManager.SENSOR_DELAY_NORMAL); 3057 } else { 3058 mSensorManager.unregisterListener(mLightListener); 3059 mHandler.removeCallbacks(mAutoBrightnessTask); 3060 } 3061 } finally { 3062 Binder.restoreCallingIdentity(identity); 3063 } 3064 } 3065 } 3066 3067 SensorEventListener mProximityListener = new SensorEventListener() { 3068 public void onSensorChanged(SensorEvent event) { 3069 long milliseconds = SystemClock.elapsedRealtime(); 3070 synchronized (mLocks) { 3071 float distance = event.values[0]; 3072 long timeSinceLastEvent = milliseconds - mLastProximityEventTime; 3073 mLastProximityEventTime = milliseconds; 3074 mHandler.removeCallbacks(mProximityTask); 3075 boolean proximityTaskQueued = false; 3076 3077 // compare against getMaximumRange to support sensors that only return 0 or 1 3078 boolean active = (distance >= 0.0 && distance < PROXIMITY_THRESHOLD && 3079 distance < mProximitySensor.getMaximumRange()); 3080 3081 if (mDebugProximitySensor) { 3082 Slog.d(TAG, "mProximityListener.onSensorChanged active: " + active); 3083 } 3084 if (timeSinceLastEvent < PROXIMITY_SENSOR_DELAY) { 3085 // enforce delaying atleast PROXIMITY_SENSOR_DELAY before processing 3086 mProximityPendingValue = (active ? 1 : 0); 3087 mHandler.postDelayed(mProximityTask, PROXIMITY_SENSOR_DELAY - timeSinceLastEvent); 3088 proximityTaskQueued = true; 3089 } else { 3090 // process the value immediately 3091 mProximityPendingValue = -1; 3092 proximityChangedLocked(active); 3093 } 3094 3095 // update mProximityPartialLock state 3096 boolean held = mProximityPartialLock.isHeld(); 3097 if (!held && proximityTaskQueued) { 3098 // hold wakelock until mProximityTask runs 3099 mProximityPartialLock.acquire(); 3100 } else if (held && !proximityTaskQueued) { 3101 mProximityPartialLock.release(); 3102 } 3103 } 3104 } 3105 3106 public void onAccuracyChanged(Sensor sensor, int accuracy) { 3107 // ignore 3108 } 3109 }; 3110 3111 SensorEventListener mLightListener = new SensorEventListener() { 3112 public void onSensorChanged(SensorEvent event) { 3113 synchronized (mLocks) { 3114 // ignore light sensor while screen is turning off 3115 if (isScreenTurningOffLocked()) { 3116 return; 3117 } 3118 3119 int value = (int)event.values[0]; 3120 long milliseconds = SystemClock.elapsedRealtime(); 3121 if (mDebugLightSensor) { 3122 Slog.d(TAG, "onSensorChanged: light value: " + value); 3123 } 3124 if (mLightSensorValue == -1 || 3125 milliseconds < mLastScreenOnTime + mLightSensorWarmupTime) { 3126 // process the value immediately if screen has just turned on 3127 mHandler.removeCallbacks(mAutoBrightnessTask); 3128 mLightSensorPendingDecrease = false; 3129 mLightSensorPendingIncrease = false; 3130 lightSensorChangedLocked(value); 3131 } else { 3132 if ((value > mLightSensorValue && mLightSensorPendingDecrease) || 3133 (value < mLightSensorValue && mLightSensorPendingIncrease) || 3134 (value == mLightSensorValue) || 3135 (!mLightSensorPendingDecrease && !mLightSensorPendingIncrease)) { 3136 // delay processing to debounce the sensor 3137 mHandler.removeCallbacks(mAutoBrightnessTask); 3138 mLightSensorPendingDecrease = (value < mLightSensorValue); 3139 mLightSensorPendingIncrease = (value > mLightSensorValue); 3140 if (mLightSensorPendingDecrease || mLightSensorPendingIncrease) { 3141 mLightSensorPendingValue = value; 3142 mHandler.postDelayed(mAutoBrightnessTask, LIGHT_SENSOR_DELAY); 3143 } 3144 } else { 3145 mLightSensorPendingValue = value; 3146 } 3147 } 3148 } 3149 } 3150 3151 public void onAccuracyChanged(Sensor sensor, int accuracy) { 3152 // ignore 3153 } 3154 }; 3155 } 3156