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

Commit 799131ca authored by Tim Yu's avatar Tim Yu Committed by Android (Google) Code Review
Browse files

Merge "[Autofill] Fix overridden metrics" into main

parents 24630204 d578d7d3
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -86,3 +86,13 @@ flag {
  description: "Highlight single field after autofill selection"
  bug: "41496744"
}

flag {
  name: "metrics_fixes"
  namespace: "autofill"
  description: "Fixes various framework reported metrics"
  bug: "362581326, 363011343"
  metadata {
    purpose: PURPOSE_BUGFIX
  }
}
+40 −5
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_
import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_NO_FOCUS;
import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_REQUEST_TIMEOUT;
import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_SESSION_COMMITTED_PREMATURELY;
import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_SUGGESTION_FILTER_OUT;
import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_UNKNOWN_REASON;
import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_VIEW_CHANGED;
import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_VIEW_FOCUSED_BEFORE_FILL_DIALOG_RESPONSE;
@@ -98,6 +99,7 @@ public final class PresentationStatsEventLogger {
            NOT_SHOWN_REASON_REQUEST_FAILED,
            NOT_SHOWN_REASON_NO_FOCUS,
            NOT_SHOWN_REASON_SESSION_COMMITTED_PREMATURELY,
            NOT_SHOWN_REASON_SUGGESTION_FILTERED,
            NOT_SHOWN_REASON_UNKNOWN
    })
    @Retention(RetentionPolicy.SOURCE)
