/* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.os; import android.Manifest.permission; import android.annotation.CallbackExecutor; import android.annotation.CurrentTimeMillisLong; import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; import android.app.PropertyInvalidatedCache; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.service.dreams.Sandman; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; import android.util.proto.ProtoOutputStream; import android.view.Display; import com.android.internal.util.Preconditions; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.net.InetAddress; import java.net.UnknownHostException; import java.time.Duration; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicLong; /** * This class lets you query and request control of aspects of the device's power state. */ @SystemService(Context.POWER_SERVICE) public final class PowerManager { private static final String TAG = "PowerManager"; /* 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 (in frameworks/proto_logging/stats/enums/os/enums.proto) can be used. */ /** * Wake lock level: Ensures that the CPU is running; the screen and keyboard * backlight will be allowed to go off. *
* 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. *
*/ public static final int PARTIAL_WAKE_LOCK = OsProtoEnums.PARTIAL_WAKE_LOCK; // 0x00000001 /** * Wake lock level: Ensures that the screen is on (but may be dimmed); * the keyboard backlight will be allowed to go off. ** 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}. *
* * @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. */ @Deprecated public static final int SCREEN_DIM_WAKE_LOCK = OsProtoEnums.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. ** 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}. *
* * @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. */ @Deprecated public static final int SCREEN_BRIGHT_WAKE_LOCK = OsProtoEnums.SCREEN_BRIGHT_WAKE_LOCK; // 0x0000000a /** * Wake lock level: Ensures that the screen and keyboard backlight are on at * full brightness. ** 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}. *
* * @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. */ @Deprecated public static final int FULL_WAKE_LOCK = OsProtoEnums.FULL_WAKE_LOCK; // 0x0000001a /** * Wake lock level: Turns the screen off when the proximity sensor activates. ** If the proximity sensor detects that an object is nearby, the screen turns off * immediately. Shortly after the object moves away, the screen turns on again. *
* A proximity wake lock does not prevent the device from falling asleep * unlike {@link #FULL_WAKE_LOCK}, {@link #SCREEN_BRIGHT_WAKE_LOCK} and * {@link #SCREEN_DIM_WAKE_LOCK}. If there is no user activity and no other * wake locks are held, then the device will fall asleep (and lock) as usual. * However, the device will not fall asleep while the screen has been turned off * by the proximity sensor because it effectively counts as ongoing user activity. *
* Since not all devices have proximity sensors, use {@link #isWakeLockLevelSupported} * to determine whether this wake lock level is supported. *
* Cannot be used with {@link #ACQUIRE_CAUSES_WAKEUP}. *
*/ public static final int PROXIMITY_SCREEN_OFF_WAKE_LOCK = OsProtoEnums.PROXIMITY_SCREEN_OFF_WAKE_LOCK; // 0x00000020 /** * Wake lock level: Put the screen in a low power state and allow the CPU to suspend * if no other wake locks are held. ** This is used by the dream manager to implement doze mode. It currently * has no effect unless the power manager is in the dozing state. *
* Requires the {@link android.Manifest.permission#DEVICE_POWER} permission. *
* * {@hide} */ public static final int DOZE_WAKE_LOCK = OsProtoEnums.DOZE_WAKE_LOCK; // 0x00000040 /** * Wake lock level: Keep the device awake enough to allow drawing to occur. ** This is used by the window manager to allow applications to draw while the * system is dozing. It currently has no effect unless the power manager is in * the dozing state. *
* Requires the {@link android.Manifest.permission#DEVICE_POWER} permission. *
* * {@hide} */ public static final int DRAW_WAKE_LOCK = OsProtoEnums.DRAW_WAKE_LOCK; // 0x00000080 /** * Wake lock level: Override the current screen timeout. ** This is used by the system to allow {@code PowerManagerService} to override the current * screen timeout by config value. * * config_screenTimeoutOverride in config.xml determines the screen timeout override value. *
* Requires the {@link android.Manifest.permission#SCREEN_TIMEOUT_OVERRIDE} permission. *
* * @hide */ public static final int SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK = OsProtoEnums.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK; // 0x00000100 /** * Mask for the wake lock level component of a combined wake lock level and flags integer. * * @hide */ public static final int WAKE_LOCK_LEVEL_MASK = 0x0000ffff; /** * Wake lock flag: Turn the screen on when the wake lock is acquired. ** This flag will require {@link android.Manifest.permission#TURN_SCREEN_ON} in future releases. *
* Normally wake locks don't actually wake the device, they just cause the screen to remain on * once it's already on. This flag will cause the device to wake up when the wake lock is * acquired. *
* Android TV playback devices attempt to turn on the HDMI-connected TV via HDMI-CEC on any * wake-up, including wake-ups triggered by wake locks. *
* Cannot be used with {@link #PARTIAL_WAKE_LOCK}. *
* * @deprecated Most applications should use {@link android.R.attr#turnScreenOn} or * {@link android.app.Activity#setTurnScreenOn(boolean)} instead, as this prevents the previous * foreground app from being resumed first when the screen turns on. */ @Deprecated @RequiresPermission(value = android.Manifest.permission.TURN_SCREEN_ON, conditional = true) public static final int ACQUIRE_CAUSES_WAKEUP = 0x10000000; /** * Wake lock flag: When this wake lock is released, poke the user activity timer * so the screen stays on for a little longer. ** This will not turn the screen on if it is not already on. *
* Cannot be used with {@link #PARTIAL_WAKE_LOCK}. *
*/ public static final int ON_AFTER_RELEASE = 0x20000000; /** * Wake lock flag: This wake lock is not important for logging events. If a later * wake lock is acquired that is important, it will be considered the one to log. * @hide */ public static final int UNIMPORTANT_FOR_LOGGING = 0x40000000; /** * Wake lock flag: This wake lock should be held by the system. * *Meant to allow tests to keep the device awake even when power restrictions are active. * * @hide */ @TestApi @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public static final int SYSTEM_WAKELOCK = 0x80000000; /** * Flag for {@link WakeLock#release WakeLock.release(int)}: Defer releasing a * {@link #PROXIMITY_SCREEN_OFF_WAKE_LOCK} wake lock until the proximity sensor * indicates that an object is not in close proximity. */ public static final int RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY = 1 << 0; /** * Flag for {@link WakeLock#release(int)} when called due to timeout. * @hide */ public static final int RELEASE_FLAG_TIMEOUT = 1 << 16; /** * Brightness value for fully on. * @hide */ @UnsupportedAppUsage public static final int BRIGHTNESS_ON = 255; /** * Brightness value for fully off. * @hide */ public static final int BRIGHTNESS_OFF = 0; /** * Brightness value for default policy handling by the system. * @hide */ public static final int BRIGHTNESS_DEFAULT = -1; /** * Brightness value for an invalid value having been stored. * @hide */ public static final int BRIGHTNESS_INVALID = -1; //Brightness values for new float implementation: /** * Brightness value for fully on as float. * @hide */ public static final float BRIGHTNESS_MAX = 1.0f; /** * Brightness value for minimum valid brightness as float. * @hide */ public static final float BRIGHTNESS_MIN = 0.0f; /** * Brightness value for fully off in float. * @hide */ public static final float BRIGHTNESS_OFF_FLOAT = -1.0f; /** * Invalid brightness value. * @hide */ public static final float BRIGHTNESS_INVALID_FLOAT = Float.NaN; // 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 */ @SystemApi public static final int USER_ACTIVITY_EVENT_OTHER = 0; /** * User activity event type: Button or key pressed or released. * @hide */ @SystemApi public static final int USER_ACTIVITY_EVENT_BUTTON = 1; /** * User activity event type: Touch down, move or up. * @hide */ @SystemApi public static final int USER_ACTIVITY_EVENT_TOUCH = 2; /** * User activity event type: Accessibility taking action on behalf of user. * @hide */ @SystemApi public static final int USER_ACTIVITY_EVENT_ACCESSIBILITY = 3; /** * User activity event type: {@link android.service.attention.AttentionService} taking action * on behalf of user. * @hide */ public static final int USER_ACTIVITY_EVENT_ATTENTION = 4; /** * User activity event type: {@link com.android.server.power.FaceDownDetector} taking action * on behalf of user. * @hide */ public static final int USER_ACTIVITY_EVENT_FACE_DOWN = 5; /** * User activity event type: There is a change in the device state. * @hide */ public static final int USER_ACTIVITY_EVENT_DEVICE_STATE = 6; /** * @hide */ @IntDef(prefix = { "USER_ACTIVITY_EVENT_" }, value = { USER_ACTIVITY_EVENT_OTHER, USER_ACTIVITY_EVENT_BUTTON, USER_ACTIVITY_EVENT_TOUCH, USER_ACTIVITY_EVENT_ACCESSIBILITY, USER_ACTIVITY_EVENT_ATTENTION, USER_ACTIVITY_EVENT_FACE_DOWN, USER_ACTIVITY_EVENT_DEVICE_STATE, }) @Retention(RetentionPolicy.SOURCE) public @interface UserActivityEvent{} /** * * Convert the user activity event to a string for debugging purposes. * @hide */ public static String userActivityEventToString(@UserActivityEvent int userActivityEvent) { switch (userActivityEvent) { case USER_ACTIVITY_EVENT_OTHER: return "other"; case USER_ACTIVITY_EVENT_BUTTON: return "button"; case USER_ACTIVITY_EVENT_TOUCH: return "touch"; case USER_ACTIVITY_EVENT_ACCESSIBILITY: return "accessibility"; case USER_ACTIVITY_EVENT_ATTENTION: return "attention"; case USER_ACTIVITY_EVENT_FACE_DOWN: return "faceDown"; case USER_ACTIVITY_EVENT_DEVICE_STATE: return "deviceState"; default: return Integer.toString(userActivityEvent); } } /** * User activity flag: If already dimmed, extend the dim timeout * but do not brighten. This flag is useful for keeping the screen on * a little longer without causing a visible change such as when * the power key is pressed. * @hide */ @SystemApi public static final int USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS = 1 << 0; /** * User activity flag: Note the user activity as usual but do not * reset the user activity timeout. This flag is useful for applying * user activity power hints when interacting with the device indirectly * on a secondary screen while allowing the primary screen to go to sleep. * @hide */ @SystemApi public static final int USER_ACTIVITY_FLAG_INDIRECT = 1 << 1; /** * @hide */ public static final int GO_TO_SLEEP_REASON_MIN = 0; /** * Go to sleep reason code: Going to sleep due by application request. * @hide */ public static final int GO_TO_SLEEP_REASON_APPLICATION = GO_TO_SLEEP_REASON_MIN; /** * 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 */ @UnsupportedAppUsage public static final int GO_TO_SLEEP_REASON_TIMEOUT = 2; /** * Go to sleep reason code: Going to sleep due to the lid switch being closed. * @hide */ public static final int GO_TO_SLEEP_REASON_LID_SWITCH = 3; /** * Go to sleep reason code: Going to sleep due to the power button being pressed. * @hide */ public static final int GO_TO_SLEEP_REASON_POWER_BUTTON = 4; /** * Go to sleep reason code: Going to sleep due to HDMI. * @hide */ public static final int GO_TO_SLEEP_REASON_HDMI = 5; /** * Go to sleep reason code: Going to sleep due to the sleep button being pressed. * @hide */ public static final int GO_TO_SLEEP_REASON_SLEEP_BUTTON = 6; /** * Go to sleep reason code: Going to sleep by request of an accessibility service * @hide */ public static final int GO_TO_SLEEP_REASON_ACCESSIBILITY = 7; /** * Go to sleep reason code: Going to sleep due to force-suspend. * @hide */ public static final int GO_TO_SLEEP_REASON_FORCE_SUSPEND = 8; /** * Go to sleep reason code: Going to sleep due to user inattentiveness. * @hide */ public static final int GO_TO_SLEEP_REASON_INATTENTIVE = 9; /** * Go to sleep reason code: Going to sleep due to quiescent boot. * @hide */ public static final int GO_TO_SLEEP_REASON_QUIESCENT = 10; /** * Go to sleep reason code: The last powered on display group has been removed. * @hide */ public static final int GO_TO_SLEEP_REASON_DISPLAY_GROUP_REMOVED = 11; /** * Go to sleep reason code: Every display group has been turned off. * @hide */ public static final int GO_TO_SLEEP_REASON_DISPLAY_GROUPS_TURNED_OFF = 12; /** * Go to sleep reason code: A foldable device has been folded. * @hide */ public static final int GO_TO_SLEEP_REASON_DEVICE_FOLD = 13; /** * @hide */ public static final int GO_TO_SLEEP_REASON_MAX = GO_TO_SLEEP_REASON_DEVICE_FOLD; /** * @hide */ public static String sleepReasonToString(@GoToSleepReason int sleepReason) { switch (sleepReason) { case GO_TO_SLEEP_REASON_ACCESSIBILITY: return "accessibility"; case GO_TO_SLEEP_REASON_APPLICATION: return "application"; case GO_TO_SLEEP_REASON_DEVICE_ADMIN: return "device_admin"; case GO_TO_SLEEP_REASON_DEVICE_FOLD: return "device_folded"; case GO_TO_SLEEP_REASON_DISPLAY_GROUP_REMOVED: return "display_group_removed"; case GO_TO_SLEEP_REASON_DISPLAY_GROUPS_TURNED_OFF: return "display_groups_turned_off"; case GO_TO_SLEEP_REASON_FORCE_SUSPEND: return "force_suspend"; case GO_TO_SLEEP_REASON_HDMI: return "hdmi"; case GO_TO_SLEEP_REASON_INATTENTIVE: return "inattentive"; case GO_TO_SLEEP_REASON_LID_SWITCH: return "lid_switch"; case GO_TO_SLEEP_REASON_POWER_BUTTON: return "power_button"; case GO_TO_SLEEP_REASON_QUIESCENT: return "quiescent"; case GO_TO_SLEEP_REASON_SLEEP_BUTTON: return "sleep_button"; case GO_TO_SLEEP_REASON_TIMEOUT: return "timeout"; default: return Integer.toString(sleepReason); } } /** * Go to sleep flag: Skip dozing state and directly go to full sleep. * @hide */ public static final int GO_TO_SLEEP_FLAG_NO_DOZE = 1 << 0; /** * Go to sleep flag: Sleep softly, go to sleep only if there's no wakelock explicitly keeping * the device awake. * @hide */ public static final int GO_TO_SLEEP_FLAG_SOFT_SLEEP = 1 << 1; /** * @hide */ @IntDef(prefix = { "BRIGHTNESS_CONSTRAINT_TYPE" }, value = { BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM, BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM, BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT, BRIGHTNESS_CONSTRAINT_TYPE_DIM, BRIGHTNESS_CONSTRAINT_TYPE_DOZE }) @Retention(RetentionPolicy.SOURCE) public @interface BrightnessConstraint{} /** * Brightness constraint type: minimum allowed value. * @hide */ public static final int BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM = 0; /** * Brightness constraint type: minimum allowed value. * @hide */ public static final int BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM = 1; /** * Brightness constraint type: minimum allowed value. * @hide */ public static final int BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT = 2; /** * Brightness constraint type: minimum allowed value. * @hide */ public static final int BRIGHTNESS_CONSTRAINT_TYPE_DIM = 3; /** * Brightness constraint type: minimum allowed value. * @hide */ public static final int BRIGHTNESS_CONSTRAINT_TYPE_DOZE = 4; /** * @hide */ @IntDef(prefix = { "WAKE_REASON_" }, value = { WAKE_REASON_UNKNOWN, WAKE_REASON_POWER_BUTTON, WAKE_REASON_APPLICATION, WAKE_REASON_PLUGGED_IN, WAKE_REASON_GESTURE, WAKE_REASON_CAMERA_LAUNCH, WAKE_REASON_WAKE_KEY, WAKE_REASON_WAKE_MOTION, WAKE_REASON_HDMI, WAKE_REASON_DISPLAY_GROUP_ADDED, WAKE_REASON_DISPLAY_GROUP_TURNED_ON, WAKE_REASON_UNFOLD_DEVICE, WAKE_REASON_DREAM_FINISHED, WAKE_REASON_TILT, WAKE_REASON_TAP, WAKE_REASON_LIFT, WAKE_REASON_BIOMETRIC, }) @Retention(RetentionPolicy.SOURCE) public @interface WakeReason{} /** * @hide */ @IntDef(prefix = { "GO_TO_SLEEP_REASON_" }, value = { GO_TO_SLEEP_REASON_ACCESSIBILITY, GO_TO_SLEEP_REASON_APPLICATION, GO_TO_SLEEP_REASON_DEVICE_ADMIN, GO_TO_SLEEP_REASON_DEVICE_FOLD, GO_TO_SLEEP_REASON_DISPLAY_GROUP_REMOVED, GO_TO_SLEEP_REASON_DISPLAY_GROUPS_TURNED_OFF, GO_TO_SLEEP_REASON_FORCE_SUSPEND, GO_TO_SLEEP_REASON_HDMI, GO_TO_SLEEP_REASON_INATTENTIVE, GO_TO_SLEEP_REASON_LID_SWITCH, GO_TO_SLEEP_REASON_POWER_BUTTON, GO_TO_SLEEP_REASON_QUIESCENT, GO_TO_SLEEP_REASON_SLEEP_BUTTON, GO_TO_SLEEP_REASON_TIMEOUT, }) @Retention(RetentionPolicy.SOURCE) public @interface GoToSleepReason{} /** * Wake up reason code: Waking for an unknown reason. * @hide */ public static final int WAKE_REASON_UNKNOWN = 0; /** * Wake up reason code: Waking up due to power button press. * @hide */ public static final int WAKE_REASON_POWER_BUTTON = 1; /** * Wake up reason code: Waking up because an application requested it. * @hide */ public static final int WAKE_REASON_APPLICATION = 2; /** * Wake up reason code: Waking up due to being plugged in or docked on a wireless charger. * @hide */ public static final int WAKE_REASON_PLUGGED_IN = 3; /** * Wake up reason code: Waking up due to a user performed gesture. This includes user * interactions with UI on the screen such as the notification shade. This does not include * {@link WAKE_REASON_TAP} or {@link WAKE_REASON_LIFT}. * @hide */ public static final int WAKE_REASON_GESTURE = 4; /** * Wake up reason code: Waking up due to the camera being launched. * @hide */ public static final int WAKE_REASON_CAMERA_LAUNCH = 5; /** * Wake up reason code: Waking up because a wake key other than power was pressed. * @hide */ public static final int WAKE_REASON_WAKE_KEY = 6; /** * Wake up reason code: Waking up because a wake motion was performed. * * For example, a trackball that was set to wake the device up was spun. * @hide */ public static final int WAKE_REASON_WAKE_MOTION = 7; /** * Wake up reason code: Waking due to HDMI. * @hide */ public static final int WAKE_REASON_HDMI = 8; /** * Wake up reason code: Waking due to the lid being opened. * @hide */ public static final int WAKE_REASON_LID = 9; /** * Wake up reason code: Waking due to display group being added. * @hide */ public static final int WAKE_REASON_DISPLAY_GROUP_ADDED = 10; /** * Wake up reason code: Waking due to display group being powered on. * @hide */ public static final int WAKE_REASON_DISPLAY_GROUP_TURNED_ON = 11; /** * Wake up reason code: Waking the device due to unfolding of a foldable device. * @hide */ public static final int WAKE_REASON_UNFOLD_DEVICE = 12; /** * Wake up reason code: Waking the device due to the dream finishing. * @hide */ public static final int WAKE_REASON_DREAM_FINISHED = 13; /** * Wake up reason code: Waking due to tilt. * @hide */ public static final int WAKE_REASON_TILT = 14; /** * Wake up reason code: Waking up due to the user single or double tapping on the screen. This * wake reason is used when the user is not tapping on a specific UI element; rather, the device * wakes up due to a generic tap on the screen. * @hide */ public static final int WAKE_REASON_TAP = 15; /** * Wake up reason code: Waking up due to a user performed lift gesture. * @hide */ public static final int WAKE_REASON_LIFT = 16; /** * Wake up reason code: Waking up due to a user interacting with a biometric. * @hide */ public static final int WAKE_REASON_BIOMETRIC = 17; /** * Convert the wake reason to a string for debugging purposes. * @hide */ public static String wakeReasonToString(@WakeReason int wakeReason) { switch (wakeReason) { case WAKE_REASON_UNKNOWN: return "WAKE_REASON_UNKNOWN"; case WAKE_REASON_POWER_BUTTON: return "WAKE_REASON_POWER_BUTTON"; case WAKE_REASON_APPLICATION: return "WAKE_REASON_APPLICATION"; case WAKE_REASON_PLUGGED_IN: return "WAKE_REASON_PLUGGED_IN"; case WAKE_REASON_GESTURE: return "WAKE_REASON_GESTURE"; case WAKE_REASON_CAMERA_LAUNCH: return "WAKE_REASON_CAMERA_LAUNCH"; case WAKE_REASON_WAKE_KEY: return "WAKE_REASON_WAKE_KEY"; case WAKE_REASON_WAKE_MOTION: return "WAKE_REASON_WAKE_MOTION"; case WAKE_REASON_HDMI: return "WAKE_REASON_HDMI"; case WAKE_REASON_LID: return "WAKE_REASON_LID"; case WAKE_REASON_DISPLAY_GROUP_ADDED: return "WAKE_REASON_DISPLAY_GROUP_ADDED"; case WAKE_REASON_DISPLAY_GROUP_TURNED_ON: return "WAKE_REASON_DISPLAY_GROUP_TURNED_ON"; case WAKE_REASON_UNFOLD_DEVICE: return "WAKE_REASON_UNFOLD_DEVICE"; case WAKE_REASON_DREAM_FINISHED: return "WAKE_REASON_DREAM_FINISHED"; case WAKE_REASON_TILT: return "WAKE_REASON_TILT"; case WAKE_REASON_TAP: return "WAKE_REASON_TAP"; case WAKE_REASON_LIFT: return "WAKE_REASON_LIFT"; case WAKE_REASON_BIOMETRIC: return "WAKE_REASON_BIOMETRIC"; default: return Integer.toString(wakeReason); } } /** * Information related to the device waking up, triggered by {@link #wakeUp}. * * @hide */ public static class WakeData { public WakeData(long wakeTime, @WakeReason int wakeReason, long sleepDurationRealtime) { this.wakeTime = wakeTime; this.wakeReason = wakeReason; this.sleepDurationRealtime = sleepDurationRealtime; } public final long wakeTime; public final @WakeReason int wakeReason; public final long sleepDurationRealtime; @Override public boolean equals(@Nullable Object o) { if (o instanceof WakeData) { final WakeData other = (WakeData) o; return wakeTime == other.wakeTime && wakeReason == other.wakeReason && sleepDurationRealtime == other.sleepDurationRealtime; } return false; } @Override public int hashCode() { return Objects.hash(wakeTime, wakeReason, sleepDurationRealtime); } } /** * Information related to the device going to sleep, triggered by {@link #goToSleep}. * * @hide */ public static class SleepData { public SleepData(long goToSleepUptimeMillis, @GoToSleepReason int goToSleepReason) { this.goToSleepUptimeMillis = goToSleepUptimeMillis; this.goToSleepReason = goToSleepReason; } public final long goToSleepUptimeMillis; public final @GoToSleepReason int goToSleepReason; @Override public boolean equals(@Nullable Object o) { if (o instanceof SleepData) { final SleepData other = (SleepData) o; return goToSleepUptimeMillis == other.goToSleepUptimeMillis && goToSleepReason == other.goToSleepReason; } return false; } @Override public int hashCode() { return Objects.hash(goToSleepUptimeMillis, goToSleepReason); } } /** * The value to pass as the 'reason' argument to reboot() to reboot into * recovery mode for tasks other than applying system updates, such as * doing factory resets. *
* Requires the {@link android.Manifest.permission#RECOVERY} * permission (in addition to * {@link android.Manifest.permission#REBOOT}). *
* @hide */ public static final String REBOOT_RECOVERY = "recovery"; /** * The value to pass as the 'reason' argument to reboot() to reboot into * recovery mode for applying system updates. ** Requires the {@link android.Manifest.permission#RECOVERY} * permission (in addition to * {@link android.Manifest.permission#REBOOT}). *
* @hide */ public static final String REBOOT_RECOVERY_UPDATE = "recovery-update"; /** * The value to pass as the 'reason' argument to reboot() when device owner requests a reboot on * the device. * @hide */ public static final String REBOOT_REQUESTED_BY_DEVICE_OWNER = "deviceowner"; /** * The 'reason' value used when rebooting in safe mode * @hide */ public static final String REBOOT_SAFE_MODE = "safemode"; /** * The 'reason' value used for rebooting userspace. * * @deprecated userspace reboot is not supported * @hide */ @SystemApi public static final String REBOOT_USERSPACE = "userspace"; /** * The 'reason' value used when rebooting the device without turning on the screen. * @hide */ public static final String REBOOT_QUIESCENT = "quiescent"; /** * The value to pass as the 'reason' argument to android_reboot(). * @hide */ public static final String SHUTDOWN_USER_REQUESTED = "userrequested"; /** * The value to pass as the 'reason' argument to android_reboot() when battery temperature * is too high. * @hide */ public static final String SHUTDOWN_BATTERY_THERMAL_STATE = "thermal,battery"; /** * The value to pass as the 'reason' argument to android_reboot() when device temperature * is too high. * @hide */ public static final String SHUTDOWN_THERMAL_STATE = "thermal"; /** * The value to pass as the 'reason' argument to android_reboot() when device is running * critically low on battery. * @hide */ public static final String SHUTDOWN_LOW_BATTERY = "battery"; /** * @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = { "SHUTDOWN_REASON_" }, value = { SHUTDOWN_REASON_UNKNOWN, SHUTDOWN_REASON_SHUTDOWN, SHUTDOWN_REASON_REBOOT, SHUTDOWN_REASON_USER_REQUESTED, SHUTDOWN_REASON_THERMAL_SHUTDOWN, SHUTDOWN_REASON_LOW_BATTERY, SHUTDOWN_REASON_BATTERY_THERMAL }) public @interface ShutdownReason {} /** * constant for shutdown reason being unknown. * @hide */ public static final int SHUTDOWN_REASON_UNKNOWN = 0; /** * constant for shutdown reason being normal shutdown. * @hide */ public static final int SHUTDOWN_REASON_SHUTDOWN = 1; /** * constant for shutdown reason being reboot. * @hide */ public static final int SHUTDOWN_REASON_REBOOT = 2; /** * constant for shutdown reason being user requested. * @hide */ public static final int SHUTDOWN_REASON_USER_REQUESTED = 3; /** * constant for shutdown reason being overheating. * @hide */ public static final int SHUTDOWN_REASON_THERMAL_SHUTDOWN = 4; /** * constant for shutdown reason being low battery. * @hide */ public static final int SHUTDOWN_REASON_LOW_BATTERY = 5; /** * constant for shutdown reason being critical battery thermal state. * @hide */ public static final int SHUTDOWN_REASON_BATTERY_THERMAL = 6; /** * @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef({ServiceType.LOCATION, ServiceType.VIBRATION, ServiceType.ANIMATION, ServiceType.FULL_BACKUP, ServiceType.KEYVALUE_BACKUP, ServiceType.NETWORK_FIREWALL, ServiceType.SCREEN_BRIGHTNESS, ServiceType.SOUND, ServiceType.BATTERY_STATS, ServiceType.DATA_SAVER, ServiceType.FORCE_ALL_APPS_STANDBY, ServiceType.FORCE_BACKGROUND_CHECK, ServiceType.OPTIONAL_SENSORS, ServiceType.AOD, ServiceType.QUICK_DOZE, ServiceType.NIGHT_MODE, }) public @interface ServiceType { int NULL = 0; int LOCATION = 1; int VIBRATION = 2; int ANIMATION = 3; int FULL_BACKUP = 4; int KEYVALUE_BACKUP = 5; int NETWORK_FIREWALL = 6; int SCREEN_BRIGHTNESS = 7; int SOUND = 8; int BATTERY_STATS = 9; int DATA_SAVER = 10; int AOD = 14; /** * Whether to enable force-app-standby on all apps or not. */ int FORCE_ALL_APPS_STANDBY = 11; /** * Whether to enable background check on all apps or not. */ int FORCE_BACKGROUND_CHECK = 12; /** * Whether to disable non-essential sensors. (e.g. edge sensors.) */ int OPTIONAL_SENSORS = 13; /** * Whether to go into Deep Doze as soon as the screen turns off or not. */ int QUICK_DOZE = 15; /** * Whether to enable night mode when battery saver is enabled. */ int NIGHT_MODE = 16; } /** * Either the location providers shouldn't be affected by battery saver, * or battery saver is off. */ public static final int LOCATION_MODE_NO_CHANGE = 0; /** * In this mode, the GPS based location provider should be disabled when battery saver is on and * the device is non-interactive. */ public static final int LOCATION_MODE_GPS_DISABLED_WHEN_SCREEN_OFF = 1; /** * All location providers should be disabled when battery saver is on and * the device is non-interactive. */ public static final int LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF = 2; /** * In this mode, all the location providers will be kept available, but location fixes * should only be provided to foreground apps. */ public static final int LOCATION_MODE_FOREGROUND_ONLY = 3; /** * In this mode, location will not be turned off, but LocationManager will throttle all * requests to providers when the device is non-interactive. */ public static final int LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF = 4; /** @hide */ public static final int MIN_LOCATION_MODE = LOCATION_MODE_NO_CHANGE; /** @hide */ public static final int MAX_LOCATION_MODE = LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF; /** * @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = {"LOCATION_MODE_"}, value = { LOCATION_MODE_NO_CHANGE, LOCATION_MODE_GPS_DISABLED_WHEN_SCREEN_OFF, LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF, LOCATION_MODE_FOREGROUND_ONLY, LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF, }) public @interface LocationPowerSaveMode {} /** * In this mode, all active SoundTrigger recognitions are enabled by the SoundTrigger system * service. * @hide */ @SystemApi public static final int SOUND_TRIGGER_MODE_ALL_ENABLED = 0; /** * In this mode, only privileged components of the SoundTrigger system service should be * enabled. This functionality is to be used to limit SoundTrigger recognitions to those only * deemed necessary by the system. * @hide */ @SystemApi public static final int SOUND_TRIGGER_MODE_CRITICAL_ONLY = 1; /** * In this mode, all active SoundTrigger recognitions should be disabled by the SoundTrigger * system service. * @hide */ @SystemApi public static final int SOUND_TRIGGER_MODE_ALL_DISABLED = 2; /** @hide */ public static final int MIN_SOUND_TRIGGER_MODE = SOUND_TRIGGER_MODE_ALL_ENABLED; /** @hide */ public static final int MAX_SOUND_TRIGGER_MODE = SOUND_TRIGGER_MODE_ALL_DISABLED; /** * @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = {"SOUND_TRIGGER_MODE_"}, value = { SOUND_TRIGGER_MODE_ALL_ENABLED, SOUND_TRIGGER_MODE_CRITICAL_ONLY, SOUND_TRIGGER_MODE_ALL_DISABLED, }) public @interface SoundTriggerPowerSaveMode {} /** @hide */ public static String locationPowerSaveModeToString(@LocationPowerSaveMode int mode) { switch (mode) { case LOCATION_MODE_NO_CHANGE: return "NO_CHANGE"; case LOCATION_MODE_GPS_DISABLED_WHEN_SCREEN_OFF: return "GPS_DISABLED_WHEN_SCREEN_OFF"; case LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF: return "ALL_DISABLED_WHEN_SCREEN_OFF"; case LOCATION_MODE_FOREGROUND_ONLY: return "FOREGROUND_ONLY"; case LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF: return "THROTTLE_REQUESTS_WHEN_SCREEN_OFF"; default: return Integer.toString(mode); } } private static final String CACHE_KEY_IS_POWER_SAVE_MODE_PROPERTY = "cache_key.is_power_save_mode"; private static final String CACHE_KEY_IS_INTERACTIVE_PROPERTY = "cache_key.is_interactive"; private static final int MAX_CACHE_ENTRIES = 1; private final PropertyInvalidatedCache* 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 = mContext.getSystemService(PowerManager.class); * 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. * *
* 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. *
* 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. * Additionally using the flag will keep only the appropriate screen on in a * multi-display scenario while using a wake lock will keep every screen powered on. *
* ** Recommended naming conventions for tags to make debugging easier: *
* The wakelock will only apply to the {@link com.android.server.display.DisplayGroup} of the * provided {@code displayId}. If {@code displayId} is {@link Display#INVALID_DISPLAY} then it * will apply to all {@link com.android.server.display.DisplayGroup DisplayGroups}. * * @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. * @param displayId The display id to which this wake lock is tied. * * @hide */ public WakeLock newWakeLock(int levelAndFlags, String tag, int displayId) { validateWakeLockParameters(levelAndFlags, tag); return new WakeLock(levelAndFlags, tag, mContext.getOpPackageName(), displayId); } /** @hide */ @UnsupportedAppUsage 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: case FULL_WAKE_LOCK: case PROXIMITY_SCREEN_OFF_WAKE_LOCK: case DOZE_WAKE_LOCK: case DRAW_WAKE_LOCK: case SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK: break; default: 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. *
* 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. *
* 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 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 * * @removed Requires signature or system permission. * @deprecated Use {@link #userActivity(long, int, int)}. */ @Deprecated public void userActivity(long when, boolean noChangeLights) { userActivity(when, USER_ACTIVITY_EVENT_OTHER, noChangeLights ? USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS : 0); } /** * Notifies the power manager that user activity happened. ** 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. *
* Requires the {@link android.Manifest.permission#DEVICE_POWER} or * {@link android.Manifest.permission#USER_ACTIVITY} 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 request with * other power management functions. It should be set * to the timestamp of the input event that caused the user activity. * @param event The user activity event. * @param flags Optional user activity flags. * * @see #wakeUp * @see #goToSleep * * @hide Requires signature or system permission. */ @SystemApi @RequiresPermission(anyOf = { android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.USER_ACTIVITY }) public void userActivity(long when, int event, int flags) { try { mService.userActivity(mContext.getDisplayId(), when, event, flags); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Forces the {@link android.view.Display#DEFAULT_DISPLAY_GROUP default display group} * to turn off. * *If the {@link android.view.Display#DEFAULT_DISPLAY_GROUP default display group} is * turned on it will be turned off. If all displays are off as a result of this action the * device will be put to sleep. If the {@link android.view.Display#DEFAULT_DISPLAY_GROUP * default display group} is already off then nothing will happen. * *
If the device is an Android TV playback device and the current active source on the * HDMI-connected TV, it will attempt to turn off that TV via HDMI-CEC. * *
* Overrides all the wake locks that are held. * This is what happens 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 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 * * @removed Requires signature permission. */ public void goToSleep(long time) { goToSleep(time, GO_TO_SLEEP_REASON_APPLICATION, 0); } /** * Forces the {@link android.view.Display#DEFAULT_DISPLAY_GROUP default display group} * to turn off. * *If the {@link android.view.Display#DEFAULT_DISPLAY_GROUP default display group} is * turned on it will be turned off. If all displays are off as a result of this action the * device will be put to sleep. If the {@link android.view.Display#DEFAULT_DISPLAY_GROUP * default display group} is already off then nothing will happen. * *
* Overrides all the wake locks that are held. * This is what happens 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 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. * @param reason The reason the device is going to sleep. * @param flags Optional flags to apply when going to sleep. * * @see #userActivity * @see #wakeUp * * @hide Requires signature permission. */ @UnsupportedAppUsage public void goToSleep(long time, int reason, int flags) { try { mService.goToSleep(time, reason, flags); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Forces the {@link com.android.server.display.DisplayGroup} of the provided {@code displayId} * to turn off. * *If the {@link com.android.server.display.DisplayGroup} of the provided {@code displayId} * is turned on it will be turned off. If all displays are off as a result of this action the * device will be put to sleep. If the {@link com.android.server.display.DisplayGroup} of * the provided {@code displayId} is already off then nothing will happen. * *
Overrides all the wake locks that are held. * This is what happens when the power key is pressed to turn off the screen. * *
Requires the {@link android.Manifest.permission#DEVICE_POWER} permission. * * @param displayId The display ID to turn off. If {@code displayId} is * {@link Display#INVALID_DISPLAY}, then all displays are turned off. * @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. * @param reason The reason the device is going to sleep. * @param flags Optional flags to apply when going to sleep. * * @see #userActivity * @see #wakeUp * * @hide Requires signature permission. */ @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public void goToSleep(int displayId, long time, @GoToSleepReason int reason, int flags) { try { mService.goToSleepWithDisplayId(displayId, time, reason, flags); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Forces the {@link android.view.Display#DEFAULT_DISPLAY_GROUP default display group} * to turn on. * *
If the {@link android.view.Display#DEFAULT_DISPLAY_GROUP default display group} is * turned off it will be turned on. Additionally, if the device is asleep it will be awoken. If * the {@link android.view.Display#DEFAULT_DISPLAY_GROUP default display group} is already * on then nothing will happen. * *
* This is what happens when the power key is pressed to turn on the screen. *
* Requires the {@link android.Manifest.permission#DEVICE_POWER} permission. *
* * @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 * * @deprecated Use {@link #wakeUp(long, int, String)} instead. * @removed Requires signature permission. */ @Deprecated public void wakeUp(long time) { wakeUp(time, WAKE_REASON_UNKNOWN, "wakeUp"); } /** * Forces the {@link android.view.Display#DEFAULT_DISPLAY_GROUP default display group} * to turn on. * *If the {@link android.view.Display#DEFAULT_DISPLAY_GROUP default display group} is * turned off it will be turned on. Additionally, if the device is asleep it will be awoken. If * the {@link android.view.Display#DEFAULT_DISPLAY_GROUP default display group} is already * on then nothing will happen. * *
* This is what happens when the power key is pressed to turn on the screen. *
* Requires the {@link android.Manifest.permission#DEVICE_POWER} permission. *
* * @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. * * @param details A free form string to explain the specific details behind the wake up for * debugging purposes. * * @see #userActivity * @see #goToSleep * * @deprecated Use {@link #wakeUp(long, int, String)} instead. * @hide */ @UnsupportedAppUsage @Deprecated public void wakeUp(long time, String details) { wakeUp(time, WAKE_REASON_UNKNOWN, details); } /** * Forces the {@link android.view.Display#DEFAULT_DISPLAY default display} to turn on. * *If the {@link android.view.Display#DEFAULT_DISPLAY default display} is turned off it will * be turned on. Additionally, if the device is asleep it will be awoken. If the {@link * android.view.Display#DEFAULT_DISPLAY default display} is already on then nothing will happen. * *
If the device is an Android TV playback device, it will attempt to turn on the * HDMI-connected TV and become the current active source via the HDMI-CEC One Touch Play * feature. * *
* This is what happens when the power key is pressed to turn on the screen. *
* Requires the {@link android.Manifest.permission#DEVICE_POWER} permission. *
* * @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. * * @param reason The reason for the wake up. * * @param details A free form string to explain the specific details behind the wake up for * debugging purposes. * * @see #userActivity * @see #goToSleep * @hide */ public void wakeUp(long time, @WakeReason int reason, String details) { try { mService.wakeUp(time, reason, details, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Forces the device to start napping. ** 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. *
* Requires the {@link android.Manifest.permission#DEVICE_POWER} permission. *
* * @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 Requires signature permission. */ public void nap(long time) { try { mService.nap(time); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Requests the device to start dreaming. ** If dream can not be started, for example if another {@link PowerManager} transition is in * progress, does nothing. Unlike {@link #nap(long)}, this does not put device to sleep when * dream ends. *
* Requires the {@link android.Manifest.permission#READ_DREAM_STATE} and * {@link android.Manifest.permission#WRITE_DREAM_STATE} permissions. *
* * @param time The time when the request to nap was issued, in the * {@link SystemClock#uptimeMillis()} time base. This timestamp may be used to correctly * order the dream request with other power management functions. It should be set * to the timestamp of the input event that caused the request to dream. * * @hide */ @SystemApi @RequiresPermission(allOf = { android.Manifest.permission.READ_DREAM_STATE, android.Manifest.permission.WRITE_DREAM_STATE }) public void dream(long time) { Sandman.startDreamByUserRequest(mContext); } /** * Boosts the brightness of the screen to maximum for a predetermined * period of time. This is used to make the screen more readable in bright * daylight for a short duration. ** Requires the {@link android.Manifest.permission#DEVICE_POWER} permission. *
* * @param time The time when the request to boost was issued, in the * {@link SystemClock#uptimeMillis()} time base. This timestamp is used to correctly * order the boost request with other power management functions. It should be set * to the timestamp of the input event that caused the request to boost. * * @hide Requires signature permission. */ public void boostScreenBrightness(long time) { try { mService.boostScreenBrightness(time); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * 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. */ public boolean isWakeLockLevelSupported(int level) { try { return mService.isWakeLockLevelSupported(level); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Returns true if the device is in an interactive state. ** For historical reasons, the name of this method refers to the power state of * the screen but it actually describes the overall interactive state of * the device. This method has been replaced by {@link #isInteractive}. *
* The value returned by this method only indicates whether the device is * in an interactive state which may have nothing to do with the screen being * on or off. To determine the actual state of the screen, * use {@link android.view.Display#getState}. *
* * @return True if the device is in an interactive state. * * @deprecated Use {@link #isInteractive} instead. */ @Deprecated public boolean isScreenOn() { return isInteractive(); } /** * Returns true if the device is in an interactive state. ** When this method returns true, the device is awake and ready to interact * with the user (although this is not a guarantee that the user is actively * interacting with the device just this moment). The main screen is usually * turned on while in this state. Certain features, such as the proximity * sensor, may temporarily turn off the screen while still leaving the device in an * interactive state. Note in particular that the device is still considered * to be interactive while dreaming (since dreams can be interactive) but not * when it is dozing or asleep. *
* When this method returns false, the device is dozing or asleep and must * be awoken before it will become ready to interact with the user again. The * main screen is usually turned off while in this state. Certain features, * such as "ambient mode" may cause the main screen to remain on (albeit in a * low power state) to display system-provided content while the device dozes. *
* The system will send a {@link android.content.Intent#ACTION_SCREEN_ON screen on} * or {@link android.content.Intent#ACTION_SCREEN_OFF screen off} broadcast * whenever the interactive state of the device changes. For historical reasons, * the names of these broadcasts refer to the power state of the screen * but they are actually sent in response to changes in the overall interactive * state of the device, as described by this method. *
* Services may use the non-interactive state as a hint to conserve power * since the user is not present. *
* * @return True if the device is in an interactive state. * * @see android.content.Intent#ACTION_SCREEN_ON * @see android.content.Intent#ACTION_SCREEN_OFF */ public boolean isInteractive() { return mInteractiveCache.query(null); } /** * Returns the interactive state for a specific display, which may not be the same as the * global wakefulness (which is true when any display is awake). * * @param displayId * @return whether the given display is present and interactive, or false * * @hide */ public boolean isInteractive(int displayId) { return mInteractiveCache.query(displayId); } /** * Returns {@code true} if this device supports rebooting userspace. * *This method exists solely for the sake of re-using same logic between {@code PowerManager} * and {@code PowerManagerService}. * * @deprecated TODO(b/292469129): remove this method. * @hide */ public static boolean isRebootingUserspaceSupportedImpl() { return false; } /** * Returns {@code true} if this device supports rebooting userspace. * * @deprecated userspace reboot is deprecated, this method always returns {@code false}. */ public boolean isRebootingUserspaceSupported() { return isRebootingUserspaceSupportedImpl(); } /** * Reboot the device. Will not return if the reboot is successful. *
* Requires the {@link android.Manifest.permission#REBOOT} permission. *
** If the {@code reason} string contains ",quiescent", then the screen stays off during reboot * and is not turned on again until the user triggers the device to wake up (for example, * by pressing the power key). * This behavior applies to Android TV devices launched on Android 11 (API level 30) or higher. *
* * @param reason code to pass to the kernel (e.g., "recovery") to * request special boot modes, or null. * @throws UnsupportedOperationException if userspace reboot was requested on a device that * doesn't support it. */ @RequiresPermission(permission.REBOOT) public void reboot(@Nullable String reason) { if (REBOOT_USERSPACE.equals(reason) && !isRebootingUserspaceSupported()) { throw new UnsupportedOperationException( "Attempted userspace reboot on a device that doesn't support it"); } try { mService.reboot(false, reason, true); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Reboot the device. Will not return if the reboot is successful. ** Requires the {@link android.Manifest.permission#REBOOT} permission. *
* @hide */ @RequiresPermission(permission.REBOOT) public void rebootSafeMode() { try { mService.rebootSafeMode(false, true); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Returns true if the platform has auto power save modes (eg. Doze & app standby) enabled. * This doesn't necessarily mean that the individual features are enabled. For example, if this * returns true, Doze might be enabled while app standby buckets remain disabled. * @hide */ @TestApi public boolean areAutoPowerSaveModesEnabled() { try { return mService.areAutoPowerSaveModesEnabled(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Returns true if the device is currently in power save mode. When in this mode, * applications should reduce their functionality in order to conserve battery as * much as possible. You can monitor for changes to this state with * {@link #ACTION_POWER_SAVE_MODE_CHANGED}. * * @return Returns true if currently in low power mode, else false. */ public boolean isPowerSaveMode() { return mPowerSaveModeCache.query(null); } /** * Set the current power save mode. * * @return True if the set was allowed. * * @hide * @see #isPowerSaveMode() */ @SystemApi @RequiresPermission(anyOf = { android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.POWER_SAVER }) public boolean setPowerSaveModeEnabled(boolean mode) { try { return mService.setPowerSaveModeEnabled(mode); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Returns true if Battery Saver is supported on this device. * * @hide */ @FlaggedApi(android.os.Flags.FLAG_BATTERY_SAVER_SUPPORTED_CHECK_API) @TestApi public boolean isBatterySaverSupported() { try { return mService.isBatterySaverSupported(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Gets the current policy for full power save mode. * * @return The {@link BatterySaverPolicyConfig} which is currently set for the full power save * policy level. * * @hide */ @SystemApi @NonNull public BatterySaverPolicyConfig getFullPowerSavePolicy() { try { return mService.getFullPowerSavePolicy(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Sets the policy for full power save mode. * * Any settings set by this API will persist for only one session of full battery saver mode. * The settings set by this API are cleared upon exit of full battery saver mode, and the * caller is expected to set the desired values again for the next full battery saver mode * session if desired. * * Use-cases: * 1. Set policy outside of full battery saver mode * - full policy set -> enter BS -> policy setting applied -> exit BS -> setting cleared * 2. Set policy inside of full battery saver mode * - enter BS -> full policy set -> policy setting applied -> exit BS -> setting cleared * * This API is intended to be used with {@link #getFullPowerSavePolicy()} API when a client only * wants to modify a specific setting(s) and leave the remaining policy attributes the same. * Example: * BatterySaverPolicyConfig newFullPolicyConfig = * new BatterySaverPolicyConfig.Builder(powerManager.getFullPowerSavePolicy()) * .setSoundTriggerMode(PowerManager.SOUND_TRIGGER_MODE_ALL_DISABLED) * .build(); * powerManager.setFullPowerSavePolicy(newFullPolicyConfig); * * @return true if there was an effectual change. If full battery saver is enabled, then this * will return true. * * @hide */ @SystemApi @RequiresPermission(anyOf = { android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.POWER_SAVER }) public boolean setFullPowerSavePolicy(@NonNull BatterySaverPolicyConfig config) { try { return mService.setFullPowerSavePolicy(config); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Updates the current state of dynamic power savings and disable threshold. This is * a signal to the system which an app can update to serve as an indicator that * the user will be in a battery critical situation before being able to plug in. * Only apps with the {@link android.Manifest.permission#POWER_SAVER} permission may do this. * This is a device global state, not a per user setting. * *When enabled, the system may enact various measures for reducing power consumption in * order to help ensure that the user will make it to their next charging point. The most * visible of these will be the automatic enabling of battery saver if the user has set * their battery saver mode to "automatic". Note * that this is NOT simply an on/off switch for features, but rather a hint for the * system to consider enacting these power saving features, some of which have additional * logic around when to activate based on this signal. * *
The provided threshold is the percentage the system should consider itself safe at given * the current state of the device. The value is an integer representing a battery level. * *
The threshold is meant to set an explicit stopping point for dynamic power savings * functionality so that the dynamic power savings itself remains a signal rather than becoming * an on/off switch for a subset of features. * @hide * * @param powerSaveHint A signal indicating to the system if it believes the * dynamic power savings behaviors should be activated. * @param disableThreshold When the suggesting app believes it would be safe to disable dynamic * power savings behaviors. * @return True if the update was allowed and succeeded. * * @hide */ @SystemApi @RequiresPermission(permission.POWER_SAVER) public boolean setDynamicPowerSaveHint(boolean powerSaveHint, int disableThreshold) { try { return mService.setDynamicPowerSaveHint(powerSaveHint, disableThreshold); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Sets the policy for adaptive power save. * * @return true if there was an effectual change. If full battery saver is enabled or the * adaptive policy is not enabled, then this will return false. * * @hide */ @SystemApi @RequiresPermission(anyOf = { android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.POWER_SAVER }) public boolean setAdaptivePowerSavePolicy(@NonNull BatterySaverPolicyConfig config) { try { return mService.setAdaptivePowerSavePolicy(config); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Enables or disables adaptive power save. * * @return true if there was an effectual change. If full battery saver is enabled, then this * will return false. * * @hide */ @SystemApi @RequiresPermission(anyOf = { android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.POWER_SAVER }) public boolean setAdaptivePowerSaveEnabled(boolean enabled) { try { return mService.setAdaptivePowerSaveEnabled(enabled); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Indicates automatic battery saver toggling by the system will be based on percentage. * * @see PowerManager#getPowerSaveModeTrigger() * * @hide */ @SystemApi public static final int POWER_SAVE_MODE_TRIGGER_PERCENTAGE = 0; /** * Indicates automatic battery saver toggling by the system will be based on the state * of the dynamic power savings signal. * * @see PowerManager#setDynamicPowerSaveHint(boolean, int) * @see PowerManager#getPowerSaveModeTrigger() * * @hide */ @SystemApi public static final int POWER_SAVE_MODE_TRIGGER_DYNAMIC = 1; /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(value = { POWER_SAVE_MODE_TRIGGER_PERCENTAGE, POWER_SAVE_MODE_TRIGGER_DYNAMIC }) public @interface AutoPowerSaveModeTriggers {} /** * Returns the current battery saver control mode. Values it may return are defined in * AutoPowerSaveModeTriggers. Note that this is a global device state, not a per user setting. * *
Note: Prior to Android version {@link Build.VERSION_CODES#S}, any app calling this method * was required to hold the {@link android.Manifest.permission#POWER_SAVER} permission. Starting * from Android version {@link Build.VERSION_CODES#S}, that permission is no longer required. * * @return The current value power saver mode for the system. * * @see AutoPowerSaveModeTriggers * @see PowerManager#getPowerSaveModeTrigger() * @hide */ @AutoPowerSaveModeTriggers @SystemApi public int getPowerSaveModeTrigger() { try { return mService.getPowerSaveModeTrigger(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Allows an app to tell the system how long it believes the battery will last and whether * this estimate is customized based on historical device usage or on a generic configuration. * These estimates will be displayed on system UI surfaces in place of the system computed * value. * * Calling this requires either the {@link android.Manifest.permission#DEVICE_POWER} or the * {@link android.Manifest.permission#BATTERY_PREDICTION} permissions. * * @param timeRemaining The time remaining as a {@link Duration}. * @param isPersonalized true if personalized based on device usage history, false otherwise. * @throws IllegalStateException if the device is powered or currently charging * @hide */ @SystemApi @RequiresPermission(anyOf = { android.Manifest.permission.BATTERY_PREDICTION, android.Manifest.permission.DEVICE_POWER }) public void setBatteryDischargePrediction(@NonNull Duration timeRemaining, boolean isPersonalized) { if (timeRemaining == null) { throw new IllegalArgumentException("time remaining must not be null"); } try { mService.setBatteryDischargePrediction(new ParcelDuration(timeRemaining), isPersonalized); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Returns the current battery life remaining estimate. * * @return The estimated battery life remaining as a {@link Duration}. Will be {@code null} if * the device is powered, charging, or an error was encountered. */ @Nullable public Duration getBatteryDischargePrediction() { try { final ParcelDuration parcelDuration = mService.getBatteryDischargePrediction(); if (parcelDuration == null) { return null; } return parcelDuration.getDuration(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Returns whether the current battery life remaining estimate is personalized based on device * usage history or not. This value does not take a device's powered or charging state into * account. * * @return A boolean indicating if the current discharge estimate is personalized based on * historical device usage or not. */ public boolean isBatteryDischargePredictionPersonalized() { try { return mService.isBatteryDischargePredictionPersonalized(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Get data about the battery saver mode for a specific service * @param serviceType unique key for the service, one of {@link ServiceType} * @return Battery saver state data. * * @hide * @see com.android.server.power.batterysaver.BatterySaverPolicy * @see PowerSaveState */ public PowerSaveState getPowerSaveState(@ServiceType int serviceType) { try { return mService.getPowerSaveState(serviceType); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Returns how location features should behave when battery saver is on. When battery saver * is off, this will always return {@link #LOCATION_MODE_NO_CHANGE}. * *
This API is normally only useful for components that provide location features. * * @see #isPowerSaveMode() * @see #ACTION_POWER_SAVE_MODE_CHANGED */ @LocationPowerSaveMode public int getLocationPowerSaveMode() { final PowerSaveState powerSaveState = getPowerSaveState(ServiceType.LOCATION); if (!powerSaveState.batterySaverEnabled) { return LOCATION_MODE_NO_CHANGE; } return powerSaveState.locationMode; } /** * Returns how SoundTrigger features should behave when battery saver is on. When battery saver * is off, this will always return {@link #SOUND_TRIGGER_MODE_ALL_ENABLED}. * *
This API is normally only useful for components that provide use SoundTrigger features. * * @see #isPowerSaveMode() * @see #ACTION_POWER_SAVE_MODE_CHANGED * * @hide */ @SoundTriggerPowerSaveMode public int getSoundTriggerPowerSaveMode() { final PowerSaveState powerSaveState = getPowerSaveState(ServiceType.SOUND); if (!powerSaveState.batterySaverEnabled) { return SOUND_TRIGGER_MODE_ALL_ENABLED; } return powerSaveState.soundTriggerMode; } /** * Returns true if the device is currently in idle mode. This happens when a device * has been sitting unused and unmoving for a sufficiently long period of time, so that * it decides to go into a lower power-use state. This may involve things like turning * off network access to apps. You can monitor for changes to this state with * {@link #ACTION_DEVICE_IDLE_MODE_CHANGED}. * * @return Returns true if currently in active device idle mode, else false. This is * when idle mode restrictions are being actively applied; it will return false if the * device is in a long-term idle mode but currently running a maintenance window where * restrictions have been lifted. */ public boolean isDeviceIdleMode() { try { return mService.isDeviceIdleMode(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Returns true if the device is currently in light idle mode. This happens when a device * has had its screen off for a short time, switching it into a batching mode where we * execute jobs, syncs, networking on a batching schedule. You can monitor for changes to * this state with {@link #ACTION_DEVICE_LIGHT_IDLE_MODE_CHANGED}. * * @return Returns true if currently in active device light idle mode, else false. This is * when light idle mode restrictions are being actively applied; it will return false if the * device is in a long-term idle mode but currently running a maintenance window where * restrictions have been lifted. */ public boolean isDeviceLightIdleMode() { try { return mService.isLightDeviceIdleMode(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * @see #isDeviceLightIdleMode() * @deprecated * @hide */ @Deprecated @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.S, publicAlternatives = "Use {@link #isDeviceLightIdleMode()} instead.") public boolean isLightDeviceIdleMode() { return isDeviceLightIdleMode(); } /** * Returns true if Low Power Standby is supported on this device. * * @hide */ @SystemApi @RequiresPermission(anyOf = { android.Manifest.permission.MANAGE_LOW_POWER_STANDBY, android.Manifest.permission.DEVICE_POWER }) public boolean isLowPowerStandbySupported() { try { return mService.isLowPowerStandbySupported(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Returns true if Low Power Standby is enabled. * *
When Low Power Standby is enabled, apps (including apps running foreground services) are * subject to additional restrictions while the device is non-interactive, outside of device * idle maintenance windows: Their network access is disabled, and any wakelocks they hold are * ignored. * *
When Low Power Standby is enabled or disabled, a Intent with action * {@link #ACTION_LOW_POWER_STANDBY_ENABLED_CHANGED} is broadcast to registered receivers. */ public boolean isLowPowerStandbyEnabled() { try { return mService.isLowPowerStandbyEnabled(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Set whether Low Power Standby is enabled. * Does nothing if Low Power Standby is not supported. * * @see #isLowPowerStandbySupported() * @see #isLowPowerStandbyEnabled() * @hide */ @SystemApi @RequiresPermission(anyOf = { android.Manifest.permission.MANAGE_LOW_POWER_STANDBY, android.Manifest.permission.DEVICE_POWER }) public void setLowPowerStandbyEnabled(boolean enabled) { try { mService.setLowPowerStandbyEnabled(enabled); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Set whether Low Power Standby should be active during doze maintenance mode. * Does nothing if Low Power Standby is not supported. * * @see #isLowPowerStandbySupported() * @see #isLowPowerStandbyEnabled() * @hide */ @SystemApi @RequiresPermission(anyOf = { android.Manifest.permission.MANAGE_LOW_POWER_STANDBY, android.Manifest.permission.DEVICE_POWER }) public void setLowPowerStandbyActiveDuringMaintenance(boolean activeDuringMaintenance) { try { mService.setLowPowerStandbyActiveDuringMaintenance(activeDuringMaintenance); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Force Low Power Standby restrictions to be active. * Does nothing if Low Power Standby is not supported. * * @see #isLowPowerStandbySupported() * @hide */ @TestApi @RequiresPermission(anyOf = { android.Manifest.permission.MANAGE_LOW_POWER_STANDBY, android.Manifest.permission.DEVICE_POWER }) public void forceLowPowerStandbyActive(boolean active) { try { mService.forceLowPowerStandbyActive(active); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Sets the current Low Power Standby policy. * * When the policy changes {@link #ACTION_LOW_POWER_STANDBY_POLICY_CHANGED} is broadcast to * registered receivers. * * @param policy The policy to set. If null, resets to the default policy. * @see #getLowPowerStandbyPolicy * @hide */ @SystemApi @RequiresPermission(anyOf = { android.Manifest.permission.MANAGE_LOW_POWER_STANDBY, android.Manifest.permission.DEVICE_POWER }) public void setLowPowerStandbyPolicy(@Nullable LowPowerStandbyPolicy policy) { try { mService.setLowPowerStandbyPolicy(LowPowerStandbyPolicy.toParcelable(policy)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Get the current Low Power Standby policy. * * When the policy changes {@link #ACTION_LOW_POWER_STANDBY_POLICY_CHANGED} is broadcast to * registered receivers. * * @see #setLowPowerStandbyPolicy * @hide */ @SystemApi @Nullable @RequiresPermission(anyOf = { android.Manifest.permission.MANAGE_LOW_POWER_STANDBY, android.Manifest.permission.DEVICE_POWER }) public LowPowerStandbyPolicy getLowPowerStandbyPolicy() { try { return LowPowerStandbyPolicy.fromParcelable(mService.getLowPowerStandbyPolicy()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Returns true if the calling package is exempt from Low Power Standby restrictions or * Low Power Standby is disabled (so Low Power Standby does not restrict apps), * false otherwise. */ public boolean isExemptFromLowPowerStandby() { try { return mService.isExemptFromLowPowerStandby(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Returns true if Low Power Standby is disabled (so Low Power Standby does not restrict apps), * or apps may be automatically exempt from Low Power Standby restrictions for the given reason. * * The system may exempt apps from Low Power Standby restrictions when using allowed features. * For example, if {@link #LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION} is allowed, * then apps with active voice interaction sessions are exempt from restrictions. */ public boolean isAllowedInLowPowerStandby(@LowPowerStandbyAllowedReason int reason) { try { return mService.isReasonAllowedInLowPowerStandby(reason); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Returns true if Low Power Standby is disabled (so Low Power Standby does not restrict apps), * or apps are allowed to use a given feature during Low Power Standby. */ public boolean isAllowedInLowPowerStandby(@NonNull String feature) { try { return mService.isFeatureAllowedInLowPowerStandby(feature); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Creates a new Low Power Standby ports lock. * *
A Low Power Standby ports lock requests that the given ports remain open during
* Low Power Standby.
* Call {@link LowPowerStandbyPortsLock#acquire} to acquire the lock.
* This request is only respected if the calling package is exempt
* (see {@link #isExemptFromLowPowerStandby()}), and until the returned
* {@code LowPowerStandbyPorts} object is destroyed or has
* {@link LowPowerStandbyPortsLock#release} called on it.
*
* @hide
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.SET_LOW_POWER_STANDBY_PORTS)
@NonNull
public LowPowerStandbyPortsLock newLowPowerStandbyPortsLock(
@NonNull List Being on the power allowlist means that the system will not apply most power saving
* features to the app. Guardrails for extreme cases may still be applied.
*/
public boolean isIgnoringBatteryOptimizations(String packageName) {
return getPowerExemptionManager().isAllowListed(packageName, true);
}
/**
* Turn off the device.
*
* @param confirm If true, shows a shutdown confirmation dialog.
* @param reason code to pass to android_reboot() (e.g. "userrequested"), or null.
* @param wait If true, this call waits for the shutdown to complete and does not return.
*
* @hide
*/
public void shutdown(boolean confirm, String reason, boolean wait) {
try {
mService.shutdown(confirm, reason, wait);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* This function checks if the device has implemented Sustained Performance
* Mode. This needs to be checked only once and is constant for a particular
* device/release.
*
* Sustained Performance Mode is intended to provide a consistent level of
* performance for prolonged amount of time.
*
* Applications should check if the device supports this mode, before using
* {@link android.view.Window#setSustainedPerformanceMode}.
*
* @return Returns True if the device supports it, false otherwise.
*
* @see android.view.Window#setSustainedPerformanceMode
*/
public boolean isSustainedPerformanceModeSupported() {
return mContext.getResources().getBoolean(
com.android.internal.R.bool.config_sustainedPerformanceModeSupported);
}
/**
* Thermal status code: Not under throttling.
*/
public static final int THERMAL_STATUS_NONE = Temperature.THROTTLING_NONE;
/**
* Thermal status code: Light throttling where UX is not impacted.
*/
public static final int THERMAL_STATUS_LIGHT = Temperature.THROTTLING_LIGHT;
/**
* Thermal status code: Moderate throttling where UX is not largely impacted.
*/
public static final int THERMAL_STATUS_MODERATE = Temperature.THROTTLING_MODERATE;
/**
* Thermal status code: Severe throttling where UX is largely impacted.
*/
public static final int THERMAL_STATUS_SEVERE = Temperature.THROTTLING_SEVERE;
/**
* Thermal status code: Platform has done everything to reduce power.
*/
public static final int THERMAL_STATUS_CRITICAL = Temperature.THROTTLING_CRITICAL;
/**
* Thermal status code: Key components in platform are shutting down due to thermal condition.
* Device functionalities will be limited.
*/
public static final int THERMAL_STATUS_EMERGENCY = Temperature.THROTTLING_EMERGENCY;
/**
* Thermal status code: Need shutdown immediately.
*/
public static final int THERMAL_STATUS_SHUTDOWN = Temperature.THROTTLING_SHUTDOWN;
/** @hide */
@Target(ElementType.TYPE_USE)
@IntDef(prefix = { "THERMAL_STATUS_" }, value = {
THERMAL_STATUS_NONE,
THERMAL_STATUS_LIGHT,
THERMAL_STATUS_MODERATE,
THERMAL_STATUS_SEVERE,
THERMAL_STATUS_CRITICAL,
THERMAL_STATUS_EMERGENCY,
THERMAL_STATUS_SHUTDOWN,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ThermalStatus {}
/**
* This function returns the current thermal status of the device.
*
* @return thermal status as int, {@link #THERMAL_STATUS_NONE} if device in not under
* thermal throttling.
*/
public @ThermalStatus int getCurrentThermalStatus() {
try {
return mThermalService.getCurrentThermalStatus();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Listener passed to
* {@link PowerManager#addThermalStatusListener} and
* {@link PowerManager#removeThermalStatusListener}
* to notify caller of thermal status has changed.
*/
public interface OnThermalStatusChangedListener {
/**
* Called when overall thermal throttling status changed.
* @param status the status
*/
void onThermalStatusChanged(@ThermalStatus int status);
}
/**
* This function adds a listener for thermal status change, listen call back will be
* enqueued tasks on the main thread
*
* @param listener listener to be added,
*/
public void addThermalStatusListener(@NonNull OnThermalStatusChangedListener listener) {
Objects.requireNonNull(listener, "listener cannot be null");
addThermalStatusListener(mContext.getMainExecutor(), listener);
}
/**
* This function adds a listener for thermal status change.
*
* @param executor {@link Executor} to handle listener callback.
* @param listener listener to be added.
*/
public void addThermalStatusListener(@NonNull @CallbackExecutor Executor executor,
@NonNull OnThermalStatusChangedListener listener) {
Objects.requireNonNull(listener, "listener cannot be null");
Objects.requireNonNull(executor, "executor cannot be null");
Preconditions.checkArgument(!mListenerMap.containsKey(listener),
"Listener already registered: %s", listener);
IThermalStatusListener internalListener = new IThermalStatusListener.Stub() {
@Override
public void onStatusChange(int status) {
final long token = Binder.clearCallingIdentity();
try {
executor.execute(() -> listener.onThermalStatusChanged(status));
} finally {
Binder.restoreCallingIdentity(token);
}
}
};
try {
if (mThermalService.registerThermalStatusListener(internalListener)) {
mListenerMap.put(listener, internalListener);
} else {
throw new RuntimeException("Listener failed to set");
}
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* This function removes a listener for thermal status change
*
* @param listener listener to be removed
*/
public void removeThermalStatusListener(@NonNull OnThermalStatusChangedListener listener) {
Objects.requireNonNull(listener, "listener cannot be null");
IThermalStatusListener internalListener = mListenerMap.get(listener);
Preconditions.checkArgument(internalListener != null, "Listener was not added");
try {
if (mThermalService.unregisterThermalStatusListener(internalListener)) {
mListenerMap.remove(listener);
} else {
throw new RuntimeException("Listener failed to remove");
}
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
@CurrentTimeMillisLong
private final AtomicLong mLastHeadroomUpdate = new AtomicLong(0L);
private static final int MINIMUM_HEADROOM_TIME_MILLIS = 500;
/**
* Provides an estimate of how much thermal headroom the device currently has before hitting
* severe throttling.
*
* Note that this only attempts to track the headroom of slow-moving sensors, such as the skin
* temperature sensor. This means that there is no benefit to calling this function more
* frequently than about once per second, and attempts to call significantly more frequently may
* result in the function returning {@code NaN}.
*
* In addition, in order to be able to provide an accurate forecast, the system does not attempt
* to forecast until it has multiple temperature samples from which to extrapolate. This should
* only take a few seconds from the time of the first call, but during this time, no forecasting
* will occur, and the current headroom will be returned regardless of the value of
* {@code forecastSeconds}.
*
* The value returned is a non-negative float that represents how much of the thermal envelope
* is in use (or is forecasted to be in use). A value of 1.0 indicates that the device is (or
* will be) throttled at {@link #THERMAL_STATUS_SEVERE}. Such throttling can affect the CPU,
* GPU, and other subsystems. Values may exceed 1.0, but there is no implied mapping to specific
* thermal status levels beyond that point. This means that values greater than 1.0 may
* correspond to {@link #THERMAL_STATUS_SEVERE}, but may also represent heavier throttling.
*
* A value of 0.0 corresponds to a fixed distance from 1.0, but does not correspond to any
* particular thermal status or temperature. Values on (0.0, 1.0] may be expected to scale
* linearly with temperature, though temperature changes over time are typically not linear.
* Negative values will be clamped to 0.0 before returning.
*
* @param forecastSeconds how many seconds in the future to forecast. Given that device
* conditions may change at any time, forecasts from further in the
* future will likely be less accurate than forecasts in the near future.
* @return a value greater than or equal to 0.0 where 1.0 indicates the SEVERE throttling
* threshold, as described above. Returns NaN if the device does not support this
* functionality or if this function is called significantly faster than once per
* second.
*/
public float getThermalHeadroom(@IntRange(from = 0, to = 60) int forecastSeconds) {
// Rate-limit calls into the thermal service
long now = SystemClock.elapsedRealtime();
long timeSinceLastUpdate = now - mLastHeadroomUpdate.get();
if (timeSinceLastUpdate < MINIMUM_HEADROOM_TIME_MILLIS) {
return Float.NaN;
}
try {
float forecast = mThermalService.getThermalHeadroom(forecastSeconds);
mLastHeadroomUpdate.set(SystemClock.elapsedRealtime());
return forecast;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Gets the thermal headroom thresholds for all available thermal throttling status above
* {@link #THERMAL_STATUS_NONE}.
*
* A thermal status key in the returned map is only set if the device manufacturer has the
* corresponding threshold defined for at least one of its sensors. If it's set, one should
* expect to see that from {@link #getCurrentThermalStatus()} or
* {@link OnThermalStatusChangedListener#onThermalStatusChanged(int)}.
*
* The headroom threshold is used to interpret the possible thermal throttling status based on
* the headroom prediction. For example, if the headroom threshold for
* {@link #THERMAL_STATUS_LIGHT} is 0.7, and a headroom prediction in 10s returns 0.75
* (or {@code getThermalHeadroom(10)=0.75}), one can expect that in 10 seconds the system could
* be in lightly throttled state if the workload remains the same. The app can consider
* taking actions according to the nearest throttling status the difference between the headroom
* and the threshold.
*
* For new devices it's guaranteed to have a single sensor, but for older devices with multiple
* sensors reporting different threshold values, the minimum threshold is taken to be
* conservative on predictions. Thus, when reading real-time headroom, it's not guaranteed that
* a real-time value of 0.75 (or {@code getThermalHeadroom(0)}=0.75) exceeding the threshold of
* 0.7 above will always come with lightly throttled state
* (or {@code getCurrentThermalStatus()=THERMAL_STATUS_LIGHT}) but it can be lower
* (or {@code getCurrentThermalStatus()=THERMAL_STATUS_NONE}). While it's always guaranteed that
* the device won't be throttled heavier than the unmet threshold's state, so a real-time
* headroom of 0.75 will never come with {@link #THERMAL_STATUS_MODERATE} but lower, and 0.65
* will never come with {@link #THERMAL_STATUS_LIGHT} but {@link #THERMAL_STATUS_NONE}.
*
* The returned map of thresholds will not change between calls to this function, so it's
* best to call this once on initialization. Modifying the result will not change the thresholds
* cached by the system, and a new call to the API will get a new copy.
*
* @return map from each thermal status to its thermal headroom
* @throws IllegalStateException if the thermal service is not ready
* @throws UnsupportedOperationException if the feature is not enabled
*/
@FlaggedApi(Flags.FLAG_ALLOW_THERMAL_HEADROOM_THRESHOLDS)
public @NonNull Map<@ThermalStatus Integer, Float> getThermalHeadroomThresholds() {
try {
synchronized (mThermalHeadroomThresholdsLock) {
if (mThermalHeadroomThresholds == null) {
mThermalHeadroomThresholds = mThermalService.getThermalHeadroomThresholds();
}
final ArrayMap This method has no effect if {@link #isAmbientDisplayAvailable()} is false.
*
* @param token A persistable identifier for the ambient display suppression that is unique
* within the calling application.
* @param suppress If set to {@code true}, ambient display will be suppressed. If set to
* {@code false}, ambient display will no longer be suppressed for the given
* token.
* @hide
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.WRITE_DREAM_STATE)
public void suppressAmbientDisplay(@NonNull String token, boolean suppress) {
try {
mService.suppressAmbientDisplay(token, suppress);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Returns true if ambient display is suppressed by the calling app with the given
* {@code token}.
*
* This method will return false if {@link #isAmbientDisplayAvailable()} is false.
*
* @param token The identifier of the ambient display suppression.
* @hide
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.READ_DREAM_STATE)
public boolean isAmbientDisplaySuppressedForToken(@NonNull String token) {
try {
return mService.isAmbientDisplaySuppressedForToken(token);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Returns true if ambient display is suppressed by any app with any token.
*
* This method will return false if {@link #isAmbientDisplayAvailable()} is false.
* @hide
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.READ_DREAM_STATE)
public boolean isAmbientDisplaySuppressed() {
try {
return mService.isAmbientDisplaySuppressed();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Returns true if ambient display is suppressed by the given {@code appUid} with the given
* {@code token}.
*
* This method will return false if {@link #isAmbientDisplayAvailable()} is false.
*
* @param token The identifier of the ambient display suppression.
* @param appUid The uid of the app that suppressed ambient display.
* @hide
*/
@RequiresPermission(allOf = {
android.Manifest.permission.READ_DREAM_STATE,
android.Manifest.permission.READ_DREAM_SUPPRESSION })
public boolean isAmbientDisplaySuppressedForTokenByApp(@NonNull String token, int appUid) {
try {
return mService.isAmbientDisplaySuppressedForTokenByApp(token, appUid);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Returns the reason the phone was last shutdown. Calling app must have the
* {@link android.Manifest.permission#DEVICE_POWER} permission to request this information.
* @return Reason for shutdown as an int, {@link #SHUTDOWN_REASON_UNKNOWN} if the file could
* not be accessed.
* @hide
*/
@ShutdownReason
public int getLastShutdownReason() {
try {
return mService.getLastShutdownReason();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Returns the reason the device last went to sleep (i.e. the last value of
* the second argument of {@link #goToSleep(long, int, int) goToSleep}).
*
* @return One of the {@code GO_TO_SLEEP_REASON_*} constants.
*
* @hide
*/
@GoToSleepReason
public int getLastSleepReason() {
try {
return mService.getLastSleepReason();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Forces the device to go to suspend, even if there are currently wakelocks being held.
* Caution
* This is a very dangerous command as it puts the device to sleep immediately. Apps and parts
* of the system will not be notified and will not have an opportunity to save state prior to
* the device going to suspend.
* This method should only be used in very rare circumstances where the device is intended
* to appear as completely off to the user and they have a well understood, reliable way of
* re-enabling it.
*
* Requires the {@link android.Manifest.permission#DEVICE_POWER} permission.
* If Low Power Standby is enabled ({@link #isLowPowerStandbyEnabled()}),
* wake-on-lan/wake-on-wlan may not be available while in standby.
* Use {@link #isAllowedInLowPowerStandby(String)} to determine whether the device allows this
* feature to be used during Low Power Standby with the currently active Low Power Standby
* policy.
*
* @see #isAllowedInLowPowerStandby(String)
*/
public static final String FEATURE_WAKE_ON_LAN_IN_LOW_POWER_STANDBY =
"com.android.lowpowerstandby.WAKE_ON_LAN";
/**
* @hide
*/
@IntDef(prefix = { "LOW_POWER_STANDBY_ALLOWED_REASON_" }, flag = true, value = {
LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION,
LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST,
LOW_POWER_STANDBY_ALLOWED_REASON_ONGOING_CALL,
})
@Retention(RetentionPolicy.SOURCE)
public @interface LowPowerStandbyAllowedReason {
}
/**
* Exempts active Voice Interaction Sessions in Low Power Standby.
*
* @see #isAllowedInLowPowerStandby(int)
*/
public static final int LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION = 1 << 0;
/**
* Exempts apps on the temporary powersave allowlist.
*
* @see #isAllowedInLowPowerStandby(int)
*/
public static final int LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST = 1 << 1;
/**
* Exempts apps with ongoing calls.
*
* This includes apps with foreground services of type "phoneCall".
*
* @see #isAllowedInLowPowerStandby(int)
*/
public static final int LOW_POWER_STANDBY_ALLOWED_REASON_ONGOING_CALL = 1 << 2;
/** @hide */
public static String lowPowerStandbyAllowedReasonsToString(
@LowPowerStandbyAllowedReason int allowedReasons) {
ArrayList Use {@link #newLowPowerStandbyPortsLock} to create a ports lock, and {@link #acquire()}
* to request the ports to remain open. The request is only respected if the app requesting the
* lock is exempt from Low Power Standby ({@link #isExemptFromLowPowerStandby()}).
*
* @hide
*/
@SystemApi
@SuppressLint("NotCloseable")
public final class LowPowerStandbyPortsLock {
private final IBinder mToken;
private final List Note: This lock is not reference counted, so calling this method will release the lock
* regardless of how many times {@link #acquire()} has been called before.
*/
@RequiresPermission(android.Manifest.permission.SET_LOW_POWER_STANDBY_PORTS)
public void release() {
synchronized (mToken) {
try {
mService.releaseLowPowerStandbyPorts(mToken);
mHeld = false;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
@Override
protected void finalize() {
synchronized (mToken) {
if (mHeld) {
Log.wtf(TAG, "LowPowerStandbyPorts finalized while still held");
release();
}
}
}
}
/**
* A listener interface to get notified when the wakelock is enabled/disabled.
*/
public interface WakeLockStateListener {
/**
* Frameworks could disable the wakelock because either device's power allowlist has
* changed, or the app's wakelock has exceeded its quota, or the app goes into cached
* state.
*
* This callback is called whenever the wakelock's state has changed.
*
* Any application using a WakeLock must request the {@code android.permission.WAKE_LOCK}
* permission in an {@code
* 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.
*
* 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()}.
*
* Ensures that the device is on at the level requested when
* the wake lock was created.
*
* 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.
*
* 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.
*
* 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.
*
* 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.
*
* Make sure to follow the tag naming convention when using WorkSource
* to make it easier for app developers to understand wake locks
* attributed to them. See {@link PowerManager#newWakeLock(int, String)}
* documentation.
* Example:
*
* Note: you must make sure that the Runnable eventually gets executed, otherwise you'll
* leak the wakelock!
*
* @hide
*/
@SuppressLint("WakelockTimeout")
public Runnable wrap(Runnable r) {
acquire();
return () -> {
try {
r.run();
} finally {
release();
}
};
}
/**
* Set the listener to get notified when the wakelock is enabled/disabled.
*
* @param executor {@link Executor} to handle listener callback.
* @param listener listener to be added, set the listener to null to cancel a listener.
*/
public void setStateListener(@NonNull @CallbackExecutor Executor executor,
@Nullable WakeLockStateListener listener) {
Preconditions.checkNotNull(executor, "executor cannot be null");
synchronized (mToken) {
if (listener != mListener) {
mListener = listener;
if (listener != null) {
mCallback = new IWakeLockCallback.Stub() {
public void onStateChanged(boolean enabled) {
final long token = Binder.clearCallingIdentity();
try {
executor.execute(() -> {
listener.onStateChanged(enabled);
});
} finally {
Binder.restoreCallingIdentity(token);
}
}
};
} else {
mCallback = null;
}
if (mHeld) {
try {
mService.updateWakeLockCallback(mToken, mCallback);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
}
}
}
/**
* @hide
*/
public static void invalidatePowerSaveModeCaches() {
PropertyInvalidatedCache.invalidateCache(CACHE_KEY_IS_POWER_SAVE_MODE_PROPERTY);
}
/**
* @hide
*/
public static void invalidateIsInteractiveCaches() {
PropertyInvalidatedCache.invalidateCache(CACHE_KEY_IS_INTERACTIVE_PROPERTY);
}
}
* mHandler.post(mWakeLock.wrap(() -> {
* // do things on handler, lock is held while we're waiting for this
* // to get scheduled and until the runnable is done executing.
* });
*
*
*