From 4343e3ebca0812fa3ed6590759e823bd532f28de Mon Sep 17 00:00:00 2001 From: Tianjie Date: Thu, 17 Dec 2020 10:46:10 -0800 Subject: [PATCH] Deprecate the old rebootAndApply API This API isn't aware of slot switch, and shouldn't be used by phonesky. So we prefer to deprecate it in case new callers use it accidentally. Also don't allow callers with REBOOT permission to call it. Bug: 170664917 Test: build Change-Id: I540b87fad461cb2c900f3e9d177bb5147abc1a22 --- core/api/system-current.txt | 2 +- core/java/android/os/IRecoverySystem.aidl | 1 + core/java/android/os/RecoverySystem.java | 29 ++++++++++++++----- .../recoverysystem/RecoverySystemService.java | 16 ++++++++-- 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 03257a0dc1a75..f2787acb1ae0a 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -7349,7 +7349,7 @@ package android.os { 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(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 @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(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; diff --git a/core/java/android/os/IRecoverySystem.aidl b/core/java/android/os/IRecoverySystem.aidl index 5f8b932832690..205288303b1eb 100644 --- a/core/java/android/os/IRecoverySystem.aidl +++ b/core/java/android/os/IRecoverySystem.aidl @@ -30,5 +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); } diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java index 189e62baba00c..6713de83d394e 100644 --- a/core/java/android/os/RecoverySystem.java +++ b/core/java/android/os/RecoverySystem.java @@ -687,8 +687,8 @@ public class RecoverySystem { } /** - * Request that the device reboot and apply the update that has been prepared. Callers are - * recommended to use {@link #rebootAndApply(Context, String, boolean)} instead. + * Request that the device reboot and apply the update that has been prepared. This API is + * deprecated, and is expected to be used by OTA only on devices running Android 11. * * @param context the Context to use. * @param updateToken this parameter is deprecated and won't be used. See details in @@ -699,18 +699,18 @@ public class RecoverySystem { * unattended reboot or if the {@code updateToken} did not match the previously * given token * @hide + * @deprecated Use {@link #rebootAndApply(Context, String, boolean)} instead */ @SystemApi - @RequiresPermission(anyOf = {android.Manifest.permission.RECOVERY, - android.Manifest.permission.REBOOT}) + @RequiresPermission(android.Manifest.permission.RECOVERY) public static void rebootAndApply(@NonNull Context context, @NonNull String updateToken, @NonNull String reason) throws IOException { if (updateToken == null) { throw new NullPointerException("updateToken == null"); } RecoverySystem rs = (RecoverySystem) context.getSystemService(Context.RECOVERY_SERVICE); - // OTA is the sole user before S, and a slot switch is required for ota update. - if (!rs.rebootWithLskf(context.getPackageName(), reason, true)) { + // OTA is the sole user, who expects a slot switch. + if (!rs.rebootWithLskfAssumeSlotSwitch(context.getPackageName(), reason)) { throw new IOException("system not prepared to apply update"); } } @@ -738,7 +738,7 @@ 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 intends to switch the slot on an A/B device. + * @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. * @hide @@ -1387,6 +1387,21 @@ public class RecoverySystem { } } + + /** + * Calls the recovery system service to reboot and apply update. This is the legacy API and + * expects a slot switch for A/B devices. + * + */ + private boolean rebootWithLskfAssumeSlotSwitch(String packageName, String reason) + throws IOException { + try { + return mService.rebootWithLskfAssumeSlotSwitch(packageName, reason); + } catch (RemoteException e) { + throw new IOException("could not reboot for update"); + } + } + /** * Internally, recovery treats each line of the command file as a separate * argv, so we only need to protect against newlines and nulls. diff --git a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java index 91f613fdbeb8c..5c01e43af5a9f 100644 --- a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java +++ b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java @@ -476,9 +476,7 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo return needClear ? ROR_REQUESTED_NEED_CLEAR : ROR_REQUESTED_SKIP_CLEAR; } - @Override // Binder call - public boolean rebootWithLskf(String packageName, String reason, boolean slotSwitch) { - enforcePermissionForResumeOnReboot(); + private boolean rebootWithLskfImpl(String packageName, String reason, boolean slotSwitch) { if (packageName == null) { Slog.w(TAG, "Missing packageName when rebooting with lskf."); return false; @@ -499,6 +497,18 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo return true; } + @Override // Binder call for the legacy rebootWithLskf + public boolean 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) { + enforcePermissionForResumeOnReboot(); + return rebootWithLskfImpl(packageName, reason, slotSwitch); + } + @Override // Binder call public boolean isLskfCaptured(String packageName) { enforcePermissionForResumeOnReboot();