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