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