diff options
3 files changed, 56 insertions, 7 deletions
diff --git a/services/core/java/com/android/server/SensitiveContentProtectionManagerService.java b/services/core/java/com/android/server/SensitiveContentProtectionManagerService.java index 0904c47b61f2..7d8aad7ab490 100644 --- a/services/core/java/com/android/server/SensitiveContentProtectionManagerService.java +++ b/services/core/java/com/android/server/SensitiveContentProtectionManagerService.java @@ -63,6 +63,9 @@ public final class SensitiveContentProtectionManagerService extends SystemServic @Nullable private MediaProjectionManager mProjectionManager; @Nullable private WindowManagerInternal mWindowManager; + // screen recorder packages exempted from screen share protection. + private ArraySet<String> mExemptedPackages = null; + final Object mSensitiveContentProtectionLock = new Object(); @GuardedBy("mSensitiveContentProtectionLock") @@ -76,7 +79,7 @@ public final class SensitiveContentProtectionManagerService extends SystemServic Trace.beginSection( "SensitiveContentProtectionManagerService.onProjectionStart"); try { - onProjectionStart(); + onProjectionStart(info); } finally { Trace.endSection(); } @@ -113,15 +116,25 @@ public final class SensitiveContentProtectionManagerService extends SystemServic if (DEBUG) Log.d(TAG, "onBootPhase - PHASE_BOOT_COMPLETED"); init(getContext().getSystemService(MediaProjectionManager.class), - LocalServices.getService(WindowManagerInternal.class)); + LocalServices.getService(WindowManagerInternal.class), + getExemptedPackages()); if (sensitiveContentAppProtection()) { publishBinderService(Context.SENSITIVE_CONTENT_PROTECTION_SERVICE, new SensitiveContentProtectionManagerServiceBinder()); } } + // These packages are exempted from screen share protection. + private ArraySet<String> getExemptedPackages() { + final ArraySet<String> exemptedPackages = + SystemConfig.getInstance().getBugreportWhitelistedPackages(); + // TODO(b/323361046) - Add sys ui recorder package. + return exemptedPackages; + } + @VisibleForTesting - void init(MediaProjectionManager projectionManager, WindowManagerInternal windowManager) { + void init(MediaProjectionManager projectionManager, WindowManagerInternal windowManager, + ArraySet<String> exemptedPackages) { if (DEBUG) Log.d(TAG, "init"); Objects.requireNonNull(projectionManager); @@ -129,6 +142,7 @@ public final class SensitiveContentProtectionManagerService extends SystemServic mProjectionManager = projectionManager; mWindowManager = windowManager; + mExemptedPackages = exemptedPackages; // TODO(b/317250444): use MediaProjectionManagerService directly, reduces unnecessary // handler, delegate, and binder death recipient @@ -165,7 +179,11 @@ public final class SensitiveContentProtectionManagerService extends SystemServic } } - private void onProjectionStart() { + private void onProjectionStart(MediaProjectionInfo info) { + if (mExemptedPackages != null && mExemptedPackages.contains(info.getPackageName())) { + Log.w(TAG, info.getPackageName() + " is exempted from screen share protection."); + return; + } // TODO(b/324447419): move GlobalSettings lookup to background thread boolean disableScreenShareProtections = Settings.Global.getInt(getContext().getContentResolver(), diff --git a/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceContentTest.java b/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceContentTest.java index dad36e787360..2366f56707fa 100644 --- a/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceContentTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceContentTest.java @@ -30,6 +30,7 @@ import static org.mockito.Mockito.verifyZeroInteractions; import android.media.projection.MediaProjectionInfo; import android.media.projection.MediaProjectionManager; import android.os.Binder; +import android.os.Process; import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; @@ -52,6 +53,8 @@ import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.util.Set; + @SmallTest @RunWith(AndroidTestingRunner.class) @RequiresFlagsEnabled(FLAG_SENSITIVE_CONTENT_APP_PROTECTION) @@ -62,12 +65,14 @@ import org.mockito.MockitoAnnotations; public class SensitiveContentProtectionManagerServiceContentTest { private final PackageInfo mPackageInfo = new PackageInfo("test.package", 12345, new Binder()); + private final String mScreenRecorderPackage = "test.screen.recorder.package"; + private final String mExemptedScreenRecorderPackage = "test.exempted.screen.recorder.package"; private SensitiveContentProtectionManagerService mSensitiveContentProtectionManagerService; private MediaProjectionManager.Callback mMediaPorjectionCallback; @Mock private WindowManagerInternal mWindowManager; @Mock private MediaProjectionManager mProjectionManager; - @Mock private MediaProjectionInfo mMediaProjectionInfo; + private MediaProjectionInfo mMediaProjectionInfo; @Captor private ArgumentCaptor<MediaProjectionManager.Callback> mMediaProjectionCallbackCaptor; @@ -85,9 +90,22 @@ public class SensitiveContentProtectionManagerServiceContentTest { MockitoAnnotations.initMocks(this); mSensitiveContentProtectionManagerService = new SensitiveContentProtectionManagerService(mContext); - mSensitiveContentProtectionManagerService.init(mProjectionManager, mWindowManager); + mSensitiveContentProtectionManagerService.init(mProjectionManager, mWindowManager, + new ArraySet<>(Set.of(mExemptedScreenRecorderPackage))); verify(mProjectionManager).addCallback(mMediaProjectionCallbackCaptor.capture(), any()); mMediaPorjectionCallback = mMediaProjectionCallbackCaptor.getValue(); + mMediaProjectionInfo = + new MediaProjectionInfo(mScreenRecorderPackage, Process.myUserHandle(), null); + } + + @Test + public void testExemptedRecorderPackageForScreenCapture() { + MediaProjectionInfo exemptedRecorderPackage = new MediaProjectionInfo( + mExemptedScreenRecorderPackage, Process.myUserHandle(), null); + mMediaPorjectionCallback.onStart(exemptedRecorderPackage); + mSensitiveContentProtectionManagerService.setSensitiveContentProtection( + mPackageInfo.getWindowToken(), mPackageInfo.getPkg(), mPackageInfo.getUid(), true); + verifyZeroInteractions(mWindowManager); } @Test diff --git a/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceNotificationTest.java b/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceNotificationTest.java index 08050a9b30e0..e74fe296d0a5 100644 --- a/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceNotificationTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceNotificationTest.java @@ -78,6 +78,8 @@ public class SensitiveContentProtectionManagerServiceNotificationTest { private static final String NOTIFICATION_PKG_1 = "com.android.server.notification.one"; private static final String NOTIFICATION_PKG_2 = "com.android.server.notification.two"; + private static final String EXEMPTED_SCREEN_RECORDER_PACKAGE = "test.screen.recorder.package"; + private static final int NOTIFICATION_UID_1 = 5; private static final int NOTIFICATION_UID_2 = 6; @@ -138,7 +140,8 @@ public class SensitiveContentProtectionManagerServiceNotificationTest { setupSensitiveNotification(); - mSensitiveContentProtectionManagerService.init(mProjectionManager, mWindowManager); + mSensitiveContentProtectionManagerService.init(mProjectionManager, mWindowManager, + new ArraySet<>(Set.of(EXEMPTED_SCREEN_RECORDER_PACKAGE))); // Obtain useful mMediaProjectionCallback verify(mProjectionManager).addCallback(mMediaProjectionCallbackCaptor.capture(), any()); @@ -275,6 +278,16 @@ public class SensitiveContentProtectionManagerServiceNotificationTest { } @Test + public void mediaProjectionOnStart_verifyExemptedRecorderPackage() { + MediaProjectionInfo mediaProjectionInfo = mock(MediaProjectionInfo.class); + when(mediaProjectionInfo.getPackageName()).thenReturn(EXEMPTED_SCREEN_RECORDER_PACKAGE); + + mMediaProjectionCallbackCaptor.getValue().onStart(mediaProjectionInfo); + + verifyZeroInteractions(mWindowManager); + } + + @Test public void mediaProjectionOnStart_onProjectionStart_setWmBlockedPackages() { ArraySet<PackageInfo> expectedBlockedPackages = setupSensitiveNotification(); |