PowerManager.java revision 631938f26dbc89e7e9530bb85d9f37706dba59f3
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 android.os; 18 19import android.content.Context; 20import android.util.Log; 21 22/** 23 * This class gives you control of the power state of the device. 24 * 25 * <p> 26 * <b>Device battery life will be significantly affected by the use of this API.</b> 27 * Do not acquire {@link WakeLock}s unless you really need them, use the minimum levels 28 * possible, and be sure to release them as soon as possible. 29 * </p><p> 30 * You can obtain an instance of this class by calling 31 * {@link android.content.Context#getSystemService(java.lang.String) Context.getSystemService()}. 32 * </p><p> 33 * The primary API you'll use is {@link #newWakeLock(int, String) newWakeLock()}. 34 * This will create a {@link PowerManager.WakeLock} object. You can then use methods 35 * on the wake lock object to control the power state of the device. 36 * </p><p> 37 * In practice it's quite simple: 38 * {@samplecode 39 * PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); 40 * PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "My Tag"); 41 * wl.acquire(); 42 * ..screen will stay on during this section.. 43 * wl.release(); 44 * } 45 * </p><p> 46 * The following wake lock levels are defined, with varying effects on system power. 47 * <i>These levels are mutually exclusive - you may only specify one of them.</i> 48 * 49 * <table border="2" width="85%" align="center" frame="hsides" rules="rows"> 50 * <thead> 51 * <tr><th>Flag Value</th> 52 * <th>CPU</th> <th>Screen</th> <th>Keyboard</th></tr> 53 * </thead> 54 * 55 * <tbody> 56 * <tr><th>{@link #PARTIAL_WAKE_LOCK}</th> 57 * <td>On*</td> <td>Off</td> <td>Off</td> 58 * </tr> 59 * 60 * <tr><th>{@link #SCREEN_DIM_WAKE_LOCK}</th> 61 * <td>On</td> <td>Dim</td> <td>Off</td> 62 * </tr> 63 * 64 * <tr><th>{@link #SCREEN_BRIGHT_WAKE_LOCK}</th> 65 * <td>On</td> <td>Bright</td> <td>Off</td> 66 * </tr> 67 * 68 * <tr><th>{@link #FULL_WAKE_LOCK}</th> 69 * <td>On</td> <td>Bright</td> <td>Bright</td> 70 * </tr> 71 * </tbody> 72 * </table> 73 * </p><p> 74 * *<i>If you hold a partial wake lock, the CPU will continue to run, regardless of any 75 * display timeouts or the state of the screen and even after the user presses the power button. 76 * In all other wake locks, the CPU will run, but the user can still put the device to sleep 77 * using the power button.</i> 78 * </p><p> 79 * In addition, you can add two more flags, which affect behavior of the screen only. 80 * <i>These flags have no effect when combined with a {@link #PARTIAL_WAKE_LOCK}.</i> 81 * 82 * <table border="2" width="85%" align="center" frame="hsides" rules="rows"> 83 * <thead> 84 * <tr><th>Flag Value</th> <th>Description</th></tr> 85 * </thead> 86 * 87 * <tbody> 88 * <tr><th>{@link #ACQUIRE_CAUSES_WAKEUP}</th> 89 * <td>Normal wake locks don't actually turn on the illumination. Instead, they cause 90 * the illumination to remain on once it turns on (e.g. from user activity). This flag 91 * will force the screen and/or keyboard to turn on immediately, when the WakeLock is 92 * acquired. A typical use would be for notifications which are important for the user to 93 * see immediately.</td> 94 * </tr> 95 * 96 * <tr><th>{@link #ON_AFTER_RELEASE}</th> 97 * <td>If this flag is set, the user activity timer will be reset when the WakeLock is 98 * released, causing the illumination to remain on a bit longer. This can be used to 99 * reduce flicker if you are cycling between wake lock conditions.</td> 100 * </tr> 101 * </tbody> 102 * </table> 103 * </p><p> 104 * Any application using a WakeLock must request the {@code android.permission.WAKE_LOCK} 105 * permission in an {@code <uses-permission>} element of the application's manifest. 106 * </p> 107 */ 108public final class PowerManager { 109 private static final String TAG = "PowerManager"; 110 111 /* NOTE: Wake lock levels were previously defined as a bit field, except that only a few 112 * combinations were actually supported so the bit field was removed. This explains 113 * why the numbering scheme is so odd. If adding a new wake lock level, any unused 114 * value can be used. 115 */ 116 117 /** 118 * Wake lock level: Ensures that the CPU is running; the screen and keyboard 119 * backlight will be allowed to go off. 120 * <p> 121 * If the user presses the power button, then the screen will be turned off 122 * but the CPU will be kept on until all partial wake locks have been released. 123 * </p> 124 */ 125 public static final int PARTIAL_WAKE_LOCK = 0x00000001; 126 127 /** 128 * Wake lock level: Ensures that the screen is on (but may be dimmed); 129 * the keyboard backlight will be allowed to go off. 130 * <p> 131 * If the user presses the power button, then the {@link #SCREEN_DIM_WAKE_LOCK} will be 132 * implicitly released by the system, causing both the screen and the CPU to be turned off. 133 * Contrast with {@link #PARTIAL_WAKE_LOCK}. 134 * </p> 135 * 136 * @deprecated Most applications should use 137 * {@link android.view.WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON} instead 138 * of this type of wake lock, as it will be correctly managed by the platform 139 * as the user moves between applications and doesn't require a special permission. 140 */ 141 @Deprecated 142 public static final int SCREEN_DIM_WAKE_LOCK = 0x00000006; 143 144 /** 145 * Wake lock level: Ensures that the screen is on at full brightness; 146 * the keyboard backlight will be allowed to go off. 147 * <p> 148 * If the user presses the power button, then the {@link #SCREEN_BRIGHT_WAKE_LOCK} will be 149 * implicitly released by the system, causing both the screen and the CPU to be turned off. 150 * Contrast with {@link #PARTIAL_WAKE_LOCK}. 151 * </p> 152 * 153 * @deprecated Most applications should use 154 * {@link android.view.WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON} instead 155 * of this type of wake lock, as it will be correctly managed by the platform 156 * as the user moves between applications and doesn't require a special permission. 157 */ 158 @Deprecated 159 public static final int SCREEN_BRIGHT_WAKE_LOCK = 0x0000000a; 160 161 /** 162 * Wake lock level: Ensures that the screen and keyboard backlight are on at 163 * full brightness. 164 * <p> 165 * If the user presses the power button, then the {@link #FULL_WAKE_LOCK} will be 166 * implicitly released by the system, causing both the screen and the CPU to be turned off. 167 * Contrast with {@link #PARTIAL_WAKE_LOCK}. 168 * </p> 169 * 170 * @deprecated Most applications should use 171 * {@link android.view.WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON} instead 172 * of this type of wake lock, as it will be correctly managed by the platform 173 * as the user moves between applications and doesn't require a special permission. 174 */ 175 @Deprecated 176 public static final int FULL_WAKE_LOCK = 0x0000001a; 177 178 /** 179 * Wake lock level: Turns the screen off when the proximity sensor activates. 180 * <p> 181 * Since not all devices have proximity sensors, use {@link #isWakeLockLevelSupported} 182 * to determine whether this wake lock level is supported. 183 * </p> 184 * 185 * {@hide} 186 */ 187 public static final int PROXIMITY_SCREEN_OFF_WAKE_LOCK = 0x00000020; 188 189 /** 190 * Mask for the wake lock level component of a combined wake lock level and flags integer. 191 * 192 * @hide 193 */ 194 public static final int WAKE_LOCK_LEVEL_MASK = 0x0000ffff; 195 196 /** 197 * Wake lock flag: Turn the screen on when the wake lock is acquired. 198 * <p> 199 * Normally wake locks don't actually wake the device, they just cause 200 * the screen to remain on once it's already on. Think of the video player 201 * application as the normal behavior. Notifications that pop up and want 202 * the device to be on are the exception; use this flag to be like them. 203 * </p><p> 204 * Cannot be used with {@link #PARTIAL_WAKE_LOCK}. 205 * </p> 206 */ 207 public static final int ACQUIRE_CAUSES_WAKEUP = 0x10000000; 208 209 /** 210 * Wake lock flag: When this wake lock is released, poke the user activity timer 211 * so the screen stays on for a little longer. 212 * <p> 213 * Will not turn the screen on if it is not already on. 214 * See {@link #ACQUIRE_CAUSES_WAKEUP} if you want that. 215 * </p><p> 216 * Cannot be used with {@link #PARTIAL_WAKE_LOCK}. 217 * </p> 218 */ 219 public static final int ON_AFTER_RELEASE = 0x20000000; 220 221 /** 222 * Flag for {@link WakeLock#release release(int)} to defer releasing a 223 * {@link #WAKE_BIT_PROXIMITY_SCREEN_OFF} wake lock until the proximity sensor returns 224 * a negative value. 225 * 226 * {@hide} 227 */ 228 public static final int WAIT_FOR_PROXIMITY_NEGATIVE = 1; 229 230 /** 231 * Brightness value for fully on. 232 * @hide 233 */ 234 public static final int BRIGHTNESS_ON = 255; 235 236 /** 237 * Brightness value for fully off. 238 * @hide 239 */ 240 public static final int BRIGHTNESS_OFF = 0; 241 242 // Note: Be sure to update android.os.BatteryStats and PowerManager.h 243 // if adding or modifying user activity event constants. 244 245 /** 246 * User activity event type: Unspecified event type. 247 * @hide 248 */ 249 public static final int USER_ACTIVITY_EVENT_OTHER = 0; 250 251 /** 252 * User activity event type: Button or key pressed or released. 253 * @hide 254 */ 255 public static final int USER_ACTIVITY_EVENT_BUTTON = 1; 256 257 /** 258 * User activity event type: Touch down, move or up. 259 * @hide 260 */ 261 public static final int USER_ACTIVITY_EVENT_TOUCH = 2; 262 263 /** 264 * User activity flag: Do not restart the user activity timeout or brighten 265 * the display in response to user activity if it is already dimmed. 266 * @hide 267 */ 268 public static final int USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS = 1 << 0; 269 270 /** 271 * Go to sleep reason code: Going to sleep due by user request. 272 * @hide 273 */ 274 public static final int GO_TO_SLEEP_REASON_USER = 0; 275 276 /** 277 * Go to sleep reason code: Going to sleep due by request of the 278 * device administration policy. 279 * @hide 280 */ 281 public static final int GO_TO_SLEEP_REASON_DEVICE_ADMIN = 1; 282 283 /** 284 * Go to sleep reason code: Going to sleep due to a screen timeout. 285 * @hide 286 */ 287 public static final int GO_TO_SLEEP_REASON_TIMEOUT = 2; 288 289 final Context mContext; 290 final IPowerManager mService; 291 final Handler mHandler; 292 293 /** 294 * {@hide} 295 */ 296 public PowerManager(Context context, IPowerManager service, Handler handler) { 297 mContext = context; 298 mService = service; 299 mHandler = handler; 300 } 301 302 /** 303 * Gets the minimum supported screen brightness setting. 304 * The screen may be allowed to become dimmer than this value but 305 * this is the minimum value that can be set by the user. 306 * @hide 307 */ 308 public int getMinimumScreenBrightnessSetting() { 309 return mContext.getResources().getInteger( 310 com.android.internal.R.integer.config_screenBrightnessSettingMinimum); 311 } 312 313 /** 314 * Gets the maximum supported screen brightness setting. 315 * The screen may be allowed to become dimmer than this value but 316 * this is the maximum value that can be set by the user. 317 * @hide 318 */ 319 public int getMaximumScreenBrightnessSetting() { 320 return mContext.getResources().getInteger( 321 com.android.internal.R.integer.config_screenBrightnessSettingMaximum); 322 } 323 324 /** 325 * Gets the default screen brightness setting. 326 * @hide 327 */ 328 public int getDefaultScreenBrightnessSetting() { 329 return mContext.getResources().getInteger( 330 com.android.internal.R.integer.config_screenBrightnessSettingDefault); 331 } 332 333 /** 334 * Returns true if the screen auto-brightness adjustment setting should 335 * be available in the UI. This setting is experimental and disabled by default. 336 * @hide 337 */ 338 public static boolean useScreenAutoBrightnessAdjustmentFeature() { 339 return SystemProperties.getBoolean("persist.power.useautobrightadj", false); 340 } 341 342 /** 343 * Creates a new wake lock with the specified level and flags. 344 * <p> 345 * The {@code levelAndFlags} parameter specifies a wake lock level and optional flags 346 * combined using the logical OR operator. 347 * </p><p> 348 * The wake lock levels are: {@link #PARTIAL_WAKE_LOCK}, 349 * {@link #FULL_WAKE_LOCK}, {@link #SCREEN_DIM_WAKE_LOCK} 350 * and {@link #SCREEN_BRIGHT_WAKE_LOCK}. Exactly one wake lock level must be 351 * specified as part of the {@code levelAndFlags} parameter. 352 * </p><p> 353 * The wake lock flags are: {@link #ACQUIRE_CAUSES_WAKEUP} 354 * and {@link #ON_AFTER_RELEASE}. Multiple flags can be combined as part of the 355 * {@code levelAndFlags} parameters. 356 * </p><p> 357 * Call {@link WakeLock#acquire() acquire()} on the object to acquire the 358 * wake lock, and {@link WakeLock#release release()} when you are done. 359 * </p><p> 360 * {@samplecode 361 * PowerManager pm = (PowerManager)mContext.getSystemService( 362 * Context.POWER_SERVICE); 363 * PowerManager.WakeLock wl = pm.newWakeLock( 364 * PowerManager.SCREEN_DIM_WAKE_LOCK 365 * | PowerManager.ON_AFTER_RELEASE, 366 * TAG); 367 * wl.acquire(); 368 * // ... do work... 369 * wl.release(); 370 * } 371 * </p><p> 372 * Although a wake lock can be created without special permissions, 373 * the {@link android.Manifest.permission#WAKE_LOCK} permission is 374 * required to actually acquire or release the wake lock that is returned. 375 * </p><p class="note"> 376 * If using this to keep the screen on, you should strongly consider using 377 * {@link android.view.WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON} instead. 378 * This window flag will be correctly managed by the platform 379 * as the user moves between applications and doesn't require a special permission. 380 * </p> 381 * 382 * @param levelAndFlags Combination of wake lock level and flag values defining 383 * the requested behavior of the WakeLock. 384 * @param tag Your class name (or other tag) for debugging purposes. 385 * 386 * @see WakeLock#acquire() 387 * @see WakeLock#release() 388 * @see #PARTIAL_WAKE_LOCK 389 * @see #FULL_WAKE_LOCK 390 * @see #SCREEN_DIM_WAKE_LOCK 391 * @see #SCREEN_BRIGHT_WAKE_LOCK 392 * @see #ACQUIRE_CAUSES_WAKEUP 393 * @see #ON_AFTER_RELEASE 394 */ 395 public WakeLock newWakeLock(int levelAndFlags, String tag) { 396 validateWakeLockParameters(levelAndFlags, tag); 397 return new WakeLock(levelAndFlags, tag); 398 } 399 400 /** @hide */ 401 public static void validateWakeLockParameters(int levelAndFlags, String tag) { 402 switch (levelAndFlags & WAKE_LOCK_LEVEL_MASK) { 403 case PARTIAL_WAKE_LOCK: 404 case SCREEN_DIM_WAKE_LOCK: 405 case SCREEN_BRIGHT_WAKE_LOCK: 406 case FULL_WAKE_LOCK: 407 case PROXIMITY_SCREEN_OFF_WAKE_LOCK: 408 break; 409 default: 410 throw new IllegalArgumentException("Must specify a valid wake lock level."); 411 } 412 if (tag == null) { 413 throw new IllegalArgumentException("The tag must not be null."); 414 } 415 } 416 417 /** 418 * Notifies the power manager that user activity happened. 419 * <p> 420 * Resets the auto-off timer and brightens the screen if the device 421 * is not asleep. This is what happens normally when a key or the touch 422 * screen is pressed or when some other user activity occurs. 423 * This method does not wake up the device if it has been put to sleep. 424 * </p><p> 425 * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission. 426 * </p> 427 * 428 * @param when The time of the user activity, in the {@link SystemClock#uptimeMillis()} 429 * time base. This timestamp is used to correctly order the user activity with 430 * other power management functions. It should be set 431 * to the timestamp of the input event that caused the user activity. 432 * @param noChangeLights If true, does not cause the keyboard backlight to turn on 433 * because of this event. This is set when the power key is pressed. 434 * We want the device to stay on while the button is down, but we're about 435 * to turn off the screen so we don't want the keyboard backlight to turn on again. 436 * Otherwise the lights flash on and then off and it looks weird. 437 * 438 * @see #wakeUp 439 * @see #goToSleep 440 */ 441 public void userActivity(long when, boolean noChangeLights) { 442 try { 443 mService.userActivity(when, USER_ACTIVITY_EVENT_OTHER, 444 noChangeLights ? USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS : 0); 445 } catch (RemoteException e) { 446 } 447 } 448 449 /** 450 * Forces the device to go to sleep. 451 * <p> 452 * Overrides all the wake locks that are held. 453 * This is what happens when the power key is pressed to turn off the screen. 454 * </p><p> 455 * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission. 456 * </p> 457 * 458 * @param time The time when the request to go to sleep was issued, in the 459 * {@link SystemClock#uptimeMillis()} time base. This timestamp is used to correctly 460 * order the user activity with other power management functions. It should be set 461 * to the timestamp of the input event that caused the request to go to sleep. 462 * 463 * @see #userActivity 464 * @see #wakeUp 465 */ 466 public void goToSleep(long time) { 467 try { 468 mService.goToSleep(time, GO_TO_SLEEP_REASON_USER); 469 } catch (RemoteException e) { 470 } 471 } 472 473 /** 474 * Forces the device to wake up from sleep. 475 * <p> 476 * If the device is currently asleep, wakes it up, otherwise does nothing. 477 * This is what happens when the power key is pressed to turn on the screen. 478 * </p><p> 479 * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission. 480 * </p> 481 * 482 * @param time The time when the request to wake up was issued, in the 483 * {@link SystemClock#uptimeMillis()} time base. This timestamp is used to correctly 484 * order the user activity with other power management functions. It should be set 485 * to the timestamp of the input event that caused the request to wake up. 486 * 487 * @see #userActivity 488 * @see #goToSleep 489 */ 490 public void wakeUp(long time) { 491 try { 492 mService.wakeUp(time); 493 } catch (RemoteException e) { 494 } 495 } 496 497 /** 498 * Sets the brightness of the backlights (screen, keyboard, button). 499 * <p> 500 * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission. 501 * </p> 502 * 503 * @param brightness The brightness value from 0 to 255. 504 * 505 * {@hide} 506 */ 507 public void setBacklightBrightness(int brightness) { 508 try { 509 mService.setTemporaryScreenBrightnessSettingOverride(brightness); 510 } catch (RemoteException e) { 511 } 512 } 513 514 /** 515 * Returns true if the specified wake lock level is supported. 516 * 517 * @param level The wake lock level to check. 518 * @return True if the specified wake lock level is supported. 519 * 520 * {@hide} 521 */ 522 public boolean isWakeLockLevelSupported(int level) { 523 try { 524 return mService.isWakeLockLevelSupported(level); 525 } catch (RemoteException e) { 526 return false; 527 } 528 } 529 530 /** 531 * Returns whether the screen is currently on. 532 * <p> 533 * Only indicates whether the screen is on. The screen could be either bright or dim. 534 * </p><p> 535 * {@samplecode 536 * PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); 537 * boolean isScreenOn = pm.isScreenOn(); 538 * } 539 * </p> 540 * 541 * @return whether the screen is on (bright or dim). 542 */ 543 public boolean isScreenOn() { 544 try { 545 return mService.isScreenOn(); 546 } catch (RemoteException e) { 547 return false; 548 } 549 } 550 551 /** 552 * Reboot the device. Will not return if the reboot is successful. 553 * <p> 554 * Requires the {@link android.Manifest.permission#REBOOT} permission. 555 * </p> 556 * 557 * @param reason code to pass to the kernel (e.g., "recovery") to 558 * request special boot modes, or null. 559 */ 560 public void reboot(String reason) { 561 try { 562 mService.reboot(reason); 563 } catch (RemoteException e) { 564 } 565 } 566 567 /** 568 * A wake lock is a mechanism to indicate that your application needs 569 * to have the device stay on. 570 * <p> 571 * Any application using a WakeLock must request the {@code android.permission.WAKE_LOCK} 572 * permission in an {@code <uses-permission>} element of the application's manifest. 573 * Obtain a wake lock by calling {@link PowerManager#newWakeLock(int, String)}. 574 * </p><p> 575 * Call {@link #acquire()} to acquire the wake lock and force the device to stay 576 * on at the level that was requested when the wake lock was created. 577 * </p><p> 578 * Call {@link #release()} when you are done and don't need the lock anymore. 579 * It is very important to do this as soon as possible to avoid running down the 580 * device's battery excessively. 581 * </p> 582 */ 583 public final class WakeLock { 584 private final int mFlags; 585 private final String mTag; 586 private final IBinder mToken; 587 private int mCount; 588 private boolean mRefCounted = true; 589 private boolean mHeld; 590 private WorkSource mWorkSource; 591 592 private final Runnable mReleaser = new Runnable() { 593 public void run() { 594 release(); 595 } 596 }; 597 598 WakeLock(int flags, String tag) { 599 mFlags = flags; 600 mTag = tag; 601 mToken = new Binder(); 602 } 603 604 @Override 605 protected void finalize() throws Throwable { 606 synchronized (mToken) { 607 if (mHeld) { 608 Log.wtf(TAG, "WakeLock finalized while still held: " + mTag); 609 try { 610 mService.releaseWakeLock(mToken, 0); 611 } catch (RemoteException e) { 612 } 613 } 614 } 615 } 616 617 /** 618 * Sets whether this WakeLock is reference counted. 619 * <p> 620 * Wake locks are reference counted by default. If a wake lock is 621 * reference counted, then each call to {@link #acquire()} must be 622 * balanced by an equal number of calls to {@link #release()}. If a wake 623 * lock is not reference counted, then one call to {@link #release()} is 624 * sufficient to undo the effect of all previous calls to {@link #acquire()}. 625 * </p> 626 * 627 * @param value True to make the wake lock reference counted, false to 628 * make the wake lock non-reference counted. 629 */ 630 public void setReferenceCounted(boolean value) { 631 synchronized (mToken) { 632 mRefCounted = value; 633 } 634 } 635 636 /** 637 * Acquires the wake lock. 638 * <p> 639 * Ensures that the device is on at the level requested when 640 * the wake lock was created. 641 * </p> 642 */ 643 public void acquire() { 644 synchronized (mToken) { 645 acquireLocked(); 646 } 647 } 648 649 /** 650 * Acquires the wake lock with a timeout. 651 * <p> 652 * Ensures that the device is on at the level requested when 653 * the wake lock was created. The lock will be released after the given timeout 654 * expires. 655 * </p> 656 * 657 * @param timeout The timeout after which to release the wake lock, in milliseconds. 658 */ 659 public void acquire(long timeout) { 660 synchronized (mToken) { 661 acquireLocked(); 662 mHandler.postDelayed(mReleaser, timeout); 663 } 664 } 665 666 private void acquireLocked() { 667 if (!mRefCounted || mCount++ == 0) { 668 // Do this even if the wake lock is already thought to be held (mHeld == true) 669 // because non-reference counted wake locks are not always properly released. 670 // For example, the keyguard's wake lock might be forcibly released by the 671 // power manager without the keyguard knowing. A subsequent call to acquire 672 // should immediately acquire the wake lock once again despite never having 673 // been explicitly released by the keyguard. 674 mHandler.removeCallbacks(mReleaser); 675 try { 676 mService.acquireWakeLock(mToken, mFlags, mTag, mWorkSource); 677 } catch (RemoteException e) { 678 } 679 mHeld = true; 680 } 681 } 682 683 /** 684 * Releases the wake lock. 685 * <p> 686 * This method releases your claim to the CPU or screen being on. 687 * The screen may turn off shortly after you release the wake lock, or it may 688 * not if there are other wake locks still held. 689 * </p> 690 */ 691 public void release() { 692 release(0); 693 } 694 695 /** 696 * Releases the wake lock with flags to modify the release behavior. 697 * <p> 698 * This method releases your claim to the CPU or screen being on. 699 * The screen may turn off shortly after you release the wake lock, or it may 700 * not if there are other wake locks still held. 701 * </p> 702 * 703 * @param flags Combination of flag values to modify the release behavior. 704 * Currently only {@link #WAIT_FOR_PROXIMITY_NEGATIVE} is supported. 705 * 706 * {@hide} 707 */ 708 public void release(int flags) { 709 synchronized (mToken) { 710 if (!mRefCounted || --mCount == 0) { 711 mHandler.removeCallbacks(mReleaser); 712 if (mHeld) { 713 try { 714 mService.releaseWakeLock(mToken, flags); 715 } catch (RemoteException e) { 716 } 717 mHeld = false; 718 } 719 } 720 if (mCount < 0) { 721 throw new RuntimeException("WakeLock under-locked " + mTag); 722 } 723 } 724 } 725 726 /** 727 * Returns true if the wake lock has been acquired but not yet released. 728 * 729 * @return True if the wake lock is held. 730 */ 731 public boolean isHeld() { 732 synchronized (mToken) { 733 return mHeld; 734 } 735 } 736 737 /** 738 * Sets the work source associated with the wake lock. 739 * <p> 740 * The work source is used to determine on behalf of which application 741 * the wake lock is being held. This is useful in the case where a 742 * service is performing work on behalf of an application so that the 743 * cost of that work can be accounted to the application. 744 * </p> 745 * 746 * @param ws The work source, or null if none. 747 */ 748 public void setWorkSource(WorkSource ws) { 749 synchronized (mToken) { 750 if (ws != null && ws.size() == 0) { 751 ws = null; 752 } 753 754 final boolean changed; 755 if (ws == null) { 756 changed = mWorkSource != null; 757 mWorkSource = null; 758 } else if (mWorkSource == null) { 759 changed = true; 760 mWorkSource = new WorkSource(ws); 761 } else { 762 changed = mWorkSource.diff(ws); 763 if (changed) { 764 mWorkSource.set(ws); 765 } 766 } 767 768 if (changed && mHeld) { 769 try { 770 mService.updateWakeLockWorkSource(mToken, mWorkSource); 771 } catch (RemoteException e) { 772 } 773 } 774 } 775 } 776 777 @Override 778 public String toString() { 779 synchronized (mToken) { 780 return "WakeLock{" 781 + Integer.toHexString(System.identityHashCode(this)) 782 + " held=" + mHeld + ", refCount=" + mCount + "}"; 783 } 784 } 785 } 786} 787