diff options
| author | 2025-02-18 10:18:19 -0800 | |
|---|---|---|
| committer | 2025-02-18 10:18:19 -0800 | |
| commit | 09526194e311ecf09e0d9c9f7f83d82f8099fc6b (patch) | |
| tree | 0e5530c9561ce6db34b64436e7a05157af6d181f | |
| parent | 768289ae3e764c607afcec88676d99f393b62260 (diff) | |
| parent | 4a7539beafde3fe8d54dd63972b1b51908c10390 (diff) | |
Merge "Exempt APP_STREAMING role holders from screenshare protections" into main
6 files changed, 174 insertions, 27 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerFlagDisabledTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerFlagDisabledTest.kt index 799e957656dc..bab5a2d6793d 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerFlagDisabledTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerFlagDisabledTest.kt @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.policy import android.app.IActivityManager +import android.app.role.RoleManager import android.content.pm.PackageManager import android.media.projection.MediaProjectionManager import android.os.Handler @@ -48,6 +49,7 @@ class SensitiveNotificationProtectionControllerFlagDisabledTest : SysuiTestCase( @Mock private lateinit var mediaProjectionManager: MediaProjectionManager @Mock private lateinit var packageManager: PackageManager @Mock private lateinit var telephonyManager: TelephonyManager + @Mock private lateinit var roleManager: RoleManager private lateinit var controller: SensitiveNotificationProtectionControllerImpl @Before @@ -62,9 +64,10 @@ class SensitiveNotificationProtectionControllerFlagDisabledTest : SysuiTestCase( activityManager, packageManager, telephonyManager, + roleManager, handler, FakeExecutor(FakeSystemClock()), - logger + logger, ) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerImpl.java index 9ab8175e13b8..36513f77f1a8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerImpl.java @@ -24,6 +24,9 @@ import static com.android.systemui.Flags.screenshareNotificationHidingBugFix; import android.annotation.MainThread; import android.app.IActivityManager; +import android.app.role.OnRoleHoldersChangedListener; +import android.app.role.RoleManager; +import android.companion.AssociationRequest; import android.content.Context; import android.content.pm.PackageManager; import android.database.ExecutorContentObserver; @@ -51,6 +54,8 @@ import com.android.systemui.util.Assert; import com.android.systemui.util.ListenerSet; import com.android.systemui.util.settings.GlobalSettings; +import java.util.List; +import java.util.Objects; import java.util.Random; import java.util.concurrent.Executor; @@ -63,12 +68,14 @@ public class SensitiveNotificationProtectionControllerImpl private static final String LOG_TAG = "SNPC"; private final SensitiveNotificationProtectionControllerLogger mLogger; private final PackageManager mPackageManager; + private final RoleManager mRoleManager; // Packages exempt from projection session protections (if they start a projection session) private final ArraySet<String> mSessionProtectionExemptPackages = new ArraySet<>(); // Packages exempt from individual notification protections (if they post a notification) private final ArraySet<String> mNotificationProtectionExemptPackages = new ArraySet<>(); private final ListenerSet<Runnable> mListeners = new ListenerSet<>(); private volatile MediaProjectionInfo mProjection; + private ArraySet<RoleHolder> mNotificationProtectionExemptByRolePackages = new ArraySet<>(); private SensitiveNotificatioMediaProjectionSession mActiveMediaProjectionSession; boolean mDisableScreenShareProtections = false; @@ -128,6 +135,27 @@ public class SensitiveNotificationProtectionControllerImpl } }; + @VisibleForTesting + final OnRoleHoldersChangedListener mRoleHoldersChangedListener = + new OnRoleHoldersChangedListener() { + @Override + public void onRoleHoldersChanged(@NonNull String roleName, + @NonNull UserHandle user) { + if (!roleName.equals(AssociationRequest.DEVICE_PROFILE_APP_STREAMING)) { + return; + } + + List<String> appStreamingRoleHolders = mRoleManager.getRoleHoldersAsUser( + roleName, user); + ArraySet<RoleHolder> roleHolders = new ArraySet<>(); + for (String appStreamingRoleHolder : appStreamingRoleHolders) { + RoleHolder roleHolder = new RoleHolder(appStreamingRoleHolder, user); + roleHolders.add(roleHolder); + } + mNotificationProtectionExemptByRolePackages = roleHolders; + } + }; + private void logSensitiveContentProtectionSessionStart( long sessionId, int projectionAppUid, boolean exempt) { mActiveMediaProjectionSession = @@ -166,11 +194,13 @@ public class SensitiveNotificationProtectionControllerImpl IActivityManager activityManager, PackageManager packageManager, TelephonyManager telephonyManager, + RoleManager roleManager, @Main Handler mainHandler, @Background Executor bgExecutor, SensitiveNotificationProtectionControllerLogger logger) { mLogger = logger; mPackageManager = packageManager; + mRoleManager = roleManager; if (!screenshareNotificationHiding()) { return; @@ -215,6 +245,8 @@ public class SensitiveNotificationProtectionControllerImpl }); mediaProjectionManager.addCallback(mMediaProjectionCallback, mainHandler); + roleManager.addOnRoleHoldersChangedListenerAsUser(bgExecutor, mRoleHoldersChangedListener, + UserHandle.ALL); } @NonNull @@ -314,6 +346,10 @@ public class SensitiveNotificationProtectionControllerImpl Log.w(LOG_TAG, "Screen share protections exempt for package " + info.getPackageName() + " via permission"); return null; + } else if (info != null && isAppStreamingRoleHolder(info)) { + Log.w(LOG_TAG, "Screen share protections exempt for package " + info.getPackageName() + + " via role(s) held"); + return null; } else if (info != null && info.getLaunchCookie() != null) { // Only enable sensitive content protection if sharing full screen // Launch cookie only set (non-null) if sharing single app/task @@ -323,11 +359,16 @@ public class SensitiveNotificationProtectionControllerImpl return info; } + private boolean isAppStreamingRoleHolder(@NonNull MediaProjectionInfo info) { + return mNotificationProtectionExemptByRolePackages.contains( + new RoleHolder(info.getPackageName(), info.getUserHandle())); + } + private boolean canRecordSensitiveContent(@NonNull String packageName) { // RECORD_SENSITIVE_CONTENT is flagged api on sensitiveNotificationAppProtection if (sensitiveNotificationAppProtection()) { return mPackageManager.checkPermission( - android.Manifest.permission.RECORD_SENSITIVE_CONTENT, packageName) + android.Manifest.permission.RECORD_SENSITIVE_CONTENT, packageName) == PackageManager.PERMISSION_GRANTED; } return false; @@ -382,4 +423,26 @@ public class SensitiveNotificationProtectionControllerImpl boolean userForcesRedaction = entry.isChannelVisibilityPrivate(); return notificationRequestsRedaction || userForcesRedaction; } + + private static final class RoleHolder { + private final String mPackageName; + private final UserHandle mUserHandle; + + RoleHolder(String packageName, UserHandle userHandle) { + mPackageName = packageName; + mUserHandle = userHandle; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof RoleHolder that)) return false; + return Objects.equals(mPackageName, that.mPackageName) && Objects.equals( + mUserHandle, that.mUserHandle); + } + + @Override + public int hashCode() { + return Objects.hash(mPackageName, mUserHandle); + } + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerTest.kt index 573927552acc..7e27783a116e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerTest.kt @@ -25,6 +25,9 @@ import android.app.Notification.VISIBILITY_PUBLIC import android.app.NotificationChannel import android.app.NotificationManager.IMPORTANCE_HIGH import android.app.NotificationManager.VISIBILITY_NO_OVERRIDE +import android.app.role.OnRoleHoldersChangedListener +import android.app.role.RoleManager +import android.companion.AssociationRequest import android.content.pm.PackageManager import android.media.projection.MediaProjectionInfo import android.media.projection.MediaProjectionManager @@ -89,6 +92,7 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { @Mock private lateinit var activityManager: IActivityManager @Mock private lateinit var mediaProjectionManager: MediaProjectionManager @Mock private lateinit var packageManager: PackageManager + @Mock private lateinit var roleManager: RoleManager @Mock private lateinit var telephonyManager: TelephonyManager @Mock private lateinit var listener1: Runnable @Mock private lateinit var listener2: Runnable @@ -98,6 +102,7 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { private lateinit var executor: FakeExecutor private lateinit var globalSettings: FakeGlobalSettings private lateinit var mediaProjectionCallback: MediaProjectionManager.Callback + private lateinit var roleHolderCallback: OnRoleHoldersChangedListener private lateinit var controller: SensitiveNotificationProtectionControllerImpl private lateinit var mediaProjectionInfo: MediaProjectionInfo @@ -117,14 +122,14 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { whenever( packageManager.getPackageUidAsUser( TEST_PROJECTION_PACKAGE_NAME, - UserHandle.CURRENT.identifier + UserHandle.CURRENT.identifier, ) ) .thenReturn(TEST_PROJECTION_PACKAGE_UID) whenever( packageManager.getPackageUidAsUser( BUGREPORT_PACKAGE_NAME, - UserHandle.CURRENT.identifier + UserHandle.CURRENT.identifier, ) ) .thenReturn(BUGREPORT_PACKAGE_UID) @@ -134,7 +139,7 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { whenever( packageManager.getPackageUidAsUser( mContext.packageName, - UserHandle.CURRENT.identifier + UserHandle.CURRENT.identifier, ) ) .thenReturn(mContext.applicationInfo.uid) @@ -155,9 +160,10 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { activityManager, packageManager, telephonyManager, + roleManager, mockExecutorHandler(executor), executor, - logger + logger, ) // Process pending work (getting global setting and list of exemptions) @@ -167,6 +173,9 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { mediaProjectionCallback = withArgCaptor { verify(mediaProjectionManager).addCallback(capture(), any()) } + roleHolderCallback = withArgCaptor { + verify(roleManager).addOnRoleHoldersChangedListenerAsUser(any(), capture(), any()) + } } @After @@ -307,7 +316,7 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { whenever( packageManager.checkPermission( android.Manifest.permission.RECORD_SENSITIVE_CONTENT, - mediaProjectionInfo.packageName + mediaProjectionInfo.packageName, ) ) .thenReturn(PackageManager.PERMISSION_GRANTED) @@ -322,7 +331,7 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { whenever( packageManager.checkPermission( android.Manifest.permission.RECORD_SENSITIVE_CONTENT, - mediaProjectionInfo.packageName + mediaProjectionInfo.packageName, ) ) .thenReturn(PackageManager.PERMISSION_GRANTED) @@ -340,6 +349,25 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { } @Test + fun isSensitiveStateActive_projectionActive_appStreamingRoleHolderExempt_false() { + setShareFullScreen() + whenever( + roleManager.getRoleHoldersAsUser( + AssociationRequest.DEVICE_PROFILE_APP_STREAMING, + mediaProjectionInfo.userHandle, + ) + ) + .thenReturn(listOf(TEST_PROJECTION_PACKAGE_NAME)) + roleHolderCallback.onRoleHoldersChanged( + AssociationRequest.DEVICE_PROFILE_APP_STREAMING, + mediaProjectionInfo.userHandle, + ) + mediaProjectionCallback.onStart(mediaProjectionInfo) + + assertFalse(controller.isSensitiveStateActive) + } + + @Test fun isSensitiveStateActive_projectionActive_disabledViaDevOption_false() { setDisabledViaDeveloperOption() mediaProjectionCallback.onStart(mediaProjectionInfo) @@ -449,7 +477,7 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { whenever( packageManager.checkPermission( android.Manifest.permission.RECORD_SENSITIVE_CONTENT, - mediaProjectionInfo.packageName + mediaProjectionInfo.packageName, ) ) .thenReturn(PackageManager.PERMISSION_GRANTED) @@ -466,7 +494,7 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { whenever( packageManager.checkPermission( android.Manifest.permission.RECORD_SENSITIVE_CONTENT, - mediaProjectionInfo.packageName + mediaProjectionInfo.packageName, ) ) .thenReturn(PackageManager.PERMISSION_GRANTED) @@ -528,7 +556,7 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { eq(TEST_PROJECTION_PACKAGE_UID), eq(false), eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__STATE__START), - eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI) + eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI), ) } @@ -541,7 +569,7 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { eq(TEST_PROJECTION_PACKAGE_UID), eq(false), eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__STATE__STOP), - eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI) + eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI), ) } } @@ -559,7 +587,7 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { eq(TEST_PROJECTION_PACKAGE_UID), eq(true), eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__STATE__START), - eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI) + eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI), ) } @@ -572,7 +600,7 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { eq(TEST_PROJECTION_PACKAGE_UID), eq(true), eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__STATE__STOP), - eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI) + eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI), ) } } @@ -590,7 +618,7 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { eq(TEST_PROJECTION_PACKAGE_UID), eq(true), eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__STATE__START), - eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI) + eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI), ) } @@ -603,7 +631,7 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { eq(TEST_PROJECTION_PACKAGE_UID), eq(true), eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__STATE__STOP), - eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI) + eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI), ) } } @@ -623,7 +651,7 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { eq(mContext.applicationInfo.uid), eq(true), eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__STATE__START), - eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI) + eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI), ) } @@ -636,7 +664,7 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { eq(mContext.applicationInfo.uid), eq(true), eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__STATE__STOP), - eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI) + eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI), ) } } @@ -654,7 +682,7 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { eq(BUGREPORT_PACKAGE_UID), eq(true), eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__STATE__START), - eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI) + eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI), ) } @@ -667,7 +695,7 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { eq(BUGREPORT_PACKAGE_UID), eq(true), eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__STATE__STOP), - eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI) + eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI), ) } } @@ -757,7 +785,7 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { return setupNotificationEntry( packageName, overrideVisibility = true, - overrideChannelVisibility = true + overrideChannelVisibility = true, ) } diff --git a/services/core/java/com/android/server/SensitiveContentProtectionManagerService.java b/services/core/java/com/android/server/SensitiveContentProtectionManagerService.java index 04edb5756599..cd632e638281 100644 --- a/services/core/java/com/android/server/SensitiveContentProtectionManagerService.java +++ b/services/core/java/com/android/server/SensitiveContentProtectionManagerService.java @@ -31,6 +31,8 @@ import static com.android.server.wm.WindowManagerInternal.OnWindowRemovedListene import android.annotation.NonNull; import android.annotation.Nullable; +import android.app.role.RoleManager; +import android.companion.AssociationRequest; import android.content.ComponentName; import android.content.Context; import android.content.pm.PackageManager; @@ -81,6 +83,8 @@ public final class SensitiveContentProtectionManagerService extends SystemServic private PackageManagerInternal mPackageManagerInternal; + private RoleManager mRoleManager; + @Nullable private WindowManagerInternal mWindowManager; @@ -225,7 +229,8 @@ public final class SensitiveContentProtectionManagerService extends SystemServic } @Override - public void onStart() {} + public void onStart() { + } @Override public void onBootPhase(int phase) { @@ -237,6 +242,7 @@ public final class SensitiveContentProtectionManagerService extends SystemServic init(getContext().getSystemService(MediaProjectionManager.class), LocalServices.getService(WindowManagerInternal.class), LocalServices.getService(PackageManagerInternal.class), + getContext().getSystemService(RoleManager.class), getExemptedPackages() ); if (sensitiveContentAppProtection()) { @@ -247,7 +253,8 @@ public final class SensitiveContentProtectionManagerService extends SystemServic @VisibleForTesting void init(MediaProjectionManager projectionManager, WindowManagerInternal windowManager, - PackageManagerInternal packageManagerInternal, ArraySet<String> exemptedPackages) { + PackageManagerInternal packageManagerInternal, RoleManager roleManager, + ArraySet<String> exemptedPackages) { if (DEBUG) Log.d(TAG, "init"); Objects.requireNonNull(projectionManager); @@ -256,6 +263,7 @@ public final class SensitiveContentProtectionManagerService extends SystemServic mProjectionManager = projectionManager; mWindowManager = windowManager; mPackageManagerInternal = packageManagerInternal; + mRoleManager = roleManager; mExemptedPackages = exemptedPackages; // TODO(b/317250444): use MediaProjectionManagerService directly, reduces unnecessary @@ -312,8 +320,10 @@ public final class SensitiveContentProtectionManagerService extends SystemServic boolean isPackageExempted = (mExemptedPackages != null && mExemptedPackages.contains( projectionInfo.getPackageName())) || canRecordSensitiveContent(projectionInfo.getPackageName()) + || holdsAppStreamingRole(projectionInfo.getPackageName(), + projectionInfo.getUserHandle()) || isAutofillServiceRecorderPackage(projectionInfo.getUserHandle().getIdentifier(), - projectionInfo.getPackageName()); + projectionInfo.getPackageName()); // TODO(b/324447419): move GlobalSettings lookup to background thread boolean isFeatureDisabled = Settings.Global.getInt(getContext().getContentResolver(), DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS, 0) != 0; @@ -348,6 +358,11 @@ public final class SensitiveContentProtectionManagerService extends SystemServic } } + private boolean holdsAppStreamingRole(String packageName, UserHandle userHandle) { + return mRoleManager.getRoleHoldersAsUser( + AssociationRequest.DEVICE_PROFILE_APP_STREAMING, userHandle).contains(packageName); + } + private void onProjectionEnd() { synchronized (mSensitiveContentProtectionLock) { mProjectionActive = false; diff --git a/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceContentTest.java b/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceContentTest.java index 5ddd8a50135b..2e315ecd7b37 100644 --- a/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceContentTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceContentTest.java @@ -26,7 +26,10 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import android.app.role.RoleManager; +import android.companion.AssociationRequest; import android.content.pm.PackageManagerInternal; import android.media.projection.MediaProjectionInfo; import android.media.projection.MediaProjectionManager; @@ -54,6 +57,7 @@ import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.util.List; import java.util.Set; @SmallTest @@ -74,6 +78,7 @@ public class SensitiveContentProtectionManagerServiceContentTest { @Mock private WindowManagerInternal mWindowManager; @Mock private MediaProjectionManager mProjectionManager; @Mock private PackageManagerInternal mPackageManagerInternal; + @Mock private RoleManager mRoleManager; private MediaProjectionInfo mMediaProjectionInfo; @Captor @@ -93,7 +98,8 @@ public class SensitiveContentProtectionManagerServiceContentTest { mSensitiveContentProtectionManagerService = new SensitiveContentProtectionManagerService(mContext); mSensitiveContentProtectionManagerService.init(mProjectionManager, mWindowManager, - mPackageManagerInternal, new ArraySet<>(Set.of(mExemptedScreenRecorderPackage))); + mPackageManagerInternal, mRoleManager, + new ArraySet<>(Set.of(mExemptedScreenRecorderPackage))); verify(mProjectionManager).addCallback(mMediaProjectionCallbackCaptor.capture(), any()); mMediaPorjectionCallback = mMediaProjectionCallbackCaptor.getValue(); mMediaProjectionInfo = @@ -152,7 +158,7 @@ public class SensitiveContentProtectionManagerServiceContentTest { String testAutofillService = mScreenRecorderPackage + "/com.example.SampleAutofillService"; int userId = Process.myUserHandle().getIdentifier(); Settings.Secure.putStringForUser(mContext.getContentResolver(), - Settings.Secure.AUTOFILL_SERVICE, testAutofillService , userId); + Settings.Secure.AUTOFILL_SERVICE, testAutofillService, userId); mMediaPorjectionCallback.onStart(mMediaProjectionInfo); mSensitiveContentProtectionManagerService.setSensitiveContentProtection( @@ -169,6 +175,19 @@ public class SensitiveContentProtectionManagerServiceContentTest { verify(mWindowManager, never()).addBlockScreenCaptureForApps(mPackageInfoCaptor.capture()); } + @Test + public void testAppStreamingRoleHolderExemption() { + when(mRoleManager.getRoleHoldersAsUser( + AssociationRequest.DEVICE_PROFILE_APP_STREAMING, + mMediaProjectionInfo.getUserHandle())).thenReturn( + List.of(mMediaProjectionInfo.getPackageName())); + + mMediaPorjectionCallback.onStart(mMediaProjectionInfo); + mSensitiveContentProtectionManagerService.setSensitiveContentProtection( + mPackageInfo.getWindowToken(), mPackageInfo.getPkg(), mPackageInfo.getUid(), true); + verify(mWindowManager, never()).addBlockScreenCaptureForApps(mPackageInfoCaptor.capture()); + } + private void mockDisabledViaDeveloperOption() { Settings.Global.putInt( mContext.getContentResolver(), diff --git a/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceNotificationTest.java b/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceNotificationTest.java index 32135f1cb7fa..3c6e18f822af 100644 --- a/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceNotificationTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceNotificationTest.java @@ -33,6 +33,8 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.app.role.RoleManager; +import android.companion.AssociationRequest; import android.content.pm.PackageManagerInternal; import android.media.projection.MediaProjectionInfo; import android.media.projection.MediaProjectionManager; @@ -67,6 +69,7 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; +import java.util.List; import java.util.Set; @SmallTest @@ -116,6 +119,9 @@ public class SensitiveContentProtectionManagerServiceNotificationTest { private PackageManagerInternal mPackageManagerInternal; @Mock + private RoleManager mRoleManager; + + @Mock private StatusBarNotification mNotification1; @Mock @@ -161,7 +167,8 @@ public class SensitiveContentProtectionManagerServiceNotificationTest { setupSensitiveNotification(); mSensitiveContentProtectionManagerService.init(mProjectionManager, mWindowManager, - mPackageManagerInternal, new ArraySet<>(Set.of(EXEMPTED_SCREEN_RECORDER_PACKAGE))); + mPackageManagerInternal, mRoleManager, + new ArraySet<>(Set.of(EXEMPTED_SCREEN_RECORDER_PACKAGE))); // Obtain useful mMediaProjectionCallback verify(mProjectionManager).addCallback(mMediaProjectionCallbackCaptor.capture(), any()); @@ -315,6 +322,18 @@ public class SensitiveContentProtectionManagerServiceNotificationTest { } @Test + public void mediaProjectionOnStart_verifyExemptedAppStreamingPackage() { + MediaProjectionInfo mediaProjectionInfo = createMediaProjectionInfo(); + when(mRoleManager.getRoleHoldersAsUser(AssociationRequest.DEVICE_PROFILE_APP_STREAMING, + mediaProjectionInfo.getUserHandle())).thenReturn( + List.of(mediaProjectionInfo.getPackageName())); + + mMediaProjectionCallbackCaptor.getValue().onStart(mediaProjectionInfo); + + verify(mWindowManager, never()).addBlockScreenCaptureForApps(mPackageInfoCaptor.capture()); + } + + @Test public void mediaProjectionOnStart_verifyExemptedRecorderPackage() { MediaProjectionInfo mediaProjectionInfo = createExemptMediaProjectionInfo(); |