Add a reset mechanism into content protection processor

Bug: 275732576
Test: Added tests and manual end to end
Change-Id: I72238dae65b634c54cc62a0f2df4dff5816ae1c3
This commit is contained in:
Nino Jagar
2023-06-05 23:29:36 +00:00
parent aaaf84c811
commit 810ddb5e27
2 changed files with 78 additions and 0 deletions

View File

@@ -75,6 +75,8 @@ public class ContentProtectionEventProcessor {
ContentCaptureEvent.TYPE_VIEW_DISAPPEARED,
ContentCaptureEvent.TYPE_VIEW_TEXT_CHANGED)));
private static final int RESET_LOGIN_TOTAL_EVENTS_TO_PROCESS = 150;
@NonNull private final RingBuffer<ContentCaptureEvent> mEventBuffer;
@NonNull private final Handler mHandler;
@@ -93,6 +95,8 @@ public class ContentProtectionEventProcessor {
@Nullable
public Instant mLastFlushTime;
private int mResetLoginRemainingEventsToProcess;
public ContentProtectionEventProcessor(
@NonNull RingBuffer<ContentCaptureEvent> eventBuffer,
@NonNull Handler handler,
@@ -130,6 +134,8 @@ public class ContentProtectionEventProcessor {
mSuspiciousTextDetected |= isSuspiciousText(event);
if (mPasswordFieldDetected && mSuspiciousTextDetected) {
loginDetected();
} else {
maybeResetLoginFlags();
}
}
@@ -139,8 +145,28 @@ public class ContentProtectionEventProcessor {
|| Instant.now().isAfter(mLastFlushTime.plus(MIN_DURATION_BETWEEN_FLUSHING))) {
flush();
}
resetLoginFlags();
}
@UiThread
private void resetLoginFlags() {
mPasswordFieldDetected = false;
mSuspiciousTextDetected = false;
mResetLoginRemainingEventsToProcess = 0;
}
@UiThread
private void maybeResetLoginFlags() {
if (mPasswordFieldDetected || mSuspiciousTextDetected) {
if (mResetLoginRemainingEventsToProcess <= 0) {
mResetLoginRemainingEventsToProcess = RESET_LOGIN_TOTAL_EVENTS_TO_PROCESS;
} else {
mResetLoginRemainingEventsToProcess--;
if (mResetLoginRemainingEventsToProcess <= 0) {
resetLoginFlags();
}
}
}
}
@UiThread

View File

@@ -91,6 +91,8 @@ public class ContentProtectionEventProcessorTest {
private static final Set<Integer> EVENT_TYPES_TO_STORE =
ImmutableSet.of(TYPE_VIEW_APPEARED, TYPE_VIEW_DISAPPEARED, TYPE_VIEW_TEXT_CHANGED);
private static final int RESET_LOGIN_TOTAL_EVENTS_TO_PROCESS = 150;
@Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
@Mock private RingBuffer<ContentCaptureEvent> mMockEventBuffer;
@@ -231,6 +233,56 @@ public class ContentProtectionEventProcessorTest {
verifyZeroInteractions(mMockContentCaptureManager);
}
@Test
public void processEvent_loginDetected_belowResetLimit() throws Exception {
when(mMockEventBuffer.toArray()).thenReturn(BUFFERED_EVENTS);
mContentProtectionEventProcessor.mSuspiciousTextDetected = true;
ContentCaptureEvent event =
createAndroidPasswordFieldEvent(
ANDROID_CLASS_NAME, InputType.TYPE_TEXT_VARIATION_PASSWORD);
for (int i = 0; i < RESET_LOGIN_TOTAL_EVENTS_TO_PROCESS; i++) {
mContentProtectionEventProcessor.processEvent(PROCESS_EVENT);
}
assertThat(mContentProtectionEventProcessor.mPasswordFieldDetected).isFalse();
assertThat(mContentProtectionEventProcessor.mSuspiciousTextDetected).isTrue();
verify(mMockEventBuffer, never()).clear();
verify(mMockEventBuffer, never()).toArray();
mContentProtectionEventProcessor.processEvent(event);
assertThat(mContentProtectionEventProcessor.mPasswordFieldDetected).isFalse();
assertThat(mContentProtectionEventProcessor.mSuspiciousTextDetected).isFalse();
verify(mMockEventBuffer).clear();
verify(mMockEventBuffer).toArray();
assertOnLoginDetected();
}
@Test
public void processEvent_loginDetected_aboveResetLimit() throws Exception {
mContentProtectionEventProcessor.mSuspiciousTextDetected = true;
ContentCaptureEvent event =
createAndroidPasswordFieldEvent(
ANDROID_CLASS_NAME, InputType.TYPE_TEXT_VARIATION_PASSWORD);
for (int i = 0; i < RESET_LOGIN_TOTAL_EVENTS_TO_PROCESS + 1; i++) {
mContentProtectionEventProcessor.processEvent(PROCESS_EVENT);
}
assertThat(mContentProtectionEventProcessor.mPasswordFieldDetected).isFalse();
assertThat(mContentProtectionEventProcessor.mSuspiciousTextDetected).isFalse();
verify(mMockEventBuffer, never()).clear();
verify(mMockEventBuffer, never()).toArray();
mContentProtectionEventProcessor.processEvent(event);
assertThat(mContentProtectionEventProcessor.mPasswordFieldDetected).isTrue();
assertThat(mContentProtectionEventProcessor.mSuspiciousTextDetected).isFalse();
verify(mMockEventBuffer, never()).clear();
verify(mMockEventBuffer, never()).toArray();
}
@Test
public void processEvent_multipleLoginsDetected_belowFlushThreshold() throws Exception {
when(mMockEventBuffer.toArray()).thenReturn(BUFFERED_EVENTS);