diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index aea15e1..007fa5d 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -4123,6 +4123,17 @@
     }
 
     /**
+     * Sets which type of notifications in a group are responsible for audibly alerting the
+     * user. See {@link #GROUP_ALERT_ALL}, {@link #GROUP_ALERT_CHILDREN},
+     * {@link #GROUP_ALERT_SUMMARY}.
+     * @param groupAlertBehavior
+     * @hide
+     */
+    public void setGroupAlertBehavior(@GroupAlertBehavior int groupAlertBehavior) {
+        mGroupAlertBehavior = groupAlertBehavior;
+    }
+
+    /**
      * Returns the bubble metadata that will be used to display app content in a floating window
      * over the existing foreground activity.
      */
diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java
index 264b53c..146c2b6 100644
--- a/core/java/android/service/notification/StatusBarNotification.java
+++ b/core/java/android/service/notification/StatusBarNotification.java
@@ -176,7 +176,11 @@
 
     private String groupKey() {
         if (overrideGroupKey != null) {
-            return user.getIdentifier() + "|" + pkg + "|" + "g:" + overrideGroupKey;
+            if (Flags.notificationForceGrouping()) {
+                return overrideGroupKey;
+            } else {
+                return user.getIdentifier() + "|" + pkg + "|" + "g:" + overrideGroupKey;
+            }
         }
         final String group = getNotification().getGroup();
         final String sortKey = getNotification().getSortKey();
diff --git a/core/java/android/service/notification/flags.aconfig b/core/java/android/service/notification/flags.aconfig
index bdef041..51961a8 100644
--- a/core/java/android/service/notification/flags.aconfig
+++ b/core/java/android/service/notification/flags.aconfig
@@ -43,4 +43,18 @@
     namespace: "systemui"
     description: "Allows the NAS to classify notifications"
     bug: "343988084"
+}
+
+flag {
+  name: "notification_force_grouping"
+  namespace: "systemui"
+  description: "This flag controls the forced auto-grouping feature"
+  bug: "336488844"
+}
+
+flag {
+  name: "notification_silent_flag"
+  namespace: "systemui"
+  description: "Guards the new FLAG_SILENT Notification flag"
+  bug: "336488844"
 }
\ No newline at end of file
diff --git a/services/core/java/com/android/server/notification/GroupHelper.java b/services/core/java/com/android/server/notification/GroupHelper.java
index 13cc99c..1cdab44 100644
--- a/services/core/java/com/android/server/notification/GroupHelper.java
+++ b/services/core/java/com/android/server/notification/GroupHelper.java
@@ -24,9 +24,14 @@
 import static android.app.Notification.FLAG_ONGOING_EVENT;
 import static android.app.Notification.VISIBILITY_PRIVATE;
 import static android.app.Notification.VISIBILITY_PUBLIC;
+import static android.service.notification.Flags.notificationForceGrouping;
 
+import android.annotation.FlaggedApi;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -34,7 +39,9 @@
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
 import android.service.notification.StatusBarNotification;
+import android.text.TextUtils;
 import android.util.ArrayMap;
+import android.util.Log;
 import android.util.Slog;
 
 import com.android.internal.R;
