Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3b0218b0 authored by Doug Zongker's avatar Doug Zongker
Browse files

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
parent 09d30981
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -109,6 +109,7 @@ package android {
    field public static final java.lang.String RECEIVE_SMS = "android.permission.RECEIVE_SMS";
    field public static final java.lang.String RECEIVE_WAP_PUSH = "android.permission.RECEIVE_WAP_PUSH";
    field public static final java.lang.String RECORD_AUDIO = "android.permission.RECORD_AUDIO";
    field public static final java.lang.String RECOVERY = "android.permission.RECOVERY";
    field public static final java.lang.String REORDER_TASKS = "android.permission.REORDER_TASKS";
    field public static final deprecated java.lang.String RESTART_PACKAGES = "android.permission.RESTART_PACKAGES";
    field public static final java.lang.String SEND_RESPOND_VIA_MESSAGE = "android.permission.SEND_RESPOND_VIA_MESSAGE";
@@ -18878,6 +18879,7 @@ package android.os {
    field public static final deprecated int FULL_WAKE_LOCK = 26; // 0x1a
    field public static final int ON_AFTER_RELEASE = 536870912; // 0x20000000
    field public static final int PARTIAL_WAKE_LOCK = 1; // 0x1
    field public static final java.lang.String REBOOT_RECOVERY = "recovery";
    field public static final deprecated int SCREEN_BRIGHT_WAKE_LOCK = 10; // 0xa
    field public static final deprecated int SCREEN_DIM_WAKE_LOCK = 6; // 0x6
  }
+12 −0
Original line number Diff line number Diff line
@@ -290,6 +290,18 @@ public final class PowerManager {
     */
    public static final int GO_TO_SLEEP_REASON_TIMEOUT = 2;

    /**
     * The value to pass as the 'reason' argument to reboot() to
     * reboot into recovery mode (for applying system updates, doing
     * factory resets, etc.).
     * <p>
     * Requires the {@link android.Manifest.permission#RECOVERY}
     * permission (in addition to
     * {@link android.Manifest.permission#REBOOT}).
     * </p>
     */
    public static final String REBOOT_RECOVERY = "recovery";
    
    final Context mContext;
    final IPowerManager mService;
    final Handler mHandler;
+8 −0
Original line number Diff line number Diff line
@@ -1719,6 +1719,14 @@
        android:label="@string/permlab_manageCaCertificates"
        android:description="@string/permdesc_manageCaCertificates" />

    <!-- Allows an application to do certain operations needed for
         interacting with the recovery (system update) system. -->
    <permission android:name="android.permission.RECOVERY"
        android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
        android:protectionLevel="signature|system"
        android:label="@string/permlab_recovery"
        android:description="@string/permdesc_recovery" />

    <!-- ========================================= -->
    <!-- Permissions for special development tools -->
    <!-- ========================================= -->
+5 −0
Original line number Diff line number Diff line
@@ -3644,6 +3644,11 @@
    <!-- Description of an application permission that lets it control keyguard. -->
    <string name="permdesc_control_keyguard">Allows an application to control keguard.</string>

    <!-- Title of an application permission that lets it interact with recovery. -->
    <string name="permlab_recovery">Interact with update and recovery system</string>
    <!-- Description of an application permission that lets it control keyguard. -->
    <string name="permdesc_recovery">Allows an application to interact with the recovery system and system updates.</string>

    <!-- Shown in the tutorial for tap twice for zoom control. -->
    <string name="tutorial_double_tap_to_zoom_message_short">Touch twice for zoom control</string>

+24 −5
Original line number Diff line number Diff line
@@ -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 = "";
        }
        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 {