Ignore ContentCapture events after the activity stopped.

Test: atest CtsContentCaptureServiceTestCases
Bug: 121033016

Change-Id: I016f13748287f77b7c5f0ceb12a5af1bb2b555ea
diff --git a/core/java/android/view/contentcapture/ContentCaptureSession.java b/core/java/android/view/contentcapture/ContentCaptureSession.java
index 9f666a4..fb6cacf 100644
--- a/core/java/android/view/contentcapture/ContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/ContentCaptureSession.java
@@ -34,6 +34,7 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.UUID;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
  * Session used to notify a system-provided Content Capture service about events associated with
@@ -90,6 +91,12 @@
 
     private final CloseGuard mCloseGuard = CloseGuard.get();
 
+    /**
+     * Guard use to ignore events after it's destroyed.
+     */
+    @NonNull
+    private final AtomicBoolean mDestroyed = new AtomicBoolean();
+
     /** @hide */
     @Nullable
     protected final String mId = UUID.randomUUID().toString();
@@ -157,10 +164,10 @@
      * <p>Once destroyed, any new notification will be dropped.
      */
     public final void destroy() {
-        //TODO(b/111276913): mark it as destroyed so other methods are ignored (and test on CTS)
-
-        //TODO(b/111276913): probably shouldn't check for it
-        if (!isContentCaptureEnabled()) return;
+        if (!mDestroyed.compareAndSet(false, true)) {
+            Log.e(mTag, "destroy(): already destroyed");
+            return;
+        }
 
         mCloseGuard.close();
 
@@ -298,10 +305,13 @@
         return new ViewNode.ViewStructureImpl(parentId, virtualId);
     }
 
-    abstract boolean isContentCaptureEnabled();
+    boolean isContentCaptureEnabled() {
+        return !mDestroyed.get();
+    }
 
     @CallSuper
     void dump(@NonNull String prefix, @NonNull PrintWriter pw) {
+        pw.print(prefix); pw.print("destroyed: "); pw.println(mDestroyed.get());
         if (mChildren != null && !mChildren.isEmpty()) {
             final String prefix2 = prefix + "  ";
             final int numberChildren = mChildren.size();
diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java
index 92e0187..12c50ce 100644
--- a/core/java/android/view/contentcapture/MainContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java
@@ -219,7 +219,7 @@
     /**
      * Callback from {@code system_server} after call to
      * {@link IContentCaptureManager#startSession(int, IBinder, ComponentName, String,
-     * ContentCaptureContext, int, IResultReceiver)}.
+     * int, IResultReceiver)}.
      *
      * @param resultCode session state
      * @param binder handle to {@code IContentCaptureDirectManager}
@@ -425,7 +425,8 @@
 
     @Override
     boolean isContentCaptureEnabled() {
-        return mSystemServerInterface != null && !mDisabled.get();
+        return super.isContentCaptureEnabled() && mSystemServerInterface != null
+                && !mDisabled.get();
     }
 
     // TODO(b/121033016): refactor "notifyXXXX" methods below to a common "Buffer" object that is