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