@@ -178,6 +180,8 @@ public final class PresentationStatsEventLogger {
            AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_SESSION_COMMITTED_PREMATURELY;
    public static final int NOT_SHOWN_REASON_UNKNOWN =
            AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_UNKNOWN_REASON;
    public static final int NOT_SHOWN_REASON_SUGGESTION_FILTERED =
            AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_SUGGESTION_FILTER_OUT;

    public static final int AUTHENTICATION_TYPE_UNKNOWN =
            AUTOFILL_PRESENTATION_EVENT_REPORTED__AUTHENTICATION_TYPE__AUTHENTICATION_TYPE_UNKNOWN;
@@ -286,11 +290,42 @@ public final class PresentationStatsEventLogger {
        });
    }

    /**
     * Call this when first entering the View. It will check if there are pre-existing characters
     * in the view, and sets NOT_SHOWN_REASON_SUGGESTION_FILTERED if there is
     */
    public void maybeSetNoPresentationEventReasonSuggestionsFiltered(AutofillValue value) {
        mEventInternal.ifPresent(
                event -> {
                    if (value == null || !value.isText()) {
                        return;
                    }

                    int length = value.getTextValue().length();

                    if (length > 0) {
                        maybeSetNoPresentationEventReason(NOT_SHOWN_REASON_SUGGESTION_FILTERED);
                    }
                });
    }

    public void maybeSetNoPresentationEventReasonIfNoReasonExists(@NotShownReason int reason) {
        mEventInternal.ifPresent(event -> {
            if (event.mCountShown == 0 && event.mNoPresentationReason == NOT_SHOWN_REASON_UNKNOWN) {
                event.mNoPresentationReason = reason;
        mEventInternal.ifPresent(
                event -> {
                    if (event.mCountShown != 0) {
                        return;
                    }

                    // The only events that can be overwritten.
                    // NOT_SHOWN_REASON_UNKNOWN is the default for inline/dropdown
                    // NOT_SHOWN_REASON_NO_FOCUS is the default for fill dialog
                    if (event.mNoPresentationReason != NOT_SHOWN_REASON_UNKNOWN
                            || event.mNoPresentationReason != NOT_SHOWN_REASON_NO_FOCUS) {
                        Slog.d(TAG, "Not setting no presentation reason because it already exists");
                        return;
                    }

                    event.mNoPresentationReason = reason;
                });
    }

+41 −10
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import static android.service.autofill.FillRequest.FLAG_VIEW_REQUESTS_CREDMAN_SE
import static android.service.autofill.FillRequest.INVALID_REQUEST_ID;
import static android.service.autofill.Flags.highlightAutofillSingleField;
import static android.service.autofill.Flags.improveFillDialogAconfig;
import static android.service.autofill.Flags.metricsFixes;
import static android.view.autofill.AutofillManager.ACTION_RESPONSE_EXPIRED;
import static android.view.autofill.AutofillManager.ACTION_START_SESSION;
import static android.view.autofill.AutofillManager.ACTION_VALUE_CHANGED;
@@ -3741,8 +3742,13 @@ final class Session
        final FillResponse lastResponse = getLastResponseLocked("logContextCommited(%s)");
        if (lastResponse == null) return;

        if (metricsFixes()) {
            mPresentationStatsEventLogger.maybeSetNoPresentationEventReasonIfNoReasonExists(
                    PresentationStatsEventLogger.getNoPresentationEventReason(commitReason));
        } else {
            mPresentationStatsEventLogger.maybeSetNoPresentationEventReason(
                    PresentationStatsEventLogger.getNoPresentationEventReason(commitReason));
        }
        mPresentationStatsEventLogger.logAndEndEvent("Context committed");

        final int flags = lastResponse.getFlags();
@@ -5125,6 +5131,13 @@ final class Session
                    mPreviouslyFillDialogPotentiallyStarted = false;
                } else {
                    mPreviouslyFillDialogPotentiallyStarted = true;
                    if (metricsFixes()) {
                        // Set the default reason for now if the user doesn't trigger any focus
                        // event on the autofillable view. This can be changed downstream when
                        // more information is available or session is committed.
                        mPresentationStatsEventLogger.maybeSetNoPresentationEventReason(
                                NOT_SHOWN_REASON_NO_FOCUS);
                    }
                }
                Optional<Integer> maybeRequestId =
                        requestNewFillResponseLocked(
@@ -5291,6 +5304,10 @@ final class Session
                    if (maybeNewRequestId.isPresent()) {
                        mPresentationStatsEventLogger.maybeSetRequestId(maybeNewRequestId.get());
                    }
                    if (metricsFixes()) {
                        mPresentationStatsEventLogger
                                .maybeSetNoPresentationEventReasonSuggestionsFiltered(value);
                    }
                }

                logPresentationStatsOnViewEnteredLocked(
@@ -5325,9 +5342,15 @@ final class Session

                    // It's not necessary that there's no more presentation for this view. It could
                    // be that the user chose some suggestion, in which case, view exits.
                    if (metricsFixes()) {
                        mPresentationStatsEventLogger
                                .maybeSetNoPresentationEventReasonIfNoReasonExists(
                                        NOT_SHOWN_REASON_VIEW_FOCUS_CHANGED);
                    } else {
                        mPresentationStatsEventLogger.maybeSetNoPresentationEventReason(
                                NOT_SHOWN_REASON_VIEW_FOCUS_CHANGED);
                    }
                }
                break;
            default:
                Slog.w(TAG, "updateLocked(): unknown action: " + action);
@@ -6935,11 +6958,15 @@ final class Session
    private void startNewEventForPresentationStatsEventLogger() {
        synchronized (mLock) {
            mPresentationStatsEventLogger.startNewEvent();
            // This is a fill dialog only state, moved to when we set
            // mPreviouslyFillDialogPotentiallyStarted = true
            if (!metricsFixes()) {
                // Set the default reason for now if the user doesn't trigger any focus event
                // on the autofillable view. This can be changed downstream when more
                // information is available or session is committed.
                mPresentationStatsEventLogger.maybeSetNoPresentationEventReason(
                        NOT_SHOWN_REASON_NO_FOCUS);
            }
            mPresentationStatsEventLogger.maybeSetDetectionPreference(
                    getDetectionPreferenceForLogging());
            mPresentationStatsEventLogger.maybeSetAutofillServiceUid(getAutofillServiceUid());
@@ -7696,7 +7723,11 @@ final class Session
        if (sVerbose) {
            Slog.v(TAG, "logAllEvents(" + id + "): commitReason: " + val);
        }
        if (metricsFixes()) {
            mSessionCommittedEventLogger.maybeSetCommitReasonIfUnset(val);
        } else {
            mSessionCommittedEventLogger.maybeSetCommitReason(val);
        }
        mSessionCommittedEventLogger.maybeSetRequestCount(mRequestCount);
        mSessionCommittedEventLogger.maybeSetSessionDurationMillis(
                SystemClock.elapsedRealtime() - mStartTime);
+11 −0
Original line number Diff line number Diff line
@@ -76,6 +76,17 @@ public final class SessionCommittedEventLogger {
    });
  }

  /** Set commit_reason if not already set */
  public void maybeSetCommitReasonIfUnset(@AutofillCommitReason int val) {
      mEventInternal.ifPresent(
          event -> {
            if (event.mCommitReason != COMMIT_REASON_UNKNOWN) {
              return;
            }
            event.mCommitReason = val;
          });
  }

  /**
   * Set session_duration_millis as long as mEventInternal presents.
   */
+55 −0
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
 */
package com.android.server.autofill;

import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_SUGGESTION_FILTER_OUT;
import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_VIEW_CHANGED;

import static com.google.common.truth.Truth.assertThat;

@@ -129,4 +131,57 @@ public class PresentationEventLoggerTest {
        assertThat(event).isNotNull();
        assertThat(event.mDisplayPresentationType).isEqualTo(3);
    }

    @Test
    public void testNoSuggestionsTextFiltered() {
        PresentationStatsEventLogger pEventLogger =
                PresentationStatsEventLogger.createPresentationLog(1, 1, 1);
        AutofillId id = new AutofillId(13);
        AutofillValue initialValue = AutofillValue.forText("hello");
        pEventLogger.startNewEvent();
        pEventLogger.maybeSetFocusedId(id);
        pEventLogger.maybeSetNoPresentationEventReasonSuggestionsFiltered(initialValue);

        PresentationStatsEventLogger.PresentationStatsEventInternal event =
                pEventLogger.getInternalEvent().get();
        assertThat(event).isNotNull();
        int NO_SUGGESTIONS =
                AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_SUGGESTION_FILTER_OUT;
        assertThat(event.mNoPresentationReason).isEqualTo(NO_SUGGESTIONS);
    }

    @Test
    public void testSuggestionsTextNotFiltered() {
        PresentationStatsEventLogger pEventLogger =
                PresentationStatsEventLogger.createPresentationLog(1, 1, 1);
        AutofillId id = new AutofillId(13);
        AutofillValue initialValue = null;
        pEventLogger.startNewEvent();
        pEventLogger.maybeSetFocusedId(id);
        pEventLogger.maybeSetNoPresentationEventReasonSuggestionsFiltered(initialValue);

        PresentationStatsEventLogger.PresentationStatsEventInternal event =
                pEventLogger.getInternalEvent().get();
        assertThat(event).isNotNull();
        assertThat(event.mNoPresentationReason).isNotEqualTo(
                AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_SUGGESTION_FILTER_OUT);
    }

    @Test
    public void testNotShownReasonNotOverridden() {

        PresentationStatsEventLogger pEventLogger =
                PresentationStatsEventLogger.createPresentationLog(1, 1, 1);

        pEventLogger.startNewEvent();
        pEventLogger.maybeSetNoPresentationEventReason(AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_VIEW_CHANGED);
        // Not allowed - no op
        pEventLogger.maybeSetNoPresentationEventReasonIfNoReasonExists(
                AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_SUGGESTION_FILTER_OUT);

        PresentationStatsEventLogger.PresentationStatsEventInternal event =
                pEventLogger.getInternalEvent().get();
        assertThat(event).isNotNull();
        assertThat(event.mNoPresentationReason).isEqualTo(AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_VIEW_CHANGED);
    }
}