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

Commit d5547af7 authored by Tianjie Xu's avatar Tianjie Xu Committed by Gerrit Code Review
Browse files

Merge "Expose error code for RoR reboot system API"

parents 0a99b6c4 559ed7f0
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -7183,10 +7183,15 @@ package android.os {
    method @RequiresPermission(android.Manifest.permission.RECOVERY) public static void processPackage(android.content.Context, java.io.File, android.os.RecoverySystem.ProgressListener, android.os.Handler) throws java.io.IOException;
    method @RequiresPermission(android.Manifest.permission.RECOVERY) public static void processPackage(android.content.Context, java.io.File, android.os.RecoverySystem.ProgressListener) throws java.io.IOException;
    method @Deprecated @RequiresPermission(android.Manifest.permission.RECOVERY) public static void rebootAndApply(@NonNull android.content.Context, @NonNull String, @NonNull String) throws java.io.IOException;
    method @RequiresPermission(anyOf={android.Manifest.permission.RECOVERY, android.Manifest.permission.REBOOT}) public static void rebootAndApply(@NonNull android.content.Context, @NonNull String, boolean) throws java.io.IOException;
    method @RequiresPermission(anyOf={android.Manifest.permission.RECOVERY, android.Manifest.permission.REBOOT}) public static int rebootAndApply(@NonNull android.content.Context, @NonNull String, boolean) throws java.io.IOException;
    method @RequiresPermission(allOf={android.Manifest.permission.RECOVERY, android.Manifest.permission.REBOOT}) public static void rebootWipeAb(android.content.Context, java.io.File, String) throws java.io.IOException;
    method @RequiresPermission(android.Manifest.permission.RECOVERY) public static void scheduleUpdateOnBoot(android.content.Context, java.io.File) throws java.io.IOException;
    method public static boolean verifyPackageCompatibility(java.io.File) throws java.io.IOException;
    field public static final int RESUME_ON_REBOOT_REBOOT_ERROR_INVALID_PACKAGE_NAME = 2000; // 0x7d0
    field public static final int RESUME_ON_REBOOT_REBOOT_ERROR_LSKF_NOT_CAPTURED = 3000; // 0xbb8
    field public static final int RESUME_ON_REBOOT_REBOOT_ERROR_PROVIDER_PREPARATION_FAILURE = 5000; // 0x1388
    field public static final int RESUME_ON_REBOOT_REBOOT_ERROR_SLOT_MISMATCH = 4000; // 0xfa0
    field public static final int RESUME_ON_REBOOT_REBOOT_ERROR_UNSPECIFIED = 1000; // 0x3e8
  }
  public final class RemoteCallback implements android.os.Parcelable {
+2 −2
Original line number Diff line number Diff line
@@ -30,6 +30,6 @@ interface IRecoverySystem {
    boolean requestLskf(in String packageName, in IntentSender sender);
    boolean clearLskf(in String packageName);
    boolean isLskfCaptured(in String packageName);
    boolean rebootWithLskfAssumeSlotSwitch(in String packageName, in String reason);
    boolean rebootWithLskf(in String packageName, in String reason, in boolean slotSwitch);
    int rebootWithLskfAssumeSlotSwitch(in String packageName, in String reason);
    int rebootWithLskf(in String packageName, in String reason, in boolean slotSwitch);
}
+72 −11
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static android.view.Display.DEFAULT_DISPLAY;

import static java.nio.charset.StandardCharsets.UTF_8;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -154,6 +155,65 @@ public class RecoverySystem {

    private final IRecoverySystem mService;

    /**
     * The error codes for reboots initiated by resume on reboot clients.
     *  @hide
     */
    @IntDef(prefix = { "RESUME_ON_REBOOT_REBOOT_ERROR_" }, value = {
            RESUME_ON_REBOOT_REBOOT_ERROR_NONE,
            RESUME_ON_REBOOT_REBOOT_ERROR_UNSPECIFIED,
            RESUME_ON_REBOOT_REBOOT_ERROR_INVALID_PACKAGE_NAME,
            RESUME_ON_REBOOT_REBOOT_ERROR_LSKF_NOT_CAPTURED,
            RESUME_ON_REBOOT_REBOOT_ERROR_SLOT_MISMATCH,
            RESUME_ON_REBOOT_REBOOT_ERROR_PROVIDER_PREPARATION_FAILURE})
    public @interface ResumeOnRebootRebootErrorCode {}

    /**
     * The preparation of resume on reboot succeeds. Don't expose it because a successful reboot
     * should just reboot the device.
     *  @hide
     */
    public static final int RESUME_ON_REBOOT_REBOOT_ERROR_NONE = 0;

    /**
     * The resume on reboot fails due to an unknown reason.
     *  @hide
     */
    @SystemApi
    public static final int RESUME_ON_REBOOT_REBOOT_ERROR_UNSPECIFIED = 1000;

    /**
     * The resume on reboot fails because the package name of the client is invalid, e.g. null
     * packageName, name contains invalid characters, etc.
     *  @hide
     */
    @SystemApi
    public static final int RESUME_ON_REBOOT_REBOOT_ERROR_INVALID_PACKAGE_NAME = 2000;

    /**
     * The resume on reboot fails because the Lock Screen Knowledge Factor hasn't been captured.
     * This error is also reported if the client attempts to reboot without preparing RoR.
     *  @hide
     */
    @SystemApi
    public static final int RESUME_ON_REBOOT_REBOOT_ERROR_LSKF_NOT_CAPTURED = 3000;

    /**
     * The resume on reboot fails because the client expects a different boot slot for the next boot
     * on A/B devices.
     *  @hide
     */
    @SystemApi
    public static final int RESUME_ON_REBOOT_REBOOT_ERROR_SLOT_MISMATCH = 4000;

    /**
     * The resume on reboot fails because the resume on reboot provider, e.g. HAL / server based,
     * fails to arm/store the escrow key.
     *  @hide
     */
    @SystemApi
    public static final int RESUME_ON_REBOOT_REBOOT_ERROR_PROVIDER_PREPARATION_FAILURE = 5000;

    /**
     * Interface definition for a callback to be invoked regularly as
     * verification proceeds.
@@ -723,7 +783,8 @@ public class RecoverySystem {
        }
        RecoverySystem rs = (RecoverySystem) context.getSystemService(Context.RECOVERY_SERVICE);
        // OTA is the sole user, who expects a slot switch.
        if (!rs.rebootWithLskfAssumeSlotSwitch(context.getPackageName(), reason)) {
        if (rs.rebootWithLskfAssumeSlotSwitch(context.getPackageName(), reason)
                != RESUME_ON_REBOOT_REBOOT_ERROR_NONE) {
            throw new IOException("system not prepared to apply update");
        }
    }
@@ -752,19 +813,19 @@ public class RecoverySystem {
     * @param context the Context to use.
     * @param reason the reboot reason to give to the {@link PowerManager}
     * @param slotSwitch true if the caller expects the slot to be switched on A/B devices.
     * @throws IOException if the reboot couldn't proceed because the device wasn't ready for an
     *               unattended reboot.
     *
     * @return 0 on success, and a non-zero error code if the reboot couldn't proceed because the
     *         device wasn't ready for an unattended reboot.
     * @throws IOException on remote exceptions from the RecoverySystemService
     * @hide
     */
    @SystemApi
    @RequiresPermission(anyOf = {android.Manifest.permission.RECOVERY,
            android.Manifest.permission.REBOOT})
    public static void rebootAndApply(@NonNull Context context,
    public static @ResumeOnRebootRebootErrorCode int rebootAndApply(@NonNull Context context,
            @NonNull String reason, boolean slotSwitch) throws IOException {
        RecoverySystem rs = context.getSystemService(RecoverySystem.class);
        if (!rs.rebootWithLskf(context.getPackageName(), reason, slotSwitch)) {
            throw new IOException("system not prepared to apply update");
        }
        return rs.rebootWithLskf(context.getPackageName(), reason, slotSwitch);
    }

    /**
@@ -1399,8 +1460,8 @@ public class RecoverySystem {
     * Calls the recovery system service to reboot and apply update.
     *
     */
    private boolean rebootWithLskf(String packageName, String reason, boolean slotSwitch)
            throws IOException {
    private @ResumeOnRebootRebootErrorCode int rebootWithLskf(String packageName, String reason,
            boolean slotSwitch) throws IOException {
        try {
            return mService.rebootWithLskf(packageName, reason, slotSwitch);
        } catch (RemoteException e) {
@@ -1414,8 +1475,8 @@ public class RecoverySystem {
     * expects a slot switch for A/B devices.
     *
     */
    private boolean rebootWithLskfAssumeSlotSwitch(String packageName, String reason)
            throws IOException {
    private @ResumeOnRebootRebootErrorCode int rebootWithLskfAssumeSlotSwitch(String packageName,
            String reason) throws IOException {
        try {
            return mService.rebootWithLskfAssumeSlotSwitch(packageName, reason);
        } catch (RemoteException e) {
+21 −29
Original line number Diff line number Diff line
@@ -16,6 +16,13 @@

package com.android.server.recoverysystem;

import static android.os.RecoverySystem.RESUME_ON_REBOOT_REBOOT_ERROR_INVALID_PACKAGE_NAME;
import static android.os.RecoverySystem.RESUME_ON_REBOOT_REBOOT_ERROR_LSKF_NOT_CAPTURED;
import static android.os.RecoverySystem.RESUME_ON_REBOOT_REBOOT_ERROR_NONE;
import static android.os.RecoverySystem.RESUME_ON_REBOOT_REBOOT_ERROR_PROVIDER_PREPARATION_FAILURE;
import static android.os.RecoverySystem.RESUME_ON_REBOOT_REBOOT_ERROR_SLOT_MISMATCH;
import static android.os.RecoverySystem.RESUME_ON_REBOOT_REBOOT_ERROR_UNSPECIFIED;
import static android.os.RecoverySystem.ResumeOnRebootRebootErrorCode;
import static android.os.UserHandle.USER_SYSTEM;

import android.annotation.IntDef;
@@ -147,24 +154,6 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo
            ROR_REQUESTED_SKIP_CLEAR})
    private @interface ResumeOnRebootActionsOnClear {}

    /**
     * The error codes for reboots initiated by resume on reboot clients.
     */
    private static final int REBOOT_ERROR_NONE = 0;
    private static final int REBOOT_ERROR_UNKNOWN = 1;
    private static final int REBOOT_ERROR_INVALID_PACKAGE_NAME = 2;
    private static final int REBOOT_ERROR_LSKF_NOT_CAPTURED = 3;
    private static final int REBOOT_ERROR_SLOT_MISMATCH = 4;
    private static final int REBOOT_ERROR_ARM_REBOOT_ESCROW_FAILURE = 5;

    @IntDef({ REBOOT_ERROR_NONE,
            REBOOT_ERROR_UNKNOWN,
            REBOOT_ERROR_INVALID_PACKAGE_NAME,
            REBOOT_ERROR_LSKF_NOT_CAPTURED,
            REBOOT_ERROR_SLOT_MISMATCH,
            REBOOT_ERROR_ARM_REBOOT_ESCROW_FAILURE})
    private @interface ResumeOnRebootRebootErrorCode {}

    /**
     * Manages shared preference, i.e. the storage used for metrics reporting.
     */
@@ -724,14 +713,14 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo
            boolean slotSwitch) {
        if (packageName == null) {
            Slog.w(TAG, "Missing packageName when rebooting with lskf.");
            return REBOOT_ERROR_INVALID_PACKAGE_NAME;
            return RESUME_ON_REBOOT_REBOOT_ERROR_INVALID_PACKAGE_NAME;
        }
        if (!isLskfCaptured(packageName)) {
            return REBOOT_ERROR_LSKF_NOT_CAPTURED;
            return RESUME_ON_REBOOT_REBOOT_ERROR_LSKF_NOT_CAPTURED;
        }

        if (!verifySlotForNextBoot(slotSwitch)) {
            return REBOOT_ERROR_SLOT_MISMATCH;
            return RESUME_ON_REBOOT_REBOOT_ERROR_SLOT_MISMATCH;
        }

        final long origId = Binder.clearCallingIdentity();
@@ -744,10 +733,10 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo

        if (!result) {
            Slog.w(TAG, "Failure to escrow key for reboot");
            return REBOOT_ERROR_ARM_REBOOT_ESCROW_FAILURE;
            return RESUME_ON_REBOOT_REBOOT_ERROR_PROVIDER_PREPARATION_FAILURE;
        }

        return REBOOT_ERROR_NONE;
        return RESUME_ON_REBOOT_REBOOT_ERROR_NONE;
    }

    private boolean useServerBasedRoR() {
@@ -788,12 +777,13 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo
                requestCount, slotSwitch, serverBased, durationSeconds, lskfCapturedCount);
    }

    private boolean rebootWithLskfImpl(String packageName, String reason, boolean slotSwitch) {
    private @ResumeOnRebootRebootErrorCode int rebootWithLskfImpl(String packageName, String reason,
            boolean slotSwitch) {
        @ResumeOnRebootRebootErrorCode int errorCode = armRebootEscrow(packageName, slotSwitch);
        reportMetricsOnRebootWithLskf(packageName, slotSwitch, errorCode);

        if (errorCode != REBOOT_ERROR_NONE) {
            return false;
        if (errorCode != RESUME_ON_REBOOT_REBOOT_ERROR_NONE) {
            return errorCode;
        }

        // Clear the metrics prefs after a successful RoR reboot.
@@ -801,17 +791,19 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo

        PowerManager pm = mInjector.getPowerManager();
        pm.reboot(reason);
        return true;
        return RESUME_ON_REBOOT_REBOOT_ERROR_UNSPECIFIED;
    }

    @Override // Binder call for the legacy rebootWithLskf
    public boolean rebootWithLskfAssumeSlotSwitch(String packageName, String reason) {
    public @ResumeOnRebootRebootErrorCode int rebootWithLskfAssumeSlotSwitch(String packageName,
            String reason) {
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY, null);
        return rebootWithLskfImpl(packageName, reason, true);
    }

    @Override // Binder call
    public boolean rebootWithLskf(String packageName, String reason, boolean slotSwitch) {
    public @ResumeOnRebootRebootErrorCode int rebootWithLskf(String packageName, String reason,
            boolean slotSwitch) {
        enforcePermissionForResumeOnReboot();
        return rebootWithLskfImpl(packageName, reason, slotSwitch);
    }
+3 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server.recoverysystem;

import android.os.IRecoverySystem;
import android.os.RecoverySystem;
import android.os.RemoteException;
import android.os.ShellCommand;

@@ -76,7 +77,8 @@ public class RecoverySystemShellCommand extends ShellCommand {
    private int rebootAndApply() throws RemoteException {
        String packageName = getNextArgRequired();
        String rebootReason = getNextArgRequired();
        boolean success = mService.rebootWithLskf(packageName, rebootReason, false);
        boolean success = (mService.rebootWithLskf(packageName, rebootReason, false)
                == RecoverySystem.RESUME_ON_REBOOT_REBOOT_ERROR_NONE);
        PrintWriter pw = getOutPrintWriter();
        // Keep the old message for cts test.
        pw.printf("%s Reboot and apply status: %s\n", packageName,
Loading