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

Commit f29535ec authored by Tim Yu's avatar Tim Yu
Browse files

Autofill Fix latency_save_ui_display_millis

Update latency to track relative to Session start

Fixes: 336912934
Test: com.android.server.autofill.SaveEventLoggerTest
Change-Id: Ie33c302ed93e94312ce562764aac779d527d98ec
parent 541563a6
Loading
Loading
Loading
Loading
+36 −9
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ 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.os.SystemClock;
import android.util.Slog;

import com.android.internal.util.FrameworkStatsLog;
@@ -45,7 +46,7 @@ import java.util.Optional;
/**
 * Helper class to log Autofill Save event stats.
 */
public final class SaveEventLogger {
public class SaveEventLogger {
  private static final String TAG = "SaveEventLogger";

  /**
@@ -112,19 +113,21 @@ public final class SaveEventLogger {
  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;

  public static final long UNINITIATED_TIMESTAMP = Long.MIN_VALUE;

  private final int mSessionId;
  private Optional<SaveEventInternal> mEventInternal;
  private long mSessionStartTimestamp;

  private SaveEventLogger(int sessionId) {
  private SaveEventLogger(int sessionId, long sessionStartTimestamp) {
      mSessionId = sessionId;
      mEventInternal = Optional.of(new SaveEventInternal());
      mSessionStartTimestamp = sessionStartTimestamp;
  }

  /**
   * A factory constructor to create FillRequestEventLogger.
   */
  public static SaveEventLogger forSessionId(int sessionId) {
    return new SaveEventLogger(sessionId);
  /** A factory constructor to create FillRequestEventLogger. */
  public static SaveEventLogger forSessionId(int sessionId, long sessionStartTimestamp) {
        return new SaveEventLogger(sessionId, sessionStartTimestamp);
  }

  /**
@@ -224,6 +227,15 @@ public final class SaveEventLogger {
    });
  }

  /* Returns timestamp (relative to mSessionStartTimestamp) or  UNINITIATED_TIMESTAMP if mSessionStartTimestamp is not set */
  private long getCurrentTimestamp() {
    long timestamp = UNINITIATED_TIMESTAMP;
    if (mSessionStartTimestamp != UNINITIATED_TIMESTAMP) {
      timestamp = SystemClock.elapsedRealtime() - mSessionStartTimestamp;
    }
    return timestamp;
  }

  /**
   * Set latency_save_ui_display_millis as long as mEventInternal presents.
   */
@@ -233,6 +245,11 @@ public final class SaveEventLogger {
    });
  }

  /** Set latency_save_ui_display_millis as long as mEventInternal presents. */
  public void maybeSetLatencySaveUiDisplayMillis() {
    maybeSetLatencySaveUiDisplayMillis(getCurrentTimestamp());
  }

  /**
   * Set latency_save_request_millis as long as mEventInternal presents.
   */
@@ -242,6 +259,11 @@ public final class SaveEventLogger {
    });
  }

  /** Set latency_save_request_millis as long as mEventInternal presents. */
  public void maybeSetLatencySaveRequestMillis() {
    maybeSetLatencySaveRequestMillis(getCurrentTimestamp());
  }

  /**
   * Set latency_save_finish_millis as long as mEventInternal presents.
   */
@@ -251,6 +273,11 @@ public final class SaveEventLogger {
    });
  }

  /** Set latency_save_finish_millis as long as mEventInternal presents. */
  public void maybeSetLatencySaveFinishMillis() {
    maybeSetLatencySaveFinishMillis(getCurrentTimestamp());
  }

  /**
   * Set is_framework_created_save_info as long as mEventInternal presents.
   */
+1 −4
Original line number Diff line number Diff line
@@ -1531,7 +1531,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
        mFillResponseEventLogger = FillResponseEventLogger.forSessionId(sessionId);
        mSessionCommittedEventLogger = SessionCommittedEventLogger.forSessionId(sessionId);
        mSessionCommittedEventLogger.maybeSetComponentPackageUid(uid);
        mSaveEventLogger = SaveEventLogger.forSessionId(sessionId);
        mSaveEventLogger = SaveEventLogger.forSessionId(sessionId, mLatencyBaseTime);
        mIsPrimaryCredential = isPrimaryCredential;
        mIgnoreViewStateResetToEmpty = AutofillFeatureFlags.shouldIgnoreViewStateResetToEmpty();

