Merge "Add content protection buffer to ContentCaptureManager" into udc-qpr-dev
This commit is contained in:
@@ -52,6 +52,7 @@ import android.view.contentcapture.ContentCaptureSession.FlushReason;
|
|||||||
|
|
||||||
import com.android.internal.annotations.GuardedBy;
|
import com.android.internal.annotations.GuardedBy;
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
|
import com.android.internal.util.RingBuffer;
|
||||||
import com.android.internal.util.SyncResultReceiver;
|
import com.android.internal.util.SyncResultReceiver;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
@@ -446,6 +447,9 @@ public final class ContentCaptureManager {
|
|||||||
@Nullable // set on-demand by addDumpable()
|
@Nullable // set on-demand by addDumpable()
|
||||||
private Dumper mDumpable;
|
private Dumper mDumpable;
|
||||||
|
|
||||||
|
// Created here in order to live across activity and session changes
|
||||||
|
@Nullable private final RingBuffer<ContentCaptureEvent> mContentProtectionEventBuffer;
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
public interface ContentCaptureClient {
|
public interface ContentCaptureClient {
|
||||||
/**
|
/**
|
||||||
@@ -456,12 +460,15 @@ public final class ContentCaptureManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
static class StrippedContext {
|
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
|
||||||
|
public static class StrippedContext {
|
||||||
@NonNull final String mPackageName;
|
@NonNull final String mPackageName;
|
||||||
@NonNull final String mContext;
|
@NonNull final String mContext;
|
||||||
final @UserIdInt int mUserId;
|
final @UserIdInt int mUserId;
|
||||||
|
|
||||||
private StrippedContext(@NonNull Context context) {
|
/** @hide */
|
||||||
|
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
|
||||||
|
public StrippedContext(@NonNull Context context) {
|
||||||
mPackageName = context.getPackageName();
|
mPackageName = context.getPackageName();
|
||||||
mContext = context.toString();
|
mContext = context.toString();
|
||||||
mUserId = context.getUserId();
|
mUserId = context.getUserId();
|
||||||
@@ -502,6 +509,16 @@ public final class ContentCaptureManager {
|
|||||||
mHandler = Handler.createAsync(Looper.getMainLooper());
|
mHandler = Handler.createAsync(Looper.getMainLooper());
|
||||||
|
|
||||||
mDataShareAdapterResourceManager = new LocalDataShareAdapterResourceManager();
|
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);
|
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
|
// NOTE: ContentCaptureManager cannot implement it directly as it would be exposed as public API
|
||||||
private final class Dumper implements Dumpable {
|
private final class Dumper implements Dumpable {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -15,14 +15,17 @@
|
|||||||
*/
|
*/
|
||||||
package android.view.contentcapture;
|
package android.view.contentcapture;
|
||||||
|
|
||||||
|
import static android.view.contentcapture.ContentCaptureEvent.TYPE_SESSION_STARTED;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.testng.Assert.assertThrows;
|
import static org.testng.Assert.assertThrows;
|
||||||
|
|
||||||
import android.content.ContentCaptureOptions;
|
import android.content.ContentCaptureOptions;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
|
import com.android.internal.util.RingBuffer;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
@@ -37,9 +40,15 @@ import org.mockito.junit.MockitoJUnitRunner;
|
|||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class ContentCaptureManagerTest {
|
public class ContentCaptureManagerTest {
|
||||||
|
|
||||||
|
private static final int BUFFER_SIZE = 100;
|
||||||
|
|
||||||
|
private static final ContentCaptureOptions EMPTY_OPTIONS = new ContentCaptureOptions(null);
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private Context mMockContext;
|
private Context mMockContext;
|
||||||
|
|
||||||
|
@Mock private IContentCaptureManager mMockContentCaptureManager;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConstructor_invalidParametersThrowsException() {
|
public void testConstructor_invalidParametersThrowsException() {
|
||||||
assertThrows(NullPointerException.class,
|
assertThrows(NullPointerException.class,
|
||||||
@@ -47,12 +56,66 @@ public class ContentCaptureManagerTest {
|
|||||||
null));
|
null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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
|
@Test
|
||||||
public void testRemoveData_invalidParametersThrowsException() {
|
public void testRemoveData_invalidParametersThrowsException() {
|
||||||
final IContentCaptureManager mockService = mock(IContentCaptureManager.class);
|
|
||||||
final ContentCaptureOptions options = new ContentCaptureOptions(null);
|
|
||||||
final ContentCaptureManager manager =
|
final ContentCaptureManager manager =
|
||||||
new ContentCaptureManager(mMockContext, mockService, options);
|
new ContentCaptureManager(mMockContext, mMockContentCaptureManager, EMPTY_OPTIONS);
|
||||||
|
|
||||||
assertThrows(NullPointerException.class, () -> manager.removeData(null));
|
assertThrows(NullPointerException.class, () -> manager.removeData(null));
|
||||||
}
|
}
|
||||||
@@ -60,10 +123,8 @@ public class ContentCaptureManagerTest {
|
|||||||
@Test
|
@Test
|
||||||
@SuppressWarnings("GuardedBy")
|
@SuppressWarnings("GuardedBy")
|
||||||
public void testFlushViewTreeAppearingEventDisabled_setAndGet() {
|
public void testFlushViewTreeAppearingEventDisabled_setAndGet() {
|
||||||
final IContentCaptureManager mockService = mock(IContentCaptureManager.class);
|
|
||||||
final ContentCaptureOptions options = new ContentCaptureOptions(null);
|
|
||||||
final ContentCaptureManager manager =
|
final ContentCaptureManager manager =
|
||||||
new ContentCaptureManager(mMockContext, mockService, options);
|
new ContentCaptureManager(mMockContext, mMockContentCaptureManager, EMPTY_OPTIONS);
|
||||||
|
|
||||||
assertThat(manager.getFlushViewTreeAppearingEventDisabled()).isFalse();
|
assertThat(manager.getFlushViewTreeAppearingEventDisabled()).isFalse();
|
||||||
manager.setFlushViewTreeAppearingEventDisabled(true);
|
manager.setFlushViewTreeAppearingEventDisabled(true);
|
||||||
@@ -71,4 +132,18 @@ public class ContentCaptureManagerTest {
|
|||||||
manager.setFlushViewTreeAppearingEventDisabled(false);
|
manager.setFlushViewTreeAppearingEventDisabled(false);
|
||||||
assertThat(manager.getFlushViewTreeAppearingEventDisabled()).isFalse();
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user