Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fff24273 authored by Richard MacGregor's avatar Richard MacGregor
Browse files

Disable clear notifications when screenshare

When screensharing, notifications that are not dismissable should also
not be clearable

Bug: 324285161
Test: atest StackCoordinatorTest
Flag: ACONFIG com.android.server.notification.screenshare_notification_hiding TRUNKFOOD
Flag: ACONFIG com.android.systemui.screenshare_notification_hiding_bug_fix DISABLED
Change-Id: I44badef472f46b166f94e9a8e1b07f36dbbbfc3c
parent bb8ac426
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -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"
+9 −1
Original line number Diff line number Diff line
@@ -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
@@ -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

/**
@@ -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) {
@@ -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
+85 −0
Original line number Diff line number Diff line
@@ -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
@@ -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
@@ -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

@@ -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(
@@ -73,6 +83,7 @@ class StackCoordinatorTest : SysuiTestCase() {
                notificationIconAreaController,
                renderListInteractor,
                activeNotificationsInteractor,
                sensitiveNotificationProtectionController,
            )
        coordinator.attach(pipeline)
        afterRenderListListener = withArgCaptor {
@@ -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
@@ -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)
    }
}