From 3b0218b0ae1fad67f539ff3c10d6d2f3abec1a11 Mon Sep 17 00:00:00 2001 From: Doug Zongker Date: Tue, 14 Jan 2014 12:29:06 -0800 Subject: boot into recovery via the pre-recovery service Change PowerManagerService to start the pre-recovery service rather than rebooting directly, when requested to reboot into recovery. Add a new RECOVERY permission which a caller needs (in addition to REBOOT) in order to go to recovery. Bug: 12188746 Change-Id: I39121b701c4724558fe751adfbad79f8567faa43 --- .../android/server/power/PowerManagerService.java | 29 ++++++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) (limited to 'services/core/java') diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index 7f03cc0..3692d76 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -1830,9 +1830,10 @@ public final class PowerManagerService extends com.android.server.SystemService } /** - * Low-level function to reboot the device. On success, this function - * doesn't return. If more than 5 seconds passes from the time, - * a reboot is requested, this method returns. + * Low-level function to reboot the device. On success, this + * function doesn't return. If more than 20 seconds passes from + * the time a reboot is requested (120 seconds for reboot to + * recovery), this method returns. * * @param reason code to pass to the kernel (e.g. "recovery"), or null. */ @@ -1840,9 +1841,24 @@ public final class PowerManagerService extends com.android.server.SystemService if (reason == null) { reason = ""; } - SystemProperties.set("sys.powerctl", "reboot," + reason); + long duration; + if (reason.equals(PowerManager.REBOOT_RECOVERY)) { + // If we are rebooting to go into recovery, instead of + // setting sys.powerctl directly we'll start the + // pre-recovery service which will do some preparation for + // recovery and then reboot for us. + // + // This preparation can take more than 20 seconds if + // there's a very large update package, so lengthen the + // timeout. + SystemProperties.set("ctl.start", "pre-recovery"); + duration = 120 * 1000L; + } else { + SystemProperties.set("sys.powerctl", "reboot," + reason); + duration = 20 * 1000L; + } try { - Thread.sleep(20000); + Thread.sleep(duration); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } @@ -2524,6 +2540,9 @@ public final class PowerManagerService extends com.android.server.SystemService @Override // Binder call public void reboot(boolean confirm, String reason, boolean wait) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null); + if (PowerManager.REBOOT_RECOVERY.equals(reason)) { + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY, null); + } final long ident = Binder.clearCallingIdentity(); try { -- cgit v1.1