Loading packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java +95 −0 Original line number Diff line number Diff line Loading @@ -70,6 +70,8 @@ import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.SmartReplyController; import com.android.systemui.statusbar.notification.ColorUpdateLogger; import com.android.systemui.statusbar.notification.ConversationNotificationProcessor; import com.android.systemui.statusbar.notification.collection.GroupEntry; import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; Loading Loading @@ -106,6 +108,7 @@ import kotlinx.coroutines.test.TestScope; import org.mockito.ArgumentCaptor; import java.util.List; import java.util.Objects; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; Loading Loading @@ -337,6 +340,46 @@ public class NotificationTestHelper { return generateRow(createNotification(), PKG, UID, USER_HANDLE, extraInflationFlags); } /** * Returns an {@link GroupEntry} group with the given number of child * notifications. */ public GroupEntry createGroupEntry(int numChildren, @Nullable List<NotificationEntry> additionalChildren) { Notification summary = new Notification.Builder(mContext, "") .setSmallIcon(R.drawable.ic_person) .setGroupSummary(true) .setGroup(GROUP_KEY) .build(); NotificationEntry summaryEntry = new NotificationEntryBuilder() .setPkg(PKG) .setOpPkg(PKG) .setId(mId++) .setUid(UID) .setInitialPid(2000) .setNotification(summary) .setParent(GroupEntry.ROOT_ENTRY) .build(); GroupEntryBuilder groupEntry = new GroupEntryBuilder() .setSummary(summaryEntry); for (int i = 0; i < numChildren; i++) { NotificationEntry child = new NotificationEntryBuilder() .setParent(GroupEntry.ROOT_ENTRY) .setNotification(new Notification.Builder(mContext, "") .setSmallIcon(R.drawable.ic_person) .setGroup(GROUP_KEY) .build()) .build(); groupEntry.addChild(child); } for (NotificationEntry entry : additionalChildren) { groupEntry.addChild(entry); } return groupEntry.build(); } /** * Returns an {@link ExpandableNotificationRow} group with the given number of child * notifications. Loading Loading @@ -410,6 +453,23 @@ public class NotificationTestHelper { return row; } /** * Returns an {@link NotificationEntry} that should be shown as a bubble and is part * of a group of notifications. */ public NotificationEntry createBubbleEntryInGroup() throws Exception { Notification n = createNotification(false /* isGroupSummary */, GROUP_KEY /* groupKey */, makeBubbleMetadata(null /* deleteIntent */, false /* autoExpand */)); n.flags |= FLAG_BUBBLE; NotificationEntry entry = generateEntry(n, PKG, UID, USER_HANDLE, mDefaultInflationFlags, IMPORTANCE_HIGH); modifyRanking(entry) .setCanBubble(true) .build(); return entry; } /** * Returns an {@link ExpandableNotificationRow} that should be shown as a bubble and is part * of a group of notifications. Loading Loading @@ -573,6 +633,41 @@ public class NotificationTestHelper { return mKeyguardBypassController; } private NotificationEntry generateEntry( Notification notification, String pkg, int uid, UserHandle userHandle, @InflationFlag int extraInflationFlags, int importance) throws Exception { final NotificationChannel channel = new NotificationChannel( notification.getChannelId(), notification.getChannelId(), importance); channel.setBlockable(true); NotificationEntry entry = new NotificationEntryBuilder() .setPkg(pkg) .setOpPkg(pkg) .setId(mId++) .setUid(uid) .setInitialPid(2000) .setNotification(notification) .setUser(userHandle) .setPostTime(System.currentTimeMillis()) .setChannel(channel) .updateRanking(rankingBuilder -> rankingBuilder.setIsConversation( notification.isStyle(Notification.MessagingStyle.class) )) .build(); return entry; } private ExpandableNotificationRow generateRow( Notification notification, String pkg, Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java +32 −12 Original line number Diff line number Diff line Loading @@ -589,10 +589,14 @@ public final class NotificationEntry extends ListEntry { /** * Get the children that are actually attached to this notification's row. * * TODO: Seems like most callers here should probably be using * {@link GroupMembershipManager#getChildren(PipelineEntry)} * TODO: Seems like most callers here should be asking a PipelineEntry, not a NotificationEntry */ public @Nullable List<NotificationEntry> getAttachedNotifChildren() { if (NotificationBundleUi.isEnabled()) { if (isGroupSummary()) { return ((GroupEntry) getParent()).getChildren(); } } else { if (row == null) { return null; } Loading @@ -609,6 +613,22 @@ public final class NotificationEntry extends ListEntry { return children; } return null; } private boolean isGroupSummary() { if (getParent() == null) { // The entry is not attached, so it doesn't count. return false; } PipelineEntry pipelineEntry = getParent(); if (!(pipelineEntry instanceof GroupEntry groupEntry)) { return false; } // If entry is a summary, its parent is a GroupEntry with summary = entry. return groupEntry.getSummary() == this; } public void notifyFullScreenIntentLaunched() { setInterruption(); Loading packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java +99 −0 Original line number Diff line number Diff line Loading @@ -135,6 +135,8 @@ import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.RankingBuilder; import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.notification.NotifPipelineFlags; import com.android.systemui.statusbar.notification.collection.GroupEntry; import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder; import com.android.systemui.statusbar.notification.collection.NotifPipeline; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; Loading @@ -151,6 +153,7 @@ import com.android.systemui.statusbar.notification.interruption.VisualInterrupti import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProviderTestUtil; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.NotificationTestHelper; import com.android.systemui.statusbar.notification.shared.NotificationBundleUi; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.policy.BatteryController; Loading Loading @@ -1229,8 +1232,36 @@ public class BubblesTest extends SysuiTestCase { } @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) public void testBubbleSummaryDismissal_suppressesSummaryAndBubbleFromShade() throws Exception { // GIVEN a group summary with a bubble child NotificationEntry groupedBubble = mNotificationTestHelper.createBubbleEntryInGroup(); GroupEntry groupSummary = mNotificationTestHelper.createGroupEntry( 0, List.of(groupedBubble)); mEntryListener.onEntryAdded(groupedBubble); when(mCommonNotifCollection.getEntry(groupedBubble.getKey())) .thenReturn(groupedBubble); assertTrue(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getKey())); // WHEN the summary is dismissed mBubblesManager.handleDismissalInterception(groupSummary.getSummary()); // THEN the summary and bubbled child are suppressed from the shade assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( groupedBubble.getKey(), groupedBubble.getSbn().getGroupKey())); assertTrue(mBubbleController.getImplCachedState().isBubbleNotificationSuppressedFromShade( groupedBubble.getKey(), groupedBubble.getSbn().getGroupKey())); assertTrue(mBubbleData.isSummarySuppressed( groupSummary.getSummary().getSbn().getGroupKey())); } @Test @DisableFlags(NotificationBundleUi.FLAG_NAME) public void testBubbleSummaryDismissal_suppressesSummaryAndBubbleFromShade_rows() throws Exception { // GIVEN a group summary with a bubble child ExpandableNotificationRow groupSummary = mNotificationTestHelper.createGroup(0); ExpandableNotificationRow groupedBubble = mNotificationTestHelper.createBubbleInGroup(); mEntryListener.onEntryAdded(groupedBubble.getEntry()); Loading @@ -1253,7 +1284,32 @@ public class BubblesTest extends SysuiTestCase { } @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) public void testAppRemovesSummary_removesAllBubbleChildren() throws Exception { // GIVEN a group summary with a bubble child NotificationEntry groupedBubble = mNotificationTestHelper.createBubbleEntryInGroup(); GroupEntry groupSummary = mNotificationTestHelper.createGroupEntry( 0, List.of(groupedBubble)); mEntryListener.onEntryAdded(groupedBubble); when(mCommonNotifCollection.getEntry(groupedBubble.getKey())) .thenReturn(groupedBubble); assertTrue(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getKey())); // GIVEN the summary is dismissed mBubblesManager.handleDismissalInterception(groupSummary.getSummary()); // WHEN the summary is cancelled by the app mEntryListener.onEntryRemoved(groupSummary.getSummary(), REASON_APP_CANCEL); // THEN the summary and its children are removed from bubble data assertFalse(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getKey())); assertFalse(mBubbleData.isSummarySuppressed( groupSummary.getSummary().getSbn().getGroupKey())); } @Test @DisableFlags(NotificationBundleUi.FLAG_NAME) public void testAppRemovesSummary_removesAllBubbleChildren_rows() throws Exception { // GIVEN a group summary with a bubble child ExpandableNotificationRow groupSummary = mNotificationTestHelper.createGroup(0); ExpandableNotificationRow groupedBubble = mNotificationTestHelper.createBubbleInGroup(); Loading @@ -1276,9 +1332,52 @@ public class BubblesTest extends SysuiTestCase { } @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) public void testSummaryDismissalMarksBubblesHiddenFromShadeAndDismissesNonBubbledChildren() throws Exception { // GIVEN a group summary with two (non-bubble) children and one bubble child NotificationEntry groupedBubble = mNotificationTestHelper.createBubbleEntryInGroup(); GroupEntry groupSummary = mNotificationTestHelper.createGroupEntry( 2, List.of(groupedBubble)); mEntryListener.onEntryAdded(groupedBubble); when(mCommonNotifCollection.getEntry(groupedBubble.getKey())) .thenReturn(groupedBubble); // WHEN the summary is dismissed mBubblesManager.handleDismissalInterception(groupSummary.getSummary()); // THEN only the NON-bubble children are dismissed List<NotificationEntry> children = groupSummary.getChildren(); verify(mNotifCallback, times(1)).removeNotification( eq(children.get(0)), any(), eq(REASON_GROUP_SUMMARY_CANCELED)); verify(mNotifCallback, times(1)).removeNotification( eq(children.get(1)), any(), eq(REASON_GROUP_SUMMARY_CANCELED)); verify(mNotifCallback, never()).removeNotification(eq(groupedBubble), any(), anyInt()); // THEN the bubble child still exists as a bubble and is suppressed from the shade assertTrue(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getKey())); assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( groupedBubble.getKey(), groupedBubble.getSbn().getGroupKey())); assertTrue(mBubbleController.getImplCachedState().isBubbleNotificationSuppressedFromShade( groupedBubble.getKey(), groupedBubble.getSbn().getGroupKey())); // THEN the summary is also suppressed from the shade assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( groupSummary.getSummary().getKey(), groupSummary.getSummary().getSbn().getGroupKey())); assertTrue(mBubbleController.getImplCachedState().isBubbleNotificationSuppressedFromShade( groupSummary.getSummary().getKey(), groupSummary.getSummary().getSbn().getGroupKey())); } @Test @DisableFlags(NotificationBundleUi.FLAG_NAME) public void testSummaryDismissalMarksBubblesHiddenFromShadeAndDismissesNonBubbledChildren_row() throws Exception { // GIVEN a group summary with two (non-bubble) children and one bubble child ExpandableNotificationRow groupSummary = mNotificationTestHelper.createGroup(2); ExpandableNotificationRow groupedBubble = mNotificationTestHelper.createBubbleInGroup(); mEntryListener.onEntryAdded(groupedBubble.getEntry()); Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java +95 −0 Original line number Diff line number Diff line Loading @@ -70,6 +70,8 @@ import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.SmartReplyController; import com.android.systemui.statusbar.notification.ColorUpdateLogger; import com.android.systemui.statusbar.notification.ConversationNotificationProcessor; import com.android.systemui.statusbar.notification.collection.GroupEntry; import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; Loading Loading @@ -106,6 +108,7 @@ import kotlinx.coroutines.test.TestScope; import org.mockito.ArgumentCaptor; import java.util.List; import java.util.Objects; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; Loading Loading @@ -337,6 +340,46 @@ public class NotificationTestHelper { return generateRow(createNotification(), PKG, UID, USER_HANDLE, extraInflationFlags); } /** * Returns an {@link GroupEntry} group with the given number of child * notifications. */ public GroupEntry createGroupEntry(int numChildren, @Nullable List<NotificationEntry> additionalChildren) { Notification summary = new Notification.Builder(mContext, "") .setSmallIcon(R.drawable.ic_person) .setGroupSummary(true) .setGroup(GROUP_KEY) .build(); NotificationEntry summaryEntry = new NotificationEntryBuilder() .setPkg(PKG) .setOpPkg(PKG) .setId(mId++) .setUid(UID) .setInitialPid(2000) .setNotification(summary) .setParent(GroupEntry.ROOT_ENTRY) .build(); GroupEntryBuilder groupEntry = new GroupEntryBuilder() .setSummary(summaryEntry); for (int i = 0; i < numChildren; i++) { NotificationEntry child = new NotificationEntryBuilder() .setParent(GroupEntry.ROOT_ENTRY) .setNotification(new Notification.Builder(mContext, "") .setSmallIcon(R.drawable.ic_person) .setGroup(GROUP_KEY) .build()) .build(); groupEntry.addChild(child); } for (NotificationEntry entry : additionalChildren) { groupEntry.addChild(entry); } return groupEntry.build(); } /** * Returns an {@link ExpandableNotificationRow} group with the given number of child * notifications. Loading Loading @@ -410,6 +453,23 @@ public class NotificationTestHelper { return row; } /** * Returns an {@link NotificationEntry} that should be shown as a bubble and is part * of a group of notifications. */ public NotificationEntry createBubbleEntryInGroup() throws Exception { Notification n = createNotification(false /* isGroupSummary */, GROUP_KEY /* groupKey */, makeBubbleMetadata(null /* deleteIntent */, false /* autoExpand */)); n.flags |= FLAG_BUBBLE; NotificationEntry entry = generateEntry(n, PKG, UID, USER_HANDLE, mDefaultInflationFlags, IMPORTANCE_HIGH); modifyRanking(entry) .setCanBubble(true) .build(); return entry; } /** * Returns an {@link ExpandableNotificationRow} that should be shown as a bubble and is part * of a group of notifications. Loading Loading @@ -573,6 +633,41 @@ public class NotificationTestHelper { return mKeyguardBypassController; } private NotificationEntry generateEntry( Notification notification, String pkg, int uid, UserHandle userHandle, @InflationFlag int extraInflationFlags, int importance) throws Exception { final NotificationChannel channel = new NotificationChannel( notification.getChannelId(), notification.getChannelId(), importance); channel.setBlockable(true); NotificationEntry entry = new NotificationEntryBuilder() .setPkg(pkg) .setOpPkg(pkg) .setId(mId++) .setUid(uid) .setInitialPid(2000) .setNotification(notification) .setUser(userHandle) .setPostTime(System.currentTimeMillis()) .setChannel(channel) .updateRanking(rankingBuilder -> rankingBuilder.setIsConversation( notification.isStyle(Notification.MessagingStyle.class) )) .build(); return entry; } private ExpandableNotificationRow generateRow( Notification notification, String pkg, Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java +32 −12 Original line number Diff line number Diff line Loading @@ -589,10 +589,14 @@ public final class NotificationEntry extends ListEntry { /** * Get the children that are actually attached to this notification's row. * * TODO: Seems like most callers here should probably be using * {@link GroupMembershipManager#getChildren(PipelineEntry)} * TODO: Seems like most callers here should be asking a PipelineEntry, not a NotificationEntry */ public @Nullable List<NotificationEntry> getAttachedNotifChildren() { if (NotificationBundleUi.isEnabled()) { if (isGroupSummary()) { return ((GroupEntry) getParent()).getChildren(); } } else { if (row == null) { return null; } Loading @@ -609,6 +613,22 @@ public final class NotificationEntry extends ListEntry { return children; } return null; } private boolean isGroupSummary() { if (getParent() == null) { // The entry is not attached, so it doesn't count. return false; } PipelineEntry pipelineEntry = getParent(); if (!(pipelineEntry instanceof GroupEntry groupEntry)) { return false; } // If entry is a summary, its parent is a GroupEntry with summary = entry. return groupEntry.getSummary() == this; } public void notifyFullScreenIntentLaunched() { setInterruption(); Loading
packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java +99 −0 Original line number Diff line number Diff line Loading @@ -135,6 +135,8 @@ import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.RankingBuilder; import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.notification.NotifPipelineFlags; import com.android.systemui.statusbar.notification.collection.GroupEntry; import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder; import com.android.systemui.statusbar.notification.collection.NotifPipeline; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; Loading @@ -151,6 +153,7 @@ import com.android.systemui.statusbar.notification.interruption.VisualInterrupti import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProviderTestUtil; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.NotificationTestHelper; import com.android.systemui.statusbar.notification.shared.NotificationBundleUi; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.policy.BatteryController; Loading Loading @@ -1229,8 +1232,36 @@ public class BubblesTest extends SysuiTestCase { } @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) public void testBubbleSummaryDismissal_suppressesSummaryAndBubbleFromShade() throws Exception { // GIVEN a group summary with a bubble child NotificationEntry groupedBubble = mNotificationTestHelper.createBubbleEntryInGroup(); GroupEntry groupSummary = mNotificationTestHelper.createGroupEntry( 0, List.of(groupedBubble)); mEntryListener.onEntryAdded(groupedBubble); when(mCommonNotifCollection.getEntry(groupedBubble.getKey())) .thenReturn(groupedBubble); assertTrue(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getKey())); // WHEN the summary is dismissed mBubblesManager.handleDismissalInterception(groupSummary.getSummary()); // THEN the summary and bubbled child are suppressed from the shade assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( groupedBubble.getKey(), groupedBubble.getSbn().getGroupKey())); assertTrue(mBubbleController.getImplCachedState().isBubbleNotificationSuppressedFromShade( groupedBubble.getKey(), groupedBubble.getSbn().getGroupKey())); assertTrue(mBubbleData.isSummarySuppressed( groupSummary.getSummary().getSbn().getGroupKey())); } @Test @DisableFlags(NotificationBundleUi.FLAG_NAME) public void testBubbleSummaryDismissal_suppressesSummaryAndBubbleFromShade_rows() throws Exception { // GIVEN a group summary with a bubble child ExpandableNotificationRow groupSummary = mNotificationTestHelper.createGroup(0); ExpandableNotificationRow groupedBubble = mNotificationTestHelper.createBubbleInGroup(); mEntryListener.onEntryAdded(groupedBubble.getEntry()); Loading @@ -1253,7 +1284,32 @@ public class BubblesTest extends SysuiTestCase { } @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) public void testAppRemovesSummary_removesAllBubbleChildren() throws Exception { // GIVEN a group summary with a bubble child NotificationEntry groupedBubble = mNotificationTestHelper.createBubbleEntryInGroup(); GroupEntry groupSummary = mNotificationTestHelper.createGroupEntry( 0, List.of(groupedBubble)); mEntryListener.onEntryAdded(groupedBubble); when(mCommonNotifCollection.getEntry(groupedBubble.getKey())) .thenReturn(groupedBubble); assertTrue(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getKey())); // GIVEN the summary is dismissed mBubblesManager.handleDismissalInterception(groupSummary.getSummary()); // WHEN the summary is cancelled by the app mEntryListener.onEntryRemoved(groupSummary.getSummary(), REASON_APP_CANCEL); // THEN the summary and its children are removed from bubble data assertFalse(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getKey())); assertFalse(mBubbleData.isSummarySuppressed( groupSummary.getSummary().getSbn().getGroupKey())); } @Test @DisableFlags(NotificationBundleUi.FLAG_NAME) public void testAppRemovesSummary_removesAllBubbleChildren_rows() throws Exception { // GIVEN a group summary with a bubble child ExpandableNotificationRow groupSummary = mNotificationTestHelper.createGroup(0); ExpandableNotificationRow groupedBubble = mNotificationTestHelper.createBubbleInGroup(); Loading @@ -1276,9 +1332,52 @@ public class BubblesTest extends SysuiTestCase { } @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) public void testSummaryDismissalMarksBubblesHiddenFromShadeAndDismissesNonBubbledChildren() throws Exception { // GIVEN a group summary with two (non-bubble) children and one bubble child NotificationEntry groupedBubble = mNotificationTestHelper.createBubbleEntryInGroup(); GroupEntry groupSummary = mNotificationTestHelper.createGroupEntry( 2, List.of(groupedBubble)); mEntryListener.onEntryAdded(groupedBubble); when(mCommonNotifCollection.getEntry(groupedBubble.getKey())) .thenReturn(groupedBubble); // WHEN the summary is dismissed mBubblesManager.handleDismissalInterception(groupSummary.getSummary()); // THEN only the NON-bubble children are dismissed List<NotificationEntry> children = groupSummary.getChildren(); verify(mNotifCallback, times(1)).removeNotification( eq(children.get(0)), any(), eq(REASON_GROUP_SUMMARY_CANCELED)); verify(mNotifCallback, times(1)).removeNotification( eq(children.get(1)), any(), eq(REASON_GROUP_SUMMARY_CANCELED)); verify(mNotifCallback, never()).removeNotification(eq(groupedBubble), any(), anyInt()); // THEN the bubble child still exists as a bubble and is suppressed from the shade assertTrue(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getKey())); assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( groupedBubble.getKey(), groupedBubble.getSbn().getGroupKey())); assertTrue(mBubbleController.getImplCachedState().isBubbleNotificationSuppressedFromShade( groupedBubble.getKey(), groupedBubble.getSbn().getGroupKey())); // THEN the summary is also suppressed from the shade assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( groupSummary.getSummary().getKey(), groupSummary.getSummary().getSbn().getGroupKey())); assertTrue(mBubbleController.getImplCachedState().isBubbleNotificationSuppressedFromShade( groupSummary.getSummary().getKey(), groupSummary.getSummary().getSbn().getGroupKey())); } @Test @DisableFlags(NotificationBundleUi.FLAG_NAME) public void testSummaryDismissalMarksBubblesHiddenFromShadeAndDismissesNonBubbledChildren_row() throws Exception { // GIVEN a group summary with two (non-bubble) children and one bubble child ExpandableNotificationRow groupSummary = mNotificationTestHelper.createGroup(2); ExpandableNotificationRow groupedBubble = mNotificationTestHelper.createBubbleInGroup(); mEntryListener.onEntryAdded(groupedBubble.getEntry()); Loading