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