Merge "Don't post throttled notifications again."
diff --git a/java/com/android/dialer/app/calllog/MissedCallNotifier.java b/java/com/android/dialer/app/calllog/MissedCallNotifier.java
index 2cd0f77..f671fb7 100644
--- a/java/com/android/dialer/app/calllog/MissedCallNotifier.java
+++ b/java/com/android/dialer/app/calllog/MissedCallNotifier.java
@@ -229,15 +229,20 @@
 
     if (useCallList) {
       // Do not repost active notifications to prevent erasing post call notes.
-      Set<String> activeTags = new ArraySet<>();
+      Set<String> activeAndThrottledTags = new ArraySet<>();
       for (StatusBarNotification activeNotification :
           DialerNotificationManager.getActiveNotifications(context)) {
-        activeTags.add(activeNotification.getTag());
+        activeAndThrottledTags.add(activeNotification.getTag());
+      }
+      // Do not repost throttled notifications
+      for (StatusBarNotification throttledNotification :
+          DialerNotificationManager.getThrottledNotificationSet()) {
+        activeAndThrottledTags.add(throttledNotification.getTag());
       }
 
       for (NewCall call : newCalls) {
         String callTag = getNotificationTagForCall(call);
-        if (!activeTags.contains(callTag)) {
+        if (!activeAndThrottledTags.contains(callTag)) {
           DialerNotificationManager.notify(
               context,
               callTag,
diff --git a/java/com/android/dialer/notification/DialerNotificationManager.java b/java/com/android/dialer/notification/DialerNotificationManager.java
index 2a66cd5..eb730be 100644
--- a/java/com/android/dialer/notification/DialerNotificationManager.java
+++ b/java/com/android/dialer/notification/DialerNotificationManager.java
@@ -27,12 +27,17 @@
 import android.util.Pair;
 import com.android.dialer.common.Assert;
 import com.android.dialer.common.LogUtil;
+import java.util.HashSet;
+import java.util.Set;
 
 /**
  * Wrapper around the notification manager APIs. The wrapper ensures that channels are set and that
  * notifications are limited to 10 per group.
  */
 public final class DialerNotificationManager {
+
+  private static final Set<StatusBarNotification> throttledNotificationSet = new HashSet<>();
+
   public static void notify(@NonNull Context context, int id, @NonNull Notification notification) {
     Assert.isNotNull(context);
     Assert.isNotNull(notification);
@@ -50,7 +55,7 @@
     }
 
     getNotificationManager(context).notify(tag, id, notification);
-    NotificationThrottler.throttle(context, notification);
+    throttledNotificationSet.addAll(NotificationThrottler.throttle(context, notification));
   }
 
   public static void cancel(@NonNull Context context, int id) {
@@ -131,5 +136,9 @@
     return context.getSystemService(NotificationManager.class);
   }
 
+  public static Set<StatusBarNotification> getThrottledNotificationSet() {
+    return throttledNotificationSet;
+  }
+
   private DialerNotificationManager() {}
 }
diff --git a/java/com/android/dialer/notification/NotificationThrottler.java b/java/com/android/dialer/notification/NotificationThrottler.java
index 329a084..1f60920 100644
--- a/java/com/android/dialer/notification/NotificationThrottler.java
+++ b/java/com/android/dialer/notification/NotificationThrottler.java
@@ -29,13 +29,15 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 /**
  * Utility to ensure that only a certain number of notifications are shown for a particular
  * notification type. Once the limit is reached, older notifications are cancelled.
  */
-/* package */ class NotificationThrottler {
+class NotificationThrottler {
   /**
    * For gropued bundled notifications, the system UI will only display the last 8. For grouped
    * unbundled notifications, the system displays all notifications until a global maximum of 50 is
@@ -47,14 +49,23 @@
 
   private static boolean didLogHighGlobalNotificationCountReached;
 
-  /* package */ static void throttle(@NonNull Context context, @NonNull Notification notification) {
+  /**
+   * For all the active notifications in the same group as the provided notification, cancel the
+   * earliest ones until the left ones is under limit.
+   *
+   * @param notification the provided notification to determine group
+   * @return a set of cancelled notification
+   */
+  static Set<StatusBarNotification> throttle(
+      @NonNull Context context, @NonNull Notification notification) {
     Assert.isNotNull(context);
     Assert.isNotNull(notification);
+    Set<StatusBarNotification> throttledNotificationSet = new HashSet<>();
 
     // No limiting for non-grouped notifications.
     String groupKey = notification.getGroup();
     if (TextUtils.isEmpty(groupKey)) {
-      return;
+      return throttledNotificationSet;
     }
 
     NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
@@ -88,8 +99,10 @@
       List<StatusBarNotification> notifications = getSortedMatchingNotifications(context, groupKey);
       for (int i = 0; i < (count - MAX_NOTIFICATIONS_PER_TAG); i++) {
         notificationManager.cancel(notifications.get(i).getTag(), notifications.get(i).getId());
+        throttledNotificationSet.add(notifications.get(i));
       }
     }
+    return throttledNotificationSet;
   }
 
   private static List<StatusBarNotification> getSortedMatchingNotifications(