@@ -42,14 +49,20 @@
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
+import java.util.Set;
+import java.util.function.Predicate;
 
 /**
  * NotificationManagerService helper for auto-grouping notifications.
  */
 public class GroupHelper {
     private static final String TAG = "GroupHelper";
+    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     protected static final String AUTOGROUP_KEY = "ranker_group";
 
@@ -63,8 +76,16 @@
     // Flags that autogroup summaries inherits if any child has them
     private static final int ANY_CHILDREN_FLAGS = FLAG_ONGOING_EVENT | FLAG_NO_CLEAR;
 
+    protected static final String AGGREGATE_GROUP_KEY = "Aggregate_";
+
+    // If an app posts more than NotificationManagerService.AUTOGROUP_SPARSE_GROUPS_AT_COUNT groups
+    //  with less than this value, they will be forced grouped
+    private static final int MIN_CHILD_COUNT_TO_AVOID_FORCE_GROUPING = 3;
+
+
     private final Callback mCallback;
     private final int mAutoGroupAtCount;
+    private final int mAutogroupSparseGroupsAtCount;
     private final Context mContext;
     private final PackageManager mPackageManager;
 
@@ -75,12 +96,41 @@
     private final ArrayMap<String, ArrayMap<String, NotificationAttributes>> mUngroupedNotifications
             = new ArrayMap<>();
 
+    // Contains the list of notifications that should be aggregated (forced grouping)
+    // but there are less than mAutoGroupAtCount per section for a package.
+    // The primary map's key is the full aggregated group key: userId|pkgName|g:groupName
+    // The internal map's key is the notification record key
+    @GuardedBy("mAggregatedNotifications")
+    private final ArrayMap<FullyQualifiedGroupKey, ArrayMap<String, NotificationAttributes>>
+            mUngroupedAbuseNotifications = new ArrayMap<>();
+
+    // Contains the list of group summaries that were canceled when "singleton groups" were
+    // force grouped. Used to remove the original group's children when an app cancels the
+    // already removed summary. Key is userId|packageName|g:OriginalGroupName
+    @GuardedBy("mAggregatedNotifications")
+    private final ArrayMap<FullyQualifiedGroupKey, CachedSummary>
+            mCanceledSummaries = new ArrayMap<>();
+
+    // Represents the current state of the aggregated (forced grouped) notifications
+    // Key is the full aggregated group key: userId|pkgName|g:groupName
+    // And groupName is "Aggregate_"+sectionName
+    @GuardedBy("mAggregatedNotifications")
+    private final ArrayMap<FullyQualifiedGroupKey, ArrayMap<String, NotificationAttributes>>
+            mAggregatedNotifications = new ArrayMap<>();
+
+    private static final List<NotificationSectioner> NOTIFICATION_SHADE_SECTIONS = List.of(
+        new NotificationSectioner("AlertingSection", 0, (record) ->
+            record.getImportance() >= NotificationManager.IMPORTANCE_DEFAULT),
+        new NotificationSectioner("SilentSection", 1, (record) ->
+            record.getImportance() < NotificationManager.IMPORTANCE_DEFAULT));
+
     public GroupHelper(Context context, PackageManager packageManager, int autoGroupAtCount,
-            Callback callback) {
+            int autoGroupSparseGroupsAtCount, Callback callback) {
         mAutoGroupAtCount = autoGroupAtCount;
         mCallback =  callback;
         mContext = context;
         mPackageManager = packageManager;
+        mAutogroupSparseGroupsAtCount = autoGroupSparseGroupsAtCount;
     }
 
     private String generatePackageKey(int userId, String pkg) {
@@ -88,40 +138,50 @@
     }
 
     @VisibleForTesting
-    @GuardedBy("mUngroupedNotifications")
-    protected int getAutogroupSummaryFlags(
-            @NonNull final ArrayMap<String, NotificationAttributes> children) {
+    protected static int getAutogroupSummaryFlags(
+            @NonNull final ArrayMap<String, NotificationAttributes> childrenMap) {
+        final Collection<NotificationAttributes> children = childrenMap.values();
         boolean allChildrenHasFlag = children.size() > 0;
         int anyChildFlagSet = 0;
-        for (int i = 0; i < children.size(); i++) {
-            if (!hasAnyFlag(children.valueAt(i).flags, ALL_CHILDREN_FLAG)) {
+        for (NotificationAttributes childAttr: children) {
+            if (!hasAnyFlag(childAttr.flags, ALL_CHILDREN_FLAG)) {
                 allChildrenHasFlag = false;
             }
-            if (hasAnyFlag(children.valueAt(i).flags, ANY_CHILDREN_FLAGS)) {
-                anyChildFlagSet |= (children.valueAt(i).flags & ANY_CHILDREN_FLAGS);
+            if (hasAnyFlag(childAttr.flags, ANY_CHILDREN_FLAGS)) {
+                anyChildFlagSet |= (childAttr.flags & ANY_CHILDREN_FLAGS);
             }
         }
         return BASE_FLAGS | (allChildrenHasFlag ? ALL_CHILDREN_FLAG : 0) | anyChildFlagSet;
     }
 
-    private boolean hasAnyFlag(int flags, int mask) {
+    private static boolean hasAnyFlag(int flags, int mask) {
         return (flags & mask) != 0;
     }
 
     /**
      * Called when a notification is newly posted. Checks whether that notification, and all other
      * active notifications should be grouped or ungrouped atuomatically, and returns whether.
-     * @param sbn The posted notification.
+     * @param record The posted notification.
      * @param autogroupSummaryExists Whether a summary for this notification already exists.
      * @return Whether the provided notification should be autogrouped synchronously.
      */
-    public boolean onNotificationPosted(StatusBarNotification sbn, boolean autogroupSummaryExists) {
+    public boolean onNotificationPosted(NotificationRecord record, boolean autogroupSummaryExists) {
         boolean sbnToBeAutogrouped = false;
         try {
-            if (!sbn.isAppGroup()) {
-                sbnToBeAutogrouped = maybeGroup(sbn, autogroupSummaryExists);
+            if (notificationForceGrouping()) {
+                final StatusBarNotification sbn = record.getSbn();
+                if (!sbn.isAppGroup()) {
+                    sbnToBeAutogrouped = maybeGroupWithSections(record, autogroupSummaryExists);
+                } else {
+                    maybeUngroupWithSections(record);
+                }
             } else {
-                maybeUngroup(sbn, false, sbn.getUserId());
+                final StatusBarNotification sbn = record.getSbn();
+                if (!sbn.isAppGroup()) {
+                    sbnToBeAutogrouped = maybeGroup(sbn, autogroupSummaryExists);
+                } else {
+                    maybeUngroup(sbn, false, sbn.getUserId());
+                }
             }
         } catch (Exception e) {
             Slog.e(TAG, "Failure processing new notification", e);
@@ -129,9 +189,20 @@
         return sbnToBeAutogrouped;
     }
 
-    public void onNotificationRemoved(StatusBarNotification sbn) {
+    /**
+     * Called when a notification was removed. Checks if that notification was part of an autogroup
+     * and triggers any necessary cleanups: summary removal, clearing caches etc.
+     *
+     * @param record The removed notification.
+     */
+    public void onNotificationRemoved(NotificationRecord record) {
         try {
-            maybeUngroup(sbn, true, sbn.getUserId());
+            if (notificationForceGrouping()) {
+                onNotificationRemoved(record, new ArrayList<>());
+            } else {
+                final StatusBarNotification sbn = record.getSbn();
+                maybeUngroup(sbn, true, sbn.getUserId());
+            }
         } catch (Exception e) {
             Slog.e(TAG, "Error processing canceled notification", e);
         }
@@ -156,10 +227,10 @@
             String packageKey = generatePackageKey(sbn.getUserId(), sbn.getPackageName());
             final ArrayMap<String, NotificationAttributes> children =
                     mUngroupedNotifications.getOrDefault(packageKey, new ArrayMap<>());
-
             NotificationAttributes attr = new NotificationAttributes(sbn.getNotification().flags,
                     sbn.getNotification().getSmallIcon(), sbn.getNotification().color,
-                    sbn.getNotification().visibility);
+                    sbn.getNotification().visibility, Notification.GROUP_ALERT_CHILDREN,
+                    sbn.getNotification().getChannelId());
             children.put(sbn.getKey(), attr);
             mUngroupedNotifications.put(packageKey, children);
 
@@ -173,17 +244,20 @@
             if (autogroupSummaryExists) {
                 NotificationAttributes attr = new NotificationAttributes(flags,
                         sbn.getNotification().getSmallIcon(), sbn.getNotification().color,
-                        VISIBILITY_PRIVATE);
+                        VISIBILITY_PRIVATE, Notification.GROUP_ALERT_CHILDREN,
+                        sbn.getNotification().getChannelId());
                 if (Flags.autogroupSummaryIconUpdate()) {
                     attr = updateAutobundledSummaryAttributes(sbn.getPackageName(), childrenAttr,
                             attr);
                 }
 
-                mCallback.updateAutogroupSummary(sbn.getUserId(), sbn.getPackageName(), attr);
+                mCallback.updateAutogroupSummary(sbn.getUserId(), sbn.getPackageName(),
+                        AUTOGROUP_KEY, attr);
             } else {
                 Icon summaryIcon = sbn.getNotification().getSmallIcon();
                 int summaryIconColor = sbn.getNotification().color;
                 int summaryVisibility = VISIBILITY_PRIVATE;
+                String summaryChannelId = sbn.getNotification().getChannelId();
                 if (Flags.autogroupSummaryIconUpdate()) {
                     // Calculate the initial summary icon, icon color and visibility
                     NotificationAttributes iconAttr = getAutobundledSummaryAttributes(
@@ -191,12 +265,14 @@
                     summaryIcon = iconAttr.icon;
                     summaryIconColor = iconAttr.iconColor;
                     summaryVisibility = iconAttr.visibility;
+                    summaryChannelId = iconAttr.channelId;
                 }
 
                 NotificationAttributes attr = new NotificationAttributes(flags, summaryIcon,
-                        summaryIconColor, summaryVisibility);
+                        summaryIconColor, summaryVisibility, Notification.GROUP_ALERT_CHILDREN,
+                        summaryChannelId);
                 mCallback.addAutoGroupSummary(sbn.getUserId(), sbn.getPackageName(), sbn.getKey(),
-                        attr);
+                        AUTOGROUP_KEY, Integer.MAX_VALUE, attr);
             }
             for (String keyToGroup : notificationsToGroup) {
                 if (android.app.Flags.checkAutogroupBeforePost()) {
@@ -204,10 +280,10 @@
                         // Autogrouping for the provided notification is to be done synchronously.
                         sbnToBeAutogrouped = true;
                     } else {
-                        mCallback.addAutoGroup(keyToGroup, /*requestSort=*/true);
+                        mCallback.addAutoGroup(keyToGroup, AUTOGROUP_KEY, /*requestSort=*/true);
                     }
                 } else {
-                    mCallback.addAutoGroup(keyToGroup, /*requestSort=*/true);
+                    mCallback.addAutoGroup(keyToGroup, AUTOGROUP_KEY, /*requestSort=*/true);
                 }
             }
         }
@@ -263,11 +339,12 @@
         }
 
         if (removeSummary) {
-            mCallback.removeAutoGroupSummary(userId, sbn.getPackageName());
+            mCallback.removeAutoGroupSummary(userId, sbn.getPackageName(), AUTOGROUP_KEY);
         } else {
             NotificationAttributes attr = new NotificationAttributes(summaryFlags,
                     sbn.getNotification().getSmallIcon(), sbn.getNotification().color,
-                    VISIBILITY_PRIVATE);
+                    VISIBILITY_PRIVATE, Notification.GROUP_ALERT_CHILDREN,
+                    sbn.getNotification().getChannelId());
             boolean attributesUpdated = false;
             if (Flags.autogroupSummaryIconUpdate()) {
                 NotificationAttributes newAttr = updateAutobundledSummaryAttributes(
@@ -279,7 +356,7 @@
             }
 
             if (updateSummaryFlags || attributesUpdated) {
-                mCallback.updateAutogroupSummary(userId, sbn.getPackageName(), attr);
+                mCallback.updateAutogroupSummary(userId, sbn.getPackageName(), AUTOGROUP_KEY, attr);
             }
         }
         if (removeAutogroupOverlay) {
@@ -287,16 +364,6 @@
         }
     }
 
-    @VisibleForTesting
-    int getNotGroupedByAppCount(int userId, String pkg) {
-        synchronized (mUngroupedNotifications) {
-            String key = generatePackageKey(userId, pkg);
-            final ArrayMap<String, NotificationAttributes> children =
-                    mUngroupedNotifications.getOrDefault(key, new ArrayMap<>());
-            return children.size();
-        }
-    }
-
     NotificationAttributes getAutobundledSummaryAttributes(@NonNull String packageName,
             @NonNull List<NotificationAttributes> childrenAttr) {
         Icon newIcon = null;
@@ -338,7 +405,20 @@
             newColor = COLOR_DEFAULT;
         }
 
-        return new NotificationAttributes(0, newIcon, newColor, newVisibility);
+        // Use GROUP_ALERT_CHILDREN
+        // Unless all children have GROUP_ALERT_SUMMARY => avoid muting all notifications in group
+        int newGroupAlertBehavior = Notification.GROUP_ALERT_SUMMARY;
+        for (NotificationAttributes attr: childrenAttr) {
+            if (attr.groupAlertBehavior != Notification.GROUP_ALERT_SUMMARY) {
+                newGroupAlertBehavior = Notification.GROUP_ALERT_CHILDREN;
+                break;
+            }
+        }
+
+        String channelId = !childrenAttr.isEmpty() ? childrenAttr.get(0).channelId : null;
+
+        return new NotificationAttributes(0, newIcon, newColor, newVisibility,
+                newGroupAlertBehavior, channelId);
     }
 
     NotificationAttributes updateAutobundledSummaryAttributes(@NonNull String packageName,
@@ -348,14 +428,28 @@
                 childrenAttr);
         Icon newIcon = newAttr.icon;
         int newColor = newAttr.iconColor;
+        String newChannelId = newAttr.channelId;
         if (newAttr.icon == null) {
             newIcon = oldAttr.icon;
         }
         if (newAttr.iconColor == Notification.COLOR_INVALID) {
             newColor = oldAttr.iconColor;
         }
+        if (newAttr.channelId == null) {
+            newChannelId = oldAttr.channelId;
+        }
 
-        return new NotificationAttributes(oldAttr.flags, newIcon, newColor, newAttr.visibility);
+        return new NotificationAttributes(oldAttr.flags, newIcon, newColor, newAttr.visibility,
+                oldAttr.groupAlertBehavior, newChannelId);
+    }
+
+    private NotificationAttributes getSummaryAttributes(String pkgName,
+            ArrayMap<String, NotificationAttributes> childrenMap) {
+        int flags = getAutogroupSummaryFlags(childrenMap);
+        NotificationAttributes attr = getAutobundledSummaryAttributes(pkgName,
+                childrenMap.values().stream().toList());
+        return new NotificationAttributes(flags, attr.icon, attr.iconColor, attr.visibility,
+                attr.groupAlertBehavior, attr.channelId);
     }
 
     /**
@@ -388,17 +482,865 @@
         }
     }
 
+    /**
+     * A non-app grouped notification has been added or updated
+     * Evaluate if:
+     * (a) an existing autogroup summary needs updated attributes
+     * (b) a new autogroup summary needs to be added with correct attributes
+     * (c) other non-app grouped children need to be moved to the autogroup
+     *
+     * This method implements autogrouping with sections support.
+     *
+     * And stores the list of upgrouped notifications & their flags
+     */
+    private boolean maybeGroupWithSections(NotificationRecord record,
+            boolean autogroupSummaryExists) {
+        final StatusBarNotification sbn = record.getSbn();
+        boolean sbnToBeAutogrouped = false;
+
+        final NotificationSectioner sectioner = getSection(record);
+        if (sectioner == null) {
+            if (DEBUG) {
+                Log.i(TAG, "Skipping autogrouping for " + record + " no valid section found.");
+            }
+            return false;
+        }
+
+        final String pkgName = sbn.getPackageName();
+        final FullyQualifiedGroupKey fullAggregateGroupKey = new FullyQualifiedGroupKey(
+                record.getUserId(), pkgName, sectioner);
+
+        // This notification is already aggregated
+        if (record.getGroupKey().equals(fullAggregateGroupKey.toString())) {
+            return false;
+        }
+
+        synchronized (mAggregatedNotifications) {
+            ArrayMap<String, NotificationAttributes> ungrouped =
+                mUngroupedAbuseNotifications.getOrDefault(fullAggregateGroupKey, new ArrayMap<>());
+            ungrouped.put(record.getKey(), new NotificationAttributes(
+                record.getFlags(),
+                record.getNotification().getSmallIcon(),
+                record.getNotification().color,
+                record.getNotification().visibility,
+                record.getNotification().getGroupAlertBehavior(),
+                record.getChannel().getId()));
+            mUngroupedAbuseNotifications.put(fullAggregateGroupKey, ungrouped);
+
+            // scenario 0: ungrouped notifications
+            if (ungrouped.size() >= mAutoGroupAtCount || autogroupSummaryExists) {
+                if (DEBUG) {
+                    if (ungrouped.size() >= mAutoGroupAtCount) {
+                        Log.i(TAG,
+                            "Found >=" + mAutoGroupAtCount
+                                + " ungrouped notifications => force grouping");
+                    } else {
+                        Log.i(TAG, "Found aggregate summary => force grouping");
+                    }
+                }
+
+                final ArrayMap<String, NotificationAttributes> aggregatedNotificationsAttrs =
+                    mAggregatedNotifications.getOrDefault(fullAggregateGroupKey, new ArrayMap<>());
+                aggregatedNotificationsAttrs.putAll(ungrouped);
+                mAggregatedNotifications.put(fullAggregateGroupKey, aggregatedNotificationsAttrs);
+
+                // add/update aggregate summary
+                updateAggregateAppGroup(fullAggregateGroupKey, record.getKey(),
+                        autogroupSummaryExists, sectioner.mSummaryId);
+
+                // add notification to aggregate group
+                for (String keyToGroup : ungrouped.keySet()) {
+                    if (android.app.Flags.checkAutogroupBeforePost()) {
+                        if (keyToGroup.equals(record.getKey())) {
+                            // Autogrouping for the posted notification is to be done synchronously.
+                            sbnToBeAutogrouped = true;
+                        } else {
+                            mCallback.addAutoGroup(keyToGroup, fullAggregateGroupKey.toString(),
+                                    true);
+                        }
+                    } else {
+                        mCallback.addAutoGroup(keyToGroup, fullAggregateGroupKey.toString(), true);
+                    }
+                }
+
+                //cleanup mUngroupedAbuseNotifications
+                mUngroupedAbuseNotifications.remove(fullAggregateGroupKey);
+            }
+        }
+
+        return sbnToBeAutogrouped;
+    }
+
+    /**
+     * A notification was added that's app grouped.
+     * Evaluate whether:
+     * (a) an existing autogroup summary needs updated attributes
+     * (b) if we need to remove our autogroup overlay for this notification
+     * (c) we need to remove the autogroup summary
+     *
+     * This method implements autogrouping with sections support.
+     *
+     * And updates the internal state of un-app-grouped notifications and their flags.
+     */
+    private void maybeUngroupWithSections(NotificationRecord record) {
+        final StatusBarNotification sbn = record.getSbn();
+        final String pkgName = sbn.getPackageName();
+        final int userId = record.getUserId();
+        final FullyQualifiedGroupKey fullAggregateGroupKey = new FullyQualifiedGroupKey(userId,
+                pkgName, getSection(record));
+
+        synchronized (mAggregatedNotifications) {
+            // if this notification still exists and has an autogroup overlay, but is now
+            // grouped by the app, clear the overlay
+            ArrayMap<String, NotificationAttributes> ungrouped =
+                mUngroupedAbuseNotifications.getOrDefault(fullAggregateGroupKey, new ArrayMap<>());
+            ungrouped.remove(sbn.getKey());
+            mUngroupedAbuseNotifications.put(fullAggregateGroupKey, ungrouped);
+
+            final ArrayMap<String, NotificationAttributes> aggregatedNotificationsAttrs =
+                mAggregatedNotifications.getOrDefault(fullAggregateGroupKey, new ArrayMap<>());
+            // check if the removed notification was part of the aggregate group
+            if (aggregatedNotificationsAttrs.containsKey(record.getKey())) {
+                aggregatedNotificationsAttrs.remove(sbn.getKey());
+                mAggregatedNotifications.put(fullAggregateGroupKey, aggregatedNotificationsAttrs);
+
+                if (DEBUG) {
+                    Log.i(TAG, "maybeUngroup removeAutoGroup: " + record);
+                }
+
+                mCallback.removeAutoGroup(sbn.getKey());
+
+                if (aggregatedNotificationsAttrs.isEmpty()) {
+                    if (DEBUG) {
+                        Log.i(TAG, "Aggregate group is empty: " + fullAggregateGroupKey);
+                    }
+                    mCallback.removeAutoGroupSummary(userId, pkgName,
+                            fullAggregateGroupKey.toString());
+                    mAggregatedNotifications.remove(fullAggregateGroupKey);
+                } else {
+                    if (DEBUG) {
+                        Log.i(TAG, "Aggregate group not empty, updating: " + fullAggregateGroupKey);
+                    }
+                    updateAggregateAppGroup(fullAggregateGroupKey, sbn.getKey(), true, 0);
+                }
+            }
+        }
+    }
+
+    /**
+     * Called when a notification is newly posted, after some delay, so that the app
+     * has a chance to post a group summary or children (complete a group).
+     * Checks whether that notification and other active notifications should be forced grouped
+     * because their grouping is incorrect:
+     *  - missing summary
+     *  - only summaries
+     *  - sparse groups == multiple groups with very few notifications
+     *
+     * @param record the notification that was posted
+     * @param notificationList the full notification list from NotificationManagerService
+     * @param summaryByGroupKey the map of group summaries from NotificationManagerService
+     */
+    @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_FORCE_GROUPING)
+    protected void onNotificationPostedWithDelay(final NotificationRecord record,
+            final List<NotificationRecord> notificationList,
+            final Map<String, NotificationRecord> summaryByGroupKey) {
+        // Ungrouped notifications are handled separately in
+        // {@link #onNotificationPosted(StatusBarNotification, boolean)}
+        final StatusBarNotification sbn = record.getSbn();
+        if (!sbn.isAppGroup()) {
+            return;
+        }
+
+        if (record.isCanceled) {
+            return;
+        }
+
+        final NotificationSectioner sectioner = getSection(record);
+        if (sectioner == null) {
+            if (DEBUG) {
+                Log.i(TAG, "Skipping autogrouping for " + record + " no valid section found.");
+            }
+            return;
+        }
+
+        final String pkgName = sbn.getPackageName();
+        final FullyQualifiedGroupKey fullAggregateGroupKey = new FullyQualifiedGroupKey(
+                record.getUserId(), pkgName, sectioner);
+
+        // This notification is already aggregated
+        if (record.getGroupKey().equals(fullAggregateGroupKey.toString())) {
+            return;
+        }
+
+        synchronized (mAggregatedNotifications) {
+            // scenario 1: group w/o summary
+            // scenario 2: summary w/o children
+            if (isGroupChildWithoutSummary(record, summaryByGroupKey) ||
+                isGroupSummaryWithoutChildren(record, notificationList)) {
+                if (DEBUG) {
+                    Log.i(TAG, "isGroupChildWithoutSummary OR isGroupSummaryWithoutChild"
+                            + record);
+                }
+
+                ArrayMap<String, NotificationAttributes> ungrouped =
+                        mUngroupedAbuseNotifications.getOrDefault(fullAggregateGroupKey,
+                            new ArrayMap<>());
+                ungrouped.put(record.getKey(), new NotificationAttributes(
+                    record.getFlags(),
+                    record.getNotification().getSmallIcon(),
+                    record.getNotification().color,
+                    record.getNotification().visibility,
+                    record.getNotification().getGroupAlertBehavior(),
+                    record.getChannel().getId()));
+                mUngroupedAbuseNotifications.put(fullAggregateGroupKey, ungrouped);
+                // Create/update summary and group if >= mAutoGroupAtCount notifications
+                //  or if aggregate group exists
+                boolean hasSummary = !mAggregatedNotifications.getOrDefault(fullAggregateGroupKey,
+                    new ArrayMap<>()).isEmpty();
+                if (ungrouped.size() >= mAutoGroupAtCount || hasSummary) {
+                    if (DEBUG) {
+                        if (ungrouped.size() >= mAutoGroupAtCount) {
+                            Log.i(TAG,
+                                "Found >=" + mAutoGroupAtCount
+                                    + " ungrouped notifications => force grouping");
+                        } else {
+                            Log.i(TAG, "Found aggregate summary => force grouping");
+                        }
+                    }
+                    aggregateUngroupedNotifications(fullAggregateGroupKey, sbn.getKey(),
+                            ungrouped, hasSummary, sectioner.mSummaryId);
+                }
+
+                return;
+            }
+
+            // scenario 3: sparse/singleton groups
+            if (Flags.notificationForceGroupSingletons()) {
+                groupSparseGroups(record, notificationList, summaryByGroupKey, sectioner,
+                    fullAggregateGroupKey);
+            }
+        }
+    }
+
+    /**
+     * Called when a notification is removed, so that this helper can adjust the aggregate groups:
+     *  - Removes the autogroup summary of the notification's section
+     *      if the record was the last child.
+     *  - Recalculates the autogroup summary "attributes":
+     *      icon, icon color, visibility, groupAlertBehavior, flags - if the removed record was
+     *  part of an autogroup.
+     *  - Removes the saved summary of the original group, if the record was the last remaining
+     *      child of a sparse group that was forced auto-grouped.
+     *
+     * see also {@link #onNotificationPostedWithDelay(NotificationRecord, List, Map)}
+     *
+     * @param record the removed notification
+     * @param notificationList the full notification list from NotificationManagerService
+     */
+    @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_FORCE_GROUPING)
+    protected void onNotificationRemoved(final NotificationRecord record,
+                final List<NotificationRecord> notificationList) {
+        final StatusBarNotification sbn = record.getSbn();
+        final String pkgName = sbn.getPackageName();
+        final int userId = record.getUserId();
+        final FullyQualifiedGroupKey fullAggregateGroupKey = new FullyQualifiedGroupKey(userId,
+                pkgName, getSection(record));
+
+        synchronized (mAggregatedNotifications) {
+            ArrayMap<String, NotificationAttributes> ungrouped =
+                mUngroupedAbuseNotifications.getOrDefault(fullAggregateGroupKey, new ArrayMap<>());
+            ungrouped.remove(record.getKey());
+            mUngroupedAbuseNotifications.put(fullAggregateGroupKey, ungrouped);
+
+            final ArrayMap<String, NotificationAttributes> aggregatedNotificationsAttrs =
+                mAggregatedNotifications.getOrDefault(fullAggregateGroupKey, new ArrayMap<>());
+            // check if the removed notification was part of the aggregate group
+            if (record.getGroupKey().equals(fullAggregateGroupKey.toString())
+                    || aggregatedNotificationsAttrs.containsKey(record.getKey())) {
+                aggregatedNotificationsAttrs.remove(record.getKey());
+                mAggregatedNotifications.put(fullAggregateGroupKey, aggregatedNotificationsAttrs);
+
+                if (aggregatedNotificationsAttrs.isEmpty()) {
+                    if (DEBUG) {
+                        Log.i(TAG, "Aggregate group is empty: " + fullAggregateGroupKey);
+                    }
+                    mCallback.removeAutoGroupSummary(userId, pkgName,
+                            fullAggregateGroupKey.toString());
+                    mAggregatedNotifications.remove(fullAggregateGroupKey);
+                } else {
+                    if (DEBUG) {
+                        Log.i(TAG, "Aggregate group not empty, updating: " + fullAggregateGroupKey);
+                    }
+                    updateAggregateAppGroup(fullAggregateGroupKey, sbn.getKey(), true, 0);
+                }
+
+                // Try to cleanup cached summaries if notification was canceled (not snoozed)
+                if (record.isCanceled) {
+                    maybeClearCanceledSummariesCache(pkgName, userId,
+                            record.getNotification().getGroup(), notificationList);
+                }
+            }
+        }
+    }
+
+    private record NotificationMoveOp(NotificationRecord record, FullyQualifiedGroupKey oldGroup,
+                                      FullyQualifiedGroupKey newGroup) { }
+
+    /**
+     * Called when a notification channel is updated, so that this helper can adjust
+     * the aggregate groups by moving children if their section has changed.
+     * see {@link #onNotificationPostedWithDelay(NotificationRecord, List, Map)}
+     * @param userId the userId of the channel
+     * @param pkgName the channel's package
+     * @param channel the channel that was updated
+     * @param notificationList the full notification list from NotificationManagerService
+     */
+    @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void onChannelUpdated(final int userId, final String pkgName,
+            final NotificationChannel channel, final List<NotificationRecord> notificationList) {
+        synchronized (mAggregatedNotifications) {
+            ArrayMap<String, NotificationRecord> notificationsToCheck = new ArrayMap<>();
+            for (NotificationRecord r : notificationList) {
+                if (r.getChannel().getId().equals(channel.getId())
+                    && r.getSbn().getPackageName().equals(pkgName)
+                    && r.getUserId() == userId) {
+                    notificationsToCheck.put(r.getKey(), r);
+                }
+            }
+
+            final ArrayList<NotificationMoveOp> notificationsToMove = new ArrayList<>();
+
+            final Set<FullyQualifiedGroupKey> oldGroups =
+                    new HashSet<>(mAggregatedNotifications.keySet());
+            for (FullyQualifiedGroupKey oldFullAggKey : oldGroups) {
+                // Only check aggregate groups that match the same userId & packageName
+                if (pkgName.equals(oldFullAggKey.pkg) && userId == oldFullAggKey.userId) {
+                    final ArrayMap<String, NotificationAttributes> notificationsInAggGroup =
+                            mAggregatedNotifications.get(oldFullAggKey);
+                    if (notificationsInAggGroup == null) {
+                        continue;
+                    }
+
+                    FullyQualifiedGroupKey newFullAggregateGroupKey = null;
+                    for (String key : notificationsInAggGroup.keySet()) {
+                        if (notificationsToCheck.get(key) != null) {
+                            // check if section changes
+                            NotificationSectioner sectioner = getSection(
+                                    notificationsToCheck.get(key));
+                            if (sectioner == null) {
+                                continue;
+                            }
+                            newFullAggregateGroupKey = new FullyQualifiedGroupKey(userId, pkgName,
+                                    sectioner);
+                            if (!oldFullAggKey.equals(newFullAggregateGroupKey)) {
+                                if (DEBUG) {
+                                    Log.i(TAG, "Change section on channel update: " + key);
+                                }
+                                notificationsToMove.add(
+                                        new NotificationMoveOp(notificationsToCheck.get(key),
+                                            oldFullAggKey, newFullAggregateGroupKey));
+                            }
+                        }
+                    }
+
+                    if (newFullAggregateGroupKey != null) {
+                        // Add any notifications left ungrouped to the new section
+                        ArrayMap<String, NotificationAttributes> ungrouped =
+                            mUngroupedAbuseNotifications.get(newFullAggregateGroupKey);
+                        if (ungrouped != null) {
+                            for (NotificationRecord r : notificationList) {
+                                if (ungrouped.containsKey(r.getKey())) {
+                                    if (DEBUG) {
+                                        Log.i(TAG, "Add previously ungrouped: " + r);
+                                    }
+                                    notificationsToMove.add(
+                                        new NotificationMoveOp(r, null, newFullAggregateGroupKey));
+                                }
+                            }
+                            //Cleanup mUngroupedAbuseNotifications
+                            mUngroupedAbuseNotifications.remove(newFullAggregateGroupKey);
+                        }
+                    }
+                }
+            }
+
+            // Batch move to new section
+            if (!notificationsToMove.isEmpty()) {
+                moveNotificationsToNewSection(userId, pkgName, notificationsToMove);
+            }
+        }
+    }
+
+    @GuardedBy("mAggregatedNotifications")
+    private void moveNotificationsToNewSection(final int userId, final String pkgName,
+            final List<NotificationMoveOp> notificationsToMove) {
+        record GroupUpdateOp(FullyQualifiedGroupKey groupKey, NotificationRecord record,
+                             boolean hasSummary) { }
+        ArrayMap<FullyQualifiedGroupKey, GroupUpdateOp> groupsToUpdate = new ArrayMap<>();
+
+        for (NotificationMoveOp moveOp: notificationsToMove) {
+            final NotificationRecord record = moveOp.record;
+            final FullyQualifiedGroupKey oldFullAggregateGroupKey = moveOp.oldGroup;
+            final FullyQualifiedGroupKey newFullAggregateGroupKey = moveOp.newGroup;
+
+            if (DEBUG) {
+                Log.i(TAG,
+                    "moveNotificationToNewSection: " + record + " " + newFullAggregateGroupKey
+                        + " from: " + oldFullAggregateGroupKey);
+            }
+
+            // Update/remove aggregate summary for old group
+            if (oldFullAggregateGroupKey != null) {
+                final ArrayMap<String, NotificationAttributes> oldAggregatedNotificationsAttrs =
+                        mAggregatedNotifications.getOrDefault(oldFullAggregateGroupKey,
+                            new ArrayMap<>());
+                oldAggregatedNotificationsAttrs.remove(record.getKey());
+                mAggregatedNotifications.put(oldFullAggregateGroupKey,
+                        oldAggregatedNotificationsAttrs);
+
+                // Only add once, for triggering notification
+                if (!groupsToUpdate.containsKey(oldFullAggregateGroupKey)) {
+                    groupsToUpdate.put(oldFullAggregateGroupKey,
+                            new GroupUpdateOp(oldFullAggregateGroupKey, record, true));
+                }
+            }
+
+            // Add/update aggregate summary for new group
+            if (newFullAggregateGroupKey != null) {
+                final ArrayMap<String, NotificationAttributes> newAggregatedNotificationsAttrs =
+                        mAggregatedNotifications.getOrDefault(newFullAggregateGroupKey,
+                            new ArrayMap<>());
+                boolean newGroupExists = !newAggregatedNotificationsAttrs.isEmpty();
+                newAggregatedNotificationsAttrs.put(record.getKey(),
+                        new NotificationAttributes(record.getFlags(),
+                            record.getNotification().getSmallIcon(),
+                            record.getNotification().color,
+                            record.getNotification().visibility,
+                            record.getNotification().getGroupAlertBehavior(),
+                            record.getChannel().getId()));
+                mAggregatedNotifications.put(newFullAggregateGroupKey,
+                        newAggregatedNotificationsAttrs);
+
+                // Only add once, for triggering notification
+                if (!groupsToUpdate.containsKey(newFullAggregateGroupKey)) {
+                    groupsToUpdate.put(newFullAggregateGroupKey,
+                            new GroupUpdateOp(newFullAggregateGroupKey, record, newGroupExists));
+                }
+
+                // Add notification to new group. do not request resort
+                record.setOverrideGroupKey(null);
+                mCallback.addAutoGroup(record.getKey(), newFullAggregateGroupKey.toString(), false);
+            }
+        }
+
+        // Update groups (sections)
+        for (FullyQualifiedGroupKey groupKey : groupsToUpdate.keySet()) {
+            final ArrayMap<String, NotificationAttributes> aggregatedNotificationsAttrs =
+                    mAggregatedNotifications.getOrDefault(groupKey, new ArrayMap<>());
+            if (aggregatedNotificationsAttrs.isEmpty()) {
+                mCallback.removeAutoGroupSummary(userId, pkgName, groupKey.toString());
+                mAggregatedNotifications.remove(groupKey);
+            } else {
+                NotificationRecord triggeringNotification = groupsToUpdate.get(groupKey).record;
+                boolean hasSummary = groupsToUpdate.get(groupKey).hasSummary;
+                NotificationSectioner sectioner = getSection(triggeringNotification);
+                if (sectioner == null) {
+                    continue;
+                }
+                updateAggregateAppGroup(groupKey, triggeringNotification.getKey(), hasSummary,
+                        sectioner.mSummaryId);
+            }
+        }
+    }
+
+    static String getFullAggregateGroupKey(String pkgName,
+            String groupName, int userId) {
+        return new FullyQualifiedGroupKey(userId, pkgName, groupName).toString();
+    }
+
+    /**
+     * Returns the full aggregate group key, which contains the userId and package name
+     * in addition to the aggregate group key (name).
+     * Equivalent to {@link StatusBarNotification#groupKey()}
+     */
+    static String getFullAggregateGroupKey(NotificationRecord record) {
+        return new FullyQualifiedGroupKey(record.getUserId(), record.getSbn().getPackageName(),
+                getSection(record)).toString();
+    }
+
+    protected static boolean isAggregatedGroup(NotificationRecord record) {
+        return (record.mOriginalFlags & Notification.FLAG_AUTOGROUP_SUMMARY) != 0;
+    }
+
+    private static int getNumChildrenForGroup(@NonNull final String groupKey,
+            final List<NotificationRecord> notificationList) {
+        //TODO (b/349072751): track grouping state in GroupHelper -> do not use notificationList
+        int numChildren = 0;
+        // find children for this summary
+        for (NotificationRecord r : notificationList) {
+            if (!r.getNotification().isGroupSummary()
+                    && groupKey.equals(r.getSbn().getGroup())) {
+                numChildren++;
+            }
+        }
+
+        if (DEBUG) {
+            Log.i(TAG, "getNumChildrenForGroup " + groupKey + " numChild: " + numChildren);
+        }
+        return numChildren;
+    }
+
+    private static boolean isGroupSummaryWithoutChildren(final NotificationRecord record,
+            final List<NotificationRecord> notificationList) {
+        final StatusBarNotification sbn = record.getSbn();
+        final String groupKey = record.getSbn().getGroup();
+
+        // ignore non app groups and non summaries
+        if (!sbn.isAppGroup() || !record.getNotification().isGroupSummary()) {
+            return false;
+        }
+
+        return getNumChildrenForGroup(groupKey, notificationList) == 0;
+    }
+
+    private static boolean isGroupChildWithoutSummary(final NotificationRecord record,
+            final Map<String, NotificationRecord> summaryByGroupKey) {
+        final StatusBarNotification sbn = record.getSbn();
+        final String groupKey = record.getSbn().getGroupKey();
+
+        if (!sbn.isAppGroup()) {
+            return false;
+        }
+
+        if (record.getNotification().isGroupSummary()) {
+            return false;
+        }
+
+        if (summaryByGroupKey.containsKey(groupKey)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @GuardedBy("mAggregatedNotifications")
+    private void aggregateUngroupedNotifications(FullyQualifiedGroupKey fullAggregateGroupKey,
+            String triggeringNotifKey, Map<String, NotificationAttributes> ungrouped,
+            final boolean hasSummary, int summaryId) {
+        final ArrayMap<String, NotificationAttributes> aggregatedNotificationsAttrs =
+                mAggregatedNotifications.getOrDefault(fullAggregateGroupKey, new ArrayMap<>());
+        aggregatedNotificationsAttrs.putAll(ungrouped);
+        mAggregatedNotifications.put(fullAggregateGroupKey, aggregatedNotificationsAttrs);
+
+        // add/update aggregate summary
+        updateAggregateAppGroup(fullAggregateGroupKey, triggeringNotifKey, hasSummary, summaryId);
+
+        // add notification to aggregate group
+        for (String key: ungrouped.keySet()) {
+            mCallback.addAutoGroup(key, fullAggregateGroupKey.toString(), true);
+        }
+
+        //cleanup mUngroupedAbuseNotifications
+        mUngroupedAbuseNotifications.remove(fullAggregateGroupKey);
+    }
+
+    @GuardedBy("mAggregatedNotifications")
+    private void updateAggregateAppGroup(FullyQualifiedGroupKey fullAggregateGroupKey,
+            String triggeringNotifKey, boolean hasSummary, int summaryId) {
+        final ArrayMap<String, NotificationAttributes> aggregatedNotificationsAttrs =
+                mAggregatedNotifications.getOrDefault(fullAggregateGroupKey, new ArrayMap<>());
+        NotificationAttributes attr = getSummaryAttributes(fullAggregateGroupKey.pkg,
+                aggregatedNotificationsAttrs);
+        String channelId = hasSummary ? attr.channelId
+                : aggregatedNotificationsAttrs.get(triggeringNotifKey).channelId;
+        NotificationAttributes summaryAttr = new NotificationAttributes(attr.flags, attr.icon,
+                attr.iconColor, attr.visibility, attr.groupAlertBehavior, channelId);
+
+        if (!hasSummary) {
+            if (DEBUG) {
+                Log.i(TAG, "Create aggregate summary: " + fullAggregateGroupKey);
+            }
+            mCallback.addAutoGroupSummary(fullAggregateGroupKey.userId, fullAggregateGroupKey.pkg,
+                    triggeringNotifKey, fullAggregateGroupKey.toString(), summaryId, summaryAttr);
+        } else {
+            if (DEBUG) {
+                Log.i(TAG, "Update aggregate summary: " + fullAggregateGroupKey);
+            }
+            mCallback.updateAutogroupSummary(fullAggregateGroupKey.userId,
+                    fullAggregateGroupKey.pkg, fullAggregateGroupKey.toString(), summaryAttr);
+        }
+    }
+
+    @GuardedBy("mAggregatedNotifications")
+    private void groupSparseGroups(final NotificationRecord record,
+            final List<NotificationRecord> notificationList,
+            final Map<String, NotificationRecord> summaryByGroupKey,
+            final NotificationSectioner sectioner,
+            final FullyQualifiedGroupKey fullAggregateGroupKey) {
+        final ArrayMap<String, NotificationRecord> sparseGroupSummaries = getSparseGroups(
+                fullAggregateGroupKey, notificationList, summaryByGroupKey, sectioner);
+        if (sparseGroupSummaries.size() >= mAutogroupSparseGroupsAtCount) {
+            if (DEBUG) {
+                Log.i(TAG,
+                    "Aggregate sparse groups for: " + record.getSbn().getPackageName()
+                        + " Section: " + sectioner.mName);
+            }
+
+            ArrayMap<String, NotificationAttributes> ungrouped =
+                    mUngroupedAbuseNotifications.getOrDefault(
+                        fullAggregateGroupKey, new ArrayMap<>());
+            final ArrayMap<String, NotificationAttributes> aggregatedNotificationsAttrs =
+                    mAggregatedNotifications.getOrDefault(fullAggregateGroupKey, new ArrayMap<>());
+            final boolean hasSummary = !aggregatedNotificationsAttrs.isEmpty();
+            for (NotificationRecord r : notificationList) {
+                // Add notifications for detected sparse groups
+                if (sparseGroupSummaries.containsKey(r.getGroupKey())) {
+                    // Move child notifications to aggregate group
+                    if (!r.getNotification().isGroupSummary()) {
+                        if (DEBUG) {
+                            Log.i(TAG, "Aggregate notification (sparse group): " + r);
+                        }
+                        mCallback.addAutoGroup(r.getKey(), fullAggregateGroupKey.toString(), true);
+                        aggregatedNotificationsAttrs.put(r.getKey(),
+                            new NotificationAttributes(r.getFlags(),
+                                r.getNotification().getSmallIcon(), r.getNotification().color,
+                                r.getNotification().visibility,
+                                r.getNotification().getGroupAlertBehavior(),
+                                r.getChannel().getId()));
+
+                    } else if (r.getNotification().isGroupSummary()) {
+                        // Remove summary notifications
+                        if (DEBUG) {
+                            Log.i(TAG, "Remove app summary (sparse group): " + r);
+                        }
+                        mCallback.removeAppProvidedSummary(r.getKey());
+                        cacheCanceledSummary(r);
+                    }
+                } else {
+                    // Add any notifications left ungrouped
+                    if (ungrouped.containsKey(r.getKey())) {
+                        if (DEBUG) {
+                            Log.i(TAG, "Aggregate ungrouped (sparse group): " + r);
+                        }
+                        mCallback.addAutoGroup(r.getKey(), fullAggregateGroupKey.toString(), true);
+                        aggregatedNotificationsAttrs.put(r.getKey(),ungrouped.get(r.getKey()));
+                    }
+                }
+            }
+
+            mAggregatedNotifications.put(fullAggregateGroupKey, aggregatedNotificationsAttrs);
+            // add/update aggregate summary
+            updateAggregateAppGroup(fullAggregateGroupKey, record.getKey(), hasSummary,
+                    sectioner.mSummaryId);
+
+            //cleanup mUngroupedAbuseNotifications
+            mUngroupedAbuseNotifications.remove(fullAggregateGroupKey);
+        }
+    }
+
+    private ArrayMap<String, NotificationRecord> getSparseGroups(
+            final FullyQualifiedGroupKey fullAggregateGroupKey,
+            final List<NotificationRecord> notificationList,
+            final Map<String, NotificationRecord> summaryByGroupKey,
+            final NotificationSectioner sectioner) {
+        ArrayMap<String, NotificationRecord> sparseGroups = new ArrayMap<>();
+        for (NotificationRecord summary : summaryByGroupKey.values()) {
+            if (summary != null && sectioner.isInSection(summary)) {
+                if (summary.getSbn().getPackageName().equalsIgnoreCase(fullAggregateGroupKey.pkg)
+                        && summary.getUserId() == fullAggregateGroupKey.userId
+                        && summary.getSbn().isAppGroup()
+                        && !summary.getGroupKey().equals(fullAggregateGroupKey.toString())) {
+                    int numChildren = getNumChildrenForGroup(summary.getSbn().getGroup(),
+                            notificationList);
+                    if (numChildren > 0 && numChildren < MIN_CHILD_COUNT_TO_AVOID_FORCE_GROUPING) {
+                        sparseGroups.put(summary.getGroupKey(), summary);
+                    }
+                }
+            }
+        }
+        return sparseGroups;
+    }
+
+    @GuardedBy("mAggregatedNotifications")
+    private void cacheCanceledSummary(NotificationRecord record) {
+        final FullyQualifiedGroupKey groupKey = new FullyQualifiedGroupKey(record.getUserId(),
+                record.getSbn().getPackageName(), record.getNotification().getGroup());
+        mCanceledSummaries.put(groupKey, new CachedSummary(record.getSbn().getId(),
+                record.getSbn().getTag(), record.getNotification().getGroup(), record.getKey()));
+    }
+
+    @GuardedBy("mAggregatedNotifications")
+    private void maybeClearCanceledSummariesCache(String pkgName, int userId,
+            String groupName, List<NotificationRecord> notificationList) {
+        final FullyQualifiedGroupKey findKey = new FullyQualifiedGroupKey(userId, pkgName,
+                groupName);
+        CachedSummary summary = mCanceledSummaries.get(findKey);
+        // Check if any notifications from original group remain
+        if (summary != null) {
+            if (DEBUG) {
+                Log.i(TAG, "Try removing cached summary: " + summary);
+            }
+            boolean stillHasChildren = false;
+            //TODO (b/349072751): track grouping state in GroupHelper -> do not use notificationList
+            for (NotificationRecord r : notificationList) {
+                if (summary.originalGroupKey.equals(r.getNotification().getGroup())
+                    && r.getUser().getIdentifier() == userId
+                    && r.getSbn().getPackageName().equals(pkgName)) {
+                    stillHasChildren = true;
+                    break;
+                }
+            }
+            if (!stillHasChildren) {
+                removeCachedSummary(pkgName, userId, summary);
+            }
+        }
+    }
+
+    @VisibleForTesting
+    @GuardedBy("mAggregatedNotifications")
+    protected CachedSummary findCanceledSummary(String pkgName, String tag, int id, int userId) {
+        for (FullyQualifiedGroupKey key: mCanceledSummaries.keySet()) {
+            if (pkgName.equals(key.pkg) && userId == key.userId) {
+                CachedSummary summary = mCanceledSummaries.get(key);
+                if (summary != null && summary.id == id && TextUtils.equals(tag, summary.tag)) {
+                    return summary;
+                }
+            }
+        }
+        return null;
+    }
+
+    @VisibleForTesting
+    @GuardedBy("mAggregatedNotifications")
+    protected CachedSummary findCanceledSummary(String pkgName, String tag, int id, int userId,
+            String groupName) {
+        final FullyQualifiedGroupKey findKey = new FullyQualifiedGroupKey(userId, pkgName,
+                groupName);
+        CachedSummary summary = mCanceledSummaries.get(findKey);
+        if (summary != null && summary.id == id && TextUtils.equals(tag, summary.tag)) {
+            return summary;
+        } else {
+            return null;
+        }
+    }
+
+    @GuardedBy("mAggregatedNotifications")
+    private void removeCachedSummary(String pkgName, int userId, CachedSummary summary) {
+        final FullyQualifiedGroupKey key = new FullyQualifiedGroupKey(userId, pkgName,
+                summary.originalGroupKey);
+        mCanceledSummaries.remove(key);
+    }
+
+    protected boolean isUpdateForCanceledSummary(final NotificationRecord record) {
+        synchronized (mAggregatedNotifications) {
+            if (record.getSbn().isAppGroup() && record.getNotification().isGroupSummary()) {
+                CachedSummary cachedSummary = findCanceledSummary(record.getSbn().getPackageName(),
+                        record.getSbn().getTag(), record.getSbn().getId(), record.getUserId(),
+                        record.getNotification().getGroup());
+                return cachedSummary != null;
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Cancels the original group's children when an app cancels a summary that was 'maybe'
+     * previously removed due to forced grouping of a "sparse group".
+     *
+     * @param pkgName packageName
+     * @param tag original summary notification tag
+     * @param id original summary notification id
+     * @param userId original summary userId
+     */
+    @FlaggedApi(Flags.FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS)
+    public void maybeCancelGroupChildrenForCanceledSummary(String pkgName, String tag, int id,
+            int userId, int cancelReason) {
+        synchronized (mAggregatedNotifications) {
+            final CachedSummary summary = findCanceledSummary(pkgName, tag, id, userId);
+            if (summary != null) {
+                if (DEBUG) {
+                    Log.i(TAG, "Found cached summary: " + summary.key);
+                }
+                mCallback.removeNotificationFromCanceledGroup(userId, pkgName,
+                        summary.originalGroupKey, cancelReason);
+                removeCachedSummary(pkgName, userId, summary);
+            }
+        }
+    }
+
+    static NotificationSectioner getSection(final NotificationRecord record) {
+        for (NotificationSectioner sectioner: NOTIFICATION_SHADE_SECTIONS) {
+            if (sectioner.isInSection(record)) {
+                return sectioner;
+            }
+        }
+        return null;
+    }
+
+    record FullyQualifiedGroupKey(int userId, String pkg, String groupName) {
+        FullyQualifiedGroupKey(int userId, String pkg, @Nullable NotificationSectioner sectioner) {
+            this(userId, pkg, AGGREGATE_GROUP_KEY + (sectioner != null ? sectioner.mName : ""));
+        }
+
+        @Override
+        public String toString() {
+            return userId + "|" + pkg + "|" + "g:" + groupName;
+        }
+    }
+
+    protected static class NotificationSectioner {
+        final String mName;
+        final int mSummaryId;
+        private final Predicate<NotificationRecord> mSectionChecker;
+
+        public NotificationSectioner(String name, int summaryId,
+                Predicate<NotificationRecord> sectionChecker) {
+            mName = name;
+            mSummaryId = summaryId;
+            mSectionChecker = sectionChecker;
+        }
+
+        boolean isInSection(final NotificationRecord record) {
+            return isNotificationGroupable(record) && mSectionChecker.test(record);
+        }
+
+        private boolean isNotificationGroupable(final NotificationRecord record) {
+            if (record.isConversation()) {
+                return false;
+            }
+
+            Notification notification = record.getSbn().getNotification();
+            boolean isColorizedFGS = notification.isForegroundService()
+                && notification.isColorized()
+                && record.getImportance() > NotificationManager.IMPORTANCE_MIN;
+            boolean isCall = record.getImportance() > NotificationManager.IMPORTANCE_MIN
+                && notification.isStyle(Notification.CallStyle.class);
+            if (isColorizedFGS || isCall) {
+                return false;
+            }
+
+            return true;
+        }
+    }
+
+    record CachedSummary(int id, String tag, String originalGroupKey, String key) {}
+
     protected static class NotificationAttributes {
         public final int flags;
         public final int iconColor;
         public final Icon icon;
         public final int visibility;
+        public final int groupAlertBehavior;
+        public final String channelId;
 
-        public NotificationAttributes(int flags, Icon icon, int iconColor, int visibility) {
+        public NotificationAttributes(int flags, Icon icon, int iconColor, int visibility,
+                int groupAlertBehavior, String channelId) {
             this.flags = flags;
             this.icon = icon;
             this.iconColor = iconColor;
             this.visibility = visibility;
+            this.groupAlertBehavior = groupAlertBehavior;
+            this.channelId = channelId;
         }
 
         public NotificationAttributes(@NonNull NotificationAttributes attr) {
@@ -406,6 +1348,8 @@
             this.icon = attr.icon;
             this.iconColor = attr.iconColor;
             this.visibility = attr.visibility;
+            this.groupAlertBehavior = attr.groupAlertBehavior;
+            this.channelId = attr.channelId;
         }
 
         @Override
@@ -417,22 +1361,39 @@
                 return false;
             }
             return flags == that.flags && iconColor == that.iconColor && icon.sameAs(that.icon)
-                    && visibility == that.visibility;
+                    && visibility == that.visibility
+                    && groupAlertBehavior == that.groupAlertBehavior
+                    && channelId.equals(that.channelId);
         }
 
         @Override
         public int hashCode() {
-            return Objects.hash(flags, iconColor, icon, visibility);
+            return Objects.hash(flags, iconColor, icon, visibility, groupAlertBehavior, channelId);
+        }
+
+        @Override
+        public String toString() {
+            return "NotificationAttributes: flags: " + flags + " icon: " + icon + " color: "
+                    + iconColor + " vis: " + visibility + " groupAlertBehavior: "
+                    + groupAlertBehavior + " channelId: " + channelId;
         }
     }
 
     protected interface Callback {
-        void addAutoGroup(String key, boolean requestSort);
+        void addAutoGroup(String key, String groupName, boolean requestSort);
         void removeAutoGroup(String key);
 
-        void addAutoGroupSummary(int userId, String pkg, String triggeringKey,
+        void addAutoGroupSummary(int userId, String pkg, String triggeringKey, String groupName,
+                int summaryId, NotificationAttributes summaryAttr);
+        void removeAutoGroupSummary(int user, String pkg, String groupKey);
+
+        void updateAutogroupSummary(int userId, String pkg, String groupKey,
                 NotificationAttributes summaryAttr);
-        void removeAutoGroupSummary(int user, String pkg);
-        void updateAutogroupSummary(int userId, String pkg, NotificationAttributes summaryAttr);
+
+        // New callbacks for API abuse grouping
+        void removeAppProvidedSummary(String key);
+
+        void removeNotificationFromCanceledGroup(int userId, String pkg, String groupKey,
+                int cancelReason);
     }
 }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index a4f534e..9e49827 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -39,6 +39,7 @@
 import static android.app.Notification.FLAG_BUBBLE;
 import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
 import static android.app.Notification.FLAG_FSI_REQUESTED_BUT_DENIED;
+import static android.app.Notification.FLAG_GROUP_SUMMARY;
 import static android.app.Notification.FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY;
 import static android.app.Notification.FLAG_NO_CLEAR;
 import static android.app.Notification.FLAG_NO_DISMISS;
@@ -108,6 +109,7 @@
 import static android.service.notification.Adjustment.TYPE_PROMOTION;
 import static android.service.notification.Adjustment.TYPE_SOCIAL_MEDIA;
 import static android.service.notification.Flags.callstyleCallbackApi;
+import static android.service.notification.Flags.notificationForceGrouping;
 import static android.service.notification.Flags.redactSensitiveNotificationsFromUntrustedListeners;
 import static android.service.notification.Flags.redactSensitiveNotificationsBigTextStyle;
 import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ALERTING;
@@ -371,6 +373,7 @@
 import com.android.server.wm.BackgroundActivityStartCallback;
 import com.android.server.wm.WindowManagerInternal;
 
+import java.util.function.BiPredicate;
 import libcore.io.IoUtils;
 
 import org.json.JSONException;
@@ -512,6 +515,8 @@
 
     private static final long DELAY_FOR_ASSISTANT_TIME = 200;
 
+    private static final long DELAY_FORCE_REGROUP_TIME = 3000;
+
     private static final String ACTION_NOTIFICATION_TIMEOUT =
             NotificationManagerService.class.getSimpleName() + ".TIMEOUT";
     private static final int REQUEST_CODE_TIMEOUT = 1;
@@ -608,6 +613,9 @@
 
     static final long NOTIFICATION_MAX_AGE_AT_POST = Duration.ofDays(14).toMillis();
 
+    // Minium number of sparse groups for a package before autogrouping them
+    private static final int AUTOGROUP_SPARSE_GROUPS_AT_COUNT = 3;
+
     private IActivityManager mAm;
     private ActivityTaskManagerInternal mAtm;
     private ActivityManager mActivityManager;
@@ -1001,17 +1009,25 @@
      * icons are different.
      * @param userId user id of the autogroup summary
      * @param pkg package of the autogroup summary
+     * @param groupKey group key of the autogroup summary
      * @param summaryAttr the new flags and/or icon & color for this summary
      * @param isAppForeground true if the app is currently in the foreground.
      */
     @GuardedBy("mNotificationLock")
-    protected void updateAutobundledSummaryLocked(int userId, String pkg,
-            NotificationAttributes summaryAttr, boolean isAppForeground) {
+    protected void updateAutobundledSummaryLocked(int userId, String pkg, String groupKey,
+                NotificationAttributes summaryAttr, boolean isAppForeground) {
         ArrayMap<String, String> summaries = mAutobundledSummaries.get(userId);
         if (summaries == null) {
             return;
         }
-        String summaryKey = summaries.get(pkg);
+        final String autbundledGroupKey;
+        if (notificationForceGrouping()) {
+            autbundledGroupKey = groupKey;
+        } else {
+            autbundledGroupKey = pkg;
+        }
+
+        String summaryKey = summaries.get(autbundledGroupKey);
         if (summaryKey == null) {
             return;
         }
@@ -1019,12 +1035,26 @@
         if (summary == null) {
             return;
         }
+
         int oldFlags = summary.getSbn().getNotification().flags;
 
         boolean attributesUpdated =
                 !summaryAttr.icon.sameAs(summary.getSbn().getNotification().getSmallIcon())
                 || summaryAttr.iconColor != summary.getSbn().getNotification().color
-                || summaryAttr.visibility != summary.getSbn().getNotification().visibility;
+                || summaryAttr.visibility != summary.getSbn().getNotification().visibility
+                || summaryAttr.groupAlertBehavior !=
+                        summary.getSbn().getNotification().getGroupAlertBehavior();
+
+        if (notificationForceGrouping()) {
+            if (!summary.getChannel().getId().equals(summaryAttr.channelId)) {
+                NotificationChannel newChannel = mPreferencesHelper.getNotificationChannel(pkg,
+                        summary.getUid(), summaryAttr.channelId, false);
+                if (newChannel != null) {
+                    summary.updateNotificationChannel(newChannel);
+                    attributesUpdated = true;
+                }
+            }
+        }
 
         if (oldFlags != summaryAttr.flags || attributesUpdated) {
             summary.getSbn().getNotification().flags =
@@ -1032,6 +1062,8 @@
             summary.getSbn().getNotification().setSmallIcon(summaryAttr.icon);
             summary.getSbn().getNotification().color = summaryAttr.iconColor;
             summary.getSbn().getNotification().visibility = summaryAttr.visibility;
+            summary.getSbn().getNotification()
+                    .setGroupAlertBehavior(summaryAttr.groupAlertBehavior);
             mHandler.post(new EnqueueNotificationRunnable(userId, summary, isAppForeground,
                     /* isAppProvided= */ false, mPostNotificationTrackerFactory.newTracker(null)));
         }
@@ -2836,12 +2868,17 @@
         mAutoGroupAtCount =
                 getContext().getResources().getInteger(R.integer.config_autoGroupAtCount);
         return new GroupHelper(getContext(), getContext().getPackageManager(),
-                mAutoGroupAtCount, new GroupHelper.Callback() {
+                mAutoGroupAtCount, AUTOGROUP_SPARSE_GROUPS_AT_COUNT, new GroupHelper.Callback() {
             @Override
-            public void addAutoGroup(String key, boolean requestSort) {
-                        synchronized (mNotificationLock) {
-                            addAutogroupKeyLocked(key, requestSort);
-                        }
+            public void addAutoGroup(String key, String groupName, boolean requestSort) {
+                synchronized (mNotificationLock) {
+                    if (notificationForceGrouping()) {
+                        convertSummaryToNotificationLocked(key);
+                        addAutogroupKeyLocked(key, groupName, requestSort);
+                    } else {
+                        addAutogroupKeyLocked(key, groupName, requestSort);
+                    }
+                }
             }
 
             @Override
@@ -2853,10 +2890,9 @@
 
             @Override
             public void addAutoGroupSummary(int userId, String pkg, String triggeringKey,
-                    NotificationAttributes summaryAttr) {
+                    String groupName, int summaryId, NotificationAttributes summaryAttr) {
                 NotificationRecord r = createAutoGroupSummary(userId, pkg, triggeringKey,
-                        summaryAttr.flags, summaryAttr.icon, summaryAttr.iconColor,
-                        summaryAttr.visibility);
+                        groupName, summaryId, summaryAttr);
                 if (r != null) {
                     final boolean isAppForeground =
                             mActivityManager.getPackageImportance(pkg) == IMPORTANCE_FOREGROUND;
@@ -2867,19 +2903,56 @@
             }
 
             @Override
-            public void removeAutoGroupSummary(int userId, String pkg) {
+            public void removeAutoGroupSummary(int userId, String pkg, String groupKey) {
                 synchronized (mNotificationLock) {
-                    clearAutogroupSummaryLocked(userId, pkg);
+                    clearAutogroupSummaryLocked(userId, pkg, groupKey);
                 }
             }
 
             @Override
-            public void updateAutogroupSummary(int userId, String pkg,
+            public void updateAutogroupSummary(int userId, String pkg, String groupKey,
                     NotificationAttributes summaryAttr) {
                 boolean isAppForeground = pkg != null
                         && mActivityManager.getPackageImportance(pkg) == IMPORTANCE_FOREGROUND;
                 synchronized (mNotificationLock) {
-                    updateAutobundledSummaryLocked(userId, pkg, summaryAttr, isAppForeground);
+                    updateAutobundledSummaryLocked(userId, pkg, groupKey, summaryAttr,
+                            isAppForeground);
+                }
+            }
+
+            @Override
+            public void removeAppProvidedSummary(String key) {
+                synchronized (mNotificationLock) {
+                    removeAppSummaryLocked(key);
+                }
+            }
+
+            @Override
+            public void removeNotificationFromCanceledGroup(int userId, String pkg,
+                    String groupKey, int cancelReason) {
+                synchronized (mNotificationLock) {
+                    final int mustNotHaveFlags;
+                    if (lifetimeExtensionRefactor()) {
+                        // Also don't allow client apps to cancel lifetime extended notifs.
+                        mustNotHaveFlags = (FLAG_FOREGROUND_SERVICE | FLAG_USER_INITIATED_JOB
+                                | FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY);
+                    } else {
+                        mustNotHaveFlags = (FLAG_FOREGROUND_SERVICE | FLAG_USER_INITIATED_JOB);
+                    }
+                    FlagChecker childrenFlagChecker = (flags) -> {
+                            if (cancelReason == REASON_CANCEL
+                                || cancelReason == REASON_CLICK
+                                || cancelReason == REASON_CANCEL_ALL) {
+                                if ((flags & FLAG_BUBBLE) != 0) {
+                                    return false;
+                                }
+                            }
+                            return (flags & mustNotHaveFlags) == 0;
+                    };
+                    cancelGroupChildrenLocked(userId, pkg, Binder.getCallingUid(),
+                            Binder.getCallingPid(), null,
+                            false, childrenFlagChecker, groupKey,
+                            REASON_APP_CANCEL, SystemClock.elapsedRealtime());
                 }
             }
         });
@@ -3107,6 +3180,18 @@
                     modifiedChannel, NOTIFICATION_CHANNEL_OR_GROUP_UPDATED);
         }
 
+        if (notificationForceGrouping()) {
+            final NotificationChannel updatedChannel = mPreferencesHelper.getNotificationChannel(
+                    pkg, uid, channel.getId(), false);
+            mHandler.postDelayed(() -> {
+                synchronized (mNotificationLock) {
+                    mGroupHelper.onChannelUpdated(
+                            UserHandle.getUserHandleForUid(uid).getIdentifier(), pkg,
+                            updatedChannel, mNotificationList);
+                }
+            }, DELAY_FORCE_REGROUP_TIME);
+        }
+
         handleSavePolicyFile();
     }
 
@@ -6652,18 +6737,33 @@
         }
     }
 
+    @SuppressWarnings("GuardedBy")
     @GuardedBy("mNotificationLock")
-    void addAutogroupKeyLocked(String key, boolean requestSort) {
+    void addAutogroupKeyLocked(String key, String groupName, boolean requestSort) {
         NotificationRecord r = mNotificationsByKey.get(key);
         if (r == null) {
             return;
         }
         if (r.getSbn().getOverrideGroupKey() == null) {
-            addAutoGroupAdjustment(r, GroupHelper.AUTOGROUP_KEY);
+            if (notificationForceGrouping()) {
+                if (r.getSbn().isAppGroup()) {
+                    // Override group key early for forced grouped notifications
+                    r.setOverrideGroupKey(groupName);
+                }
+            }
+
+            addAutoGroupAdjustment(r, groupName);
             EventLogTags.writeNotificationAutogrouped(key);
+
             if (!android.app.Flags.checkAutogroupBeforePost() || requestSort) {
                 mRankingHandler.requestSort();
             }
+
+            if (notificationForceGrouping()) {
+                if (r.getSbn().isAppGroup()) {
+                    mListeners.notifyPostedLocked(r, r);
+                }
+            }
         }
     }
 
@@ -6692,27 +6792,57 @@
     // Clears the 'fake' auto-group summary.
     @VisibleForTesting
     @GuardedBy("mNotificationLock")
-    void clearAutogroupSummaryLocked(int userId, String pkg) {
+    void clearAutogroupSummaryLocked(int userId, String pkg, String groupKey) {
+        final String autbundledGroupKey;
+        if (notificationForceGrouping()) {
+            autbundledGroupKey = groupKey;
+        } else {
+            autbundledGroupKey = pkg;
+        }
         ArrayMap<String, String> summaries = mAutobundledSummaries.get(userId);
-        if (summaries != null && summaries.containsKey(pkg)) {
-            final NotificationRecord removed = findNotificationByKeyLocked(summaries.remove(pkg));
+        if (summaries != null && summaries.containsKey(autbundledGroupKey)) {
+            final NotificationRecord removed = findNotificationByKeyLocked(
+                    summaries.remove(autbundledGroupKey));
             if (removed != null) {
                 final StatusBarNotification sbn = removed.getSbn();
                 cancelNotification(MY_UID, MY_PID, pkg, sbn.getTag(), sbn.getId(), 0, 0, false,
-                        userId, REASON_UNAUTOBUNDLED, null);
+                    userId, REASON_UNAUTOBUNDLED, null);
             }
         }
     }
 
     @GuardedBy("mNotificationLock")
-    private boolean hasAutoGroupSummaryLocked(StatusBarNotification sbn) {
-        ArrayMap<String, String> summaries = mAutobundledSummaries.get(sbn.getUserId());
-        return summaries != null && summaries.containsKey(sbn.getPackageName());
+    void removeAppSummaryLocked(String key) {
+        NotificationRecord r = mNotificationsByKey.get(key);
+        if (r == null) {
+            return;
+        }
+        if (convertSummaryToNotificationLocked(key)) {
+            r.isCanceled = true;
+            cancelNotification(Binder.getCallingUid(),
+                    Binder.getCallingPid(), r.getSbn().getPackageName(),
+                    r.getSbn().getTag(), r.getSbn().getId(), 0, 0,
+                    false, r.getUserId(),
+                    NotificationListenerService.REASON_GROUP_OPTIMIZATION, null);
+        }
+    }
+
+    @GuardedBy("mNotificationLock")
+    private boolean hasAutoGroupSummaryLocked(NotificationRecord record) {
+        final String autbundledGroupKey;
+        if (notificationForceGrouping()) {
+            autbundledGroupKey = GroupHelper.getFullAggregateGroupKey(record);
+        } else {
+            autbundledGroupKey = record.getSbn().getPackageName();
+        }
+
+        ArrayMap<String, String> summaries = mAutobundledSummaries.get(record.getUserId());
+        return summaries != null && summaries.containsKey(autbundledGroupKey);
     }
 
     // Creates a 'fake' summary for a package that has exceeded the solo-notification limit.
     NotificationRecord createAutoGroupSummary(int userId, String pkg, String triggeringKey,
-            int flagsToSet, Icon summaryIcon, int summaryIconColor, int summaryVisibilty) {
+            String groupKey, int summaryId, NotificationAttributes summaryAttr) {
         NotificationRecord summaryRecord = null;
         boolean isPermissionFixed = mPermissionHelper.isPermissionFixed(pkg, userId);
         synchronized (mNotificationLock) {
@@ -6730,24 +6860,35 @@
                 summaries = new ArrayMap<>();
             }
             mAutobundledSummaries.put(userId, summaries);
-            if (!summaries.containsKey(pkg)) {
+
+            boolean hasSummary;
+            String channelId;
+            if (notificationForceGrouping()) {
+                hasSummary = summaries.containsKey(groupKey);
+                channelId = summaryAttr.channelId;
+            } else {
+                hasSummary = summaries.containsKey(pkg);
+                channelId = notificationRecord.getChannel().getId();
+            }
+
+            if (!hasSummary) {
                 // Add summary
                 final ApplicationInfo appInfo =
                         adjustedSbn.getNotification().extras.getParcelable(
                                 EXTRA_BUILDER_APPLICATION_INFO, ApplicationInfo.class);
                 final Bundle extras = new Bundle();
                 extras.putParcelable(EXTRA_BUILDER_APPLICATION_INFO, appInfo);
-                final String channelId = notificationRecord.getChannel().getId();
+
 
                 final Notification summaryNotification =
                                 new Notification.Builder(getContext(), channelId)
-                                .setSmallIcon(summaryIcon)
+                                .setSmallIcon(summaryAttr.icon)
                                 .setGroupSummary(true)
-                                .setGroupAlertBehavior(Notification.GROUP_ALERT_CHILDREN)
-                                .setGroup(GroupHelper.AUTOGROUP_KEY)
-                                .setFlag(flagsToSet, true)
-                                .setColor(summaryIconColor)
-                                .setVisibility(summaryVisibilty)
+                                .setGroupAlertBehavior(summaryAttr.groupAlertBehavior)
+                                .setGroup(groupKey)
+                                .setFlag(summaryAttr.flags, true)
+                                .setColor(summaryAttr.iconColor)
+                                .setVisibility(summaryAttr.visibility)
                                 .build();
                 summaryNotification.extras.putAll(extras);
                 Intent appIntent = getContext().getPackageManager().getLaunchIntentForPackage(pkg);
@@ -6759,17 +6900,22 @@
                 final StatusBarNotification summarySbn =
                         new StatusBarNotification(adjustedSbn.getPackageName(),
                                 adjustedSbn.getOpPkg(),
-                                Integer.MAX_VALUE,
-                                GroupHelper.AUTOGROUP_KEY, adjustedSbn.getUid(),
+                                summaryId,
+                                groupKey, adjustedSbn.getUid(),
                                 adjustedSbn.getInitialPid(), summaryNotification,
-                                adjustedSbn.getUser(), GroupHelper.AUTOGROUP_KEY,
+                                adjustedSbn.getUser(), groupKey,
                                 System.currentTimeMillis());
                 summaryRecord = new NotificationRecord(getContext(), summarySbn,
                         notificationRecord.getChannel());
                 summaryRecord.setImportanceFixed(isPermissionFixed);
                 summaryRecord.setIsAppImportanceLocked(
                         notificationRecord.getIsAppImportanceLocked());
-                summaries.put(pkg, summarySbn.getKey());
+
+                if (notificationForceGrouping()) {
+                    summaries.put(summarySbn.getGroupKey(), summarySbn.getKey());
+                } else {
+                    summaries.put(pkg, summarySbn.getKey());
+                }
             }
             if (summaryRecord != null && checkDisqualifyingFeatures(userId, uid,
                     summaryRecord.getSbn().getId(), summaryRecord.getSbn().getTag(), summaryRecord,
@@ -6780,6 +6926,27 @@
         return null;
     }
 
+    @GuardedBy("mNotificationLock")
+    boolean convertSummaryToNotificationLocked(final String key) {
+        NotificationRecord r = mNotificationsByKey.get(key);
+        if (r == null) {
+            return false;
+        }
+        // Convert summary to regular notification
+        if (r.getSbn().isAppGroup() && r.getNotification().isGroupSummary()) {
+            String oldGroupKey = r.getGroupKey();
+            NotificationRecord groupSummary = mSummaryByGroupKey.get(oldGroupKey);
+            if (groupSummary != null && groupSummary.getKey().equals(r.getKey())) {
+                mSummaryByGroupKey.remove(oldGroupKey);
+            }
+            // Clear summary flag
+            StatusBarNotification sbn = r.getSbn();
+            sbn.getNotification().flags = (r.mOriginalFlags & ~FLAG_GROUP_SUMMARY);
+            return true;
+        }
+        return false;
+    }
+
     // Gets packages that have requested notification permission, and whether that has been
     // allowed/denied, for all users on the device.
     // Returns a single map containing that info keyed by (uid, package name) for all users.
@@ -8347,8 +8514,15 @@
          * They will be recreated as needed when the group children are unsnoozed
          */
         private boolean isSnoozable(NotificationRecord record) {
-            return !(record.getNotification().isGroupSummary() && GroupHelper.AUTOGROUP_KEY.equals(
-                    record.getNotification().getGroup()));
+            if (notificationForceGrouping()) {
+                boolean isExemptedSummary =
+                        ((record.getFlags() & FLAG_AUTOGROUP_SUMMARY) != 0
+                        || GroupHelper.isAggregatedGroup(record));
+                return !(record.getNotification().isGroupSummary() && isExemptedSummary);
+            } else {
+                return !(record.getNotification().isGroupSummary()
+                        && GroupHelper.AUTOGROUP_KEY.equals(record.getNotification().getGroup()));
+            }
         }
     }
 
@@ -8471,9 +8645,12 @@
                     cancelNotificationLocked(
                             r, mSendDelete, mReason, mRank, mCount, wasPosted, listenerName,
                             mCancellationElapsedTimeMs);
-                    cancelGroupChildrenLocked(r, mCallingUid, mCallingPid, listenerName,
-                            mSendDelete, childrenFlagChecker, mReason,
-                            mCancellationElapsedTimeMs);
+                    if (r.getNotification().isGroupSummary()) {
+                        cancelGroupChildrenLocked(mUserId, mPkg, mCallingUid, mCallingPid,
+                                listenerName, mSendDelete, childrenFlagChecker,
+                                r.getNotification().getGroup(), mReason,
+                                mCancellationElapsedTimeMs);
+                    }
                     mAttentionHelper.updateLightsLocked();
                     if (mShortcutHelper != null) {
                         mShortcutHelper.maybeListenForShortcutChangesForBubbles(r,
@@ -8481,6 +8658,14 @@
                                 mHandler);
                     }
                 } else {
+                    if (notificationForceGrouping()) {
+                        // No notification was found => maybe it was canceled by forced grouping
+                        if (Flags.notificationForceGroupSingletons()) {
+                            mGroupHelper.maybeCancelGroupChildrenForCanceledSummary(mPkg, mTag,
+                                mId, mUserId, mReason);
+                        }
+                    }
+
                     // No notification was found, assume that it is snoozed and cancel it.
                     if (mReason != REASON_SNOOZED) {
                         final boolean wasSnoozed = mSnoozeHelper.cancel(mUserId, mPkg, mTag, mId);
@@ -8708,7 +8893,7 @@
             boolean appBanned = !areNotificationsEnabledForPackageInt(pkg, uid);
             boolean isCallNotification = isCallNotification(pkg, uid);
             boolean posted = false;
-            synchronized (mNotificationLock) {
+            synchronized (NotificationManagerService.this.mNotificationLock) {
                 try {
                     NotificationRecord r = findNotificationByListLocked(mEnqueuedNotifications,
                             key);
@@ -8731,6 +8916,29 @@
                         return false;
                     }
 
+                    if (notificationForceGrouping()) {
+                        if (Flags.notificationForceGroupSingletons()) {
+                            // Check if this is an updated for a summary for an aggregated sparse
+                            // group and remove it because that summary has been canceled
+                            if (mGroupHelper.isUpdateForCanceledSummary(r)) {
+                                if (DBG) {
+                                    Log.w(TAG,
+                                        "Suppressing notification because summary was canceled: "
+                                            + r);
+                                }
+
+                                String groupKey = r.getGroupKey();
+                                NotificationRecord groupSummary = mSummaryByGroupKey.get(groupKey);
+                                if (groupSummary != null && groupSummary.getKey()
+                                        .equals(r.getKey())) {
+                                    mSummaryByGroupKey.remove(groupKey);
+                                }
+                                return false;
+                            }
+                        }
+                    }
+
+
                     final boolean isPackageSuspended =
                             isPackagePausedOrSuspended(r.getSbn().getPackageName(), r.getUid());
                     r.setHidden(isPackageSuspended);
@@ -8788,18 +8996,38 @@
                         if (notification.getSmallIcon() != null && !isCritical(r)) {
                             StatusBarNotification oldSbn = (old != null) ? old.getSbn() : null;
                             if (oldSbn == null || !Objects.equals(oldSbn.getGroup(), n.getGroup())
+                                    || !Objects.equals(oldSbn.getNotification().getGroup(),
+                                        n.getNotification().getGroup())
                                     || oldSbn.getNotification().flags
                                     != n.getNotification().flags) {
                                 synchronized (mNotificationLock) {
-                                    boolean willBeAutogrouped = mGroupHelper.onNotificationPosted(n,
-                                            hasAutoGroupSummaryLocked(n));
+                                    final String autogroupName =
+                                            notificationForceGrouping() ?
+                                                GroupHelper.getFullAggregateGroupKey(r)
+                                                : GroupHelper.AUTOGROUP_KEY;
+                                    boolean willBeAutogrouped =
+                                            mGroupHelper.onNotificationPosted(r,
+                                                hasAutoGroupSummaryLocked(r));
                                     if (willBeAutogrouped) {
                                         // The newly posted notification will be autogrouped, but
                                         // was not autogrouped onPost, to avoid an unnecessary sort.
                                         // We add the autogroup key to the notification without a
                                         // sort here, and it'll be sorted below with extractSignals.
-                                        addAutogroupKeyLocked(key, /* requestSort= */false);
+                                        addAutogroupKeyLocked(key,
+                                                autogroupName, /*requestSort=*/false);
+                                    } else {
+                                        if (notificationForceGrouping()) {
+                                            // Wait 3 seconds so that the app has a chance to post
+                                            // a group summary or children (complete a group)
+                                            mHandler.postDelayed(() -> {
+                                                synchronized (mNotificationLock) {
+                                                    mGroupHelper.onNotificationPostedWithDelay(
+                                                        r, mNotificationList, mSummaryByGroupKey);
+                                                }
+                                            }, r.getKey(), DELAY_FORCE_REGROUP_TIME);
+                                        }
                                     }
+
                                 }
                             }
                         }
@@ -8835,9 +9063,18 @@
                                     mHandler.post(() -> {
                                         synchronized (mNotificationLock) {
                                             mGroupHelper.onNotificationPosted(
-                                                    n, hasAutoGroupSummaryLocked(n));
+                                                    r, hasAutoGroupSummaryLocked(r));
                                         }
                                     });
+
+                                    if (notificationForceGrouping()) {
+                                        mHandler.postDelayed(() -> {
+                                            synchronized (mNotificationLock) {
+                                                mGroupHelper.onNotificationPostedWithDelay(r,
+                                                        mNotificationList, mSummaryByGroupKey);
+                                            }
+                                        }, r.getKey(), DELAY_FORCE_REGROUP_TIME);
+                                    }
                                 }
                             }
                         }
@@ -8846,12 +9083,20 @@
                         if (old != null && !old.isCanceled) {
                             mListeners.notifyRemovedLocked(r,
                                     REASON_ERROR, r.getStats());
-                            mHandler.post(new Runnable() {
-                                @Override
-                                public void run() {
-                                    mGroupHelper.onNotificationRemoved(n);
-                                }
-                            });
+                            if (notificationForceGrouping()) {
+                                mHandler.post(() -> {
+                                    synchronized (mNotificationLock) {
+                                        mGroupHelper.onNotificationRemoved(r, mNotificationList);
+                                    }
+                                });
+                            } else {
+                                mHandler.post(new Runnable() {
+                                    @Override
+                                    public void run() {
+                                        mGroupHelper.onNotificationRemoved(r);
+                                    }
+                                });
+                            }
                         }
 
                         if (callstyleCallbackApi()) {
@@ -9082,6 +9327,18 @@
             n.flags &= ~Notification.FLAG_GROUP_SUMMARY;
         }
 
+        if (notificationForceGrouping()) {
+            if (old != null) {
+                // If this is an update to a summary that was forced grouped => remove summary flag
+                boolean wasSummary = (old.mOriginalFlags & FLAG_GROUP_SUMMARY) != 0;
+                boolean wasForcedGrouped = (old.getFlags() & FLAG_GROUP_SUMMARY) == 0
+                        && old.getSbn().getOverrideGroupKey() != null;
+                if (n.isGroupSummary() && wasSummary && wasForcedGrouped) {
+                    n.flags &= ~FLAG_GROUP_SUMMARY;
+                }
+            }
+        }
+
         String group = sbn.getGroupKey();
         boolean isSummary = n.isGroupSummary();
 
@@ -9114,8 +9371,10 @@
         // notification was a summary and the new one isn't, or when the old
         // notification was a summary and its group key changed.
         if (oldIsSummary && (!isSummary || !oldGroup.equals(group))) {
-            cancelGroupChildrenLocked(old, callingUid, callingPid, null, false /* sendDelete */,
-                    childrenFlagChecker, REASON_APP_CANCEL, SystemClock.elapsedRealtime());
+            cancelGroupChildrenLocked(old.getUserId(), old.getSbn().getPackageName(), callingUid,
+                    callingPid, null, false /* sendDelete */, childrenFlagChecker,
+                    old.getNotification().getGroup(), REASON_APP_CANCEL,
+                    SystemClock.elapsedRealtime());
         }
     }
 
@@ -9777,12 +10036,21 @@
                     r.isCanceled = true;
                 }
                 mListeners.notifyRemovedLocked(r, reason, r.getStats());
-                mHandler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        mGroupHelper.onNotificationRemoved(r.getSbn());
-                    }
-                });
+                if (notificationForceGrouping()) {
+                    mHandler.removeCallbacksAndMessages(r.getKey());
+                    mHandler.post(() -> {
+                        synchronized (NotificationManagerService.this.mNotificationLock) {
+                            mGroupHelper.onNotificationRemoved(r, mNotificationList);
+                        }
+                    });
+                } else {
+                    mHandler.post(new Runnable() {
+                        @Override
+                        public void run() {
+                            mGroupHelper.onNotificationRemoved(r);
+                        }
+                    });
+                }
                 if (callstyleCallbackApi()) {
                     notifyCallNotificationEventListenerOnRemoved(r);
                 }
@@ -9815,9 +10083,15 @@
         }
         final ArrayMap<String, String> summaries =
                 mAutobundledSummaries.get(r.getSbn().getUserId());
+        final String autbundledGroupKey;
+        if (notificationForceGrouping()) {
+            autbundledGroupKey = groupKey;
+        } else {
+            autbundledGroupKey = r.getSbn().getPackageName();
+        }
         if (summaries != null && r.getSbn().getKey().equals(
-                summaries.get(r.getSbn().getPackageName()))) {
-            summaries.remove(r.getSbn().getPackageName());
+                summaries.get(autbundledGroupKey))) {
+            summaries.remove(autbundledGroupKey);
         }
 
         // Save it for users of getHistoricalNotifications(), unless the whole channel was deleted
@@ -10081,6 +10355,15 @@
         public boolean apply(int flags);
     }
 
+    private static boolean isChildOfGroup(final NotificationRecord childRecord, int userId,
+            String pkg, String groupKey) {
+        return (childRecord.getUser().getIdentifier() == userId
+            && childRecord.getSbn().getPackageName().equals(pkg)
+            && childRecord.getSbn().isGroup()
+            && !childRecord.getNotification().isGroupSummary()
+            && TextUtils.equals(groupKey, childRecord.getNotification().getGroup()));
+    }
+
     @GuardedBy("mNotificationLock")
     private void cancelAllNotificationsByListLocked(ArrayList<NotificationRecord> notificationList,
             @Nullable String pkg, boolean nullPkgIndicatesUserSwitch, @Nullable String channelId,
@@ -10238,43 +10521,34 @@
 
     // Warning: The caller is responsible for invoking updateLightsLocked().
     @GuardedBy("mNotificationLock")
-    private void cancelGroupChildrenLocked(NotificationRecord r, int callingUid, int callingPid,
-            String listenerName, boolean sendDelete, FlagChecker flagChecker, int reason,
-            @ElapsedRealtimeLong long cancellationElapsedTimeMs) {
-        Notification n = r.getNotification();
-        if (!n.isGroupSummary()) {
-            return;
-        }
-
-        String pkg = r.getSbn().getPackageName();
-
+    private void cancelGroupChildrenLocked(int userId, String pkg, int callingUid, int callingPid,
+            String listenerName, boolean sendDelete, FlagChecker flagChecker, String groupKey,
+            int reason, @ElapsedRealtimeLong long cancellationElapsedTimeMs) {
         if (pkg == null) {
-            if (DBG) Slog.e(TAG, "No package for group summary: " + r.getKey());
+            if (DBG) Slog.e(TAG, "No package for group summary");
             return;
         }
 
-        cancelGroupChildrenByListLocked(mNotificationList, r, callingUid, callingPid, listenerName,
-                sendDelete, true, flagChecker, reason, cancellationElapsedTimeMs);
-        cancelGroupChildrenByListLocked(mEnqueuedNotifications, r, callingUid, callingPid,
-                listenerName, sendDelete, false, flagChecker, reason, cancellationElapsedTimeMs);
+        cancelGroupChildrenByListLocked(mNotificationList, userId, pkg, callingUid, callingPid,
+                listenerName, sendDelete, true, flagChecker, groupKey,
+                reason, cancellationElapsedTimeMs);
+        cancelGroupChildrenByListLocked(mEnqueuedNotifications, userId, pkg, callingUid, callingPid,
+                listenerName, sendDelete, false, flagChecker, groupKey,
+                reason, cancellationElapsedTimeMs);
     }
 
     @GuardedBy("mNotificationLock")
     private void cancelGroupChildrenByListLocked(ArrayList<NotificationRecord> notificationList,
-            NotificationRecord parentNotification, int callingUid, int callingPid,
+            int userId, String pkg, int callingUid, int callingPid,
             String listenerName, boolean sendDelete, boolean wasPosted, FlagChecker flagChecker,
-            int reason, @ElapsedRealtimeLong long cancellationElapsedTimeMs) {
-        final String pkg = parentNotification.getSbn().getPackageName();
-        final int userId = parentNotification.getUserId();
+            String groupKey, int reason, @ElapsedRealtimeLong long cancellationElapsedTimeMs) {
         final int childReason = REASON_GROUP_SUMMARY_CANCELED;
         for (int i = notificationList.size() - 1; i >= 0; i--) {
             final NotificationRecord childR = notificationList.get(i);
             final StatusBarNotification childSbn = childR.getSbn();
-            if ((childSbn.isGroup() && !childSbn.getNotification().isGroupSummary()) &&
-                    childR.getGroupKey().equals(parentNotification.getGroupKey())
-                    && (flagChecker == null || flagChecker.apply(childR.getFlags()))
-                    && (!childR.getChannel().isImportantConversation()
-                            || reason != REASON_CANCEL)) {
+            if (isChildOfGroup(childR, userId, pkg, groupKey)
+                && (flagChecker == null || flagChecker.apply(childR.getFlags()))
+                && (!childR.getChannel().isImportantConversation() || reason != REASON_CANCEL)) {
                 EventLogTags.writeNotificationCancel(callingUid, callingPid, pkg, childSbn.getId(),
                         childSbn.getTag(), userId, 0, 0, childReason, listenerName);
                 notificationList.remove(i);
@@ -10354,6 +10628,7 @@
                 != null) {
             return r;
         }
+
         return null;
     }
 
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 0d4bdf6..bd00901 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -449,9 +449,16 @@
         mRankingTimeMs = calculateRankingTimeMs(previous.getRankingTimeMs());
         mCreationTimeMs = previous.mCreationTimeMs;
         mVisibleSinceMs = previous.mVisibleSinceMs;
-        if (previous.getSbn().getOverrideGroupKey() != null && !getSbn().isAppGroup()) {
-            getSbn().setOverrideGroupKey(previous.getSbn().getOverrideGroupKey());
+        if (android.service.notification.Flags.notificationForceGrouping()) {
+            if (previous.getSbn().getOverrideGroupKey() != null) {
+                getSbn().setOverrideGroupKey(previous.getSbn().getOverrideGroupKey());
+            }
+        } else {
+            if (previous.getSbn().getOverrideGroupKey() != null && !getSbn().isAppGroup()) {
+                getSbn().setOverrideGroupKey(previous.getSbn().getOverrideGroupKey());
+            }
         }
+
         // Don't copy importance information or mGlobalSortKey, recompute them.
     }
 
diff --git a/services/core/java/com/android/server/notification/flags.aconfig b/services/core/java/com/android/server/notification/flags.aconfig
index bf6b652..7265cff 100644
--- a/services/core/java/com/android/server/notification/flags.aconfig
+++ b/services/core/java/com/android/server/notification/flags.aconfig
@@ -141,4 +141,11 @@
   namespace: "systemui"
   description: "This flag does not allow notifications older than 2 weeks old to be posted"
   bug: "339833083"
-}
\ No newline at end of file
+}
+
+flag {
+  name: "notification_force_group_singletons"
+  namespace: "systemui"
+  description: "This flag enables forced auto-grouping singleton groups"
+  bug: "336488844"
+}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
index 8a7d276..225c1dc 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
@@ -20,13 +20,23 @@
 import static android.app.Notification.FLAG_BUBBLE;
 import static android.app.Notification.FLAG_CAN_COLORIZE;
 import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
+import static android.app.Notification.FLAG_GROUP_SUMMARY;
 import static android.app.Notification.FLAG_NO_CLEAR;
 import static android.app.Notification.FLAG_ONGOING_EVENT;
+import static android.app.Notification.GROUP_ALERT_ALL;
+import static android.app.Notification.GROUP_ALERT_CHILDREN;
+import static android.app.Notification.GROUP_ALERT_SUMMARY;
 import static android.app.Notification.VISIBILITY_PRIVATE;
 import static android.app.Notification.VISIBILITY_PUBLIC;
 import static android.app.Notification.VISIBILITY_SECRET;
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.service.notification.Flags.FLAG_NOTIFICATION_FORCE_GROUPING;
 import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
 
+import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL;
+import static com.android.server.notification.GroupHelper.AGGREGATE_GROUP_KEY;
+import static com.android.server.notification.GroupHelper.AUTOGROUP_KEY;
 import static com.android.server.notification.GroupHelper.BASE_FLAGS;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -41,6 +51,7 @@
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -49,6 +60,7 @@
 
 import android.annotation.SuppressLint;
 import android.app.Notification;
+import android.app.NotificationChannel;
 import android.content.pm.PackageManager;
 import android.graphics.Color;
 import android.graphics.drawable.AdaptiveIconDrawable;
@@ -66,6 +78,7 @@
 
 import com.android.internal.R;
 import com.android.server.UiServiceTestCase;
+import com.android.server.notification.GroupHelper.CachedSummary;
 import com.android.server.notification.GroupHelper.NotificationAttributes;
 
 import org.junit.Before;
@@ -90,11 +103,15 @@
     public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
 
     private final int DEFAULT_VISIBILITY = VISIBILITY_PRIVATE;
+    private final int DEFAULT_GROUP_ALERT = GROUP_ALERT_CHILDREN;
+
+    private final String TEST_CHANNEL_ID = "TEST_CHANNEL_ID";
 
     private @Mock GroupHelper.Callback mCallback;
     private @Mock PackageManager mPackageManager;
 
     private final static int AUTOGROUP_AT_COUNT = 7;
+    private final static int AUTOGROUP_SINGLETONS_AT_COUNT = 2;
     private GroupHelper mGroupHelper;
     private @Mock Icon mSmallIcon;
 
@@ -113,7 +130,7 @@
         MockitoAnnotations.initMocks(this);
 
         mGroupHelper = new GroupHelper(getContext(), mPackageManager, AUTOGROUP_AT_COUNT,
-                mCallback);
+                AUTOGROUP_SINGLETONS_AT_COUNT, mCallback);
 
         NotificationRecord r = mock(NotificationRecord.class);
         StatusBarNotification sbn = getSbn("package", 0, "0", UserHandle.SYSTEM);
@@ -124,7 +141,7 @@
 
     private StatusBarNotification getSbn(String pkg, int id, String tag,
             UserHandle user, String groupKey, Icon smallIcon, int iconColor) {
-        Notification.Builder nb = new Notification.Builder(getContext(), "test_channel_id")
+        Notification.Builder nb = new Notification.Builder(getContext(), TEST_CHANNEL_ID)
                 .setContentTitle("A")
                 .setWhen(1205)
                 .setSmallIcon(smallIcon)
@@ -146,15 +163,54 @@
         return getSbn(pkg, id, tag, user, null);
     }
 
+    private NotificationRecord getNotificationRecord(String pkg, int id, String tag,
+            UserHandle user) {
+        return getNotificationRecord(pkg, id, tag, user, null, false);
+    }
+
+    private NotificationRecord getNotificationRecord(String pkg, int id, String tag,
+            UserHandle user, String groupKey, boolean isSummary) {
+        return getNotificationRecord(pkg, id, tag, user, groupKey, isSummary, IMPORTANCE_DEFAULT);
+    }
+
+    private NotificationRecord getNotificationRecord(String pkg, int id, String tag,
+            UserHandle user, String groupKey, boolean isSummary, int importance) {
+        return getNotificationRecord(pkg, id, tag, user, groupKey, isSummary,
+                new NotificationChannel(TEST_CHANNEL_ID, TEST_CHANNEL_ID, importance));
+    }
+
+    private NotificationRecord getNotificationRecord(String pkg, int id, String tag,
+            UserHandle user, String groupKey, boolean isSummary, NotificationChannel channel) {
+        StatusBarNotification sbn = getSbn(pkg, id, tag, user, groupKey);
+        if (isSummary) {
+            sbn.getNotification().flags |= FLAG_GROUP_SUMMARY;
+        }
+        return new NotificationRecord(getContext(), sbn, channel);
+    }
+
+    private NotificationRecord getNotificationRecord(StatusBarNotification sbn) {
+        return new NotificationRecord(getContext(), sbn,
+            new NotificationChannel(TEST_CHANNEL_ID, TEST_CHANNEL_ID, IMPORTANCE_DEFAULT));
+    }
+
     private NotificationAttributes getNotificationAttributes(int flags) {
-        return new NotificationAttributes(flags, mSmallIcon, COLOR_DEFAULT, DEFAULT_VISIBILITY);
+        return new NotificationAttributes(flags, mSmallIcon, COLOR_DEFAULT, DEFAULT_VISIBILITY,
+                DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
+    }
+
+    private String getExpectedAutogroupKey(final NotificationRecord record) {
+        if (android.service.notification.Flags.notificationForceGrouping()) {
+            return GroupHelper.getFullAggregateGroupKey(record);
+        } else {
+            return AUTOGROUP_KEY;
+        }
     }
 
     @Test
     public void testGetAutogroupSummaryFlags_noChildren() {
         ArrayMap<String, NotificationAttributes> children = new ArrayMap<>();
 
-        assertEquals(BASE_FLAGS, mGroupHelper.getAutogroupSummaryFlags(children));
+        assertEquals(BASE_FLAGS, GroupHelper.getAutogroupSummaryFlags(children));
     }
 
     @Test
@@ -165,7 +221,7 @@
         children.put("c", getNotificationAttributes(FLAG_BUBBLE));
 
         assertEquals(FLAG_ONGOING_EVENT | BASE_FLAGS,
-                mGroupHelper.getAutogroupSummaryFlags(children));
+                GroupHelper.getAutogroupSummaryFlags(children));
     }
 
     @Test
@@ -176,7 +232,7 @@
         children.put("c", getNotificationAttributes(FLAG_BUBBLE));
 
         assertEquals(FLAG_NO_CLEAR | FLAG_ONGOING_EVENT | BASE_FLAGS,
-                mGroupHelper.getAutogroupSummaryFlags(children));
+                GroupHelper.getAutogroupSummaryFlags(children));
     }
 
     @Test
