Loading api/system-current.txt +4 −0 Original line number Diff line number Diff line Loading @@ -2132,6 +2132,7 @@ package android.content.pm { field public static final String EXTRA_REQUEST_PERMISSIONS_NAMES = "android.content.pm.extra.REQUEST_PERMISSIONS_NAMES"; field public static final String EXTRA_REQUEST_PERMISSIONS_RESULTS = "android.content.pm.extra.REQUEST_PERMISSIONS_RESULTS"; field public static final String FEATURE_BROADCAST_RADIO = "android.hardware.broadcastradio"; field public static final String FEATURE_REBOOT_ESCROW = "android.hardware.reboot_escrow"; field public static final String FEATURE_TELEPHONY_CARRIERLOCK = "android.hardware.telephony.carrierlock"; field public static final int FLAG_PERMISSION_APPLY_RESTRICTION = 16384; // 0x4000 field public static final int FLAG_PERMISSION_GRANTED_BY_DEFAULT = 32; // 0x20 Loading Loading @@ -6958,9 +6959,12 @@ 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 boolean 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(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 boolean rebootAndApply(@NonNull android.content.Context, @NonNull String, @NonNull String) 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; Loading core/java/android/content/pm/PackageManager.java +12 −0 Original line number Diff line number Diff line Loading @@ -2917,6 +2917,18 @@ public abstract class PackageManager { @SdkConstant(SdkConstantType.FEATURE) public static final String FEATURE_IPSEC_TUNNELS = "android.software.ipsec_tunnels"; /** * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: The device has * the requisite hardware support to support reboot escrow of synthetic password for updates. * * <p>This feature implies that the device has the RebootEscrow HAL implementation. * * @hide */ @SystemApi @SdkConstant(SdkConstantType.FEATURE) public static final String FEATURE_REBOOT_ESCROW = "android.hardware.reboot_escrow"; /** * Extra field name for the URI to a verification file. Passed to a package * verifier. Loading core/java/android/os/IRecoverySystem.aidl +4 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.os; import android.content.IntentSender; import android.os.IRecoverySystemProgressListener; /** @hide */ Loading @@ -26,4 +27,7 @@ interface IRecoverySystem { boolean setupBcb(in String command); boolean clearBcb(); void rebootRecoveryWithCommand(in String command); boolean requestLskf(in String updateToken, in IntentSender sender); boolean clearLskf(); boolean rebootWithLskf(in String updateToken, in String reason); } core/java/android/os/RecoverySystem.java +124 −9 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ package android.os; import static java.nio.charset.StandardCharsets.UTF_8; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.annotation.SystemApi; Loading @@ -29,6 +31,7 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.IntentSender; import android.content.pm.PackageManager; import android.provider.Settings; import android.telephony.SubscriptionInfo; Loading Loading @@ -624,22 +627,91 @@ public class RecoverySystem { } /** * 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 (bootloader control block), which will * be read by the bootloader and the recovery image. * 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. * <p> * When the system is already prepared for update and this API is called again with the same * {@code updateToken}, it will not call the intent sender nor request the user enter their Lock * Screen Knowledge Factor. * <p> * When this API is called again with a different {@code updateToken}, the prepared-for-update * status is reset and process repeats as though it's the initial call to this method as * described in the first paragraph. * * @param Context the Context to use. * @param packageFile the package to be installed. * * @throws IOException if there were any errors setting up the BCB. * @param context the Context to use. * @param updateToken token used to indicate which update was prepared * @param intentSender the intent to call when the update is prepared; may be {@code null} * @throws IOException if there were any errors setting up unattended update * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.RECOVERY) public static void prepareForUnattendedUpdate(@NonNull Context context, @NonNull String updateToken, @Nullable IntentSender intentSender) throws IOException { if (updateToken == null) { throw new NullPointerException("updateToken == null"); } RecoverySystem rs = (RecoverySystem) context.getSystemService(Context.RECOVERY_SERVICE); if (!rs.requestLskf(updateToken, intentSender)) { throw new IOException("preparation for update failed"); } } /** * Request that any previously requested Lock Screen Knowledge Factor (LSKF) is cleared and * the preparation for unattended update is reset. * * @param context the Context to use. * @throws IOException if there were any errors setting up unattended update * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.RECOVERY) public static void scheduleUpdateOnBoot(Context context, File packageFile) public static boolean clearPrepareForUnattendedUpdate(@NonNull Context context) throws IOException { RecoverySystem rs = (RecoverySystem) context.getSystemService(Context.RECOVERY_SERVICE); return rs.clearLskf(); } /** * Request that the device reboot and apply the update that has been prepared. The * {@code updateToken} must match what was given for {@link #prepareForUnattendedUpdate} or * this will return {@code false}. * * @param context the Context to use. * @param updateToken the token used to call {@link #prepareForUnattendedUpdate} before * @param reason the reboot reason to give to the {@link PowerManager} * @throws IOException if there were any errors setting up unattended update * @return false if the reboot couldn't proceed because the device wasn't ready for an * unattended reboot or if the {@code updateToken} did not match the previously * given token * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.RECOVERY) public static boolean 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); return rs.rebootWithLskf(updateToken, reason); } /** * 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 * (bootloader control block), which will be read by the bootloader and the recovery image. * * @param context the Context to use. * @param packageFile the package to be installed. * @throws IOException if there were any errors setting up the BCB. * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.RECOVERY) public static void scheduleUpdateOnBoot(Context context, File packageFile) throws IOException { String filename = packageFile.getCanonicalPath(); boolean securityUpdate = filename.endsWith("_s.zip"); Loading Loading @@ -1203,6 +1275,49 @@ public class RecoverySystem { } } /** * Begins the process of asking the user for the Lock Screen Knowledge Factor. * * @param updateToken token that will be used in calls to {@link #rebootAndApply} to ensure * that the preparation was for the correct update * @return true if the request was correct * @throws IOException if the recovery system service could not be contacted */ private boolean requestLskf(String updateToken, IntentSender sender) throws IOException { try { return mService.requestLskf(updateToken, sender); } catch (RemoteException e) { throw new IOException("could request update"); } } /** * Calls the recovery system service and clears the setup for the OTA. * * @return true if the setup for OTA was cleared * @throws IOException if the recovery system service could not be contacted */ private boolean clearLskf() throws IOException { try { return mService.clearLskf(); } catch (RemoteException e) { throw new IOException("could not clear LSKF"); } } /** * Calls the recovery system service to reboot and apply update. * * @param updateToken the update token for which the update was prepared */ private boolean rebootWithLskf(String updateToken, String reason) throws IOException { try { return mService.rebootWithLskf(updateToken, 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. Loading core/java/com/android/internal/widget/LockPatternUtils.java +5 −0 Original line number Diff line number Diff line Loading @@ -1598,6 +1598,11 @@ public class LockPatternUtils { */ public static final int STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN = 0x20; /** * Strong authentication is required to prepare for unattended upgrade. */ public static final int STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE = 0x40; /** * Strong auth flags that do not prevent biometric methods from being accepted as auth. * If any other flags are set, biometric authentication is disabled. Loading Loading
api/system-current.txt +4 −0 Original line number Diff line number Diff line Loading @@ -2132,6 +2132,7 @@ package android.content.pm { field public static final String EXTRA_REQUEST_PERMISSIONS_NAMES = "android.content.pm.extra.REQUEST_PERMISSIONS_NAMES"; field public static final String EXTRA_REQUEST_PERMISSIONS_RESULTS = "android.content.pm.extra.REQUEST_PERMISSIONS_RESULTS"; field public static final String FEATURE_BROADCAST_RADIO = "android.hardware.broadcastradio"; field public static final String FEATURE_REBOOT_ESCROW = "android.hardware.reboot_escrow"; field public static final String FEATURE_TELEPHONY_CARRIERLOCK = "android.hardware.telephony.carrierlock"; field public static final int FLAG_PERMISSION_APPLY_RESTRICTION = 16384; // 0x4000 field public static final int FLAG_PERMISSION_GRANTED_BY_DEFAULT = 32; // 0x20 Loading Loading @@ -6958,9 +6959,12 @@ 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 boolean 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(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 boolean rebootAndApply(@NonNull android.content.Context, @NonNull String, @NonNull String) 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; Loading
core/java/android/content/pm/PackageManager.java +12 −0 Original line number Diff line number Diff line Loading @@ -2917,6 +2917,18 @@ public abstract class PackageManager { @SdkConstant(SdkConstantType.FEATURE) public static final String FEATURE_IPSEC_TUNNELS = "android.software.ipsec_tunnels"; /** * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: The device has * the requisite hardware support to support reboot escrow of synthetic password for updates. * * <p>This feature implies that the device has the RebootEscrow HAL implementation. * * @hide */ @SystemApi @SdkConstant(SdkConstantType.FEATURE) public static final String FEATURE_REBOOT_ESCROW = "android.hardware.reboot_escrow"; /** * Extra field name for the URI to a verification file. Passed to a package * verifier. Loading
core/java/android/os/IRecoverySystem.aidl +4 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.os; import android.content.IntentSender; import android.os.IRecoverySystemProgressListener; /** @hide */ Loading @@ -26,4 +27,7 @@ interface IRecoverySystem { boolean setupBcb(in String command); boolean clearBcb(); void rebootRecoveryWithCommand(in String command); boolean requestLskf(in String updateToken, in IntentSender sender); boolean clearLskf(); boolean rebootWithLskf(in String updateToken, in String reason); }
core/java/android/os/RecoverySystem.java +124 −9 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ package android.os; import static java.nio.charset.StandardCharsets.UTF_8; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.annotation.SystemApi; Loading @@ -29,6 +31,7 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.IntentSender; import android.content.pm.PackageManager; import android.provider.Settings; import android.telephony.SubscriptionInfo; Loading Loading @@ -624,22 +627,91 @@ public class RecoverySystem { } /** * 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 (bootloader control block), which will * be read by the bootloader and the recovery image. * 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. * <p> * When the system is already prepared for update and this API is called again with the same * {@code updateToken}, it will not call the intent sender nor request the user enter their Lock * Screen Knowledge Factor. * <p> * When this API is called again with a different {@code updateToken}, the prepared-for-update * status is reset and process repeats as though it's the initial call to this method as * described in the first paragraph. * * @param Context the Context to use. * @param packageFile the package to be installed. * * @throws IOException if there were any errors setting up the BCB. * @param context the Context to use. * @param updateToken token used to indicate which update was prepared * @param intentSender the intent to call when the update is prepared; may be {@code null} * @throws IOException if there were any errors setting up unattended update * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.RECOVERY) public static void prepareForUnattendedUpdate(@NonNull Context context, @NonNull String updateToken, @Nullable IntentSender intentSender) throws IOException { if (updateToken == null) { throw new NullPointerException("updateToken == null"); } RecoverySystem rs = (RecoverySystem) context.getSystemService(Context.RECOVERY_SERVICE); if (!rs.requestLskf(updateToken, intentSender)) { throw new IOException("preparation for update failed"); } } /** * Request that any previously requested Lock Screen Knowledge Factor (LSKF) is cleared and * the preparation for unattended update is reset. * * @param context the Context to use. * @throws IOException if there were any errors setting up unattended update * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.RECOVERY) public static void scheduleUpdateOnBoot(Context context, File packageFile) public static boolean clearPrepareForUnattendedUpdate(@NonNull Context context) throws IOException { RecoverySystem rs = (RecoverySystem) context.getSystemService(Context.RECOVERY_SERVICE); return rs.clearLskf(); } /** * Request that the device reboot and apply the update that has been prepared. The * {@code updateToken} must match what was given for {@link #prepareForUnattendedUpdate} or * this will return {@code false}. * * @param context the Context to use. * @param updateToken the token used to call {@link #prepareForUnattendedUpdate} before * @param reason the reboot reason to give to the {@link PowerManager} * @throws IOException if there were any errors setting up unattended update * @return false if the reboot couldn't proceed because the device wasn't ready for an * unattended reboot or if the {@code updateToken} did not match the previously * given token * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.RECOVERY) public static boolean 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); return rs.rebootWithLskf(updateToken, reason); } /** * 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 * (bootloader control block), which will be read by the bootloader and the recovery image. * * @param context the Context to use. * @param packageFile the package to be installed. * @throws IOException if there were any errors setting up the BCB. * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.RECOVERY) public static void scheduleUpdateOnBoot(Context context, File packageFile) throws IOException { String filename = packageFile.getCanonicalPath(); boolean securityUpdate = filename.endsWith("_s.zip"); Loading Loading @@ -1203,6 +1275,49 @@ public class RecoverySystem { } } /** * Begins the process of asking the user for the Lock Screen Knowledge Factor. * * @param updateToken token that will be used in calls to {@link #rebootAndApply} to ensure * that the preparation was for the correct update * @return true if the request was correct * @throws IOException if the recovery system service could not be contacted */ private boolean requestLskf(String updateToken, IntentSender sender) throws IOException { try { return mService.requestLskf(updateToken, sender); } catch (RemoteException e) { throw new IOException("could request update"); } } /** * Calls the recovery system service and clears the setup for the OTA. * * @return true if the setup for OTA was cleared * @throws IOException if the recovery system service could not be contacted */ private boolean clearLskf() throws IOException { try { return mService.clearLskf(); } catch (RemoteException e) { throw new IOException("could not clear LSKF"); } } /** * Calls the recovery system service to reboot and apply update. * * @param updateToken the update token for which the update was prepared */ private boolean rebootWithLskf(String updateToken, String reason) throws IOException { try { return mService.rebootWithLskf(updateToken, 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. Loading
core/java/com/android/internal/widget/LockPatternUtils.java +5 −0 Original line number Diff line number Diff line Loading @@ -1598,6 +1598,11 @@ public class LockPatternUtils { */ public static final int STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN = 0x20; /** * Strong authentication is required to prepare for unattended upgrade. */ public static final int STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE = 0x40; /** * Strong auth flags that do not prevent biometric methods from being accepted as auth. * If any other flags are set, biometric authentication is disabled. Loading