summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt36
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorLogger.kt9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt62
3 files changed, 104 insertions, 3 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
index ccf6feca6992..8f3eb4f7e223 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
@@ -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)
+ }
+ }
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorLogger.kt
index 204a494c32e8..8625cdbc89d5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorLogger.kt
@@ -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"
+ })
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
index 2970807afb36..340bc96f80c2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
@@ -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) {