diff --git a/api/16.txt b/api/16.txt index 70c4032dc643c..513327c86cbf7 100644 --- a/api/16.txt +++ b/api/16.txt @@ -15962,7 +15962,7 @@ package android.os { field public static final int PATTERN_SIMPLE_GLOB = 2; // 0x2 } - public class PowerManager { + public final class PowerManager { method public void goToSleep(long); method public boolean isScreenOn(); method public android.os.PowerManager.WakeLock newWakeLock(int, java.lang.String); @@ -15976,7 +15976,7 @@ package android.os { field public static final int SCREEN_DIM_WAKE_LOCK = 6; // 0x6 } - public class PowerManager.WakeLock { + public final class PowerManager.WakeLock { method public void acquire(); method public void acquire(long); method public boolean isHeld(); diff --git a/api/current.txt b/api/current.txt index 89f265ddd0914..9e768cce1a902 100644 --- a/api/current.txt +++ b/api/current.txt @@ -15979,7 +15979,7 @@ package android.os { field public static final int PATTERN_SIMPLE_GLOB = 2; // 0x2 } - public class PowerManager { + public final class PowerManager { method public void goToSleep(long); method public boolean isScreenOn(); method public android.os.PowerManager.WakeLock newWakeLock(int, java.lang.String); @@ -15993,7 +15993,7 @@ package android.os { field public static final int SCREEN_DIM_WAKE_LOCK = 6; // 0x6 } - public class PowerManager.WakeLock { + public final class PowerManager.WakeLock { method public void acquire(); method public void acquire(long); method public boolean isHeld(); diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index 903c8b3cde12b..318c0ae00bbbf 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -19,19 +19,21 @@ package android.os; import android.util.Log; /** - * This class gives you control of the power state of the device. - * - *

Device battery life will be significantly affected by the use of this API. Do not - * acquire WakeLocks unless you really need them, use the minimum levels possible, and be sure - * to release it as soon as you can. - * - *

You can obtain an instance of this class by calling + * This class gives you control of the power state of the device. + * + *

+ * Device battery life will be significantly affected by the use of this API. + * Do not acquire {@link WakeLock}s unless you really need them, use the minimum levels + * possible, and be sure to release them as soon as possible. + *

+ * You can obtain an instance of this class by calling * {@link android.content.Context#getSystemService(java.lang.String) Context.getSystemService()}. - * - *

The primary API you'll use is {@link #newWakeLock(int, String) newWakeLock()}. This will - * create a {@link PowerManager.WakeLock} object. You can then use methods on this object to - * control the power state of the device. In practice it's quite simple: - * + *

+ * The primary API you'll use is {@link #newWakeLock(int, String) newWakeLock()}. + * This will create a {@link PowerManager.WakeLock} object. You can then use methods + * on the wake lock object to control the power state of the device. + *

+ * In practice it's quite simple: * {@samplecode * PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); * PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "My Tag"); @@ -39,11 +41,11 @@ import android.util.Log; * ..screen will stay on during this section.. * wl.release(); * } - * - *

The following flags are defined, with varying effects on system power. These flags are - * mutually exclusive - you may only specify one of them. - * + *

+ * The following flags are defined, with varying effects on system power. + * These flags are mutually exclusive - you may only specify one of them. * + *

* * * @@ -67,15 +69,16 @@ import android.util.Log; * * *
Flag ValueCPU Screen Keyboard
- * - *

*If you hold a partial wakelock, the CPU will continue to run, irrespective of any timers - * and even after the user presses the power button. In all other wakelocks, the CPU will run, but - * the user can still put the device to sleep using the power button. - * - *

In addition, you can add two more flags, which affect behavior of the screen only. These - * flags have no effect when combined with a {@link #PARTIAL_WAKE_LOCK}. - * + *

+ * *If you hold a partial wake lock, the CPU will continue to run, regardless of any + * display timeouts or the state of the screen and even after the user presses the power button. + * In all other wake locks, the CPU will run, but the user can still put the device to sleep + * using the power button. + *

+ * In addition, you can add two more flags, which affect behavior of the screen only. + * These flags have no effect when combined with a {@link #PARTIAL_WAKE_LOCK}. * + *

* * * @@ -96,73 +99,77 @@ import android.util.Log; * * *
Flag Value Description
- * + *

* Any application using a WakeLock must request the {@code android.permission.WAKE_LOCK} * permission in an {@code <uses-permission>} element of the application's manifest. + *

*/ -public class PowerManager -{ +public final class PowerManager { private static final String TAG = "PowerManager"; - - /** + + /* * These internal values define the underlying power elements that we might * want to control individually. Eventually we'd like to expose them. */ - private static final int WAKE_BIT_CPU_STRONG = 1; - private static final int WAKE_BIT_CPU_WEAK = 2; - private static final int WAKE_BIT_SCREEN_DIM = 4; - private static final int WAKE_BIT_SCREEN_BRIGHT = 8; - private static final int WAKE_BIT_KEYBOARD_BRIGHT = 16; - private static final int WAKE_BIT_PROXIMITY_SCREEN_OFF = 32; - + private static final int WAKE_BIT_CPU_STRONG = 1 << 0; + private static final int WAKE_BIT_CPU_WEAK = 1 << 1; + private static final int WAKE_BIT_SCREEN_DIM = 1 << 2; + private static final int WAKE_BIT_SCREEN_BRIGHT = 1 << 3; + private static final int WAKE_BIT_KEYBOARD_BRIGHT = 1 << 4; + private static final int WAKE_BIT_PROXIMITY_SCREEN_OFF = 1 << 5; + private static final int LOCK_MASK = WAKE_BIT_CPU_STRONG - | WAKE_BIT_CPU_WEAK - | WAKE_BIT_SCREEN_DIM - | WAKE_BIT_SCREEN_BRIGHT - | WAKE_BIT_KEYBOARD_BRIGHT - | WAKE_BIT_PROXIMITY_SCREEN_OFF; + | WAKE_BIT_CPU_WEAK + | WAKE_BIT_SCREEN_DIM + | WAKE_BIT_SCREEN_BRIGHT + | WAKE_BIT_KEYBOARD_BRIGHT + | WAKE_BIT_PROXIMITY_SCREEN_OFF; /** - * Wake lock that ensures that the CPU is running. The screen might - * not be on. + * Wake lock level: Ensures that the CPU is running; the screen and keyboard + * backlight will be allowed to go off. */ public static final int PARTIAL_WAKE_LOCK = WAKE_BIT_CPU_STRONG; /** - * Wake lock that ensures that the screen and keyboard are on at + * Wake lock level: Ensures that the screen and keyboard backlight are on at * full brightness. * - *

Most applications should strongly consider using - * {@link android.view.WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON}. - * This window flag will be correctly managed by the platform - * as the user moves between applications and doesn't require a special permission.

+ *

+ * Most applications should strongly consider using + * {@link android.view.WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON} instead + * of managing their own wake locks. This window flag will be correctly managed + * by the platform as the user moves between applications and doesn't require + * a special permission. + *

*/ public static final int FULL_WAKE_LOCK = WAKE_BIT_CPU_WEAK | WAKE_BIT_SCREEN_BRIGHT - | WAKE_BIT_KEYBOARD_BRIGHT; + | WAKE_BIT_KEYBOARD_BRIGHT; /** + * Wake lock level: Ensures that the screen is on at full brightness; + * the keyboard backlight will be allowed to go off. + * * @deprecated Most applications should use * {@link android.view.WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON} instead * of this type of wake lock, as it will be correctly managed by the platform * as the user moves between applications and doesn't require a special permission. - * - * Wake lock that ensures that the screen is on at full brightness; - * the keyboard backlight will be allowed to go off. */ @Deprecated public static final int SCREEN_BRIGHT_WAKE_LOCK = WAKE_BIT_CPU_WEAK | WAKE_BIT_SCREEN_BRIGHT; /** - * Wake lock that ensures that the screen is on (but may be dimmed); + * Wake lock level: Ensures that the screen is on (but may be dimmed); * the keyboard backlight will be allowed to go off. */ public static final int SCREEN_DIM_WAKE_LOCK = WAKE_BIT_CPU_WEAK | WAKE_BIT_SCREEN_DIM; /** - * Wake lock that turns the screen off when the proximity sensor activates. - * Since not all devices have proximity sensors, use - * {@link #getSupportedWakeLockFlags() getSupportedWakeLockFlags()} to determine if - * this wake lock mode is supported. + * Wake lock level: Turns the screen off when the proximity sensor activates. + *

+ * Since not all devices have proximity sensors, use {@link #getSupportedWakeLockFlags()} + * to determine whether this wake lock level is supported. + *

* * {@hide} */ @@ -170,7 +177,7 @@ public class PowerManager /** * Flag for {@link WakeLock#release release(int)} to defer releasing a - * {@link #WAKE_BIT_PROXIMITY_SCREEN_OFF} wakelock until the proximity sensor returns + * {@link #WAKE_BIT_PROXIMITY_SCREEN_OFF} wake lock until the proximity sensor returns * a negative value. * * {@hide} @@ -178,25 +185,29 @@ public class PowerManager public static final int WAIT_FOR_PROXIMITY_NEGATIVE = 1; /** + * Wake lock flag: Turn the screen on when the wake lock is acquired. + *

* Normally wake locks don't actually wake the device, they just cause - * it to remain on once it's already on. Think of the video player - * app as the normal behavior. Notifications that pop up and want + * the screen to remain on once it's already on. Think of the video player + * application as the normal behavior. Notifications that pop up and want * the device to be on are the exception; use this flag to be like them. - *

- * Does not work with PARTIAL_WAKE_LOCKs. + *

+ * Cannot be used with {@link #PARTIAL_WAKE_LOCK}. + *

*/ - public static final int ACQUIRE_CAUSES_WAKEUP = 0x10000000; + public static final int ACQUIRE_CAUSES_WAKEUP = 1 << 28; /** - * When this wake lock is released, poke the user activity timer + * Wake lock flag: When this wake lock is released, poke the user activity timer * so the screen stays on for a little longer. *

- * Will not turn the screen on if it is not already on. See {@link #ACQUIRE_CAUSES_WAKEUP} - * if you want that. - *

- * Does not work with PARTIAL_WAKE_LOCKs. + * Will not turn the screen on if it is not already on. + * See {@link #ACQUIRE_CAUSES_WAKEUP} if you want that. + *

+ * Cannot be used with {@link #PARTIAL_WAKE_LOCK}. + *

*/ - public static final int ON_AFTER_RELEASE = 0x20000000; + public static final int ON_AFTER_RELEASE = 1 << 29; /** * Brightness value to use when battery is low. @@ -222,179 +233,253 @@ public class PowerManager */ public static final int BRIGHTNESS_OFF = 0; + final IPowerManager mService; + final Handler mHandler; + /** - * Class lets you say that you need to have the device on. + * {@hide} + */ + public PowerManager(IPowerManager service, Handler handler) { + mService = service; + mHandler = handler; + } + + /** + * Creates a new wake lock with the specified level and flags. *

- * Call release when you are done and don't need the lock anymore. + * The {@code levelAndFlags} parameter specifies a wake lock level and optional flags + * combined using the logical OR operator. + *

+ * The wake lock levels are: {@link #PARTIAL_WAKE_LOCK}, + * {@link #FULL_WAKE_LOCK}, {@link #SCREEN_DIM_WAKE_LOCK} + * and {@link #SCREEN_BRIGHT_WAKE_LOCK}. Exactly one wake lock level must be + * specified as part of the {@code levelAndFlags} parameter. + *

+ * The wake lock flags are: {@link #ACQUIRE_CAUSES_WAKEUP} + * and {@link #ON_AFTER_RELEASE}. Multiple flags can be combined as part of the + * {@code levelAndFlags} parameters. + *

+ * Call {@link WakeLock#acquire() acquire()} on the object to acquire the + * wake lock, and {@link WakeLock#release release()} when you are done. + *

+ * {@samplecode + * PowerManager pm = (PowerManager)mContext.getSystemService( + * Context.POWER_SERVICE); + * PowerManager.WakeLock wl = pm.newWakeLock( + * PowerManager.SCREEN_DIM_WAKE_LOCK + * | PowerManager.ON_AFTER_RELEASE, + * TAG); + * wl.acquire(); + * // ... do work... + * wl.release(); + * } + *

+ * Although a wake lock can be created without special permissions, + * the {@link android.Manifest.permission#WAKE_LOCK} permission is + * required to actually acquire or release the wake lock that is returned. + *

+ * If using this to keep the screen on, you should strongly consider using + * {@link android.view.WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON} instead. + * This window flag will be correctly managed by the platform + * as the user moves between applications and doesn't require a special permission. + *

+ * + * @param levelAndFlags Combination of wake lock level and flag values defining + * the requested behavior of the WakeLock. + * @param tag Your class name (or other tag) for debugging purposes. + * + * @see WakeLock#acquire() + * @see WakeLock#release() + * @see #PARTIAL_WAKE_LOCK + * @see #FULL_WAKE_LOCK + * @see #SCREEN_DIM_WAKE_LOCK + * @see #SCREEN_BRIGHT_WAKE_LOCK + * @see #ACQUIRE_CAUSES_WAKEUP + * @see #ON_AFTER_RELEASE + */ + public WakeLock newWakeLock(int levelAndFlags, String tag) { + switch (levelAndFlags & LOCK_MASK) { + case PARTIAL_WAKE_LOCK: + case SCREEN_DIM_WAKE_LOCK: + case SCREEN_BRIGHT_WAKE_LOCK: + case FULL_WAKE_LOCK: + case PROXIMITY_SCREEN_OFF_WAKE_LOCK: + break; + default: + throw new IllegalArgumentException("Must specify a wake lock level."); + } + if (tag == null) { + throw new IllegalArgumentException("The tag must not be null."); + } + return new WakeLock(levelAndFlags, tag); + } + + /** + * Notifies the power manager that user activity happened. + *

+ * Turns the device from whatever state it's in to full on, and resets + * the auto-off timer. + *

+ * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission. + *

+ * + * @param when The time of the user activity, in the {@link SystemClock#uptimeMillis()} + * time base. This timestamp is used to correctly order the user activity with + * other power management functions. It should be set + * to the timestamp of the input event that caused the user activity. + * @param noChangeLights If true, does not cause the keyboard backlight to turn on + * because of this event. This is set when the power key is pressed. + * We want the device to stay on while the button is down, but we're about + * to turn off the screen so we don't want the keyboard backlight to turn on again. + * Otherwise the lights flash on and then off and it looks weird. + */ + public void userActivity(long when, boolean noChangeLights) { + try { + mService.userActivity(when, noChangeLights); + } catch (RemoteException e) { + } + } + + /** + * Forces the device to go to sleep. + *

+ * Overrides all the wake locks that are held. This is what happen when the power + * key is pressed to turn off the screen. + *

+ * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission. + *

+ * + * @param time The time when the request to go to sleep was issued, in the + * {@link SystemClock#uptimeMillis()} time base. This timestamp is used to correctly + * order the user activity with other power management functions. It should be set + * to the timestamp of the input event that caused the request to go to sleep. + */ + public void goToSleep(long time) { + try { + mService.goToSleep(time); + } catch (RemoteException e) { + } + } + + /** + * Sets the brightness of the backlights (screen, keyboard, button). + *

+ * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission. + *

+ * + * @param brightness The brightness value from 0 to 255. + * + * {@hide} + */ + public void setBacklightBrightness(int brightness) { + try { + mService.setBacklightBrightness(brightness); + } catch (RemoteException e) { + } + } + + /** + * Returns the set of wake lock levels and flags for {@link #newWakeLock} + * that are supported on the device. + *

+ * For example, to test to see if the {@link #PROXIMITY_SCREEN_OFF_WAKE_LOCK} + * is supported: + * {@samplecode + * PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); + * int supportedFlags = pm.getSupportedWakeLockFlags(); + * boolean proximitySupported = ((supportedFlags & PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) + * == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK); + * } + *

+ * + * @return The set of supported WakeLock flags. + * + * {@hide} + */ + public int getSupportedWakeLockFlags() { + try { + return mService.getSupportedWakeLockFlags(); + } catch (RemoteException e) { + return 0; + } + } + + /** + * Returns whether the screen is currently on. + *

+ * Only indicates whether the screen is on. The screen could be either bright or dim. + *

+ * {@samplecode + * PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); + * boolean isScreenOn = pm.isScreenOn(); + * } + *

+ * + * @return whether the screen is on (bright or dim). + */ + public boolean isScreenOn() { + try { + return mService.isScreenOn(); + } catch (RemoteException e) { + return false; + } + } + + /** + * Reboot the device. Will not return if the reboot is successful. + *

+ * Requires the {@link android.Manifest.permission#REBOOT} permission. + *

+ * + * @param reason code to pass to the kernel (e.g., "recovery") to + * request special boot modes, or null. + */ + public void reboot(String reason) { + try { + mService.reboot(reason); + } catch (RemoteException e) { + } + } + + /** + * A wake lock is a mechanism to indicate that your application needs + * to have the device stay on. *

* Any application using a WakeLock must request the {@code android.permission.WAKE_LOCK} * permission in an {@code <uses-permission>} element of the application's manifest. + * Obtain a wake lock by calling {@link PowerManager#newWakeLock(int, String)}. + *

+ * Call {@link #acquire()} to acquire the wake lock and force the device to stay + * on at the level that was requested when the wake lock was created. + *

+ * Call {@link #release()} when you are done and don't need the lock anymore. + * It is very important to do this as soon as possible to avoid running down the + * device's battery excessively. + *

*/ - public class WakeLock - { - static final int RELEASE_WAKE_LOCK = 1; + public final class WakeLock { + private final int mFlags; + private final String mTag; + private final IBinder mToken; + private int mCount; + private boolean mRefCounted = true; + private boolean mHeld; + private WorkSource mWorkSource; - Runnable mReleaser = new Runnable() { + private final Runnable mReleaser = new Runnable() { public void run() { release(); } }; - - int mFlags; - String mTag; - IBinder mToken; - int mCount = 0; - boolean mRefCounted = true; - boolean mHeld = false; - WorkSource mWorkSource; - - WakeLock(int flags, String tag) - { - switch (flags & LOCK_MASK) { - case PARTIAL_WAKE_LOCK: - case SCREEN_DIM_WAKE_LOCK: - case SCREEN_BRIGHT_WAKE_LOCK: - case FULL_WAKE_LOCK: - case PROXIMITY_SCREEN_OFF_WAKE_LOCK: - break; - default: - throw new IllegalArgumentException(); - } + WakeLock(int flags, String tag) { mFlags = flags; mTag = tag; mToken = new Binder(); } - /** - * Sets whether this WakeLock is ref counted. - * - *

Wake locks are reference counted by default. - * - * @param value true for ref counted, false for not ref counted. - */ - public void setReferenceCounted(boolean value) - { - mRefCounted = value; - } - - /** - * Makes sure the device is on at the level you asked when you created - * the wake lock. - */ - public void acquire() - { - synchronized (mToken) { - acquireLocked(); - } - } - - /** - * Makes sure the device is on at the level you asked when you created - * the wake lock. The lock will be released after the given timeout. - * - * @param timeout Release the lock after the give timeout in milliseconds. - */ - public void acquire(long timeout) { - synchronized (mToken) { - acquireLocked(); - mHandler.postDelayed(mReleaser, timeout); - } - } - - private void acquireLocked() { - if (!mRefCounted || mCount++ == 0) { - mHandler.removeCallbacks(mReleaser); - try { - mService.acquireWakeLock(mFlags, mToken, mTag, mWorkSource); - } catch (RemoteException e) { - } - mHeld = true; - } - } - - /** - * Release your claim to the CPU or screen being on. - * - *

- * It may turn off shortly after you release it, or it may not if there - * are other wake locks held. - */ - public void release() { - release(0); - } - - /** - * Release your claim to the CPU or screen being on. - * @param flags Combination of flag values to modify the release behavior. - * Currently only {@link #WAIT_FOR_PROXIMITY_NEGATIVE} is supported. - * - *

- * It may turn off shortly after you release it, or it may not if there - * are other wake locks held. - * - * {@hide} - */ - public void release(int flags) { - synchronized (mToken) { - if (!mRefCounted || --mCount == 0) { - mHandler.removeCallbacks(mReleaser); - try { - mService.releaseWakeLock(mToken, flags); - } catch (RemoteException e) { - } - mHeld = false; - } - if (mCount < 0) { - throw new RuntimeException("WakeLock under-locked " + mTag); - } - } - } - - public boolean isHeld() - { - synchronized (mToken) { - return mHeld; - } - } - - public void setWorkSource(WorkSource ws) { - synchronized (mToken) { - if (ws != null && ws.size() == 0) { - ws = null; - } - boolean changed = true; - if (ws == null) { - mWorkSource = null; - } else if (mWorkSource == null) { - changed = mWorkSource != null; - mWorkSource = new WorkSource(ws); - } else { - changed = mWorkSource.diff(ws); - if (changed) { - mWorkSource.set(ws); - } - } - if (changed && mHeld) { - try { - mService.updateWakeLockWorkSource(mToken, mWorkSource); - } catch (RemoteException e) { - } - } - } - } - - public String toString() { - synchronized (mToken) { - return "WakeLock{" - + Integer.toHexString(System.identityHashCode(this)) - + " held=" + mHeld + ", refCount=" + mCount + "}"; - } - } - @Override - protected void finalize() throws Throwable - { + protected void finalize() throws Throwable { synchronized (mToken) { if (mHeld) { Log.wtf(TAG, "WakeLock finalized while still held: " + mTag); @@ -405,180 +490,170 @@ public class PowerManager } } } - } - /** - * Get a wake lock at the level of the flags parameter. Call - * {@link WakeLock#acquire() acquire()} on the object to acquire the - * wake lock, and {@link WakeLock#release release()} when you are done. - * - * {@samplecode - *PowerManager pm = (PowerManager)mContext.getSystemService( - * Context.POWER_SERVICE); - *PowerManager.WakeLock wl = pm.newWakeLock( - * PowerManager.SCREEN_DIM_WAKE_LOCK - * | PowerManager.ON_AFTER_RELEASE, - * TAG); - *wl.acquire(); - * // ... - *wl.release(); - * } - * - *

If using this to keep the screen on, you should strongly consider using - * {@link android.view.WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON} instead. - * This window flag will be correctly managed by the platform - * as the user moves between applications and doesn't require a special permission.

- * - * @param flags Combination of flag values defining the requested behavior of the WakeLock. - * @param tag Your class name (or other tag) for debugging purposes. - * - * @see WakeLock#acquire() - * @see WakeLock#release() - */ - public WakeLock newWakeLock(int flags, String tag) - { - if (tag == null) { - throw new NullPointerException("tag is null in PowerManager.newWakeLock"); + /** + * Sets whether this WakeLock is reference counted. + *

+ * Wake locks are reference counted by default. If a wake lock is + * reference counted, then each call to {@link #acquire()} must be + * balanced by an equal number of calls to {@link #release()}. If a wake + * lock is not reference counted, then one call to {@link #release()} is + * sufficient to undo the effect of all previous calls to {@link #acquire()}. + *

+ * + * @param value True to make the wake lock reference counted, false to + * make the wake lock non-reference counted. + */ + public void setReferenceCounted(boolean value) { + synchronized (mToken) { + mRefCounted = value; + } } - return new WakeLock(flags, tag); - } - /** - * User activity happened. - *

- * Turns the device from whatever state it's in to full on, and resets - * the auto-off timer. - * - * @param when is used to order this correctly with the wake lock calls. - * This time should be in the {@link SystemClock#uptimeMillis - * SystemClock.uptimeMillis()} time base. - * @param noChangeLights should be true if you don't want the lights to - * turn on because of this event. This is set when the power - * key goes down. We want the device to stay on while the button - * is down, but we're about to turn off. Otherwise the lights - * flash on and then off and it looks weird. - */ - public void userActivity(long when, boolean noChangeLights) - { - try { - mService.userActivity(when, noChangeLights); - } catch (RemoteException e) { + /** + * Acquires the wake lock. + *

+ * Ensures that the device is on at the level requested when + * the wake lock was created. + *

+ */ + public void acquire() { + synchronized (mToken) { + acquireLocked(); + } + } + + /** + * Acquires the wake lock with a timeout. + *

+ * Ensures that the device is on at the level requested when + * the wake lock was created. The lock will be released after the given timeout + * expires. + *

+ * + * @param timeout The timeout after which to release the wake lock, in milliseconds. + */ + public void acquire(long timeout) { + synchronized (mToken) { + acquireLocked(); + mHandler.postDelayed(mReleaser, timeout); + } + } + + private void acquireLocked() { + if (!mRefCounted || mCount++ == 0) { + mHandler.removeCallbacks(mReleaser); + if (!mHeld) { + try { + mService.acquireWakeLock(mFlags, mToken, mTag, mWorkSource); + } catch (RemoteException e) { + } + mHeld = true; + } + } + } + + /** + * Releases the wake lock. + *

+ * This method releases your claim to the CPU or screen being on. + * The screen may turn off shortly after you release the wake lock, or it may + * not if there are other wake locks still held. + *

+ */ + public void release() { + release(0); + } + + /** + * Releases the wake lock with flags to modify the release behavior. + *

+ * This method releases your claim to the CPU or screen being on. + * The screen may turn off shortly after you release the wake lock, or it may + * not if there are other wake locks still held. + *

+ * + * @param flags Combination of flag values to modify the release behavior. + * Currently only {@link #WAIT_FOR_PROXIMITY_NEGATIVE} is supported. + * + * {@hide} + */ + public void release(int flags) { + synchronized (mToken) { + if (!mRefCounted || --mCount == 0) { + mHandler.removeCallbacks(mReleaser); + if (mHeld) { + try { + mService.releaseWakeLock(mToken, flags); + } catch (RemoteException e) { + } + mHeld = false; + } + } + if (mCount < 0) { + throw new RuntimeException("WakeLock under-locked " + mTag); + } + } + } + + /** + * Returns true if the wake lock has been acquired but not yet released. + * + * @return True if the wake lock is held. + */ + public boolean isHeld() { + synchronized (mToken) { + return mHeld; + } + } + + /** + * Sets the work source associated with the wake lock. + *

+ * The work source is used to determine on behalf of which application + * the wake lock is being held. This is useful in the case where a + * service is performing work on behalf of an application so that the + * cost of that work can be accounted to the application. + *

+ * + * @param ws The work source, or null if none. + */ + public void setWorkSource(WorkSource ws) { + synchronized (mToken) { + if (ws != null && ws.size() == 0) { + ws = null; + } + + final boolean changed; + if (ws == null) { + changed = mWorkSource != null; + mWorkSource = null; + } else if (mWorkSource == null) { + changed = true; + mWorkSource = new WorkSource(ws); + } else { + changed = mWorkSource.diff(ws); + if (changed) { + mWorkSource.set(ws); + } + } + + if (changed && mHeld) { + try { + mService.updateWakeLockWorkSource(mToken, mWorkSource); + } catch (RemoteException e) { + } + } + } + } + + @Override + public String toString() { + synchronized (mToken) { + return "WakeLock{" + + Integer.toHexString(System.identityHashCode(this)) + + " held=" + mHeld + ", refCount=" + mCount + "}"; + } } } - - /** - * Force the device to go to sleep. Overrides all the wake locks that are - * held. - * - * @param time is used to order this correctly with the wake lock calls. - * The time should be in the {@link SystemClock#uptimeMillis - * SystemClock.uptimeMillis()} time base. - */ - public void goToSleep(long time) - { - try { - mService.goToSleep(time); - } catch (RemoteException e) { - } - } - - /** - * sets the brightness of the backlights (screen, keyboard, button). - * - * @param brightness value from 0 to 255 - * - * {@hide} - */ - public void setBacklightBrightness(int brightness) - { - try { - mService.setBacklightBrightness(brightness); - } catch (RemoteException e) { - } - } - - /** - * Returns the set of flags for {@link #newWakeLock(int, String) newWakeLock()} - * that are supported on the device. - * For example, to test to see if the {@link #PROXIMITY_SCREEN_OFF_WAKE_LOCK} - * is supported: - * - * {@samplecode - * PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); - * int supportedFlags = pm.getSupportedWakeLockFlags(); - * boolean proximitySupported = ((supportedFlags & PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) - * == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK); - * } - * - * @return the set of supported WakeLock flags. - * - * {@hide} - */ - public int getSupportedWakeLockFlags() - { - try { - return mService.getSupportedWakeLockFlags(); - } catch (RemoteException e) { - return 0; - } - } - - /** - * Returns whether the screen is currently on. The screen could be bright - * or dim. - * - * {@samplecode - * PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); - * boolean isScreenOn = pm.isScreenOn(); - * } - * - * @return whether the screen is on (bright or dim). - */ - public boolean isScreenOn() - { - try { - return mService.isScreenOn(); - } catch (RemoteException e) { - return false; - } - } - - /** - * Reboot the device. Will not return if the reboot is - * successful. Requires the {@link android.Manifest.permission#REBOOT} - * permission. - * - * @param reason code to pass to the kernel (e.g., "recovery") to - * request special boot modes, or null. - */ - public void reboot(String reason) - { - try { - mService.reboot(reason); - } catch (RemoteException e) { - } - } - - private PowerManager() - { - } - - /** - * {@hide} - */ - public PowerManager(IPowerManager service, Handler handler) - { - mService = service; - mHandler = handler; - } - - /** - * TODO: It would be nice to be able to set the poke lock here, - * but I'm not sure what would be acceptable as an interface - - * either a PokeLock object (like WakeLock) or, possibly just a - * method call to set the poke lock. - */ - - IPowerManager mService; - Handler mHandler; }