Merge "Dataset authentication for Augmented Autofill" into rvc-dev am: 74c6b2a668
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/11825429 Change-Id: Ie961aeef7ba61047a319f68abe70b9447523dabc
This commit is contained in:
@@ -815,6 +815,19 @@ final class AutofillManagerServiceImpl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void logAugmentedAutofillAuthenticationSelected(int sessionId, @Nullable String selectedDataset,
|
||||||
|
@Nullable Bundle clientState) {
|
||||||
|
synchronized (mLock) {
|
||||||
|
if (mAugmentedAutofillEventHistory == null
|
||||||
|
|| mAugmentedAutofillEventHistory.getSessionId() != sessionId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mAugmentedAutofillEventHistory.addEvent(
|
||||||
|
new Event(Event.TYPE_DATASET_AUTHENTICATION_SELECTED, selectedDataset,
|
||||||
|
clientState, null, null, null, null, null, null, null, null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void logAugmentedAutofillSelected(int sessionId, @Nullable String suggestionId,
|
void logAugmentedAutofillSelected(int sessionId, @Nullable String suggestionId,
|
||||||
@Nullable Bundle clientState) {
|
@Nullable Bundle clientState) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
@@ -1198,6 +1211,14 @@ final class AutofillManagerServiceImpl
|
|||||||
suggestionId, clientState);
|
suggestionId, clientState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void logAugmentedAutofillAuthenticationSelected(int sessionId,
|
||||||
|
String suggestionId, Bundle clientState) {
|
||||||
|
AutofillManagerServiceImpl.this
|
||||||
|
.logAugmentedAutofillAuthenticationSelected(
|
||||||
|
sessionId, suggestionId, clientState);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onServiceDied(@NonNull RemoteAugmentedAutofillService service) {
|
public void onServiceDied(@NonNull RemoteAugmentedAutofillService service) {
|
||||||
Slog.w(TAG, "remote augmented autofill service died");
|
Slog.w(TAG, "remote augmented autofill service died");
|
||||||
|
|||||||
@@ -263,7 +263,28 @@ final class RemoteAugmentedAutofillService
|
|||||||
request, inlineSuggestionsData, focusedId, filterText,
|
request, inlineSuggestionsData, focusedId, filterText,
|
||||||
new InlineFillUi.InlineSuggestionUiCallback() {
|
new InlineFillUi.InlineSuggestionUiCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void autofill(Dataset dataset) {
|
public void autofill(Dataset dataset, int datasetIndex) {
|
||||||
|
if (dataset.getAuthentication() != null) {
|
||||||
|
mCallbacks.logAugmentedAutofillAuthenticationSelected(sessionId,
|
||||||
|
dataset.getId(), clientState);
|
||||||
|
final IntentSender action = dataset.getAuthentication();
|
||||||
|
final int authenticationId =
|
||||||
|
AutofillManager.makeAuthenticationId(
|
||||||
|
Session.AUGMENTED_AUTOFILL_REQUEST_ID,
|
||||||
|
datasetIndex);
|
||||||
|
final Intent fillInIntent = new Intent();
|
||||||
|
fillInIntent.putExtra(AutofillManager.EXTRA_CLIENT_STATE,
|
||||||
|
clientState);
|
||||||
|
try {
|
||||||
|
client.authenticate(sessionId, authenticationId, action,
|
||||||
|
fillInIntent, false);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Slog.w(TAG, "Error starting auth flow");
|
||||||
|
inlineSuggestionsCallback.apply(
|
||||||
|
InlineFillUi.emptyUi(focusedId));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
mCallbacks.logAugmentedAutofillSelected(sessionId,
|
mCallbacks.logAugmentedAutofillSelected(sessionId,
|
||||||
dataset.getId(), clientState);
|
dataset.getId(), clientState);
|
||||||
try {
|
try {
|
||||||
@@ -319,5 +340,8 @@ final class RemoteAugmentedAutofillService
|
|||||||
|
|
||||||
void logAugmentedAutofillSelected(int sessionId, @Nullable String suggestionId,
|
void logAugmentedAutofillSelected(int sessionId, @Nullable String suggestionId,
|
||||||
@Nullable Bundle clientState);
|
@Nullable Bundle clientState);
|
||||||
|
|
||||||
|
void logAugmentedAutofillAuthenticationSelected(int sessionId,
|
||||||
|
@Nullable String suggestionId, @Nullable Bundle clientState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,7 +144,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
|||||||
|
|
||||||
private final MetricsLogger mMetricsLogger = new MetricsLogger();
|
private final MetricsLogger mMetricsLogger = new MetricsLogger();
|
||||||
|
|
||||||
private static AtomicInteger sIdCounter = new AtomicInteger();
|
static final int AUGMENTED_AUTOFILL_REQUEST_ID = 1;
|
||||||
|
|
||||||
|
private static AtomicInteger sIdCounter = new AtomicInteger(2);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ID of the session.
|
* ID of the session.
|
||||||
@@ -736,7 +738,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
|||||||
viewState.setState(newState);
|
viewState.setState(newState);
|
||||||
|
|
||||||
int requestId;
|
int requestId;
|
||||||
|
// TODO(b/158623971): Update this to prevent possible overflow
|
||||||
do {
|
do {
|
||||||
requestId = sIdCounter.getAndIncrement();
|
requestId = sIdCounter.getAndIncrement();
|
||||||
} while (requestId == INVALID_REQUEST_ID);
|
} while (requestId == INVALID_REQUEST_ID);
|
||||||
@@ -1344,6 +1346,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
|||||||
+ id + " destroyed");
|
+ id + " destroyed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
final int requestId = AutofillManager.getRequestIdFromAuthenticationId(authenticationId);
|
||||||
|
if (requestId == AUGMENTED_AUTOFILL_REQUEST_ID) {
|
||||||
|
setAuthenticationResultForAugmentedAutofillLocked(data, authenticationId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (mResponses == null) {
|
if (mResponses == null) {
|
||||||
// Typically happens when app explicitly called cancel() while the service was showing
|
// Typically happens when app explicitly called cancel() while the service was showing
|
||||||
// the auth UI.
|
// the auth UI.
|
||||||
@@ -1351,7 +1358,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
|||||||
removeSelf();
|
removeSelf();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final int requestId = AutofillManager.getRequestIdFromAuthenticationId(authenticationId);
|
|
||||||
final FillResponse authenticatedResponse = mResponses.get(requestId);
|
final FillResponse authenticatedResponse = mResponses.get(requestId);
|
||||||
if (authenticatedResponse == null || data == null) {
|
if (authenticatedResponse == null || data == null) {
|
||||||
Slog.w(TAG, "no authenticated response");
|
Slog.w(TAG, "no authenticated response");
|
||||||
@@ -1410,6 +1416,58 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GuardedBy("mLock")
|
||||||
|
void setAuthenticationResultForAugmentedAutofillLocked(Bundle data, int authId) {
|
||||||
|
final Dataset dataset = (data == null) ? null :
|
||||||
|
data.getParcelable(AutofillManager.EXTRA_AUTHENTICATION_RESULT);
|
||||||
|
if (sDebug) {
|
||||||
|
Slog.d(TAG, "Auth result for augmented autofill: sessionId=" + id
|
||||||
|
+ ", authId=" + authId + ", dataset=" + dataset);
|
||||||
|
}
|
||||||
|
if (dataset == null
|
||||||
|
|| dataset.getFieldIds().size() != 1
|
||||||
|
|| dataset.getFieldIds().get(0) == null
|
||||||
|
|| dataset.getFieldValues().size() != 1
|
||||||
|
|| dataset.getFieldValues().get(0) == null) {
|
||||||
|
if (sDebug) {
|
||||||
|
Slog.d(TAG, "Rejecting empty/invalid auth result");
|
||||||
|
}
|
||||||
|
mService.resetLastAugmentedAutofillResponse();
|
||||||
|
removeSelfLocked();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final List<AutofillId> fieldIds = dataset.getFieldIds();
|
||||||
|
final List<AutofillValue> autofillValues = dataset.getFieldValues();
|
||||||
|
final AutofillId fieldId = fieldIds.get(0);
|
||||||
|
final AutofillValue value = autofillValues.get(0);
|
||||||
|
|
||||||
|
// Update state to ensure that after filling the field here we don't end up firing another
|
||||||
|
// autofill request that will end up showing the same suggestions to the user again. When
|
||||||
|
// the auth activity came up, the field for which the suggestions were shown lost focus and
|
||||||
|
// mCurrentViewId was cleared. We need to set mCurrentViewId back to the id of the field
|
||||||
|
// that we are filling.
|
||||||
|
fieldId.setSessionId(id);
|
||||||
|
mCurrentViewId = fieldId;
|
||||||
|
|
||||||
|
// Notify the Augmented Autofill provider of the dataset that was selected.
|
||||||
|
final Bundle clientState = data.getBundle(AutofillManager.EXTRA_CLIENT_STATE);
|
||||||
|
mService.logAugmentedAutofillSelected(id, dataset.getId(), clientState);
|
||||||
|
|
||||||
|
// Fill the value into the field.
|
||||||
|
if (sDebug) {
|
||||||
|
Slog.d(TAG, "Filling after auth: fieldId=" + fieldId + ", value=" + value);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
mClient.autofill(id, fieldIds, autofillValues, true);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Slog.w(TAG, "Error filling after auth: fieldId=" + fieldId + ", value=" + value
|
||||||
|
+ ", error=" + e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the suggestions since the user already accepted one of them.
|
||||||
|
mInlineSessionController.setInlineFillUiLocked(InlineFillUi.emptyUi(fieldId));
|
||||||
|
}
|
||||||
|
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
void setHasCallbackLocked(boolean hasIt) {
|
void setHasCallbackLocked(boolean hasIt) {
|
||||||
if (mDestroyed) {
|
if (mDestroyed) {
|
||||||
@@ -2506,6 +2564,10 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
|||||||
+ actionAsString(action) + ", flags=" + flags);
|
+ actionAsString(action) + ", flags=" + flags);
|
||||||
}
|
}
|
||||||
ViewState viewState = mViewStates.get(id);
|
ViewState viewState = mViewStates.get(id);
|
||||||
|
if (sVerbose) {
|
||||||
|
Slog.v(TAG, "updateLocked(" + this.id + "): mCurrentViewId=" + mCurrentViewId
|
||||||
|
+ ", mExpiredResponse=" + mExpiredResponse + ", viewState=" + viewState);
|
||||||
|
}
|
||||||
|
|
||||||
if (viewState == null) {
|
if (viewState == null) {
|
||||||
if (action == ACTION_START_SESSION || action == ACTION_VALUE_CHANGED
|
if (action == ACTION_START_SESSION || action == ACTION_VALUE_CHANGED
|
||||||
|
|||||||
@@ -290,7 +290,7 @@ public final class InlineFillUi {
|
|||||||
/**
|
/**
|
||||||
* Callback to autofill a dataset to the client app.
|
* Callback to autofill a dataset to the client app.
|
||||||
*/
|
*/
|
||||||
void autofill(@NonNull Dataset dataset);
|
void autofill(@NonNull Dataset dataset, int datasetIndex);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback to start Intent in client app.
|
* Callback to start Intent in client app.
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ final class InlineSuggestionFactory {
|
|||||||
return createInlineSuggestionsInternal(/* isAugmented= */ true, request,
|
return createInlineSuggestionsInternal(/* isAugmented= */ true, request,
|
||||||
datasets, autofillId, onErrorCallback,
|
datasets, autofillId, onErrorCallback,
|
||||||
(dataset, datasetIndex) ->
|
(dataset, datasetIndex) ->
|
||||||
inlineSuggestionUiCallback.autofill(dataset),
|
inlineSuggestionUiCallback.autofill(dataset, datasetIndex),
|
||||||
(intentSender) ->
|
(intentSender) ->
|
||||||
inlineSuggestionUiCallback.startIntentSender(intentSender, new Intent()),
|
inlineSuggestionUiCallback.startIntentSender(intentSender, new Intent()),
|
||||||
remoteRenderService);
|
remoteRenderService);
|
||||||
|
|||||||
Reference in New Issue
Block a user