Merge "Add a new Autofill FillEvent - for when the user taps a field. Test: atest android.autofillservice.cts.inline.InlineFillEventHistoryTest" into udc-dev
This commit is contained in:
@@ -39862,6 +39862,7 @@ package android.service.autofill {
|
|||||||
field public static final int TYPE_DATASET_AUTHENTICATION_SELECTED = 1; // 0x1
|
field public static final int TYPE_DATASET_AUTHENTICATION_SELECTED = 1; // 0x1
|
||||||
field public static final int TYPE_DATASET_SELECTED = 0; // 0x0
|
field public static final int TYPE_DATASET_SELECTED = 0; // 0x0
|
||||||
field public static final int TYPE_SAVE_SHOWN = 3; // 0x3
|
field public static final int TYPE_SAVE_SHOWN = 3; // 0x3
|
||||||
|
field public static final int TYPE_VIEW_REQUESTED_AUTOFILL = 6; // 0x6
|
||||||
field public static final int UI_TYPE_DIALOG = 3; // 0x3
|
field public static final int UI_TYPE_DIALOG = 3; // 0x3
|
||||||
field public static final int UI_TYPE_INLINE = 2; // 0x2
|
field public static final int UI_TYPE_INLINE = 2; // 0x2
|
||||||
field public static final int UI_TYPE_MENU = 1; // 0x1
|
field public static final int UI_TYPE_MENU = 1; // 0x1
|
||||||
|
|||||||
@@ -233,6 +233,22 @@ public final class FillEventHistory implements Parcelable {
|
|||||||
*/
|
*/
|
||||||
public static final int TYPE_DATASETS_SHOWN = 5;
|
public static final int TYPE_DATASETS_SHOWN = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The app/user requested for a field to be Autofilled.
|
||||||
|
*
|
||||||
|
* This event is fired when the view has been entered (by user or app) in order
|
||||||
|
* to differentiate from FillRequests that have been pretriggered for FillDialogs.
|
||||||
|
*
|
||||||
|
* For example, the user might navigate away from a screen without tapping any
|
||||||
|
* fields. In this case, a FillRequest/FillResponse has been generated, but was
|
||||||
|
* not used for Autofilling. The user did not intend to see an Autofill result,
|
||||||
|
* but a FillRequest was still generated. This is different from when the user
|
||||||
|
* did tap on a field after the pretriggered FillRequest, this event will appear
|
||||||
|
* in the FillEventHistory, signaling that the user did intend to Autofill
|
||||||
|
* something.
|
||||||
|
*/
|
||||||
|
public static final int TYPE_VIEW_REQUESTED_AUTOFILL = 6;
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
@IntDef(prefix = { "TYPE_" }, value = {
|
@IntDef(prefix = { "TYPE_" }, value = {
|
||||||
TYPE_DATASET_SELECTED,
|
TYPE_DATASET_SELECTED,
|
||||||
@@ -240,7 +256,8 @@ public final class FillEventHistory implements Parcelable {
|
|||||||
TYPE_AUTHENTICATION_SELECTED,
|
TYPE_AUTHENTICATION_SELECTED,
|
||||||
TYPE_SAVE_SHOWN,
|
TYPE_SAVE_SHOWN,
|
||||||
TYPE_CONTEXT_COMMITTED,
|
TYPE_CONTEXT_COMMITTED,
|
||||||
TYPE_DATASETS_SHOWN
|
TYPE_DATASETS_SHOWN,
|
||||||
|
TYPE_VIEW_REQUESTED_AUTOFILL
|
||||||
})
|
})
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@interface EventIds{}
|
@interface EventIds{}
|
||||||
@@ -659,8 +676,8 @@ public final class FillEventHistory implements Parcelable {
|
|||||||
@Nullable AutofillId[] detectedFieldIds,
|
@Nullable AutofillId[] detectedFieldIds,
|
||||||
@Nullable FieldClassification[] detectedFieldClassifications,
|
@Nullable FieldClassification[] detectedFieldClassifications,
|
||||||
int saveDialogNotShowReason, int uiType) {
|
int saveDialogNotShowReason, int uiType) {
|
||||||
mEventType = Preconditions.checkArgumentInRange(eventType, 0, TYPE_DATASETS_SHOWN,
|
mEventType = Preconditions.checkArgumentInRange(eventType, 0,
|
||||||
"eventType");
|
TYPE_VIEW_REQUESTED_AUTOFILL, "eventType");
|
||||||
mDatasetId = datasetId;
|
mDatasetId = datasetId;
|
||||||
mClientState = clientState;
|
mClientState = clientState;
|
||||||
mSelectedDatasetIds = selectedDatasetIds;
|
mSelectedDatasetIds = selectedDatasetIds;
|
||||||
@@ -723,6 +740,8 @@ public final class FillEventHistory implements Parcelable {
|
|||||||
return "TYPE_CONTEXT_COMMITTED";
|
return "TYPE_CONTEXT_COMMITTED";
|
||||||
case TYPE_DATASETS_SHOWN:
|
case TYPE_DATASETS_SHOWN:
|
||||||
return "TYPE_DATASETS_SHOWN";
|
return "TYPE_DATASETS_SHOWN";
|
||||||
|
case TYPE_VIEW_REQUESTED_AUTOFILL:
|
||||||
|
return "TYPE_VIEW_REQUESTED_AUTOFILL";
|
||||||
default:
|
default:
|
||||||
return "TYPE_UNKNOWN";
|
return "TYPE_UNKNOWN";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -849,6 +849,32 @@ final class AutofillManagerServiceImpl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the last fill response when a view was entered.
|
||||||
|
*/
|
||||||
|
void logViewEntered(int sessionId, @Nullable Bundle clientState) {
|
||||||
|
synchronized (mLock) {
|
||||||
|
if (!isValidEventLocked("logViewEntered", sessionId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mEventHistory.getEvents() != null) {
|
||||||
|
// Do not log this event more than once
|
||||||
|
for (Event event : mEventHistory.getEvents()) {
|
||||||
|
if (event.getType() == Event.TYPE_VIEW_REQUESTED_AUTOFILL) {
|
||||||
|
Slog.v(TAG, "logViewEntered: already logged TYPE_VIEW_REQUESTED_AUTOFILL");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mEventHistory.addEvent(
|
||||||
|
new Event(Event.TYPE_VIEW_REQUESTED_AUTOFILL, null, clientState, null,
|
||||||
|
null, null, null, null, null, null, null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void logAugmentedAutofillAuthenticationSelected(int sessionId, @Nullable String selectedDataset,
|
void logAugmentedAutofillAuthenticationSelected(int sessionId, @Nullable String selectedDataset,
|
||||||
@Nullable Bundle clientState) {
|
@Nullable Bundle clientState) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
|
|||||||
@@ -441,6 +441,18 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
|||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
private boolean mPreviouslyFillDialogPotentiallyStarted;
|
private boolean mPreviouslyFillDialogPotentiallyStarted;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keeps track of if the user entered view, this is used to
|
||||||
|
* distinguish Fill Request that did not have user interaction
|
||||||
|
* with ones that did.
|
||||||
|
*
|
||||||
|
* This is set to true when entering view - after FillDialog FillRequest
|
||||||
|
* or on plain user tap.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
@GuardedBy("mLock")
|
||||||
|
private boolean mLogViewEntered;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keeps the fill dialog trigger ids of the last response. This invalidates
|
* Keeps the fill dialog trigger ids of the last response. This invalidates
|
||||||
* the trigger ids of the previous response.
|
* the trigger ids of the previous response.
|
||||||
@@ -1289,6 +1301,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
|||||||
|
|
||||||
mMetricsLogger.write(newLogMaker(MetricsEvent.AUTOFILL_SESSION_STARTED)
|
mMetricsLogger.write(newLogMaker(MetricsEvent.AUTOFILL_SESSION_STARTED)
|
||||||
.addTaggedData(MetricsEvent.FIELD_AUTOFILL_FLAGS, flags));
|
.addTaggedData(MetricsEvent.FIELD_AUTOFILL_FLAGS, flags));
|
||||||
|
mLogViewEntered = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1413,6 +1426,14 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
|||||||
|
|
||||||
mService.setLastResponse(id, response);
|
mService.setLastResponse(id, response);
|
||||||
|
|
||||||
|
synchronized (mLock) {
|
||||||
|
if (mLogViewEntered) {
|
||||||
|
mLogViewEntered = false;
|
||||||
|
mService.logViewEntered(id, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
final long disableDuration = response.getDisableDuration();
|
final long disableDuration = response.getDisableDuration();
|
||||||
final boolean autofillDisabled = disableDuration > 0;
|
final boolean autofillDisabled = disableDuration > 0;
|
||||||
if (autofillDisabled) {
|
if (autofillDisabled) {
|
||||||
@@ -3545,6 +3566,28 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
synchronized (mLock) {
|
||||||
|
if (!mLogViewEntered) {
|
||||||
|
// If the current request is for FillDialog (preemptive)
|
||||||
|
// then this is the first time that the view is entered
|
||||||
|
// (mLogViewEntered == false) in this case, setLastResponse()
|
||||||
|
// has already been called, so just log here.
|
||||||
|
// If the current request is not and (mLogViewEntered == false)
|
||||||
|
// then the last session is being tracked (setLastResponse not called)
|
||||||
|
// so this calling logViewEntered will be a nop.
|
||||||
|
// Calling logViewEntered() twice will only log it once
|
||||||
|
// TODO(271181979): this is broken for multiple partitions
|
||||||
|
mService.logViewEntered(this.id, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this is the first time view is entered for inline, the last
|
||||||
|
// session is still being tracked, so logViewEntered() needs
|
||||||
|
// to be delayed until setLastResponse is called.
|
||||||
|
// For fill dialog requests case logViewEntered is already called above
|
||||||
|
// so this will do nothing. Assumption: only one fill dialog per session
|
||||||
|
mLogViewEntered = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Previously, fill request will only start whenever a view is entered.
|
// Previously, fill request will only start whenever a view is entered.
|
||||||
// With Fill Dialog, request starts prior to view getting entered. So, we can't end
|
// With Fill Dialog, request starts prior to view getting entered. So, we can't end
|
||||||
// the event at this moment, otherwise we will be wrongly attributing fill dialog
|
// the event at this moment, otherwise we will be wrongly attributing fill dialog
|
||||||
|
|||||||
Reference in New Issue
Block a user