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

Commit 41afcdc4 authored by Tianjie's avatar Tianjie Committed by Tianjie Xu
Browse files

Update the system API to support multi client RoR

Detailed design in http://go/multi-client-ror. We will reuse most of
the old APIs, and there are a few notable changes
1. Infer the package name from the existing context
2. Remove the unused update token
3. Add the REBOOT permission, so phonesky can hold it.
4. Add a new API for rebootAndApply, which takes a slotSwitch parameter

Bug: 170664917
Test: build

Change-Id: Icb012138bd1789ce03564aa255e5bd4e84374130
parent fa7173b8
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -7343,12 +7343,14 @@ package android.os {
  public class RecoverySystem {
    method @RequiresPermission(android.Manifest.permission.RECOVERY) public static void cancelScheduledUpdate(android.content.Context) throws java.io.IOException;
    method @RequiresPermission(android.Manifest.permission.RECOVERY) public static void clearPrepareForUnattendedUpdate(@NonNull android.content.Context) throws java.io.IOException;
    method @RequiresPermission(anyOf={android.Manifest.permission.RECOVERY, android.Manifest.permission.REBOOT}) public static void clearPrepareForUnattendedUpdate(@NonNull android.content.Context) throws java.io.IOException;
    method @RequiresPermission(android.Manifest.permission.RECOVERY) public static void installPackage(android.content.Context, java.io.File, boolean) throws java.io.IOException;
    method @RequiresPermission(android.Manifest.permission.RECOVERY) public static void prepareForUnattendedUpdate(@NonNull android.content.Context, @NonNull String, @Nullable android.content.IntentSender) throws java.io.IOException;
    method @RequiresPermission(anyOf={android.Manifest.permission.RECOVERY, android.Manifest.permission.REBOOT}) public static boolean isPreparedForUnattendedUpdate(@NonNull android.content.Context) throws java.io.IOException;
    method @RequiresPermission(anyOf={android.Manifest.permission.RECOVERY, android.Manifest.permission.REBOOT}) public static void prepareForUnattendedUpdate(@NonNull android.content.Context, @NonNull String, @Nullable android.content.IntentSender) throws java.io.IOException;
    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 @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, @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(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;
+65 −10
Original line number Diff line number Diff line
@@ -631,10 +631,19 @@ public class RecoverySystem {
    /**
     * Prepare to apply an unattended update by asking the user for their Lock Screen Knowledge
     * Factor (LSKF). If supplied, the {@code intentSender} will be called when the system is setup
     * and ready to apply the OTA.
     * and ready to apply the OTA. This API is expected to handle requests from multiple clients
     * simultaneously, e.g. from ota and mainline.
     *
     * <p> The behavior of multi-client Resume on Reboot works as follows
     * <li> Each client should call this function to prepare for Resume on Reboot before calling
     *      {@link #rebootAndApply(Context, String, boolean)} </li>
     * <li> One client cannot clear the Resume on Reboot preparation of another client. </li>
     * <li> If multiple clients have prepared for Resume on Reboot, the subsequent reboot will be
     *      first come, first served. </li>
     *
     * @param context the Context to use.
     * @param updateToken this parameter is deprecated and won't be used. See details in
     * @param updateToken this parameter is deprecated and won't be used. Callers can supply with
     *                    an empty string. See details in
     *                    <a href="http://go/multi-client-ror">http://go/multi-client-ror</a>
     *                    TODO(xunchang) update the link of document with the public doc.
     * @param intentSender the intent to call when the update is prepared; may be {@code null}
@@ -642,7 +651,8 @@ public class RecoverySystem {
     * @hide
     */
    @SystemApi
    @RequiresPermission(android.Manifest.permission.RECOVERY)
    @RequiresPermission(anyOf = {android.Manifest.permission.RECOVERY,
            android.Manifest.permission.REBOOT})
    public static void prepareForUnattendedUpdate(@NonNull Context context,
            @NonNull String updateToken, @Nullable IntentSender intentSender) throws IOException {
        if (updateToken == null) {
@@ -658,12 +668,16 @@ public class RecoverySystem {
     * Request that any previously requested Lock Screen Knowledge Factor (LSKF) is cleared and
     * the preparation for unattended update is reset.
     *
     * <p> Note that the API won't clear the underlying Resume on Reboot preparation state if
     * another client has requested. So the reboot call from the other client can still succeed.
     *
     * @param context the Context to use.
     * @throws IOException if there were any errors clearing the unattended update state
     * @hide
     */
    @SystemApi
    @RequiresPermission(android.Manifest.permission.RECOVERY)
    @RequiresPermission(anyOf = {android.Manifest.permission.RECOVERY,
            android.Manifest.permission.REBOOT})
    public static void clearPrepareForUnattendedUpdate(@NonNull Context context)
            throws IOException {
        RecoverySystem rs = (RecoverySystem) context.getSystemService(Context.RECOVERY_SERVICE);
@@ -673,7 +687,8 @@ public class RecoverySystem {
    }

    /**
     * Request that the device reboot and apply the update that has been prepared.
     * Request that the device reboot and apply the update that has been prepared. Callers are
     * recommended to use {@link #rebootAndApply(Context, String, boolean)} instead.
     *
     * @param context the Context to use.
     * @param updateToken this parameter is deprecated and won't be used. See details in
@@ -686,7 +701,8 @@ public class RecoverySystem {
     * @hide
     */
    @SystemApi
    @RequiresPermission(android.Manifest.permission.RECOVERY)
    @RequiresPermission(anyOf = {android.Manifest.permission.RECOVERY,
            android.Manifest.permission.REBOOT})
    public static void rebootAndApply(@NonNull Context context, @NonNull String updateToken,
            @NonNull String reason) throws IOException {
        if (updateToken == null) {
@@ -699,6 +715,45 @@ public class RecoverySystem {
        }
    }

    /**
     * Query if Resume on Reboot has been prepared for a given caller.
     *
     * @param context the Context to use.
     * @throws IOException if there were any errors connecting to the service or querying the state.
     * @hide
     */
    @SystemApi
    @RequiresPermission(anyOf = {android.Manifest.permission.RECOVERY,
            android.Manifest.permission.REBOOT})
    public static boolean isPreparedForUnattendedUpdate(@NonNull Context context)
            throws IOException {
        RecoverySystem rs = context.getSystemService(RecoverySystem.class);
        return rs.isLskfCaptured(context.getPackageName());
    }

    /**
     * Request that the device reboot and apply the update that has been prepared.
     * {@link #prepareForUnattendedUpdate} must be called before for the given client,
     * otherwise the function call will fail.
     *
     * @param context the Context to use.
     * @param reason the reboot reason to give to the {@link PowerManager}
     * @param slotSwitch true if the caller intends to switch the slot on an A/B device.
     * @throws IOException if the reboot couldn't proceed because the device wasn't ready for an
     *               unattended reboot.
     * @hide
     */
    @SystemApi
    @RequiresPermission(anyOf = {android.Manifest.permission.RECOVERY,
            android.Manifest.permission.REBOOT})
    public static void 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");
        }
    }

    /**
     * Schedule to install the given package on next boot. The caller needs to ensure that the
     * package must have been processed (uncrypt'd) if needed. It sets up the command in BCB
@@ -1278,7 +1333,7 @@ public class RecoverySystem {
    /**
     * Begins the process of asking the user for the Lock Screen Knowledge Factor.
     *
     * @param packageName the package name of the caller who requests resume on reboot
     * @param packageName the package name of the caller who requests Resume on Reboot
     * @return true if the request was correct
     * @throws IOException if the recovery system service could not be contacted
     */
@@ -1305,10 +1360,10 @@ public class RecoverySystem {
    }

    /**
     * Queries if the resume on reboot has been prepared for a given caller.
     * Queries if the Resume on Reboot has been prepared for a given caller.
     *
     * @param packageName the identifier of the caller who requests resume on reboot
     * @return true if resume on reboot is prepared.
     * @param packageName the identifier of the caller who requests Resume on Reboot
     * @return true if Resume on Reboot is prepared.
     * @throws IOException if the recovery system service could not be contacted
     */
    private boolean isLskfCaptured(String packageName) throws IOException {