@@ -187,7 +243,7 @@
         children.put("c", getNotificationAttributes(FLAG_BUBBLE));
 
         assertEquals(FLAG_ONGOING_EVENT | BASE_FLAGS,
-                mGroupHelper.getAutogroupSummaryFlags(children));
+                GroupHelper.getAutogroupSummaryFlags(children));
     }
 
     @Test
@@ -199,7 +255,7 @@
         children.put("d", getNotificationAttributes(FLAG_ONGOING_EVENT));
 
         assertEquals(FLAG_ONGOING_EVENT | BASE_FLAGS,
-                mGroupHelper.getAutogroupSummaryFlags(children));
+                GroupHelper.getAutogroupSummaryFlags(children));
     }
 
     @Test
@@ -210,7 +266,7 @@
         children.put("c", getNotificationAttributes(FLAG_BUBBLE));
 
         assertEquals(BASE_FLAGS,
-                mGroupHelper.getAutogroupSummaryFlags(children));
+                GroupHelper.getAutogroupSummaryFlags(children));
     }
 
     @Test
@@ -222,7 +278,7 @@
         children.put("d", getNotificationAttributes(FLAG_AUTO_CANCEL | FLAG_FOREGROUND_SERVICE));
 
         assertEquals(FLAG_AUTO_CANCEL | BASE_FLAGS,
-                mGroupHelper.getAutogroupSummaryFlags(children));
+                GroupHelper.getAutogroupSummaryFlags(children));
     }
 
     @Test
