Loading services/core/java/com/android/server/notification/GroupHelper.java +4 −0 Original line number Diff line number Diff line Loading @@ -1435,6 +1435,10 @@ public class GroupHelper { return false; } if (record.getSbn().getNotification().isMediaNotification()) { return false; } return true; } } Loading services/core/java/com/android/server/notification/NotificationManagerService.java +36 −11 Original line number Diff line number Diff line Loading @@ -7480,16 +7480,24 @@ public class NotificationManagerService extends SystemService { // strip flag from all enqueued notifications. listeners will be informed // in post runnable. StatusBarNotification sbn = r.getSbn(); if (notificationForceGrouping()) { sbn.getNotification().flags = (r.getFlags() & ~flag); } else { sbn.getNotification().flags = (r.mOriginalFlags & ~flag); } } } NotificationRecord r = findNotificationByListLocked( mNotificationList, pkg, null, notificationId, userId); if (r != null) { // if posted notification exists, strip its flag and tell listeners StatusBarNotification sbn = r.getSbn(); if (notificationForceGrouping()) { sbn.getNotification().flags = (r.getFlags() & ~flag); } else { sbn.getNotification().flags = (r.mOriginalFlags & ~flag); } mRankingHelper.sort(mNotificationList); mListeners.notifyPostedLocked(r, r); } Loading Loading @@ -9486,6 +9494,28 @@ public class NotificationManagerService extends SystemService { return record.getCriticality() < CriticalNotificationExtractor.NORMAL; } /** * Check if the notification was a summary that has been auto-grouped * @param r the current notification record * @param old the previous notification record * @return true if the notification record was a summary that was auto-grouped */ @GuardedBy("mNotificationLock") private boolean wasSummaryAutogrouped(NotificationRecord r, NotificationRecord old) { boolean wasAutogrouped = false; if (old != null) { boolean wasSummary = (old.mOriginalFlags & FLAG_GROUP_SUMMARY) != 0; boolean wasForcedGrouped = (old.getFlags() & FLAG_GROUP_SUMMARY) == 0 && old.getSbn().getOverrideGroupKey() != null; boolean isNotAutogroupSummary = (r.getFlags() & FLAG_AUTOGROUP_SUMMARY) == 0 && (r.getFlags() & FLAG_GROUP_SUMMARY) != 0; if ((wasSummary && wasForcedGrouped) || (wasForcedGrouped && isNotAutogroupSummary)) { wasAutogrouped = true; } } return wasAutogrouped; } /** * Ensures that grouped notification receive their special treatment. * Loading @@ -9506,16 +9536,11 @@ public class NotificationManagerService extends SystemService { } 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) { if (wasSummaryAutogrouped(r, old)) { n.flags &= ~FLAG_GROUP_SUMMARY; } } } String group = sbn.getGroupKey(); boolean isSummary = n.isGroupSummary(); Loading services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java +23 −1 Original line number Diff line number Diff line Loading @@ -2662,6 +2662,17 @@ public class GroupHelperTest extends UiServiceTestCase { when(n.isColorized()).thenReturn(true); when(n.isStyle(Notification.CallStyle.class)).thenReturn(false); assertThat(GroupHelper.getSection(notification_colorFg)).isNull(); NotificationRecord notification_media = spy(getNotificationRecord(mPkg, 0, "", mUser, "", false, IMPORTANCE_LOW)); n = mock(Notification.class); sbn = spy(getSbn("package", 0, "0", UserHandle.SYSTEM)); when(notification_media.isConversation()).thenReturn(false); when(notification_media.getNotification()).thenReturn(n); when(notification_media.getSbn()).thenReturn(sbn); when(sbn.getNotification()).thenReturn(n); when(n.isMediaNotification()).thenReturn(true); assertThat(GroupHelper.getSection(notification_media)).isNull(); } @Test Loading Loading @@ -2756,7 +2767,7 @@ public class GroupHelperTest extends UiServiceTestCase { @Test @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING, FLAG_NOTIFICATION_FORCE_GROUP_CONVERSATIONS}) public void testNonGroupableNotifications_forceGroupConversations() { // Check that there is no valid section for: calls, foreground services // Check that there is no valid section for: calls, foreground services, media notifications NotificationRecord notification_call = spy(getNotificationRecord(mPkg, 0, "", mUser, "", false, IMPORTANCE_LOW)); Notification n = mock(Notification.class); Loading @@ -2780,6 +2791,17 @@ public class GroupHelperTest extends UiServiceTestCase { when(n.isColorized()).thenReturn(true); when(n.isStyle(Notification.CallStyle.class)).thenReturn(false); assertThat(GroupHelper.getSection(notification_colorFg)).isNull(); NotificationRecord notification_media = spy(getNotificationRecord(mPkg, 0, "", mUser, "", false, IMPORTANCE_LOW)); n = mock(Notification.class); sbn = spy(getSbn("package", 0, "0", UserHandle.SYSTEM)); when(notification_media.isConversation()).thenReturn(false); when(notification_media.getNotification()).thenReturn(n); when(notification_media.getSbn()).thenReturn(sbn); when(sbn.getNotification()).thenReturn(n); when(n.isMediaNotification()).thenReturn(true); assertThat(GroupHelper.getSection(notification_media)).isNull(); } @Test Loading services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +126 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import static android.app.Notification.FLAG_AUTO_CANCEL; 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_LIFETIME_EXTENDED_BY_DIRECT_REPLY; import static android.app.Notification.FLAG_NO_CLEAR; import static android.app.Notification.FLAG_NO_DISMISS; Loading Loading @@ -2871,6 +2872,131 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { verify(mGroupHelper, never()).onNotificationPostedWithDelay(eq(r), any(), any()); } @Test @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING) public void testEnqueueNotification_forceGrouped_clearsSummaryFlag() throws Exception { final String originalGroupName = "originalGroup"; final String aggregateGroupName = "Aggregate_Test"; // Old record was a summary and it was auto-grouped final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, originalGroupName, true); mService.addNotification(r); mService.convertSummaryToNotificationLocked(r.getKey()); mService.addAutogroupKeyLocked(r.getKey(), aggregateGroupName, true); assertThat(mService.mNotificationList).hasSize(1); // Update record is a summary final Notification updatedNotification = generateNotificationRecord( mTestNotificationChannel, 0, originalGroupName, true).getNotification(); assertThat(updatedNotification.flags & FLAG_GROUP_SUMMARY).isEqualTo(FLAG_GROUP_SUMMARY); mBinderService.enqueueNotificationWithTag(mPkg, mPkg, r.getSbn().getTag(), r.getSbn().getId(), updatedNotification, r.getSbn().getUserId()); waitForIdle(); // Check that FLAG_GROUP_SUMMARY was removed assertThat(mService.mNotificationList).hasSize(1); assertThat(mService.mNotificationList.get(0).getFlags() & FLAG_GROUP_SUMMARY).isEqualTo(0); } @Test @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING) public void testEnqueueNotification_forceGroupedRegular_updatedAsSummary_clearsSummaryFlag() throws Exception { final String originalGroupName = "originalGroup"; final String aggregateGroupName = "Aggregate_Test"; // Old record was not summary and it was auto-grouped final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, originalGroupName, false); mService.addNotification(r); mService.addAutogroupKeyLocked(r.getKey(), aggregateGroupName, true); assertThat(mService.mNotificationList).hasSize(1); // Update record is a summary final Notification updatedNotification = generateNotificationRecord( mTestNotificationChannel, 0, originalGroupName, true).getNotification(); assertThat(updatedNotification.flags & FLAG_GROUP_SUMMARY).isEqualTo(FLAG_GROUP_SUMMARY); mBinderService.enqueueNotificationWithTag(mPkg, mPkg, r.getSbn().getTag(), r.getSbn().getId(), updatedNotification, r.getSbn().getUserId()); waitForIdle(); // Check that FLAG_GROUP_SUMMARY was removed assertThat(mService.mNotificationList).hasSize(1); assertThat(mService.mNotificationList.get(0).getFlags() & FLAG_GROUP_SUMMARY).isEqualTo(0); } @Test @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING) public void testEnqueueNotification_notForceGrouped_dontClearSummaryFlag() throws Exception { final String originalGroupName = "originalGroup"; // Old record was a summary and it was not auto-grouped final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, originalGroupName, true); mService.addNotification(r); assertThat(mService.mNotificationList).hasSize(1); // Update record is a summary final Notification updatedNotification = generateNotificationRecord( mTestNotificationChannel, 0, originalGroupName, true).getNotification(); assertThat(updatedNotification.flags & FLAG_GROUP_SUMMARY).isEqualTo(FLAG_GROUP_SUMMARY); mBinderService.enqueueNotificationWithTag(mPkg, mPkg, r.getSbn().getTag(), r.getSbn().getId(), updatedNotification, r.getSbn().getUserId()); waitForIdle(); // Check that FLAG_GROUP_SUMMARY was not removed assertThat(mService.mNotificationList).hasSize(1); assertThat(mService.mNotificationList.get(0).getFlags() & FLAG_GROUP_SUMMARY).isEqualTo( FLAG_GROUP_SUMMARY); } @Test @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING) public void testRemoveFGSFlagFromNotification_enqueued_forceGrouped_clearsSummaryFlag() { final String originalGroupName = "originalGroup"; final String aggregateGroupName = "Aggregate_Test"; final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, null, originalGroupName, true); r.getSbn().getNotification().flags &= ~FLAG_GROUP_SUMMARY; r.setOverrideGroupKey(aggregateGroupName); mService.addEnqueuedNotification(r); mInternalService.removeForegroundServiceFlagFromNotification( mPkg, r.getSbn().getId(), r.getSbn().getUserId()); waitForIdle(); assertThat(mService.mEnqueuedNotifications).hasSize(1); assertThat(mService.mEnqueuedNotifications.get(0).getFlags() & FLAG_GROUP_SUMMARY) .isEqualTo(0); } @Test @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING) public void testRemoveFGSFlagFromNotification_posted_forceGrouped_clearsSummaryFlag() { final String originalGroupName = "originalGroup"; final String aggregateGroupName = "Aggregate_Test"; final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, null, originalGroupName, true); r.getSbn().getNotification().flags &= ~FLAG_GROUP_SUMMARY; r.setOverrideGroupKey(aggregateGroupName); mService.addNotification(r); mInternalService.removeForegroundServiceFlagFromNotification( mPkg, r.getSbn().getId(), r.getSbn().getUserId()); waitForIdle(); assertThat(mService.mNotificationList).hasSize(1); assertThat(mService.mNotificationList.get(0).getFlags() & FLAG_GROUP_SUMMARY).isEqualTo(0); } @Test public void testCancelAllNotifications_IgnoreForegroundService() throws Exception { when(mAmi.applyForegroundServiceNotification( Loading Loading
services/core/java/com/android/server/notification/GroupHelper.java +4 −0 Original line number Diff line number Diff line Loading @@ -1435,6 +1435,10 @@ public class GroupHelper { return false; } if (record.getSbn().getNotification().isMediaNotification()) { return false; } return true; } } Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +36 −11 Original line number Diff line number Diff line Loading @@ -7480,16 +7480,24 @@ public class NotificationManagerService extends SystemService { // strip flag from all enqueued notifications. listeners will be informed // in post runnable. StatusBarNotification sbn = r.getSbn(); if (notificationForceGrouping()) { sbn.getNotification().flags = (r.getFlags() & ~flag); } else { sbn.getNotification().flags = (r.mOriginalFlags & ~flag); } } } NotificationRecord r = findNotificationByListLocked( mNotificationList, pkg, null, notificationId, userId); if (r != null) { // if posted notification exists, strip its flag and tell listeners StatusBarNotification sbn = r.getSbn(); if (notificationForceGrouping()) { sbn.getNotification().flags = (r.getFlags() & ~flag); } else { sbn.getNotification().flags = (r.mOriginalFlags & ~flag); } mRankingHelper.sort(mNotificationList); mListeners.notifyPostedLocked(r, r); } Loading Loading @@ -9486,6 +9494,28 @@ public class NotificationManagerService extends SystemService { return record.getCriticality() < CriticalNotificationExtractor.NORMAL; } /** * Check if the notification was a summary that has been auto-grouped * @param r the current notification record * @param old the previous notification record * @return true if the notification record was a summary that was auto-grouped */ @GuardedBy("mNotificationLock") private boolean wasSummaryAutogrouped(NotificationRecord r, NotificationRecord old) { boolean wasAutogrouped = false; if (old != null) { boolean wasSummary = (old.mOriginalFlags & FLAG_GROUP_SUMMARY) != 0; boolean wasForcedGrouped = (old.getFlags() & FLAG_GROUP_SUMMARY) == 0 && old.getSbn().getOverrideGroupKey() != null; boolean isNotAutogroupSummary = (r.getFlags() & FLAG_AUTOGROUP_SUMMARY) == 0 && (r.getFlags() & FLAG_GROUP_SUMMARY) != 0; if ((wasSummary && wasForcedGrouped) || (wasForcedGrouped && isNotAutogroupSummary)) { wasAutogrouped = true; } } return wasAutogrouped; } /** * Ensures that grouped notification receive their special treatment. * Loading @@ -9506,16 +9536,11 @@ public class NotificationManagerService extends SystemService { } 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) { if (wasSummaryAutogrouped(r, old)) { n.flags &= ~FLAG_GROUP_SUMMARY; } } } String group = sbn.getGroupKey(); boolean isSummary = n.isGroupSummary(); Loading
services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java +23 −1 Original line number Diff line number Diff line Loading @@ -2662,6 +2662,17 @@ public class GroupHelperTest extends UiServiceTestCase { when(n.isColorized()).thenReturn(true); when(n.isStyle(Notification.CallStyle.class)).thenReturn(false); assertThat(GroupHelper.getSection(notification_colorFg)).isNull(); NotificationRecord notification_media = spy(getNotificationRecord(mPkg, 0, "", mUser, "", false, IMPORTANCE_LOW)); n = mock(Notification.class); sbn = spy(getSbn("package", 0, "0", UserHandle.SYSTEM)); when(notification_media.isConversation()).thenReturn(false); when(notification_media.getNotification()).thenReturn(n); when(notification_media.getSbn()).thenReturn(sbn); when(sbn.getNotification()).thenReturn(n); when(n.isMediaNotification()).thenReturn(true); assertThat(GroupHelper.getSection(notification_media)).isNull(); } @Test Loading Loading @@ -2756,7 +2767,7 @@ public class GroupHelperTest extends UiServiceTestCase { @Test @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING, FLAG_NOTIFICATION_FORCE_GROUP_CONVERSATIONS}) public void testNonGroupableNotifications_forceGroupConversations() { // Check that there is no valid section for: calls, foreground services // Check that there is no valid section for: calls, foreground services, media notifications NotificationRecord notification_call = spy(getNotificationRecord(mPkg, 0, "", mUser, "", false, IMPORTANCE_LOW)); Notification n = mock(Notification.class); Loading @@ -2780,6 +2791,17 @@ public class GroupHelperTest extends UiServiceTestCase { when(n.isColorized()).thenReturn(true); when(n.isStyle(Notification.CallStyle.class)).thenReturn(false); assertThat(GroupHelper.getSection(notification_colorFg)).isNull(); NotificationRecord notification_media = spy(getNotificationRecord(mPkg, 0, "", mUser, "", false, IMPORTANCE_LOW)); n = mock(Notification.class); sbn = spy(getSbn("package", 0, "0", UserHandle.SYSTEM)); when(notification_media.isConversation()).thenReturn(false); when(notification_media.getNotification()).thenReturn(n); when(notification_media.getSbn()).thenReturn(sbn); when(sbn.getNotification()).thenReturn(n); when(n.isMediaNotification()).thenReturn(true); assertThat(GroupHelper.getSection(notification_media)).isNull(); } @Test Loading
services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +126 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import static android.app.Notification.FLAG_AUTO_CANCEL; 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_LIFETIME_EXTENDED_BY_DIRECT_REPLY; import static android.app.Notification.FLAG_NO_CLEAR; import static android.app.Notification.FLAG_NO_DISMISS; Loading Loading @@ -2871,6 +2872,131 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { verify(mGroupHelper, never()).onNotificationPostedWithDelay(eq(r), any(), any()); } @Test @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING) public void testEnqueueNotification_forceGrouped_clearsSummaryFlag() throws Exception { final String originalGroupName = "originalGroup"; final String aggregateGroupName = "Aggregate_Test"; // Old record was a summary and it was auto-grouped final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, originalGroupName, true); mService.addNotification(r); mService.convertSummaryToNotificationLocked(r.getKey()); mService.addAutogroupKeyLocked(r.getKey(), aggregateGroupName, true); assertThat(mService.mNotificationList).hasSize(1); // Update record is a summary final Notification updatedNotification = generateNotificationRecord( mTestNotificationChannel, 0, originalGroupName, true).getNotification(); assertThat(updatedNotification.flags & FLAG_GROUP_SUMMARY).isEqualTo(FLAG_GROUP_SUMMARY); mBinderService.enqueueNotificationWithTag(mPkg, mPkg, r.getSbn().getTag(), r.getSbn().getId(), updatedNotification, r.getSbn().getUserId()); waitForIdle(); // Check that FLAG_GROUP_SUMMARY was removed assertThat(mService.mNotificationList).hasSize(1); assertThat(mService.mNotificationList.get(0).getFlags() & FLAG_GROUP_SUMMARY).isEqualTo(0); } @Test @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING) public void testEnqueueNotification_forceGroupedRegular_updatedAsSummary_clearsSummaryFlag() throws Exception { final String originalGroupName = "originalGroup"; final String aggregateGroupName = "Aggregate_Test"; // Old record was not summary and it was auto-grouped final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, originalGroupName, false); mService.addNotification(r); mService.addAutogroupKeyLocked(r.getKey(), aggregateGroupName, true); assertThat(mService.mNotificationList).hasSize(1); // Update record is a summary final Notification updatedNotification = generateNotificationRecord( mTestNotificationChannel, 0, originalGroupName, true).getNotification(); assertThat(updatedNotification.flags & FLAG_GROUP_SUMMARY).isEqualTo(FLAG_GROUP_SUMMARY); mBinderService.enqueueNotificationWithTag(mPkg, mPkg, r.getSbn().getTag(), r.getSbn().getId(), updatedNotification, r.getSbn().getUserId()); waitForIdle(); // Check that FLAG_GROUP_SUMMARY was removed assertThat(mService.mNotificationList).hasSize(1); assertThat(mService.mNotificationList.get(0).getFlags() & FLAG_GROUP_SUMMARY).isEqualTo(0); } @Test @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING) public void testEnqueueNotification_notForceGrouped_dontClearSummaryFlag() throws Exception { final String originalGroupName = "originalGroup"; // Old record was a summary and it was not auto-grouped final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, originalGroupName, true); mService.addNotification(r); assertThat(mService.mNotificationList).hasSize(1); // Update record is a summary final Notification updatedNotification = generateNotificationRecord( mTestNotificationChannel, 0, originalGroupName, true).getNotification(); assertThat(updatedNotification.flags & FLAG_GROUP_SUMMARY).isEqualTo(FLAG_GROUP_SUMMARY); mBinderService.enqueueNotificationWithTag(mPkg, mPkg, r.getSbn().getTag(), r.getSbn().getId(), updatedNotification, r.getSbn().getUserId()); waitForIdle(); // Check that FLAG_GROUP_SUMMARY was not removed assertThat(mService.mNotificationList).hasSize(1); assertThat(mService.mNotificationList.get(0).getFlags() & FLAG_GROUP_SUMMARY).isEqualTo( FLAG_GROUP_SUMMARY); } @Test @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING) public void testRemoveFGSFlagFromNotification_enqueued_forceGrouped_clearsSummaryFlag() { final String originalGroupName = "originalGroup"; final String aggregateGroupName = "Aggregate_Test"; final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, null, originalGroupName, true); r.getSbn().getNotification().flags &= ~FLAG_GROUP_SUMMARY; r.setOverrideGroupKey(aggregateGroupName); mService.addEnqueuedNotification(r); mInternalService.removeForegroundServiceFlagFromNotification( mPkg, r.getSbn().getId(), r.getSbn().getUserId()); waitForIdle(); assertThat(mService.mEnqueuedNotifications).hasSize(1); assertThat(mService.mEnqueuedNotifications.get(0).getFlags() & FLAG_GROUP_SUMMARY) .isEqualTo(0); } @Test @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING) public void testRemoveFGSFlagFromNotification_posted_forceGrouped_clearsSummaryFlag() { final String originalGroupName = "originalGroup"; final String aggregateGroupName = "Aggregate_Test"; final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, null, originalGroupName, true); r.getSbn().getNotification().flags &= ~FLAG_GROUP_SUMMARY; r.setOverrideGroupKey(aggregateGroupName); mService.addNotification(r); mInternalService.removeForegroundServiceFlagFromNotification( mPkg, r.getSbn().getId(), r.getSbn().getUserId()); waitForIdle(); assertThat(mService.mNotificationList).hasSize(1); assertThat(mService.mNotificationList.get(0).getFlags() & FLAG_GROUP_SUMMARY).isEqualTo(0); } @Test public void testCancelAllNotifications_IgnoreForegroundService() throws Exception { when(mAmi.applyForegroundServiceNotification( Loading