Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5ad52889 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Check sparse group child notifications for trigger section" into main

parents 642883fa 53926ed6
Loading
Loading
Loading
Loading
+41 −3
Original line number Diff line number Diff line
@@ -1466,7 +1466,8 @@ public class GroupHelper {
        }
    }

    private ArrayMap<String, NotificationRecord> getSparseGroups(
    @VisibleForTesting
    protected ArrayMap<String, NotificationRecord> getSparseGroups(
            final FullyQualifiedGroupKey fullAggregateGroupKey,
            final List<NotificationRecord> notificationList,
            final Map<String, NotificationRecord> summaryByGroupKey,
@@ -1478,8 +1479,8 @@ public class GroupHelper {
                        && summary.getUserId() == fullAggregateGroupKey.userId
                        && summary.getSbn().isAppGroup()
                        && !summary.getGroupKey().equals(fullAggregateGroupKey.toString())) {
                    int numChildren = getNumChildrenForGroup(summary.getSbn().getGroup(),
                            notificationList);
                    int numChildren = getNumChildrenForGroupWithSection(summary.getSbn().getGroup(),
                            notificationList, sectioner);
                    if (numChildren > 0 && numChildren < MIN_CHILD_COUNT_TO_AVOID_FORCE_GROUPING) {
                        sparseGroups.put(summary.getGroupKey(), summary);
                    }
@@ -1489,6 +1490,43 @@ public class GroupHelper {
        return sparseGroups;
    }

    /**
     *  Get the number of children of a group if all match a certain section.
     *  Used for force grouping sparse groups, where the summary may match a section but the
     *  child notifications do not: ie. conversations
     *
     * @param groupKey the group key (name)
     * @param notificationList all notifications list
     * @param sectioner the section to match
     * @return number of children in that group or -1 if section does not match
     */
    private int getNumChildrenForGroupWithSection(final String groupKey,
            final List<NotificationRecord> notificationList,
            final NotificationSectioner sectioner) {
        int numChildren = 0;
        for (NotificationRecord r : notificationList) {
            if (!r.getNotification().isGroupSummary() && groupKey.equals(r.getSbn().getGroup())) {
                NotificationSectioner childSection = getSection(r);
                if (childSection == null || childSection != sectioner) {
                    if (DEBUG) {
                        Slog.i(TAG,
                                "getNumChildrenForGroupWithSection skip because invalid section: "
                                    + groupKey + " r: " + r);
                    }
                    return -1;
                } else {
                    numChildren++;
                }
            }
        }

        if (DEBUG) {
            Slog.i(TAG,
                    "getNumChildrenForGroupWithSection " + groupKey + " numChild: " + numChildren);
        }
        return numChildren;
    }

    @GuardedBy("mAggregatedNotifications")
    private void cacheCanceledSummary(NotificationRecord record) {
        final FullyQualifiedGroupKey groupKey = new FullyQualifiedGroupKey(record.getUserId(),
+116 −0
Original line number Diff line number Diff line
@@ -84,7 +84,9 @@ import androidx.test.filters.SmallTest;
import com.android.internal.R;
import com.android.server.UiServiceTestCase;
import com.android.server.notification.GroupHelper.CachedSummary;
import com.android.server.notification.GroupHelper.FullyQualifiedGroupKey;
import com.android.server.notification.GroupHelper.NotificationAttributes;
import com.android.server.notification.GroupHelper.NotificationSectioner;

import org.junit.Before;
import org.junit.Rule;
@@ -3252,6 +3254,120 @@ public class GroupHelperTest extends UiServiceTestCase {
        assertThat(cachedSummary).isNull();
    }

    @Test
    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
    @DisableFlags(FLAG_NOTIFICATION_FORCE_GROUP_CONVERSATIONS)
    public void testNonGroupableChildren_singletonGroups_disableConversations() {
        // Check that singleton groups with children that are not groupable, is not grouped
        // Even though the group summary is a regular (alerting) notification, the children are
        // conversations => the group should not be forced grouped.
        final List<NotificationRecord> notificationList = new ArrayList<>();
        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
        final String pkg = "package";

        // Trigger notification, ungrouped
        final int triggerId = 1;
        NotificationRecord triggerNotification = getNotificationRecord(pkg, triggerId,
                String.valueOf(triggerId), UserHandle.SYSTEM);
        notificationList.add(triggerNotification);
        final NotificationSectioner triggerSection = GroupHelper.getSection(triggerNotification);
        final FullyQualifiedGroupKey triggerFullAggregateGroupKey = new FullyQualifiedGroupKey(
                triggerNotification.getUserId(), triggerNotification.getSbn().getPackageName(),
                triggerSection);

        // Add singleton group with alerting child
        final String groupName_valid = "testGrp_valid";
        final int summaryId_valid = 0;
        NotificationRecord summary = getNotificationRecord(pkg, summaryId_valid,
                String.valueOf(summaryId_valid), UserHandle.SYSTEM, groupName_valid, true);
        notificationList.add(summary);
        summaryByGroup.put(summary.getGroupKey(), summary);
        final String groupKey_valid = summary.getGroupKey();
        NotificationRecord child = getNotificationRecord(pkg, summaryId_valid + 42,
                String.valueOf(summaryId_valid + 42), UserHandle.SYSTEM, groupName_valid, false);
        notificationList.add(child);

        // Add singleton group with conversation child
        final String groupName_invalid = "testGrp_invalid";
        final int summaryId_invalid = 100;
        summary = getNotificationRecord(pkg, summaryId_invalid,
                String.valueOf(summaryId_invalid), UserHandle.SYSTEM, groupName_invalid, true);
        notificationList.add(summary);
        final String groupKey_invalid = summary.getGroupKey();
        summaryByGroup.put(summary.getGroupKey(), summary);
        child = getNotificationRecord(pkg, summaryId_invalid + 42,
                String.valueOf(summaryId_invalid + 42), UserHandle.SYSTEM, groupName_invalid,
                false);
        child = spy(child);
        when(child.isConversation()).thenReturn(true);
        notificationList.add(child);

        // Check that the invalid group will not be force grouped
        final ArrayMap<String, NotificationRecord> sparseGroups = mGroupHelper.getSparseGroups(
                triggerFullAggregateGroupKey, notificationList, summaryByGroup, triggerSection);
        assertThat(sparseGroups).containsKey(groupKey_valid);
        assertThat(sparseGroups).doesNotContainKey(groupKey_invalid);
    }

    @Test
    @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING, FLAG_NOTIFICATION_FORCE_GROUP_CONVERSATIONS})
    public void testNonGroupableChildren_singletonGroups_enableConversations() {
        // Check that singleton groups with children that are not groupable, is not grouped
        // Conversations are groupable (FLAG_NOTIFICATION_FORCE_GROUP_CONVERSATIONS is enabled)
        // The invalid group is the alerting notifications: because the triggering notifications'
        // section is Conversations, so the alerting group should be skipped.
        final List<NotificationRecord> notificationList = new ArrayList<>();
        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
        final String pkg = "package";

        // Trigger notification, ungrouped conversation
        final int triggerId = 1;
        NotificationRecord triggerNotification = getNotificationRecord(pkg, triggerId,
                String.valueOf(triggerId), UserHandle.SYSTEM);
        triggerNotification = spy(triggerNotification);
        when(triggerNotification.isConversation()).thenReturn(true);
        notificationList.add(triggerNotification);
        final NotificationSectioner triggerSection = GroupHelper.getSection(triggerNotification);
        final FullyQualifiedGroupKey triggerFullAggregateGroupKey = new FullyQualifiedGroupKey(
                triggerNotification.getUserId(), triggerNotification.getSbn().getPackageName(),
                triggerSection);

        // Add singleton group with conversation child
        final String groupName_valid = "testGrp_valid";
        final int summaryId_valid = 0;
        NotificationRecord summary = getNotificationRecord(pkg, summaryId_valid,
                String.valueOf(summaryId_valid), UserHandle.SYSTEM, groupName_valid, true);
        summary = spy(summary);
        when(summary.isConversation()).thenReturn(true);
        notificationList.add(summary);
        summaryByGroup.put(summary.getGroupKey(), summary);
        final String groupKey_valid = summary.getGroupKey();
        NotificationRecord child = getNotificationRecord(pkg, summaryId_valid + 42,
                String.valueOf(summaryId_valid + 42), UserHandle.SYSTEM, groupName_valid, false);
        child = spy(child);
        when(child.isConversation()).thenReturn(true);
        notificationList.add(child);

        // Add singleton group with non-conversation child
        final String groupName_invalid = "testGrp_invalid";
        final int summaryId_invalid = 100;
        summary = getNotificationRecord(pkg, summaryId_invalid,
                String.valueOf(summaryId_invalid), UserHandle.SYSTEM, groupName_invalid, true);
        notificationList.add(summary);
        final String groupKey_invalid = summary.getGroupKey();
        summaryByGroup.put(summary.getGroupKey(), summary);
        child = getNotificationRecord(pkg, summaryId_invalid + 42,
                String.valueOf(summaryId_invalid + 42), UserHandle.SYSTEM, groupName_invalid,
                false);
        notificationList.add(child);

        // Check that the invalid group will not be force grouped
        final ArrayMap<String, NotificationRecord> sparseGroups = mGroupHelper.getSparseGroups(
                triggerFullAggregateGroupKey, notificationList, summaryByGroup, triggerSection);
        assertThat(sparseGroups).containsKey(groupKey_valid);
        assertThat(sparseGroups).doesNotContainKey(groupKey_invalid);
    }

    @Test
    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
    @DisableFlags(FLAG_NOTIFICATION_FORCE_GROUP_CONVERSATIONS)