@@ -235,15 +291,16 @@
                 FLAG_AUTO_CANCEL | FLAG_FOREGROUND_SERVICE | FLAG_ONGOING_EVENT));
 
         assertEquals(FLAG_AUTO_CANCEL| FLAG_ONGOING_EVENT | BASE_FLAGS,
-                mGroupHelper.getAutogroupSummaryFlags(children));
+                GroupHelper.getAutogroupSummaryFlags(children));
     }
 
     @Test
     public void testNoGroup_postingUnderLimit() {
         final String pkg = "package";
         for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
-            mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
-                    false);
+            mGroupHelper.onNotificationPosted(
+                getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
+                false);
         }
         verifyZeroInteractions(mCallback);
     }
@@ -253,11 +310,12 @@
         final String pkg = "package";
         final String pkg2 = "package2";
         for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
-            mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
-                    false);
+            mGroupHelper.onNotificationPosted(
+                getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
+                false);
         }
         mGroupHelper.onNotificationPosted(
-                getSbn(pkg2, AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM), false);
+            getNotificationRecord(pkg2, AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM), false);
         verifyZeroInteractions(mCallback);
     }
 
@@ -265,11 +323,12 @@
     public void testNoGroup_multiUser() {
         final String pkg = "package";
         for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
-            mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
-                    false);
+            mGroupHelper.onNotificationPosted(
+                getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
+                false);
         }
         mGroupHelper.onNotificationPosted(
-                getSbn(pkg, AUTOGROUP_AT_COUNT, "four", UserHandle.of(7)), false);
+            getNotificationRecord(pkg, AUTOGROUP_AT_COUNT, "four", UserHandle.of(7)), false);
         verifyZeroInteractions(mCallback);
     }
 
@@ -278,10 +337,11 @@
         final String pkg = "package";
         for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
             mGroupHelper.onNotificationPosted(
-                    getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false);
+                getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false);
         }
         mGroupHelper.onNotificationPosted(
-                getSbn(pkg, AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM, "a"), false);
+            getNotificationRecord(pkg, AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM, "a", false),
+            false);
         verifyZeroInteractions(mCallback);
     }
 
