Merge "Autofill Presentation Logs 3" into main
diff --git a/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java b/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
index 676abd1..d7da2f0 100644
--- a/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
+++ b/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
@@ -295,6 +295,38 @@
});
}
+ /**
+ * Called for inline suggestions - inflated one at
+ * a time. If InlineSuggestions were filtered,
+ * reset the count be incrementing
+ */
+ public void maybeIncrementCountShown() {
+ mEventInternal.ifPresent(event -> {
+ if (event.shouldResetShownCount) {
+ event.shouldResetShownCount = false;
+ event.mCountShown = 0;
+ }
+
+ if (event.mCountShown == 0) {
+ // The first time suggestions are rendered
+ // set time stamp
+ maybeSetSuggestionPresentedTimestampMs();
+ }
+
+ event.mCountShown += 1;
+ });
+ }
+
+ /**
+ * Call this when UI is hidden. This will set a flag to reset count for inline. We do this
+ * instead of resetting right away in case there are 0 inline presentations after.
+ */
+ public void markShownCountAsResettable() {
+ mEventInternal.ifPresent(event -> {
+ event.shouldResetShownCount = true;
+ });
+ }
+
public void maybeSetCountShown(@Nullable List<Dataset> datasetList,
AutofillId currentViewId) {
mEventInternal.ifPresent(event -> {
@@ -306,6 +338,13 @@
});
}
+ public void maybeSetCountShown(int datasets) {
+ mEventInternal.ifPresent(
+ event -> {
+ event.mCountShown = datasets;
+ });
+ }
+
private static CountContainer getDatasetCountForAutofillId(@Nullable List<Dataset> datasetList,
AutofillId currentViewId) {
@@ -567,31 +606,36 @@
* <p>If the ViewState contains ViewState.STATE_AUTOFILLED, sets field_autofilled_timestamp_ms
* else, set field_first_modified_timestamp_ms (if unset) and field_last_modified_timestamp_ms
*/
- public void onFieldTextUpdated(ViewState state) {
- mEventInternal.ifPresent(
- event -> {
+ public void onFieldTextUpdated(ViewState state, int length) {
+ mEventInternal.ifPresent(event -> {
int timestamp = getElapsedTime();
// Focused id should be set before this is called
- if (state.id != null && state.id.getViewId() != event.mFocusedId) {
+ if (state == null || state.id == null || state.id.getViewId() != event.mFocusedId) {
// if these don't match, the currently field different than before
Slog.w(
TAG,
- "current id: "
- + state.id.getViewId()
- + " is different than focused id: "
- + event.mFocusedId);
+ "Bad view state for: " + event.mFocusedId);
return;
}
+ // Text changed because filling into form, just log Autofill timestamp
if ((state.getState() & ViewState.STATE_AUTOFILLED) != 0) {
event.mAutofilledTimestampMs = timestamp;
- } else {
- if (event.mFieldModifiedFirstTimestampMs == DEFAULT_VALUE_INT) {
- event.mFieldModifiedFirstTimestampMs = timestamp;
- }
- event.mFieldModifiedLastTimestampMs = timestamp;
+ return;
}
- });
+
+ // Set length variables
+ if (event.mFieldFirstLength == DEFAULT_VALUE_INT) {
+ event.mFieldFirstLength = length;
+ }
+ event.mFieldLastLength = length;
+
+ // Set timestamp variables
+ if (event.mFieldModifiedFirstTimestampMs == DEFAULT_VALUE_INT) {
+ event.mFieldModifiedFirstTimestampMs = timestamp;
+ }
+ event.mFieldModifiedLastTimestampMs = timestamp;
+ });
}
public void setPresentationSelectedTimestamp() {
@@ -661,15 +705,16 @@
/** Sets focused_autofill_id using view id */
public void maybeSetFocusedId(AutofillId id) {
- maybeSetFocusedId(id.getViewId());
+ mEventInternal.ifPresent(
+ event -> {
+ event.mFocusedId = id.getViewId();
+ if (id.isVirtualInt()) {
+ event.mFocusedVirtualAutofillId =
+ id.getVirtualChildIntId() % 100;
+ }
+ });
}
- /** Sets focused_autofill_id as long as mEventInternal is present */
- public void maybeSetFocusedId(int id) {
- mEventInternal.ifPresent(event -> {
- event.mFocusedId = id;
- });
- }
/**
* Set views_filled_failure_count using failure count as long as mEventInternal
* presents.
@@ -823,7 +868,7 @@
@NotShownReason int mNoPresentationReason = NOT_SHOWN_REASON_UNKNOWN;
boolean mIsDatasetAvailable;
int mAvailableCount;
- int mCountShown;
+ int mCountShown = 0;
int mCountFilteredUserTyping;
int mCountNotShownImePresentationNotDrawn;
int mCountNotShownImeUserNotSeen;
@@ -870,6 +915,9 @@
ArraySet<AutofillId> mAutofillIdsAttemptedAutofill;
ArraySet<AutofillId> mAlreadyFilledAutofillIds = new ArraySet<>();
+
+ // Not logged - used for internal logic
+ boolean shouldResetShownCount = false;
PresentationStatsEventInternal() {}
}
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index b22f999..cdae16b 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -30,7 +30,6 @@
import static android.service.autofill.FillEventHistory.Event.UI_TYPE_CREDMAN_BOTTOM_SHEET;
import static android.service.autofill.FillEventHistory.Event.UI_TYPE_DIALOG;
import static android.service.autofill.FillEventHistory.Event.UI_TYPE_INLINE;
-import static android.service.autofill.FillEventHistory.Event.UI_TYPE_MENU;
import static android.service.autofill.FillEventHistory.Event.UI_TYPE_UNKNOWN;
import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST;
import static android.service.autofill.FillRequest.FLAG_PASSWORD_INPUT_TYPE;
@@ -2661,19 +2660,30 @@
// AutofillUiCallback
@Override
- public void onShown(int uiType) {
+ public void onShown(int uiType, int numDatasetsShown) {
synchronized (mLock) {
+ mPresentationStatsEventLogger.maybeSetDisplayPresentationType(uiType);
+
if (uiType == UI_TYPE_INLINE) {
- if (mLoggedInlineDatasetShown) {
+ // Inline Suggestions are inflated one at a time
+ // This number will be reset when filtered
+ // This will also call maybeSetSuggestionPresentedTimestampMs
+ mPresentationStatsEventLogger.maybeIncrementCountShown();
+
+ if (!mLoggedInlineDatasetShown) {
// Chip inflation already logged, do not log again.
// This is needed because every chip inflation will call this.
- return;
+ mService.logDatasetShown(this.id, mClientState, uiType);
+ Slog.d(TAG, "onShown(): " + uiType + ", " + numDatasetsShown);
}
mLoggedInlineDatasetShown = true;
+ } else {
+ mPresentationStatsEventLogger.maybeSetCountShown(numDatasetsShown);
+ // Explicitly sets maybeSetSuggestionPresentedTimestampMs
+ mPresentationStatsEventLogger.maybeSetSuggestionPresentedTimestampMs();
+ mService.logDatasetShown(this.id, mClientState, uiType);
+ Slog.d(TAG, "onShown(): " + uiType + ", " + numDatasetsShown);
}
- mService.logDatasetShown(this.id, mClientState, uiType);
- mPresentationStatsEventLogger.maybeSetSuggestionPresentedTimestampMs();
- Slog.d(TAG, "onShown(): " + uiType);
}
}
@@ -2739,6 +2749,7 @@
}
mInlineSessionController.hideInlineSuggestionsUiLocked(id);
+ mPresentationStatsEventLogger.markShownCountAsResettable();
}
}
@@ -4868,7 +4879,9 @@
currentView.maybeCallOnFillReady(flags);
}
}
- mPresentationStatsEventLogger.onFieldTextUpdated(viewState);
+ if (textValue != null) {
+ mPresentationStatsEventLogger.onFieldTextUpdated(viewState, textValue.length());
+ }
if (viewState.id.equals(this.mCurrentViewId)
&& (viewState.getState() & ViewState.STATE_INLINE_SHOWN) != 0) {
@@ -4965,8 +4978,6 @@
synchronized (mLock) {
final ViewState currentView = mViewStates.get(mCurrentViewId);
currentView.setState(ViewState.STATE_FILL_DIALOG_SHOWN);
- mPresentationStatsEventLogger.maybeSetCountShown(
- response.getDatasets(), mCurrentViewId);
mPresentationStatsEventLogger.maybeSetDisplayPresentationType(UI_TYPE_DIALOG);
}
// Just show fill dialog once, so disabled after shown.
@@ -4987,10 +4998,6 @@
// back a response via callback.
final ViewState currentView = mViewStates.get(mCurrentViewId);
currentView.setState(ViewState.STATE_INLINE_SHOWN);
- // TODO(b/234475358): Log more accurate value of number of inline suggestions
- // shown, inflated, and filtered.
- mPresentationStatsEventLogger.maybeSetCountShown(
- response.getDatasets(), mCurrentViewId);
mPresentationStatsEventLogger.maybeSetInlinePresentationAndSuggestionHostUid(
mContext, userId);
return;
@@ -5004,12 +5011,6 @@
mService.getMaster().getMaxInputLengthForAutofill());
synchronized (mLock) {
- mPresentationStatsEventLogger.maybeSetCountShown(
- response.getDatasets(), mCurrentViewId);
- mPresentationStatsEventLogger.maybeSetDisplayPresentationType(UI_TYPE_MENU);
- }
-
- synchronized (mLock) {
if (mUiShownTime == 0) {
// Log first time UI is shown.
mUiShownTime = SystemClock.elapsedRealtime();
@@ -5249,7 +5250,7 @@
@Override
public void onInflate() {
- Session.this.onShown(UI_TYPE_INLINE);
+ Session.this.onShown(UI_TYPE_INLINE, 1);
}
}, mService.getMaster().getMaxInputLengthForAutofill());
return mInlineSessionController.setInlineFillUiLocked(inlineFillUi);
diff --git a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
index 8cc666b..2e9a4dc 100644
--- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
@@ -102,7 +102,7 @@
void cancelSession();
void requestShowSoftInput(AutofillId id);
void requestFallbackFromFillDialog();
- void onShown(int uiType);
+ void onShown(int uiType, int datasetSize);
}
public AutoFillUI(@NonNull Context context) {
@@ -246,9 +246,9 @@
}
@Override
- public void onShown() {
+ public void onShown(int datasetSize) {
if (mCallback != null) {
- mCallback.onShown(UI_TYPE_MENU);
+ mCallback.onShown(UI_TYPE_MENU, datasetSize);
}
}
@@ -462,7 +462,7 @@
@Override
public void onShown() {
- callback.onShown(UI_TYPE_DIALOG);
+ mCallback.onShown(UI_TYPE_DIALOG, response.getDatasets().size());
}
@Override
diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
index 1831ecd..1bda70d 100644
--- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
@@ -16,6 +16,7 @@
package com.android.server.autofill.ui;
import static android.service.autofill.FillResponse.FLAG_CREDENTIAL_MANAGER_RESPONSE;
+
import static com.android.server.autofill.Helper.paramsToString;
import static com.android.server.autofill.Helper.sDebug;
import static com.android.server.autofill.Helper.sFullScreenMode;
@@ -90,7 +91,7 @@
void onDatasetPicked(@NonNull Dataset dataset);
void onCanceled();
void onDestroy();
- void onShown();
+ void onShown(int datasetSize);
void requestShowFillUi(int width, int height,
IAutofillWindowPresenter windowPresenter);
void requestHideFillUi();
@@ -742,7 +743,8 @@
mWm.addView(mContentView, params);
mOverlayControl.hideOverlays();
mShowing = true;
- mCallback.onShown();
+ int numShownDatasets = (mAdapter == null) ? 0 : mAdapter.getCount();
+ mCallback.onShown(numShownDatasets);
} else {
mWm.updateViewLayout(mContentView, params);
}