ConfirmationPrompt: Update for API review.
Misc. changes but notably the ConfirmationDialog class was renamed to
ConfirmationPrompt.
Manually tested by updating sample Android Confirmations application
to use updated API.
Bug: 77242268
Test: Manually tested.
Change-Id: I1caa3c6bff9486b43ba111329d1ef83c3b67baf9
diff --git a/api/current.txt b/api/current.txt
index 670f6ca..f1d0ef0 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -38428,23 +38428,10 @@
public abstract class ConfirmationCallback {
ctor public ConfirmationCallback();
- method public void onConfirmedByUser(byte[]);
- method public void onDismissedByApplication();
- method public void onDismissedByUser();
- method public void onError(java.lang.Exception);
- }
-
- public class ConfirmationDialog {
- method public void cancelPrompt();
- method public static boolean isSupported();
- method public void presentPrompt(java.util.concurrent.Executor, android.security.ConfirmationCallback) throws android.security.ConfirmationAlreadyPresentingException, android.security.ConfirmationNotAvailableException;
- }
-
- public static class ConfirmationDialog.Builder {
- ctor public ConfirmationDialog.Builder();
- method public android.security.ConfirmationDialog build(android.content.Context);
- method public android.security.ConfirmationDialog.Builder setExtraData(byte[]);
- method public android.security.ConfirmationDialog.Builder setPromptText(java.lang.CharSequence);
+ method public void onCanceled();
+ method public void onConfirmed(byte[]);
+ method public void onDismissed();
+ method public void onError(java.lang.Throwable);
}
public class ConfirmationNotAvailableException extends java.lang.Exception {
@@ -38452,6 +38439,19 @@
ctor public ConfirmationNotAvailableException(java.lang.String);
}
+ public class ConfirmationPrompt {
+ method public void cancelPrompt();
+ method public static boolean isSupported(android.content.Context);
+ method public void presentPrompt(java.util.concurrent.Executor, android.security.ConfirmationCallback) throws android.security.ConfirmationAlreadyPresentingException, android.security.ConfirmationNotAvailableException;
+ }
+
+ public static final class ConfirmationPrompt.Builder {
+ ctor public ConfirmationPrompt.Builder(android.content.Context);
+ method public android.security.ConfirmationPrompt build();
+ method public android.security.ConfirmationPrompt.Builder setExtraData(byte[]);
+ method public android.security.ConfirmationPrompt.Builder setPromptText(java.lang.CharSequence);
+ }
+
public final class KeyChain {
ctor public KeyChain();
method public static void choosePrivateKeyAlias(android.app.Activity, android.security.KeyChainAliasCallback, java.lang.String[], java.security.Principal[], java.lang.String, int, java.lang.String);
diff --git a/core/java/android/security/ConfirmationCallback.java b/core/java/android/security/ConfirmationCallback.java
index 4670bce..fd027f0 100644
--- a/core/java/android/security/ConfirmationCallback.java
+++ b/core/java/android/security/ConfirmationCallback.java
@@ -33,22 +33,22 @@
*
* @param dataThatWasConfirmed the data that was confirmed, see above for the format.
*/
- public void onConfirmedByUser(@NonNull byte[] dataThatWasConfirmed) {}
+ public void onConfirmed(@NonNull byte[] dataThatWasConfirmed) {}
/**
* Called when the requested prompt was dismissed (not accepted) by the user.
*/
- public void onDismissedByUser() {}
+ public void onDismissed() {}
/**
* Called when the requested prompt was dismissed by the application.
*/
- public void onDismissedByApplication() {}
+ public void onCanceled() {}
/**
* Called when the requested prompt was dismissed because of a low-level error.
*
- * @param e an exception representing the error.
+ * @param e a throwable representing the error.
*/
- public void onError(Exception e) {}
+ public void onError(Throwable e) {}
}
diff --git a/core/java/android/security/ConfirmationDialog.java b/core/java/android/security/ConfirmationPrompt.java
similarity index 88%
rename from core/java/android/security/ConfirmationDialog.java
rename to core/java/android/security/ConfirmationPrompt.java
index 1697106..5330cff 100644
--- a/core/java/android/security/ConfirmationDialog.java
+++ b/core/java/android/security/ConfirmationPrompt.java
@@ -68,7 +68,7 @@
* {@link #presentPrompt presentPrompt()} method. The <i>Relying Party</i> stores the nonce locally
* since it'll use it in a later step.
* <li> If the user approves the prompt a <i>Confirmation Response</i> is returned in the
- * {@link ConfirmationCallback#onConfirmedByUser onConfirmedByUser(byte[])} callback as the
+ * {@link ConfirmationCallback#onConfirmed onConfirmed(byte[])} callback as the
* <code>dataThatWasConfirmed</code> parameter. This blob contains the text that was shown to the
* user, the <code>extraData</code> parameter, and possibly other data.
* <li> The application signs the <i>Confirmation Response</i> with the previously created key and
@@ -82,8 +82,8 @@
* last bullet, is to have the <i>Relying Party</i> generate <code>promptText</code> and store it
* along the nonce in the <code>extraData</code> blob.
*/
-public class ConfirmationDialog {
- private static final String TAG = "ConfirmationDialog";
+public class ConfirmationPrompt {
+ private static final String TAG = "ConfirmationPrompt";
private CharSequence mPromptText;
private byte[] mExtraData;
@@ -97,15 +97,15 @@
ConfirmationCallback callback) {
switch (responseCode) {
case KeyStore.CONFIRMATIONUI_OK:
- callback.onConfirmedByUser(dataThatWasConfirmed);
+ callback.onConfirmed(dataThatWasConfirmed);
break;
case KeyStore.CONFIRMATIONUI_CANCELED:
- callback.onDismissedByUser();
+ callback.onDismissed();
break;
case KeyStore.CONFIRMATIONUI_ABORTED:
- callback.onDismissedByApplication();
+ callback.onCanceled();
break;
case KeyStore.CONFIRMATIONUI_SYSTEM_ERROR:
@@ -145,21 +145,25 @@
};
/**
- * A builder that collects arguments, to be shown on the system-provided confirmation dialog.
+ * A builder that collects arguments, to be shown on the system-provided confirmation prompt.
*/
- public static class Builder {
+ public static final class Builder {
+ private Context mContext;
private CharSequence mPromptText;
private byte[] mExtraData;
/**
- * Creates a builder for the confirmation dialog.
+ * Creates a builder for the confirmation prompt.
+ *
+ * @param context the application context
*/
- public Builder() {
+ public Builder(Context context) {
+ mContext = context;
}
/**
- * Sets the prompt text for the dialog.
+ * Sets the prompt text for the prompt.
*
* @param promptText the text to present in the prompt.
* @return the builder.
@@ -170,7 +174,7 @@
}
/**
- * Sets the extra data for the dialog.
+ * Sets the extra data for the prompt.
*
* @param extraData data to include in the response data.
* @return the builder.
@@ -181,24 +185,23 @@
}
/**
- * Creates a {@link ConfirmationDialog} with the arguments supplied to this builder.
+ * Creates a {@link ConfirmationPrompt} with the arguments supplied to this builder.
*
- * @param context the application context
- * @return a {@link ConfirmationDialog}
+ * @return a {@link ConfirmationPrompt}
* @throws IllegalArgumentException if any of the required fields are not set.
*/
- public ConfirmationDialog build(Context context) {
+ public ConfirmationPrompt build() {
if (TextUtils.isEmpty(mPromptText)) {
throw new IllegalArgumentException("prompt text must be set and non-empty");
}
if (mExtraData == null) {
throw new IllegalArgumentException("extraData must be set");
}
- return new ConfirmationDialog(context, mPromptText, mExtraData);
+ return new ConfirmationPrompt(mContext, mPromptText, mExtraData);
}
}
- private ConfirmationDialog(Context context, CharSequence promptText, byte[] extraData) {
+ private ConfirmationPrompt(Context context, CharSequence promptText, byte[] extraData) {
mContext = context;
mPromptText = promptText;
mExtraData = extraData;
@@ -227,10 +230,10 @@
return uiOptionsAsFlags;
}
- private boolean isAccessibilityServiceRunning() {
+ private static boolean isAccessibilityServiceRunning(Context context) {
boolean serviceRunning = false;
try {
- ContentResolver contentResolver = mContext.getContentResolver();
+ ContentResolver contentResolver = context.getContentResolver();
int a11yEnabled = Settings.Secure.getInt(contentResolver,
Settings.Secure.ACCESSIBILITY_ENABLED);
if (a11yEnabled == 1) {
@@ -249,12 +252,12 @@
* When the prompt is no longer being presented, one of the methods in
* {@link ConfirmationCallback} is called on the supplied callback object.
*
- * Confirmation dialogs may not be available when accessibility services are running so this
+ * Confirmation prompts may not be available when accessibility services are running so this
* may fail with a {@link ConfirmationNotAvailableException} exception even if
* {@link #isSupported} returns {@code true}.
*
* @param executor the executor identifying the thread that will receive the callback.
- * @param callback the callback to use when the dialog is done showing.
+ * @param callback the callback to use when the prompt is done showing.
* @throws IllegalArgumentException if the prompt text is too long or malfomed.
* @throws ConfirmationAlreadyPresentingException if another prompt is being presented.
* @throws ConfirmationNotAvailableException if confirmation prompts are not supported.
@@ -265,7 +268,7 @@
if (mCallback != null) {
throw new ConfirmationAlreadyPresentingException();
}
- if (isAccessibilityServiceRunning()) {
+ if (isAccessibilityServiceRunning(mContext)) {
throw new ConfirmationNotAvailableException();
}
mCallback = callback;
@@ -301,7 +304,7 @@
* Cancels a prompt currently being displayed.
*
* On success, the
- * {@link ConfirmationCallback#onDismissedByApplication onDismissedByApplication()} method on
+ * {@link ConfirmationCallback#onCanceled onCanceled()} method on
* the supplied callback object will be called asynchronously.
*
* @throws IllegalStateException if no prompt is currently being presented.
@@ -324,9 +327,13 @@
/**
* Checks if the device supports confirmation prompts.
*
+ * @param context the application context.
* @return true if confirmation prompts are supported by the device.
*/
- public static boolean isSupported() {
+ public static boolean isSupported(Context context) {
+ if (isAccessibilityServiceRunning(context)) {
+ return false;
+ }
return KeyStore.getInstance().isConfirmationPromptSupported();
}
}