@@ -289,185 +349,241 @@
     @DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testAddSummary_alwaysAutogroup() {
         final String pkg = "package";
+        final String autogroupKey = getExpectedAutogroupKey(
+                getNotificationRecord(pkg, 0, String.valueOf(0), UserHandle.SYSTEM));
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
             mGroupHelper.onNotificationPosted(
-                    getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false);
+                getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false);
         }
         verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(getNotificationAttributes(BASE_FLAGS)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+                anyInt(), eq(pkg), anyString(), eq(autogroupKey),
+                anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), eq(autogroupKey),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
-        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
     }
 
     @Test
     @EnableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testAddSummary() {
         final String pkg = "package";
+        final String autogroupKey = getExpectedAutogroupKey(
+                getNotificationRecord(pkg, 0, String.valueOf(0), UserHandle.SYSTEM));
         for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
             assertThat(mGroupHelper.onNotificationPosted(
-                    getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false)).isFalse();
+                    getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
+                    false)).isFalse();
         }
         assertThat(mGroupHelper.onNotificationPosted(
-                getSbn(pkg, AUTOGROUP_AT_COUNT - 1, String.valueOf(AUTOGROUP_AT_COUNT - 1),
+            getNotificationRecord(pkg, AUTOGROUP_AT_COUNT - 1, String.valueOf(AUTOGROUP_AT_COUNT - 1),
                         UserHandle.SYSTEM), false)).isTrue();
-        verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(getNotificationAttributes(BASE_FLAGS)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(autogroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
-        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
     }
 
     @Test
     @DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testAddSummary_oneChildOngoing_summaryOngoing_alwaysAutogroup() {
         final String pkg = "package";
+        final String autogroupKey = getExpectedAutogroupKey(
+                getNotificationRecord(pkg, 0, String.valueOf(0), UserHandle.SYSTEM));
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
             if (i == 0) {
-                sbn.getNotification().flags |= FLAG_ONGOING_EVENT;
+                r.getNotification().flags |= FLAG_ONGOING_EVENT;
             }
-            mGroupHelper.onNotificationPosted(sbn, false);
+            mGroupHelper.onNotificationPosted(r, false);
         }
         verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(autogroupKey), anyInt(),
                 eq(getNotificationAttributes(BASE_FLAGS | FLAG_ONGOING_EVENT)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
-        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
     }
 
     @Test
     @EnableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testAddSummary_oneChildOngoing_summaryOngoing() {
         final String pkg = "package";
+        final String autogroupKey = getExpectedAutogroupKey(
+                getNotificationRecord(pkg, 0, String.valueOf(0), UserHandle.SYSTEM));
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
             if (i == 0) {
-                sbn.getNotification().flags |= FLAG_ONGOING_EVENT;
+                r.getNotification().flags |= FLAG_ONGOING_EVENT;
             }
-            mGroupHelper.onNotificationPosted(sbn, false);
+            mGroupHelper.onNotificationPosted(r, false);
         }
         verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(autogroupKey), anyInt(),
                 eq(getNotificationAttributes(BASE_FLAGS | FLAG_ONGOING_EVENT)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
-        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
     }
 
     @Test
     @DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testAddSummary_oneChildAutoCancel_summaryNotAutoCancel_alwaysAutogroup() {
         final String pkg = "package";
+        final String autogroupKey = getExpectedAutogroupKey(
+            getNotificationRecord(pkg, 0, String.valueOf(0), UserHandle.SYSTEM));
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
             if (i == 0) {
-                sbn.getNotification().flags |= FLAG_AUTO_CANCEL;
+                r.getNotification().flags |= FLAG_AUTO_CANCEL;
             }
-            mGroupHelper.onNotificationPosted(sbn, false);
+            mGroupHelper.onNotificationPosted(r, false);
         }
-        verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(getNotificationAttributes(BASE_FLAGS)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(autogroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
-        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
     }
 
     @Test
     @EnableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testAddSummary_oneChildAutoCancel_summaryNotAutoCancel() {
         final String pkg = "package";
+        final String autogroupKey = getExpectedAutogroupKey(
+                getNotificationRecord(pkg, 0, String.valueOf(0), UserHandle.SYSTEM));
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
             if (i == 0) {
-                sbn.getNotification().flags |= FLAG_AUTO_CANCEL;
+                r.getNotification().flags |= FLAG_AUTO_CANCEL;
             }
-            mGroupHelper.onNotificationPosted(sbn, false);
+            mGroupHelper.onNotificationPosted(r, false);
         }
-        verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(getNotificationAttributes(BASE_FLAGS)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(autogroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(),
+                eq(autogroupKey), anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
-        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
     }
 
     @Test
     @DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testAddSummary_allChildrenAutoCancel_summaryAutoCancel_alwaysAutogroup() {
         final String pkg = "package";
+        final String autogroupKey = getExpectedAutogroupKey(
+                getNotificationRecord(pkg, 0, String.valueOf(0), UserHandle.SYSTEM));
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            sbn.getNotification().flags |= FLAG_AUTO_CANCEL;
-            mGroupHelper.onNotificationPosted(sbn, false);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
+            r.getNotification().flags |= FLAG_AUTO_CANCEL;
+            mGroupHelper.onNotificationPosted(r, false);
         }
         verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(autogroupKey), anyInt(),
                 eq(getNotificationAttributes(BASE_FLAGS | FLAG_AUTO_CANCEL)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), eq(autogroupKey),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
-        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
     }
 
     @Test
     @EnableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testAddSummary_allChildrenAutoCancel_summaryAutoCancel() {
         final String pkg = "package";
+        final String autogroupKey = getExpectedAutogroupKey(
+                getNotificationRecord(pkg, 0, String.valueOf(0), UserHandle.SYSTEM));
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            sbn.getNotification().flags |= FLAG_AUTO_CANCEL;
-            mGroupHelper.onNotificationPosted(sbn, false);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
+            r.getNotification().flags |= FLAG_AUTO_CANCEL;
+            mGroupHelper.onNotificationPosted(r, false);
         }
         verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(autogroupKey), anyInt(),
                 eq(getNotificationAttributes(BASE_FLAGS | FLAG_AUTO_CANCEL)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(),
+                eq(autogroupKey), anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
-        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
     }
 
     @Test
     @DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testAddSummary_summaryAutoCancelNoClear_alwaysAutogroup() {
         final String pkg = "package";
+        final String autogroupKey = getExpectedAutogroupKey(
+                getNotificationRecord(pkg, 0, String.valueOf(0), UserHandle.SYSTEM));
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            sbn.getNotification().flags |= FLAG_AUTO_CANCEL;
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
+            r.getNotification().flags |= FLAG_AUTO_CANCEL;
             if (i == 0) {
-                sbn.getNotification().flags |= FLAG_NO_CLEAR;
+                r.getNotification().flags |= FLAG_NO_CLEAR;
             }
-            mGroupHelper.onNotificationPosted(sbn, false);
+            mGroupHelper.onNotificationPosted(r, false);
         }
         verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(autogroupKey), anyInt(),
                 eq(getNotificationAttributes(BASE_FLAGS | FLAG_AUTO_CANCEL | FLAG_NO_CLEAR)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), eq(autogroupKey),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
-        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
     }
 
     @Test
     @EnableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testAddSummary_summaryAutoCancelNoClear() {
         final String pkg = "package";
+        final String autogroupKey = getExpectedAutogroupKey(
+                getNotificationRecord(pkg, 0, String.valueOf(0), UserHandle.SYSTEM));
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            sbn.getNotification().flags |= FLAG_AUTO_CANCEL;
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
+            r.getNotification().flags |= FLAG_AUTO_CANCEL;
             if (i == 0) {
-                sbn.getNotification().flags |= FLAG_NO_CLEAR;
+                r.getNotification().flags |= FLAG_NO_CLEAR;
             }
-            mGroupHelper.onNotificationPosted(sbn, false);
+            mGroupHelper.onNotificationPosted(r, false);
         }
         verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(autogroupKey), anyInt(),
                 eq(getNotificationAttributes(BASE_FLAGS | FLAG_AUTO_CANCEL | FLAG_NO_CLEAR)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(),
+                eq(autogroupKey), anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
-        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
     }
 
     @Test
@@ -475,15 +591,16 @@
         final String pkg = "package";
 
         // Post AUTOGROUP_AT_COUNT ongoing notifications
-        ArrayList<StatusBarNotification>  notifications = new ArrayList<>();
+        ArrayList<NotificationRecord> notifications = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            sbn.getNotification().flags |= FLAG_ONGOING_EVENT;
-            notifications.add(sbn);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
+            r.getNotification().flags |= FLAG_ONGOING_EVENT;
+            notifications.add(r);
         }
 
-        for (StatusBarNotification sbn: notifications) {
-            mGroupHelper.onNotificationPosted(sbn, false);
+        for (NotificationRecord r: notifications) {
+            mGroupHelper.onNotificationPosted(r, false);
         }
 
         // One notification is no longer ongoing
@@ -491,7 +608,7 @@
         mGroupHelper.onNotificationPosted(notifications.get(0), true);
 
         // Summary should keep FLAG_ONGOING_EVENT if any child has it
-        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(),
+        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(), anyString(),
                 eq(getNotificationAttributes(BASE_FLAGS | FLAG_ONGOING_EVENT)));
     }
 
@@ -500,24 +617,25 @@
         final String pkg = "package";
 
         // Post AUTOGROUP_AT_COUNT ongoing notifications
-        ArrayList<StatusBarNotification>  notifications = new ArrayList<>();
+        ArrayList<NotificationRecord> notifications = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
             if (i == 0) {
-                sbn.getNotification().flags |= FLAG_ONGOING_EVENT;
+                r.getNotification().flags |= FLAG_ONGOING_EVENT;
             }
-            notifications.add(sbn);
+            notifications.add(r);
         }
 
-        for (StatusBarNotification sbn: notifications) {
-            mGroupHelper.onNotificationPosted(sbn, false);
+        for (NotificationRecord r: notifications) {
+            mGroupHelper.onNotificationPosted(r, false);
         }
 
         // remove ongoing
         mGroupHelper.onNotificationRemoved(notifications.get(0));
 
         // Summary is no longer ongoing
-        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(),
+        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(), anyString(),
                 eq(getNotificationAttributes(BASE_FLAGS)));
     }
 
@@ -526,14 +644,15 @@
         final String pkg = "package";
 
         // Post AUTOGROUP_AT_COUNT ongoing notifications
-        ArrayList<StatusBarNotification>  notifications = new ArrayList<>();
+        ArrayList<NotificationRecord> notifications = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            notifications.add(sbn);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
+            notifications.add(r);
         }
 
-        for (StatusBarNotification sbn: notifications) {
-            mGroupHelper.onNotificationPosted(sbn, false);
+        for (NotificationRecord r: notifications) {
+            mGroupHelper.onNotificationPosted(r, false);
         }
 
         // update to ongoing
@@ -541,7 +660,7 @@
         mGroupHelper.onNotificationPosted(notifications.get(0), true);
 
         // Summary is now ongoing
-        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(),
+        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(), anyString(),
                 eq(getNotificationAttributes(BASE_FLAGS | FLAG_ONGOING_EVENT)));
     }
 
@@ -550,23 +669,25 @@
         final String pkg = "package";
 
         // Post AUTOGROUP_AT_COUNT ongoing notifications
-        ArrayList<StatusBarNotification>  notifications = new ArrayList<>();
+        ArrayList<NotificationRecord> notifications = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            notifications.add(sbn);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                UserHandle.SYSTEM);
+            notifications.add(r);
         }
 
-        for (StatusBarNotification sbn: notifications) {
-            mGroupHelper.onNotificationPosted(sbn, false);
+        for (NotificationRecord r: notifications) {
+            mGroupHelper.onNotificationPosted(r, false);
         }
 
         // add ongoing
-        StatusBarNotification sbn = getSbn(pkg, AUTOGROUP_AT_COUNT + 1, null, UserHandle.SYSTEM);
-        sbn.getNotification().flags |= FLAG_ONGOING_EVENT;
-        mGroupHelper.onNotificationPosted(sbn, true);
+        NotificationRecord r = getNotificationRecord(pkg, AUTOGROUP_AT_COUNT + 1, null,
+                UserHandle.SYSTEM);
+        r.getNotification().flags |= FLAG_ONGOING_EVENT;
+        mGroupHelper.onNotificationPosted(r, true);
 
         // Summary is now ongoing
-        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(),
+        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(), anyString(),
                 eq(getNotificationAttributes(BASE_FLAGS | FLAG_ONGOING_EVENT)));
     }
 
@@ -575,51 +696,84 @@
         final String pkg = "package";
 
         // Post AUTOGROUP_AT_COUNT ongoing notifications
-        ArrayList<StatusBarNotification>  notifications = new ArrayList<>();
+        ArrayList<NotificationRecord> notifications = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                UserHandle.SYSTEM);
             if (i == 0) {
-                sbn.getNotification().flags |= FLAG_ONGOING_EVENT;
+                r.getNotification().flags |= FLAG_ONGOING_EVENT;
             }
-            notifications.add(sbn);
+            notifications.add(r);
         }
 
-        for (StatusBarNotification sbn: notifications) {
-            mGroupHelper.onNotificationPosted(sbn, false);
+        for (NotificationRecord r: notifications) {
+            mGroupHelper.onNotificationPosted(r, false);
         }
 
         // app group the ongoing child
-        StatusBarNotification sbn = getSbn(pkg, 0, "0", UserHandle.SYSTEM, "app group now");
-        mGroupHelper.onNotificationPosted(sbn, true);
+        NotificationRecord r = getNotificationRecord(pkg, 0, "0", UserHandle.SYSTEM,
+                "app group now", false);
+        mGroupHelper.onNotificationPosted(r, true);
 
         // Summary is no longer ongoing
-        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(),
+        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(), anyString(),
                 eq(getNotificationAttributes(BASE_FLAGS)));
     }
 
     @Test
+    @DisableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
     public void testAutoGrouped_singleOngoing_removeNonOngoingChild() {
         final String pkg = "package";
 
         // Post AUTOGROUP_AT_COUNT ongoing notifications
-        ArrayList<StatusBarNotification>  notifications = new ArrayList<>();
+        ArrayList<NotificationRecord> notifications = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
             if (i == 0) {
-                sbn.getNotification().flags |= FLAG_ONGOING_EVENT;
+                r.getNotification().flags |= FLAG_ONGOING_EVENT;
             }
-            notifications.add(sbn);
+            notifications.add(r);
         }
 
-        for (StatusBarNotification sbn: notifications) {
-            mGroupHelper.onNotificationPosted(sbn, false);
+        for (NotificationRecord r: notifications) {
+            mGroupHelper.onNotificationPosted(r, false);
         }
 
         // remove ongoing
         mGroupHelper.onNotificationRemoved(notifications.get(1));
 
         // Summary is still ongoing
-        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testAutoGrouped_singleOngoing_removeNonOngoingChild_forceGrouping() {
+        final String pkg = "package";
+
+        // Post AUTOGROUP_AT_COUNT ongoing notifications
+        ArrayList<NotificationRecord> notifications = new ArrayList<>();
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                UserHandle.SYSTEM);
+            if (i == 0) {
+                r.getNotification().flags |= FLAG_ONGOING_EVENT;
+            }
+            notifications.add(r);
+        }
+
+        for (NotificationRecord r: notifications) {
+            mGroupHelper.onNotificationPosted(r, false);
+        }
+
+        // remove ongoing
+        mGroupHelper.onNotificationRemoved(notifications.get(1));
+
+        // Summary is still ongoing
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
     }
 
     @Test
@@ -627,15 +781,16 @@
         final String pkg = "package";
 
         // Post AUTOGROUP_AT_COUNT ongoing notifications
-        ArrayList<StatusBarNotification>  notifications = new ArrayList<>();
+        ArrayList<NotificationRecord> notifications = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            sbn.getNotification().flags |= FLAG_AUTO_CANCEL;
-            notifications.add(sbn);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
+            r.getNotification().flags |= FLAG_AUTO_CANCEL;
+            notifications.add(r);
         }
 
-        for (StatusBarNotification sbn: notifications) {
-            mGroupHelper.onNotificationPosted(sbn, false);
+        for (NotificationRecord r: notifications) {
+            mGroupHelper.onNotificationPosted(r, false);
         }
 
         // One notification is no longer autocancelable
@@ -643,7 +798,7 @@
         mGroupHelper.onNotificationPosted(notifications.get(0), true);
 
         // Summary should no longer be autocancelable
-        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(),
+        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(), anyString(),
                 eq(getNotificationAttributes(BASE_FLAGS)));
     }
 
@@ -652,17 +807,18 @@
         final String pkg = "package";
 
         // Post AUTOGROUP_AT_COUNT ongoing notifications
-        ArrayList<StatusBarNotification>  notifications = new ArrayList<>();
+        ArrayList<NotificationRecord> notifications = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
             if (i != 0) {
-                sbn.getNotification().flags |= FLAG_AUTO_CANCEL;
+                r.getNotification().flags |= FLAG_AUTO_CANCEL;
             }
-            notifications.add(sbn);
+            notifications.add(r);
         }
 
-        for (StatusBarNotification sbn: notifications) {
-            mGroupHelper.onNotificationPosted(sbn, false);
+        for (NotificationRecord r: notifications) {
+            mGroupHelper.onNotificationPosted(r, false);
         }
 
         // Missing notification is now autocancelable
@@ -670,254 +826,327 @@
         mGroupHelper.onNotificationPosted(notifications.get(0), true);
 
         // Summary should now autocancelable
-        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(),
+        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(), anyString(),
                 eq(getNotificationAttributes(BASE_FLAGS | FLAG_AUTO_CANCEL)));
     }
 
     @Test
+    @DisableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
     public void testAutoGrouped_allAutoCancel_updateChildAppGrouped() {
         final String pkg = "package";
 
         // Post AUTOGROUP_AT_COUNT ongoing notifications
-        ArrayList<StatusBarNotification>  notifications = new ArrayList<>();
+        ArrayList<NotificationRecord> notifications = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            sbn.getNotification().flags |= FLAG_AUTO_CANCEL;
-            notifications.add(sbn);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
+            r.getNotification().flags |= FLAG_AUTO_CANCEL;
+            notifications.add(r);
         }
 
-        for (StatusBarNotification sbn: notifications) {
-            mGroupHelper.onNotificationPosted(sbn, false);
+        for (NotificationRecord r: notifications) {
+            mGroupHelper.onNotificationPosted(r, false);
         }
 
         // One notification is now grouped by app
-        StatusBarNotification sbn = getSbn(pkg, 0, "0", UserHandle.SYSTEM, "app group now");
-        mGroupHelper.onNotificationPosted(sbn, true);
+        NotificationRecord r = getNotificationRecord(pkg, 0, "0", UserHandle.SYSTEM,
+                "app group now", false);
+        mGroupHelper.onNotificationPosted(r, true);
 
         // Summary should be still be autocancelable
-        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
     }
 
     @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testAutoGrouped_allAutoCancel_updateChildAppGrouped_forceGrouping() {
+        final String pkg = "package";
+
+        // Post AUTOGROUP_AT_COUNT ongoing notifications
+        ArrayList<NotificationRecord> notifications = new ArrayList<>();
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                UserHandle.SYSTEM);
+            r.getNotification().flags |= FLAG_AUTO_CANCEL;
+            notifications.add(r);
+        }
+
+        for (NotificationRecord r: notifications) {
+            mGroupHelper.onNotificationPosted(r, false);
+        }
+
+        // One notification is now grouped by app
+        NotificationRecord r = getNotificationRecord(pkg, 0, "0", UserHandle.SYSTEM,
+            "app group now", false);
+        mGroupHelper.onNotificationPosted(r, true);
+
+        // Summary should be still be autocancelable
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+            any());
+    }
+
+    @Test
+    @DisableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
     public void testAutoGrouped_allAutoCancel_removeChild() {
         final String pkg = "package";
 
         // Post AUTOGROUP_AT_COUNT ongoing notifications
-        ArrayList<StatusBarNotification>  notifications = new ArrayList<>();
+        ArrayList<NotificationRecord> notifications = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            sbn.getNotification().flags |= FLAG_AUTO_CANCEL;
-            notifications.add(sbn);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
+            r.getNotification().flags |= FLAG_AUTO_CANCEL;
+            notifications.add(r);
         }
 
-        for (StatusBarNotification sbn: notifications) {
-            mGroupHelper.onNotificationPosted(sbn, false);
+        for (NotificationRecord r: notifications) {
+            mGroupHelper.onNotificationPosted(r, false);
         }
 
         mGroupHelper.onNotificationRemoved(notifications.get(0));
 
         // Summary should still be autocancelable
-        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testAutoGrouped_allAutoCancel_removeChild_forceGrouping() {
+        final String pkg = "package";
+
+        // Post AUTOGROUP_AT_COUNT ongoing notifications
+        ArrayList<NotificationRecord> notifications = new ArrayList<>();
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                UserHandle.SYSTEM);
+            r.getNotification().flags |= FLAG_AUTO_CANCEL;
+            notifications.add(r);
+        }
+
+        for (NotificationRecord r: notifications) {
+            mGroupHelper.onNotificationPosted(r, false);
+        }
+
+        mGroupHelper.onNotificationRemoved(notifications.get(0));
+
+        // Summary should still be autocancelable
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+            any());
     }
 
     @Test
     @DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testDropToZeroRemoveGroup_disableFlag() {
         final String pkg = "package";
-        List<StatusBarNotification> posted = new ArrayList<>();
+        ArrayList<NotificationRecord> posted = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            posted.add(sbn);
-            mGroupHelper.onNotificationPosted(sbn, false);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
+            posted.add(r);
+            mGroupHelper.onNotificationPosted(r, false);
         }
-        verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(getNotificationAttributes(BASE_FLAGS)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(), anyString(),
+                anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
         Mockito.reset(mCallback);
 
         for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
             mGroupHelper.onNotificationRemoved(posted.remove(0));
         }
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
         Mockito.reset(mCallback);
 
         mGroupHelper.onNotificationRemoved(posted.remove(0));
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString(), anyString());
     }
 
     @Test
     @EnableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testDropToZeroRemoveGroup() {
         final String pkg = "package";
-        List<StatusBarNotification> posted = new ArrayList<>();
+        ArrayList<NotificationRecord> posted = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            posted.add(sbn);
-            mGroupHelper.onNotificationPosted(sbn, false);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
+            posted.add(r);
+            mGroupHelper.onNotificationPosted(r, false);
         }
-        verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(getNotificationAttributes(BASE_FLAGS)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(), anyString(),
+                anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
         Mockito.reset(mCallback);
 
         for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
             mGroupHelper.onNotificationRemoved(posted.remove(0));
         }
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
         Mockito.reset(mCallback);
 
         mGroupHelper.onNotificationRemoved(posted.remove(0));
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString(), anyString());
     }
 
     @Test
     @DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testAppStartsGrouping_disableFlag() {
         final String pkg = "package";
-        List<StatusBarNotification> posted = new ArrayList<>();
+        ArrayList<NotificationRecord> posted = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            posted.add(sbn);
-            mGroupHelper.onNotificationPosted(sbn, false);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
+            posted.add(r);
+            mGroupHelper.onNotificationPosted(r, false);
         }
-        verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(getNotificationAttributes(BASE_FLAGS)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                anyString(), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
         Mockito.reset(mCallback);
 
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            final StatusBarNotification sbn =
-                    getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, "app group");
-            sbn.setOverrideGroupKey("autogrouped");
-            mGroupHelper.onNotificationPosted(sbn, true);
-            verify(mCallback, times(1)).removeAutoGroup(sbn.getKey());
+            final NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM, "app group", false);
+            r.getSbn().setOverrideGroupKey("autogrouped");
+            mGroupHelper.onNotificationPosted(r, true);
+            verify(mCallback, times(1)).removeAutoGroup(r.getKey());
             if (i < AUTOGROUP_AT_COUNT - 1) {
-                verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+                verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(),
+                        anyString());
             }
         }
-        verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString(), anyString());
     }
 
     @Test
     @EnableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testAppStartsGrouping() {
         final String pkg = "package";
-        List<StatusBarNotification> posted = new ArrayList<>();
+        ArrayList<NotificationRecord> posted = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            posted.add(sbn);
-            mGroupHelper.onNotificationPosted(sbn, false);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
+            posted.add(r);
+            mGroupHelper.onNotificationPosted(r, false);
         }
-        verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(getNotificationAttributes(BASE_FLAGS)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                anyString(), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
         Mockito.reset(mCallback);
 
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            final StatusBarNotification sbn =
-                    getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, "app group");
-            sbn.setOverrideGroupKey("autogrouped");
-            mGroupHelper.onNotificationPosted(sbn, true);
-            verify(mCallback, times(1)).removeAutoGroup(sbn.getKey());
+            final NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM, "app group", false);
+            r.getSbn().setOverrideGroupKey("autogrouped");
+            mGroupHelper.onNotificationPosted(r, true);
+            verify(mCallback, times(1)).removeAutoGroup(r.getKey());
             if (i < AUTOGROUP_AT_COUNT - 1) {
-                verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+                verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(),
+                        anyString());
             }
         }
-        verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString(), anyString());
     }
 
     @Test
     @DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testNewNotificationsAddedToAutogroup_ifOriginalNotificationsCanceled_alwaysGroup() {
         final String pkg = "package";
-        List<StatusBarNotification> posted = new ArrayList<>();
+        ArrayList<NotificationRecord> posted = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            posted.add(sbn);
-            mGroupHelper.onNotificationPosted(sbn, false);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                UserHandle.SYSTEM);
+            posted.add(r);
+            mGroupHelper.onNotificationPosted(r, false);
         }
-        verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(getNotificationAttributes(BASE_FLAGS)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                anyString(), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
         Mockito.reset(mCallback);
 
         for (int i = posted.size() - 2; i >= 0; i--) {
             mGroupHelper.onNotificationRemoved(posted.remove(i));
         }
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
         Mockito.reset(mCallback);
 
-        // only one child remains
-        assertEquals(1, mGroupHelper.getNotGroupedByAppCount(UserHandle.USER_SYSTEM, pkg));
-
         // Add new notification; it should be autogrouped even though the total count is
         // < AUTOGROUP_AT_COUNT
-        final StatusBarNotification sbn = getSbn(pkg, 5, String.valueOf(5), UserHandle.SYSTEM);
-        posted.add(sbn);
-        assertThat(mGroupHelper.onNotificationPosted(sbn, true)).isFalse();
-        verify(mCallback, times(1)).addAutoGroup(sbn.getKey(), true);
+        final NotificationRecord r = getNotificationRecord(pkg, 5, String.valueOf(5),
+                UserHandle.SYSTEM);
+        final String autogroupKey = getExpectedAutogroupKey(r);
+        posted.add(r);
+        assertThat(mGroupHelper.onNotificationPosted(r, true)).isFalse();
+        verify(mCallback, times(1)).addAutoGroup(r.getKey(), autogroupKey, true);
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
-        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(),
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(), anyString(),
                 eq(getNotificationAttributes(BASE_FLAGS)));
-        verify(mCallback, never()).addAutoGroupSummary(anyInt(), anyString(), anyString(), any());
+        verify(mCallback, never()).addAutoGroupSummary(anyInt(), anyString(), anyString(),
+                anyString(), anyInt(), any());
     }
 
     @Test
     @EnableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testNewNotificationsAddedToAutogroup_ifOriginalNotificationsCanceled() {
         final String pkg = "package";
-        List<StatusBarNotification> posted = new ArrayList<>();
+        ArrayList<NotificationRecord> posted = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            posted.add(sbn);
-            mGroupHelper.onNotificationPosted(sbn, false);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                UserHandle.SYSTEM);
+            posted.add(r);
+            mGroupHelper.onNotificationPosted(r, false);
         }
 
