Don't post throttled notifications again.

Throttled missed call notification can be post again since they are in the newCalls list and not in activeNotifications list. We should record them and don't post again.

Test: MissedCallNotifierTest, NotificationThrottlerTest
PiperOrigin-RevId: 197177610
Change-Id: I1b03029663621f0a0c06951564eadf78bad016a1
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(