From 57300d9057fae45decaa7dcfc7dad0b31d710a92 Mon Sep 17 00:00:00 2001 From: Nikita Ioffe Date: Thu, 9 Apr 2020 00:47:33 +0100 Subject: [PATCH] Introduce static @hide PowerManager.isRebootingUserspaceSupportedImpl() This method consolidates logic of testing whenever rebooting userspace is supported in a place that can be used both from PowerMager.isRebootingUserspaceSupported() API and from PowerManagerService.reboot() implementation. Consequently, this makes `adb shell svc power reboot userspace` also benefit from that check, and fail userspace reboot on devices that don't support it. Also tweaked logic of ignoring RemoteException to take into account userspace reboot. Test: adb root Test: adb shell setprop init.userspace_reboot.is_supported 0 Test: adb shell svc power reboot userspace & verified error message Test: adb shell setprop init.userspace_reboot.is_supported 1 Test: adb shell svc power reboot userspace & verified no error message Test: atest PowerManagerTest Test: atest CtsUserspaceRebootHostSideTestCases Bug: 152803929 Change-Id: I2d3a8e0ae1320c408a838c5c5fdf4cd977b167b3 --- .../com/android/commands/svc/PowerCommand.java | 7 ++++++- core/java/android/os/PowerManager.java | 15 ++++++++++++++- .../android/server/power/PowerManagerService.java | 4 ++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/cmds/svc/src/com/android/commands/svc/PowerCommand.java b/cmds/svc/src/com/android/commands/svc/PowerCommand.java index 3180b77f5700e..957ebfbef7998 100644 --- a/cmds/svc/src/com/android/commands/svc/PowerCommand.java +++ b/cmds/svc/src/com/android/commands/svc/PowerCommand.java @@ -24,6 +24,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; import android.os.SystemProperties; +import android.sysprop.InitProperties; public class PowerCommand extends Svc.Command { private static final int FORCE_SUSPEND_DELAY_DEFAULT_MILLIS = 0; @@ -103,6 +104,8 @@ public class PowerCommand extends Svc.Command { pm.reboot(false, mode, true); } catch (RemoteException e) { maybeLogRemoteException("Failed to reboot."); + } catch (Exception e) { + System.err.println("Failed to reboot: " + e.getMessage()); } return; } else if ("shutdown".equals(args[1])) { @@ -138,7 +141,9 @@ public class PowerCommand extends Svc.Command { // if it is already in shutdown flow. private void maybeLogRemoteException(String msg) { String powerProp = SystemProperties.get("sys.powerctl"); - if (powerProp.isEmpty()) { + // Also check if userspace reboot is ongoing, since in case of userspace reboot value of the + // sys.powerctl property will be reset. + if (powerProp.isEmpty() && !InitProperties.userspace_reboot_in_progress().orElse(false)) { System.err.println(msg); } } diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index b8e1aa88c3a3b..be2de0edda2d8 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -1483,12 +1483,25 @@ public final class PowerManager { return mInteractiveCache.query(null); } + + /** + * 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}. + * + * @hide + */ + public static boolean isRebootingUserspaceSupportedImpl() { + return InitProperties.is_userspace_reboot_supported().orElse(false); + } + /** * Returns {@code true} if this device supports rebooting userspace. */ // TODO(b/138605180): add link to documentation once it's ready. public boolean isRebootingUserspaceSupported() { - return InitProperties.is_userspace_reboot_supported().orElse(false); + return isRebootingUserspaceSupportedImpl(); } /** diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index cd6c5bfaeb795..5a3464d8a35f6 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -3219,6 +3219,10 @@ public final class PowerManagerService extends SystemService private void shutdownOrRebootInternal(final @HaltMode int haltMode, final boolean confirm, @Nullable final String reason, boolean wait) { if (PowerManager.REBOOT_USERSPACE.equals(reason)) { + if (!PowerManager.isRebootingUserspaceSupportedImpl()) { + throw new UnsupportedOperationException( + "Attempted userspace reboot on a device that doesn't support it"); + } UserspaceRebootLogger.noteUserspaceRebootWasRequested(); } if (mHandler == null || !mSystemReady) {