-        verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(getNotificationAttributes(BASE_FLAGS)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                anyString(), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
         Mockito.reset(mCallback);
 
         for (int i = posted.size() - 2; i >= 0; i--) {
             mGroupHelper.onNotificationRemoved(posted.remove(i));
         }
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
         Mockito.reset(mCallback);
 
-        // only one child remains
-        assertEquals(1, mGroupHelper.getNotGroupedByAppCount(UserHandle.USER_SYSTEM, pkg));
-
         // Add new notification; it should be autogrouped even though the total count is
         // < AUTOGROUP_AT_COUNT
-        final StatusBarNotification sbn = getSbn(pkg, 5, String.valueOf(5), UserHandle.SYSTEM);
-        posted.add(sbn);
-        assertThat(mGroupHelper.onNotificationPosted(sbn, true)).isTrue();
+        final NotificationRecord r = getNotificationRecord(pkg, 5, String.valueOf(5),
+                UserHandle.SYSTEM);
+        posted.add(r);
+        assertThat(mGroupHelper.onNotificationPosted(r, true)).isTrue();
         // addAutoGroup not called on sbn, because the autogrouping is expected to be done
         // synchronously.
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
-        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(),
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(), anyString(),
                 eq(getNotificationAttributes(BASE_FLAGS)));
-        verify(mCallback, never()).addAutoGroupSummary(anyInt(), anyString(), anyString(), any());
+        verify(mCallback, never()).addAutoGroupSummary(anyInt(), anyString(), anyString(),
+                anyString(), anyInt(), any());
     }
 
     @Test
@@ -929,29 +1158,32 @@
         when(icon.sameAs(icon)).thenReturn(true);
         final int iconColor = Color.BLUE;
         final NotificationAttributes attr = new NotificationAttributes(BASE_FLAGS, icon, iconColor,
-                DEFAULT_VISIBILITY);
+                DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
 
         // Add notifications with same icon and color
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
-                    icon, iconColor);
-            mGroupHelper.onNotificationPosted(sbn, false);
+            NotificationRecord r = getNotificationRecord(
+                    getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null, icon, iconColor));
+            mGroupHelper.onNotificationPosted(r, false);
         }
         // Check that the summary would have the same icon and color
         verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(attr));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+                anyInt(), eq(pkg), anyString(), anyString(), anyInt(), eq(attr));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
 
         // After auto-grouping, add new notification with the same color
-        StatusBarNotification sbn = getSbn(pkg, AUTOGROUP_AT_COUNT,
-                String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, null, icon, iconColor);
-        mGroupHelper.onNotificationPosted(sbn, true);
+        NotificationRecord r = getNotificationRecord(
+                getSbn(pkg, AUTOGROUP_AT_COUNT, String.valueOf(AUTOGROUP_AT_COUNT),
+                    UserHandle.SYSTEM,null, icon, iconColor));
+        mGroupHelper.onNotificationPosted(r, true);
 
         // Check that the summary was updated
         //NotificationAttributes newAttr = new NotificationAttributes(BASE_FLAGS, icon, iconColor);
-        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), eq(attr));
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                eq(attr));
     }
 
     @Test
@@ -963,29 +1195,31 @@
         when(icon.sameAs(icon)).thenReturn(true);
         final int iconColor = Color.BLUE;
         final NotificationAttributes attr = new NotificationAttributes(BASE_FLAGS, icon, iconColor,
-                DEFAULT_VISIBILITY);
+                DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
 
         // Add notifications with same icon and color
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
-                    icon, iconColor);
-            mGroupHelper.onNotificationPosted(sbn, false);
+            NotificationRecord r = getNotificationRecord(
+                    getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null, icon, iconColor));
+            mGroupHelper.onNotificationPosted(r, false);
         }
         // Check that the summary would have the same icon and color
-        verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(attr));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                anyString(), anyInt(), eq(attr));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
 
         // After auto-grouping, add new notification with the same color
-        StatusBarNotification sbn = getSbn(pkg, AUTOGROUP_AT_COUNT,
-                String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, null, icon, iconColor);
-        mGroupHelper.onNotificationPosted(sbn, true);
+        NotificationRecord r = getNotificationRecord(getSbn(pkg, AUTOGROUP_AT_COUNT,
+            String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, null, icon, iconColor));
+        mGroupHelper.onNotificationPosted(r, true);
 
         // Check that the summary was updated
         //NotificationAttributes newAttr = new NotificationAttributes(BASE_FLAGS, icon, iconColor);
-        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), eq(attr));
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                eq(attr));
     }
 
     @Test
@@ -1004,33 +1238,37 @@
         doReturn(monochromeIcon).when(groupHelper).getMonochromeAppIcon(eq(pkg));
 
         final NotificationAttributes initialAttr = new NotificationAttributes(BASE_FLAGS,
-                initialIcon, initialIconColor, DEFAULT_VISIBILITY);
+                initialIcon, initialIconColor, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT,
+                TEST_CHANNEL_ID);
 
         // Add notifications with same icon and color
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
-                    initialIcon, initialIconColor);
-            groupHelper.onNotificationPosted(sbn, false);
+            NotificationRecord r = getNotificationRecord(
+                getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
+                    initialIcon, initialIconColor));
+            groupHelper.onNotificationPosted(r, false);
         }
         // Check that the summary would have the same icon and color
-        verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(initialAttr));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                anyString(), anyInt(), eq(initialAttr));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
 
         // After auto-grouping, add new notification with a different color
         final Icon newIcon = mock(Icon.class);
         final int newIconColor = Color.YELLOW;
-        StatusBarNotification sbn = getSbn(pkg, AUTOGROUP_AT_COUNT,
+        NotificationRecord r = getNotificationRecord(getSbn(pkg, AUTOGROUP_AT_COUNT,
                 String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, null, newIcon,
-                newIconColor);
-        groupHelper.onNotificationPosted(sbn, true);
+                newIconColor));
+        groupHelper.onNotificationPosted(r, true);
 
         // Summary should be updated to the default color and the icon to the monochrome icon
         NotificationAttributes newAttr = new NotificationAttributes(BASE_FLAGS, monochromeIcon,
-                COLOR_DEFAULT, DEFAULT_VISIBILITY);
-        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), eq(newAttr));
+                COLOR_DEFAULT, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                eq(newAttr));
     }
 
     @Test
@@ -1049,33 +1287,37 @@
         doReturn(monochromeIcon).when(groupHelper).getMonochromeAppIcon(eq(pkg));
 
         final NotificationAttributes initialAttr = new NotificationAttributes(BASE_FLAGS,
-                initialIcon, initialIconColor, DEFAULT_VISIBILITY);
+                initialIcon, initialIconColor, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT,
+                TEST_CHANNEL_ID);
 
         // Add notifications with same icon and color
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
-                    initialIcon, initialIconColor);
-            groupHelper.onNotificationPosted(sbn, false);
+            NotificationRecord r = getNotificationRecord(
+                getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
+                    initialIcon, initialIconColor));
+            groupHelper.onNotificationPosted(r, false);
         }
         // Check that the summary would have the same icon and color
-        verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(initialAttr));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                anyString(), anyInt(), eq(initialAttr));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
 
         // After auto-grouping, add new notification with a different color
         final Icon newIcon = mock(Icon.class);
         final int newIconColor = Color.YELLOW;
-        StatusBarNotification sbn = getSbn(pkg, AUTOGROUP_AT_COUNT,
-                String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, null, newIcon,
-                newIconColor);
-        groupHelper.onNotificationPosted(sbn, true);
+        NotificationRecord r = getNotificationRecord(getSbn(pkg, AUTOGROUP_AT_COUNT,
+            String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, null, newIcon,
+            newIconColor));
+        groupHelper.onNotificationPosted(r, true);
 
         // Summary should be updated to the default color and the icon to the monochrome icon
         NotificationAttributes newAttr = new NotificationAttributes(BASE_FLAGS, monochromeIcon,
-                COLOR_DEFAULT, DEFAULT_VISIBILITY);
-        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), eq(newAttr));
+                COLOR_DEFAULT, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                eq(newAttr));
     }
 
     @Test
@@ -1087,32 +1329,35 @@
         when(icon.sameAs(icon)).thenReturn(true);
         final int iconColor = Color.BLUE;
         final NotificationAttributes attr = new NotificationAttributes(BASE_FLAGS, icon, iconColor,
-                VISIBILITY_PRIVATE);
+                VISIBILITY_PRIVATE, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
 
         // Add notifications with same icon and color and default visibility (private)
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
-                    icon, iconColor);
-            mGroupHelper.onNotificationPosted(sbn, false);
+            NotificationRecord r = getNotificationRecord(
+                getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
+                    icon, iconColor));
+            mGroupHelper.onNotificationPosted(r, false);
         }
         // Check that the summary has private visibility
         verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(attr));
+                anyInt(), eq(pkg), anyString(), anyString(), anyInt(), eq(attr));
 
-        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
 
         // After auto-grouping, add new notification with public visibility
-        StatusBarNotification sbn = getSbn(pkg, AUTOGROUP_AT_COUNT,
-                String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, null, icon, iconColor);
-        sbn.getNotification().visibility = VISIBILITY_PUBLIC;
-        mGroupHelper.onNotificationPosted(sbn, true);
+        NotificationRecord r = getNotificationRecord(getSbn(pkg, AUTOGROUP_AT_COUNT,
+            String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, null, icon, iconColor));
+        r.getNotification().visibility = VISIBILITY_PUBLIC;
+        mGroupHelper.onNotificationPosted(r, true);
 
         // Check that the summary visibility was updated
         NotificationAttributes newAttr = new NotificationAttributes(BASE_FLAGS, icon, iconColor,
-                VISIBILITY_PUBLIC);
-        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), eq(newAttr));
+                VISIBILITY_PUBLIC, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                eq(newAttr));
     }
 
     @Test
@@ -1124,71 +1369,116 @@
         when(icon.sameAs(icon)).thenReturn(true);
         final int iconColor = Color.BLUE;
         final NotificationAttributes attr = new NotificationAttributes(BASE_FLAGS, icon, iconColor,
-                VISIBILITY_PRIVATE);
+                VISIBILITY_PRIVATE, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
 
         // Add notifications with same icon and color and default visibility (private)
         for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
-                    icon, iconColor);
-            assertThat(mGroupHelper.onNotificationPosted(sbn, false)).isFalse();
+            NotificationRecord r = getNotificationRecord(
+                getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
+                    icon, iconColor));
+            assertThat(mGroupHelper.onNotificationPosted(r, false)).isFalse();
         }
         // The last notification added will reach the autogroup threshold.
-        StatusBarNotification sbn = getSbn(pkg, AUTOGROUP_AT_COUNT - 1,
-                String.valueOf(AUTOGROUP_AT_COUNT - 1), UserHandle.SYSTEM, null, icon, iconColor);
-        assertThat(mGroupHelper.onNotificationPosted(sbn, false)).isTrue();
+        NotificationRecord r = getNotificationRecord(getSbn(pkg, AUTOGROUP_AT_COUNT - 1,
+            String.valueOf(AUTOGROUP_AT_COUNT - 1), UserHandle.SYSTEM, null, icon, iconColor));
+        assertThat(mGroupHelper.onNotificationPosted(r, false)).isTrue();
 
         // Check that the summary has private visibility
-        verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(attr));
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(), anyString(),
+                anyInt(), eq(attr));
         // The last sbn is expected to be added to autogroup synchronously.
-        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
 
         // After auto-grouping, add new notification with public visibility
-        sbn = getSbn(pkg, AUTOGROUP_AT_COUNT,
-                String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, null, icon, iconColor);
-        sbn.getNotification().visibility = VISIBILITY_PUBLIC;
-        assertThat(mGroupHelper.onNotificationPosted(sbn, true)).isTrue();
+        r = getNotificationRecord(getSbn(pkg, AUTOGROUP_AT_COUNT,
+            String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, null, icon, iconColor));
+        r.getNotification().visibility = VISIBILITY_PUBLIC;
+        assertThat(mGroupHelper.onNotificationPosted(r, true)).isTrue();
 
         // Check that the summary visibility was updated
         NotificationAttributes newAttr = new NotificationAttributes(BASE_FLAGS, icon, iconColor,
-                VISIBILITY_PUBLIC);
-        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), eq(newAttr));
+                VISIBILITY_PUBLIC, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                eq(newAttr));
     }
 
     @Test
     @EnableFlags(Flags.FLAG_AUTOGROUP_SUMMARY_ICON_UPDATE)
+    @DisableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
     public void testAutoGrouped_diffIcon_diffColor_removeChild_updateTo_sameIcon_sameColor() {
         final String pkg = "package";
         final Icon initialIcon = mock(Icon.class);
         when(initialIcon.sameAs(initialIcon)).thenReturn(true);
         final int initialIconColor = Color.BLUE;
         final NotificationAttributes initialAttr = new NotificationAttributes(
-                GroupHelper.FLAG_INVALID, initialIcon, initialIconColor, DEFAULT_VISIBILITY);
+                GroupHelper.FLAG_INVALID, initialIcon, initialIconColor, DEFAULT_VISIBILITY,
+                DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
 
         // Add AUTOGROUP_AT_COUNT-1 notifications with same icon and color
-        ArrayList<StatusBarNotification> notifications = new ArrayList<>();
+        ArrayList<NotificationRecord> notifications = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
-                    initialIcon, initialIconColor);
-            notifications.add(sbn);
+            NotificationRecord r = getNotificationRecord(
+                getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
+                    initialIcon, initialIconColor));
+            notifications.add(r);
         }
         // And an additional notification with different icon and color
         final int lastIdx = AUTOGROUP_AT_COUNT - 1;
-        StatusBarNotification newSbn = getSbn(pkg, lastIdx,
+        NotificationRecord newRec = getNotificationRecord(getSbn(pkg, lastIdx,
                 String.valueOf(lastIdx), UserHandle.SYSTEM, null, mock(Icon.class),
-                Color.YELLOW);
-        notifications.add(newSbn);
-        for (StatusBarNotification sbn: notifications) {
-            mGroupHelper.onNotificationPosted(sbn, false);
+                Color.YELLOW));
+        notifications.add(newRec);
+        for (NotificationRecord r: notifications) {
+            mGroupHelper.onNotificationPosted(r, false);
         }
 
         // Remove last notification (the only one with different icon and color)
         mGroupHelper.onNotificationRemoved(notifications.get(lastIdx));
 
         // Summary should be updated to the common icon and color
-        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), eq(initialAttr));
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                eq(initialAttr));
+    }
+
+    @Test
+    @EnableFlags({Flags.FLAG_AUTOGROUP_SUMMARY_ICON_UPDATE,
+            FLAG_NOTIFICATION_FORCE_GROUPING})
+    public void testAutoGrouped_diffIcon_diffColor_removeChild_updateTo_sameIcon_sameColor_forceGrouping() {
+        final String pkg = "package";
+        final Icon initialIcon = mock(Icon.class);
+        when(initialIcon.sameAs(initialIcon)).thenReturn(true);
+        final int initialIconColor = Color.BLUE;
+        final NotificationAttributes initialAttr = new NotificationAttributes(
+            BASE_FLAGS, initialIcon, initialIconColor, DEFAULT_VISIBILITY,
+            DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
+
+        // Add AUTOGROUP_AT_COUNT-1 notifications with same icon and color
+        ArrayList<NotificationRecord> notifications = new ArrayList<>();
+        for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
+            NotificationRecord r = getNotificationRecord(
+                getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
+                    initialIcon, initialIconColor));
+            notifications.add(r);
+        }
+        // And an additional notification with different icon and color
+        final int lastIdx = AUTOGROUP_AT_COUNT - 1;
+        NotificationRecord newRec = getNotificationRecord(getSbn(pkg, lastIdx,
+            String.valueOf(lastIdx), UserHandle.SYSTEM, null, mock(Icon.class),
+            Color.YELLOW));
+        notifications.add(newRec);
+        for (NotificationRecord r: notifications) {
+            mGroupHelper.onNotificationPosted(r, false);
+        }
+
+        // Remove last notification (the only one with different icon and color)
+        mGroupHelper.onNotificationRemoved(notifications.get(lastIdx));
+
+        // Summary should be updated to the common icon and color
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+            eq(initialAttr));
     }
 
     @Test
@@ -1202,7 +1492,7 @@
         List<NotificationAttributes> childrenAttr = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
             childrenAttr.add(new NotificationAttributes(0, icon, COLOR_DEFAULT,
-                    DEFAULT_VISIBILITY));
+                    DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID));
         }
 
         //Check that the generated summary icon is the same as the child notifications'
@@ -1223,7 +1513,7 @@
         List<NotificationAttributes> childrenAttr = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
             childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), COLOR_DEFAULT,
-                    DEFAULT_VISIBILITY));
+                    DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID));
         }
 
         // Check that the generated summary icon is the monochrome icon
@@ -1240,7 +1530,7 @@
         List<NotificationAttributes> childrenAttr = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
             childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), iconColor,
-                    DEFAULT_VISIBILITY));
+                    DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID));
         }
 
         // Check that the generated summary icon color is the same as the child notifications'
@@ -1257,7 +1547,7 @@
         List<NotificationAttributes> childrenAttr = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
             childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), i,
-                    DEFAULT_VISIBILITY));
+                    DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID));
         }
 
         // Check that the generated summary icon color is the default color
@@ -1274,10 +1564,10 @@
         // Create notifications with private and public visibility
         List<NotificationAttributes> childrenAttr = new ArrayList<>();
         childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), iconColor,
-                VISIBILITY_PUBLIC));
+                VISIBILITY_PUBLIC, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID));
         for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
             childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), iconColor,
-                    VISIBILITY_PRIVATE));
+                    VISIBILITY_PRIVATE, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID));
         }
 
         // Check that the generated summary visibility is public
@@ -1301,7 +1591,7 @@
                 visibility = VISIBILITY_SECRET;
             }
             childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), iconColor,
-                    visibility));
+                    visibility, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID));
         }
 
         // Check that the generated summary visibility is private
@@ -1311,6 +1601,90 @@
     }
 
     @Test
