Loading api/system-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -5328,6 +5328,7 @@ package android.os { public final class PowerManager { method @RequiresPermission(allOf={android.Manifest.permission.READ_DREAM_STATE, android.Manifest.permission.WRITE_DREAM_STATE}) public void dream(long); method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public boolean forceSuspend(); method @RequiresPermission(android.Manifest.permission.POWER_SAVER) public int getPowerSaveMode(); method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.POWER_SAVER}) public boolean setAdaptivePowerSaveEnabled(boolean); method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.POWER_SAVER}) public boolean setAdaptivePowerSavePolicy(@NonNull android.os.BatterySaverPolicyConfig); Loading cmds/svc/src/com/android/commands/svc/PowerCommand.java +27 −1 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ import android.os.SystemClock; import android.os.SystemProperties; public class PowerCommand extends Svc.Command { private static final int FORCE_SUSPEND_DELAY_DEFAULT_MILLIS = 0; public PowerCommand() { super("power"); } Loading @@ -42,7 +44,17 @@ public class PowerCommand extends Svc.Command { + " svc power reboot [reason]\n" + " Perform a runtime shutdown and reboot device with specified reason.\n" + " svc power shutdown\n" + " Perform a runtime shutdown and power off the device.\n"; + " Perform a runtime shutdown and power off the device.\n" + " svc power forcesuspend [t]\n" + " Force the system into suspend, ignoring all wakelocks.\n" + " t - Number of milliseconds to wait before issuing force-suspend.\n" + " Helps with devices that can't suspend while plugged in.\n" + " Defaults to " + FORCE_SUSPEND_DELAY_DEFAULT_MILLIS + ".\n" + " When using a delay, you must use the nohup shell modifier:\n" + " 'adb shell nohup svc power forcesuspend [time]'\n" + " Use caution; this is dangerous. It puts the device to sleep\n" + " immediately without giving apps or the system an opportunity to\n" + " save their state.\n"; } public void run(String[] args) { Loading Loading @@ -101,6 +113,20 @@ public class PowerCommand extends Svc.Command { maybeLogRemoteException("Failed to shutdown."); } return; } else if ("forcesuspend".equals(args[1])) { int delayMillis = args.length > 2 ? Integer.parseInt(args[2]) : FORCE_SUSPEND_DELAY_DEFAULT_MILLIS; try { Thread.sleep(delayMillis); if (!pm.forceSuspend()) { System.err.println("Failed to force suspend."); } } catch (InterruptedException e) { System.err.println("Failed to force suspend: " + e); } catch (RemoteException e) { maybeLogRemoteException("Failed to force-suspend with exception: " + e); } return; } } } Loading core/java/android/os/IPowerManager.aidl +3 −0 Original line number Diff line number Diff line Loading @@ -74,4 +74,7 @@ interface IPowerManager // controls whether PowerManager should doze after the screen turns off or not void setDozeAfterScreenOff(boolean on); // Forces the system to suspend even if there are held wakelocks. boolean forceSuspend(); } core/java/android/os/PowerManager.java +44 −1 Original line number Diff line number Diff line Loading @@ -362,11 +362,16 @@ public final class PowerManager { @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 = 0; 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 Loading Loading @@ -411,6 +416,17 @@ public final class PowerManager { */ 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; /** * @hide */ public static final int GO_TO_SLEEP_REASON_MAX = GO_TO_SLEEP_REASON_FORCE_SUSPEND; /** * @hide */ Loading @@ -424,6 +440,7 @@ public final class PowerManager { case GO_TO_SLEEP_REASON_HDMI: return "hdmi"; case GO_TO_SLEEP_REASON_SLEEP_BUTTON: return "sleep_button"; case GO_TO_SLEEP_REASON_ACCESSIBILITY: return "accessibility"; case GO_TO_SLEEP_REASON_FORCE_SUSPEND: return "force_suspend"; default: return Integer.toString(sleepReason); } } Loading Loading @@ -1852,6 +1869,32 @@ public final class PowerManager { } } /** * Forces the device to go to suspend, even if there are currently wakelocks being held. * <b>Caution</b> * 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. * </p><p> * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission. * </p> * * @return true on success, false otherwise. * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public boolean forceSuspend() { try { return mService.forceSuspend(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Intent that is broadcast when the state of {@link #isPowerSaveMode()} changes. * This broadcast is only sent to registered receivers. Loading services/core/java/com/android/server/power/PowerManagerService.java +66 −35 Original line number Diff line number Diff line Loading @@ -538,6 +538,9 @@ public final class PowerManagerService extends SystemService // True if we are currently in VR Mode. private boolean mIsVrModeEnabled; // True if we in the process of performing a forceSuspend private boolean mForceSuspendActive; private final class ForegroundProfileObserver extends SynchronousUserSwitchObserver { @Override public void onUserSwitching(int newUserId) throws RemoteException {} Loading Loading @@ -684,6 +687,11 @@ public final class PowerManagerService extends SystemService public void nativeSetFeature(int featureId, int data) { PowerManagerService.nativeSetFeature(featureId, data); } /** Wrapper for PowerManager.nativeForceSuspend */ public boolean nativeForceSuspend() { return PowerManagerService.nativeForceSuspend(); } } @VisibleForTesting Loading Loading @@ -718,6 +726,7 @@ public final class PowerManagerService extends SystemService private static native void nativeSetAutoSuspend(boolean enable); private static native void nativeSendPowerHint(int hintId, int data); private static native void nativeSetFeature(int featureId, int data); private static native boolean nativeForceSuspend(); public PowerManagerService(Context context) { this(context, new Injector()); Loading Loading @@ -1427,7 +1436,7 @@ public final class PowerManagerService extends SystemService } if (eventTime < mLastSleepTime || mWakefulness == WAKEFULNESS_AWAKE || !mBootCompleted || !mSystemReady) { || !mBootCompleted || !mSystemReady || mForceSuspendActive) { return false; } Loading Loading @@ -1463,8 +1472,13 @@ public final class PowerManagerService extends SystemService } } // This method is called goToSleep for historical reasons but we actually start // dozing before really going to sleep. /** * Puts the system in doze. * * This method is called goToSleep for historical reasons but actually attempts to DOZE, * and only tucks itself in to SLEEP if requested with the flag * {@link PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE}. */ @SuppressWarnings("deprecation") private boolean goToSleepNoUpdateLocked(long eventTime, int reason, int flags, int uid) { if (DEBUG_SPEW) { Loading @@ -1481,35 +1495,10 @@ public final class PowerManagerService extends SystemService Trace.traceBegin(Trace.TRACE_TAG_POWER, "goToSleep"); try { switch (reason) { case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN: Slog.i(TAG, "Going to sleep due to device administration policy " reason = Math.min(PowerManager.GO_TO_SLEEP_REASON_MAX, Math.max(reason, PowerManager.GO_TO_SLEEP_REASON_MIN)); Slog.i(TAG, "Going to sleep due to " + PowerManager.sleepReasonToString(reason) + " (uid " + uid + ")..."); break; case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT: Slog.i(TAG, "Going to sleep due to screen timeout (uid " + uid +")..."); break; case PowerManager.GO_TO_SLEEP_REASON_LID_SWITCH: Slog.i(TAG, "Going to sleep due to lid switch (uid " + uid +")..."); break; case PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON: Slog.i(TAG, "Going to sleep due to power button (uid " + uid +")..."); break; case PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON: Slog.i(TAG, "Going to sleep due to sleep button (uid " + uid +")..."); break; case PowerManager.GO_TO_SLEEP_REASON_HDMI: Slog.i(TAG, "Going to sleep due to HDMI standby (uid " + uid +")..."); break; case PowerManager.GO_TO_SLEEP_REASON_ACCESSIBILITY: Slog.i(TAG, "Going to sleep by an accessibility service request (uid " + uid +")..."); break; default: Slog.i(TAG, "Going to sleep by application request (uid " + uid +")..."); reason = PowerManager.GO_TO_SLEEP_REASON_APPLICATION; break; } mLastSleepTime = eventTime; mLastSleepReason = reason; Loading Loading @@ -3063,10 +3052,10 @@ public final class PowerManagerService extends SystemService if (appid >= Process.FIRST_APPLICATION_UID) { // Cached inactive processes are never allowed to hold wake locks. if (mConstants.NO_CACHED_WAKE_LOCKS) { disabled = !wakeLock.mUidState.mActive && wakeLock.mUidState.mProcState disabled = mForceSuspendActive || (!wakeLock.mUidState.mActive && wakeLock.mUidState.mProcState != ActivityManager.PROCESS_STATE_NONEXISTENT && wakeLock.mUidState.mProcState > ActivityManager.PROCESS_STATE_RECEIVER; wakeLock.mUidState.mProcState > ActivityManager.PROCESS_STATE_RECEIVER); } if (mDeviceIdleMode) { // If we are in idle mode, we will also ignore all partial wake locks that are Loading Loading @@ -3241,6 +3230,34 @@ public final class PowerManagerService extends SystemService } } private boolean forceSuspendInternal(int uid) { try { synchronized (mLock) { mForceSuspendActive = true; // Place the system in an non-interactive state goToSleepInternal(SystemClock.uptimeMillis(), PowerManager.GO_TO_SLEEP_REASON_FORCE_SUSPEND, PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE, uid); // Disable all the partial wake locks as well updateWakeLockDisabledStatesLocked(); } Slog.i(TAG, "Force-Suspending (uid " + uid + ")..."); boolean success = mNativeWrapper.nativeForceSuspend(); if (!success) { Slog.i(TAG, "Force-Suspending failed in native."); } return success; } finally { synchronized (mLock) { mForceSuspendActive = false; // Re-enable wake locks once again. updateWakeLockDisabledStatesLocked(); } } } /** * Low-level function turn the device off immediately, without trying * to be clean. Most people should use {@link ShutdownThread} for a clean shutdown. Loading Loading @@ -4743,6 +4760,20 @@ public final class PowerManagerService extends SystemService } } @Override // binder call public boolean forceSuspend() { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.DEVICE_POWER, null); final int uid = Binder.getCallingUid(); final long ident = Binder.clearCallingIdentity(); try { return forceSuspendInternal(uid); } finally { Binder.restoreCallingIdentity(ident); } } @Override // Binder call protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; Loading Loading
api/system-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -5328,6 +5328,7 @@ package android.os { public final class PowerManager { method @RequiresPermission(allOf={android.Manifest.permission.READ_DREAM_STATE, android.Manifest.permission.WRITE_DREAM_STATE}) public void dream(long); method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public boolean forceSuspend(); method @RequiresPermission(android.Manifest.permission.POWER_SAVER) public int getPowerSaveMode(); method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.POWER_SAVER}) public boolean setAdaptivePowerSaveEnabled(boolean); method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.POWER_SAVER}) public boolean setAdaptivePowerSavePolicy(@NonNull android.os.BatterySaverPolicyConfig); Loading
cmds/svc/src/com/android/commands/svc/PowerCommand.java +27 −1 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ import android.os.SystemClock; import android.os.SystemProperties; public class PowerCommand extends Svc.Command { private static final int FORCE_SUSPEND_DELAY_DEFAULT_MILLIS = 0; public PowerCommand() { super("power"); } Loading @@ -42,7 +44,17 @@ public class PowerCommand extends Svc.Command { + " svc power reboot [reason]\n" + " Perform a runtime shutdown and reboot device with specified reason.\n" + " svc power shutdown\n" + " Perform a runtime shutdown and power off the device.\n"; + " Perform a runtime shutdown and power off the device.\n" + " svc power forcesuspend [t]\n" + " Force the system into suspend, ignoring all wakelocks.\n" + " t - Number of milliseconds to wait before issuing force-suspend.\n" + " Helps with devices that can't suspend while plugged in.\n" + " Defaults to " + FORCE_SUSPEND_DELAY_DEFAULT_MILLIS + ".\n" + " When using a delay, you must use the nohup shell modifier:\n" + " 'adb shell nohup svc power forcesuspend [time]'\n" + " Use caution; this is dangerous. It puts the device to sleep\n" + " immediately without giving apps or the system an opportunity to\n" + " save their state.\n"; } public void run(String[] args) { Loading Loading @@ -101,6 +113,20 @@ public class PowerCommand extends Svc.Command { maybeLogRemoteException("Failed to shutdown."); } return; } else if ("forcesuspend".equals(args[1])) { int delayMillis = args.length > 2 ? Integer.parseInt(args[2]) : FORCE_SUSPEND_DELAY_DEFAULT_MILLIS; try { Thread.sleep(delayMillis); if (!pm.forceSuspend()) { System.err.println("Failed to force suspend."); } } catch (InterruptedException e) { System.err.println("Failed to force suspend: " + e); } catch (RemoteException e) { maybeLogRemoteException("Failed to force-suspend with exception: " + e); } return; } } } Loading
core/java/android/os/IPowerManager.aidl +3 −0 Original line number Diff line number Diff line Loading @@ -74,4 +74,7 @@ interface IPowerManager // controls whether PowerManager should doze after the screen turns off or not void setDozeAfterScreenOff(boolean on); // Forces the system to suspend even if there are held wakelocks. boolean forceSuspend(); }
core/java/android/os/PowerManager.java +44 −1 Original line number Diff line number Diff line Loading @@ -362,11 +362,16 @@ public final class PowerManager { @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 = 0; 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 Loading Loading @@ -411,6 +416,17 @@ public final class PowerManager { */ 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; /** * @hide */ public static final int GO_TO_SLEEP_REASON_MAX = GO_TO_SLEEP_REASON_FORCE_SUSPEND; /** * @hide */ Loading @@ -424,6 +440,7 @@ public final class PowerManager { case GO_TO_SLEEP_REASON_HDMI: return "hdmi"; case GO_TO_SLEEP_REASON_SLEEP_BUTTON: return "sleep_button"; case GO_TO_SLEEP_REASON_ACCESSIBILITY: return "accessibility"; case GO_TO_SLEEP_REASON_FORCE_SUSPEND: return "force_suspend"; default: return Integer.toString(sleepReason); } } Loading Loading @@ -1852,6 +1869,32 @@ public final class PowerManager { } } /** * Forces the device to go to suspend, even if there are currently wakelocks being held. * <b>Caution</b> * 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. * </p><p> * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission. * </p> * * @return true on success, false otherwise. * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public boolean forceSuspend() { try { return mService.forceSuspend(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Intent that is broadcast when the state of {@link #isPowerSaveMode()} changes. * This broadcast is only sent to registered receivers. Loading
services/core/java/com/android/server/power/PowerManagerService.java +66 −35 Original line number Diff line number Diff line Loading @@ -538,6 +538,9 @@ public final class PowerManagerService extends SystemService // True if we are currently in VR Mode. private boolean mIsVrModeEnabled; // True if we in the process of performing a forceSuspend private boolean mForceSuspendActive; private final class ForegroundProfileObserver extends SynchronousUserSwitchObserver { @Override public void onUserSwitching(int newUserId) throws RemoteException {} Loading Loading @@ -684,6 +687,11 @@ public final class PowerManagerService extends SystemService public void nativeSetFeature(int featureId, int data) { PowerManagerService.nativeSetFeature(featureId, data); } /** Wrapper for PowerManager.nativeForceSuspend */ public boolean nativeForceSuspend() { return PowerManagerService.nativeForceSuspend(); } } @VisibleForTesting Loading Loading @@ -718,6 +726,7 @@ public final class PowerManagerService extends SystemService private static native void nativeSetAutoSuspend(boolean enable); private static native void nativeSendPowerHint(int hintId, int data); private static native void nativeSetFeature(int featureId, int data); private static native boolean nativeForceSuspend(); public PowerManagerService(Context context) { this(context, new Injector()); Loading Loading @@ -1427,7 +1436,7 @@ public final class PowerManagerService extends SystemService } if (eventTime < mLastSleepTime || mWakefulness == WAKEFULNESS_AWAKE || !mBootCompleted || !mSystemReady) { || !mBootCompleted || !mSystemReady || mForceSuspendActive) { return false; } Loading Loading @@ -1463,8 +1472,13 @@ public final class PowerManagerService extends SystemService } } // This method is called goToSleep for historical reasons but we actually start // dozing before really going to sleep. /** * Puts the system in doze. * * This method is called goToSleep for historical reasons but actually attempts to DOZE, * and only tucks itself in to SLEEP if requested with the flag * {@link PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE}. */ @SuppressWarnings("deprecation") private boolean goToSleepNoUpdateLocked(long eventTime, int reason, int flags, int uid) { if (DEBUG_SPEW) { Loading @@ -1481,35 +1495,10 @@ public final class PowerManagerService extends SystemService Trace.traceBegin(Trace.TRACE_TAG_POWER, "goToSleep"); try { switch (reason) { case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN: Slog.i(TAG, "Going to sleep due to device administration policy " reason = Math.min(PowerManager.GO_TO_SLEEP_REASON_MAX, Math.max(reason, PowerManager.GO_TO_SLEEP_REASON_MIN)); Slog.i(TAG, "Going to sleep due to " + PowerManager.sleepReasonToString(reason) + " (uid " + uid + ")..."); break; case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT: Slog.i(TAG, "Going to sleep due to screen timeout (uid " + uid +")..."); break; case PowerManager.GO_TO_SLEEP_REASON_LID_SWITCH: Slog.i(TAG, "Going to sleep due to lid switch (uid " + uid +")..."); break; case PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON: Slog.i(TAG, "Going to sleep due to power button (uid " + uid +")..."); break; case PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON: Slog.i(TAG, "Going to sleep due to sleep button (uid " + uid +")..."); break; case PowerManager.GO_TO_SLEEP_REASON_HDMI: Slog.i(TAG, "Going to sleep due to HDMI standby (uid " + uid +")..."); break; case PowerManager.GO_TO_SLEEP_REASON_ACCESSIBILITY: Slog.i(TAG, "Going to sleep by an accessibility service request (uid " + uid +")..."); break; default: Slog.i(TAG, "Going to sleep by application request (uid " + uid +")..."); reason = PowerManager.GO_TO_SLEEP_REASON_APPLICATION; break; } mLastSleepTime = eventTime; mLastSleepReason = reason; Loading Loading @@ -3063,10 +3052,10 @@ public final class PowerManagerService extends SystemService if (appid >= Process.FIRST_APPLICATION_UID) { // Cached inactive processes are never allowed to hold wake locks. if (mConstants.NO_CACHED_WAKE_LOCKS) { disabled = !wakeLock.mUidState.mActive && wakeLock.mUidState.mProcState disabled = mForceSuspendActive || (!wakeLock.mUidState.mActive && wakeLock.mUidState.mProcState != ActivityManager.PROCESS_STATE_NONEXISTENT && wakeLock.mUidState.mProcState > ActivityManager.PROCESS_STATE_RECEIVER; wakeLock.mUidState.mProcState > ActivityManager.PROCESS_STATE_RECEIVER); } if (mDeviceIdleMode) { // If we are in idle mode, we will also ignore all partial wake locks that are Loading Loading @@ -3241,6 +3230,34 @@ public final class PowerManagerService extends SystemService } } private boolean forceSuspendInternal(int uid) { try { synchronized (mLock) { mForceSuspendActive = true; // Place the system in an non-interactive state goToSleepInternal(SystemClock.uptimeMillis(), PowerManager.GO_TO_SLEEP_REASON_FORCE_SUSPEND, PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE, uid); // Disable all the partial wake locks as well updateWakeLockDisabledStatesLocked(); } Slog.i(TAG, "Force-Suspending (uid " + uid + ")..."); boolean success = mNativeWrapper.nativeForceSuspend(); if (!success) { Slog.i(TAG, "Force-Suspending failed in native."); } return success; } finally { synchronized (mLock) { mForceSuspendActive = false; // Re-enable wake locks once again. updateWakeLockDisabledStatesLocked(); } } } /** * Low-level function turn the device off immediately, without trying * to be clean. Most people should use {@link ShutdownThread} for a clean shutdown. Loading Loading @@ -4743,6 +4760,20 @@ public final class PowerManagerService extends SystemService } } @Override // binder call public boolean forceSuspend() { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.DEVICE_POWER, null); final int uid = Binder.getCallingUid(); final long ident = Binder.clearCallingIdentity(); try { return forceSuspendInternal(uid); } finally { Binder.restoreCallingIdentity(ident); } } @Override // Binder call protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; Loading