Finishes the session when the service returns a null response on authentication.
Test: cts-tradefed run commandAndExit cts-dev -m CtsAutoFillServiceTestCases -t android.autofillservice.cts.LoginActivityTest#testFillResponseAuthServiceHasNoData
Test: cts-tradefed run commandAndExit cts-dev -m CtsAutoFillServiceTestCases
Fixes: 64985246
Change-Id: Id9a4b9f1752dcee6c67ac659b9dbd6dd1dd7b43c
diff --git a/core/java/android/service/autofill/FillResponse.java b/core/java/android/service/autofill/FillResponse.java
index 3b09c67..6d8a959 100644
--- a/core/java/android/service/autofill/FillResponse.java
+++ b/core/java/android/service/autofill/FillResponse.java
@@ -148,10 +148,12 @@
* {@link android.view.autofill.AutofillManager#EXTRA_ASSIST_STRUCTURE screen
* content} and your {@link android.view.autofill.AutofillManager#EXTRA_CLIENT_STATE
* client state}. Once you complete your authentication flow you should set the
- * {@link Activity} result to {@link android.app.Activity#RESULT_OK} and provide the fully
- * populated {@link FillResponse response} by setting it to the
- * {@link android.view.autofill.AutofillManager#EXTRA_AUTHENTICATION_RESULT} extra.
- * For example, if you provided an empty {@link FillResponse resppnse} because the
+ * {@link Activity} result to {@link android.app.Activity#RESULT_OK} and set the
+ * {@link android.view.autofill.AutofillManager#EXTRA_AUTHENTICATION_RESULT} extra
+ * with the fully populated {@link FillResponse response} (or {@code null} if the screen
+ * cannot be autofilled).
+ *
+ * <p>For example, if you provided an empty {@link FillResponse response} because the
* user's data was locked and marked that the response needs an authentication then
* in the response returned if authentication succeeds you need to provide all
* available data sets some of which may need to be further authenticated, for
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 95db603..d81cd64 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -456,14 +456,7 @@
}
}
if (response == null) {
- if (sVerbose) Slog.v(TAG, "canceling session " + id + " when server returned null");
- if ((requestFlags & FLAG_MANUAL_REQUEST) != 0) {
- getUiForShowing().showError(R.string.autofill_error_cannot_autofill, this);
- }
- mService.resetLastResponse();
- // Nothing to be done, but need to notify client.
- notifyUnavailableToClient();
- removeSelf();
+ processNullResponseLocked(requestFlags);
return;
}
@@ -748,16 +741,24 @@
}
final Parcelable result = data.getParcelable(AutofillManager.EXTRA_AUTHENTICATION_RESULT);
+ if (sDebug) Slog.d(TAG, "setAuthenticationResultLocked(): result=" + result);
if (result instanceof FillResponse) {
final FillResponse response = (FillResponse) result;
mMetricsLogger.action(MetricsEvent.AUTOFILL_AUTHENTICATED, mPackageName);
replaceResponseLocked(authenticatedResponse, response);
} else if (result instanceof Dataset) {
+ // TODO: add proper metric
if (datasetIdx != AutofillManager.AUTHENTICATION_ID_DATASET_ID_UNDEFINED) {
final Dataset dataset = (Dataset) result;
authenticatedResponse.getDatasets().set(datasetIdx, dataset);
autoFill(requestId, datasetIdx, dataset);
}
+ } else {
+ if (result != null) {
+ Slog.w(TAG, "service returned invalid auth type: " + result);
+ }
+ // TODO: add proper metric (on else)
+ processNullResponseLocked(0);
}
}
@@ -1409,6 +1410,17 @@
processResponseLocked(newResponse, 0);
}
+ private void processNullResponseLocked(int flags) {
+ if (sVerbose) Slog.v(TAG, "canceling session " + id + " when server returned null");
+ if ((flags & FLAG_MANUAL_REQUEST) != 0) {
+ getUiForShowing().showError(R.string.autofill_error_cannot_autofill, this);
+ }
+ mService.resetLastResponse();
+ // Nothing to be done, but need to notify client.
+ notifyUnavailableToClient();
+ removeSelf();
+ }
+
private void processResponseLocked(@NonNull FillResponse newResponse, int flags) {
// Make sure we are hiding the UI which will be shown
// only if handling the current response requires it.