Set avalanche HUN duration based on next top HUN priority
Bug: 315362456
Flag: ACONFIG notification_throttle_hun DEVELOPMENT
Test: AvalancheControllerTest
Change-Id: I35962c0f97bc65f0df8688e4156be1daf82117e1
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/AvalancheControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/AvalancheControllerTest.kt
index 183a58a..be63301 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/AvalancheControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/AvalancheControllerTest.kt
@@ -25,6 +25,7 @@
import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun
+import com.android.systemui.statusbar.policy.HeadsUpManagerTestUtil.createFullScreenIntentEntry
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.settings.FakeGlobalSettings
import com.android.systemui.util.time.FakeSystemClock
@@ -97,6 +98,12 @@
return entry
}
+ private fun createFsiHeadsUpEntry(id: Int): BaseHeadsUpManager.HeadsUpEntry {
+ val entry = testableHeadsUpManager!!.createHeadsUpEntry()
+ entry.setEntry(createFullScreenIntentEntry(id, mContext))
+ return entry
+ }
+
@Test
fun testUpdate_isShowing_runsRunnable() {
// Entry is showing
@@ -238,4 +245,68 @@
// Next entry is shown
Truth.assertThat(mAvalancheController.headsUpEntryShowing).isEqualTo(nextEntry)
}
+
+ @Test
+ fun testGetDurationMs_lastEntry_useAutoDismissTime() {
+ // Entry is showing
+ val showingEntry = createHeadsUpEntry(id = 0)
+ mAvalancheController.headsUpEntryShowing = showingEntry
+
+ // Nothing is next
+ mAvalancheController.clearNext()
+
+ val durationMs = mAvalancheController.getDurationMs(showingEntry, autoDismissMs = 5000)
+ Truth.assertThat(durationMs).isEqualTo(5000)
+ }
+
+ @Test
+ fun testGetDurationMs_nextEntryLowerPriority_500() {
+ // Entry is showing
+ val showingEntry = createFsiHeadsUpEntry(id = 1)
+ mAvalancheController.headsUpEntryShowing = showingEntry
+
+ // There's another entry waiting to show next
+ val nextEntry = createHeadsUpEntry(id = 0)
+ mAvalancheController.addToNext(nextEntry, runnableMock!!)
+
+ // Next entry has lower priority
+ Truth.assertThat(nextEntry.compareNonTimeFields(showingEntry)).isEqualTo(1)
+
+ val durationMs = mAvalancheController.getDurationMs(showingEntry, autoDismissMs = 5000)
+ Truth.assertThat(durationMs).isEqualTo(5000)
+ }
+
+ @Test
+ fun testGetDurationMs_nextEntrySamePriority_1000() {
+ // Entry is showing
+ val showingEntry = createHeadsUpEntry(id = 0)
+ mAvalancheController.headsUpEntryShowing = showingEntry
+
+ // There's another entry waiting to show next
+ val nextEntry = createHeadsUpEntry(id = 1)
+ mAvalancheController.addToNext(nextEntry, runnableMock!!)
+
+ // Same priority
+ Truth.assertThat(nextEntry.compareNonTimeFields(showingEntry)).isEqualTo(0)
+
+ val durationMs = mAvalancheController.getDurationMs(showingEntry, autoDismissMs = 5000)
+ Truth.assertThat(durationMs).isEqualTo(1000)
+ }
+
+ @Test
+ fun testGetDurationMs_nextEntryHigherPriority_500() {
+ // Entry is showing
+ val showingEntry = createHeadsUpEntry(id = 0)
+ mAvalancheController.headsUpEntryShowing = showingEntry
+
+ // There's another entry waiting to show next
+ val nextEntry = createFsiHeadsUpEntry(id = 1)
+ mAvalancheController.addToNext(nextEntry, runnableMock!!)
+
+ // Next entry has higher priority
+ Truth.assertThat(nextEntry.compareNonTimeFields(showingEntry)).isEqualTo(-1)
+
+ val durationMs = mAvalancheController.getDurationMs(showingEntry, autoDismissMs = 5000)
+ Truth.assertThat(durationMs).isEqualTo(500)
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java
index 830bcef..ed0d272 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java
@@ -117,21 +117,6 @@
return HeadsUpManagerTestUtil.createEntry(id, notif);
}
- private PendingIntent createFullScreenIntent() {
- return PendingIntent.getActivity(
- getContext(), 0, new Intent(getContext(), this.getClass()),
- PendingIntent.FLAG_MUTABLE_UNAUDITED);
- }
-
- private NotificationEntry createFullScreenIntentEntry(int id) {
- final Notification notif = new Notification.Builder(mContext, "")
- .setSmallIcon(R.drawable.ic_person)
- .setFullScreenIntent(createFullScreenIntent(), /* highPriority */ true)
- .build();
- return HeadsUpManagerTestUtil.createEntry(id, notif);
- }
-
-
private void useAccessibilityTimeout(boolean use) {
if (use) {
doReturn(TEST_A11Y_AUTO_DISMISS_TIME).when(mAccessibilityMgr)
@@ -239,7 +224,8 @@
@Test
public void testShouldHeadsUpBecomePinned_hasFSI_notUnpinned_true() {
final BaseHeadsUpManager hum = createHeadsUpManager();
- final NotificationEntry notifEntry = createFullScreenIntentEntry(/* id = */ 0);
+ final NotificationEntry notifEntry =
+ HeadsUpManagerTestUtil.createFullScreenIntentEntry(/* id = */ 0, mContext);
// Add notifEntry to ANM mAlertEntries map and make it NOT unpinned
hum.showNotification(notifEntry);
@@ -254,7 +240,8 @@
@Test
public void testShouldHeadsUpBecomePinned_wasUnpinned_false() {
final BaseHeadsUpManager hum = createHeadsUpManager();
- final NotificationEntry notifEntry = createFullScreenIntentEntry(/* id = */ 0);
+ final NotificationEntry notifEntry =
+ HeadsUpManagerTestUtil.createFullScreenIntentEntry(/* id = */ 0, mContext);
// Add notifEntry to ANM mAlertEntries map and make it unpinned
hum.showNotification(notifEntry);
@@ -443,7 +430,8 @@
@Test
public void testIsSticky_hasFullScreenIntent_true() {
final BaseHeadsUpManager hum = createHeadsUpManager();
- final NotificationEntry notifEntry = createFullScreenIntentEntry(/* id = */ 0);
+ final NotificationEntry notifEntry =
+ HeadsUpManagerTestUtil.createFullScreenIntentEntry(/* id = */ 0, mContext);
hum.showNotification(notifEntry);
@@ -554,7 +542,8 @@
// Needs full screen intent in order to be pinned
final BaseHeadsUpManager.HeadsUpEntry entryToPin = hum.new HeadsUpEntry();
- entryToPin.setEntry(createFullScreenIntentEntry(/* id = */ 0));
+ entryToPin.setEntry(
+ HeadsUpManagerTestUtil.createFullScreenIntentEntry(/* id = */ 0, mContext));
// Note: the standard way to show a notification would be calling showNotification rather
// than onAlertEntryAdded. However, in practice showNotification in effect adds
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTestUtil.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTestUtil.java
index c70b03b..bda8619 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTestUtil.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTestUtil.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.policy;
import android.app.ActivityManager;
+import android.app.PendingIntent;
+import android.content.Intent;
import android.os.UserHandle;
import android.content.Context;
@@ -67,4 +69,16 @@
return new NotificationEntryBuilder().setSbn(
HeadsUpManagerTestUtil.createSbn(id, context)).build();
}
+
+ protected static NotificationEntry createFullScreenIntentEntry(int id, Context context) {
+ final PendingIntent intent = PendingIntent.getActivity(
+ context, 0, new Intent(),
+ PendingIntent.FLAG_IMMUTABLE);
+
+ final Notification notif = new Notification.Builder(context, "")
+ .setSmallIcon(com.android.systemui.res.R.drawable.ic_person)
+ .setFullScreenIntent(intent, /* highPriority */ true)
+ .build();
+ return HeadsUpManagerTestUtil.createEntry(id, notif);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt
index 6aaf5d6..55a0f59 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt
@@ -131,21 +131,37 @@
}
/**
- * Returns true if given HeadsUpEntry is the last one tracked by AvalancheController. Used by
- * BaseHeadsUpManager.HeadsUpEntry.calculateFinishTime to shorten display duration during active
- * avalanche.
+ * Returns duration based on
+ * 1) Whether HeadsUpEntry is the last one tracked byAvalancheController
+ * 2) The priority of the top HUN in the next batch Used by
+ * BaseHeadsUpManager.HeadsUpEntry.calculateFinishTime to shorten display duration.
*/
- fun shortenDuration(entry: HeadsUpEntry): Boolean {
+ fun getDurationMs(entry: HeadsUpEntry, autoDismissMs: Int): Int {
if (!NotificationThrottleHun.isEnabled) {
- // Use default display duration, like we always did before AvalancheController existed
- return false
+ // Use default duration, like we did before AvalancheController existed
+ return autoDismissMs
}
val showingList: MutableList<HeadsUpEntry> = mutableListOf()
headsUpEntryShowing?.let { showingList.add(it) }
- val allEntryList = showingList + nextList
- // Shorten duration if not last entry
- return allEntryList.indexOf(entry) != allEntryList.size - 1
+ val entryList = showingList + nextList
+ if (entryList.indexOf(entry) == entryList.size - 1) {
+ // Use default duration if last entry
+ return autoDismissMs
+ }
+
+ nextList.sort()
+ val nextEntry = nextList[0]
+
+ if (nextEntry.compareNonTimeFields(entry) == -1) {
+ // Next entry is higher priority
+ return 500
+ } else if (nextEntry.compareNonTimeFields(entry) == 0) {
+ // Next entry is same priority
+ return 1000
+ } else {
+ return autoDismissMs
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java
index fae0f0c..639d604 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java
@@ -767,7 +767,7 @@
return mEarliestRemovalTime < mSystemClock.elapsedRealtime();
}
- public int compareTo(@NonNull HeadsUpEntry headsUpEntry) {
+ public int compareNonTimeFields(HeadsUpEntry headsUpEntry) {
boolean isPinned = mEntry.isRowPinned();
boolean otherPinned = headsUpEntry.mEntry.isRowPinned();
if (isPinned && !otherPinned) {
@@ -797,7 +797,14 @@
} else if (!mRemoteInputActive && headsUpEntry.mRemoteInputActive) {
return 1;
}
+ return 0;
+ }
+ public int compareTo(@NonNull HeadsUpEntry headsUpEntry) {
+ int nonTimeCompareResult = compareNonTimeFields(headsUpEntry);
+ if (nonTimeCompareResult != 0) {
+ return nonTimeCompareResult;
+ }
if (mPostTime > headsUpEntry.mPostTime) {
return -1;
} else if (mPostTime == headsUpEntry.mPostTime) {
@@ -920,10 +927,8 @@
int requestedTimeOutMs;
if (isStickyForSomeTime()) {
requestedTimeOutMs = mStickyForSomeTimeAutoDismissTime;
- } else if (mAvalancheController.shortenDuration(this)) {
- requestedTimeOutMs = 1000;
} else {
- requestedTimeOutMs = mAutoDismissTime;
+ requestedTimeOutMs = mAvalancheController.getDurationMs(this, mAutoDismissTime);
}
final long duration = getRecommendedHeadsUpTimeoutMs(requestedTimeOutMs);
return mPostTime + duration;