Loading services/contentcapture/java/com/android/server/contentprotection/ContentProtectionAllowlistManager.java +33 −4 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Handler; import android.os.UserHandle; import android.service.contentcapture.IContentProtectionAllowlistCallback; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -52,6 +54,10 @@ public class ContentProtectionAllowlistManager { @NonNull final PackageMonitor mPackageMonitor; @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) @NonNull final IContentProtectionAllowlistCallback mAllowlistCallback; private final Object mHandlerToken = new Object(); private final Object mLock = new Object(); Loading @@ -74,6 +80,7 @@ public class ContentProtectionAllowlistManager { mHandler = handler; mTimeoutMs = timeoutMs; mPackageMonitor = createPackageMonitor(); mAllowlistCallback = createAllowlistCallback(); } /** Starts the manager. */ Loading Loading @@ -107,7 +114,7 @@ public class ContentProtectionAllowlistManager { return allowedPackages.contains(packageName); } private void setAllowlist(@NonNull List<String> packages) { private void handleUpdateAllowlistResponse(@NonNull List<String> packages) { synchronized (mLock) { mAllowedPackages = packages.stream().collect(Collectors.toUnmodifiableSet()); } Loading @@ -115,14 +122,14 @@ public class ContentProtectionAllowlistManager { } private void handleInitialUpdate() { handleUpdate(); handlePackagesChanged(); // Initial update done, start listening to package updates now mPackageMonitor.register( mContentCaptureManagerService.getContext(), UserHandle.ALL, mHandler); } private void handleUpdate() { private void handlePackagesChanged() { if (!blocklistUpdateEnabled()) { return; } Loading @@ -145,6 +152,12 @@ public class ContentProtectionAllowlistManager { // If there are any pending updates queued already, they can be removed immediately mHandler.removeCallbacksAndMessages(mHandlerToken); mUpdatePendingUntil = Instant.now().plusMillis(mTimeoutMs); try { remoteContentProtectionService.onUpdateAllowlistRequest(mAllowlistCallback); } catch (Exception ex) { Slog.e(TAG, "Failed to call remote service", ex); } } /** @hide */ Loading @@ -154,12 +167,28 @@ public class ContentProtectionAllowlistManager { return new ContentProtectionPackageMonitor(); } /** @hide */ @NonNull @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) protected IContentProtectionAllowlistCallback createAllowlistCallback() { return new ContentProtectionAllowlistCallback(); } private final class ContentProtectionPackageMonitor extends PackageMonitor { // This callback might be invoked multiple times, for more info refer to the comment above @Override public void onSomePackagesChanged() { handleUpdate(); handlePackagesChanged(); } } private final class ContentProtectionAllowlistCallback extends IContentProtectionAllowlistCallback.Stub { @Override public void setAllowlist(List<String> packages) { mHandler.post(() -> handleUpdateAllowlistResponse(packages)); } } } services/tests/servicestests/src/com/android/server/contentprotection/ContentProtectionAllowlistManagerTest.java +169 −24 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import android.os.Handler; import android.os.UserHandle; import android.os.test.TestLooper; import android.platform.test.flag.junit.SetFlagsRule; import android.service.contentcapture.IContentProtectionAllowlistCallback; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; Loading @@ -48,6 +49,8 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import java.util.List; /** * Test for {@link ContentProtectionAllowlistManager}. * Loading @@ -58,7 +61,9 @@ import org.mockito.junit.MockitoRule; @SmallTest public class ContentProtectionAllowlistManagerTest { private static final String PACKAGE_NAME = "com.test.package.name"; private static final String FIRST_PACKAGE_NAME = "com.test.first.package.name"; private static final String SECOND_PACKAGE_NAME = "com.test.second.package.name"; private static final long TIMEOUT_MS = 111_111_111L; Loading @@ -74,12 +79,18 @@ public class ContentProtectionAllowlistManagerTest { @Mock private RemoteContentProtectionService mMockRemoteContentProtectionService; @Mock private IContentProtectionAllowlistCallback mMockAllowlistCallback; private final TestLooper mTestLooper = new TestLooper(); private Handler mHandler; private ContentProtectionAllowlistManager mContentProtectionAllowlistManager; private boolean mUseMockPackageMonitor = true; private boolean mUseMockAllowlistCallback = true; @Before public void setup() { mHandler = new Handler(mTestLooper.getLooper()); Loading @@ -91,6 +102,8 @@ public class ContentProtectionAllowlistManagerTest { assertThat(mHandler.hasMessagesOrCallbacks()).isFalse(); verifyZeroInteractions(mMockContentCaptureManagerService); verifyZeroInteractions(mMockPackageMonitor); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test Loading @@ -103,6 +116,8 @@ public class ContentProtectionAllowlistManagerTest { assertThat(mHandler.hasMessagesOrCallbacks()).isTrue(); verifyZeroInteractions(mMockContentCaptureManagerService); verifyZeroInteractions(mMockPackageMonitor); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test Loading @@ -117,6 +132,8 @@ public class ContentProtectionAllowlistManagerTest { verify(mMockContentCaptureManagerService).createRemoteContentProtectionService(); verify(mMockPackageMonitor).register(any(), eq(UserHandle.ALL), eq(mHandler)); verify(mMockPackageMonitor, never()).unregister(); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test Loading @@ -132,6 +149,8 @@ public class ContentProtectionAllowlistManagerTest { verify(mMockContentCaptureManagerService).createRemoteContentProtectionService(); verify(mMockPackageMonitor).register(any(), eq(UserHandle.ALL), eq(mHandler)); verify(mMockPackageMonitor, never()).unregister(); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test Loading @@ -144,6 +163,8 @@ public class ContentProtectionAllowlistManagerTest { assertThat(mHandler.hasMessagesOrCallbacks()).isTrue(); verifyZeroInteractions(mMockContentCaptureManagerService); verifyZeroInteractions(mMockPackageMonitor); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test Loading @@ -158,6 +179,8 @@ public class ContentProtectionAllowlistManagerTest { verifyZeroInteractions(mMockContentCaptureManagerService); verify(mMockPackageMonitor).register(any(), eq(UserHandle.ALL), eq(mHandler)); verify(mMockPackageMonitor, never()).unregister(); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test Loading @@ -173,6 +196,8 @@ public class ContentProtectionAllowlistManagerTest { verifyZeroInteractions(mMockContentCaptureManagerService); verify(mMockPackageMonitor).register(any(), eq(UserHandle.ALL), eq(mHandler)); verify(mMockPackageMonitor, never()).unregister(); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test Loading @@ -186,6 +211,8 @@ public class ContentProtectionAllowlistManagerTest { verifyZeroInteractions(mMockContentCaptureManagerService); verify(mMockPackageMonitor, never()).register(any(), any(), any()); verify(mMockPackageMonitor).unregister(); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test Loading @@ -201,6 +228,8 @@ public class ContentProtectionAllowlistManagerTest { verifyZeroInteractions(mMockContentCaptureManagerService); verify(mMockPackageMonitor, never()).register(any(), any(), any()); verify(mMockPackageMonitor).unregister(); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test Loading @@ -216,6 +245,8 @@ public class ContentProtectionAllowlistManagerTest { verify(mMockContentCaptureManagerService).createRemoteContentProtectionService(); verify(mMockPackageMonitor).register(any(), eq(UserHandle.ALL), eq(mHandler)); verify(mMockPackageMonitor).unregister(); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test Loading @@ -229,6 +260,8 @@ public class ContentProtectionAllowlistManagerTest { verifyZeroInteractions(mMockContentCaptureManagerService); verify(mMockPackageMonitor, never()).register(any(), any(), any()); verify(mMockPackageMonitor).unregister(); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test Loading @@ -244,6 +277,8 @@ public class ContentProtectionAllowlistManagerTest { verifyZeroInteractions(mMockContentCaptureManagerService); verify(mMockPackageMonitor, never()).register(any(), any(), any()); verify(mMockPackageMonitor).unregister(); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test Loading @@ -259,6 +294,8 @@ public class ContentProtectionAllowlistManagerTest { verifyZeroInteractions(mMockContentCaptureManagerService); verify(mMockPackageMonitor).register(any(), eq(UserHandle.ALL), eq(mHandler)); verify(mMockPackageMonitor).unregister(); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test Loading @@ -274,6 +311,8 @@ public class ContentProtectionAllowlistManagerTest { assertThat(mHandler.hasMessagesOrCallbacks()).isFalse(); verify(mMockPackageMonitor).register(any(), eq(UserHandle.ALL), eq(mHandler)); verify(mMockPackageMonitor).unregister(); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test Loading @@ -290,60 +329,130 @@ public class ContentProtectionAllowlistManagerTest { assertThat(mHandler.hasMessagesOrCallbacks()).isFalse(); verify(mMockPackageMonitor, times(2)).register(any(), eq(UserHandle.ALL), eq(mHandler)); verify(mMockPackageMonitor).unregister(); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test public void isAllowed_default() { boolean actual = mContentProtectionAllowlistManager.isAllowed(FIRST_PACKAGE_NAME); assertThat(actual).isFalse(); verifyZeroInteractions(mMockContentCaptureManagerService); verifyZeroInteractions(mMockPackageMonitor); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test public void isAllowed() { boolean actual = mContentProtectionAllowlistManager.isAllowed(PACKAGE_NAME); public void isAllowed_false() throws Exception { mUseMockAllowlistCallback = false; ContentProtectionAllowlistManager manager = new TestContentProtectionAllowlistManager(); manager.mAllowlistCallback.setAllowlist(List.of(FIRST_PACKAGE_NAME)); mTestLooper.dispatchNext(); boolean actual = manager.isAllowed(SECOND_PACKAGE_NAME); assertThat(actual).isFalse(); verifyZeroInteractions(mMockContentCaptureManagerService); verifyZeroInteractions(mMockPackageMonitor); verifyZeroInteractions(mMockRemoteContentProtectionService); } @Test public void handleUpdate_updateDisabled() { public void isAllowed_true() throws Exception { mUseMockAllowlistCallback = false; ContentProtectionAllowlistManager manager = new TestContentProtectionAllowlistManager(); manager.mAllowlistCallback.setAllowlist(List.of(FIRST_PACKAGE_NAME)); mTestLooper.dispatchNext(); boolean actual = manager.isAllowed(FIRST_PACKAGE_NAME); assertThat(actual).isTrue(); verifyZeroInteractions(mMockContentCaptureManagerService); verifyZeroInteractions(mMockPackageMonitor); verifyZeroInteractions(mMockRemoteContentProtectionService); } @Test public void handlePackagesChanged_updateDisabled() { mSetFlagsRule.disableFlags(FLAG_BLOCKLIST_UPDATE_ENABLED); ContentProtectionAllowlistManager manager = new ContentProtectionAllowlistManager( mMockContentCaptureManagerService, mHandler, TIMEOUT_MS); mUseMockPackageMonitor = false; ContentProtectionAllowlistManager manager = new TestContentProtectionAllowlistManager(); manager.mPackageMonitor.onSomePackagesChanged(); verifyZeroInteractions(mMockContentCaptureManagerService); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test public void handleUpdate_updateEnabled() { public void handlePackagesChanged_updateEnabled_noService() { mSetFlagsRule.enableFlags(FLAG_BLOCKLIST_UPDATE_ENABLED); ContentProtectionAllowlistManager manager = new ContentProtectionAllowlistManager( mMockContentCaptureManagerService, mHandler, TIMEOUT_MS); mUseMockPackageMonitor = false; ContentProtectionAllowlistManager manager = new TestContentProtectionAllowlistManager(); manager.mPackageMonitor.onSomePackagesChanged(); verify(mMockContentCaptureManagerService).createRemoteContentProtectionService(); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test public void handleUpdate_rateLimit_noService() { public void handlePackagesChanged_updateEnabled_withService() { mSetFlagsRule.enableFlags(FLAG_BLOCKLIST_UPDATE_ENABLED); ContentProtectionAllowlistManager manager = new ContentProtectionAllowlistManager( mMockContentCaptureManagerService, mHandler, TIMEOUT_MS); mUseMockPackageMonitor = false; ContentProtectionAllowlistManager manager = new TestContentProtectionAllowlistManager(); when(mMockContentCaptureManagerService.createRemoteContentProtectionService()) .thenReturn(mMockRemoteContentProtectionService); manager.mPackageMonitor.onSomePackagesChanged(); verify(mMockRemoteContentProtectionService) .onUpdateAllowlistRequest(mMockAllowlistCallback); verifyZeroInteractions(mMockAllowlistCallback); } @Test public void handlePackagesChanged_updateEnabled_withServiceException() { mSetFlagsRule.enableFlags(FLAG_BLOCKLIST_UPDATE_ENABLED); mUseMockPackageMonitor = false; ContentProtectionAllowlistManager manager = new TestContentProtectionAllowlistManager(); when(mMockContentCaptureManagerService.createRemoteContentProtectionService()) .thenReturn(mMockRemoteContentProtectionService); doThrow(new RuntimeException("TEST EXCEPTION")) .when(mMockRemoteContentProtectionService) .onUpdateAllowlistRequest(mMockAllowlistCallback); manager.mPackageMonitor.onSomePackagesChanged(); // Does not rethrow verify(mMockRemoteContentProtectionService) .onUpdateAllowlistRequest(mMockAllowlistCallback); verifyZeroInteractions(mMockAllowlistCallback); } @Test public void handlePackagesChanged_rateLimit_noService() { mSetFlagsRule.enableFlags(FLAG_BLOCKLIST_UPDATE_ENABLED); mUseMockPackageMonitor = false; ContentProtectionAllowlistManager manager = new TestContentProtectionAllowlistManager(); manager.mPackageMonitor.onSomePackagesChanged(); manager.mPackageMonitor.onSomePackagesChanged(); verify(mMockContentCaptureManagerService, times(2)).createRemoteContentProtectionService(); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test public void handleUpdate_rateLimit_beforeTimeout() { public void handlePackagesChanged_rateLimit_beforeTimeout() { mSetFlagsRule.enableFlags(FLAG_BLOCKLIST_UPDATE_ENABLED); ContentProtectionAllowlistManager manager = new ContentProtectionAllowlistManager( mMockContentCaptureManagerService, mHandler, TIMEOUT_MS); mUseMockPackageMonitor = false; ContentProtectionAllowlistManager manager = new TestContentProtectionAllowlistManager(); when(mMockContentCaptureManagerService.createRemoteContentProtectionService()) .thenReturn(mMockRemoteContentProtectionService); Loading @@ -351,32 +460,68 @@ public class ContentProtectionAllowlistManagerTest { manager.mPackageMonitor.onSomePackagesChanged(); verify(mMockContentCaptureManagerService).createRemoteContentProtectionService(); verify(mMockRemoteContentProtectionService) .onUpdateAllowlistRequest(mMockAllowlistCallback); verifyZeroInteractions(mMockAllowlistCallback); } @Test public void handleUpdate_rateLimit_afterTimeout() { public void handlePackagesChanged_rateLimit_afterTimeout() { mSetFlagsRule.enableFlags(FLAG_BLOCKLIST_UPDATE_ENABLED); mUseMockPackageMonitor = false; ContentProtectionAllowlistManager manager = new ContentProtectionAllowlistManager( mMockContentCaptureManagerService, mHandler, /* timeoutMs= */ 0L); new TestContentProtectionAllowlistManager(/* timeoutMs= */ 0L); when(mMockContentCaptureManagerService.createRemoteContentProtectionService()) .thenReturn(mMockRemoteContentProtectionService); manager.mPackageMonitor.onSomePackagesChanged(); manager.mPackageMonitor.onSomePackagesChanged(); verify(mMockContentCaptureManagerService, times(2)).createRemoteContentProtectionService(); verify(mMockRemoteContentProtectionService, times(2)) .onUpdateAllowlistRequest(mMockAllowlistCallback); verifyZeroInteractions(mMockAllowlistCallback); } @Test public void handlePackagesChanged_rateLimit_afterUpdate() throws Exception { mSetFlagsRule.enableFlags(FLAG_BLOCKLIST_UPDATE_ENABLED); mUseMockPackageMonitor = false; mUseMockAllowlistCallback = false; ContentProtectionAllowlistManager manager = new TestContentProtectionAllowlistManager(); when(mMockContentCaptureManagerService.createRemoteContentProtectionService()) .thenReturn(mMockRemoteContentProtectionService); manager.mPackageMonitor.onSomePackagesChanged(); manager.mAllowlistCallback.setAllowlist(List.of()); mTestLooper.dispatchNext(); manager.mPackageMonitor.onSomePackagesChanged(); verify(mMockContentCaptureManagerService, times(2)).createRemoteContentProtectionService(); verify(mMockRemoteContentProtectionService, times(2)) .onUpdateAllowlistRequest(manager.mAllowlistCallback); } private class TestContentProtectionAllowlistManager extends ContentProtectionAllowlistManager { TestContentProtectionAllowlistManager() { super(mMockContentCaptureManagerService, mHandler, TIMEOUT_MS); this(TIMEOUT_MS); } TestContentProtectionAllowlistManager(long timeoutMs) { super(mMockContentCaptureManagerService, mHandler, timeoutMs); } @Override protected IContentProtectionAllowlistCallback createAllowlistCallback() { return mUseMockAllowlistCallback ? mMockAllowlistCallback : super.createAllowlistCallback(); } @Override protected PackageMonitor createPackageMonitor() { return mMockPackageMonitor; return mUseMockPackageMonitor ? mMockPackageMonitor : super.createPackageMonitor(); } } } Loading
services/contentcapture/java/com/android/server/contentprotection/ContentProtectionAllowlistManager.java +33 −4 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Handler; import android.os.UserHandle; import android.service.contentcapture.IContentProtectionAllowlistCallback; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -52,6 +54,10 @@ public class ContentProtectionAllowlistManager { @NonNull final PackageMonitor mPackageMonitor; @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) @NonNull final IContentProtectionAllowlistCallback mAllowlistCallback; private final Object mHandlerToken = new Object(); private final Object mLock = new Object(); Loading @@ -74,6 +80,7 @@ public class ContentProtectionAllowlistManager { mHandler = handler; mTimeoutMs = timeoutMs; mPackageMonitor = createPackageMonitor(); mAllowlistCallback = createAllowlistCallback(); } /** Starts the manager. */ Loading Loading @@ -107,7 +114,7 @@ public class ContentProtectionAllowlistManager { return allowedPackages.contains(packageName); } private void setAllowlist(@NonNull List<String> packages) { private void handleUpdateAllowlistResponse(@NonNull List<String> packages) { synchronized (mLock) { mAllowedPackages = packages.stream().collect(Collectors.toUnmodifiableSet()); } Loading @@ -115,14 +122,14 @@ public class ContentProtectionAllowlistManager { } private void handleInitialUpdate() { handleUpdate(); handlePackagesChanged(); // Initial update done, start listening to package updates now mPackageMonitor.register( mContentCaptureManagerService.getContext(), UserHandle.ALL, mHandler); } private void handleUpdate() { private void handlePackagesChanged() { if (!blocklistUpdateEnabled()) { return; } Loading @@ -145,6 +152,12 @@ public class ContentProtectionAllowlistManager { // If there are any pending updates queued already, they can be removed immediately mHandler.removeCallbacksAndMessages(mHandlerToken); mUpdatePendingUntil = Instant.now().plusMillis(mTimeoutMs); try { remoteContentProtectionService.onUpdateAllowlistRequest(mAllowlistCallback); } catch (Exception ex) { Slog.e(TAG, "Failed to call remote service", ex); } } /** @hide */ Loading @@ -154,12 +167,28 @@ public class ContentProtectionAllowlistManager { return new ContentProtectionPackageMonitor(); } /** @hide */ @NonNull @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) protected IContentProtectionAllowlistCallback createAllowlistCallback() { return new ContentProtectionAllowlistCallback(); } private final class ContentProtectionPackageMonitor extends PackageMonitor { // This callback might be invoked multiple times, for more info refer to the comment above @Override public void onSomePackagesChanged() { handleUpdate(); handlePackagesChanged(); } } private final class ContentProtectionAllowlistCallback extends IContentProtectionAllowlistCallback.Stub { @Override public void setAllowlist(List<String> packages) { mHandler.post(() -> handleUpdateAllowlistResponse(packages)); } } }
services/tests/servicestests/src/com/android/server/contentprotection/ContentProtectionAllowlistManagerTest.java +169 −24 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import android.os.Handler; import android.os.UserHandle; import android.os.test.TestLooper; import android.platform.test.flag.junit.SetFlagsRule; import android.service.contentcapture.IContentProtectionAllowlistCallback; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; Loading @@ -48,6 +49,8 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import java.util.List; /** * Test for {@link ContentProtectionAllowlistManager}. * Loading @@ -58,7 +61,9 @@ import org.mockito.junit.MockitoRule; @SmallTest public class ContentProtectionAllowlistManagerTest { private static final String PACKAGE_NAME = "com.test.package.name"; private static final String FIRST_PACKAGE_NAME = "com.test.first.package.name"; private static final String SECOND_PACKAGE_NAME = "com.test.second.package.name"; private static final long TIMEOUT_MS = 111_111_111L; Loading @@ -74,12 +79,18 @@ public class ContentProtectionAllowlistManagerTest { @Mock private RemoteContentProtectionService mMockRemoteContentProtectionService; @Mock private IContentProtectionAllowlistCallback mMockAllowlistCallback; private final TestLooper mTestLooper = new TestLooper(); private Handler mHandler; private ContentProtectionAllowlistManager mContentProtectionAllowlistManager; private boolean mUseMockPackageMonitor = true; private boolean mUseMockAllowlistCallback = true; @Before public void setup() { mHandler = new Handler(mTestLooper.getLooper()); Loading @@ -91,6 +102,8 @@ public class ContentProtectionAllowlistManagerTest { assertThat(mHandler.hasMessagesOrCallbacks()).isFalse(); verifyZeroInteractions(mMockContentCaptureManagerService); verifyZeroInteractions(mMockPackageMonitor); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test Loading @@ -103,6 +116,8 @@ public class ContentProtectionAllowlistManagerTest { assertThat(mHandler.hasMessagesOrCallbacks()).isTrue(); verifyZeroInteractions(mMockContentCaptureManagerService); verifyZeroInteractions(mMockPackageMonitor); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test Loading @@ -117,6 +132,8 @@ public class ContentProtectionAllowlistManagerTest { verify(mMockContentCaptureManagerService).createRemoteContentProtectionService(); verify(mMockPackageMonitor).register(any(), eq(UserHandle.ALL), eq(mHandler)); verify(mMockPackageMonitor, never()).unregister(); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test Loading @@ -132,6 +149,8 @@ public class ContentProtectionAllowlistManagerTest { verify(mMockContentCaptureManagerService).createRemoteContentProtectionService(); verify(mMockPackageMonitor).register(any(), eq(UserHandle.ALL), eq(mHandler)); verify(mMockPackageMonitor, never()).unregister(); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test Loading @@ -144,6 +163,8 @@ public class ContentProtectionAllowlistManagerTest { assertThat(mHandler.hasMessagesOrCallbacks()).isTrue(); verifyZeroInteractions(mMockContentCaptureManagerService); verifyZeroInteractions(mMockPackageMonitor); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test Loading @@ -158,6 +179,8 @@ public class ContentProtectionAllowlistManagerTest { verifyZeroInteractions(mMockContentCaptureManagerService); verify(mMockPackageMonitor).register(any(), eq(UserHandle.ALL), eq(mHandler)); verify(mMockPackageMonitor, never()).unregister(); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test Loading @@ -173,6 +196,8 @@ public class ContentProtectionAllowlistManagerTest { verifyZeroInteractions(mMockContentCaptureManagerService); verify(mMockPackageMonitor).register(any(), eq(UserHandle.ALL), eq(mHandler)); verify(mMockPackageMonitor, never()).unregister(); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test Loading @@ -186,6 +211,8 @@ public class ContentProtectionAllowlistManagerTest { verifyZeroInteractions(mMockContentCaptureManagerService); verify(mMockPackageMonitor, never()).register(any(), any(), any()); verify(mMockPackageMonitor).unregister(); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test Loading @@ -201,6 +228,8 @@ public class ContentProtectionAllowlistManagerTest { verifyZeroInteractions(mMockContentCaptureManagerService); verify(mMockPackageMonitor, never()).register(any(), any(), any()); verify(mMockPackageMonitor).unregister(); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test Loading @@ -216,6 +245,8 @@ public class ContentProtectionAllowlistManagerTest { verify(mMockContentCaptureManagerService).createRemoteContentProtectionService(); verify(mMockPackageMonitor).register(any(), eq(UserHandle.ALL), eq(mHandler)); verify(mMockPackageMonitor).unregister(); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test Loading @@ -229,6 +260,8 @@ public class ContentProtectionAllowlistManagerTest { verifyZeroInteractions(mMockContentCaptureManagerService); verify(mMockPackageMonitor, never()).register(any(), any(), any()); verify(mMockPackageMonitor).unregister(); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test Loading @@ -244,6 +277,8 @@ public class ContentProtectionAllowlistManagerTest { verifyZeroInteractions(mMockContentCaptureManagerService); verify(mMockPackageMonitor, never()).register(any(), any(), any()); verify(mMockPackageMonitor).unregister(); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test Loading @@ -259,6 +294,8 @@ public class ContentProtectionAllowlistManagerTest { verifyZeroInteractions(mMockContentCaptureManagerService); verify(mMockPackageMonitor).register(any(), eq(UserHandle.ALL), eq(mHandler)); verify(mMockPackageMonitor).unregister(); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test Loading @@ -274,6 +311,8 @@ public class ContentProtectionAllowlistManagerTest { assertThat(mHandler.hasMessagesOrCallbacks()).isFalse(); verify(mMockPackageMonitor).register(any(), eq(UserHandle.ALL), eq(mHandler)); verify(mMockPackageMonitor).unregister(); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test Loading @@ -290,60 +329,130 @@ public class ContentProtectionAllowlistManagerTest { assertThat(mHandler.hasMessagesOrCallbacks()).isFalse(); verify(mMockPackageMonitor, times(2)).register(any(), eq(UserHandle.ALL), eq(mHandler)); verify(mMockPackageMonitor).unregister(); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test public void isAllowed_default() { boolean actual = mContentProtectionAllowlistManager.isAllowed(FIRST_PACKAGE_NAME); assertThat(actual).isFalse(); verifyZeroInteractions(mMockContentCaptureManagerService); verifyZeroInteractions(mMockPackageMonitor); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test public void isAllowed() { boolean actual = mContentProtectionAllowlistManager.isAllowed(PACKAGE_NAME); public void isAllowed_false() throws Exception { mUseMockAllowlistCallback = false; ContentProtectionAllowlistManager manager = new TestContentProtectionAllowlistManager(); manager.mAllowlistCallback.setAllowlist(List.of(FIRST_PACKAGE_NAME)); mTestLooper.dispatchNext(); boolean actual = manager.isAllowed(SECOND_PACKAGE_NAME); assertThat(actual).isFalse(); verifyZeroInteractions(mMockContentCaptureManagerService); verifyZeroInteractions(mMockPackageMonitor); verifyZeroInteractions(mMockRemoteContentProtectionService); } @Test public void handleUpdate_updateDisabled() { public void isAllowed_true() throws Exception { mUseMockAllowlistCallback = false; ContentProtectionAllowlistManager manager = new TestContentProtectionAllowlistManager(); manager.mAllowlistCallback.setAllowlist(List.of(FIRST_PACKAGE_NAME)); mTestLooper.dispatchNext(); boolean actual = manager.isAllowed(FIRST_PACKAGE_NAME); assertThat(actual).isTrue(); verifyZeroInteractions(mMockContentCaptureManagerService); verifyZeroInteractions(mMockPackageMonitor); verifyZeroInteractions(mMockRemoteContentProtectionService); } @Test public void handlePackagesChanged_updateDisabled() { mSetFlagsRule.disableFlags(FLAG_BLOCKLIST_UPDATE_ENABLED); ContentProtectionAllowlistManager manager = new ContentProtectionAllowlistManager( mMockContentCaptureManagerService, mHandler, TIMEOUT_MS); mUseMockPackageMonitor = false; ContentProtectionAllowlistManager manager = new TestContentProtectionAllowlistManager(); manager.mPackageMonitor.onSomePackagesChanged(); verifyZeroInteractions(mMockContentCaptureManagerService); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test public void handleUpdate_updateEnabled() { public void handlePackagesChanged_updateEnabled_noService() { mSetFlagsRule.enableFlags(FLAG_BLOCKLIST_UPDATE_ENABLED); ContentProtectionAllowlistManager manager = new ContentProtectionAllowlistManager( mMockContentCaptureManagerService, mHandler, TIMEOUT_MS); mUseMockPackageMonitor = false; ContentProtectionAllowlistManager manager = new TestContentProtectionAllowlistManager(); manager.mPackageMonitor.onSomePackagesChanged(); verify(mMockContentCaptureManagerService).createRemoteContentProtectionService(); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test public void handleUpdate_rateLimit_noService() { public void handlePackagesChanged_updateEnabled_withService() { mSetFlagsRule.enableFlags(FLAG_BLOCKLIST_UPDATE_ENABLED); ContentProtectionAllowlistManager manager = new ContentProtectionAllowlistManager( mMockContentCaptureManagerService, mHandler, TIMEOUT_MS); mUseMockPackageMonitor = false; ContentProtectionAllowlistManager manager = new TestContentProtectionAllowlistManager(); when(mMockContentCaptureManagerService.createRemoteContentProtectionService()) .thenReturn(mMockRemoteContentProtectionService); manager.mPackageMonitor.onSomePackagesChanged(); verify(mMockRemoteContentProtectionService) .onUpdateAllowlistRequest(mMockAllowlistCallback); verifyZeroInteractions(mMockAllowlistCallback); } @Test public void handlePackagesChanged_updateEnabled_withServiceException() { mSetFlagsRule.enableFlags(FLAG_BLOCKLIST_UPDATE_ENABLED); mUseMockPackageMonitor = false; ContentProtectionAllowlistManager manager = new TestContentProtectionAllowlistManager(); when(mMockContentCaptureManagerService.createRemoteContentProtectionService()) .thenReturn(mMockRemoteContentProtectionService); doThrow(new RuntimeException("TEST EXCEPTION")) .when(mMockRemoteContentProtectionService) .onUpdateAllowlistRequest(mMockAllowlistCallback); manager.mPackageMonitor.onSomePackagesChanged(); // Does not rethrow verify(mMockRemoteContentProtectionService) .onUpdateAllowlistRequest(mMockAllowlistCallback); verifyZeroInteractions(mMockAllowlistCallback); } @Test public void handlePackagesChanged_rateLimit_noService() { mSetFlagsRule.enableFlags(FLAG_BLOCKLIST_UPDATE_ENABLED); mUseMockPackageMonitor = false; ContentProtectionAllowlistManager manager = new TestContentProtectionAllowlistManager(); manager.mPackageMonitor.onSomePackagesChanged(); manager.mPackageMonitor.onSomePackagesChanged(); verify(mMockContentCaptureManagerService, times(2)).createRemoteContentProtectionService(); verifyZeroInteractions(mMockRemoteContentProtectionService); verifyZeroInteractions(mMockAllowlistCallback); } @Test public void handleUpdate_rateLimit_beforeTimeout() { public void handlePackagesChanged_rateLimit_beforeTimeout() { mSetFlagsRule.enableFlags(FLAG_BLOCKLIST_UPDATE_ENABLED); ContentProtectionAllowlistManager manager = new ContentProtectionAllowlistManager( mMockContentCaptureManagerService, mHandler, TIMEOUT_MS); mUseMockPackageMonitor = false; ContentProtectionAllowlistManager manager = new TestContentProtectionAllowlistManager(); when(mMockContentCaptureManagerService.createRemoteContentProtectionService()) .thenReturn(mMockRemoteContentProtectionService); Loading @@ -351,32 +460,68 @@ public class ContentProtectionAllowlistManagerTest { manager.mPackageMonitor.onSomePackagesChanged(); verify(mMockContentCaptureManagerService).createRemoteContentProtectionService(); verify(mMockRemoteContentProtectionService) .onUpdateAllowlistRequest(mMockAllowlistCallback); verifyZeroInteractions(mMockAllowlistCallback); } @Test public void handleUpdate_rateLimit_afterTimeout() { public void handlePackagesChanged_rateLimit_afterTimeout() { mSetFlagsRule.enableFlags(FLAG_BLOCKLIST_UPDATE_ENABLED); mUseMockPackageMonitor = false; ContentProtectionAllowlistManager manager = new ContentProtectionAllowlistManager( mMockContentCaptureManagerService, mHandler, /* timeoutMs= */ 0L); new TestContentProtectionAllowlistManager(/* timeoutMs= */ 0L); when(mMockContentCaptureManagerService.createRemoteContentProtectionService()) .thenReturn(mMockRemoteContentProtectionService); manager.mPackageMonitor.onSomePackagesChanged(); manager.mPackageMonitor.onSomePackagesChanged(); verify(mMockContentCaptureManagerService, times(2)).createRemoteContentProtectionService(); verify(mMockRemoteContentProtectionService, times(2)) .onUpdateAllowlistRequest(mMockAllowlistCallback); verifyZeroInteractions(mMockAllowlistCallback); } @Test public void handlePackagesChanged_rateLimit_afterUpdate() throws Exception { mSetFlagsRule.enableFlags(FLAG_BLOCKLIST_UPDATE_ENABLED); mUseMockPackageMonitor = false; mUseMockAllowlistCallback = false; ContentProtectionAllowlistManager manager = new TestContentProtectionAllowlistManager(); when(mMockContentCaptureManagerService.createRemoteContentProtectionService()) .thenReturn(mMockRemoteContentProtectionService); manager.mPackageMonitor.onSomePackagesChanged(); manager.mAllowlistCallback.setAllowlist(List.of()); mTestLooper.dispatchNext(); manager.mPackageMonitor.onSomePackagesChanged(); verify(mMockContentCaptureManagerService, times(2)).createRemoteContentProtectionService(); verify(mMockRemoteContentProtectionService, times(2)) .onUpdateAllowlistRequest(manager.mAllowlistCallback); } private class TestContentProtectionAllowlistManager extends ContentProtectionAllowlistManager { TestContentProtectionAllowlistManager() { super(mMockContentCaptureManagerService, mHandler, TIMEOUT_MS); this(TIMEOUT_MS); } TestContentProtectionAllowlistManager(long timeoutMs) { super(mMockContentCaptureManagerService, mHandler, timeoutMs); } @Override protected IContentProtectionAllowlistCallback createAllowlistCallback() { return mUseMockAllowlistCallback ? mMockAllowlistCallback : super.createAllowlistCallback(); } @Override protected PackageMonitor createPackageMonitor() { return mMockPackageMonitor; return mUseMockPackageMonitor ? mMockPackageMonitor : super.createPackageMonitor(); } } }