Connect protection event processor with remote service

BYPASS_INCLUSIVE_LANGUAGE_REASON=Existing code in production

Bug: 275732576
Test: Added tests
Change-Id: I910460bb6fece38f38ffefa7eed4e8cad3f43277
This commit is contained in:
Nino Jagar
2023-06-01 23:04:13 +00:00
parent 685876265b
commit 2958d4453b
7 changed files with 273 additions and 25 deletions

View File

@@ -48,7 +48,7 @@ import java.io.PrintWriter;
*
* @hide
*/
public final class ContentCaptureServiceInfo {
public class ContentCaptureServiceInfo {
private static final String TAG = ContentCaptureServiceInfo.class.getSimpleName();
private static final String XML_TAG_SERVICE = "content-capture-service";

View File

@@ -17,6 +17,7 @@
package android.view.contentcapture;
import android.content.ComponentName;
import android.content.pm.ParceledListSlice;
import android.view.contentcapture.ContentCaptureContext;
import android.view.contentcapture.ContentCaptureEvent;
import android.view.contentcapture.DataRemovalRequest;
@@ -108,4 +109,9 @@ oneway interface IContentCaptureManager {
*/
void registerContentCaptureOptionsCallback(String packageName,
in IContentCaptureOptionsCallback callback);
/**
* Notifies the system server that a login was detected.
*/
void onLoginDetected(in ParceledListSlice<ContentCaptureEvent> events);
}

View File

@@ -162,7 +162,7 @@ public class ContentProtectionEventProcessor {
private void handlerOnLoginDetected(@NonNull ParceledListSlice<ContentCaptureEvent> events) {
try {
// TODO(b/275732576): Call mContentCaptureManager
mContentCaptureManager.onLoginDetected(events);
} catch (Exception ex) {
Log.e(TAG, "Failed to flush events for: " + mPackageName, ex);
}

View File

@@ -26,10 +26,12 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import android.annotation.Nullable;
import android.content.Context;
import android.content.pm.ParceledListSlice;
import android.os.Handler;
import android.os.Looper;
import android.text.InputType;
@@ -51,6 +53,7 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
@@ -82,6 +85,9 @@ public class ContentProtectionEventProcessorTest {
private static final ContentCaptureEvent PROCESS_EVENT = createProcessEvent();
private static final ContentCaptureEvent[] BUFFERED_EVENTS =
new ContentCaptureEvent[] {PROCESS_EVENT};
private static final Set<Integer> EVENT_TYPES_TO_STORE =
ImmutableSet.of(TYPE_VIEW_APPEARED, TYPE_VIEW_DISAPPEARED, TYPE_VIEW_TEXT_CHANGED);
@@ -165,11 +171,12 @@ public class ContentProtectionEventProcessorTest {
verify(mMockEventBuffer, never()).clear();
verify(mMockEventBuffer, never()).toArray();
verifyZeroInteractions(mMockContentCaptureManager);
}
@Test
public void processEvent_loginDetected() {
when(mMockEventBuffer.toArray()).thenReturn(new ContentCaptureEvent[0]);
public void processEvent_loginDetected() throws Exception {
when(mMockEventBuffer.toArray()).thenReturn(BUFFERED_EVENTS);
mContentProtectionEventProcessor.mPasswordFieldDetected = true;
mContentProtectionEventProcessor.mSuspiciousTextDetected = true;
@@ -179,6 +186,7 @@ public class ContentProtectionEventProcessorTest {
assertThat(mContentProtectionEventProcessor.mSuspiciousTextDetected).isFalse();
verify(mMockEventBuffer).clear();
verify(mMockEventBuffer).toArray();
assertOnLoginDetected();
}
@Test
@@ -192,6 +200,7 @@ public class ContentProtectionEventProcessorTest {
assertThat(mContentProtectionEventProcessor.mSuspiciousTextDetected).isTrue();
verify(mMockEventBuffer, never()).clear();
verify(mMockEventBuffer, never()).toArray();
verifyZeroInteractions(mMockContentCaptureManager);
}
@Test
@@ -205,6 +214,7 @@ public class ContentProtectionEventProcessorTest {
assertThat(mContentProtectionEventProcessor.mSuspiciousTextDetected).isFalse();
verify(mMockEventBuffer, never()).clear();
verify(mMockEventBuffer, never()).toArray();
verifyZeroInteractions(mMockContentCaptureManager);
}
@Test
@@ -218,11 +228,12 @@ public class ContentProtectionEventProcessorTest {
assertThat(mContentProtectionEventProcessor.mSuspiciousTextDetected).isFalse();
verify(mMockEventBuffer, never()).clear();
verify(mMockEventBuffer, never()).toArray();
verifyZeroInteractions(mMockContentCaptureManager);
}
@Test
public void processEvent_multipleLoginsDetected_belowFlushThreshold() {
when(mMockEventBuffer.toArray()).thenReturn(new ContentCaptureEvent[0]);
public void processEvent_multipleLoginsDetected_belowFlushThreshold() throws Exception {
when(mMockEventBuffer.toArray()).thenReturn(BUFFERED_EVENTS);
mContentProtectionEventProcessor.mPasswordFieldDetected = true;
mContentProtectionEventProcessor.mSuspiciousTextDetected = true;
@@ -236,11 +247,12 @@ public class ContentProtectionEventProcessorTest {
assertThat(mContentProtectionEventProcessor.mSuspiciousTextDetected).isFalse();
verify(mMockEventBuffer).clear();
verify(mMockEventBuffer).toArray();
assertOnLoginDetected();
}
@Test
public void processEvent_multipleLoginsDetected_aboveFlushThreshold() {
when(mMockEventBuffer.toArray()).thenReturn(new ContentCaptureEvent[0]);
public void processEvent_multipleLoginsDetected_aboveFlushThreshold() throws Exception {
when(mMockEventBuffer.toArray()).thenReturn(BUFFERED_EVENTS);
mContentProtectionEventProcessor.mPasswordFieldDetected = true;
mContentProtectionEventProcessor.mSuspiciousTextDetected = true;
@@ -256,6 +268,7 @@ public class ContentProtectionEventProcessorTest {
assertThat(mContentProtectionEventProcessor.mSuspiciousTextDetected).isFalse();
verify(mMockEventBuffer, times(2)).clear();
verify(mMockEventBuffer, times(2)).toArray();
assertOnLoginDetected(PROCESS_EVENT, /* times= */ 2);
}
@Test
@@ -269,6 +282,7 @@ public class ContentProtectionEventProcessorTest {
assertThat(mContentProtectionEventProcessor.mPasswordFieldDetected).isTrue();
verify(mMockEventBuffer, never()).clear();
verify(mMockEventBuffer, never()).toArray();
verifyZeroInteractions(mMockContentCaptureManager);
}
@Test
@@ -282,6 +296,7 @@ public class ContentProtectionEventProcessorTest {
assertThat(mContentProtectionEventProcessor.mPasswordFieldDetected).isFalse();
verify(mMockEventBuffer, never()).clear();
verify(mMockEventBuffer, never()).toArray();
verifyZeroInteractions(mMockContentCaptureManager);
}
@Test
@@ -296,6 +311,7 @@ public class ContentProtectionEventProcessorTest {
assertThat(mContentProtectionEventProcessor.mPasswordFieldDetected).isFalse();
verify(mMockEventBuffer, never()).clear();
verify(mMockEventBuffer, never()).toArray();
verifyZeroInteractions(mMockContentCaptureManager);
}
@Test
@@ -309,21 +325,22 @@ public class ContentProtectionEventProcessorTest {
assertThat(mContentProtectionEventProcessor.mPasswordFieldDetected).isFalse();
verify(mMockEventBuffer, never()).clear();
verify(mMockEventBuffer, never()).toArray();
verifyZeroInteractions(mMockContentCaptureManager);
}
@Test
public void isPasswordField_webView() {
when(mMockEventBuffer.toArray()).thenReturn(new ContentCaptureEvent[0]);
public void isPasswordField_webView() throws Exception {
ContentCaptureEvent event =
createWebViewPasswordFieldEvent(
/* className= */ null, /* eventText= */ null, PASSWORD_TEXT);
when(mMockEventBuffer.toArray()).thenReturn(new ContentCaptureEvent[] {event});
mContentProtectionEventProcessor.processEvent(event);
assertThat(mContentProtectionEventProcessor.mPasswordFieldDetected).isFalse();
verify(mMockEventBuffer).clear();
verify(mMockEventBuffer).toArray();
assertOnLoginDetected(event, /* times= */ 1);
}
@Test
@@ -337,6 +354,7 @@ public class ContentProtectionEventProcessorTest {
assertThat(mContentProtectionEventProcessor.mPasswordFieldDetected).isFalse();
verify(mMockEventBuffer, never()).clear();
verify(mMockEventBuffer, never()).toArray();
verifyZeroInteractions(mMockContentCaptureManager);
}
@Test
@@ -350,6 +368,7 @@ public class ContentProtectionEventProcessorTest {
assertThat(mContentProtectionEventProcessor.mPasswordFieldDetected).isFalse();
verify(mMockEventBuffer, never()).clear();
verify(mMockEventBuffer, never()).toArray();
verifyZeroInteractions(mMockContentCaptureManager);
}
@Test
@@ -362,6 +381,7 @@ public class ContentProtectionEventProcessorTest {
assertThat(mContentProtectionEventProcessor.mPasswordFieldDetected).isFalse();
verify(mMockEventBuffer, never()).clear();
verify(mMockEventBuffer, never()).toArray();
verifyZeroInteractions(mMockContentCaptureManager);
}
@Test
@@ -373,6 +393,7 @@ public class ContentProtectionEventProcessorTest {
assertThat(mContentProtectionEventProcessor.mSuspiciousTextDetected).isFalse();
verify(mMockEventBuffer, never()).clear();
verify(mMockEventBuffer, never()).toArray();
verifyZeroInteractions(mMockContentCaptureManager);
}
@Test
@@ -384,6 +405,7 @@ public class ContentProtectionEventProcessorTest {
assertThat(mContentProtectionEventProcessor.mSuspiciousTextDetected).isTrue();
verify(mMockEventBuffer, never()).clear();
verify(mMockEventBuffer, never()).toArray();
verifyZeroInteractions(mMockContentCaptureManager);
}
@Test
@@ -395,6 +417,7 @@ public class ContentProtectionEventProcessorTest {
assertThat(mContentProtectionEventProcessor.mSuspiciousTextDetected).isTrue();
verify(mMockEventBuffer, never()).clear();
verify(mMockEventBuffer, never()).toArray();
verifyZeroInteractions(mMockContentCaptureManager);
}
@Test
@@ -406,6 +429,7 @@ public class ContentProtectionEventProcessorTest {
assertThat(mContentProtectionEventProcessor.mSuspiciousTextDetected).isTrue();
verify(mMockEventBuffer, never()).clear();
verify(mMockEventBuffer, never()).toArray();
verifyZeroInteractions(mMockContentCaptureManager);
}
@Test
@@ -420,6 +444,7 @@ public class ContentProtectionEventProcessorTest {
assertThat(mContentProtectionEventProcessor.mSuspiciousTextDetected).isTrue();
verify(mMockEventBuffer, never()).clear();
verify(mMockEventBuffer, never()).toArray();
verifyZeroInteractions(mMockContentCaptureManager);
}
private static ContentCaptureEvent createEvent(int type) {
@@ -474,4 +499,18 @@ public class ContentProtectionEventProcessorTest {
return createProcessEvent(
/* className= */ null, /* inputType= */ 0, eventText, viewNodeText);
}
private void assertOnLoginDetected() throws Exception {
assertOnLoginDetected(PROCESS_EVENT, /* times= */ 1);
}
private void assertOnLoginDetected(ContentCaptureEvent event, int times) throws Exception {
ArgumentCaptor<ParceledListSlice> captor = ArgumentCaptor.forClass(ParceledListSlice.class);
verify(mMockContentCaptureManager, times(times)).onLoginDetected(captor.capture());
assertThat(captor.getValue()).isNotNull();
List<ContentCaptureEvent> actual = captor.getValue().getList();
assertThat(actual).isNotNull();
assertThat(actual).containsExactly(event);
}
}

View File

@@ -50,6 +50,7 @@ import android.content.Context;
import android.content.pm.ActivityPresentationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ParceledListSlice;
import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.os.Binder;
@@ -69,6 +70,7 @@ import android.provider.DeviceConfig;
import android.provider.DeviceConfig.Properties;
import android.provider.Settings;
import android.service.contentcapture.ActivityEvent.ActivityEventType;
import android.service.contentcapture.ContentCaptureServiceInfo;
import android.service.contentcapture.IDataShareCallback;
import android.service.contentcapture.IDataShareReadAdapter;
import android.service.voice.VoiceInteractionManagerInternal;
@@ -79,6 +81,7 @@ import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.view.contentcapture.ContentCaptureCondition;
import android.view.contentcapture.ContentCaptureEvent;
import android.view.contentcapture.ContentCaptureHelper;
import android.view.contentcapture.ContentCaptureManager;
import android.view.contentcapture.DataRemovalRequest;
@@ -96,6 +99,7 @@ import com.android.internal.util.DumpUtils;
import com.android.server.LocalServices;
import com.android.server.contentprotection.ContentProtectionBlocklistManager;
import com.android.server.contentprotection.ContentProtectionPackageManager;
import com.android.server.contentprotection.RemoteContentProtectionService;
import com.android.server.infra.AbstractMasterSystemService;
import com.android.server.infra.FrameworkResourcesServiceNameResolver;
@@ -208,6 +212,8 @@ public class ContentCaptureManagerService extends
final GlobalContentCaptureOptions mGlobalContentCaptureOptions =
new GlobalContentCaptureOptions();
@Nullable private final ComponentName mContentProtectionServiceComponentName;
@Nullable private final ContentProtectionBlocklistManager mContentProtectionBlocklistManager;
public ContentCaptureManagerService(@NonNull Context context) {
@@ -249,10 +255,16 @@ public class ContentCaptureManagerService extends
}
if (getEnableContentProtectionReceiverLocked()) {
mContentProtectionBlocklistManager = createContentProtectionBlocklistManager(context);
mContentProtectionBlocklistManager.updateBlocklist(
mDevCfgContentProtectionAppsBlocklistSize);
mContentProtectionServiceComponentName = getContentProtectionServiceComponentName();
if (mContentProtectionServiceComponentName != null) {
mContentProtectionBlocklistManager = createContentProtectionBlocklistManager();
mContentProtectionBlocklistManager.updateBlocklist(
mDevCfgContentProtectionAppsBlocklistSize);
} else {
mContentProtectionBlocklistManager = null;
}
} else {
mContentProtectionServiceComponentName = null;
mContentProtectionBlocklistManager = null;
}
}
@@ -785,9 +797,82 @@ public class ContentCaptureManagerService extends
/** @hide */
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
@NonNull
protected ContentProtectionBlocklistManager createContentProtectionBlocklistManager(
@NonNull Context context) {
return new ContentProtectionBlocklistManager(new ContentProtectionPackageManager(context));
protected ContentProtectionBlocklistManager createContentProtectionBlocklistManager() {
return new ContentProtectionBlocklistManager(
new ContentProtectionPackageManager(getContext()));
}
@Nullable
private ComponentName getContentProtectionServiceComponentName() {
String flatComponentName = getContentProtectionServiceFlatComponentName();
ComponentName componentName = ComponentName.unflattenFromString(flatComponentName);
if (componentName == null) {
return null;
}
// Check permissions by trying to construct {@link ContentCaptureServiceInfo}
try {
createContentProtectionServiceInfo(componentName);
} catch (Exception ex) {
// Swallow, exception was already logged
return null;
}
return componentName;
}
/** @hide */
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
@Nullable
protected String getContentProtectionServiceFlatComponentName() {
return getContext()
.getString(com.android.internal.R.string.config_defaultContentProtectionService);
}
/**
* Can also throw runtime exceptions such as {@link SecurityException}.
*
* @hide
*/
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
@NonNull
protected ContentCaptureServiceInfo createContentProtectionServiceInfo(
@NonNull ComponentName componentName) throws PackageManager.NameNotFoundException {
return new ContentCaptureServiceInfo(
getContext(), componentName, /* isTemp= */ false, UserHandle.getCallingUserId());
}
@Nullable
private RemoteContentProtectionService createRemoteContentProtectionService() {
if (mContentProtectionServiceComponentName == null) {
// This case should not be possible but make sure
return null;
}
synchronized (mLock) {
if (!mDevCfgEnableContentProtectionReceiver) {
return null;
}
}
return createRemoteContentProtectionService(mContentProtectionServiceComponentName);
}
/** @hide */
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
@NonNull
protected RemoteContentProtectionService createRemoteContentProtectionService(
@NonNull ComponentName componentName) {
return new RemoteContentProtectionService(
getContext(),
componentName,
UserHandle.getCallingUserId(),
isBindInstantServiceAllowed());
}
/** @hide */
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
@NonNull
protected ContentCaptureManagerServiceStub getContentCaptureManagerServiceStub() {
return mContentCaptureManagerServiceStub;
}
final class ContentCaptureManagerServiceStub extends IContentCaptureManager.Stub {
@@ -1023,6 +1108,19 @@ public class ContentCaptureManagerService extends
public void setDefaultServiceEnabled(@UserIdInt int userId, boolean enabled) {
ContentCaptureManagerService.this.setDefaultServiceEnabled(userId, enabled);
}
@Override
public void onLoginDetected(@NonNull ParceledListSlice<ContentCaptureEvent> events) {
RemoteContentProtectionService service = createRemoteContentProtectionService();
if (service == null) {
return;
}
try {
service.onLoginDetected(events);
} catch (Exception ex) {
Slog.e(TAG, "Failed to call remote service", ex);
}
}
}
private final class LocalService extends ContentCaptureManagerInternal {
@@ -1205,7 +1303,8 @@ public class ContentCaptureManagerService extends
}
private boolean isContentProtectionReceiverEnabled(@NonNull String packageName) {
if (mContentProtectionBlocklistManager == null) {
if (mContentProtectionServiceComponentName == null
|| mContentProtectionBlocklistManager == null) {
return false;
}
synchronized (mLock) {

View File

@@ -37,7 +37,8 @@ import java.time.Duration;
*
* @hide
*/
class RemoteContentProtectionService extends ServiceConnector.Impl<IContentCaptureDirectManager> {
public class RemoteContentProtectionService
extends ServiceConnector.Impl<IContentCaptureDirectManager> {
private static final String TAG = RemoteContentProtectionService.class.getSimpleName();
@@ -45,7 +46,7 @@ class RemoteContentProtectionService extends ServiceConnector.Impl<IContentCaptu
@NonNull private final ComponentName mComponentName;
protected RemoteContentProtectionService(
public RemoteContentProtectionService(
@NonNull Context context,
@NonNull ComponentName componentName,
int userId,

View File

@@ -30,7 +30,11 @@ import android.annotation.NonNull;
import android.content.ComponentName;
import android.content.ContentCaptureOptions;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.ParceledListSlice;
import android.content.pm.UserInfo;
import android.service.contentcapture.ContentCaptureServiceInfo;
import android.view.contentcapture.ContentCaptureEvent;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -38,6 +42,7 @@ import androidx.test.filters.SmallTest;
import com.android.server.LocalServices;
import com.android.server.contentprotection.ContentProtectionBlocklistManager;
import com.android.server.contentprotection.RemoteContentProtectionService;
import com.android.server.pm.UserManagerInternal;
import com.google.common.collect.ImmutableList;
@@ -68,6 +73,12 @@ public class ContentCaptureManagerServiceTest {
private static final ComponentName COMPONENT_NAME =
new ComponentName(PACKAGE_NAME, "TestClass");
private static final ContentCaptureEvent EVENT =
new ContentCaptureEvent(/* sessionId= */ 100, /* type= */ 200);
private static final ParceledListSlice<ContentCaptureEvent> PARCELED_EVENTS =
new ParceledListSlice<>(ImmutableList.of(EVENT));
private static final Context sContext = ApplicationProvider.getApplicationContext();
@Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
@@ -76,10 +87,22 @@ public class ContentCaptureManagerServiceTest {
@Mock private ContentProtectionBlocklistManager mMockContentProtectionBlocklistManager;
@Mock private ContentCaptureServiceInfo mMockContentCaptureServiceInfo;
@Mock private RemoteContentProtectionService mMockRemoteContentProtectionService;
private boolean mDevCfgEnableContentProtectionReceiver;
private int mContentProtectionBlocklistManagersCreated;
private int mContentProtectionServiceInfosCreated;
private int mRemoteContentProtectionServicesCreated;
private String mConfigDefaultContentProtectionService = COMPONENT_NAME.flattenToString();
private boolean mContentProtectionServiceInfoConstructorShouldThrow;
private ContentCaptureManagerService mContentCaptureManagerService;
@Before
@@ -91,24 +114,54 @@ public class ContentCaptureManagerServiceTest {
}
@Test
public void constructor_default_doesNotCreateContentProtectionBlocklistManager() {
public void constructor_contentProtection_flagDisabled_noBlocklistManager() {
assertThat(mContentProtectionBlocklistManagersCreated).isEqualTo(0);
assertThat(mContentProtectionServiceInfosCreated).isEqualTo(0);
verifyZeroInteractions(mMockContentProtectionBlocklistManager);
}
@Test
public void constructor_flagDisabled_doesNotContentProtectionBlocklistManager() {
public void constructor_contentProtection_componentNameNull_noBlocklistManager() {
mConfigDefaultContentProtectionService = null;
mContentCaptureManagerService = new TestContentCaptureManagerService();
assertThat(mContentProtectionBlocklistManagersCreated).isEqualTo(0);
assertThat(mContentProtectionServiceInfosCreated).isEqualTo(0);
verifyZeroInteractions(mMockContentProtectionBlocklistManager);
}
@Test
public void constructor_flagEnabled_createsContentProtectionBlocklistManager() {
public void constructor_contentProtection_componentNameBlank_noBlocklistManager() {
mConfigDefaultContentProtectionService = " ";
mContentCaptureManagerService = new TestContentCaptureManagerService();
assertThat(mContentProtectionBlocklistManagersCreated).isEqualTo(0);
assertThat(mContentProtectionServiceInfosCreated).isEqualTo(0);
verifyZeroInteractions(mMockContentProtectionBlocklistManager);
}
@Test
public void constructor_contentProtection_serviceInfoThrows_noBlocklistManager() {
mDevCfgEnableContentProtectionReceiver = true;
mContentProtectionServiceInfoConstructorShouldThrow = true;
mContentCaptureManagerService = new TestContentCaptureManagerService();
assertThat(mContentProtectionBlocklistManagersCreated).isEqualTo(0);
assertThat(mContentProtectionServiceInfosCreated).isEqualTo(1);
verifyZeroInteractions(mMockContentProtectionBlocklistManager);
}
@Test
public void constructor_contentProtection_enabled_createsBlocklistManager() {
mDevCfgEnableContentProtectionReceiver = true;
mContentCaptureManagerService = new TestContentCaptureManagerService();
assertThat(mContentProtectionBlocklistManagersCreated).isEqualTo(1);
assertThat(mContentProtectionServiceInfosCreated).isEqualTo(1);
verify(mMockContentProtectionBlocklistManager).updateBlocklist(anyInt());
}
@@ -298,6 +351,35 @@ public class ContentCaptureManagerServiceTest {
verify(mMockContentProtectionBlocklistManager, never()).isAllowed(anyString());
}
@Test
public void onLoginDetected_disabledAfterConstructor() {
mDevCfgEnableContentProtectionReceiver = true;
mContentCaptureManagerService = new TestContentCaptureManagerService();
mContentCaptureManagerService.mDevCfgEnableContentProtectionReceiver = false;
mContentCaptureManagerService
.getContentCaptureManagerServiceStub()
.onLoginDetected(PARCELED_EVENTS);
assertThat(mContentProtectionServiceInfosCreated).isEqualTo(1);
assertThat(mRemoteContentProtectionServicesCreated).isEqualTo(0);
verifyZeroInteractions(mMockRemoteContentProtectionService);
}
@Test
public void onLoginDetected_enabled() {
mDevCfgEnableContentProtectionReceiver = true;
mContentCaptureManagerService = new TestContentCaptureManagerService();
mContentCaptureManagerService
.getContentCaptureManagerServiceStub()
.onLoginDetected(PARCELED_EVENTS);
assertThat(mContentProtectionServiceInfosCreated).isEqualTo(1);
assertThat(mRemoteContentProtectionServicesCreated).isEqualTo(1);
verify(mMockRemoteContentProtectionService).onLoginDetected(PARCELED_EVENTS);
}
private class TestContentCaptureManagerService extends ContentCaptureManagerService {
TestContentCaptureManagerService() {
@@ -312,10 +394,31 @@ public class ContentCaptureManagerServiceTest {
}
@Override
protected ContentProtectionBlocklistManager createContentProtectionBlocklistManager(
@NonNull Context context) {
protected ContentProtectionBlocklistManager createContentProtectionBlocklistManager() {
mContentProtectionBlocklistManagersCreated++;
return mMockContentProtectionBlocklistManager;
}
@Override
protected String getContentProtectionServiceFlatComponentName() {
return mConfigDefaultContentProtectionService;
}
@Override
protected ContentCaptureServiceInfo createContentProtectionServiceInfo(
@NonNull ComponentName componentName) throws PackageManager.NameNotFoundException {
mContentProtectionServiceInfosCreated++;
if (mContentProtectionServiceInfoConstructorShouldThrow) {
throw new RuntimeException("TEST RUNTIME EXCEPTION");
}
return mMockContentCaptureServiceInfo;
}
@Override
protected RemoteContentProtectionService createRemoteContentProtectionService(
@NonNull ComponentName componentName) {
mRemoteContentProtectionServicesCreated++;
return mMockRemoteContentProtectionService;
}
}
}