[Autofill] Add new API for getting FillEventHistory

Introduce a new callback in AutofillService that is called when the
session is finished.

Bug: 370059095
Test: android.autofillservice.cts.commontests.FillEventHistoryCommonTestCase.test_onSessionDestroyed
Flag: android.service.autofill.autofill_session_destroyed
Change-Id: I2fcb7d7a1a5c55e4afec73acd37a4bf148f3040b
diff --git a/core/api/current.txt b/core/api/current.txt
index 38a0144..d797336 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -40889,13 +40889,14 @@
 
   public abstract class AutofillService extends android.app.Service {
     ctor public AutofillService();
-    method @Nullable public final android.service.autofill.FillEventHistory getFillEventHistory();
+    method @Deprecated @FlaggedApi("android.service.autofill.autofill_session_destroyed") @Nullable public final android.service.autofill.FillEventHistory getFillEventHistory();
     method public final android.os.IBinder onBind(android.content.Intent);
     method public void onConnected();
     method public void onDisconnected();
     method public abstract void onFillRequest(@NonNull android.service.autofill.FillRequest, @NonNull android.os.CancellationSignal, @NonNull android.service.autofill.FillCallback);
     method public abstract void onSaveRequest(@NonNull android.service.autofill.SaveRequest, @NonNull android.service.autofill.SaveCallback);
     method public void onSavedDatasetsInfoRequest(@NonNull android.service.autofill.SavedDatasetsInfoCallback);
+    method @FlaggedApi("android.service.autofill.autofill_session_destroyed") public void onSessionDestroyed(@Nullable android.service.autofill.FillEventHistory);
     field public static final String EXTRA_FILL_RESPONSE = "android.service.autofill.extra.FILL_RESPONSE";
     field public static final String SERVICE_INTERFACE = "android.service.autofill.AutofillService";
     field public static final String SERVICE_META_DATA = "android.autofill";
diff --git a/core/java/android/service/autofill/AutofillService.java b/core/java/android/service/autofill/AutofillService.java
index 269839b..2d922b4 100644
--- a/core/java/android/service/autofill/AutofillService.java
+++ b/core/java/android/service/autofill/AutofillService.java
@@ -15,9 +15,12 @@
  */
 package android.service.autofill;
 
+import static android.service.autofill.Flags.FLAG_AUTOFILL_SESSION_DESTROYED;
+
 import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
 
 import android.annotation.CallSuper;
+import android.annotation.FlaggedApi;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SdkConstant;
@@ -669,6 +672,14 @@
                     AutofillService.this,
                     new SavedDatasetsInfoCallbackImpl(receiver, SavedDatasetsInfo.TYPE_PASSWORDS)));
         }
+
+        @Override
+        public void onSessionDestroyed(@Nullable FillEventHistory history) {
+            mHandler.sendMessage(obtainMessage(
+                    AutofillService::onSessionDestroyed,
+                    AutofillService.this,
+                    history));
+        }
     };
 
     private Handler mHandler;
@@ -783,26 +794,42 @@
     }
 
     /**
-     * Gets the events that happened after the last
-     * {@link AutofillService#onFillRequest(FillRequest, android.os.CancellationSignal, FillCallback)}
+     * Called when an Autofill context has ended and the Autofill session is finished. This will be
+     * called as the last step of the Autofill lifecycle described in {@link AutofillManager}.
+     *
+     * <p>This will also contain the finished Session's FillEventHistory, so providers do not need
+     * to explicitly call {@link #getFillEventHistory()}
+     *
+     * <p>This will usually happens whenever {@link AutofillManager#commit()} or {@link
+     * AutofillManager#cancel()} is called.
+     */
+    @FlaggedApi(FLAG_AUTOFILL_SESSION_DESTROYED)
+    public void onSessionDestroyed(@Nullable FillEventHistory history) {}
+
+    /**
+     * Gets the events that happened after the last {@link
+     * AutofillService#onFillRequest(FillRequest, android.os.CancellationSignal, FillCallback)}
      * call.
      *
      * <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.
      *
-     * <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}.
+     * <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.
-     *
      * @throws RuntimeException if the event history could not be retrieved.
+     * @deprecated Use {@link #onSessionDestroyed(FillEventHistory) instead}
      */
