Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c31a0125 authored by jiewenlei's avatar jiewenlei
Browse files

Add the logging of save event for Autofill framework.

Change-Id: I14e6441454e40fc3f323c4aba74fe63587c74bcd

Test: m
bug: 265051751
Change-Id: I694a68b467d9acca59cd21e5755a9d0bbf4c0200
parent e183b209
Loading
Loading
Loading
Loading
+9 −11
Original line number Diff line number Diff line
@@ -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<FillResponseEventInternal> mEventInternal;

+9 −6
Original line number Diff line number Diff line
@@ -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<SaveEventInternal> mEventInternal;
+107 −2
Original line number Diff line number Diff line
@@ -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;
        }