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

Commit dff1a888 authored by Yuri Lin's avatar Yuri Lin
Browse files

Implement onRankingApplied in HeadsUpCoordinator

This allows us to detect any changes due to ranking updates that cause a notification to newly need to HUN.

Bug: 248325248
Test: manual, atest HeadsUpCoordinatorTest
Change-Id: I24b53cc33a518399dfbe57a66aefb07e80892fdf
parent d58065ce
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -440,6 +440,42 @@ class HeadsUpCoordinator @Inject constructor(
        override fun onEntryCleanUp(entry: NotificationEntry) {
            mHeadsUpViewBinder.abortBindCallback(entry)
        }

        /**
         * Identify notifications whose heads-up state changes when the notification rankings are
         * updated, and have those changed notifications alert if necessary.
         *
         * This method will occur after any operations in onEntryAdded or onEntryUpdated, so any
         * handling of ranking changes needs to take into account that we may have just made a
         * PostedEntry for some of these notifications.
         */
        override fun onRankingApplied() {
            // Because a ranking update may cause some notifications that are no longer (or were
            // never) in mPostedEntries to need to alert, we need to check every notification
            // known to the pipeline.
            for (entry in mNotifPipeline.allNotifs) {
                // The only entries we can consider alerting for here are entries that have never
                // interrupted and that now say they should heads up; if they've alerted in the
                // past, we don't want to incorrectly alert a second time if there wasn't an
                // explicit notification update.
                if (entry.hasInterrupted()) continue

                // The cases where we should consider this notification to be updated:
                // - if this entry is not present in PostedEntries, and is now in a shouldHeadsUp
                //   state
                // - if it is present in PostedEntries and the previous state of shouldHeadsUp
                //   differs from the updated one
                val shouldHeadsUpEver = mNotificationInterruptStateProvider.checkHeadsUp(entry,
                                /* log= */ false)
                val postedShouldHeadsUpEver = mPostedEntries[entry.key]?.shouldHeadsUpEver ?: false
                val shouldUpdateEntry = postedShouldHeadsUpEver != shouldHeadsUpEver

                if (shouldUpdateEntry) {
                    mLogger.logEntryUpdatedByRanking(entry.key, shouldHeadsUpEver)
                    onEntryUpdated(entry)
                }
            }
        }
    }

    /**
+9 −0
Original line number Diff line number Diff line
@@ -59,4 +59,13 @@ class HeadsUpCoordinatorLogger constructor(
                    " numPostedEntries=$int1 logicalGroupSize=$int2"
        })
    }

    fun logEntryUpdatedByRanking(key: String, shouldHun: Boolean) {
        buffer.log(TAG, LogLevel.DEBUG, {
            str1 = key
            bool1 = shouldHun
        }, {
            "updating entry via ranking applied: $str1 updated shouldHeadsUp=$bool1"
        })
    }
}
+59 −3
Original line number Diff line number Diff line
@@ -47,6 +47,8 @@ import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.withArgCaptor
import com.android.systemui.util.time.FakeSystemClock
import java.util.ArrayList
import java.util.function.Consumer
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Before
@@ -57,10 +59,8 @@ import org.mockito.BDDMockito.given
import org.mockito.Mockito.never
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
import java.util.ArrayList
import java.util.function.Consumer
import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations

@SmallTest
@RunWith(AndroidTestingRunner::class)
@@ -671,8 +671,64 @@ class HeadsUpCoordinatorTest : SysuiTestCase() {
        verify(mHeadsUpManager, never()).showNotification(mGroupChild2)
    }

    @Test
    fun testOnRankingApplied_newEntryShouldAlert() {
        // GIVEN that mEntry has never interrupted in the past, and now should
        assertFalse(mEntry.hasInterrupted())
        setShouldHeadsUp(mEntry)
        whenever(mNotifPipeline.allNotifs).thenReturn(listOf(mEntry))

        // WHEN a ranking applied update occurs
        mCollectionListener.onRankingApplied()
        mBeforeTransformGroupsListener.onBeforeTransformGroups(listOf(mEntry))
        mBeforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(mEntry))

        // THEN the notification is shown
        finishBind(mEntry)
        verify(mHeadsUpManager).showNotification(mEntry)
    }

    @Test
    fun testOnRankingApplied_alreadyAlertedEntryShouldNotAlertAgain() {
        // GIVEN that mEntry has alerted in the past
        mEntry.setInterruption()
        setShouldHeadsUp(mEntry)
        whenever(mNotifPipeline.allNotifs).thenReturn(listOf(mEntry))

        // WHEN a ranking applied update occurs
        mCollectionListener.onRankingApplied()
        mBeforeTransformGroupsListener.onBeforeTransformGroups(listOf(mEntry))
        mBeforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(mEntry))

        // THEN the notification is never bound or shown
        verify(mHeadsUpViewBinder, never()).bindHeadsUpView(any(), any())
        verify(mHeadsUpManager, never()).showNotification(any())
    }

    @Test
    fun testOnRankingApplied_entryUpdatedToHun() {
        // GIVEN that mEntry is added in a state where it should not HUN
        setShouldHeadsUp(mEntry, false)
        mCollectionListener.onEntryAdded(mEntry)

        // and it is then updated such that it should now HUN
        setShouldHeadsUp(mEntry)
        whenever(mNotifPipeline.allNotifs).thenReturn(listOf(mEntry))

        // WHEN a ranking applied update occurs
        mCollectionListener.onRankingApplied()
        mBeforeTransformGroupsListener.onBeforeTransformGroups(listOf(mEntry))
        mBeforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(mEntry))

        // THEN the notification is shown
        finishBind(mEntry)
        verify(mHeadsUpManager).showNotification(mEntry)
    }

    private fun setShouldHeadsUp(entry: NotificationEntry, should: Boolean = true) {
        whenever(mNotificationInterruptStateProvider.shouldHeadsUp(entry)).thenReturn(should)
        whenever(mNotificationInterruptStateProvider.checkHeadsUp(eq(entry), any()))
                .thenReturn(should)
    }

    private fun finishBind(entry: NotificationEntry) {