diff --git a/api/current.txt b/api/current.txt index f3f1cb928934f8f0ab1a0de1801708cfaed81c30..f7053b62184d2fc06304fe1b8531ab11103a0b32 100644 --- a/api/current.txt +++ b/api/current.txt @@ -35016,11 +35016,12 @@ package android.os { method public boolean isIgnoringBatteryOptimizations(String); method public boolean isInteractive(); method public boolean isPowerSaveMode(); + method public boolean isRebootingUserspaceSupported(); method @Deprecated public boolean isScreenOn(); method public boolean isSustainedPerformanceModeSupported(); method public boolean isWakeLockLevelSupported(int); method public android.os.PowerManager.WakeLock newWakeLock(int, String); - method public void reboot(String); + method public void reboot(@Nullable String); method public void removeThermalStatusListener(@NonNull android.os.PowerManager.OnThermalStatusChangedListener); field public static final int ACQUIRE_CAUSES_WAKEUP = 268435456; // 0x10000000 field public static final String ACTION_DEVICE_IDLE_MODE_CHANGED = "android.os.action.DEVICE_IDLE_MODE_CHANGED"; diff --git a/api/system-current.txt b/api/system-current.txt index e539e6cc60f62f08f36dd1283e678b5329f229e0..fe7b3999d7b7f3badf83c8379d0086230593efa4 100755 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -5986,6 +5986,7 @@ package android.os { method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.USER_ACTIVITY}) public void userActivity(long, int, int); field public static final int POWER_SAVE_MODE_TRIGGER_DYNAMIC = 1; // 0x1 field public static final int POWER_SAVE_MODE_TRIGGER_PERCENTAGE = 0; // 0x0 + field public static final String REBOOT_USERSPACE = "userspace"; field public static final int USER_ACTIVITY_EVENT_ACCESSIBILITY = 3; // 0x3 field public static final int USER_ACTIVITY_EVENT_BUTTON = 1; // 0x1 field public static final int USER_ACTIVITY_EVENT_OTHER = 0; // 0x0 diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index ab4d424ac0532b17f899d52b1b9270a34742beb7..c618dbc2b551542d4e403e2a28baf6ccfceee0fc 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -20,6 +20,7 @@ import android.Manifest.permission; import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SystemApi; @@ -604,6 +605,13 @@ public final class PowerManager { */ public static final String REBOOT_SAFE_MODE = "safemode"; + /** + * The 'reason' value used for rebooting userspace. + * @hide + */ + @SystemApi + public static final String REBOOT_USERSPACE = "userspace"; + /** * The 'reason' value used when rebooting the device without turning on the screen. * @hide @@ -1382,6 +1390,14 @@ public final class PowerManager { } } + /** + * Returns {@code true} if this device supports rebooting userspace. + */ + // TODO(b/138605180): add link to documentation once it's ready. + public boolean isRebootingUserspaceSupported() { + return SystemProperties.getBoolean("ro.init.userspace_reboot.is_supported", false); + } + /** * Reboot the device. Will not return if the reboot is successful. * <p> @@ -1390,8 +1406,14 @@ public final class PowerManager { * * @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. */ - public void reboot(String reason) { + 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) { diff --git a/core/tests/coretests/src/android/os/PowerManagerTest.java b/core/tests/coretests/src/android/os/PowerManagerTest.java index 576ac73bc183126f68e29c9dc6a71cde41b32cda..5cb7852f7acc75fcaff7567794267d8d3fbfd2d8 100644 --- a/core/tests/coretests/src/android/os/PowerManagerTest.java +++ b/core/tests/coretests/src/android/os/PowerManagerTest.java @@ -239,4 +239,17 @@ public class PowerManagerTest extends AndroidTestCase { verify(mListener2, timeout(CALLBACK_TIMEOUT_MILLI_SEC) .times(1)).onThermalStatusChanged(status); } + + @Test + public void testUserspaceRebootNotSupported_throwsUnsupportedOperationException() { + // Can't use assumption framework with AndroidTestCase :( + if (mPm.isRebootingUserspaceSupported()) { + return; + } + try { + mPm.reboot(PowerManager.REBOOT_USERSPACE); + fail("UnsupportedOperationException not thrown"); + } catch (UnsupportedOperationException expected) { + } + } }