summaryrefslogtreecommitdiffstats
path: root/core/java/android/os/PowerManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/os/PowerManager.java')
-rw-r--r--core/java/android/os/PowerManager.java915
1 files changed, 577 insertions, 338 deletions
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 903c8b3..ae50ddb 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -16,22 +16,25 @@
package android.os;
+import android.content.Context;
import android.util.Log;
/**
- * This class gives you control of the power state of the device.
- *
- * <p><b>Device battery life will be significantly affected by the use of this API.</b> 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.
- *
- * <p>You can obtain an instance of this class by calling
+ * This class gives you control of the power state of the device.
+ *
+ * <p>
+ * <b>Device battery life will be significantly affected by the use of this API.</b>
+ * 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.
+ * </p><p>
+ * You can obtain an instance of this class by calling
* {@link android.content.Context#getSystemService(java.lang.String) Context.getSystemService()}.
- *
- * <p>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:
- *
+ * </p><p>
+ * 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.
+ * </p><p>
+ * 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 +42,11 @@ import android.util.Log;
* ..screen will stay on during this section..
* wl.release();
* }
- *
- * <p>The following flags are defined, with varying effects on system power. <i>These flags are
- * mutually exclusive - you may only specify one of them.</i>
- * <table border="2" width="85%" align="center" frame="hsides" rules="rows">
+ * </p><p>
+ * The following wake lock levels are defined, with varying effects on system power.
+ * <i>These levels are mutually exclusive - you may only specify one of them.</i>
*
+ * <table border="2" width="85%" align="center" frame="hsides" rules="rows">
* <thead>
* <tr><th>Flag Value</th>
* <th>CPU</th> <th>Screen</th> <th>Keyboard</th></tr>
@@ -67,15 +70,16 @@ import android.util.Log;
* </tr>
* </tbody>
* </table>
- *
- * <p>*<i>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.</i>
- *
- * <p>In addition, you can add two more flags, which affect behavior of the screen only. <i>These
- * flags have no effect when combined with a {@link #PARTIAL_WAKE_LOCK}.</i>
- * <table border="2" width="85%" align="center" frame="hsides" rules="rows">
+ * </p><p>
+ * *<i>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.</i>
+ * </p><p>
+ * In addition, you can add two more flags, which affect behavior of the screen only.
+ * <i>These flags have no effect when combined with a {@link #PARTIAL_WAKE_LOCK}.</i>
*
+ * <table border="2" width="85%" align="center" frame="hsides" rules="rows">
* <thead>
* <tr><th>Flag Value</th> <th>Description</th></tr>
* </thead>
@@ -96,113 +100,132 @@ import android.util.Log;
* </tr>
* </tbody>
* </table>
- *
+ * </p><p>
* Any application using a WakeLock must request the {@code android.permission.WAKE_LOCK}
* permission in an {@code &lt;uses-permission&gt;} element of the application's manifest.
+ * </p>
*/
-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.
+
+ /* NOTE: Wake lock levels were previously defined as a bit field, except that only a few
+ * combinations were actually supported so the bit field was removed. This explains
+ * why the numbering scheme is so odd. If adding a new wake lock level, any unused
+ * value can be used.
*/
- 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 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 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.
+ * <p>
+ * If the user presses the power button, then the screen will be turned off
+ * but the CPU will be kept on until all partial wake locks have been released.
+ * </p>
*/
- public static final int PARTIAL_WAKE_LOCK = WAKE_BIT_CPU_STRONG;
+ public static final int PARTIAL_WAKE_LOCK = 0x00000001;
/**
- * Wake lock that ensures that the screen and keyboard are on at
- * full brightness.
+ * Wake lock level: Ensures that the screen is on (but may be dimmed);
+ * the keyboard backlight will be allowed to go off.
+ * <p>
+ * If the user presses the power button, then the {@link #SCREEN_DIM_WAKE_LOCK} will be
+ * implicitly released by the system, causing both the screen and the CPU to be turned off.
+ * Contrast with {@link #PARTIAL_WAKE_LOCK}.
+ * </p>
*
- * <p class="note">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.</p>
+ * @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.
*/
- public static final int FULL_WAKE_LOCK = WAKE_BIT_CPU_WEAK | WAKE_BIT_SCREEN_BRIGHT
- | WAKE_BIT_KEYBOARD_BRIGHT;
+ @Deprecated
+ public static final int SCREEN_DIM_WAKE_LOCK = 0x00000006;
/**
+ * Wake lock level: Ensures that the screen is on at full brightness;
+ * the keyboard backlight will be allowed to go off.
+ * <p>
+ * If the user presses the power button, then the {@link #SCREEN_BRIGHT_WAKE_LOCK} will be
+ * implicitly released by the system, causing both the screen and the CPU to be turned off.
+ * Contrast with {@link #PARTIAL_WAKE_LOCK}.
+ * </p>
+ *
* @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;
+ public static final int SCREEN_BRIGHT_WAKE_LOCK = 0x0000000a;
/**
- * Wake lock that ensures that the screen is on (but may be dimmed);
- * the keyboard backlight will be allowed to go off.
+ * Wake lock level: Ensures that the screen and keyboard backlight are on at
+ * full brightness.
+ * <p>
+ * If the user presses the power button, then the {@link #FULL_WAKE_LOCK} will be
+ * implicitly released by the system, causing both the screen and the CPU to be turned off.
+ * Contrast with {@link #PARTIAL_WAKE_LOCK}.
+ * </p>
+ *
+ * @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.
*/
- public static final int SCREEN_DIM_WAKE_LOCK = WAKE_BIT_CPU_WEAK | WAKE_BIT_SCREEN_DIM;
+ @Deprecated
+ public static final int FULL_WAKE_LOCK = 0x0000001a;
/**
- * 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.
+ * <p>
+ * Since not all devices have proximity sensors, use {@link #isWakeLockLevelSupported}
+ * to determine whether this wake lock level is supported.
+ * </p>
*
* {@hide}
*/
- public static final int PROXIMITY_SCREEN_OFF_WAKE_LOCK = WAKE_BIT_PROXIMITY_SCREEN_OFF;
+ public static final int PROXIMITY_SCREEN_OFF_WAKE_LOCK = 0x00000020;
/**
- * Flag for {@link WakeLock#release release(int)} to defer releasing a
- * {@link #WAKE_BIT_PROXIMITY_SCREEN_OFF} wakelock until the proximity sensor returns
- * a negative value.
+ * Mask for the wake lock level component of a combined wake lock level and flags integer.
*
- * {@hide}
+ * @hide
*/
- public static final int WAIT_FOR_PROXIMITY_NEGATIVE = 1;
+ public static final int WAKE_LOCK_LEVEL_MASK = 0x0000ffff;
/**
+ * Wake lock flag: Turn the screen on when the wake lock is acquired.
+ * <p>
* 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.
- * <p>
- * Does not work with PARTIAL_WAKE_LOCKs.
+ * </p><p>
+ * Cannot be used with {@link #PARTIAL_WAKE_LOCK}.
+ * </p>
*/
public static final int ACQUIRE_CAUSES_WAKEUP = 0x10000000;
/**
- * 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.
* <p>
- * Will not turn the screen on if it is not already on. See {@link #ACQUIRE_CAUSES_WAKEUP}
- * if you want that.
- * <p>
- * 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.
+ * </p><p>
+ * Cannot be used with {@link #PARTIAL_WAKE_LOCK}.
+ * </p>
*/
public static final int ON_AFTER_RELEASE = 0x20000000;
/**
- * Brightness value to use when battery is low.
- * @hide
+ * Flag for {@link WakeLock#release release(int)} to defer releasing a
+ * {@link #WAKE_BIT_PROXIMITY_SCREEN_OFF} wake lock until the proximity sensor returns
+ * a negative value.
+ *
+ * {@hide}
*/
- public static final int BRIGHTNESS_LOW_BATTERY = 10;
+ public static final int WAIT_FOR_PROXIMITY_NEGATIVE = 1;
/**
* Brightness value for fully on.
@@ -211,46 +234,181 @@ public class PowerManager
public static final int BRIGHTNESS_ON = 255;
/**
- * Brightness value for dim backlight.
+ * Brightness value for fully off.
+ * @hide
+ */
+ public static final int BRIGHTNESS_OFF = 0;
+
+ // Note: Be sure to update android.os.BatteryStats and PowerManager.h
+ // if adding or modifying user activity event constants.
+
+ /**
+ * User activity event type: Unspecified event type.
* @hide
*/
- public static final int BRIGHTNESS_DIM = 20;
+ public static final int USER_ACTIVITY_EVENT_OTHER = 0;
/**
- * Brightness value for fully off.
+ * User activity event type: Button or key pressed or released.
* @hide
*/
- public static final int BRIGHTNESS_OFF = 0;
+ public static final int USER_ACTIVITY_EVENT_BUTTON = 1;
/**
- * Class lets you say that you need to have the device on.
- * <p>
- * Call release when you are done and don't need the lock anymore.
+ * User activity event type: Touch down, move or up.
+ * @hide
+ */
+ public static final int USER_ACTIVITY_EVENT_TOUCH = 2;
+
+ /**
+ * User activity flag: Do not restart the user activity timeout or brighten
+ * the display in response to user activity if it is already dimmed.
+ * @hide
+ */
+ public static final int USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS = 1 << 0;
+
+ /**
+ * Go to sleep reason code: Going to sleep due by user request.
+ * @hide
+ */
+ public static final int GO_TO_SLEEP_REASON_USER = 0;
+
+ /**
+ * Go to sleep reason code: Going to sleep due by request of the
+ * device administration policy.
+ * @hide
+ */
+ public static final int GO_TO_SLEEP_REASON_DEVICE_ADMIN = 1;
+
+ /**
+ * Go to sleep reason code: Going to sleep due to a screen timeout.
+ * @hide
+ */
+ public static final int GO_TO_SLEEP_REASON_TIMEOUT = 2;
+
+ final Context mContext;
+ final IPowerManager mService;
+ final Handler mHandler;
+
+ /**
+ * {@hide}
+ */
+ public PowerManager(Context context, IPowerManager service, Handler handler) {
+ mContext = context;
+ mService = service;
+ mHandler = handler;
+ }
+
+ /**
+ * Gets the minimum supported screen brightness setting.
+ * The screen may be allowed to become dimmer than this value but
+ * this is the minimum value that can be set by the user.
+ * @hide
+ */
+ public int getMinimumScreenBrightnessSetting() {
+ return mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_screenBrightnessSettingMinimum);
+ }
+
+ /**
+ * Gets the maximum supported screen brightness setting.
+ * The screen may be allowed to become dimmer than this value but
+ * this is the maximum value that can be set by the user.
+ * @hide
+ */
+ public int getMaximumScreenBrightnessSetting() {
+ return mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_screenBrightnessSettingMaximum);
+ }
+
+ /**
+ * Gets the default screen brightness setting.
+ * @hide
+ */
+ public int getDefaultScreenBrightnessSetting() {
+ return mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_screenBrightnessSettingDefault);
+ }
+
+ /**
+ * Returns true if the screen auto-brightness adjustment setting should
+ * be available in the UI. This setting is experimental and disabled by default.
+ * @hide
+ */
+ public static boolean useScreenAutoBrightnessAdjustmentFeature() {
+ return SystemProperties.getBoolean("persist.power.useautobrightadj", false);
+ }
+
+ /**
+ * Returns true if the twilight service should be used to adjust screen brightness
+ * policy. This setting is experimental and disabled by default.
+ * @hide
+ */
+ public static boolean useTwilightAdjustmentFeature() {
+ return SystemProperties.getBoolean("persist.power.usetwilightadj", false);
+ }
+
+ /**
+ * Creates a new wake lock with the specified level and flags.
* <p>
- * Any application using a WakeLock must request the {@code android.permission.WAKE_LOCK}
- * permission in an {@code &lt;uses-permission&gt;} element of the application's manifest.
+ * The {@code levelAndFlags} parameter specifies a wake lock level and optional flags
+ * combined using the logical OR operator.
+ * </p><p>
+ * 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.
+ * </p><p>
+ * 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.
+ * </p><p>
+ * Call {@link WakeLock#acquire() acquire()} on the object to acquire the
+ * wake lock, and {@link WakeLock#release release()} when you are done.
+ * </p><p>
+ * {@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();
+ * }
+ * </p><p>
+ * 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.
+ * </p><p class="note">
+ * 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.
+ * </p>
+ *
+ * @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 class WakeLock
- {
- static final int RELEASE_WAKE_LOCK = 1;
+ public WakeLock newWakeLock(int levelAndFlags, String tag) {
+ validateWakeLockParameters(levelAndFlags, tag);
+ return new WakeLock(levelAndFlags, tag);
+ }
- 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) {
+ /** @hide */
+ public static void validateWakeLockParameters(int levelAndFlags, String tag) {
+ switch (levelAndFlags & WAKE_LOCK_LEVEL_MASK) {
case PARTIAL_WAKE_LOCK:
case SCREEN_DIM_WAKE_LOCK:
case SCREEN_BRIGHT_WAKE_LOCK:
@@ -258,42 +416,282 @@ public class PowerManager
case PROXIMITY_SCREEN_OFF_WAKE_LOCK:
break;
default:
- throw new IllegalArgumentException();
+ throw new IllegalArgumentException("Must specify a valid wake lock level.");
+ }
+ if (tag == null) {
+ throw new IllegalArgumentException("The tag must not be null.");
+ }
+ }
+
+ /**
+ * Notifies the power manager that user activity happened.
+ * <p>
+ * Resets the auto-off timer and brightens the screen if the device
+ * is not asleep. This is what happens normally when a key or the touch
+ * screen is pressed or when some other user activity occurs.
+ * This method does not wake up the device if it has been put to sleep.
+ * </p><p>
+ * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission.
+ * </p>
+ *
+ * @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 request 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.
+ *
+ * @see #wakeUp
+ * @see #goToSleep
+ */
+ public void userActivity(long when, boolean noChangeLights) {
+ try {
+ mService.userActivity(when, USER_ACTIVITY_EVENT_OTHER,
+ noChangeLights ? USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS : 0);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * Forces the device to go to sleep.
+ * <p>
+ * Overrides all the wake locks that are held.
+ * This is what happens when the power key is pressed to turn off the screen.
+ * </p><p>
+ * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission.
+ * </p>
+ *
+ * @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 go to sleep request with other power management functions. It should be set
+ * to the timestamp of the input event that caused the request to go to sleep.
+ *
+ * @see #userActivity
+ * @see #wakeUp
+ */
+ public void goToSleep(long time) {
+ try {
+ mService.goToSleep(time, GO_TO_SLEEP_REASON_USER);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * Forces the device to wake up from sleep.
+ * <p>
+ * If the device is currently asleep, wakes it up, otherwise does nothing.
+ * This is what happens when the power key is pressed to turn on the screen.
+ * </p><p>
+ * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission.
+ * </p>
+ *
+ * @param time The time when the request to wake up was issued, in the
+ * {@link SystemClock#uptimeMillis()} time base. This timestamp is used to correctly
+ * order the wake up request with other power management functions. It should be set
+ * to the timestamp of the input event that caused the request to wake up.
+ *
+ * @see #userActivity
+ * @see #goToSleep
+ */
+ public void wakeUp(long time) {
+ try {
+ mService.wakeUp(time);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * Forces the device to start napping.
+ * <p>
+ * If the device is currently awake, starts dreaming, otherwise does nothing.
+ * When the dream ends or if the dream cannot be started, the device will
+ * either wake up or go to sleep depending on whether there has been recent
+ * user activity.
+ * </p><p>
+ * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission.
+ * </p>
+ *
+ * @param time The time when the request to nap was issued, in the
+ * {@link SystemClock#uptimeMillis()} time base. This timestamp is used to correctly
+ * order the nap request with other power management functions. It should be set
+ * to the timestamp of the input event that caused the request to nap.
+ *
+ * @see #wakeUp
+ * @see #goToSleep
+ *
+ * @hide
+ */
+ public void nap(long time) {
+ try {
+ mService.nap(time);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * Sets the brightness of the backlights (screen, keyboard, button).
+ * <p>
+ * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission.
+ * </p>
+ *
+ * @param brightness The brightness value from 0 to 255.
+ *
+ * {@hide}
+ */
+ public void setBacklightBrightness(int brightness) {
+ try {
+ mService.setTemporaryScreenBrightnessSettingOverride(brightness);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * Returns true if the specified wake lock level is supported.
+ *
+ * @param level The wake lock level to check.
+ * @return True if the specified wake lock level is supported.
+ *
+ * {@hide}
+ */
+ public boolean isWakeLockLevelSupported(int level) {
+ try {
+ return mService.isWakeLockLevelSupported(level);
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Returns whether the screen is currently on.
+ * <p>
+ * Only indicates whether the screen is on. The screen could be either bright or dim.
+ * </p><p>
+ * {@samplecode
+ * PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
+ * boolean isScreenOn = pm.isScreenOn();
+ * }
+ * </p>
+ *
+ * @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.
+ * <p>
+ * Requires the {@link android.Manifest.permission#REBOOT} permission.
+ * </p>
+ *
+ * @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.
+ * <p>
+ * Any application using a WakeLock must request the {@code android.permission.WAKE_LOCK}
+ * permission in an {@code &lt;uses-permission&gt;} element of the application's manifest.
+ * Obtain a wake lock by calling {@link PowerManager#newWakeLock(int, String)}.
+ * </p><p>
+ * 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.
+ * </p><p>
+ * 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.
+ * </p>
+ */
+ 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;
+
+ private final Runnable mReleaser = new Runnable() {
+ public void run() {
+ release();
}
+ };
+ WakeLock(int flags, String tag) {
mFlags = flags;
mTag = tag;
mToken = new Binder();
}
+ @Override
+ protected void finalize() throws Throwable {
+ synchronized (mToken) {
+ if (mHeld) {
+ Log.wtf(TAG, "WakeLock finalized while still held: " + mTag);
+ try {
+ mService.releaseWakeLock(mToken, 0);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+ }
+
/**
- * Sets whether this WakeLock is ref counted.
- *
- * <p>Wake locks are reference counted by default.
+ * Sets whether this WakeLock is reference counted.
+ * <p>
+ * 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()}.
+ * </p>
*
- * @param value true for ref counted, false for not ref counted.
+ * @param value True to make the wake lock reference counted, false to
+ * make the wake lock non-reference counted.
*/
- public void setReferenceCounted(boolean value)
- {
- mRefCounted = value;
+ public void setReferenceCounted(boolean value) {
+ synchronized (mToken) {
+ mRefCounted = value;
+ }
}
/**
- * Makes sure the device is on at the level you asked when you created
- * the wake lock.
+ * Acquires the wake lock.
+ * <p>
+ * Ensures that the device is on at the level requested when
+ * the wake lock was created.
+ * </p>
*/
- public void acquire()
- {
+ 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.
+ * Acquires the wake lock with a timeout.
+ * <p>
+ * 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.
+ * </p>
+ *
+ * @param timeout The timeout after which to release the wake lock, in milliseconds.
*/
public void acquire(long timeout) {
synchronized (mToken) {
@@ -301,12 +699,18 @@ public class PowerManager
mHandler.postDelayed(mReleaser, timeout);
}
}
-
+
private void acquireLocked() {
if (!mRefCounted || mCount++ == 0) {
+ // Do this even if the wake lock is already thought to be held (mHeld == true)
+ // because non-reference counted wake locks are not always properly released.
+ // For example, the keyguard's wake lock might be forcibly released by the
+ // power manager without the keyguard knowing. A subsequent call to acquire
+ // should immediately acquire the wake lock once again despite never having
+ // been explicitly released by the keyguard.
mHandler.removeCallbacks(mReleaser);
try {
- mService.acquireWakeLock(mFlags, mToken, mTag, mWorkSource);
+ mService.acquireWakeLock(mToken, mFlags, mTag, mWorkSource);
} catch (RemoteException e) {
}
mHeld = true;
@@ -314,24 +718,27 @@ public class PowerManager
}
/**
- * Release your claim to the CPU or screen being on.
- *
+ * Releases the wake lock.
* <p>
- * It may turn off shortly after you release it, or it may not if there
- * are other wake locks held.
+ * 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.
+ * </p>
*/
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.
- *
+ * Releases the wake lock with flags to modify the release behavior.
* <p>
- * It may turn off shortly after you release it, or it may not if there
- * are other wake locks held.
+ * 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.
+ * </p>
+ *
+ * @param flags Combination of flag values to modify the release behavior.
+ * Currently only {@link #WAIT_FOR_PROXIMITY_NEGATIVE} is supported.
*
* {@hide}
*/
@@ -339,11 +746,13 @@ public class PowerManager
synchronized (mToken) {
if (!mRefCounted || --mCount == 0) {
mHandler.removeCallbacks(mReleaser);
- try {
- mService.releaseWakeLock(mToken, flags);
- } catch (RemoteException e) {
+ if (mHeld) {
+ try {
+ mService.releaseWakeLock(mToken, flags);
+ } catch (RemoteException e) {
+ }
+ mHeld = false;
}
- mHeld = false;
}
if (mCount < 0) {
throw new RuntimeException("WakeLock under-locked " + mTag);
@@ -351,23 +760,40 @@ public class PowerManager
}
}
- public boolean isHeld()
- {
+ /**
+ * 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.
+ * <p>
+ * 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.
+ * </p>
+ *
+ * @param ws The work source, or null if none.
+ */
public void setWorkSource(WorkSource ws) {
synchronized (mToken) {
if (ws != null && ws.size() == 0) {
ws = null;
}
- boolean changed = true;
+
+ final boolean changed;
if (ws == null) {
+ changed = mWorkSource != null;
mWorkSource = null;
} else if (mWorkSource == null) {
- changed = mWorkSource != null;
+ changed = true;
mWorkSource = new WorkSource(ws);
} else {
changed = mWorkSource.diff(ws);
@@ -375,6 +801,7 @@ public class PowerManager
mWorkSource.set(ws);
}
}
+
if (changed && mHeld) {
try {
mService.updateWakeLockWorkSource(mToken, mWorkSource);
@@ -384,6 +811,7 @@ public class PowerManager
}
}
+ @Override
public String toString() {
synchronized (mToken) {
return "WakeLock{"
@@ -391,194 +819,5 @@ public class PowerManager
+ " held=" + mHeld + ", refCount=" + mCount + "}";
}
}
-
- @Override
- protected void finalize() throws Throwable
- {
- synchronized (mToken) {
- if (mHeld) {
- Log.wtf(TAG, "WakeLock finalized while still held: " + mTag);
- try {
- mService.releaseWakeLock(mToken, 0);
- } catch (RemoteException e) {
- }
- }
- }
- }
}
-
- /**
- * 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();
- * }
- *
- * <p class="note">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.</p>
- *
- * @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");
- }
- return new WakeLock(flags, tag);
- }
-
- /**
- * User activity happened.
- * <p>
- * 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) {
- }
- }
-
- /**
- * 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;
}