Merge changes from topics 'bug_62802026_take_2', 'bug_62802026' into oc-dev

* changes:
  Don't add FillEventHistory events to the wrong session.
  Fixed how FillEventHistory is reset and clarified javadoc.
diff --git a/core/java/android/service/autofill/AutofillService.java b/core/java/android/service/autofill/AutofillService.java
index 07c3503..394bd0a 100644
--- a/core/java/android/service/autofill/AutofillService.java
+++ b/core/java/android/service/autofill/AutofillService.java
@@ -208,12 +208,22 @@
     }
 
     /**
-     * Returns the {@link FillEventHistory.Event events} since the last {@link FillResponse} was
-     * returned.
+     * Gets the events that happened after the last
+     * {@link AutofillService#onFillRequest(FillRequest, android.os.CancellationSignal, FillCallback)}
+     * call.
      *
-     * <p>The history is not persisted over reboots.
+     * <p>This method is typically used to keep track of previous user actions to optimize further
+     * requests. For example, the service might return email addresses in alphabetical order by
+     * default, but change that order based on the address the user picked on previous requests.
      *
-     * @return The history or {@code null} if there are not events.
+     * <p>The history is not persisted over reboots, and it's cleared every time the service
+     * replies to a {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback)} by calling
+     * {@link FillCallback#onSuccess(FillResponse)} or {@link FillCallback#onFailure(CharSequence)}
+     * (if the service doesn't call any of these methods, the history will clear out after some
+     * pre-defined time). Hence, the service should call {@link #getFillEventHistory()} before
+     * finishing the {@link FillCallback}.
+     *
+     * @return The history or {@code null} if there are no events.
      */
     @Nullable public final FillEventHistory getFillEventHistory() {
         AutofillManager afm = getSystemService(AutofillManager.class);
diff --git a/core/java/android/service/autofill/FillEventHistory.java b/core/java/android/service/autofill/FillEventHistory.java
index 3d72fcc..f7dc1c5 100644
--- a/core/java/android/service/autofill/FillEventHistory.java
+++ b/core/java/android/service/autofill/FillEventHistory.java
@@ -33,7 +33,20 @@
 import java.util.List;
 
 /**
- * Describes what happened after the latest call to {@link FillCallback#onSuccess(FillResponse)}.
+ * Describes what happened after the last
+ * {@link AutofillService#onFillRequest(FillRequest, android.os.CancellationSignal, FillCallback)}
+ * call.
+ *
+ * <p>This history is typically used to keep track of previous user actions to optimize further
+ * requests. For example, the service might return email addresses in alphabetical order by
+ * default, but change that order based on the address the user picked on previous requests.
+ *
+ * <p>The history is not persisted over reboots, and it's cleared every time the service
+ * replies to a
+ * {@link AutofillService#onFillRequest(FillRequest, android.os.CancellationSignal, FillCallback)}
+ * by calling {@link FillCallback#onSuccess(FillResponse)} or
+ * {@link FillCallback#onFailure(CharSequence)} (if the service doesn't call any of these methods,
+ * the history will clear out after some pre-defined time).
  */
 public final class FillEventHistory implements Parcelable {
     /**
@@ -41,6 +54,11 @@
      */
     private final int mServiceUid;
 
+    /**
+     * Not in parcel. The ID of the autofill session that created the {@link FillResponse}.
+     */
+    private final int mSessionId;
+
     @Nullable private final Bundle mClientState;
     @Nullable List<Event> mEvents;
 
@@ -55,10 +73,17 @@
         return mServiceUid;
     }
 
+    /** @hide */
+    public int getSessionId() {
+        return mSessionId;
+    }
+
     /**
-     * Returns the client state of the {@link FillResponse}.
+     * Returns the client state set in the previous {@link FillResponse}.
      *
-     * @return The client state set by the last {@link FillResponse}
+     * <p><b>NOTE: </b>the state is associated with the app that was autofilled in the previous
+     * {@link AutofillService#onFillRequest(FillRequest, android.os.CancellationSignal, FillCallback)}
+     * , which is not necessary the same app being autofilled now.
      */
     @Nullable public Bundle getClientState() {
         return mClientState;
@@ -87,9 +112,10 @@
     /**
      * @hide
      */
-    public FillEventHistory(int serviceUid, @Nullable Bundle clientState) {
+    public FillEventHistory(int serviceUid, int sessionId, @Nullable Bundle clientState) {
         mClientState = clientState;
         mServiceUid = serviceUid;
+        mSessionId = sessionId;
     }
 
     @Override
@@ -190,7 +216,7 @@
             new Parcelable.Creator<FillEventHistory>() {
                 @Override
                 public FillEventHistory createFromParcel(Parcel parcel) {
-                    FillEventHistory selection = new FillEventHistory(0, parcel.readBundle());
+                    FillEventHistory selection = new FillEventHistory(0, 0, parcel.readBundle());
 
                     int numEvents = parcel.readInt();
                     for (int i = 0; i < numEvents; i++) {
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 38b796b..1a02e8d 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -489,46 +489,78 @@
      * Initializes the last fill selection after an autofill service returned a new
      * {@link FillResponse}.
      */
-    void setLastResponse(int serviceUid, @NonNull FillResponse response) {
+    void setLastResponse(int serviceUid, int sessionId, @NonNull FillResponse response) {
         synchronized (mLock) {
-            mEventHistory = new FillEventHistory(serviceUid, response.getClientState());
+            mEventHistory = new FillEventHistory(serviceUid, sessionId, response.getClientState());
         }
     }
 
     /**
+     * Resets the last fill selection.
+     */
+    void resetLastResponse() {
+        synchronized (mLock) {
+            mEventHistory = null;
+        }
+    }
+
+    private boolean isValidEventLocked(String method, int sessionId) {
+        if (mEventHistory == null) {
+            Slog.w(TAG, method + ": not logging event because history is null");
+            return false;
+        }
+        if (sessionId != mEventHistory.getSessionId()) {
+            if (sDebug) {
+                Slog.d(TAG, method + ": not logging event for session " + sessionId
+                        + " because tracked session is " + mEventHistory.getSessionId());
+            }
+            return false;
+        }
+        return true;
+    }
+
+    /**
      * Updates the last fill selection when an authentication was selected.
      */
-    void setAuthenticationSelected() {
+    void setAuthenticationSelected(int sessionId) {
         synchronized (mLock) {
-            mEventHistory.addEvent(new Event(Event.TYPE_AUTHENTICATION_SELECTED, null));
+            if (isValidEventLocked("setAuthenticationSelected()", sessionId)) {
+                mEventHistory.addEvent(new Event(Event.TYPE_AUTHENTICATION_SELECTED, null));
+            }
         }
     }
 
     /**
      * Updates the last fill selection when an dataset authentication was selected.
      */
-    void setDatasetAuthenticationSelected(@Nullable String selectedDataset) {
+    void setDatasetAuthenticationSelected(@Nullable String selectedDataset, int sessionId) {
         synchronized (mLock) {
-            mEventHistory.addEvent(
-                    new Event(Event.TYPE_DATASET_AUTHENTICATION_SELECTED, selectedDataset));
+            if (isValidEventLocked("setDatasetAuthenticationSelected()", sessionId)) {
+                mEventHistory.addEvent(
+                        new Event(Event.TYPE_DATASET_AUTHENTICATION_SELECTED, selectedDataset));
+            }
         }
     }
 
     /**
      * Updates the last fill selection when an save Ui is shown.
      */
-    void setSaveShown() {
+    void setSaveShown(int sessionId) {
         synchronized (mLock) {
-            mEventHistory.addEvent(new Event(Event.TYPE_SAVE_SHOWN, null));
+            if (isValidEventLocked("setSaveShown()", sessionId)) {
+                mEventHistory.addEvent(new Event(Event.TYPE_SAVE_SHOWN, null));
+            }
         }
     }
 
     /**
      * Updates the last fill response when a dataset was selected.
      */
-    void setDatasetSelected(@Nullable String selectedDataset) {
+    void setDatasetSelected(@Nullable String selectedDataset, int sessionId) {
         synchronized (mLock) {
-            mEventHistory.addEvent(new Event(Event.TYPE_DATASET_SELECTED, selectedDataset));
+            if (isValidEventLocked("setDatasetSelected()", sessionId)) {
+                mEventHistory.addEvent(new Event(Event.TYPE_DATASET_SELECTED, selectedDataset));
+            }
         }
     }
 
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index 9aebf6d..aebe92e 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -427,6 +427,7 @@
                     mCompleted = true;
                 }
 
+                Slog.w(LOG_TAG, getClass().getSimpleName() + " timed out");
                 final RemoteFillService remoteService = mWeakService.get();
                 if (remoteService != null) {
                     fail(remoteService);
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 3ae0511..72ad752 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -407,13 +407,14 @@
             if ((requestFlags & FLAG_MANUAL_REQUEST) != 0) {
                 getUiForShowing().showError(R.string.autofill_error_cannot_autofill, this);
             }
+            mService.resetLastResponse();
             // Nothing to be done, but need to notify client.
             notifyUnavailableToClient();
             removeSelf();
             return;
         }
 
-        mService.setLastResponse(serviceUid, response);
+        mService.setLastResponse(serviceUid, id, response);
 
         if ((response.getDatasets() == null || response.getDatasets().isEmpty())
                         && response.getAuthentication() == null) {
@@ -444,6 +445,7 @@
                         + id + " destroyed");
                 return;
             }
+            mService.resetLastResponse();
         }
         LogMaker log = (new LogMaker(MetricsEvent.AUTOFILL_REQUEST))
                 .setType(MetricsEvent.TYPE_FAILURE)
@@ -542,7 +544,7 @@
                     getFillContextByRequestIdLocked(requestId).getStructure(), extras);
         }
 
-        mService.setAuthenticationSelected();
+        mService.setAuthenticationSelected(id);
 
         final int authenticationId = AutofillManager.makeAuthenticationId(requestId, datasetIndex);
         mHandlerCaller.getHandler().post(() -> startAuthentication(authenticationId,
@@ -831,7 +833,7 @@
             }
             if (atLeastOneChanged) {
                 if (sDebug) Slog.d(TAG, "at least one field changed - showing save UI");
-                mService.setSaveShown();
+                mService.setSaveShown(id);
                 getUiForShowing().showSaveUi(mService.getServiceLabel(), saveInfo, mPackageName,
                         this);
 
@@ -1362,14 +1364,14 @@
             }
             // Autofill it directly...
             if (dataset.getAuthentication() == null) {
-                mService.setDatasetSelected(dataset.getId());
+                mService.setDatasetSelected(dataset.getId(), id);
 
                 autoFillApp(dataset);
                 return;
             }
 
             // ...or handle authentication.
-            mService.setDatasetAuthenticationSelected(dataset.getId());
+            mService.setDatasetAuthenticationSelected(dataset.getId(), id);
             setViewStatesLocked(null, dataset, ViewState.STATE_WAITING_DATASET_AUTH, false);
             final Intent fillInIntent = createAuthFillInIntent(
                     getFillContextByRequestIdLocked(requestId).getStructure(), mClientState);