diff --git a/services/autofill/java/com/android/server/autofill/FillResponseEventLogger.java b/services/autofill/java/com/android/server/autofill/FillResponseEventLogger.java index 6b8246cd5bfb1..8f2ab714c4af1 100644 --- a/services/autofill/java/com/android/server/autofill/FillResponseEventLogger.java +++ b/services/autofill/java/com/android/server/autofill/FillResponseEventLogger.java @@ -17,16 +17,16 @@ package com.android.server.autofill; import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED; -import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__DISPLAY_PRESENTATION_TYPE__UNKNOWN_AUTOFILL_DISPLAY_PRESENTATION_TYPE; -import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__DISPLAY_PRESENTATION_TYPE__MENU; -import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__DISPLAY_PRESENTATION_TYPE__INLINE; import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__DISPLAY_PRESENTATION_TYPE__DIALOG; +import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__DISPLAY_PRESENTATION_TYPE__INLINE; +import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__DISPLAY_PRESENTATION_TYPE__MENU; +import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__DISPLAY_PRESENTATION_TYPE__UNKNOWN_AUTOFILL_DISPLAY_PRESENTATION_TYPE; +import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__AUTHENTICATION_RESULT__AUTHENTICATION_FAILURE; +import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__AUTHENTICATION_RESULT__AUTHENTICATION_RESULT_UNKNOWN; +import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__AUTHENTICATION_RESULT__AUTHENTICATION_SUCCESS; import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__AUTHENTICATION_TYPE__AUTHENTICATION_TYPE_UNKNOWN; import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__AUTHENTICATION_TYPE__DATASET_AUTHENTICATION; import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__AUTHENTICATION_TYPE__FULL_AUTHENTICATION; -import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__AUTHENTICATION_RESULT__AUTHENTICATION_RESULT_UNKNOWN; -import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__AUTHENTICATION_RESULT__AUTHENTICATION_SUCCESS; -import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__AUTHENTICATION_RESULT__AUTHENTICATION_FAILURE; import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__RESPONSE_STATUS__RESPONSE_STATUS_CANCELLED; import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__RESPONSE_STATUS__RESPONSE_STATUS_FAILURE; import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__RESPONSE_STATUS__RESPONSE_STATUS_SESSION_DESTROYED; @@ -37,12 +37,7 @@ import static com.android.server.autofill.Helper.sVerbose; import android.annotation.IntDef; import android.annotation.Nullable; -import android.content.ComponentName; -import android.content.Context; -import android.content.pm.PackageManager; -import android.provider.Settings; import android.service.autofill.Dataset; -import android.text.TextUtils; import android.util.Slog; import android.view.autofill.AutofillId; @@ -154,6 +149,9 @@ public final class FillResponseEventLogger { // succeeded. public static final int AVAILABLE_COUNT_WHEN_FILL_REQUEST_FAILED_OR_TIMEOUT = -1; + // Log a magic number to indicate that the FillResponse contains a saveTriggerId. + public static final int HAVE_SAVE_TRIGGER_ID = 1; + private final int mSessionId; private Optional mEventInternal; diff --git a/services/autofill/java/com/android/server/autofill/SaveEventLogger.java b/services/autofill/java/com/android/server/autofill/SaveEventLogger.java index 4b7d5bdf0002f..e5435c2869fdc 100644 --- a/services/autofill/java/com/android/server/autofill/SaveEventLogger.java +++ b/services/autofill/java/com/android/server/autofill/SaveEventLogger.java @@ -23,8 +23,10 @@ import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_SAVE_EVENT_RE import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_SAVE_EVENT_REPORTED__SAVE_UI_NOT_SHOWN_REASON__NO_SAVE_REASON_NONE; import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_SAVE_EVENT_REPORTED__SAVE_UI_NOT_SHOWN_REASON__NO_SAVE_REASON_NO_SAVE_INFO; import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_SAVE_EVENT_REPORTED__SAVE_UI_NOT_SHOWN_REASON__NO_SAVE_REASON_NO_VALUE_CHANGED; +import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_SAVE_EVENT_REPORTED__SAVE_UI_NOT_SHOWN_REASON__NO_SAVE_REASON_SESSION_DESTROYED; import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_SAVE_EVENT_REPORTED__SAVE_UI_NOT_SHOWN_REASON__NO_SAVE_REASON_UNKNOWN; import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_SAVE_EVENT_REPORTED__SAVE_UI_NOT_SHOWN_REASON__NO_SAVE_REASON_WITH_DELAY_SAVE_FLAG; +import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_SAVE_EVENT_REPORTED__SAVE_UI_NOT_SHOWN_REASON__NO_SAVE_REASON_WITH_DONT_SAVE_ON_FINISH_FLAG; import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_SAVE_EVENT_REPORTED__SAVE_UI_SHOWN_REASON__SAVE_UI_SHOWN_REASON_OPTIONAL_ID_CHANGE; import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_SAVE_EVENT_REPORTED__SAVE_UI_SHOWN_REASON__SAVE_UI_SHOWN_REASON_REQUIRED_ID_CHANGE; import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_SAVE_EVENT_REPORTED__SAVE_UI_SHOWN_REASON__SAVE_UI_SHOWN_REASON_TRIGGER_ID_SET; @@ -32,11 +34,6 @@ import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_SAVE_EVENT_RE import static com.android.server.autofill.Helper.sVerbose; import android.annotation.IntDef; -import android.content.ComponentName; -import android.content.Context; -import android.content.pm.PackageManager; -import android.provider.Settings; -import android.text.TextUtils; import android.util.Slog; import com.android.internal.util.FrameworkStatsLog; @@ -74,10 +71,12 @@ public final class SaveEventLogger { NO_SAVE_REASON_NONE, NO_SAVE_REASON_NO_SAVE_INFO, NO_SAVE_REASON_WITH_DELAY_SAVE_FLAG, + NO_SAVE_REASON_WITH_DONT_SAVE_ON_FINISH_FLAG, NO_SAVE_REASON_HAS_EMPTY_REQUIRED, NO_SAVE_REASON_NO_VALUE_CHANGED, NO_SAVE_REASON_FIELD_VALIDATION_FAILED, - NO_SAVE_REASON_DATASET_MATCH + NO_SAVE_REASON_DATASET_MATCH, + NO_SAVE_REASON_SESSION_DESTROYED }) @Retention(RetentionPolicy.SOURCE) public @interface SaveUiNotShownReason { @@ -108,6 +107,10 @@ public final class SaveEventLogger { AUTOFILL_SAVE_EVENT_REPORTED__SAVE_UI_NOT_SHOWN_REASON__NO_SAVE_REASON_FIELD_VALIDATION_FAILED; public static final int NO_SAVE_REASON_DATASET_MATCH = AUTOFILL_SAVE_EVENT_REPORTED__SAVE_UI_NOT_SHOWN_REASON__NO_SAVE_REASON_DATASET_MATCH; + public static final int NO_SAVE_REASON_SESSION_DESTROYED = + AUTOFILL_SAVE_EVENT_REPORTED__SAVE_UI_NOT_SHOWN_REASON__NO_SAVE_REASON_SESSION_DESTROYED; + public static final int NO_SAVE_REASON_WITH_DONT_SAVE_ON_FINISH_FLAG = + AUTOFILL_SAVE_EVENT_REPORTED__SAVE_UI_NOT_SHOWN_REASON__NO_SAVE_REASON_WITH_DONT_SAVE_ON_FINISH_FLAG; private final int mSessionId; private Optional mEventInternal; diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index fe2a3bafaf22e..8d039fc020267 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -45,6 +45,7 @@ import static com.android.server.autofill.FillRequestEventLogger.TRIGGER_REASON_ import static com.android.server.autofill.FillRequestEventLogger.TRIGGER_REASON_PRE_TRIGGER; import static com.android.server.autofill.FillRequestEventLogger.TRIGGER_REASON_SERVED_FROM_CACHED_RESPONSE; import static com.android.server.autofill.FillResponseEventLogger.AVAILABLE_COUNT_WHEN_FILL_REQUEST_FAILED_OR_TIMEOUT; +import static com.android.server.autofill.FillResponseEventLogger.HAVE_SAVE_TRIGGER_ID; import static com.android.server.autofill.FillResponseEventLogger.RESPONSE_STATUS_FAILURE; import static com.android.server.autofill.FillResponseEventLogger.RESPONSE_STATUS_SESSION_DESTROYED; import static com.android.server.autofill.FillResponseEventLogger.RESPONSE_STATUS_SUCCESS; @@ -58,8 +59,22 @@ import static com.android.server.autofill.Helper.toArray; import static com.android.server.autofill.PresentationStatsEventLogger.NOT_SHOWN_REASON_NO_FOCUS; import static com.android.server.autofill.PresentationStatsEventLogger.NOT_SHOWN_REASON_REQUEST_FAILED; import static com.android.server.autofill.PresentationStatsEventLogger.NOT_SHOWN_REASON_REQUEST_TIMEOUT; +import static com.android.server.autofill.PresentationStatsEventLogger.NOT_SHOWN_REASON_SESSION_COMMITTED_PREMATURELY; import static com.android.server.autofill.PresentationStatsEventLogger.NOT_SHOWN_REASON_VIEW_CHANGED; import static com.android.server.autofill.PresentationStatsEventLogger.NOT_SHOWN_REASON_VIEW_FOCUS_CHANGED; +import static com.android.server.autofill.SaveEventLogger.NO_SAVE_REASON_DATASET_MATCH; +import static com.android.server.autofill.SaveEventLogger.NO_SAVE_REASON_FIELD_VALIDATION_FAILED; +import static com.android.server.autofill.SaveEventLogger.NO_SAVE_REASON_HAS_EMPTY_REQUIRED; +import static com.android.server.autofill.SaveEventLogger.NO_SAVE_REASON_NONE; +import static com.android.server.autofill.SaveEventLogger.NO_SAVE_REASON_NO_SAVE_INFO; +import static com.android.server.autofill.SaveEventLogger.NO_SAVE_REASON_NO_VALUE_CHANGED; +import static com.android.server.autofill.SaveEventLogger.NO_SAVE_REASON_SESSION_DESTROYED; +import static com.android.server.autofill.SaveEventLogger.NO_SAVE_REASON_WITH_DELAY_SAVE_FLAG; +import static com.android.server.autofill.SaveEventLogger.NO_SAVE_REASON_WITH_DONT_SAVE_ON_FINISH_FLAG; +import static com.android.server.autofill.SaveEventLogger.SAVE_UI_SHOWN_REASON_OPTIONAL_ID_CHANGE; +import static com.android.server.autofill.SaveEventLogger.SAVE_UI_SHOWN_REASON_REQUIRED_ID_CHANGE; +import static com.android.server.autofill.SaveEventLogger.SAVE_UI_SHOWN_REASON_TRIGGER_ID_SET; +import static com.android.server.autofill.SaveEventLogger.SAVE_UI_SHOWN_REASON_UNKNOWN; import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS; import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE; @@ -457,6 +472,14 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState @GuardedBy("mLock") private FillResponseEventLogger mFillResponseEventLogger; + @NonNull + @GuardedBy("mLock") + private SaveEventLogger mSaveEventLogger; + + @NonNull + @GuardedBy("mLock") + private SessionCommittedEventLogger mSessionCommittedEventLogger; + /** * Fill dialog request would likely be sent slightly later. */ @@ -1327,6 +1350,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState mPresentationStatsEventLogger = PresentationStatsEventLogger.forSessionId(sessionId); mFillRequestEventLogger = FillRequestEventLogger.forSessionId(sessionId); mFillResponseEventLogger = FillResponseEventLogger.forSessionId(sessionId); + mSessionCommittedEventLogger = SessionCommittedEventLogger.forSessionId(sessionId); + mSaveEventLogger = SaveEventLogger.forSessionId(sessionId); synchronized (mLock) { mSessionFlags = new SessionFlags(); mSessionFlags.mAugmentedAutofillOnly = forAugmentedAutofillOnly; @@ -2048,6 +2073,12 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState @Override public void onSaveRequestSuccess(@NonNull String servicePackageName, @Nullable IntentSender intentSender) { + // Log onSaveRequest result. + mSaveEventLogger.maybeSetIsSaved(true); + final long saveRequestFinishTimestamp = SystemClock.elapsedRealtime() - mLatencyBaseTime; + mSaveEventLogger.maybeSetLatencySaveFinishMillis(saveRequestFinishTimestamp); + mSaveEventLogger.logAndEndEvent(); + synchronized (mLock) { mSessionFlags.mShowingSaveUi = false; @@ -2060,6 +2091,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState LogMaker log = newLogMaker(MetricsEvent.AUTOFILL_DATA_SAVE_REQUEST, servicePackageName) .setType(intentSender == null ? MetricsEvent.TYPE_SUCCESS : MetricsEvent.TYPE_OPEN); mMetricsLogger.write(log); + + if (intentSender != null) { if (sDebug) Slog.d(TAG, "Starting intent sender on save()"); startIntentSenderAndFinishSession(intentSender); @@ -2074,6 +2107,12 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState public void onSaveRequestFailure(@Nullable CharSequence message, @NonNull String servicePackageName) { boolean showMessage = !TextUtils.isEmpty(message); + + // Log onSaveRequest result. + final long saveRequestFinishTimestamp = SystemClock.elapsedRealtime() - mLatencyBaseTime; + mSaveEventLogger.maybeSetLatencySaveFinishMillis(saveRequestFinishTimestamp); + mSaveEventLogger.logAndEndEvent(); + synchronized (mLock) { mSessionFlags.mShowingSaveUi = false; @@ -2099,6 +2138,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } mMetricsLogger.write(log); + if (showMessage) { getUiForShowing().showError(message, this); } @@ -2188,13 +2228,17 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState // AutoFillUiCallback @Override public void save() { + mSaveEventLogger.maybeSetSaveButtonClicked(true); synchronized (mLock) { if (mDestroyed) { Slog.w(TAG, "Call to Session#save() rejected - session: " + id + " destroyed"); + mSaveEventLogger.logAndEndEvent(); return; } } + final long saveRequestStartTimestamp = SystemClock.elapsedRealtime() - mLatencyBaseTime; + mSaveEventLogger.maybeSetLatencySaveRequestMillis(saveRequestStartTimestamp); mHandler.sendMessage(obtainMessage( AutofillManagerServiceImpl::handleSessionSave, mService, this)); @@ -2203,12 +2247,14 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState // AutoFillUiCallback @Override public void cancelSave() { + mSaveEventLogger.maybeSetDialogDismissed(true); synchronized (mLock) { mSessionFlags.mShowingSaveUi = false; if (mDestroyed) { Slog.w(TAG, "Call to Session#cancelSave() rejected - session: " + id + " destroyed"); + mSaveEventLogger.logAndEndEvent(); return; } } @@ -3031,6 +3077,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState if (mDestroyed) { Slog.w(TAG, "Call to Session#showSaveLocked() rejected - session: " + id + " destroyed"); + mSaveEventLogger.maybeSetSaveUiNotShownReason(NO_SAVE_REASON_SESSION_DESTROYED); + mSaveEventLogger.logAndEndEvent(); return new SaveResult(/* logSaveShown= */ false, /* removeSession= */ false, Event.NO_SAVE_UI_REASON_NONE); } @@ -3050,6 +3098,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState */ if (saveInfo == null) { if (sVerbose) Slog.v(TAG, "showSaveLocked(" + this.id + "): no saveInfo from service"); + mSaveEventLogger.maybeSetSaveUiNotShownReason(NO_SAVE_REASON_NO_SAVE_INFO); + mSaveEventLogger.logAndEndEvent(); return new SaveResult(/* logSaveShown= */ false, /* removeSession= */ true, Event.NO_SAVE_UI_REASON_NO_SAVE_INFO); } @@ -3057,6 +3107,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState if ((saveInfo.getFlags() & SaveInfo.FLAG_DELAY_SAVE) != 0) { // TODO(b/113281366): log metrics if (sDebug) Slog.v(TAG, "showSaveLocked(" + this.id + "): service asked to delay save"); + mSaveEventLogger.maybeSetSaveUiNotShownReason(NO_SAVE_REASON_WITH_DELAY_SAVE_FLAG); + mSaveEventLogger.logAndEndEvent(); return new SaveResult(/* logSaveShown= */ false, /* removeSession= */ false, Event.NO_SAVE_UI_REASON_WITH_DELAY_SAVE_FLAG); } @@ -3130,6 +3182,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState + "didn't change: " + value); } changed = false; + } else { + mSaveEventLogger.maybeSetIsNewField(true); } } else { isUpdate = true; @@ -3153,6 +3207,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState int saveDialogNotShowReason; if (!allRequiredAreNotEmpty) { saveDialogNotShowReason = Event.NO_SAVE_UI_REASON_HAS_EMPTY_REQUIRED; + + mSaveEventLogger.maybeSetSaveUiNotShownReason(NO_SAVE_REASON_HAS_EMPTY_REQUIRED); + mSaveEventLogger.logAndEndEvent(); } else { // Must look up all optional ids in 2 scenarios: // - if no required id changed but an optional id did, it should trigger save / update @@ -3188,6 +3245,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } if (filledValue != null) { isUpdate = true; + } else { + mSaveEventLogger.maybeSetIsNewField(true); } atLeastOneChanged = true; } @@ -3206,6 +3265,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } if (!atLeastOneChanged) { saveDialogNotShowReason = Event.NO_SAVE_UI_REASON_NO_VALUE_CHANGED; + mSaveEventLogger.maybeSetSaveUiNotShownReason(NO_SAVE_REASON_NO_VALUE_CHANGED); + mSaveEventLogger.logAndEndEvent(); } else { if (sDebug) { Slog.d(TAG, "at least one field changed, validate fields for save UI"); @@ -3224,6 +3285,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState Slog.e(TAG, "Not showing save UI because validation failed:", e); log.setType(MetricsEvent.TYPE_FAILURE); mMetricsLogger.write(log); + mSaveEventLogger.maybeSetSaveUiNotShownReason( + NO_SAVE_REASON_FIELD_VALIDATION_FAILED); + mSaveEventLogger.logAndEndEvent(); return new SaveResult(/* logSaveShown= */ false, /* removeSession= */ true, Event.NO_SAVE_UI_REASON_FIELD_VALIDATION_FAILED); } @@ -3231,6 +3295,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState mMetricsLogger.write(log); if (!isValid) { Slog.i(TAG, "not showing save UI because fields failed validation"); + mSaveEventLogger.maybeSetSaveUiNotShownReason( + NO_SAVE_REASON_FIELD_VALIDATION_FAILED); + mSaveEventLogger.logAndEndEvent(); return new SaveResult(/* logSaveShown= */ false, /* removeSession= */ true, Event.NO_SAVE_UI_REASON_FIELD_VALIDATION_FAILED); } @@ -3271,6 +3338,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState Slog.d(TAG, "ignoring Save UI because all fields match contents of " + "dataset #" + i + ": " + dataset); } + mSaveEventLogger.maybeSetSaveUiNotShownReason(NO_SAVE_REASON_DATASET_MATCH); + mSaveEventLogger.logAndEndEvent(); return new SaveResult(/* logSaveShown= */ false, /* removeSession= */ true, Event.NO_SAVE_UI_REASON_DATASET_MATCH); } @@ -3292,14 +3361,18 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } if (serviceLabel == null || serviceIcon == null) { wtf(null, "showSaveLocked(): no service label or icon"); + mSaveEventLogger.maybeSetSaveUiNotShownReason(NO_SAVE_REASON_NONE); + mSaveEventLogger.logAndEndEvent(); return new SaveResult(/* logSaveShown= */ false, /* removeSession= */ true, Event.NO_SAVE_UI_REASON_NONE); } - + final long saveUiDisplayStartTimestamp = SystemClock.elapsedRealtime(); getUiForShowing().showSaveUi(serviceLabel, serviceIcon, mService.getServicePackageName(), saveInfo, this, mComponentName, this, mPendingSaveUi, isUpdate, mCompatMode, response.getShowSaveDialogIcon()); + mSaveEventLogger.maybeSetLatencySaveUiDisplayMillis( + SystemClock.elapsedRealtime()- saveUiDisplayStartTimestamp); if (client != null) { try { client.setSaveUiState(id, true); @@ -3471,11 +3544,15 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState if (mDestroyed) { Slog.w(TAG, "Call to Session#callSaveLocked() rejected - session: " + id + " destroyed"); + mSaveEventLogger.maybeSetIsSaved(false); + mSaveEventLogger.logAndEndEvent(); return; } if (mRemoteFillService == null) { wtf(null, "callSaveLocked() called without a remote service. " + "mForAugmentedAutofillOnly: %s", mSessionFlags.mAugmentedAutofillOnly); + mSaveEventLogger.maybeSetIsSaved(false); + mSaveEventLogger.logAndEndEvent(); return; } @@ -3483,6 +3560,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState if (mContexts == null) { Slog.w(TAG, "callSaveLocked(): no contexts"); + mSaveEventLogger.maybeSetIsSaved(false); + mSaveEventLogger.logAndEndEvent(); return; } @@ -3899,6 +3978,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState mPresentationStatsEventLogger.maybeSetRequestId(response.getRequestId()); mPresentationStatsEventLogger.maybeSetAvailableCount( response.getDatasets(), mCurrentViewId); + mFillResponseEventLogger.maybeSetAvailableCount( + response.getDatasets(), mCurrentViewId); } if (isSameViewEntered) { @@ -4069,6 +4150,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState if (mDestroyed) { Slog.w(TAG, "Call to Session#onFillReady() rejected - session: " + id + " destroyed"); + mSaveEventLogger.maybeSetSaveUiNotShownReason(NO_SAVE_REASON_SESSION_DESTROYED); + mSaveEventLogger.logAndEndEvent(); + mPresentationStatsEventLogger.maybeSetNoPresentationEventReason( + NOT_SHOWN_REASON_SESSION_COMMITTED_PREMATURELY); + mPresentationStatsEventLogger.logAndEndEvent(); return; } } @@ -4100,7 +4186,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState synchronized (mLock) { // Time passed since Session was created - long suggestionSentRelativeTimestamp = + final long suggestionSentRelativeTimestamp = SystemClock.elapsedRealtime() - mLatencyBaseTime; mPresentationStatsEventLogger.maybeSetSuggestionSentTimestampMs( (int) (suggestionSentRelativeTimestamp)); @@ -4468,10 +4554,19 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState saveTriggerId = saveInfo.getTriggerId(); if (saveTriggerId != null) { writeLog(MetricsEvent.AUTOFILL_EXPLICIT_SAVE_TRIGGER_DEFINITION); + mSaveEventLogger.maybeSetSaveUiShownReason(SAVE_UI_SHOWN_REASON_TRIGGER_ID_SET); } flags = saveInfo.getFlags(); mSaveOnAllViewsInvisible = (flags & SaveInfo.FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE) != 0; + mFillResponseEventLogger.maybeSetSaveUiTriggerIds(HAVE_SAVE_TRIGGER_ID); + + // Start to log Save event. + mSaveEventLogger.maybeSetRequestId(response.getRequestId()); + mSaveEventLogger.maybeSetAppPackageUid(uid); + mSaveEventLogger.maybeSetSaveUiTriggerIds(HAVE_SAVE_TRIGGER_ID); + mSaveEventLogger.maybeSetFlag(flags); + // We only need to track views if we want to save once they become invisible. if (mSaveOnAllViewsInvisible) { if (trackedViews == null) { @@ -4479,18 +4574,28 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } if (saveInfo.getRequiredIds() != null) { Collections.addAll(trackedViews, saveInfo.getRequiredIds()); + mSaveEventLogger.maybeSetSaveUiShownReason( + SAVE_UI_SHOWN_REASON_REQUIRED_ID_CHANGE); } if (saveInfo.getOptionalIds() != null) { Collections.addAll(trackedViews, saveInfo.getOptionalIds()); + mSaveEventLogger.maybeSetSaveUiShownReason( + SAVE_UI_SHOWN_REASON_OPTIONAL_ID_CHANGE); } } if ((flags & SaveInfo.FLAG_DONT_SAVE_ON_FINISH) != 0) { + mSaveEventLogger.maybeSetSaveUiShownReason( + SAVE_UI_SHOWN_REASON_UNKNOWN); + mSaveEventLogger.maybeSetSaveUiNotShownReason( + NO_SAVE_REASON_WITH_DONT_SAVE_ON_FINISH_FLAG); saveOnFinish = false; } } else { flags = 0; + mSaveEventLogger.maybeSetSaveUiNotShownReason( + NO_SAVE_REASON_NO_SAVE_INFO); saveTriggerId = null; }