@@ -3931,13 +3931,10 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
                    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, mContext,  mPendingSaveUi, isUpdate, mCompatMode,
                        response.getShowSaveDialogIcon(), mSaveEventLogger);
                mSaveEventLogger.maybeSetLatencySaveUiDisplayMillis(
                    SystemClock.elapsedRealtime()- saveUiDisplayStartTimestamp);
                if (client != null) {
                    try {
                        client.setSaveUiState(id, true);
+2 −0
Original line number Diff line number Diff line
@@ -413,6 +413,8 @@ public final class AutoFillUI {
                    callback.startIntentSender(intentSender, intent);
                }
            }, mUiModeMgr.isNightMode(), isUpdate, compatMode, showServiceIcon);

            mSaveEventLogger.maybeSetLatencySaveUiDisplayMillis();
        });
    }

+85 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.server.autofill;

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

import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.ArgumentCaptor;

@RunWith(JUnit4.class)
public class SaveEventLoggerTest {

    @Test
    public void testTimestampsInitialized() {
        SaveEventLogger mLogger = spy(SaveEventLogger.forSessionId(1, 1));

        mLogger.maybeSetLatencySaveUiDisplayMillis();
        mLogger.maybeSetLatencySaveRequestMillis();
        mLogger.maybeSetLatencySaveFinishMillis();

        ArgumentCaptor<Long> latencySaveUiDisplayMillis = ArgumentCaptor.forClass(Long.class);
        ArgumentCaptor<Long> latencySaveRequestMillis = ArgumentCaptor.forClass(Long.class);
        ArgumentCaptor<Long> latencySaveFinishMillis = ArgumentCaptor.forClass(Long.class);

        verify(mLogger, times(1))
                .maybeSetLatencySaveUiDisplayMillis(latencySaveUiDisplayMillis.capture());
        verify(mLogger, times(1))
                .maybeSetLatencySaveRequestMillis(latencySaveRequestMillis.capture());
        verify(mLogger, times(1))
                .maybeSetLatencySaveFinishMillis(latencySaveFinishMillis.capture());

        assertThat(latencySaveUiDisplayMillis.getValue())
                .isNotEqualTo(SaveEventLogger.UNINITIATED_TIMESTAMP);
        assertThat(latencySaveRequestMillis.getValue())
                .isNotEqualTo(SaveEventLogger.UNINITIATED_TIMESTAMP);
        assertThat(latencySaveFinishMillis.getValue())
                .isNotEqualTo(SaveEventLogger.UNINITIATED_TIMESTAMP);
    }

    @Test
    public void testTimestampsNotInitialized() {
        SaveEventLogger mLogger =
                spy(SaveEventLogger.forSessionId(1, SaveEventLogger.UNINITIATED_TIMESTAMP));

        mLogger.maybeSetLatencySaveUiDisplayMillis();
        mLogger.maybeSetLatencySaveRequestMillis();
        mLogger.maybeSetLatencySaveFinishMillis();
        ArgumentCaptor<Long> latencySaveUiDisplayMillis = ArgumentCaptor.forClass(Long.class);
        ArgumentCaptor<Long> latencySaveRequestMillis = ArgumentCaptor.forClass(Long.class);
        ArgumentCaptor<Long> latencySaveFinishMillis = ArgumentCaptor.forClass(Long.class);

        verify(mLogger, times(1))
                .maybeSetLatencySaveUiDisplayMillis(latencySaveUiDisplayMillis.capture());
        verify(mLogger, times(1))
                .maybeSetLatencySaveRequestMillis(latencySaveRequestMillis.capture());
        verify(mLogger, times(1))
                .maybeSetLatencySaveFinishMillis(latencySaveFinishMillis.capture());

        assertThat(latencySaveUiDisplayMillis.getValue())
                .isEqualTo(SaveEventLogger.UNINITIATED_TIMESTAMP);
        assertThat(latencySaveRequestMillis.getValue())
                .isEqualTo(SaveEventLogger.UNINITIATED_TIMESTAMP);
        assertThat(latencySaveFinishMillis.getValue())
                .isEqualTo(SaveEventLogger.UNINITIATED_TIMESTAMP);
    }
}