diff options
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( |