+    public void testAutobundledSummaryAlertBehavior_oneChildAlertChildren() {
+        final String pkg = "package";
+        final int iconColor = Color.BLUE;
+        // Create notifications with GROUP_ALERT_SUMMARY + one with GROUP_ALERT_CHILDREN
+        List<NotificationAttributes> childrenAttr = new ArrayList<>();
+        childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), iconColor,
+                VISIBILITY_PUBLIC, GROUP_ALERT_CHILDREN, TEST_CHANNEL_ID));
+        for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
+            childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), iconColor,
+                VISIBILITY_PRIVATE, GROUP_ALERT_SUMMARY, TEST_CHANNEL_ID));
+        }
+        // Check that the generated summary alert behavior is GROUP_ALERT_CHILDREN
+        int groupAlertBehavior = mGroupHelper.getAutobundledSummaryAttributes(pkg,
+                childrenAttr).groupAlertBehavior;
+        assertThat(groupAlertBehavior).isEqualTo(GROUP_ALERT_CHILDREN);
+    }
+
+    @Test
+    public void testAutobundledSummaryAlertBehavior_oneChildAlertAll() {
+        final String pkg = "package";
+        final int iconColor = Color.BLUE;
+        // Create notifications with GROUP_ALERT_SUMMARY + one with GROUP_ALERT_ALL
+        List<NotificationAttributes> childrenAttr = new ArrayList<>();
+        childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), iconColor,
+                VISIBILITY_PUBLIC, GROUP_ALERT_ALL, TEST_CHANNEL_ID));
+        for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
+            childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), iconColor,
+                VISIBILITY_PRIVATE, GROUP_ALERT_SUMMARY, TEST_CHANNEL_ID));
+        }
+        // Check that the generated summary alert behavior is GROUP_ALERT_CHILDREN
+        int groupAlertBehavior = mGroupHelper.getAutobundledSummaryAttributes(pkg,
+                childrenAttr).groupAlertBehavior;
+        assertThat(groupAlertBehavior).isEqualTo(GROUP_ALERT_CHILDREN);
+    }
+
+    @Test
+    public void testAutobundledSummaryAlertBehavior_allChildAlertSummary() {
+        final String pkg = "package";
+        final int iconColor = Color.BLUE;
+        // Create notifications with GROUP_ALERT_SUMMARY
+        List<NotificationAttributes> childrenAttr = new ArrayList<>();
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), iconColor,
+                VISIBILITY_PRIVATE, GROUP_ALERT_SUMMARY, TEST_CHANNEL_ID));
+        }
+
+        // Check that the generated summary alert behavior is GROUP_ALERT_SUMMARY
+        int groupAlertBehavior = mGroupHelper.getAutobundledSummaryAttributes(pkg,
+                childrenAttr).groupAlertBehavior;
+        assertThat(groupAlertBehavior).isEqualTo(GROUP_ALERT_SUMMARY);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_AUTOGROUP_SUMMARY_ICON_UPDATE)
+    public void testAutobundledSummaryChannelId() {
+        final String pkg = "package";
+        final int iconColor = Color.BLUE;
+        final String expectedChannelId = TEST_CHANNEL_ID + "0";
+        // Create notifications with different channelIds
+        List<NotificationAttributes> childrenAttr = new ArrayList<>();
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), iconColor,
+                    DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID+i));
+        }
+
+        // Check that the generated summary channelId is the first child in the list
+        String summaryChannelId = mGroupHelper.getAutobundledSummaryAttributes(pkg,
+                childrenAttr).channelId;
+        assertThat(summaryChannelId).isEqualTo(expectedChannelId);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_AUTOGROUP_SUMMARY_ICON_UPDATE)
+    public void testAutobundledSummaryChannelId_noChildren() {
+        final String pkg = "package";
+        // No child notifications
+        List<NotificationAttributes> childrenAttr = new ArrayList<>();
+        // Check that the generated summary channelId is null
+        String summaryChannelId = mGroupHelper.getAutobundledSummaryAttributes(pkg,
+                childrenAttr).channelId;
+        assertThat(summaryChannelId).isNull();
+    }
+
+    @Test
     @EnableFlags(Flags.FLAG_AUTOGROUP_SUMMARY_ICON_UPDATE)
     public void testMonochromeAppIcon_adaptiveIconExists() throws Exception {
         final String pkg = "testPackage";
@@ -1333,4 +1707,855 @@
         assertThat(mGroupHelper.getMonochromeAppIcon(pkg).getResId())
                 .isEqualTo(fallbackIconResId);
     }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testGetAggregateGroupKey() {
+        final String fullAggregateGroupKey = GroupHelper.getFullAggregateGroupKey("pkg",
+                "groupKey", 1234);
+        assertThat(fullAggregateGroupKey).isEqualTo("1234|pkg|g:groupKey");
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testNoGroup_postingUnderLimit_forcedGrouping() {
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        final String pkg = "package";
+        for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM, "testGrp " + i, true);
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        verifyZeroInteractions(mCallback);
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testNoGroup_AutobundledAlready_forcedGrouping() {
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        final String pkg = "package";
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM, null, true);
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        verifyZeroInteractions(mCallback);
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testNoGroup_isCanceled_forcedGrouping() {
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        final String pkg = "package";
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM, "testGrp" + i, true);
+            r.isCanceled = true;
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        verifyZeroInteractions(mCallback);
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testNoGroup_isAggregated_forcedGrouping() {
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        final String pkg = "package";
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            String aggregateGroupKey = AGGREGATE_GROUP_KEY + "AlertingSection";
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM, aggregateGroupKey, true);
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        verifyZeroInteractions(mCallback);
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testNoGroup_multiPackage_forcedGrouping() {
+        final String pkg = "package";
+        final String pkg2 = "package2";
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM, "testGrp " + i, true);
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        NotificationRecord r = getNotificationRecord(pkg2, AUTOGROUP_AT_COUNT,
+                String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, "testGrp", true);
+        notificationList.add(r);
+        mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        verifyZeroInteractions(mCallback);
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testNoGroup_multiUser_forcedGrouping() {
+        final String pkg = "package";
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM, "testGrp " + i, true);
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        NotificationRecord r = getNotificationRecord(pkg, AUTOGROUP_AT_COUNT,
+                String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.of(7), "testGrp", true);
+        notificationList.add(r);
+        mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        verifyZeroInteractions(mCallback);
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testNoGroup_summaryWithChildren_forcedGrouping() {
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        final String pkg = "package";
+        for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                UserHandle.SYSTEM, "testGrp " + i, true);
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        // Next posted summary has 1 child => no forced grouping
+        NotificationRecord summary = getNotificationRecord(pkg, AUTOGROUP_AT_COUNT,
+            String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, "testGrp", true);
+        notificationList.add(summary);
+        NotificationRecord child = getNotificationRecord(pkg, AUTOGROUP_AT_COUNT + 1,
+            String.valueOf(AUTOGROUP_AT_COUNT + 1), UserHandle.SYSTEM, "testGrp", false);
+        notificationList.add(child);
+        mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+        verifyZeroInteractions(mCallback);
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testNoGroup_groupWithSummary_forcedGrouping() {
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        final String pkg = "package";
+        for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                UserHandle.SYSTEM, "testGrp " + i, true);
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        // Next posted notification has summary => no forced grouping
+        NotificationRecord summary = getNotificationRecord(pkg, AUTOGROUP_AT_COUNT,
+            String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, "testGrp", true);
+        notificationList.add(summary);
+        NotificationRecord child = getNotificationRecord(pkg, AUTOGROUP_AT_COUNT + 1,
+            String.valueOf(AUTOGROUP_AT_COUNT + 1), UserHandle.SYSTEM, "testGrp", false);
+        notificationList.add(child);
+        summaryByGroup.put(summary.getGroupKey(), summary);
+        mGroupHelper.onNotificationPostedWithDelay(child, notificationList, summaryByGroup);
+        verifyZeroInteractions(mCallback);
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testAddAggregateSummary_summaryNoChildren() {
+        final String pkg = "package";
+        final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+                AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        // Post group summaries without children => force autogroup
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                UserHandle.SYSTEM, "testGrp " + i, true);
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+            eq(expectedGroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+            eq(expectedGroupKey), eq(true));
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+            any());
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testAddAggregateSummary_childrenNoSummary() {
+        final String pkg = "package";
+        final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+                AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        // Post group notifications without summaries => force autogroup
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                UserHandle.SYSTEM, "testGrp " + i, false);
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(expectedGroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+                eq(expectedGroupKey), eq(true));
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testAddAggregateSummary_multipleSections() {
+        final String pkg = "package";
+        final String expectedGroupKey_alerting = GroupHelper.getFullAggregateGroupKey(pkg,
+            AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+        final String expectedGroupKey_silent = GroupHelper.getFullAggregateGroupKey(pkg,
+            AGGREGATE_GROUP_KEY + "SilentSection", UserHandle.SYSTEM.getIdentifier());
+
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        // Post notifications with different importance values => force group into separate sections
+        NotificationRecord r;
+        for (int i = 0; i < 2 * AUTOGROUP_AT_COUNT; i++) {
+            if (i % 2 == 0) {
+                r = getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM,
+                    "testGrp " + i, true, IMPORTANCE_DEFAULT);
+            } else {
+                r = getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM,
+                    "testGrp " + i, false, IMPORTANCE_LOW);
+            }
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+            eq(expectedGroupKey_alerting), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+            eq(expectedGroupKey_silent), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+                eq(expectedGroupKey_alerting), eq(true));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+            eq(expectedGroupKey_silent), eq(true));
+
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+    }
+
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    @DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
+    public void testAddAggregateSummary_mixUngroupedAndAbusive_alwaysAutogroup() {
+        final String pkg = "package";
+        final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+            AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+        // Post ungrouped notifications => create autogroup
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            mGroupHelper.onNotificationPosted(
+                getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false);
+        }
+        verify(mCallback, times(1)).addAutoGroupSummary(
+                anyInt(), eq(pkg), anyString(), eq(expectedGroupKey),
+                anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), eq(expectedGroupKey),
+                anyBoolean());
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
+
+        reset(mCallback);
+
+        // Post group notifications without summaries => add to autogroup
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        final int id = AUTOGROUP_AT_COUNT;
+        NotificationRecord r = getNotificationRecord(pkg, id, String.valueOf(id),
+                UserHandle.SYSTEM, "testGrp " + id, false);
+        notificationList.add(r);
+        mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+
+        // Check that the new notification was added
+        verify(mCallback, times(1)).addAutoGroup(eq(r.getKey()),
+                eq(expectedGroupKey), eq(true));
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), eq(pkg),
+                eq(expectedGroupKey), any());
+        verify(mCallback, never()).addAutoGroupSummary(anyInt(), anyString(), anyString(),
+                anyString(), anyInt(), any());
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    @DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
+    public void testUpdateAggregateSummary_postUngroupedAfterForcedGrouping_alwaysAutogroup() {
+        final String pkg = "package";
+        final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+            AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        // Post group notifications without summaries => force autogroup
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                UserHandle.SYSTEM, "testGrp " + i, false);
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+            eq(expectedGroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+            eq(expectedGroupKey), eq(true));
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+            any());
+
+        reset(mCallback);
+
+        // Post ungrouped notification => update autogroup
+        final int id = AUTOGROUP_AT_COUNT;
+        NotificationRecord r = getNotificationRecord(pkg, id, String.valueOf(id),
+                UserHandle.SYSTEM);
+        mGroupHelper.onNotificationPosted(r, true);
+
+        verify(mCallback, times(1)).addAutoGroup(eq(r.getKey()),
+                eq(expectedGroupKey), eq(true));
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), eq(pkg),
+                eq(expectedGroupKey), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, never()).addAutoGroupSummary(anyInt(), anyString(), anyString(),
+                anyString(), anyInt(), any());
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+    }
+
+    @Test
+    @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+            android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST})
+    public void testUpdateAggregateSummary_postUngroupedAfterForcedGrouping() {
+        final String pkg = "package";
+        final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+            AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        // Post group notifications without summaries => force autogroup
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                UserHandle.SYSTEM, "testGrp " + i, false);
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+            eq(expectedGroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+            eq(expectedGroupKey), eq(true));
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+            any());
+
+        reset(mCallback);
+
+        // Post ungrouped notification => update autogroup
+        final int id = AUTOGROUP_AT_COUNT;
+        NotificationRecord r = getNotificationRecord(pkg, id, String.valueOf(id),
+            UserHandle.SYSTEM);
+        mGroupHelper.onNotificationPosted(r, true);
+
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), eq(pkg),
+            eq(expectedGroupKey), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, never()).addAutoGroup(anyString(), anyString(), anyBoolean());
+        verify(mCallback, never()).addAutoGroupSummary(anyInt(), anyString(), anyString(),
+            anyString(), anyInt(), any());
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testUpdateAggregateSummary_postAfterForcedGrouping() {
+        final String pkg = "package";
+        final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+            AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        // Post group notifications w/o summaries and summaries w/o children => force autogrouping
+        NotificationRecord r;
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            if (i % 2 == 0) {
+                r = getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM,
+                    "testGrp " + i, true);
+            } else {
+                r = getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM,
+                    "testGrp " + i, false);
+            }
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+
+        // Post another notification after forced grouping
+        final Icon icon = mock(Icon.class);
+        when(icon.sameAs(icon)).thenReturn(true);
+        final int iconColor = Color.BLUE;
+        r = getNotificationRecord(
+                getSbn(pkg, AUTOGROUP_AT_COUNT, String.valueOf(AUTOGROUP_AT_COUNT),
+                    UserHandle.SYSTEM, "testGrp " + AUTOGROUP_AT_COUNT, icon, iconColor));
+
+        notificationList.add(r);
+        mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+            eq(expectedGroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT + 1)).addAutoGroup(anyString(),
+            eq(expectedGroupKey), eq(true));
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), eq(pkg),
+            eq(expectedGroupKey), any());
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testRemoveAggregateSummary_removeAllNotifications() {
+        final String pkg = "package";
+        final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+            AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        // Post group notifications without summaries => force autogroup
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                UserHandle.SYSTEM, "testGrp " + i, false);
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(expectedGroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+                eq(expectedGroupKey), eq(true));
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
+        Mockito.reset(mCallback);
+
+        // Remove all posted notifications
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM, "testGrp " + i, false);
+            r.setOverrideGroupKey(expectedGroupKey);
+            mGroupHelper.onNotificationRemoved(r, notificationList);
+        }
+        // Check that the autogroup summary is removed
+        verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), eq(pkg),
+                eq(expectedGroupKey));
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testMoveAggregateGroups_updateChannel() {
+        final String pkg = "package";
+        final String expectedGroupKey_alerting = GroupHelper.getFullAggregateGroupKey(pkg,
+            AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+        final NotificationChannel channel = new NotificationChannel(TEST_CHANNEL_ID,
+                TEST_CHANNEL_ID, IMPORTANCE_DEFAULT);
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        // Post group notifications without summaries => force autogroup
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM, "testGrp " + i, false, channel);
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(expectedGroupKey_alerting), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+                eq(expectedGroupKey_alerting), eq(true));
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+            any());
+        Mockito.reset(mCallback);
+
+        // Update the channel importance for all posted notifications
+        final String expectedGroupKey_silent = GroupHelper.getFullAggregateGroupKey(pkg,
+            AGGREGATE_GROUP_KEY + "SilentSection", UserHandle.SYSTEM.getIdentifier());
+        channel.setImportance(IMPORTANCE_LOW);
+        for (NotificationRecord r: notificationList) {
+            r.updateNotificationChannel(channel);
+        }
+        mGroupHelper.onChannelUpdated(UserHandle.SYSTEM.getIdentifier(), pkg, channel,
+                notificationList);
+
+        // Check that all notifications are moved to the silent section group
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(expectedGroupKey_silent), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+                eq(expectedGroupKey_silent), eq(false));
+
+        // Check that the alerting section group is removed
+        verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), eq(pkg),
+                eq(expectedGroupKey_alerting));
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testMoveAggregateGroups_updateChannel_multipleChannels() {
+        final String pkg = "package";
+        final String expectedGroupKey_alerting = GroupHelper.getFullAggregateGroupKey(pkg,
+            AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+        final NotificationChannel channel1 = new NotificationChannel("TEST_CHANNEL_ID1",
+            "TEST_CHANNEL_ID1", IMPORTANCE_DEFAULT);
+        final NotificationChannel channel2 = new NotificationChannel("TEST_CHANNEL_ID2",
+            "TEST_CHANNEL_ID2", IMPORTANCE_DEFAULT);
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        // Post notifications with different channels that autogroup within the same section
+        NotificationRecord r;
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            if (i % 2 == 0) {
+                r = getNotificationRecord(pkg, i, String.valueOf(i),
+                        UserHandle.SYSTEM, "testGrp " + i, false, channel1);
+            } else {
+                r = getNotificationRecord(pkg, i, String.valueOf(i),
+                        UserHandle.SYSTEM, "testGrp " + i, false, channel2);
+            }
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        NotificationAttributes expectedSummaryAttr = new NotificationAttributes(BASE_FLAGS,
+                mSmallIcon, COLOR_DEFAULT, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT,
+                "TEST_CHANNEL_ID1");
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(expectedGroupKey_alerting), anyInt(), eq(expectedSummaryAttr));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+                eq(expectedGroupKey_alerting), eq(true));
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
+        Mockito.reset(mCallback);
+
+        // Update channel1's importance
+        final String expectedGroupKey_silent = GroupHelper.getFullAggregateGroupKey(pkg,
+            AGGREGATE_GROUP_KEY + "SilentSection", UserHandle.SYSTEM.getIdentifier());
+        channel1.setImportance(IMPORTANCE_LOW);
+        for (NotificationRecord record: notificationList) {
+            if (record.getChannel().getId().equals(channel1.getId())) {
+                record.updateNotificationChannel(channel1);
+            }
+        }
+        mGroupHelper.onChannelUpdated(UserHandle.SYSTEM.getIdentifier(), pkg, channel1,
+                notificationList);
+
+        // Check that channel1's notifications are moved to the silent section group
+        expectedSummaryAttr = new NotificationAttributes(BASE_FLAGS,
+                mSmallIcon, COLOR_DEFAULT, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT,
+                "TEST_CHANNEL_ID1");
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(expectedGroupKey_silent), anyInt(), eq(expectedSummaryAttr));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT/2 + 1)).addAutoGroup(anyString(),
+                eq(expectedGroupKey_silent), eq(false));
+
+        // Check that the alerting section group is not removed, only updated
+        expectedSummaryAttr = new NotificationAttributes(BASE_FLAGS,
+            mSmallIcon, COLOR_DEFAULT, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT,
+            "TEST_CHANNEL_ID2");
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), eq(pkg),
+                eq(expectedGroupKey_alerting));
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), eq(pkg),
+                eq(expectedGroupKey_alerting), eq(expectedSummaryAttr));
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testMoveAggregateGroups_updateChannel_groupsUngrouped() {
+        final String pkg = "package";
+        final String expectedGroupKey_silent = GroupHelper.getFullAggregateGroupKey(pkg,
+            AGGREGATE_GROUP_KEY + "SilentSection", UserHandle.SYSTEM.getIdentifier());
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+
+        // Post too few group notifications without summaries => do not autogroup
+        final NotificationChannel lowPrioChannel = new NotificationChannel("TEST_CHANNEL_LOW_ID",
+                "TEST_CHANNEL_LOW_ID", IMPORTANCE_LOW);
+        final int numUngrouped = AUTOGROUP_AT_COUNT - 1;
+        int startIdx = 42;
+        for (int i = startIdx; i < startIdx + numUngrouped; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM, "testGrp " + i, false, lowPrioChannel);
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        verify(mCallback, never()).addAutoGroup(anyString(), anyString(), anyBoolean());
+        verify(mCallback, never()).addAutoGroupSummary(anyInt(), anyString(), anyString(),
+                anyString(), anyInt(), any());
+
+        reset(mCallback);
+
+        final String expectedGroupKey_alerting = GroupHelper.getFullAggregateGroupKey(pkg,
+            AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+        final NotificationChannel channel = new NotificationChannel(TEST_CHANNEL_ID,
+                TEST_CHANNEL_ID, IMPORTANCE_DEFAULT);
+
+        // Post group notifications without summaries => force autogroup
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM, "testGrp " + i, false, channel);
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(expectedGroupKey_alerting), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+                eq(expectedGroupKey_alerting), eq(true));
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
+        Mockito.reset(mCallback);
+
+        // Update the channel importance for all posted notifications
+        final int numSilentGroupNotifications = AUTOGROUP_AT_COUNT + numUngrouped;
+        channel.setImportance(IMPORTANCE_LOW);
+        for (NotificationRecord r: notificationList) {
+            r.updateNotificationChannel(channel);
+        }
+        mGroupHelper.onChannelUpdated(UserHandle.SYSTEM.getIdentifier(), pkg, channel,
+                notificationList);
+
+        // Check that all notifications are moved to the silent section group
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(expectedGroupKey_silent), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(numSilentGroupNotifications)).addAutoGroup(anyString(),
+                eq(expectedGroupKey_silent), eq(false));
+
+        // Check that the alerting section group is removed
+        verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), eq(pkg),
+                eq(expectedGroupKey_alerting));
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
+    }
+
+    @Test
+    @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+            Flags.FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS})
+    public void testNoGroup_singletonGroup_underLimit() {
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        final String pkg = "package";
+        // Post singleton groups, under forced group limit
+        for (int i = 0; i < AUTOGROUP_SINGLETONS_AT_COUNT - 1; i++) {
+            NotificationRecord summary = getNotificationRecord(pkg, i,
+                    String.valueOf(i), UserHandle.SYSTEM, "testGrp "+i, true);
+            notificationList.add(summary);
+            NotificationRecord child = getNotificationRecord(pkg, i + 42,
+                    String.valueOf(i + 42), UserHandle.SYSTEM, "testGrp "+i, false);
+            notificationList.add(child);
+            summaryByGroup.put(summary.getGroupKey(), summary);
+            mGroupHelper.onNotificationPostedWithDelay(child, notificationList, summaryByGroup);
+            mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+        }
+        verifyZeroInteractions(mCallback);
+    }
+
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    @DisableFlags(Flags.FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS)
+    public void testAddAggregateSummary_singletonGroup_disableFlag() {
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        final String pkg = "package";
+        // Post singleton groups, above forced group limit
+        for (int i = 0; i < AUTOGROUP_SINGLETONS_AT_COUNT; i++) {
+            NotificationRecord summary = getNotificationRecord(pkg, i,
+                    String.valueOf(i), UserHandle.SYSTEM, "testGrp "+i, true);
+            notificationList.add(summary);
+            NotificationRecord child = getNotificationRecord(pkg, i + 42,
+                    String.valueOf(i + 42), UserHandle.SYSTEM, "testGrp "+i, false);
+            notificationList.add(child);
+            summaryByGroup.put(summary.getGroupKey(), summary);
+            mGroupHelper.onNotificationPostedWithDelay(child, notificationList, summaryByGroup);
+            mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+        }
+        // FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS is disabled => don't force group
+        verifyZeroInteractions(mCallback);
+    }
+
+    @Test
+    @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+            Flags.FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS})
+    public void testAddAggregateSummary_singletonGroups() {
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        final String pkg = "package";
+        final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+            AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+        // Post singleton groups, above forced group limit
+        for (int i = 0; i < AUTOGROUP_SINGLETONS_AT_COUNT; i++) {
+            NotificationRecord summary = getNotificationRecord(pkg, i,
+                String.valueOf(i), UserHandle.SYSTEM, "testGrp "+i, true);
+            notificationList.add(summary);
+            NotificationRecord child = getNotificationRecord(pkg, i + 42,
+                String.valueOf(i + 42), UserHandle.SYSTEM, "testGrp "+i, false);
+            notificationList.add(child);
+            summaryByGroup.put(summary.getGroupKey(), summary);
+            mGroupHelper.onNotificationPostedWithDelay(child, notificationList, summaryByGroup);
+            summary.isCanceled = true;  // simulate removing the app summary
+            mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+
+        }
+        // Check that notifications are forced grouped
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(expectedGroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_SINGLETONS_AT_COUNT)).addAutoGroup(anyString(),
+                eq(expectedGroupKey), eq(true));
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
+
+        // Check that summaries are canceled
+        verify(mCallback, times(AUTOGROUP_SINGLETONS_AT_COUNT)).removeAppProvidedSummary(anyString());
+    }
+
+    @Test
+    @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+            Flags.FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS})
+    public void testCancelCachedSummary_singletonGroups() {
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        final String pkg = "package";
+        final int id = 0;
+        // Post singleton groups, above forced group limit
+        for (int i = 0; i < AUTOGROUP_SINGLETONS_AT_COUNT; i++) {
+            NotificationRecord summary = getNotificationRecord(pkg, i,
+                    String.valueOf(i), UserHandle.SYSTEM, "testGrp "+i, true);
+            notificationList.add(summary);
+            NotificationRecord child = getNotificationRecord(pkg, i + 42,
+                    String.valueOf(i + 42), UserHandle.SYSTEM, "testGrp "+i, false);
+            notificationList.add(child);
+            summaryByGroup.put(summary.getGroupKey(), summary);
+            mGroupHelper.onNotificationPostedWithDelay(child, notificationList, summaryByGroup);
+            summary.isCanceled = true;  // simulate removing the app summary
+            mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+        }
+        Mockito.reset(mCallback);
+
+        // App cancels the summary of an aggregated group
+        mGroupHelper.maybeCancelGroupChildrenForCanceledSummary(pkg, String.valueOf(id), id,
+                UserHandle.SYSTEM.getIdentifier(), REASON_APP_CANCEL);
+
+        verify(mCallback, times(1)).removeNotificationFromCanceledGroup(
+                eq(UserHandle.SYSTEM.getIdentifier()), eq(pkg), eq("testGrp " + id),
+                eq(REASON_APP_CANCEL));
+        CachedSummary cachedSummary = mGroupHelper.findCanceledSummary(pkg, String.valueOf(id), id,
+                UserHandle.SYSTEM.getIdentifier());
+        assertThat(cachedSummary).isNull();
+    }
+
+    @Test
+    @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+            Flags.FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS})
+    public void testRemoveCachedSummary_singletonGroups_removeChildren() {
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        final String pkg = "package";
+        final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+            AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+        final int id = 0;
+        NotificationRecord childToRemove = null;
+        // Post singleton groups, above forced group limit
+        for (int i = 0; i < AUTOGROUP_SINGLETONS_AT_COUNT; i++) {
+            NotificationRecord summary = getNotificationRecord(pkg, i,
+                    String.valueOf(i), UserHandle.SYSTEM, "testGrp "+i, true);
+            notificationList.add(summary);
+            NotificationRecord child = getNotificationRecord(pkg, i + 42, String.valueOf(i + 42),
+                    UserHandle.SYSTEM, "testGrp " + i, false);
+            if (i == id) {
+                childToRemove = child;
+            }
+            notificationList.add(child);
+            summaryByGroup.put(summary.getGroupKey(), summary);
+            mGroupHelper.onNotificationPostedWithDelay(child, notificationList, summaryByGroup);
+            summary.isCanceled = true;  // simulate removing the app summary
+            mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+        }
+        // override group key for child notifications
+        List<NotificationRecord> notificationListAfterGrouping = new ArrayList<>(
+            notificationList.stream().filter(r -> {
+                if (r.getSbn().getNotification().isGroupChild()) {
+                    r.setOverrideGroupKey(expectedGroupKey);
+                    return true;
+                } else {
+                    return false;
+                }
+            }).toList());
+        summaryByGroup.clear();
+        Mockito.reset(mCallback);
+
+        //Cancel child 0 => remove cached summary
+        childToRemove.isCanceled = true;
+        notificationListAfterGrouping.remove(childToRemove);
+        mGroupHelper.onNotificationRemoved(childToRemove, notificationListAfterGrouping);
+        CachedSummary cachedSummary = mGroupHelper.findCanceledSummary(pkg, String.valueOf(id), id,
+                UserHandle.SYSTEM.getIdentifier());
+        assertThat(cachedSummary).isNull();
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testGroupSectioners() {
+        final NotificationRecord notification_alerting = getNotificationRecord(mPkg, 0, "", mUser,
+            "", false, IMPORTANCE_DEFAULT);
+        assertThat(GroupHelper.getSection(notification_alerting).mName).isEqualTo("AlertingSection");
+
+        final NotificationRecord notification_silent = getNotificationRecord(mPkg, 0, "", mUser,
+            "", false, IMPORTANCE_LOW);
+        assertThat(GroupHelper.getSection(notification_silent).mName).isEqualTo("SilentSection");
+
+        NotificationRecord notification_conversation = mock(NotificationRecord.class);
+        when(notification_conversation.isConversation()).thenReturn(true);
+        assertThat(GroupHelper.getSection(notification_conversation)).isNull();
+
+        NotificationRecord notification_call = spy(getNotificationRecord(mPkg, 0, "", mUser,
+                "", false, IMPORTANCE_LOW));
+        Notification n = mock(Notification.class);
+        StatusBarNotification sbn = spy(getSbn("package", 0, "0", UserHandle.SYSTEM));
+        when(notification_call.isConversation()).thenReturn(false);
+        when(notification_call.getNotification()).thenReturn(n);
+        when(notification_call.getSbn()).thenReturn(sbn);
+        when(sbn.getNotification()).thenReturn(n);
+        when(n.isStyle(Notification.CallStyle.class)).thenReturn(true);
+        assertThat(GroupHelper.getSection(notification_call)).isNull();
+
+        NotificationRecord notification_colorFg = spy(getNotificationRecord(mPkg, 0, "", mUser,
+            "", false, IMPORTANCE_LOW));
+        sbn = spy(getSbn("package", 0, "0", UserHandle.SYSTEM));
+        n = mock(Notification.class);
+        when(notification_colorFg.isConversation()).thenReturn(false);
+        when(notification_colorFg.getNotification()).thenReturn(n);
+        when(notification_colorFg.getSbn()).thenReturn(sbn);
+        when(sbn.getNotification()).thenReturn(n);
+        when(n.isForegroundService()).thenReturn(true);
+        when(n.isColorized()).thenReturn(true);
+        when(n.isStyle(Notification.CallStyle.class)).thenReturn(false);
+        assertThat(GroupHelper.getSection(notification_colorFg)).isNull();
+    }
+
 }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index c48d745..5d306e1 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -39,8 +39,10 @@
 import static android.app.Notification.FLAG_ONGOING_EVENT;
 import static android.app.Notification.FLAG_ONLY_ALERT_ONCE;
 import static android.app.Notification.FLAG_USER_INITIATED_JOB;
+import static android.app.Notification.GROUP_ALERT_CHILDREN;
 import static android.app.Notification.VISIBILITY_PRIVATE;
 import static android.app.NotificationChannel.NEWS_ID;
+import static android.app.NotificationChannel.DEFAULT_CHANNEL_ID;
 import static android.app.NotificationChannel.USER_LOCKED_ALLOW_BUBBLE;
 import static android.app.NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED;
 import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL;
@@ -98,11 +100,13 @@
 import static android.service.notification.Condition.SOURCE_CONTEXT;
 import static android.service.notification.Condition.SOURCE_USER_ACTION;
 import static android.service.notification.Condition.STATE_TRUE;
+import static android.service.notification.Flags.FLAG_NOTIFICATION_FORCE_GROUPING;
 import static android.service.notification.Flags.FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS;
 import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ALERTING;
 import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_CONVERSATIONS;
 import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ONGOING;
 import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_EFFECTS;
+import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL;
 import static android.service.notification.NotificationListenerService.REASON_CANCEL;
 import static android.service.notification.NotificationListenerService.REASON_LOCKDOWN;
 import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
@@ -117,6 +121,7 @@
 import static com.android.server.am.PendingIntentRecord.FLAG_SERVICE_SENDER;
 import static com.android.server.notification.Flags.FLAG_ALL_NOTIFS_NEED_TTL;
 import static com.android.server.notification.Flags.FLAG_REJECT_OLD_NOTIFICATIONS;
+import static com.android.server.notification.GroupHelper.AUTOGROUP_KEY;
 import static com.android.server.notification.NotificationManagerService.BITMAP_DURATION;
 import static com.android.server.notification.NotificationManagerService.DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE;
 import static com.android.server.notification.NotificationManagerService.NOTIFICATION_TTL;
@@ -369,6 +374,7 @@
     private static final int TOAST_DURATION = 2_000;
     private static final int SECONDARY_DISPLAY_ID = 42;
     private static final int TEST_PROFILE_USERHANDLE = 12;
+    private static final long DELAY_FORCE_REGROUP_TIME = 3000;
 
     private static final String ACTION_NOTIFICATION_TIMEOUT =
             NotificationManagerService.class.getSimpleName() + ".TIMEOUT";
@@ -2487,43 +2493,372 @@
     }
 
     @Test
