Loading packages/SystemUI/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerImpl.java +43 −21 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.systemui.statusbar.policy; import static android.permission.flags.Flags.sensitiveNotificationAppProtection; import static android.provider.Settings.Global.DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS; import static com.android.server.notification.Flags.screenshareNotificationHiding; Loading @@ -23,6 +24,7 @@ import static com.android.server.notification.Flags.screenshareNotificationHidin import android.annotation.MainThread; import android.app.IActivityManager; import android.content.Context; import android.content.pm.PackageManager; import android.database.ExecutorContentObserver; import android.media.projection.MediaProjectionInfo; import android.media.projection.MediaProjectionManager; Loading @@ -33,6 +35,9 @@ import android.service.notification.StatusBarNotification; import android.util.ArraySet; import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Background; Loading @@ -52,6 +57,7 @@ public class SensitiveNotificationProtectionControllerImpl implements SensitiveNotificationProtectionController { private static final String LOG_TAG = "SNPC"; private final SensitiveNotificationProtectionControllerLogger mLogger; private final PackageManager mPackageManager; private final ArraySet<String> mExemptPackages = new ArraySet<>(); private final ListenerSet<Runnable> mListeners = new ListenerSet<>(); private volatile MediaProjectionInfo mProjection; Loading @@ -64,17 +70,7 @@ public class SensitiveNotificationProtectionControllerImpl public void onStart(MediaProjectionInfo info) { Trace.beginSection("SNPC.onProjectionStart"); try { if (mDisableScreenShareProtections) { Log.w(LOG_TAG, "Screen share protections disabled, ignoring projectionstart"); mLogger.logProjectionStart(false, info.getPackageName()); return; } // Only enable sensitive content protection if sharing full screen // Launch cookie only set (non-null) if sharing single app/task updateProjectionStateAndNotifyListeners( (info.getLaunchCookie() == null) ? info : null); updateProjectionStateAndNotifyListeners(info); mLogger.logProjectionStart(isSensitiveStateActive(), info.getPackageName()); } finally { Trace.endSection(); Loading @@ -99,10 +95,12 @@ public class SensitiveNotificationProtectionControllerImpl GlobalSettings settings, MediaProjectionManager mediaProjectionManager, IActivityManager activityManager, PackageManager packageManager, @Main Handler mainHandler, @Background Executor bgExecutor, SensitiveNotificationProtectionControllerLogger logger) { mLogger = logger; mPackageManager = packageManager; if (!screenshareNotificationHiding()) { return; Loading Loading @@ -168,7 +166,7 @@ public class SensitiveNotificationProtectionControllerImpl mExemptPackages.addAll(exemptPackages); if (mProjection != null) { mListeners.forEach(Runnable::run); updateProjectionStateAndNotifyListeners(mProjection); } } Loading @@ -177,13 +175,13 @@ public class SensitiveNotificationProtectionControllerImpl * listeners */ @MainThread private void updateProjectionStateAndNotifyListeners(MediaProjectionInfo info) { private void updateProjectionStateAndNotifyListeners(@Nullable MediaProjectionInfo info) { Assert.isMainThread(); // capture previous state boolean wasSensitive = isSensitiveStateActive(); // update internal state mProjection = info; mProjection = getNonExemptProjectionInfo(info); // if either previous or new state is sensitive, notify listeners. if (wasSensitive || isSensitiveStateActive()) { Loading @@ -191,6 +189,36 @@ public class SensitiveNotificationProtectionControllerImpl } } private MediaProjectionInfo getNonExemptProjectionInfo(@Nullable MediaProjectionInfo info) { if (mDisableScreenShareProtections) { Log.w(LOG_TAG, "Screen share protections disabled"); return null; } else if (info != null && mExemptPackages.contains(info.getPackageName())) { Log.w(LOG_TAG, "Screen share protections exempt for package " + info.getPackageName()); return null; } else if (info != null && canRecordSensitiveContent(info.getPackageName())) { Log.w(LOG_TAG, "Screen share protections exempt for package " + info.getPackageName() + " via permission"); 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 Log.w(LOG_TAG, "Screen share protections exempt for single app screenshare"); return null; } return info; } 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) == PackageManager.PERMISSION_GRANTED; } return false; } @Override public void registerSensitiveStateListener(Runnable onSensitiveStateChanged) { mListeners.addIfAbsent(onSensitiveStateChanged); Loading @@ -201,15 +229,9 @@ public class SensitiveNotificationProtectionControllerImpl mListeners.remove(onSensitiveStateChanged); } // TODO(b/323396693): opportunity for optimization @Override public boolean isSensitiveStateActive() { MediaProjectionInfo projection = mProjection; if (projection == null) { return false; } return !mExemptPackages.contains(projection.getPackageName()); return mProjection != null; } @Override Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerFlagDisabledTest.kt +3 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.policy import android.app.IActivityManager import android.content.pm.PackageManager import android.media.projection.MediaProjectionManager import android.os.Handler import android.platform.test.annotations.DisableFlags Loading Loading @@ -44,6 +45,7 @@ class SensitiveNotificationProtectionControllerFlagDisabledTest : SysuiTestCase( @Mock private lateinit var handler: Handler @Mock private lateinit var activityManager: IActivityManager @Mock private lateinit var mediaProjectionManager: MediaProjectionManager @Mock private lateinit var packageManager: PackageManager private lateinit var controller: SensitiveNotificationProtectionControllerImpl @Before Loading @@ -56,6 +58,7 @@ class SensitiveNotificationProtectionControllerFlagDisabledTest : SysuiTestCase( FakeGlobalSettings(), mediaProjectionManager, activityManager, packageManager, handler, FakeExecutor(FakeSystemClock()), logger Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerTest.kt +79 −0 Original line number Diff line number Diff line Loading @@ -25,9 +25,14 @@ 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.content.pm.PackageManager import android.media.projection.MediaProjectionInfo import android.media.projection.MediaProjectionManager import android.permission.flags.Flags.FLAG_SENSITIVE_NOTIFICATION_APP_PROTECTION import android.platform.test.annotations.EnableFlags import android.platform.test.annotations.RequiresFlagsDisabled import android.platform.test.annotations.RequiresFlagsEnabled import android.platform.test.flag.junit.DeviceFlagsValueProvider import android.provider.Settings.Global.DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS import android.testing.AndroidTestingRunner import android.testing.TestableLooper.RunWithLooper Loading @@ -48,9 +53,11 @@ import org.junit.Assert.assertFalse import org.junit.Assert.assertNotNull import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.any import org.mockito.ArgumentMatchers.anyString import org.mockito.Mock import org.mockito.Mockito.mock import org.mockito.Mockito.times Loading @@ -64,10 +71,13 @@ import org.mockito.MockitoAnnotations @RunWithLooper @EnableFlags(Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING) class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { @get:Rule val checkFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule() private val logger = SensitiveNotificationProtectionControllerLogger(logcatLogBuffer()) @Mock private lateinit var activityManager: IActivityManager @Mock private lateinit var mediaProjectionManager: MediaProjectionManager @Mock private lateinit var packageManager: PackageManager @Mock private lateinit var mediaProjectionInfo: MediaProjectionInfo @Mock private lateinit var listener1: Runnable @Mock private lateinit var listener2: Runnable Loading @@ -87,6 +97,9 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { whenever(activityManager.bugreportWhitelistedPackages) .thenReturn(listOf(BUGREPORT_PACKAGE_NAME)) whenever(packageManager.checkPermission(anyString(), anyString())) .thenReturn(PackageManager.PERMISSION_DENIED) executor = FakeExecutor(FakeSystemClock()) globalSettings = FakeGlobalSettings() controller = Loading @@ -95,6 +108,7 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { globalSettings, mediaProjectionManager, activityManager, packageManager, mockExecutorHandler(executor), executor, logger Loading Loading @@ -236,6 +250,36 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { assertFalse(controller.isSensitiveStateActive) } @Test @RequiresFlagsDisabled(FLAG_SENSITIVE_NOTIFICATION_APP_PROTECTION) fun isSensitiveStateActive_projectionActive_permissionExempt_flagDisabled_true() { whenever( packageManager.checkPermission( android.Manifest.permission.RECORD_SENSITIVE_CONTENT, mediaProjectionInfo.packageName ) ) .thenReturn(PackageManager.PERMISSION_GRANTED) mediaProjectionCallback.onStart(mediaProjectionInfo) assertTrue(controller.isSensitiveStateActive) } @Test @RequiresFlagsEnabled(FLAG_SENSITIVE_NOTIFICATION_APP_PROTECTION) fun isSensitiveStateActive_projectionActive_permissionExempt_false() { whenever( packageManager.checkPermission( android.Manifest.permission.RECORD_SENSITIVE_CONTENT, mediaProjectionInfo.packageName ) ) .thenReturn(PackageManager.PERMISSION_GRANTED) mediaProjectionCallback.onStart(mediaProjectionInfo) assertFalse(controller.isSensitiveStateActive) } @Test fun isSensitiveStateActive_projectionActive_bugReportHandlerExempt_false() { whenever(mediaProjectionInfo.packageName).thenReturn(BUGREPORT_PACKAGE_NAME) Loading Loading @@ -308,6 +352,40 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { assertFalse(controller.shouldProtectNotification(notificationEntry)) } @Test @RequiresFlagsDisabled(FLAG_SENSITIVE_NOTIFICATION_APP_PROTECTION) fun shouldProtectNotification_projectionActive_permissionExempt_flagDisabled_true() { whenever( packageManager.checkPermission( android.Manifest.permission.RECORD_SENSITIVE_CONTENT, mediaProjectionInfo.packageName ) ) .thenReturn(PackageManager.PERMISSION_GRANTED) mediaProjectionCallback.onStart(mediaProjectionInfo) val notificationEntry = setupNotificationEntry(TEST_PACKAGE_NAME, false) assertTrue(controller.shouldProtectNotification(notificationEntry)) } @Test @RequiresFlagsEnabled(FLAG_SENSITIVE_NOTIFICATION_APP_PROTECTION) fun shouldProtectNotification_projectionActive_permissionExempt_false() { whenever( packageManager.checkPermission( android.Manifest.permission.RECORD_SENSITIVE_CONTENT, mediaProjectionInfo.packageName ) ) .thenReturn(PackageManager.PERMISSION_GRANTED) mediaProjectionCallback.onStart(mediaProjectionInfo) val notificationEntry = setupNotificationEntry(TEST_PACKAGE_NAME, false) assertFalse(controller.shouldProtectNotification(notificationEntry)) } @Test fun shouldProtectNotification_projectionActive_bugReportHandlerExempt_false() { whenever(mediaProjectionInfo.packageName).thenReturn(BUGREPORT_PACKAGE_NAME) Loading @@ -327,6 +405,7 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { assertFalse(controller.shouldProtectNotification(notificationEntry)) } @Test fun shouldProtectNotification_projectionActive_publicNotification_false() { mediaProjectionCallback.onStart(mediaProjectionInfo) Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerImpl.java +43 −21 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.systemui.statusbar.policy; import static android.permission.flags.Flags.sensitiveNotificationAppProtection; import static android.provider.Settings.Global.DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS; import static com.android.server.notification.Flags.screenshareNotificationHiding; Loading @@ -23,6 +24,7 @@ import static com.android.server.notification.Flags.screenshareNotificationHidin import android.annotation.MainThread; import android.app.IActivityManager; import android.content.Context; import android.content.pm.PackageManager; import android.database.ExecutorContentObserver; import android.media.projection.MediaProjectionInfo; import android.media.projection.MediaProjectionManager; Loading @@ -33,6 +35,9 @@ import android.service.notification.StatusBarNotification; import android.util.ArraySet; import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Background; Loading @@ -52,6 +57,7 @@ public class SensitiveNotificationProtectionControllerImpl implements SensitiveNotificationProtectionController { private static final String LOG_TAG = "SNPC"; private final SensitiveNotificationProtectionControllerLogger mLogger; private final PackageManager mPackageManager; private final ArraySet<String> mExemptPackages = new ArraySet<>(); private final ListenerSet<Runnable> mListeners = new ListenerSet<>(); private volatile MediaProjectionInfo mProjection; Loading @@ -64,17 +70,7 @@ public class SensitiveNotificationProtectionControllerImpl public void onStart(MediaProjectionInfo info) { Trace.beginSection("SNPC.onProjectionStart"); try { if (mDisableScreenShareProtections) { Log.w(LOG_TAG, "Screen share protections disabled, ignoring projectionstart"); mLogger.logProjectionStart(false, info.getPackageName()); return; } // Only enable sensitive content protection if sharing full screen // Launch cookie only set (non-null) if sharing single app/task updateProjectionStateAndNotifyListeners( (info.getLaunchCookie() == null) ? info : null); updateProjectionStateAndNotifyListeners(info); mLogger.logProjectionStart(isSensitiveStateActive(), info.getPackageName()); } finally { Trace.endSection(); Loading @@ -99,10 +95,12 @@ public class SensitiveNotificationProtectionControllerImpl GlobalSettings settings, MediaProjectionManager mediaProjectionManager, IActivityManager activityManager, PackageManager packageManager, @Main Handler mainHandler, @Background Executor bgExecutor, SensitiveNotificationProtectionControllerLogger logger) { mLogger = logger; mPackageManager = packageManager; if (!screenshareNotificationHiding()) { return; Loading Loading @@ -168,7 +166,7 @@ public class SensitiveNotificationProtectionControllerImpl mExemptPackages.addAll(exemptPackages); if (mProjection != null) { mListeners.forEach(Runnable::run); updateProjectionStateAndNotifyListeners(mProjection); } } Loading @@ -177,13 +175,13 @@ public class SensitiveNotificationProtectionControllerImpl * listeners */ @MainThread private void updateProjectionStateAndNotifyListeners(MediaProjectionInfo info) { private void updateProjectionStateAndNotifyListeners(@Nullable MediaProjectionInfo info) { Assert.isMainThread(); // capture previous state boolean wasSensitive = isSensitiveStateActive(); // update internal state mProjection = info; mProjection = getNonExemptProjectionInfo(info); // if either previous or new state is sensitive, notify listeners. if (wasSensitive || isSensitiveStateActive()) { Loading @@ -191,6 +189,36 @@ public class SensitiveNotificationProtectionControllerImpl } } private MediaProjectionInfo getNonExemptProjectionInfo(@Nullable MediaProjectionInfo info) { if (mDisableScreenShareProtections) { Log.w(LOG_TAG, "Screen share protections disabled"); return null; } else if (info != null && mExemptPackages.contains(info.getPackageName())) { Log.w(LOG_TAG, "Screen share protections exempt for package " + info.getPackageName()); return null; } else if (info != null && canRecordSensitiveContent(info.getPackageName())) { Log.w(LOG_TAG, "Screen share protections exempt for package " + info.getPackageName() + " via permission"); 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 Log.w(LOG_TAG, "Screen share protections exempt for single app screenshare"); return null; } return info; } 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) == PackageManager.PERMISSION_GRANTED; } return false; } @Override public void registerSensitiveStateListener(Runnable onSensitiveStateChanged) { mListeners.addIfAbsent(onSensitiveStateChanged); Loading @@ -201,15 +229,9 @@ public class SensitiveNotificationProtectionControllerImpl mListeners.remove(onSensitiveStateChanged); } // TODO(b/323396693): opportunity for optimization @Override public boolean isSensitiveStateActive() { MediaProjectionInfo projection = mProjection; if (projection == null) { return false; } return !mExemptPackages.contains(projection.getPackageName()); return mProjection != null; } @Override Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerFlagDisabledTest.kt +3 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.policy import android.app.IActivityManager import android.content.pm.PackageManager import android.media.projection.MediaProjectionManager import android.os.Handler import android.platform.test.annotations.DisableFlags Loading Loading @@ -44,6 +45,7 @@ class SensitiveNotificationProtectionControllerFlagDisabledTest : SysuiTestCase( @Mock private lateinit var handler: Handler @Mock private lateinit var activityManager: IActivityManager @Mock private lateinit var mediaProjectionManager: MediaProjectionManager @Mock private lateinit var packageManager: PackageManager private lateinit var controller: SensitiveNotificationProtectionControllerImpl @Before Loading @@ -56,6 +58,7 @@ class SensitiveNotificationProtectionControllerFlagDisabledTest : SysuiTestCase( FakeGlobalSettings(), mediaProjectionManager, activityManager, packageManager, handler, FakeExecutor(FakeSystemClock()), logger Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerTest.kt +79 −0 Original line number Diff line number Diff line Loading @@ -25,9 +25,14 @@ 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.content.pm.PackageManager import android.media.projection.MediaProjectionInfo import android.media.projection.MediaProjectionManager import android.permission.flags.Flags.FLAG_SENSITIVE_NOTIFICATION_APP_PROTECTION import android.platform.test.annotations.EnableFlags import android.platform.test.annotations.RequiresFlagsDisabled import android.platform.test.annotations.RequiresFlagsEnabled import android.platform.test.flag.junit.DeviceFlagsValueProvider import android.provider.Settings.Global.DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS import android.testing.AndroidTestingRunner import android.testing.TestableLooper.RunWithLooper Loading @@ -48,9 +53,11 @@ import org.junit.Assert.assertFalse import org.junit.Assert.assertNotNull import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.any import org.mockito.ArgumentMatchers.anyString import org.mockito.Mock import org.mockito.Mockito.mock import org.mockito.Mockito.times Loading @@ -64,10 +71,13 @@ import org.mockito.MockitoAnnotations @RunWithLooper @EnableFlags(Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING) class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { @get:Rule val checkFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule() private val logger = SensitiveNotificationProtectionControllerLogger(logcatLogBuffer()) @Mock private lateinit var activityManager: IActivityManager @Mock private lateinit var mediaProjectionManager: MediaProjectionManager @Mock private lateinit var packageManager: PackageManager @Mock private lateinit var mediaProjectionInfo: MediaProjectionInfo @Mock private lateinit var listener1: Runnable @Mock private lateinit var listener2: Runnable Loading @@ -87,6 +97,9 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { whenever(activityManager.bugreportWhitelistedPackages) .thenReturn(listOf(BUGREPORT_PACKAGE_NAME)) whenever(packageManager.checkPermission(anyString(), anyString())) .thenReturn(PackageManager.PERMISSION_DENIED) executor = FakeExecutor(FakeSystemClock()) globalSettings = FakeGlobalSettings() controller = Loading @@ -95,6 +108,7 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { globalSettings, mediaProjectionManager, activityManager, packageManager, mockExecutorHandler(executor), executor, logger Loading Loading @@ -236,6 +250,36 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { assertFalse(controller.isSensitiveStateActive) } @Test @RequiresFlagsDisabled(FLAG_SENSITIVE_NOTIFICATION_APP_PROTECTION) fun isSensitiveStateActive_projectionActive_permissionExempt_flagDisabled_true() { whenever( packageManager.checkPermission( android.Manifest.permission.RECORD_SENSITIVE_CONTENT, mediaProjectionInfo.packageName ) ) .thenReturn(PackageManager.PERMISSION_GRANTED) mediaProjectionCallback.onStart(mediaProjectionInfo) assertTrue(controller.isSensitiveStateActive) } @Test @RequiresFlagsEnabled(FLAG_SENSITIVE_NOTIFICATION_APP_PROTECTION) fun isSensitiveStateActive_projectionActive_permissionExempt_false() { whenever( packageManager.checkPermission( android.Manifest.permission.RECORD_SENSITIVE_CONTENT, mediaProjectionInfo.packageName ) ) .thenReturn(PackageManager.PERMISSION_GRANTED) mediaProjectionCallback.onStart(mediaProjectionInfo) assertFalse(controller.isSensitiveStateActive) } @Test fun isSensitiveStateActive_projectionActive_bugReportHandlerExempt_false() { whenever(mediaProjectionInfo.packageName).thenReturn(BUGREPORT_PACKAGE_NAME) Loading Loading @@ -308,6 +352,40 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { assertFalse(controller.shouldProtectNotification(notificationEntry)) } @Test @RequiresFlagsDisabled(FLAG_SENSITIVE_NOTIFICATION_APP_PROTECTION) fun shouldProtectNotification_projectionActive_permissionExempt_flagDisabled_true() { whenever( packageManager.checkPermission( android.Manifest.permission.RECORD_SENSITIVE_CONTENT, mediaProjectionInfo.packageName ) ) .thenReturn(PackageManager.PERMISSION_GRANTED) mediaProjectionCallback.onStart(mediaProjectionInfo) val notificationEntry = setupNotificationEntry(TEST_PACKAGE_NAME, false) assertTrue(controller.shouldProtectNotification(notificationEntry)) } @Test @RequiresFlagsEnabled(FLAG_SENSITIVE_NOTIFICATION_APP_PROTECTION) fun shouldProtectNotification_projectionActive_permissionExempt_false() { whenever( packageManager.checkPermission( android.Manifest.permission.RECORD_SENSITIVE_CONTENT, mediaProjectionInfo.packageName ) ) .thenReturn(PackageManager.PERMISSION_GRANTED) mediaProjectionCallback.onStart(mediaProjectionInfo) val notificationEntry = setupNotificationEntry(TEST_PACKAGE_NAME, false) assertFalse(controller.shouldProtectNotification(notificationEntry)) } @Test fun shouldProtectNotification_projectionActive_bugReportHandlerExempt_false() { whenever(mediaProjectionInfo.packageName).thenReturn(BUGREPORT_PACKAGE_NAME) Loading @@ -327,6 +405,7 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { assertFalse(controller.shouldProtectNotification(notificationEntry)) } @Test fun shouldProtectNotification_projectionActive_publicNotification_false() { mediaProjectionCallback.onStart(mediaProjectionInfo) Loading