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

Commit 84e94f27 authored by Julia Tuttle's avatar Julia Tuttle
Browse files

Implement common suppression logic

Bug: 261728888
Test: atest NotificationInterruptStateProviderWrapperTest
Test: atest VisualInterruptionDecisionProviderImplTest
Flag: ACONFIG com.android.systemui.visual_interruptions_refactor DEVELOPMENT
Change-Id: I3cda6c62721e433750033d8ab8e742fa16c6feb5
parent 79e14a7a
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -183,6 +183,20 @@ class PulseLowImportanceSuppressor() :
    override fun shouldSuppress(entry: NotificationEntry) = entry.importance < IMPORTANCE_DEFAULT
}

class HunGroupAlertBehaviorSuppressor() :
    VisualInterruptionFilter(
        types = setOf(PEEK, PULSE),
        reason = "suppressive group alert behavior"
    ) {
    override fun shouldSuppress(entry: NotificationEntry) =
        entry.sbn.let { it.isGroup && it.notification.suppressAlertingDueToGrouping() }
}

class HunJustLaunchedFsiSuppressor() :
    VisualInterruptionFilter(types = setOf(PEEK, PULSE), reason = "just launched FSI") {
    override fun shouldSuppress(entry: NotificationEntry) = entry.hasJustLaunchedFullScreenIntent()
}

class BubbleNotAllowedSuppressor() :
    VisualInterruptionFilter(types = setOf(BUBBLE), reason = "not allowed") {
    override fun shouldSuppress(entry: NotificationEntry) = !entry.canBubble()
@@ -196,3 +210,10 @@ class BubbleNoMetadataSuppressor() :

    override fun shouldSuppress(entry: NotificationEntry) = !isValidMetadata(entry.bubbleMetadata)
}

