diff options
| -rw-r--r-- | core/java/android/view/contentcapture/ContentCaptureManager.java | 28 | ||||
| -rw-r--r-- | core/tests/coretests/src/android/view/contentcapture/ContentCaptureManagerTest.java | 89 |
2 files changed, 108 insertions, 9 deletions
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java index c37e311209df..c9afdc0ad074 100644 --- a/core/java/android/view/contentcapture/ContentCaptureManager.java +++ b/core/java/android/view/contentcapture/ContentCaptureManager.java @@ -52,6 +52,7 @@ import android.view.contentcapture.ContentCaptureSession.FlushReason; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.RingBuffer; import com.android.internal.util.SyncResultReceiver; import java.io.PrintWriter; @@ -446,6 +447,9 @@ public final class ContentCaptureManager { @Nullable // set on-demand by addDumpable() private Dumper mDumpable; + // Created here in order to live across activity and session changes + @Nullable private final RingBuffer<ContentCaptureEvent> mContentProtectionEventBuffer; + /** @hide */ public interface ContentCaptureClient { /** @@ -456,12 +460,15 @@ public final class ContentCaptureManager { } /** @hide */ - static class StrippedContext { + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) + public static class StrippedContext { @NonNull final String mPackageName; @NonNull final String mContext; final @UserIdInt int mUserId; - private StrippedContext(@NonNull Context context) { + /** @hide */ + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) + public StrippedContext(@NonNull Context context) { mPackageName = context.getPackageName(); mContext = context.toString(); mUserId = context.getUserId(); @@ -502,6 +509,16 @@ public final class ContentCaptureManager { mHandler = Handler.createAsync(Looper.getMainLooper()); mDataShareAdapterResourceManager = new LocalDataShareAdapterResourceManager(); + + if (mOptions.contentProtectionOptions.enableReceiver + && mOptions.contentProtectionOptions.bufferSize > 0) { + mContentProtectionEventBuffer = + new RingBuffer( + ContentCaptureEvent.class, + mOptions.contentProtectionOptions.bufferSize); + } else { + mContentProtectionEventBuffer = null; + } } /** @@ -870,6 +887,13 @@ public final class ContentCaptureManager { activity.addDumpable(mDumpable); } + /** @hide */ + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) + @Nullable + public RingBuffer<ContentCaptureEvent> getContentProtectionEventBuffer() { + return mContentProtectionEventBuffer; + } + // NOTE: ContentCaptureManager cannot implement it directly as it would be exposed as public API private final class Dumper implements Dumpable { @Override diff --git a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureManagerTest.java b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureManagerTest.java index 17ed4c478350..101f7c21fa19 100644 --- a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureManagerTest.java +++ b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureManagerTest.java @@ -15,14 +15,17 @@ */ package android.view.contentcapture; +import static android.view.contentcapture.ContentCaptureEvent.TYPE_SESSION_STARTED; + import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Mockito.mock; import static org.testng.Assert.assertThrows; import android.content.ContentCaptureOptions; import android.content.Context; +import com.android.internal.util.RingBuffer; + import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -37,9 +40,15 @@ import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class ContentCaptureManagerTest { + private static final int BUFFER_SIZE = 100; + + private static final ContentCaptureOptions EMPTY_OPTIONS = new ContentCaptureOptions(null); + @Mock private Context mMockContext; + @Mock private IContentCaptureManager mMockContentCaptureManager; + @Test public void testConstructor_invalidParametersThrowsException() { assertThrows(NullPointerException.class, @@ -48,11 +57,65 @@ public class ContentCaptureManagerTest { } @Test + public void testConstructor_contentProtection_default_bufferNotCreated() { + ContentCaptureManager manager = + new ContentCaptureManager(mMockContext, mMockContentCaptureManager, EMPTY_OPTIONS); + + assertThat(manager.getContentProtectionEventBuffer()).isNull(); + } + + @Test + public void testConstructor_contentProtection_disabled_bufferNotCreated() { + ContentCaptureOptions options = + createOptions( + new ContentCaptureOptions.ContentProtectionOptions( + /* enableReceiver= */ false, BUFFER_SIZE)); + + ContentCaptureManager manager = + new ContentCaptureManager(mMockContext, mMockContentCaptureManager, options); + + assertThat(manager.getContentProtectionEventBuffer()).isNull(); + } + + @Test + public void testConstructor_contentProtection_invalidBufferSize_bufferNotCreated() { + ContentCaptureOptions options = + createOptions( + new ContentCaptureOptions.ContentProtectionOptions( + /* enableReceiver= */ true, /* bufferSize= */ 0)); + + ContentCaptureManager manager = + new ContentCaptureManager(mMockContext, mMockContentCaptureManager, options); + + assertThat(manager.getContentProtectionEventBuffer()).isNull(); + } + + @Test + public void testConstructor_contentProtection_enabled_bufferCreated() { + ContentCaptureOptions options = + createOptions( + new ContentCaptureOptions.ContentProtectionOptions( + /* enableReceiver= */ true, BUFFER_SIZE)); + + ContentCaptureManager manager = + new ContentCaptureManager(mMockContext, mMockContentCaptureManager, options); + RingBuffer<ContentCaptureEvent> buffer = manager.getContentProtectionEventBuffer(); + + assertThat(buffer).isNotNull(); + ContentCaptureEvent[] expected = new ContentCaptureEvent[BUFFER_SIZE]; + int offset = 3; + for (int i = 0; i < BUFFER_SIZE + offset; i++) { + ContentCaptureEvent event = new ContentCaptureEvent(i, TYPE_SESSION_STARTED); + buffer.append(event); + expected[(i + BUFFER_SIZE - offset) % BUFFER_SIZE] = event; + } + assertThat(buffer.toArray()).isEqualTo(expected); + } + + @Test public void testRemoveData_invalidParametersThrowsException() { - final IContentCaptureManager mockService = mock(IContentCaptureManager.class); - final ContentCaptureOptions options = new ContentCaptureOptions(null); final ContentCaptureManager manager = - new ContentCaptureManager(mMockContext, mockService, options); + new ContentCaptureManager(mMockContext, mMockContentCaptureManager, EMPTY_OPTIONS); assertThrows(NullPointerException.class, () -> manager.removeData(null)); } @@ -60,10 +123,8 @@ public class ContentCaptureManagerTest { @Test @SuppressWarnings("GuardedBy") public void testFlushViewTreeAppearingEventDisabled_setAndGet() { - final IContentCaptureManager mockService = mock(IContentCaptureManager.class); - final ContentCaptureOptions options = new ContentCaptureOptions(null); final ContentCaptureManager manager = - new ContentCaptureManager(mMockContext, mockService, options); + new ContentCaptureManager(mMockContext, mMockContentCaptureManager, EMPTY_OPTIONS); assertThat(manager.getFlushViewTreeAppearingEventDisabled()).isFalse(); manager.setFlushViewTreeAppearingEventDisabled(true); @@ -71,4 +132,18 @@ public class ContentCaptureManagerTest { manager.setFlushViewTreeAppearingEventDisabled(false); assertThat(manager.getFlushViewTreeAppearingEventDisabled()).isFalse(); } + + private ContentCaptureOptions createOptions( + ContentCaptureOptions.ContentProtectionOptions contentProtectionOptions) { + return new ContentCaptureOptions( + /* loggingLevel= */ 0, + /* maxBufferSize= */ 0, + /* idleFlushingFrequencyMs= */ 0, + /* textChangeFlushingFrequencyMs= */ 0, + /* logHistorySize= */ 0, + /* disableFlushForViewTreeAppearing= */ false, + /* enableReceiver= */ true, + contentProtectionOptions, + /* whitelistedComponents= */ null); + } } |