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