class AlertKeyguardVisibilitySuppressor(
    private val keyguardNotificationVisibilityProvider: KeyguardNotificationVisibilityProvider
) : VisualInterruptionFilter(types = setOf(PEEK, PULSE, BUBBLE), reason = "hidden on keyguard") {
    override fun shouldSuppress(entry: NotificationEntry) =
        keyguardNotificationVisibilityProvider.shouldHideNotification(entry)
}
+4 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ constructor(
    private val batteryController: BatteryController,
    private val globalSettings: GlobalSettings,
    private val headsUpManager: HeadsUpManager,
    private val keyguardNotificationVisibilityProvider: KeyguardNotificationVisibilityProvider,
    private val logger: NotificationInterruptLogger,
    @Main private val mainHandler: Handler,
    private val powerManager: PowerManager,
@@ -67,6 +68,9 @@ constructor(
        addFilter(PulseLowImportanceSuppressor())
        addFilter(BubbleNotAllowedSuppressor())
        addFilter(BubbleNoMetadataSuppressor())
        addFilter(HunGroupAlertBehaviorSuppressor())
        addFilter(HunJustLaunchedFsiSuppressor())
        addFilter(AlertKeyguardVisibilitySuppressor(keyguardNotificationVisibilityProvider))

        started = true
    }
+1 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro
            batteryController,
            globalSettings,
            headsUpManager,
            keyguardNotificationVisibilityProvider,
            logger,
            mainHandler,
            powerManager,
+136 −0
Original line number Diff line number Diff line
@@ -20,6 +20,9 @@ import android.app.ActivityManager
import android.app.Notification
import android.app.Notification.BubbleMetadata
import android.app.Notification.FLAG_BUBBLE
import android.app.Notification.GROUP_ALERT_ALL
import android.app.Notification.GROUP_ALERT_CHILDREN
import android.app.Notification.GROUP_ALERT_SUMMARY
import android.app.Notification.VISIBILITY_PRIVATE
import android.app.NotificationChannel
import android.app.NotificationManager.IMPORTANCE_DEFAULT
@@ -305,6 +308,110 @@ abstract class VisualInterruptionDecisionProviderTestBase : SysuiTestCase() {
        assertShouldNotHeadsUp(buildPulseEntry { importance = IMPORTANCE_LOW })
    }

    private fun withPeekAndPulseEntry(
        extendEntry: EntryBuilder.() -> Unit,
        block: (NotificationEntry) -> Unit
    ) {
        ensurePeekState()
        block(buildPeekEntry(extendEntry))

        ensurePulseState()
        block(buildPulseEntry(extendEntry))
    }

    @Test
    fun testShouldHeadsUp_groupedSummaryNotif_groupAlertAll() {
        withPeekAndPulseEntry({
            isGrouped = true
            isGroupSummary = true
            groupAlertBehavior = GROUP_ALERT_ALL
        }) {
            assertShouldHeadsUp(it)
        }
    }

    @Test
    fun testShouldHeadsUp_groupedSummaryNotif_groupAlertSummary() {
        withPeekAndPulseEntry({
            isGrouped = true
            isGroupSummary = true
            groupAlertBehavior = GROUP_ALERT_SUMMARY
        }) {
            assertShouldHeadsUp(it)
        }
    }

    @Test
    fun testShouldNotHeadsUp_groupedSummaryNotif_groupAlertChildren() {
        withPeekAndPulseEntry({
            isGrouped = true
            isGroupSummary = true
            groupAlertBehavior = GROUP_ALERT_CHILDREN
        }) {
            assertShouldNotHeadsUp(it)
        }
    }

    @Test
    fun testShouldHeadsUp_ungroupedSummaryNotif_groupAlertChildren() {
        withPeekAndPulseEntry({
            isGrouped = false
            isGroupSummary = true
            groupAlertBehavior = GROUP_ALERT_CHILDREN
        }) {
            assertShouldHeadsUp(it)
        }
    }

    @Test
    fun testShouldHeadsUp_groupedChildNotif_groupAlertAll() {
        withPeekAndPulseEntry({
            isGrouped = true
            isGroupSummary = false
            groupAlertBehavior = GROUP_ALERT_ALL
        }) {
            assertShouldHeadsUp(it)
        }
    }

    @Test
    fun testShouldHeadsUp_groupedChildNotif_groupAlertChildren() {
        withPeekAndPulseEntry({
            isGrouped = true
            isGroupSummary = false
            groupAlertBehavior = GROUP_ALERT_CHILDREN
        }) {
            assertShouldHeadsUp(it)
        }
    }

    @Test
    fun testShouldNotHeadsUp_groupedChildNotif_groupAlertSummary() {
        withPeekAndPulseEntry({
            isGrouped = true
            isGroupSummary = false
            groupAlertBehavior = GROUP_ALERT_SUMMARY
        }) {
            assertShouldNotHeadsUp(it)
        }
    }

    @Test
    fun testShouldHeadsUp_ungroupedChildNotif_groupAlertSummary() {
        withPeekAndPulseEntry({
            isGrouped = false
            isGroupSummary = false
            groupAlertBehavior = GROUP_ALERT_SUMMARY
        }) {
            assertShouldHeadsUp(it)
        }
    }

    @Test
    fun testShouldNotHeadsUp_justLaunchedFsi() {
        withPeekAndPulseEntry({ hasJustLaunchedFsi = true }) { assertShouldNotHeadsUp(it) }
    }

    @Test
    fun testShouldBubble_withIntentAndIcon() {
        ensureBubbleState()
@@ -357,6 +464,18 @@ abstract class VisualInterruptionDecisionProviderTestBase : SysuiTestCase() {
        assertShouldBubble(buildBubbleEntry())
    }

    @Test
    fun testShouldNotAlert_hiddenOnKeyguard() {
        ensurePeekState({ keyguardShouldHideNotification = true })
        assertShouldNotHeadsUp(buildPeekEntry())

        ensurePulseState({ keyguardShouldHideNotification = true })
        assertShouldNotHeadsUp(buildPulseEntry())

        ensureBubbleState({ keyguardShouldHideNotification = true })
        assertShouldNotBubble(buildBubbleEntry())
    }

    @Test
    fun testShouldFsi_notInteractive() {
        ensureNotInteractiveFsiState()
@@ -507,6 +626,10 @@ abstract class VisualInterruptionDecisionProviderTestBase : SysuiTestCase() {
        var hasBubbleMetadata = false
        var bubbleIsShortcut = false
        var bubbleSuppressesNotification: Boolean? = null
        var isGrouped = false
        var isGroupSummary: Boolean? = null
        var groupAlertBehavior: Int? = null
        var hasJustLaunchedFsi = false

        private fun buildBubbleMetadata(): BubbleMetadata {
            val builder =
@@ -544,6 +667,14 @@ abstract class VisualInterruptionDecisionProviderTestBase : SysuiTestCase() {
                    if (hasBubbleMetadata) {
                        setBubbleMetadata(buildBubbleMetadata())
                    }

                    if (isGrouped) {
                        setGroup(TEST_GROUP_KEY)
                    }

                    isGroupSummary?.let { setGroupSummary(it) }

                    groupAlertBehavior?.let { setGroupAlertBehavior(it) }
                }
                .build()
                .apply {
@@ -564,6 +695,10 @@ abstract class VisualInterruptionDecisionProviderTestBase : SysuiTestCase() {
                }
                .build()!!
                .also {
                    if (hasJustLaunchedFsi) {
                        it.notifyFullScreenIntentLaunched()
                    }

                    modifyRanking(it)
                        .apply {
                            suppressedVisualEffects?.let { setSuppressedVisualEffects(it) }
@@ -608,3 +743,4 @@ private const val TEST_CHANNEL_ID = "test_channel"
private const val TEST_CHANNEL_NAME = "Test Channel"
private const val TEST_PACKAGE = "test_package"
private const val TEST_TAG = "test_tag"
private const val TEST_GROUP_KEY = "test_group_key"