diff options
5 files changed, 127 insertions, 32 deletions
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 183a58a495a3..be63301e5749 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.SysuiTestCase 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 @@ class AvalancheControllerTest : SysuiTestCase() { 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 @@ class AvalancheControllerTest : SysuiTestCase() { // 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 830bcef55046..ed0d272cd848 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 @@ public class BaseHeadsUpManagerTest extends SysuiTestCase { 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 @@ public class BaseHeadsUpManagerTest extends SysuiTestCase { @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 @@ public class BaseHeadsUpManagerTest extends SysuiTestCase { @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 @@ public class BaseHeadsUpManagerTest extends SysuiTestCase { @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 @@ public class BaseHeadsUpManagerTest extends SysuiTestCase { // 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 c70b03b08789..bda86197d3bd 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 @@ public class HeadsUpManagerTestUtil { 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 6aaf5d60ac0b..55a0f59bf461 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 @@ class AvalancheController @Inject constructor() { } /** - * 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 05cc73edd892..50de3cba6b59 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java @@ -776,7 +776,7 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { 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) { @@ -806,7 +806,14 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { } 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) { @@ -929,10 +936,8 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { 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; |