+    @DisableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
     public void testAutobundledSummary_notificationAdded() {
         NotificationRecord summary =
-                generateNotificationRecord(mTestNotificationChannel, 0, "pkg", true);
+                generateNotificationRecord(mTestNotificationChannel, 0, AUTOGROUP_KEY, true);
         summary.getNotification().flags |= Notification.FLAG_AUTOGROUP_SUMMARY;
         mService.addNotification(summary);
         mService.mSummaryByGroupKey.put("pkg", summary);
         mService.mAutobundledSummaries.put(0, new ArrayMap<>());
         mService.mAutobundledSummaries.get(0).put("pkg", summary.getKey());
 
-        mService.updateAutobundledSummaryLocked(0, "pkg",
+        mService.updateAutobundledSummaryLocked(0, "pkg", AUTOGROUP_KEY,
                 new NotificationAttributes(GroupHelper.BASE_FLAGS | FLAG_ONGOING_EVENT,
-                    mock(Icon.class), 0, VISIBILITY_PRIVATE), false);
+                    mock(Icon.class), 0,
+                    VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN, DEFAULT_CHANNEL_ID), false);
         waitForIdle();
 
         assertTrue(summary.getSbn().isOngoing());
     }
 
     @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testAutobundledSummary_notificationAdded_forcedGrouping() {
+        NotificationRecord summary =
+                generateNotificationRecord(mTestNotificationChannel, 0, AUTOGROUP_KEY, true);
+        summary.getNotification().flags |= Notification.FLAG_AUTOGROUP_SUMMARY;
+        mService.addNotification(summary);
+        mService.mSummaryByGroupKey.put("pkg", summary);
+        mService.mAutobundledSummaries.put(0, new ArrayMap<>());
+        mService.mAutobundledSummaries.get(0).put(summary.getGroupKey(), summary.getKey());
+
+        mService.updateAutobundledSummaryLocked(0, "pkg", summary.getGroupKey(),
+                new NotificationAttributes(GroupHelper.BASE_FLAGS | FLAG_ONGOING_EVENT,
+                    mock(Icon.class), 0,
+                    VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN, DEFAULT_CHANNEL_ID), false);
+        waitForIdle();
+
+        assertTrue(summary.getSbn().isOngoing());
+    }
+
+    @Test
+    @DisableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
     public void testAutobundledSummary_notificationRemoved() {
         NotificationRecord summary =
-                generateNotificationRecord(mTestNotificationChannel, 0, "pkg", true);
+                generateNotificationRecord(mTestNotificationChannel, 0, AUTOGROUP_KEY, true);
         summary.getNotification().flags |= Notification.FLAG_AUTOGROUP_SUMMARY;
         summary.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
         mService.addNotification(summary);
         mService.mAutobundledSummaries.put(0, new ArrayMap<>());
         mService.mAutobundledSummaries.get(0).put("pkg", summary.getKey());
-        mService.mSummaryByGroupKey.put("pkg", summary);
+        mService.mSummaryByGroupKey.put(summary.getGroupKey(), summary);
 
-        mService.updateAutobundledSummaryLocked(0, "pkg",
+        mService.updateAutobundledSummaryLocked(0, "pkg", AUTOGROUP_KEY,
                 new NotificationAttributes(GroupHelper.BASE_FLAGS,
-                    mock(Icon.class), 0, VISIBILITY_PRIVATE), false);
+                    mock(Icon.class), 0,
+                    VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN, DEFAULT_CHANNEL_ID), false);
         waitForIdle();
 
         assertFalse(summary.getSbn().isOngoing());
     }
 
     @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testAutobundledSummary_notificationRemoved_forceGrouping() {
+        NotificationRecord summary =
+            generateNotificationRecord(mTestNotificationChannel, 0, AUTOGROUP_KEY, true);
+        summary.getNotification().flags |= Notification.FLAG_AUTOGROUP_SUMMARY;
+        summary.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
+        mService.addNotification(summary);
+        mService.mAutobundledSummaries.put(0, new ArrayMap<>());
+        mService.mAutobundledSummaries.get(0).put(summary.getGroupKey(), summary.getKey());
+
+        mService.updateAutobundledSummaryLocked(0, "pkg", summary.getGroupKey(),
+                new NotificationAttributes(GroupHelper.BASE_FLAGS,
+                    mock(Icon.class), 0,
+                    VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN, DEFAULT_CHANNEL_ID), false);
+        waitForIdle();
+
+        assertFalse(summary.getSbn().isOngoing());
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testAggregatedSummary_updateSummaryAttributes() {
+        final String aggregateGroupName = "Aggregate_Test";
+        final String newChannelId = "newChannelId";
+        final NotificationChannel newChannel = new NotificationChannel(
+                newChannelId, newChannelId, IMPORTANCE_DEFAULT);
+        mService.setPreferencesHelper(mPreferencesHelper);
+        final NotificationRecord summary =
+                generateNotificationRecord(mTestNotificationChannel, 0, aggregateGroupName, true);
+        final String groupKey = summary.getGroupKey();
+        summary.getNotification().flags |= Notification.FLAG_AUTOGROUP_SUMMARY;
+        mService.addNotification(summary);
+        mService.mAutobundledSummaries.put(0, new ArrayMap<>());
+        mService.mAutobundledSummaries.get(0).put(groupKey, summary.getKey());
+        when(mPreferencesHelper.getNotificationChannel(eq("pkg"), anyInt(),
+                eq(newChannelId), anyBoolean())).thenReturn(newChannel);
+
+        mService.updateAutobundledSummaryLocked(0, "pkg", groupKey,
+                new NotificationAttributes(GroupHelper.BASE_FLAGS | FLAG_ONGOING_EVENT,
+                    mock(Icon.class), 0, VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN, newChannelId),
+                    false);
+        waitForIdle();
+
+        assertTrue(summary.getSbn().isOngoing());
+        assertThat(summary.getNotification().getGroupAlertBehavior()).isEqualTo(
+                GROUP_ALERT_CHILDREN);
+
+        assertThat(summary.getChannel().getId()).isEqualTo(newChannelId);
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testAddAggregateNotification_notifyPostedLocked() throws Exception {
+        final String originalGroupName = "originalGroup";
+        final NotificationRecord r =
+                generateNotificationRecord(mTestNotificationChannel, 0, originalGroupName, false);
+        mService.addNotification(r);
+        mService.addAutogroupKeyLocked(r.getKey(), "grpKey", true);
+
+        assertThat(r.getSbn().getOverrideGroupKey()).isEqualTo("grpKey");
+        verify(mRankingHandler, times(1)).requestSort();
+        verify(mListeners, times(1)).notifyPostedLocked(eq(r), eq(r));
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testAddAggregateSummaryNotification_convertSummary() throws Exception {
+        final String originalGroupName = "originalGroup";
+        final NotificationRecord r =
+                generateNotificationRecord(mTestNotificationChannel, 0, originalGroupName, true);
+        final String groupKey = r.getGroupKey();
+        mService.addNotification(r);
+        assertThat(mService.mSummaryByGroupKey.containsKey(groupKey)).isTrue();
+        boolean isConverted = mService.convertSummaryToNotificationLocked(r.getKey());
+
+        assertThat(isConverted).isTrue();
+        assertThat(r.getSbn().isGroup()).isTrue();
+        assertThat(r.getNotification().isGroupSummary()).isFalse();
+        assertThat(mService.mSummaryByGroupKey.containsKey(groupKey)).isFalse();
+    }
+
+    @Test
+    @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+            Flags.FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS})
+    public void testAggregateGroups_RemoveAppSummary() throws Exception {
+        final String originalGroupName = "originalGroup";
+        final NotificationRecord r =
+                generateNotificationRecord(mTestNotificationChannel, 0, originalGroupName, true);
+        mService.addNotification(r);
+        mService.removeAppSummaryLocked(r.getKey());
+
+        assertThat(r.isCanceled).isTrue();
+        waitForIdle();
+        verify(mWorkerHandler, times(1)).scheduleCancelNotification(any(), eq(0));
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testUngroupingAggregateSummary() throws Exception {
+        final String originalGroupName = "originalGroup";
+        final String aggregateGroupName = "Aggregate_Test";
+        final int summaryId = Integer.MAX_VALUE;
+        // Add 2 group notifications without a summary
+        NotificationRecord nr0 =
+                generateNotificationRecord(mTestNotificationChannel, 0, originalGroupName, false);
+        NotificationRecord nr1 =
+                generateNotificationRecord(mTestNotificationChannel, 1, originalGroupName, false);
+        mService.addNotification(nr0);
+        mService.addNotification(nr1);
+        mService.mSummaryByGroupKey.remove(nr0.getGroupKey());
+
+        // GroupHelper is a mock, so make the calls it would make
+        // Add aggregate group summary
+        NotificationAttributes attr = new NotificationAttributes(GroupHelper.BASE_FLAGS,
+                mock(Icon.class), 0, VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN,
+                nr0.getChannel().getId());
+        NotificationRecord aggregateSummary = mService.createAutoGroupSummary(nr0.getUserId(),
+                nr0.getSbn().getPackageName(), nr0.getKey(), aggregateGroupName, summaryId, attr);
+        mService.addNotification(aggregateSummary);
+        nr0.setOverrideGroupKey(aggregateGroupName);
+        nr1.setOverrideGroupKey(aggregateGroupName);
+        final String fullAggregateGroupKey = nr0.getGroupKey();
+
+        // Check that the aggregate group summary was created
+        assertThat(aggregateSummary.getNotification().getGroup()).isEqualTo(aggregateGroupName);
+        assertThat(aggregateSummary.getNotification().getChannelId()).isEqualTo(
+                nr0.getChannel().getId());
+        assertThat(mService.mSummaryByGroupKey.containsKey(fullAggregateGroupKey)).isTrue();
+
+        // Cancel both children
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg, nr0.getSbn().getTag(),
+                nr0.getSbn().getId(), nr0.getSbn().getUserId());
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg, nr1.getSbn().getTag(),
+                nr1.getSbn().getId(), nr1.getSbn().getUserId());
+        waitForIdle();
+
+        verify(mGroupHelper, times(1)).onNotificationRemoved(eq(nr0), any());
+        verify(mGroupHelper, times(1)).onNotificationRemoved(eq(nr1), any());
+
+        // GroupHelper would send 'remove summary' event
+        mService.clearAutogroupSummaryLocked(nr1.getUserId(), nr1.getSbn().getPackageName(),
+                fullAggregateGroupKey);
+        waitForIdle();
+
+        // Make sure the summary was removed and not re-posted
+        assertThat(mService.getNotificationRecordCount()).isEqualTo(0);
+    }
+
+    @Test
+    @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+            Flags.FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS})
+    public void testCancelGroupChildrenForCanceledSummary_singletonGroup() throws Exception {
+        final String originalGroupName = "originalGroup";
+        final String aggregateGroupName = "Aggregate_Test";
+        final int summaryId = Integer.MAX_VALUE;
+        // Add a "singleton group"
+        NotificationRecord nr0 =
+                generateNotificationRecord(mTestNotificationChannel, 0, originalGroupName, false);
+        NotificationRecord nr1 =
+                generateNotificationRecord(mTestNotificationChannel, 1, originalGroupName, false);
+        final NotificationRecord summary =
+                generateNotificationRecord(mTestNotificationChannel, 2, originalGroupName, true);
+        final String originalGroupKey = summary.getGroupKey();
+        mService.addNotification(nr0);
+        mService.addNotification(nr1);
+        mService.addNotification(summary);
+
+        // GroupHelper is a mock, so make the calls it would make
+        // Remove the app's summary notification
+        mService.removeAppSummaryLocked(summary.getKey());
+        waitForIdle();
+
+        // Add aggregate group summary
+        NotificationAttributes attr = new NotificationAttributes(GroupHelper.BASE_FLAGS,
+                mock(Icon.class), 0, VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN,
+                nr0.getChannel().getId());
+        NotificationRecord aggregateSummary = mService.createAutoGroupSummary(nr0.getUserId(),
+            nr0.getSbn().getPackageName(), nr0.getKey(), aggregateGroupName, summaryId, attr);
+        mService.addNotification(aggregateSummary);
+
+        nr0.setOverrideGroupKey(aggregateGroupName);
+        nr1.setOverrideGroupKey(aggregateGroupName);
+        final String fullAggregateGroupKey = nr0.getGroupKey();
+
+        assertThat(aggregateSummary.getNotification().getGroup()).isEqualTo(aggregateGroupName);
+        assertThat(aggregateSummary.getNotification().getChannelId()).isEqualTo(
+                nr0.getChannel().getId());
+        assertThat(mService.mSummaryByGroupKey.containsKey(fullAggregateGroupKey)).isTrue();
+        assertThat(mService.mSummaryByGroupKey.containsKey(originalGroupKey)).isFalse();
+
+        // Cancel the original app summary (is already removed)
+        mBinderService.cancelNotificationWithTag(summary.getSbn().getPackageName(),
+                summary.getSbn().getPackageName(), summary.getSbn().getTag(),
+                summary.getSbn().getId(), summary.getSbn().getUserId());
+        waitForIdle();
+
+        // Check if NMS.CancelNotificationRunnable calls maybeCancelGroupChildrenForCanceledSummary
+        verify(mGroupHelper, times(1)).maybeCancelGroupChildrenForCanceledSummary(
+                eq(summary.getSbn().getPackageName()), eq(summary.getSbn().getTag()),
+                eq(summary.getSbn().getId()), eq(summary.getSbn().getUserId()),
+                eq(REASON_APP_CANCEL));
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testUpdateChannel_notifyGroupHelper() throws Exception {
+        mService.setPreferencesHelper(mPreferencesHelper);
+        mTestNotificationChannel.setLightColor(Color.CYAN);
+        when(mPreferencesHelper.getNotificationChannel(eq(mPkg), anyInt(),
+                eq(mTestNotificationChannel.getId()), anyBoolean()))
+                .thenReturn(mTestNotificationChannel);
+
+        mBinderService.updateNotificationChannelForPackage(mPkg, mUid, mTestNotificationChannel);
+        mTestableLooper.moveTimeForward(DELAY_FORCE_REGROUP_TIME);
+        waitForIdle();
+
+        verify(mGroupHelper, times(1)).onChannelUpdated(eq(Process.myUserHandle().getIdentifier()),
+                eq(mPkg), eq(mTestNotificationChannel), any());
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testSnoozeRunnable_snoozeAggregateGroupChild_summaryNotSnoozed() throws Exception {
+        final String aggregateGroupName = "Aggregate_Test";
+
+        // build autogroup summary notification
+        Notification.Builder nb = new Notification.Builder(mContext,
+                mTestNotificationChannel.getId())
+                .setContentTitle("foo")
+                .setSmallIcon(android.R.drawable.sym_def_app_icon)
+                .setGroup(aggregateGroupName)
+                .setGroupSummary(true)
+                .setFlag(Notification.FLAG_AUTOGROUP_SUMMARY, true);
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 1,
+                "tag" + System.currentTimeMillis(), mUid, 0, nb.build(),
+                UserHandle.getUserHandleForUid(mUid), null, 0);
+        final NotificationRecord summary = new NotificationRecord(mContext, sbn,
+                mTestNotificationChannel);
+
+        final NotificationRecord child = generateNotificationRecord(
+                mTestNotificationChannel, 2, aggregateGroupName, false);
+        mService.addNotification(summary);
+        mService.addNotification(child);
+        when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
+
+        // snooze child only
+        NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
+                mService.new SnoozeNotificationRunnable(
+                    child.getKey(), 100, null);
+        snoozeNotificationRunnable.run();
+
+        // only child should be snoozed
+        verify(mSnoozeHelper, times(1)).snooze(any(NotificationRecord.class), anyLong());
+
+        // both group summary and child should be cancelled
+        assertNull(mService.getNotificationRecord(summary.getKey()));
+        assertNull(mService.getNotificationRecord(child.getKey()));
+
+        assertEquals(4, mNotificationRecordLogger.numCalls());
+        assertEquals(NotificationRecordLogger.NotificationEvent.NOTIFICATION_SNOOZED,
+                mNotificationRecordLogger.event(0));
+        assertEquals(
+                NotificationRecordLogger.NotificationCancelledEvent.NOTIFICATION_CANCEL_SNOOZED,
+                mNotificationRecordLogger.event(1));
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testOnlyForceGroupIfNeeded_newNotification_notAutogrouped() {
+        NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, null, false);
+        when(mGroupHelper.onNotificationPosted(any(), anyBoolean())).thenReturn(false);
+        mService.addEnqueuedNotification(r);
+        NotificationManagerService.PostNotificationRunnable runnable =
+                mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
+                    r.getUid(), mPostNotificationTrackerFactory.newTracker(null));
+        runnable.run();
+        waitForIdle();
+
+        mTestableLooper.moveTimeForward(DELAY_FORCE_REGROUP_TIME);
+        waitForIdle();
+
+        verify(mGroupHelper, times(1)).onNotificationPosted(any(), anyBoolean());
+        verify(mGroupHelper, times(1)).onNotificationPostedWithDelay(eq(r), any(), any());
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testOnlyForceGroupIfNeeded_newNotification_wasAutogrouped() {
+        NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, null, false);
+        when(mGroupHelper.onNotificationPosted(any(), anyBoolean())).thenReturn(true);
+        mService.addEnqueuedNotification(r);
+        NotificationManagerService.PostNotificationRunnable runnable =
+            mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
+                r.getUid(), mPostNotificationTrackerFactory.newTracker(null));
+        runnable.run();
+        waitForIdle();
+
+        mTestableLooper.moveTimeForward(DELAY_FORCE_REGROUP_TIME);
+        waitForIdle();
+
+        verify(mGroupHelper, times(1)).onNotificationPosted(any(), anyBoolean());
+        verify(mGroupHelper, never()).onNotificationPostedWithDelay(eq(r), any(), any());
+    }
+
+    @Test
     public void testCancelAllNotifications_IgnoreForegroundService() throws Exception {
         when(mAmi.applyForegroundServiceNotification(
                 any(), anyString(), anyInt(), anyString(), anyInt())).thenReturn(SHOW_IMMEDIATELY);
@@ -3653,9 +3988,11 @@
         when(mPermissionHelper.hasPermission(mUid)).thenReturn(true);
         when(mPermissionHelper.isPermissionFixed(mPkg, temp.getUserId())).thenReturn(true);
 
+        NotificationAttributes attr = new NotificationAttributes(GroupHelper.BASE_FLAGS,
+            mock(Icon.class), 0, VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN, DEFAULT_CHANNEL_ID);
+
         NotificationRecord r = mService.createAutoGroupSummary(temp.getUserId(),
-                temp.getSbn().getPackageName(), temp.getKey(), 0, mock(Icon.class), 0,
-                VISIBILITY_PRIVATE);
+            temp.getSbn().getPackageName(), temp.getKey(), AUTOGROUP_KEY, Integer.MAX_VALUE, attr);
 
         assertThat(r.isImportanceFixed()).isTrue();
     }
@@ -4796,6 +5133,7 @@
     }
 
     @Test
+    @DisableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
     public void testSnoozeRunnable_snoozeAutoGroupChild_summaryNotSnoozed() throws Exception {
         final NotificationRecord parent = generateNotificationRecord(
                 mTestNotificationChannel, 1, GroupHelper.AUTOGROUP_KEY, true);
@@ -5659,7 +5997,7 @@
     public void testAddAutogroup_requestsSort() throws Exception {
         final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
         mService.addNotification(r);
-        mService.addAutogroupKeyLocked(r.getKey(), true);
+        mService.addAutogroupKeyLocked(r.getKey(), "grpKey", true);
 
         verify(mRankingHandler, times(1)).requestSort();
     }
@@ -5679,7 +6017,7 @@
         final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
         r.setOverrideGroupKey("TEST");
         mService.addNotification(r);
-        mService.addAutogroupKeyLocked(r.getKey(), true);
+        mService.addAutogroupKeyLocked(r.getKey(), "grpName", true);
 
         verify(mRankingHandler, never()).requestSort();
     }
@@ -5689,7 +6027,7 @@
     public void testAutogroupSuppressSort_noSort() throws Exception {
         final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
         mService.addNotification(r);
-        mService.addAutogroupKeyLocked(r.getKey(), false);
+        mService.addAutogroupKeyLocked(r.getKey(), "grpName", false);
 
         verify(mRankingHandler, never()).requestSort();
     }
@@ -12688,6 +13026,7 @@
     }
 
     @Test
+    @DisableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
     public void testUngroupingOngoingAutoSummary() throws Exception {
         NotificationRecord nr0 =
                 generateNotificationRecord(mTestNotificationChannel, 0);
@@ -12701,10 +13040,12 @@
         // grouphelper is a mock here, so make the calls it would make
 
         // add summary
+        NotificationAttributes attr = new NotificationAttributes(
+                GroupHelper.BASE_FLAGS | FLAG_ONGOING_EVENT, mock(Icon.class), 0,
+                VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN, DEFAULT_CHANNEL_ID);
         mService.addNotification(
                 mService.createAutoGroupSummary(nr1.getUserId(), nr1.getSbn().getPackageName(),
-                    nr1.getKey(), GroupHelper.BASE_FLAGS | FLAG_ONGOING_EVENT, mock(Icon.class), 0,
-                    VISIBILITY_PRIVATE));
+                    nr1.getKey(), AUTOGROUP_KEY, Integer.MAX_VALUE, attr));
 
         // cancel both children
         mBinderService.cancelNotificationWithTag(mPkg, mPkg, nr0.getSbn().getTag(),
@@ -12714,7 +13055,8 @@
         waitForIdle();
 
         // group helper would send 'remove summary' event
-        mService.clearAutogroupSummaryLocked(nr1.getUserId(), nr1.getSbn().getPackageName());
+        mService.clearAutogroupSummaryLocked(nr1.getUserId(), nr1.getSbn().getPackageName(),
+                AUTOGROUP_KEY);
         waitForIdle();
 
         // make sure the summary was removed and not re-posted
@@ -12722,6 +13064,45 @@
     }
 
     @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testUngroupingOngoingAutoSummary_forceGrouping() throws Exception {
+        NotificationRecord nr0 =
+            generateNotificationRecord(mTestNotificationChannel, 0);
+        NotificationRecord nr1 =
+            generateNotificationRecord(mTestNotificationChannel, 0);
+        nr1.getSbn().getNotification().flags |= FLAG_ONGOING_EVENT;
+
+        mService.addNotification(nr0);
+        mService.addNotification(nr1);
+
+        // grouphelper is a mock here, so make the calls it would make
+
+        // add summary
+        NotificationAttributes attr = new NotificationAttributes(
+            GroupHelper.BASE_FLAGS | FLAG_ONGOING_EVENT, mock(Icon.class), 0,
+            VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN, DEFAULT_CHANNEL_ID);
+        mService.addNotification(
+            mService.createAutoGroupSummary(nr1.getUserId(), nr1.getSbn().getPackageName(),
+                nr1.getKey(), AUTOGROUP_KEY, Integer.MAX_VALUE, attr));
+
+        // cancel both children
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg, nr0.getSbn().getTag(),
+            nr0.getSbn().getId(), nr0.getSbn().getUserId());
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg, nr1.getSbn().getTag(),
+            nr1.getSbn().getId(), nr1.getSbn().getUserId());
+        waitForIdle();
+
+        // group helper would send 'remove summary' event
+        mService.clearAutogroupSummaryLocked(nr1.getUserId(), nr1.getSbn().getPackageName(),
+            AUTOGROUP_KEY);
+        waitForIdle();
+
+        // make sure the summary was removed and not re-posted
+        assertThat(mService.getNotificationRecordCount()).isEqualTo(0);
+    }
+
+    @Test
+    @DisableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
     public void testUngroupingAutoSummary_differentUsers() throws Exception {
         NotificationRecord nr0 =
                 generateNotificationRecord(mTestNotificationChannel, 0, USER_SYSTEM);
@@ -12729,11 +13110,14 @@
                 generateNotificationRecord(mTestNotificationChannel, 1, USER_SYSTEM);
 
         // add notifications + summary for USER_SYSTEM
+        NotificationAttributes attr = new NotificationAttributes(
+            GroupHelper.BASE_FLAGS, mock(Icon.class), 0,
+            VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN, DEFAULT_CHANNEL_ID);
         mService.addNotification(nr0);
         mService.addNotification(nr1);
         mService.addNotification(
                 mService.createAutoGroupSummary(nr1.getUserId(), nr1.getSbn().getPackageName(),
-                nr1.getKey(), GroupHelper.BASE_FLAGS, mock(Icon.class), 0, VISIBILITY_PRIVATE));
+                nr1.getKey(), AUTOGROUP_KEY, Integer.MAX_VALUE, attr));
 
         // add notifications + summary for USER_ALL
         NotificationRecord nr0_all =
@@ -12746,7 +13130,7 @@
         mService.addNotification(
                 mService.createAutoGroupSummary(nr0_all.getUserId(),
                 nr0_all.getSbn().getPackageName(),
-                nr0_all.getKey(), GroupHelper.BASE_FLAGS, mock(Icon.class), 0, VISIBILITY_PRIVATE));
+                nr0_all.getKey(), AUTOGROUP_KEY, Integer.MAX_VALUE, attr));
 
         // cancel both children for USER_ALL
         mBinderService.cancelNotificationWithTag(mPkg, mPkg, nr0_all.getSbn().getTag(),
@@ -12757,7 +13141,7 @@
 
         // group helper would send 'remove summary' event
         mService.clearAutogroupSummaryLocked(UserHandle.USER_ALL,
-                nr0_all.getSbn().getPackageName());
+                nr0_all.getSbn().getPackageName(), AUTOGROUP_KEY);
         waitForIdle();
 
         // make sure the right summary was removed
@@ -12770,6 +13154,58 @@
     }
 
     @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testUngroupingAutoSummary_differentUsers_forceGrouping() throws Exception {
+        NotificationRecord nr0 =
+            generateNotificationRecord(mTestNotificationChannel, 0, USER_SYSTEM);
+        NotificationRecord nr1 =
+            generateNotificationRecord(mTestNotificationChannel, 1, USER_SYSTEM);
+
+        // add notifications + summary for USER_SYSTEM
+        NotificationAttributes attr = new NotificationAttributes(
+            GroupHelper.BASE_FLAGS, mock(Icon.class), 0,
+            VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN, DEFAULT_CHANNEL_ID);
+        mService.addNotification(nr0);
+        mService.addNotification(nr1);
+        mService.addNotification(
+            mService.createAutoGroupSummary(nr1.getUserId(), nr1.getSbn().getPackageName(),
+                nr1.getKey(), AUTOGROUP_KEY, Integer.MAX_VALUE, attr));
+
+        // add notifications + summary for USER_ALL
+        NotificationRecord nr0_all =
+            generateNotificationRecord(mTestNotificationChannel, 2, UserHandle.USER_ALL);
+        NotificationRecord nr1_all =
+            generateNotificationRecord(mTestNotificationChannel, 3, UserHandle.USER_ALL);
+
+        mService.addNotification(nr0_all);
+        mService.addNotification(nr1_all);
+        mService.addNotification(
+            mService.createAutoGroupSummary(nr0_all.getUserId(),
+                nr0_all.getSbn().getPackageName(),
+                nr0_all.getKey(), AUTOGROUP_KEY, Integer.MAX_VALUE, attr));
+
+        // cancel both children for USER_ALL
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg, nr0_all.getSbn().getTag(),
+            nr0_all.getSbn().getId(), UserHandle.USER_ALL);
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg, nr1_all.getSbn().getTag(),
+            nr1_all.getSbn().getId(), UserHandle.USER_ALL);
+        waitForIdle();
+
+        // group helper would send 'remove summary' event
+        mService.clearAutogroupSummaryLocked(UserHandle.USER_ALL,
+            nr0_all.getSbn().getPackageName(), AUTOGROUP_KEY);
+        waitForIdle();
+
+        // make sure the right summary was removed
+        assertThat(mService.getNotificationCount(nr0_all.getSbn().getPackageName(),
+            UserHandle.USER_ALL, 0, null)).isEqualTo(0);
+
+        // the USER_SYSTEM notifications + summary were not removed
+        assertThat(mService.getNotificationCount(nr0.getSbn().getPackageName(),
+            USER_SYSTEM, 0, null)).isEqualTo(3);
+    }
+
+    @Test
     public void testStrongAuthTracker_isInLockDownMode() {
         mStrongAuthTracker.setGetStrongAuthForUserReturnValue(
                 STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
