diff options
| author | 2021-01-28 22:46:18 +0000 | |
|---|---|---|
| committer | 2021-01-28 22:46:18 +0000 | |
| commit | 468a6659645ba771e5e2ed29a31a7569ecd0243b (patch) | |
| tree | 799d562880c263623d478c1d2379c5bba0a4c9aa /keystore/java | |
| parent | 8b756e725ee315aeaaf946dbe7d12acb58e9cb0a (diff) | |
| parent | 1f8a1b854d2e611de9a174fb6f8234f1e62fafbd (diff) | |
Merge "Keystore 2.0 SPI: Add back-off hint to BackendBusyException." am: 9aba68730c am: b03763fb58 am: 1f8a1b854d
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1558768
MUST ONLY BE SUBMITTED BY AUTOMERGER
Change-Id: Id9b14285a83ca6b8c9b603c47e33382b10335161
Diffstat (limited to 'keystore/java')
| -rw-r--r-- | keystore/java/android/security/KeyStoreSecurityLevel.java | 7 | ||||
| -rw-r--r-- | keystore/java/android/security/keystore/BackendBusyException.java | 37 |
2 files changed, 37 insertions, 7 deletions
diff --git a/keystore/java/android/security/KeyStoreSecurityLevel.java b/keystore/java/android/security/KeyStoreSecurityLevel.java index bc669bae056b..372add9b7ecb 100644 --- a/keystore/java/android/security/KeyStoreSecurityLevel.java +++ b/keystore/java/android/security/KeyStoreSecurityLevel.java @@ -96,20 +96,21 @@ public class KeyStoreSecurityLevel { } catch (ServiceSpecificException e) { switch (e.errorCode) { case ResponseCode.BACKEND_BUSY: { + long backOffHint = (long) (Math.random() * 80 + 20); if (CompatChanges.isChangeEnabled( KeyStore2.KEYSTORE_OPERATION_CREATION_MAY_FAIL)) { // Starting with Android S we inform the caller about the // backend being busy. - throw new BackendBusyException(); + throw new BackendBusyException(backOffHint); } else { // Before Android S operation creation must always succeed. So we // just have to retry. We do so with a randomized back-off between - // 50 and 250ms. + // 20 and 100ms. // It is a little awkward that we cannot break out of this loop // by interrupting this thread. But that is the expected behavior. // There is some comfort in the fact that interrupting a thread // also does not unblock a thread waiting for a binder transaction. - interruptedPreservingSleep((long) (Math.random() * 200 + 50)); + interruptedPreservingSleep(backOffHint); } break; } diff --git a/keystore/java/android/security/keystore/BackendBusyException.java b/keystore/java/android/security/keystore/BackendBusyException.java index 1a88469d7e54..a813e939a720 100644 --- a/keystore/java/android/security/keystore/BackendBusyException.java +++ b/keystore/java/android/security/keystore/BackendBusyException.java @@ -16,37 +16,66 @@ package android.security.keystore; +import android.annotation.DurationMillisLong; import android.annotation.NonNull; import java.security.ProviderException; /** * Indicates a transient error that prevented a key operation from being created. - * Callers should try again with a back-off period of 10-30 milliseconds. + * Callers should try again with a back-off period of {@link #getBackOffHintMillis()} + * milliseconds. */ public class BackendBusyException extends ProviderException { + private final long mBackOffHintMillis; + /** * Constructs a new {@code BackendBusyException} without detail message and cause. + * */ - public BackendBusyException() { + public BackendBusyException(@DurationMillisLong long backOffHintMillis) { super("The keystore backend has no operation slots available. Retry later."); + if (backOffHintMillis < 0) { + throw new IllegalArgumentException("Back-off hint cannot be negative."); + } + mBackOffHintMillis = backOffHintMillis; } /** * Constructs a new {@code BackendBusyException} with the provided detail message and * no cause. */ - public BackendBusyException(@NonNull String message) { + public BackendBusyException(@DurationMillisLong long backOffHintMillis, + @NonNull String message) { super(message); + if (backOffHintMillis < 0) { + throw new IllegalArgumentException("Back-off hint cannot be negative."); + } + mBackOffHintMillis = backOffHintMillis; } /** * Constructs a new {@code BackendBusyException} with the provided detail message and * cause. */ - public BackendBusyException(@NonNull String message, @NonNull Throwable cause) { + public BackendBusyException(@DurationMillisLong long backOffHintMillis, + @NonNull String message, @NonNull Throwable cause) { super(message, cause); + if (backOffHintMillis < 0) { + throw new IllegalArgumentException("Back-off hint cannot be negative."); + } + mBackOffHintMillis = backOffHintMillis; } + /** + * When retrying to start a Keystore operation after receiving this exception, this can be + * used to determine how long to wait before retrying. It is not guaranteed that the operation + * will succeeds after this time. Multiple retries may be necessary if the system is congested. + * + * @return Number of milliseconds to back off before retrying. + */ + public @DurationMillisLong long getBackOffHintMillis() { + return mBackOffHintMillis; + } } |