diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java index 0f21a6c0587c2..74c97fdbddca5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java @@ -674,6 +674,12 @@ public class ShadeListBuilder implements Dumpable { // having its summary promoted, regardless of how many children it has Set groupsWithChildrenLostToStability = getGroupsWithChildrenLostToStability(shadeList); + // Like groups which lost a child to stability, any group which lost a child to promotion + // is exempt from having its summary promoted when it has no attached children. + Set groupsWithChildrenLostToPromotionOrStability = + getGroupsWithChildrenLostToPromotion(shadeList); + groupsWithChildrenLostToPromotionOrStability.addAll(groupsWithChildrenLostToStability); + for (int i = 0; i < shadeList.size(); i++) { final ListEntry tle = shadeList.get(i); @@ -683,9 +689,9 @@ public class ShadeListBuilder implements Dumpable { final boolean hasSummary = group.getSummary() != null; if (hasSummary && children.size() == 0) { - if (groupsWithChildrenLostToStability.contains(group.getKey())) { - // This group lost a child on this run to stability, so it is exempt from - // having its summary promoted to the top level, so prune it. + if (groupsWithChildrenLostToPromotionOrStability.contains(group.getKey())) { + // This group lost a child on this run to promotion or stability, so it is + // exempt from having its summary promoted to the top level, so prune it. // It has no children, so it will just vanish. pruneGroupAtIndexAndPromoteAnyChildren(shadeList, group, i); } else { @@ -825,6 +831,26 @@ public class ShadeListBuilder implements Dumpable { return groupsWithChildrenLostToStability; } + /** + * Collect the keys of any groups which have already lost a child to a {@link NotifPromoter} + * this run. + * + * These groups will be exempt from appearing without any children. + */ + @NonNull + private Set getGroupsWithChildrenLostToPromotion(List shadeList) { + ArraySet groupsWithChildrenLostToPromotion = new ArraySet<>(); + for (int i = 0; i < shadeList.size(); i++) { + final ListEntry tle = shadeList.get(i); + if (tle.getAttachState().getPromoter() != null) { + // This top-level-entry was part of a group, but was promoted out of it. + final String groupKey = tle.getRepresentativeEntry().getSbn().getGroupKey(); + groupsWithChildrenLostToPromotion.add(groupKey); + } + } + return groupsWithChildrenLostToPromotion; + } + /** * If a ListEntry was added to the shade list and then later removed (e.g. because it was a * group that was broken up), this method will erase any bookkeeping traces of that addition diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java index 2e84482496ca4..8fb066bb4a391 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java @@ -367,6 +367,50 @@ public class ShadeListBuilderTest extends SysuiTestCase { assertNull(mEntrySet.get(1).getParent()); } + @Test + public void testGroupsWhoLoseAllChildrenToPromotionSuppressSummary() { + // GIVEN a group with two children + addGroupChild(0, PACKAGE_2, GROUP_1); + addGroupSummary(1, PACKAGE_2, GROUP_1); + addGroupChild(2, PACKAGE_2, GROUP_1); + + // GIVEN a promoter that will promote one of children to top level + mListBuilder.addPromoter(new IdPromoter(0, 2)); + + // WHEN we build the list + dispatchBuild(); + + // THEN both children end up at top level (because group is now too small) + verifyBuiltList( + notif(0), + notif(2) + ); + + // THEN the summary is discarded + assertNull(mEntrySet.get(1).getParent()); + } + + @Test + public void testGroupsWhoLoseOnlyChildToPromotionSuppressSummary() { + // GIVEN a group with two children + addGroupChild(0, PACKAGE_2, GROUP_1); + addGroupSummary(1, PACKAGE_2, GROUP_1); + + // GIVEN a promoter that will promote one of children to top level + mListBuilder.addPromoter(new IdPromoter(0)); + + // WHEN we build the list + dispatchBuild(); + + // THEN both children end up at top level (because group is now too small) + verifyBuiltList( + notif(0) + ); + + // THEN the summary is discarded + assertNull(mEntrySet.get(1).getParent()); + } + @Test public void testPreviousParentsAreSetProperly() { // GIVEN a notification that is initially added to the list