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