-    @Nullable public final FillEventHistory getFillEventHistory() {
+    @FlaggedApi(FLAG_AUTOFILL_SESSION_DESTROYED)
+    @Deprecated
+    @Nullable
+    public final FillEventHistory getFillEventHistory() {
         final AutofillManager afm = getSystemService(AutofillManager.class);
 
         if (afm == null) {
diff --git a/core/java/android/service/autofill/IAutoFillService.aidl b/core/java/android/service/autofill/IAutoFillService.aidl
index 3b64b8a..71b75e7 100644
--- a/core/java/android/service/autofill/IAutoFillService.aidl
+++ b/core/java/android/service/autofill/IAutoFillService.aidl
@@ -25,6 +25,8 @@
 import android.service.autofill.SaveRequest;
 import com.android.internal.os.IResultReceiver;
 
+parcelable FillEventHistory;
+
 /**
  * Interface from the system to an auto fill service.
  *
@@ -38,4 +40,5 @@
     void onSaveRequest(in SaveRequest request, in ISaveCallback callback);
     void onSavedPasswordCountRequest(in IResultReceiver receiver);
     void onConvertCredentialRequest(in ConvertCredentialRequest convertCredentialRequest, in IConvertCredentialCallback convertCredentialCallback);
+    void onSessionDestroyed(in FillEventHistory history);
 }
diff --git a/services/autofill/features.aconfig b/services/autofill/features.aconfig
index 444844121..80ccb03 100644
--- a/services/autofill/features.aconfig
+++ b/services/autofill/features.aconfig
@@ -2,6 +2,13 @@
 container: "system"
 
 flag {
+  name: "autofill_session_destroyed"
+  namespace: "autofill"
+  description: "Guards against new metrics definitions introduced in W"
+  bug: "342676602"
+}
+
+flag {
   name: "autofill_w_metrics"
   namespace: "autofill"
   description: "Guards against new metrics definitions introduced in W"
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index cd4ace2..5cf96bf 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -61,6 +61,7 @@
 import android.service.autofill.FillEventHistory.Event;
 import android.service.autofill.FillEventHistory.Event.NoSaveReason;
 import android.service.autofill.FillResponse;
+import android.service.autofill.Flags;
 import android.service.autofill.IAutoFillService;
 import android.service.autofill.InlineSuggestionRenderService;
 import android.service.autofill.SaveInfo;
@@ -100,6 +101,7 @@
 import java.util.List;
 import java.util.Objects;
 import java.util.Random;
+
 /**
  * Bridge between the {@code system_server}'s {@link AutofillManagerService} and the
  * app's {@link IAutoFillService} implementation.
@@ -748,6 +750,22 @@
     @GuardedBy("mLock")
     void removeSessionLocked(int sessionId) {
         mSessions.remove(sessionId);
+        if (Flags.autofillSessionDestroyed()) {
+            if (sVerbose) {
+                Slog.v(
+                        TAG,
+                        "removeSessionLocked(): removed " + sessionId);
+            }
+            RemoteFillService remoteService =
+                    new RemoteFillService(
+                            getContext(),
+                            mInfo.getServiceInfo().getComponentName(),
+                            mUserId,
+                            /* callbacks= */ null,
+                            mMaster.isInstantServiceAllowed(),
+                            /* credentialAutofillService= */ null);
+            remoteService.onSessionDestroyed(null);
+        }
     }
 
     /**
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index 07f5dcc..f1e8884 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -34,6 +34,7 @@
 import android.service.autofill.AutofillService;
 import android.service.autofill.ConvertCredentialRequest;
 import android.service.autofill.ConvertCredentialResponse;
+import android.service.autofill.FillEventHistory;
 import android.service.autofill.FillRequest;
 import android.service.autofill.FillResponse;
 import android.service.autofill.IAutoFillService;
@@ -497,6 +498,14 @@
                 }));
     }
 
+    public void onSessionDestroyed(@Nullable FillEventHistory history) {
+        boolean success = run(service -> {
+            service.onSessionDestroyed(history);
+        });
+
+        if (sVerbose) Slog.v(TAG, "called onSessionDestroyed(): " + success);
+    }
+
     void onSavedPasswordCountRequest(IResultReceiver receiver) {
         run(service -> service.onSavedPasswordCountRequest(receiver));
     }