Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt +102 −49 Original line number Diff line number Diff line Loading @@ -20,10 +20,14 @@ import android.app.Notification import android.os.UserHandle import com.android.keyguard.KeyguardUpdateMonitor import com.android.server.notification.Flags.screenshareNotificationHiding import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.statusbar.NotificationLockscreenUserManager import com.android.systemui.statusbar.StatusBarState import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter import com.android.systemui.statusbar.notification.DynamicPrivacyController import com.android.systemui.statusbar.notification.collection.GroupEntry import com.android.systemui.statusbar.notification.collection.ListEntry Loading @@ -32,27 +36,33 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Invalidator import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.statusbar.policy.SensitiveNotificationProtectionController import com.android.systemui.user.domain.interactor.SelectedUserInteractor import dagger.Binds import dagger.Module import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.launch @Module(includes = [PrivateSensitiveContentCoordinatorModule::class]) interface SensitiveContentCoordinatorModule @Module interface PrivateSensitiveContentCoordinatorModule { @Binds fun bindCoordinator(impl: SensitiveContentCoordinatorImpl): SensitiveContentCoordinator @Binds fun bindCoordinator(impl: SensitiveContentCoordinatorImpl): SensitiveContentCoordinator } /** Coordinates re-inflation and post-processing of sensitive notification content. */ interface SensitiveContentCoordinator : Coordinator @CoordinatorScope class SensitiveContentCoordinatorImpl @Inject constructor( class SensitiveContentCoordinatorImpl @Inject constructor( private val dynamicPrivacyController: DynamicPrivacyController, private val lockscreenUserManager: NotificationLockscreenUserManager, private val keyguardUpdateMonitor: KeyguardUpdateMonitor, Loading @@ -61,18 +71,25 @@ class SensitiveContentCoordinatorImpl @Inject constructor( private val selectedUserInteractor: SelectedUserInteractor, private val sensitiveNotificationProtectionController: SensitiveNotificationProtectionController, ) : Invalidator("SensitiveContentInvalidator"), private val deviceEntryInteractor: DeviceEntryInteractor, private val sceneInteractor: SceneInteractor, @Application private val scope: CoroutineScope, ) : Invalidator("SensitiveContentInvalidator"), SensitiveContentCoordinator, DynamicPrivacyController.Listener, OnBeforeRenderListListener { private val onSensitiveStateChanged = Runnable() { invalidateList("onSensitiveStateChanged") } private var inTransitionFromLockedToGone = false private val onSensitiveStateChanged = Runnable() { invalidateList("onSensitiveStateChanged") } private val screenshareSecretFilter = object : NotifFilter("ScreenshareSecretFilter") { private val screenshareSecretFilter = object : NotifFilter("ScreenshareSecretFilter") { val NotificationEntry.isSecret get() = channel?.lockscreenVisibility == Notification.VISIBILITY_SECRET || get() = channel?.lockscreenVisibility == Notification.VISIBILITY_SECRET || sbn.notification?.visibility == Notification.VISIBILITY_SECRET override fun shouldFilterOut(entry: NotificationEntry, now: Long): Boolean { return screenshareNotificationHiding() && sensitiveNotificationProtectionController.isSensitiveStateActive && Loading @@ -83,23 +100,56 @@ class SensitiveContentCoordinatorImpl @Inject constructor( override fun attach(pipeline: NotifPipeline) { dynamicPrivacyController.addListener(this) if (screenshareNotificationHiding()) { sensitiveNotificationProtectionController .registerSensitiveStateListener(onSensitiveStateChanged) sensitiveNotificationProtectionController.registerSensitiveStateListener( onSensitiveStateChanged ) } pipeline.addOnBeforeRenderListListener(this) pipeline.addPreRenderInvalidator(this) if (screenshareNotificationHiding()) { pipeline.addFinalizeFilter(screenshareSecretFilter) } if (SceneContainerFlag.isEnabled) { scope.launch { sceneInteractor.transitionState .mapNotNull { val transitioningToGone = it.isTransitioning(to = Scenes.Gone) val deviceEntered = deviceEntryInteractor.isDeviceEntered.value when { transitioningToGone && !deviceEntered -> true !transitioningToGone -> false else -> null } } .distinctUntilChanged() .collect { inTransitionFromLockedToGone = it invalidateList("inTransitionFromLockedToGoneChanged") } } } } override fun onDynamicPrivacyChanged(): Unit = invalidateList("onDynamicPrivacyChanged") private val isKeyguardGoingAway: Boolean get() { if (SceneContainerFlag.isEnabled) { return inTransitionFromLockedToGone } else { return keyguardStateController.isKeyguardGoingAway } } override fun onBeforeRenderList(entries: List<ListEntry>) { if (keyguardStateController.isKeyguardGoingAway || if ( isKeyguardGoingAway || statusBarStateController.state == StatusBarState.KEYGUARD && keyguardUpdateMonitor.getUserUnlockedWithBiometricAndIsBypassing( selectedUserInteractor.getSelectedUserId())) { selectedUserInteractor.getSelectedUserId() ) ) { // don't update yet if: // - the keyguard is currently going away // - LS is about to be dismissed by a biometric that bypasses LS (avoid notif flash) Loading @@ -109,19 +159,22 @@ class SensitiveContentCoordinatorImpl @Inject constructor( return } val isSensitiveContentProtectionActive = screenshareNotificationHiding() && val isSensitiveContentProtectionActive = screenshareNotificationHiding() && sensitiveNotificationProtectionController.isSensitiveStateActive val currentUserId = lockscreenUserManager.currentUserId val devicePublic = lockscreenUserManager.isLockscreenPublicMode(currentUserId) val deviceSensitive = (devicePublic && val deviceSensitive = (devicePublic && !lockscreenUserManager.userAllowsPrivateNotificationsInPublic(currentUserId)) || isSensitiveContentProtectionActive val dynamicallyUnlocked = dynamicPrivacyController.isDynamicallyUnlocked for (entry in extractAllRepresentativeEntries(entries).filter { it.rowExists() }) { val notifUserId = entry.sbn.user.identifier val userLockscreen = devicePublic || lockscreenUserManager.isLockscreenPublicMode(notifUserId) val userPublic = when { val userLockscreen = devicePublic || lockscreenUserManager.isLockscreenPublicMode(notifUserId) val userPublic = when { // if we're not on the lockscreen, we're definitely private !userLockscreen -> false // we are on the lockscreen, so unless we're dynamically unlocked, we're Loading @@ -129,14 +182,16 @@ class SensitiveContentCoordinatorImpl @Inject constructor( !dynamicallyUnlocked -> true // we're dynamically unlocked, but check if the notification needs // a separate challenge if it's from a work profile else -> when (notifUserId) { else -> when (notifUserId) { currentUserId -> false UserHandle.USER_ALL -> false else -> lockscreenUserManager.needsSeparateWorkChallenge(notifUserId) } } val shouldProtectNotification = screenshareNotificationHiding() && val shouldProtectNotification = screenshareNotificationHiding() && sensitiveNotificationProtectionController.shouldProtectNotification(entry) val needsRedaction = lockscreenUserManager.needsRedaction(entry) Loading @@ -149,9 +204,7 @@ class SensitiveContentCoordinatorImpl @Inject constructor( } } private fun extractAllRepresentativeEntries( entries: List<ListEntry> ): Sequence<NotificationEntry> = private fun extractAllRepresentativeEntries(entries: List<ListEntry>): Sequence<NotificationEntry> = entries.asSequence().flatMap(::extractAllRepresentativeEntries) private fun extractAllRepresentativeEntries(listEntry: ListEntry): Sequence<NotificationEntry> = Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt +23 −7 Original line number Diff line number Diff line Loading @@ -28,7 +28,11 @@ import androidx.test.filters.SmallTest import com.android.keyguard.KeyguardUpdateMonitor import com.android.server.notification.Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING import com.android.systemui.SysuiTestCase import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor import com.android.systemui.kosmos.applicationCoroutineScope import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.statusbar.NotificationLockscreenUserManager import com.android.systemui.statusbar.RankingBuilder import com.android.systemui.statusbar.StatusBarState Loading @@ -45,6 +49,7 @@ import com.android.systemui.statusbar.notification.collection.listbuilder.plugga import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.statusbar.policy.SensitiveNotificationProtectionController import com.android.systemui.testKosmos import com.android.systemui.user.domain.interactor.SelectedUserInteractor import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.eq Loading @@ -52,6 +57,7 @@ import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.withArgCaptor import dagger.BindsInstance import dagger.Component import kotlinx.coroutines.CoroutineScope import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Test Loading @@ -64,6 +70,8 @@ import org.mockito.Mockito.`when` as whenever @RunWith(AndroidJUnit4::class) class SensitiveContentCoordinatorTest : SysuiTestCase() { val kosmos = testKosmos() val dynamicPrivacyController: DynamicPrivacyController = mock() val lockscreenUserManager: NotificationLockscreenUserManager = mock() val pipeline: NotifPipeline = mock() Loading @@ -73,6 +81,8 @@ class SensitiveContentCoordinatorTest : SysuiTestCase() { val mSelectedUserInteractor: SelectedUserInteractor = mock() val sensitiveNotificationProtectionController: SensitiveNotificationProtectionController = mock() val deviceEntryInteractor: DeviceEntryInteractor = mock() val sceneInteractor: SceneInteractor = mock() val coordinator: SensitiveContentCoordinator = DaggerTestSensitiveContentCoordinatorComponent.factory() Loading @@ -83,7 +93,10 @@ class SensitiveContentCoordinatorTest : SysuiTestCase() { statusBarStateController, keyguardStateController, mSelectedUserInteractor, sensitiveNotificationProtectionController sensitiveNotificationProtectionController, deviceEntryInteractor, sceneInteractor, kosmos.applicationCoroutineScope, ) .coordinator Loading Loading @@ -136,8 +149,7 @@ class SensitiveContentCoordinatorTest : SysuiTestCase() { @Test @EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING) fun screenshareSecretFilter_sensitiveInctive_noFiltersSecret() { whenever(sensitiveNotificationProtectionController.isSensitiveStateActive) .thenReturn(false) whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(false) coordinator.attach(pipeline) val filter = withArgCaptor<NotifFilter> { verify(pipeline).addFinalizeFilter(capture()) } Loading Loading @@ -683,7 +695,8 @@ class SensitiveContentCoordinatorTest : SysuiTestCase() { val mockSbn: StatusBarNotification = mock<StatusBarNotification>().apply { whenever(user).thenReturn(mockUserHandle) } val mockRow: ExpandableNotificationRow = mock<ExpandableNotificationRow>() val mockEntry = mock<NotificationEntry>().apply { val mockEntry = mock<NotificationEntry>().apply { whenever(sbn).thenReturn(mockSbn) whenever(row).thenReturn(mockRow) } Loading Loading @@ -737,6 +750,9 @@ interface TestSensitiveContentCoordinatorComponent { @BindsInstance selectedUserInteractor: SelectedUserInteractor, @BindsInstance sensitiveNotificationProtectionController: SensitiveNotificationProtectionController, @BindsInstance deviceEntryInteractor: DeviceEntryInteractor, @BindsInstance sceneInteractor: SceneInteractor, @BindsInstance @Application scope: CoroutineScope, ): TestSensitiveContentCoordinatorComponent } } Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt +102 −49 Original line number Diff line number Diff line Loading @@ -20,10 +20,14 @@ import android.app.Notification import android.os.UserHandle import com.android.keyguard.KeyguardUpdateMonitor import com.android.server.notification.Flags.screenshareNotificationHiding import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.statusbar.NotificationLockscreenUserManager import com.android.systemui.statusbar.StatusBarState import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter import com.android.systemui.statusbar.notification.DynamicPrivacyController import com.android.systemui.statusbar.notification.collection.GroupEntry import com.android.systemui.statusbar.notification.collection.ListEntry Loading @@ -32,27 +36,33 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Invalidator import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.statusbar.policy.SensitiveNotificationProtectionController import com.android.systemui.user.domain.interactor.SelectedUserInteractor import dagger.Binds import dagger.Module import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.launch @Module(includes = [PrivateSensitiveContentCoordinatorModule::class]) interface SensitiveContentCoordinatorModule @Module interface PrivateSensitiveContentCoordinatorModule { @Binds fun bindCoordinator(impl: SensitiveContentCoordinatorImpl): SensitiveContentCoordinator @Binds fun bindCoordinator(impl: SensitiveContentCoordinatorImpl): SensitiveContentCoordinator } /** Coordinates re-inflation and post-processing of sensitive notification content. */ interface SensitiveContentCoordinator : Coordinator @CoordinatorScope class SensitiveContentCoordinatorImpl @Inject constructor( class SensitiveContentCoordinatorImpl @Inject constructor( private val dynamicPrivacyController: DynamicPrivacyController, private val lockscreenUserManager: NotificationLockscreenUserManager, private val keyguardUpdateMonitor: KeyguardUpdateMonitor, Loading @@ -61,18 +71,25 @@ class SensitiveContentCoordinatorImpl @Inject constructor( private val selectedUserInteractor: SelectedUserInteractor, private val sensitiveNotificationProtectionController: SensitiveNotificationProtectionController, ) : Invalidator("SensitiveContentInvalidator"), private val deviceEntryInteractor: DeviceEntryInteractor, private val sceneInteractor: SceneInteractor, @Application private val scope: CoroutineScope, ) : Invalidator("SensitiveContentInvalidator"), SensitiveContentCoordinator, DynamicPrivacyController.Listener, OnBeforeRenderListListener { private val onSensitiveStateChanged = Runnable() { invalidateList("onSensitiveStateChanged") } private var inTransitionFromLockedToGone = false private val onSensitiveStateChanged = Runnable() { invalidateList("onSensitiveStateChanged") } private val screenshareSecretFilter = object : NotifFilter("ScreenshareSecretFilter") { private val screenshareSecretFilter = object : NotifFilter("ScreenshareSecretFilter") { val NotificationEntry.isSecret get() = channel?.lockscreenVisibility == Notification.VISIBILITY_SECRET || get() = channel?.lockscreenVisibility == Notification.VISIBILITY_SECRET || sbn.notification?.visibility == Notification.VISIBILITY_SECRET override fun shouldFilterOut(entry: NotificationEntry, now: Long): Boolean { return screenshareNotificationHiding() && sensitiveNotificationProtectionController.isSensitiveStateActive && Loading @@ -83,23 +100,56 @@ class SensitiveContentCoordinatorImpl @Inject constructor( override fun attach(pipeline: NotifPipeline) { dynamicPrivacyController.addListener(this) if (screenshareNotificationHiding()) { sensitiveNotificationProtectionController .registerSensitiveStateListener(onSensitiveStateChanged) sensitiveNotificationProtectionController.registerSensitiveStateListener( onSensitiveStateChanged ) } pipeline.addOnBeforeRenderListListener(this) pipeline.addPreRenderInvalidator(this) if (screenshareNotificationHiding()) { pipeline.addFinalizeFilter(screenshareSecretFilter) } if (SceneContainerFlag.isEnabled) { scope.launch { sceneInteractor.transitionState .mapNotNull { val transitioningToGone = it.isTransitioning(to = Scenes.Gone) val deviceEntered = deviceEntryInteractor.isDeviceEntered.value when { transitioningToGone && !deviceEntered -> true !transitioningToGone -> false else -> null } } .distinctUntilChanged() .collect { inTransitionFromLockedToGone = it invalidateList("inTransitionFromLockedToGoneChanged") } } } } override fun onDynamicPrivacyChanged(): Unit = invalidateList("onDynamicPrivacyChanged") private val isKeyguardGoingAway: Boolean get() { if (SceneContainerFlag.isEnabled) { return inTransitionFromLockedToGone } else { return keyguardStateController.isKeyguardGoingAway } } override fun onBeforeRenderList(entries: List<ListEntry>) { if (keyguardStateController.isKeyguardGoingAway || if ( isKeyguardGoingAway || statusBarStateController.state == StatusBarState.KEYGUARD && keyguardUpdateMonitor.getUserUnlockedWithBiometricAndIsBypassing( selectedUserInteractor.getSelectedUserId())) { selectedUserInteractor.getSelectedUserId() ) ) { // don't update yet if: // - the keyguard is currently going away // - LS is about to be dismissed by a biometric that bypasses LS (avoid notif flash) Loading @@ -109,19 +159,22 @@ class SensitiveContentCoordinatorImpl @Inject constructor( return } val isSensitiveContentProtectionActive = screenshareNotificationHiding() && val isSensitiveContentProtectionActive = screenshareNotificationHiding() && sensitiveNotificationProtectionController.isSensitiveStateActive val currentUserId = lockscreenUserManager.currentUserId val devicePublic = lockscreenUserManager.isLockscreenPublicMode(currentUserId) val deviceSensitive = (devicePublic && val deviceSensitive = (devicePublic && !lockscreenUserManager.userAllowsPrivateNotificationsInPublic(currentUserId)) || isSensitiveContentProtectionActive val dynamicallyUnlocked = dynamicPrivacyController.isDynamicallyUnlocked for (entry in extractAllRepresentativeEntries(entries).filter { it.rowExists() }) { val notifUserId = entry.sbn.user.identifier val userLockscreen = devicePublic || lockscreenUserManager.isLockscreenPublicMode(notifUserId) val userPublic = when { val userLockscreen = devicePublic || lockscreenUserManager.isLockscreenPublicMode(notifUserId) val userPublic = when { // if we're not on the lockscreen, we're definitely private !userLockscreen -> false // we are on the lockscreen, so unless we're dynamically unlocked, we're Loading @@ -129,14 +182,16 @@ class SensitiveContentCoordinatorImpl @Inject constructor( !dynamicallyUnlocked -> true // we're dynamically unlocked, but check if the notification needs // a separate challenge if it's from a work profile else -> when (notifUserId) { else -> when (notifUserId) { currentUserId -> false UserHandle.USER_ALL -> false else -> lockscreenUserManager.needsSeparateWorkChallenge(notifUserId) } } val shouldProtectNotification = screenshareNotificationHiding() && val shouldProtectNotification = screenshareNotificationHiding() && sensitiveNotificationProtectionController.shouldProtectNotification(entry) val needsRedaction = lockscreenUserManager.needsRedaction(entry) Loading @@ -149,9 +204,7 @@ class SensitiveContentCoordinatorImpl @Inject constructor( } } private fun extractAllRepresentativeEntries( entries: List<ListEntry> ): Sequence<NotificationEntry> = private fun extractAllRepresentativeEntries(entries: List<ListEntry>): Sequence<NotificationEntry> = entries.asSequence().flatMap(::extractAllRepresentativeEntries) private fun extractAllRepresentativeEntries(listEntry: ListEntry): Sequence<NotificationEntry> = Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt +23 −7 Original line number Diff line number Diff line Loading @@ -28,7 +28,11 @@ import androidx.test.filters.SmallTest import com.android.keyguard.KeyguardUpdateMonitor import com.android.server.notification.Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING import com.android.systemui.SysuiTestCase import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor import com.android.systemui.kosmos.applicationCoroutineScope import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.statusbar.NotificationLockscreenUserManager import com.android.systemui.statusbar.RankingBuilder import com.android.systemui.statusbar.StatusBarState Loading @@ -45,6 +49,7 @@ import com.android.systemui.statusbar.notification.collection.listbuilder.plugga import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.statusbar.policy.SensitiveNotificationProtectionController import com.android.systemui.testKosmos import com.android.systemui.user.domain.interactor.SelectedUserInteractor import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.eq Loading @@ -52,6 +57,7 @@ import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.withArgCaptor import dagger.BindsInstance import dagger.Component import kotlinx.coroutines.CoroutineScope import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Test Loading @@ -64,6 +70,8 @@ import org.mockito.Mockito.`when` as whenever @RunWith(AndroidJUnit4::class) class SensitiveContentCoordinatorTest : SysuiTestCase() { val kosmos = testKosmos() val dynamicPrivacyController: DynamicPrivacyController = mock() val lockscreenUserManager: NotificationLockscreenUserManager = mock() val pipeline: NotifPipeline = mock() Loading @@ -73,6 +81,8 @@ class SensitiveContentCoordinatorTest : SysuiTestCase() { val mSelectedUserInteractor: SelectedUserInteractor = mock() val sensitiveNotificationProtectionController: SensitiveNotificationProtectionController = mock() val deviceEntryInteractor: DeviceEntryInteractor = mock() val sceneInteractor: SceneInteractor = mock() val coordinator: SensitiveContentCoordinator = DaggerTestSensitiveContentCoordinatorComponent.factory() Loading @@ -83,7 +93,10 @@ class SensitiveContentCoordinatorTest : SysuiTestCase() { statusBarStateController, keyguardStateController, mSelectedUserInteractor, sensitiveNotificationProtectionController sensitiveNotificationProtectionController, deviceEntryInteractor, sceneInteractor, kosmos.applicationCoroutineScope, ) .coordinator Loading Loading @@ -136,8 +149,7 @@ class SensitiveContentCoordinatorTest : SysuiTestCase() { @Test @EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING) fun screenshareSecretFilter_sensitiveInctive_noFiltersSecret() { whenever(sensitiveNotificationProtectionController.isSensitiveStateActive) .thenReturn(false) whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(false) coordinator.attach(pipeline) val filter = withArgCaptor<NotifFilter> { verify(pipeline).addFinalizeFilter(capture()) } Loading Loading @@ -683,7 +695,8 @@ class SensitiveContentCoordinatorTest : SysuiTestCase() { val mockSbn: StatusBarNotification = mock<StatusBarNotification>().apply { whenever(user).thenReturn(mockUserHandle) } val mockRow: ExpandableNotificationRow = mock<ExpandableNotificationRow>() val mockEntry = mock<NotificationEntry>().apply { val mockEntry = mock<NotificationEntry>().apply { whenever(sbn).thenReturn(mockSbn) whenever(row).thenReturn(mockRow) } Loading Loading @@ -737,6 +750,9 @@ interface TestSensitiveContentCoordinatorComponent { @BindsInstance selectedUserInteractor: SelectedUserInteractor, @BindsInstance sensitiveNotificationProtectionController: SensitiveNotificationProtectionController, @BindsInstance deviceEntryInteractor: DeviceEntryInteractor, @BindsInstance sceneInteractor: SceneInteractor, @BindsInstance @Application scope: CoroutineScope, ): TestSensitiveContentCoordinatorComponent } }