diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AlertingNotificationManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/AlertingNotificationManager.java index 7cf0583206e11..2a21f421869b8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/AlertingNotificationManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/AlertingNotificationManager.java @@ -238,7 +238,7 @@ public abstract class AlertingNotificationManager implements NotificationLifetim * @param key the key to check if removable * @return true if the alert entry can be removed */ - protected boolean canRemoveImmediately(String key) { + public boolean canRemoveImmediately(String key) { AlertEntry alertEntry = mAlertEntries.get(key); return alertEntry == null || alertEntry.wasShownLongEnough() || alertEntry.mEntry.isRowDismissed(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.java index ed9663e9c6727..f9f0b9da87782 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.java @@ -179,23 +179,26 @@ public class HeadsUpCoordinator implements Coordinator { @Override public boolean shouldExtendLifetime(@NonNull NotificationEntry entry, int reason) { - boolean isShowingHun = isCurrentlyShowingHun(entry); - if (isShowingHun) { + boolean extend = !mHeadsUpManager.canRemoveImmediately(entry.getKey()); + if (extend) { if (isSticky(entry)) { long removeAfterMillis = mHeadsUpManager.getEarliestRemovalTime(entry.getKey()); - if (removeAfterMillis <= 0) return false; mExecutor.executeDelayed(() -> { - // make sure that the entry was not updated - long removeAfterMillis2 = - mHeadsUpManager.getEarliestRemovalTime(entry.getKey()); - if (mNotifsExtendingLifetime.contains(entry) && removeAfterMillis2 <= 0) { - mHeadsUpManager.removeNotification(entry.getKey(), true); + if (mNotifsExtendingLifetime.contains(entry) + && mHeadsUpManager.canRemoveImmediately(entry.getKey())) { + mHeadsUpManager.removeNotification( + entry.getKey(), /* releaseImmediately */ true); } }, removeAfterMillis); + } else { + // remove as early as possible + mExecutor.execute( + () -> mHeadsUpManager.removeNotification( + entry.getKey(), /* releaseImmediately */ false)); } mNotifsExtendingLifetime.add(entry); } - return isShowingHun; + return extend; } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java index 01acce302b308..2824ab85152f8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java @@ -412,7 +412,7 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, } @Override - protected boolean canRemoveImmediately(@NonNull String key) { + public boolean canRemoveImmediately(@NonNull String key) { if (mSwipedOutKeys.contains(key)) { // We always instantly dismiss views being manually swiped out. mSwipedOutKeys.remove(key); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.java index a11b46df12182..b3ee5f8373e45 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.java @@ -140,10 +140,13 @@ public class HeadsUpCoordinatorTest extends SysuiTestCase { public void testCancelStickyNotification() { when(mHeadsUpManager.isSticky(anyString())).thenReturn(true); addHUN(mEntry); + when(mHeadsUpManager.canRemoveImmediately(anyString())).thenReturn(false, true); when(mHeadsUpManager.getEarliestRemovalTime(anyString())).thenReturn(1000L, 0L); assertTrue(mNotifLifetimeExtender.shouldExtendLifetime(mEntry, 0)); mClock.advanceTime(1000L); mExecutor.runAllReady(); + verify(mHeadsUpManager, times(0)) + .removeNotification(anyString(), eq(false)); verify(mHeadsUpManager, times(1)) .removeNotification(anyString(), eq(true)); } @@ -156,6 +159,22 @@ public class HeadsUpCoordinatorTest extends SysuiTestCase { assertTrue(mNotifLifetimeExtender.shouldExtendLifetime(mEntry, 0)); mClock.advanceTime(1000L); mExecutor.runAllReady(); + verify(mHeadsUpManager, times(0)) + .removeNotification(anyString(), eq(false)); + verify(mHeadsUpManager, times(0)) + .removeNotification(anyString(), eq(true)); + } + + @Test + public void testCancelNotification() { + when(mHeadsUpManager.isSticky(anyString())).thenReturn(false); + addHUN(mEntry); + when(mHeadsUpManager.getEarliestRemovalTime(anyString())).thenReturn(1000L, 500L); + assertTrue(mNotifLifetimeExtender.shouldExtendLifetime(mEntry, 0)); + mClock.advanceTime(1000L); + mExecutor.runAllReady(); + verify(mHeadsUpManager, times(1)) + .removeNotification(anyString(), eq(false)); verify(mHeadsUpManager, times(0)) .removeNotification(anyString(), eq(true)); } @@ -189,6 +208,13 @@ public class HeadsUpCoordinatorTest extends SysuiTestCase { // GIVEN there is a HUN, mEntry addHUN(mEntry); + given(mHeadsUpManager.canRemoveImmediately(anyString())).willAnswer(i -> { + String key = i.getArgument(0); + for (NotificationEntry entry : mHuns) { + if (entry.getKey().equals(key)) return false; + } + return true; + }); // THEN only the current HUN, mEntry, should be lifetimeExtended assertTrue(mNotifLifetimeExtender.shouldExtendLifetime(mEntry, /* cancellationReason */ 0)); assertFalse(mNotifLifetimeExtender.shouldExtendLifetime(