Loading packages/SystemUI/aconfig/systemui.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -691,6 +691,16 @@ flag { } } flag { name: "screenshare_notification_hiding_bug_fix" namespace: "systemui" description: "Various bug fixes for notification redaction while screensharing" bug: "312784809" metadata { purpose: PURPOSE_BUGFIX } } flag { name: "qs_ui_refactor" namespace: "systemui" Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt +9 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ package com.android.systemui.statusbar.notification.collection.coordinator import com.android.app.tracing.traceSection import com.android.server.notification.Flags.screenshareNotificationHiding import com.android.systemui.Flags.screenshareNotificationHidingBugFix import com.android.systemui.statusbar.notification.collection.ListEntry import com.android.systemui.statusbar.notification.collection.NotifPipeline import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope Loading @@ -29,6 +31,7 @@ import com.android.systemui.statusbar.notification.footer.shared.FooterViewRefac import com.android.systemui.statusbar.notification.shared.NotificationIconContainerRefactor import com.android.systemui.statusbar.notification.stack.BUCKET_SILENT import com.android.systemui.statusbar.phone.NotificationIconAreaController import com.android.systemui.statusbar.policy.SensitiveNotificationProtectionController import javax.inject.Inject /** Loading @@ -43,6 +46,8 @@ internal constructor( private val notificationIconAreaController: NotificationIconAreaController, private val renderListInteractor: RenderNotificationListInteractor, private val activeNotificationsInteractor: ActiveNotificationsInteractor, private val sensitiveNotificationProtectionController: SensitiveNotificationProtectionController, ) : Coordinator { override fun attach(pipeline: NotifPipeline) { Loading Loading @@ -71,13 +76,16 @@ internal constructor( var hasClearableAlertingNotifs = false var hasNonClearableSilentNotifs = false var hasClearableSilentNotifs = false val isSensitiveContentProtectionActive = screenshareNotificationHiding() && screenshareNotificationHidingBugFix() && sensitiveNotificationProtectionController.isSensitiveStateActive entries.forEach { val section = checkNotNull(it.section) { "Null section for ${it.key}" } val entry = checkNotNull(it.representativeEntry) { "Null notif entry for ${it.key}" } val isSilent = section.bucket == BUCKET_SILENT // NOTE: NotificationEntry.isClearable will internally check group children to ensure // the group itself definitively clearable. val isClearable = entry.isClearable val isClearable = !isSensitiveContentProtectionActive && entry.isClearable when { isSilent && isClearable -> hasClearableSilentNotifs = true isSilent && !isClearable -> hasNonClearableSilentNotifs = true Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinatorTest.kt +85 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ import android.platform.test.annotations.EnableFlags import android.testing.AndroidTestingRunner import android.testing.TestableLooper.RunWithLooper import androidx.test.filters.SmallTest import com.android.server.notification.Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING import com.android.systemui.Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING_BUG_FIX import com.android.systemui.SysuiTestCase import com.android.systemui.statusbar.notification.collection.NotifPipeline import com.android.systemui.statusbar.notification.collection.NotificationEntry Loading @@ -36,6 +38,7 @@ import com.android.systemui.statusbar.notification.shared.NotificationIconContai import com.android.systemui.statusbar.notification.stack.BUCKET_ALERTING import com.android.systemui.statusbar.notification.stack.BUCKET_SILENT import com.android.systemui.statusbar.phone.NotificationIconAreaController import com.android.systemui.statusbar.policy.SensitiveNotificationProtectionController import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.withArgCaptor import org.junit.Before Loading @@ -43,6 +46,7 @@ import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.Mockito.verify import org.mockito.Mockito.verifyZeroInteractions import org.mockito.MockitoAnnotations.initMocks import org.mockito.Mockito.`when` as whenever Loading @@ -60,12 +64,18 @@ class StackCoordinatorTest : SysuiTestCase() { @Mock private lateinit var notificationIconAreaController: NotificationIconAreaController @Mock private lateinit var renderListInteractor: RenderNotificationListInteractor @Mock private lateinit var activeNotificationsInteractor: ActiveNotificationsInteractor @Mock private lateinit var sensitiveNotificationProtectionController: SensitiveNotificationProtectionController @Mock private lateinit var stackController: NotifStackController @Mock private lateinit var section: NotifSection @Before fun setUp() { initMocks(this) whenever(sensitiveNotificationProtectionController.isSensitiveStateActive) .thenReturn(false) entry = NotificationEntryBuilder().setSection(section).build() coordinator = StackCoordinator( Loading @@ -73,6 +83,7 @@ class StackCoordinatorTest : SysuiTestCase() { notificationIconAreaController, renderListInteractor, activeNotificationsInteractor, sensitiveNotificationProtectionController, ) coordinator.attach(pipeline) afterRenderListListener = withArgCaptor { Loading Loading @@ -107,6 +118,18 @@ class StackCoordinatorTest : SysuiTestCase() { whenever(section.bucket).thenReturn(BUCKET_ALERTING) afterRenderListListener.onAfterRenderList(listOf(entry), stackController) verify(stackController).setNotifStats(NotifStats(1, false, true, false, false)) verifyZeroInteractions(activeNotificationsInteractor) } @Test @DisableFlags(FooterViewRefactor.FLAG_NAME) @EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING, FLAG_SCREENSHARE_NOTIFICATION_HIDING_BUG_FIX) fun testSetNotificationStats_isSensitiveStateActive_nonClearableAlerting() { whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true) whenever(section.bucket).thenReturn(BUCKET_ALERTING) afterRenderListListener.onAfterRenderList(listOf(entry), stackController) verify(stackController).setNotifStats(NotifStats(1, true, false, false, false)) verifyZeroInteractions(activeNotificationsInteractor) } @Test Loading @@ -115,5 +138,67 @@ class StackCoordinatorTest : SysuiTestCase() { whenever(section.bucket).thenReturn(BUCKET_SILENT) afterRenderListListener.onAfterRenderList(listOf(entry), stackController) verify(stackController).setNotifStats(NotifStats(1, false, false, false, true)) verifyZeroInteractions(activeNotificationsInteractor) } @Test @DisableFlags(FooterViewRefactor.FLAG_NAME) @EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING, FLAG_SCREENSHARE_NOTIFICATION_HIDING_BUG_FIX) fun testSetNotificationStats_isSensitiveStateActive_nonClearableSilent() { whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true) whenever(section.bucket).thenReturn(BUCKET_SILENT) afterRenderListListener.onAfterRenderList(listOf(entry), stackController) verify(stackController).setNotifStats(NotifStats(1, false, false, true, false)) verifyZeroInteractions(activeNotificationsInteractor) } @Test @EnableFlags(FooterViewRefactor.FLAG_NAME) fun testSetNotificationStats_footerFlagOn_clearableAlerting() { whenever(section.bucket).thenReturn(BUCKET_ALERTING) afterRenderListListener.onAfterRenderList(listOf(entry), stackController) verify(activeNotificationsInteractor) .setNotifStats(NotifStats(1, false, true, false, false)) verifyZeroInteractions(stackController) } @Test @EnableFlags( FooterViewRefactor.FLAG_NAME, FLAG_SCREENSHARE_NOTIFICATION_HIDING, FLAG_SCREENSHARE_NOTIFICATION_HIDING_BUG_FIX ) fun testSetNotificationStats_footerFlagOn_isSensitiveStateActive_nonClearableAlerting() { whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true) whenever(section.bucket).thenReturn(BUCKET_ALERTING) afterRenderListListener.onAfterRenderList(listOf(entry), stackController) verify(activeNotificationsInteractor) .setNotifStats(NotifStats(1, true, false, false, false)) verifyZeroInteractions(stackController) } @Test @EnableFlags(FooterViewRefactor.FLAG_NAME) fun testSetNotificationStats_footerFlagOn_clearableSilent() { whenever(section.bucket).thenReturn(BUCKET_SILENT) afterRenderListListener.onAfterRenderList(listOf(entry), stackController) verify(activeNotificationsInteractor) .setNotifStats(NotifStats(1, false, false, false, true)) verifyZeroInteractions(stackController) } @Test @EnableFlags( FooterViewRefactor.FLAG_NAME, FLAG_SCREENSHARE_NOTIFICATION_HIDING, FLAG_SCREENSHARE_NOTIFICATION_HIDING_BUG_FIX ) fun testSetNotificationStats_footerFlagOn_isSensitiveStateActive_nonClearableSilent() { whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true) whenever(section.bucket).thenReturn(BUCKET_SILENT) afterRenderListListener.onAfterRenderList(listOf(entry), stackController) verify(activeNotificationsInteractor) .setNotifStats(NotifStats(1, false, false, true, false)) verifyZeroInteractions(stackController) } } Loading
packages/SystemUI/aconfig/systemui.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -691,6 +691,16 @@ flag { } } flag { name: "screenshare_notification_hiding_bug_fix" namespace: "systemui" description: "Various bug fixes for notification redaction while screensharing" bug: "312784809" metadata { purpose: PURPOSE_BUGFIX } } flag { name: "qs_ui_refactor" namespace: "systemui" Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt +9 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ package com.android.systemui.statusbar.notification.collection.coordinator import com.android.app.tracing.traceSection import com.android.server.notification.Flags.screenshareNotificationHiding import com.android.systemui.Flags.screenshareNotificationHidingBugFix import com.android.systemui.statusbar.notification.collection.ListEntry import com.android.systemui.statusbar.notification.collection.NotifPipeline import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope Loading @@ -29,6 +31,7 @@ import com.android.systemui.statusbar.notification.footer.shared.FooterViewRefac import com.android.systemui.statusbar.notification.shared.NotificationIconContainerRefactor import com.android.systemui.statusbar.notification.stack.BUCKET_SILENT import com.android.systemui.statusbar.phone.NotificationIconAreaController import com.android.systemui.statusbar.policy.SensitiveNotificationProtectionController import javax.inject.Inject /** Loading @@ -43,6 +46,8 @@ internal constructor( private val notificationIconAreaController: NotificationIconAreaController, private val renderListInteractor: RenderNotificationListInteractor, private val activeNotificationsInteractor: ActiveNotificationsInteractor, private val sensitiveNotificationProtectionController: SensitiveNotificationProtectionController, ) : Coordinator { override fun attach(pipeline: NotifPipeline) { Loading Loading @@ -71,13 +76,16 @@ internal constructor( var hasClearableAlertingNotifs = false var hasNonClearableSilentNotifs = false var hasClearableSilentNotifs = false val isSensitiveContentProtectionActive = screenshareNotificationHiding() && screenshareNotificationHidingBugFix() && sensitiveNotificationProtectionController.isSensitiveStateActive entries.forEach { val section = checkNotNull(it.section) { "Null section for ${it.key}" } val entry = checkNotNull(it.representativeEntry) { "Null notif entry for ${it.key}" } val isSilent = section.bucket == BUCKET_SILENT // NOTE: NotificationEntry.isClearable will internally check group children to ensure // the group itself definitively clearable. val isClearable = entry.isClearable val isClearable = !isSensitiveContentProtectionActive && entry.isClearable when { isSilent && isClearable -> hasClearableSilentNotifs = true isSilent && !isClearable -> hasNonClearableSilentNotifs = true Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinatorTest.kt +85 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ import android.platform.test.annotations.EnableFlags import android.testing.AndroidTestingRunner import android.testing.TestableLooper.RunWithLooper import androidx.test.filters.SmallTest import com.android.server.notification.Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING import com.android.systemui.Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING_BUG_FIX import com.android.systemui.SysuiTestCase import com.android.systemui.statusbar.notification.collection.NotifPipeline import com.android.systemui.statusbar.notification.collection.NotificationEntry Loading @@ -36,6 +38,7 @@ import com.android.systemui.statusbar.notification.shared.NotificationIconContai import com.android.systemui.statusbar.notification.stack.BUCKET_ALERTING import com.android.systemui.statusbar.notification.stack.BUCKET_SILENT import com.android.systemui.statusbar.phone.NotificationIconAreaController import com.android.systemui.statusbar.policy.SensitiveNotificationProtectionController import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.withArgCaptor import org.junit.Before Loading @@ -43,6 +46,7 @@ import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.Mockito.verify import org.mockito.Mockito.verifyZeroInteractions import org.mockito.MockitoAnnotations.initMocks import org.mockito.Mockito.`when` as whenever Loading @@ -60,12 +64,18 @@ class StackCoordinatorTest : SysuiTestCase() { @Mock private lateinit var notificationIconAreaController: NotificationIconAreaController @Mock private lateinit var renderListInteractor: RenderNotificationListInteractor @Mock private lateinit var activeNotificationsInteractor: ActiveNotificationsInteractor @Mock private lateinit var sensitiveNotificationProtectionController: SensitiveNotificationProtectionController @Mock private lateinit var stackController: NotifStackController @Mock private lateinit var section: NotifSection @Before fun setUp() { initMocks(this) whenever(sensitiveNotificationProtectionController.isSensitiveStateActive) .thenReturn(false) entry = NotificationEntryBuilder().setSection(section).build() coordinator = StackCoordinator( Loading @@ -73,6 +83,7 @@ class StackCoordinatorTest : SysuiTestCase() { notificationIconAreaController, renderListInteractor, activeNotificationsInteractor, sensitiveNotificationProtectionController, ) coordinator.attach(pipeline) afterRenderListListener = withArgCaptor { Loading Loading @@ -107,6 +118,18 @@ class StackCoordinatorTest : SysuiTestCase() { whenever(section.bucket).thenReturn(BUCKET_ALERTING) afterRenderListListener.onAfterRenderList(listOf(entry), stackController) verify(stackController).setNotifStats(NotifStats(1, false, true, false, false)) verifyZeroInteractions(activeNotificationsInteractor) } @Test @DisableFlags(FooterViewRefactor.FLAG_NAME) @EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING, FLAG_SCREENSHARE_NOTIFICATION_HIDING_BUG_FIX) fun testSetNotificationStats_isSensitiveStateActive_nonClearableAlerting() { whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true) whenever(section.bucket).thenReturn(BUCKET_ALERTING) afterRenderListListener.onAfterRenderList(listOf(entry), stackController) verify(stackController).setNotifStats(NotifStats(1, true, false, false, false)) verifyZeroInteractions(activeNotificationsInteractor) } @Test Loading @@ -115,5 +138,67 @@ class StackCoordinatorTest : SysuiTestCase() { whenever(section.bucket).thenReturn(BUCKET_SILENT) afterRenderListListener.onAfterRenderList(listOf(entry), stackController) verify(stackController).setNotifStats(NotifStats(1, false, false, false, true)) verifyZeroInteractions(activeNotificationsInteractor) } @Test @DisableFlags(FooterViewRefactor.FLAG_NAME) @EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING, FLAG_SCREENSHARE_NOTIFICATION_HIDING_BUG_FIX) fun testSetNotificationStats_isSensitiveStateActive_nonClearableSilent() { whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true) whenever(section.bucket).thenReturn(BUCKET_SILENT) afterRenderListListener.onAfterRenderList(listOf(entry), stackController) verify(stackController).setNotifStats(NotifStats(1, false, false, true, false)) verifyZeroInteractions(activeNotificationsInteractor) } @Test @EnableFlags(FooterViewRefactor.FLAG_NAME) fun testSetNotificationStats_footerFlagOn_clearableAlerting() { whenever(section.bucket).thenReturn(BUCKET_ALERTING) afterRenderListListener.onAfterRenderList(listOf(entry), stackController) verify(activeNotificationsInteractor) .setNotifStats(NotifStats(1, false, true, false, false)) verifyZeroInteractions(stackController) } @Test @EnableFlags( FooterViewRefactor.FLAG_NAME, FLAG_SCREENSHARE_NOTIFICATION_HIDING, FLAG_SCREENSHARE_NOTIFICATION_HIDING_BUG_FIX ) fun testSetNotificationStats_footerFlagOn_isSensitiveStateActive_nonClearableAlerting() { whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true) whenever(section.bucket).thenReturn(BUCKET_ALERTING) afterRenderListListener.onAfterRenderList(listOf(entry), stackController) verify(activeNotificationsInteractor) .setNotifStats(NotifStats(1, true, false, false, false)) verifyZeroInteractions(stackController) } @Test @EnableFlags(FooterViewRefactor.FLAG_NAME) fun testSetNotificationStats_footerFlagOn_clearableSilent() { whenever(section.bucket).thenReturn(BUCKET_SILENT) afterRenderListListener.onAfterRenderList(listOf(entry), stackController) verify(activeNotificationsInteractor) .setNotifStats(NotifStats(1, false, false, false, true)) verifyZeroInteractions(stackController) } @Test @EnableFlags( FooterViewRefactor.FLAG_NAME, FLAG_SCREENSHARE_NOTIFICATION_HIDING, FLAG_SCREENSHARE_NOTIFICATION_HIDING_BUG_FIX ) fun testSetNotificationStats_footerFlagOn_isSensitiveStateActive_nonClearableSilent() { whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true) whenever(section.bucket).thenReturn(BUCKET_SILENT) afterRenderListListener.onAfterRenderList(listOf(entry), stackController) verify(activeNotificationsInteractor) .setNotifStats(NotifStats(1, false, false, true, false)) verifyZeroInteractions(stackController) } }