summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Kai Li <klikli@google.com> 2025-01-16 01:54:29 -0800
committer Kai Li <klikli@google.com> 2025-02-11 10:22:16 +0800
commitbbeb46cd34180be4d10f15405b15cc4660cedd06 (patch)
treeb48e9ca7c58e6b93553419da426ef2aa4adc4d78
parentada0f53c777a8275aeeca24360a539a7c5a9af72 (diff)
Send a FLUSH event after each frame.
This `notifyContentCaptureEvents` is called after the view traversal. The CC events are buffered in the `AttachInfo.mContentCaptureEvents` during the traversal. Send a FLUSH event at the end of the traversal to kick off the System Intelligence to process and rebuild the VH. Bug: 380381249 Change-Id: Ie0dd7c2511ff584b3c46035693359ed9df69660e Flag: android.view.contentcapture.flags.flush_after_each_frame Test: atest FrameworksCoreTests:android.view.contentcapture.MainContentCaptureSessionTest
-rw-r--r--core/java/android/view/contentcapture/MainContentCaptureSession.java4
-rw-r--r--core/java/android/view/contentcapture/flags/content_capture_flags.aconfig11
-rw-r--r--core/tests/coretests/src/android/view/contentcapture/MainContentCaptureSessionTest.java35
3 files changed, 50 insertions, 0 deletions
diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java
index 2fb78c038ca2..b66020b0c92b 100644
--- a/core/java/android/view/contentcapture/MainContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java
@@ -57,6 +57,7 @@ import android.view.View;
import android.view.ViewStructure;
import android.view.autofill.AutofillId;
import android.view.contentcapture.ViewNode.ViewStructureImpl;
+import android.view.contentcapture.flags.Flags;
import android.view.contentprotection.ContentProtectionEventProcessor;
import android.view.inputmethod.BaseInputConnection;
@@ -1008,6 +1009,9 @@ public final class MainContentCaptureSession extends ContentCaptureSession {
}
}
internalNotifyViewTreeEvent(sessionId, /* started= */ false);
+ if (Flags.flushAfterEachFrame()) {
+ internalNotifySessionFlushEvent(sessionId);
+ }
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
diff --git a/core/java/android/view/contentcapture/flags/content_capture_flags.aconfig b/core/java/android/view/contentcapture/flags/content_capture_flags.aconfig
index e7bc004ca2d2..8c98fa455cc8 100644
--- a/core/java/android/view/contentcapture/flags/content_capture_flags.aconfig
+++ b/core/java/android/view/contentcapture/flags/content_capture_flags.aconfig
@@ -15,3 +15,14 @@ flag {
bug: "380381249"
is_exported: true
}
+
+flag {
+ name: "flush_after_each_frame"
+ namespace: "pixel_state_server"
+ description: "Feature flag to send a flush event after each frame"
+ bug: "380381249"
+ is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/core/tests/coretests/src/android/view/contentcapture/MainContentCaptureSessionTest.java b/core/tests/coretests/src/android/view/contentcapture/MainContentCaptureSessionTest.java
index b42bcee77c67..5f89f9c14793 100644
--- a/core/tests/coretests/src/android/view/contentcapture/MainContentCaptureSessionTest.java
+++ b/core/tests/coretests/src/android/view/contentcapture/MainContentCaptureSessionTest.java
@@ -36,11 +36,15 @@ import android.content.pm.ParceledListSlice;
import android.graphics.Insets;
import android.os.Handler;
import android.os.RemoteException;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.SparseArray;
import android.view.View;
import android.view.autofill.AutofillId;
+import android.view.contentcapture.flags.Flags;
import android.view.contentprotection.ContentProtectionEventProcessor;
import androidx.test.core.app.ApplicationProvider;
@@ -90,6 +94,8 @@ public class MainContentCaptureSessionTest {
@Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+ @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
@Mock private IContentCaptureManager mMockSystemServerInterface;
@Mock private ContentProtectionEventProcessor mMockContentProtectionEventProcessor;
@@ -407,6 +413,7 @@ public class MainContentCaptureSessionTest {
}
@Test
+ @DisableFlags(Flags.FLAG_FLUSH_AFTER_EACH_FRAME)
@SuppressWarnings("GuardedBy")
public void notifyContentCaptureEvents_started_ContentCaptureEnabled_ProtectionEnabled()
throws RemoteException {
@@ -434,6 +441,34 @@ public class MainContentCaptureSessionTest {
}
@Test
+ @EnableFlags(Flags.FLAG_FLUSH_AFTER_EACH_FRAME)
+ @SuppressWarnings("GuardedBy")
+ public void notifyContentCaptureEvents_started_ContentCaptureEnabled_ProtectionEnabled_Flush()
+ throws RemoteException {
+ ContentCaptureOptions options =
+ createOptions(
+ /* enableContentCaptureReceiver= */ true,
+ /* enableContentProtectionReceiver= */ true);
+ MainContentCaptureSession session = createSession(options);
+ session.mDirectServiceInterface = mMockContentCaptureDirectManager;
+
+ session.onSessionStarted(0x2, null);
+ // Override the processor for interaction verification.
+ session.mContentProtectionEventProcessor = mMockContentProtectionEventProcessor;
+ notifyContentCaptureEvents(session);
+ mTestableLooper.processAllMessages();
+
+ // Force flush will happen twice.
+ verify(mMockContentCaptureDirectManager, times(1))
+ .sendEvents(any(), eq(FLUSH_REASON_VIEW_TREE_APPEARING), any());
+ verify(mMockContentCaptureDirectManager, times(1))
+ .sendEvents(any(), eq(FLUSH_REASON_VIEW_TREE_APPEARED), any());
+ // 5 view events + 2 view tree events + 1 flush event
+ verify(mMockContentProtectionEventProcessor, times(8)).processEvent(any());
+ assertThat(session.mEvents).isEmpty();
+ }
+
+ @Test
public void notifyViewAppearedBelowMaximumBufferSize() throws RemoteException {
ContentCaptureOptions options =
createOptions(