Loading services/core/java/com/android/server/notification/GroupHelper.java +19 −3 Original line number Original line Diff line number Diff line Loading @@ -840,7 +840,23 @@ public class GroupHelper { Log.i(TAG, "isGroupChildWithoutSummary OR isGroupSummaryWithoutChild" Log.i(TAG, "isGroupChildWithoutSummary OR isGroupSummaryWithoutChild" + record); + record); } } boolean aggregated = addToUngroupedAndMaybeAggregate(record, fullAggregateGroupKey, sectioner); addToUngroupedAndMaybeAggregate(record, fullAggregateGroupKey, sectioner); if (android.service.notification.Flags.notificationClassification()) { if (!aggregated && isSummaryWithAllChildrenBundled(record, notificationList, new ArrayList<>())) { // Cancel the summary and cache it if does not get aggregated // in order to avoid empty summaries if (DEBUG) { Slog.i(TAG, "Empty group summary to be canceled and cached: " + record); } mCallback.removeAppProvidedSummary(record.getKey()); cacheCanceledSummary(record); } } return; return; } } Loading Loading @@ -1660,7 +1676,7 @@ public class GroupHelper { // Find all posted children for this summary // Find all posted children for this summary for (NotificationRecord r : postedNotificationsList) { for (NotificationRecord r : postedNotificationsList) { if (!r.getNotification().isGroupSummary() if (!r.getNotification().isGroupSummary() && groupKey.equals(r.getSbn().getGroup())) { && groupKey.equals(r.getSbn().getNotification().getGroup())) { numChildren++; numChildren++; if (isInBundleSection(r)) { if (isInBundleSection(r)) { numBundledChildren++; numBundledChildren++; Loading @@ -1670,7 +1686,7 @@ public class GroupHelper { // Find all enqueued children for this summary // Find all enqueued children for this summary for (NotificationRecord r : enqueuedNotificationsList) { for (NotificationRecord r : enqueuedNotificationsList) { if (!r.getNotification().isGroupSummary() if (!r.getNotification().isGroupSummary() && groupKey.equals(r.getSbn().getGroup())) { && groupKey.equals(r.getSbn().getNotification().getGroup())) { numChildren++; numChildren++; if (isInBundleSection(r)) { if (isInBundleSection(r)) { numBundledChildren++; numBundledChildren++; Loading services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +113 −0 Original line number Original line Diff line number Diff line Loading @@ -20016,6 +20016,119 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertThat(s.getNotification().flags & FLAG_SILENT).isEqualTo(FLAG_SILENT); assertThat(s.getNotification().flags & FLAG_SILENT).isEqualTo(FLAG_SILENT); } } @Test @EnableFlags(FLAG_NOTIFICATION_CLASSIFICATION) public void testAllChildrenBundled_summaryCanceled() throws Exception { when(mAssistants.isClassificationTypeAllowed(anyInt(), anyInt())).thenReturn(true); when(mAssistants.isAdjustmentAllowedForPackage(anyInt(), anyString(), anyString())).thenReturn(true); when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true); // Create a group with 2 children and a summary final String originalGroupName = "originalGroup"; final int summaryId = 0; // Post the child notifications first and bundle them immediately final NotificationRecord r1 = generateNotificationRecord(mTestNotificationChannel, summaryId + 1, originalGroupName, false); mService.addNotification(r1); Bundle signals = new Bundle(); signals.putInt(KEY_TYPE, TYPE_NEWS); Adjustment adjustment = new Adjustment(r1.getSbn().getPackageName(), r1.getKey(), signals, "", r1.getUser().getIdentifier()); mBinderService.applyAdjustmentFromAssistant(null, adjustment); waitForIdle(); r1.applyAdjustments(); r1.setOverrideGroupKey("newsBundleGroup"); assertThat(r1.getChannel().getId()).isEqualTo(NEWS_ID); final NotificationRecord r2 = generateNotificationRecord(mTestNotificationChannel, summaryId + 2, originalGroupName, false); mService.addNotification(r2); signals.putInt(KEY_TYPE, TYPE_PROMOTION); adjustment = new Adjustment(r2.getSbn().getPackageName(), r2.getKey(), signals, "", r2.getUser().getIdentifier()); mBinderService.applyAdjustmentFromAssistant(null, adjustment); waitForIdle(); r2.applyAdjustments(); r2.setOverrideGroupKey("promotionsBundleGroup"); assertThat(r2.getChannel().getId()).isEqualTo(PROMOTIONS_ID); // Post summary final NotificationRecord summary = generateNotificationRecord(mTestNotificationChannel, summaryId, originalGroupName, true); mService.addEnqueuedNotification(summary); mService.new PostNotificationRunnable(summary.getKey(), summary.getSbn().getPackageName(), summary.getUid(), mPostNotificationTrackerFactory.newTracker(null)).run(); waitForIdle(); // Check that the summary has FLAG_SILENT set NotificationRecord s = mService.findNotificationLocked(summary.getSbn().getPackageName(), summary.getSbn().getTag(), summary.getSbn().getId(), summary.getSbn().getUserId()); assertThat(s).isNotNull(); assertThat(s.getNotification().flags & FLAG_SILENT).isEqualTo(FLAG_SILENT); // Advance DELAY_FORCE_REGROUP_TIME: calls GroupHelper.onNotificationPostedWithDelay moveTimeForwardAndWaitForIdle(DELAY_FORCE_REGROUP_TIME); // Check that the summary was canceled and cached in GroupHelper s = mService.findNotificationLocked(summary.getSbn().getPackageName(), summary.getSbn().getTag(), summary.getSbn().getId(), summary.getSbn().getUserId()); assertThat(s).isNull(); assertThat(mGroupHelper.findCanceledSummary(summary.getSbn().getPackageName(), summary.getSbn().getTag(), summary.getSbn().getId(), summary.getSbn().getUserId(), summary.getSbn().getNotification().getGroup())).isNotNull(); } @Test @EnableFlags(FLAG_NOTIFICATION_CLASSIFICATION) public void testSomeChildrenBundled_summaryNotCanceled() throws Exception { when(mAssistants.isClassificationTypeAllowed(anyInt(), anyInt())).thenReturn(true); when(mAssistants.isAdjustmentAllowedForPackage(anyInt(), anyString(), anyString())).thenReturn(true); when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true); // Create a group with 2 children and a summary final String originalGroupName = "originalGroup"; final int summaryId = 0; // Post the child notifications first and bundle one of them final NotificationRecord r1 = generateNotificationRecord(mTestNotificationChannel, summaryId + 1, originalGroupName, false); mService.addNotification(r1); Bundle signals = new Bundle(); signals.putInt(KEY_TYPE, TYPE_NEWS); Adjustment adjustment = new Adjustment(r1.getSbn().getPackageName(), r1.getKey(), signals, "", r1.getUser().getIdentifier()); mBinderService.applyAdjustmentFromAssistant(null, adjustment); waitForIdle(); r1.applyAdjustments(); r1.setOverrideGroupKey("newsBundleGroup"); assertThat(r1.getChannel().getId()).isEqualTo(NEWS_ID); final NotificationRecord r2 = generateNotificationRecord(mTestNotificationChannel, summaryId + 2, originalGroupName, false); mService.addNotification(r2); waitForIdle(); // Post summary final NotificationRecord summary = generateNotificationRecord(mTestNotificationChannel, summaryId, originalGroupName, true); mService.addEnqueuedNotification(summary); mService.new PostNotificationRunnable(summary.getKey(), summary.getSbn().getPackageName(), summary.getUid(), mPostNotificationTrackerFactory.newTracker(null)).run(); moveTimeForwardAndWaitForIdle(DELAY_FORCE_REGROUP_TIME); // Check that the summary was not canceled and does NOT have FLAG_SILENT set NotificationRecord s = mService.findNotificationLocked(summary.getSbn().getPackageName(), summary.getSbn().getTag(), summary.getSbn().getId(), summary.getSbn().getUserId()); assertThat(s).isEqualTo(summary); assertThat(s.getNotification().flags & FLAG_SILENT).isEqualTo(0); } @Test @Test @EnableFlags({FLAG_NM_SUMMARIZATION}) @EnableFlags({FLAG_NM_SUMMARIZATION}) public void testDisableBundleAdjustment_unsummarizesNotifications() throws Exception { public void testDisableBundleAdjustment_unsummarizesNotifications() throws Exception { Loading
services/core/java/com/android/server/notification/GroupHelper.java +19 −3 Original line number Original line Diff line number Diff line Loading @@ -840,7 +840,23 @@ public class GroupHelper { Log.i(TAG, "isGroupChildWithoutSummary OR isGroupSummaryWithoutChild" Log.i(TAG, "isGroupChildWithoutSummary OR isGroupSummaryWithoutChild" + record); + record); } } boolean aggregated = addToUngroupedAndMaybeAggregate(record, fullAggregateGroupKey, sectioner); addToUngroupedAndMaybeAggregate(record, fullAggregateGroupKey, sectioner); if (android.service.notification.Flags.notificationClassification()) { if (!aggregated && isSummaryWithAllChildrenBundled(record, notificationList, new ArrayList<>())) { // Cancel the summary and cache it if does not get aggregated // in order to avoid empty summaries if (DEBUG) { Slog.i(TAG, "Empty group summary to be canceled and cached: " + record); } mCallback.removeAppProvidedSummary(record.getKey()); cacheCanceledSummary(record); } } return; return; } } Loading Loading @@ -1660,7 +1676,7 @@ public class GroupHelper { // Find all posted children for this summary // Find all posted children for this summary for (NotificationRecord r : postedNotificationsList) { for (NotificationRecord r : postedNotificationsList) { if (!r.getNotification().isGroupSummary() if (!r.getNotification().isGroupSummary() && groupKey.equals(r.getSbn().getGroup())) { && groupKey.equals(r.getSbn().getNotification().getGroup())) { numChildren++; numChildren++; if (isInBundleSection(r)) { if (isInBundleSection(r)) { numBundledChildren++; numBundledChildren++; Loading @@ -1670,7 +1686,7 @@ public class GroupHelper { // Find all enqueued children for this summary // Find all enqueued children for this summary for (NotificationRecord r : enqueuedNotificationsList) { for (NotificationRecord r : enqueuedNotificationsList) { if (!r.getNotification().isGroupSummary() if (!r.getNotification().isGroupSummary() && groupKey.equals(r.getSbn().getGroup())) { && groupKey.equals(r.getSbn().getNotification().getGroup())) { numChildren++; numChildren++; if (isInBundleSection(r)) { if (isInBundleSection(r)) { numBundledChildren++; numBundledChildren++; Loading
services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +113 −0 Original line number Original line Diff line number Diff line Loading @@ -20016,6 +20016,119 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertThat(s.getNotification().flags & FLAG_SILENT).isEqualTo(FLAG_SILENT); assertThat(s.getNotification().flags & FLAG_SILENT).isEqualTo(FLAG_SILENT); } } @Test @EnableFlags(FLAG_NOTIFICATION_CLASSIFICATION) public void testAllChildrenBundled_summaryCanceled() throws Exception { when(mAssistants.isClassificationTypeAllowed(anyInt(), anyInt())).thenReturn(true); when(mAssistants.isAdjustmentAllowedForPackage(anyInt(), anyString(), anyString())).thenReturn(true); when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true); // Create a group with 2 children and a summary final String originalGroupName = "originalGroup"; final int summaryId = 0; // Post the child notifications first and bundle them immediately final NotificationRecord r1 = generateNotificationRecord(mTestNotificationChannel, summaryId + 1, originalGroupName, false); mService.addNotification(r1); Bundle signals = new Bundle(); signals.putInt(KEY_TYPE, TYPE_NEWS); Adjustment adjustment = new Adjustment(r1.getSbn().getPackageName(), r1.getKey(), signals, "", r1.getUser().getIdentifier()); mBinderService.applyAdjustmentFromAssistant(null, adjustment); waitForIdle(); r1.applyAdjustments(); r1.setOverrideGroupKey("newsBundleGroup"); assertThat(r1.getChannel().getId()).isEqualTo(NEWS_ID); final NotificationRecord r2 = generateNotificationRecord(mTestNotificationChannel, summaryId + 2, originalGroupName, false); mService.addNotification(r2); signals.putInt(KEY_TYPE, TYPE_PROMOTION); adjustment = new Adjustment(r2.getSbn().getPackageName(), r2.getKey(), signals, "", r2.getUser().getIdentifier()); mBinderService.applyAdjustmentFromAssistant(null, adjustment); waitForIdle(); r2.applyAdjustments(); r2.setOverrideGroupKey("promotionsBundleGroup"); assertThat(r2.getChannel().getId()).isEqualTo(PROMOTIONS_ID); // Post summary final NotificationRecord summary = generateNotificationRecord(mTestNotificationChannel, summaryId, originalGroupName, true); mService.addEnqueuedNotification(summary); mService.new PostNotificationRunnable(summary.getKey(), summary.getSbn().getPackageName(), summary.getUid(), mPostNotificationTrackerFactory.newTracker(null)).run(); waitForIdle(); // Check that the summary has FLAG_SILENT set NotificationRecord s = mService.findNotificationLocked(summary.getSbn().getPackageName(), summary.getSbn().getTag(), summary.getSbn().getId(), summary.getSbn().getUserId()); assertThat(s).isNotNull(); assertThat(s.getNotification().flags & FLAG_SILENT).isEqualTo(FLAG_SILENT); // Advance DELAY_FORCE_REGROUP_TIME: calls GroupHelper.onNotificationPostedWithDelay moveTimeForwardAndWaitForIdle(DELAY_FORCE_REGROUP_TIME); // Check that the summary was canceled and cached in GroupHelper s = mService.findNotificationLocked(summary.getSbn().getPackageName(), summary.getSbn().getTag(), summary.getSbn().getId(), summary.getSbn().getUserId()); assertThat(s).isNull(); assertThat(mGroupHelper.findCanceledSummary(summary.getSbn().getPackageName(), summary.getSbn().getTag(), summary.getSbn().getId(), summary.getSbn().getUserId(), summary.getSbn().getNotification().getGroup())).isNotNull(); } @Test @EnableFlags(FLAG_NOTIFICATION_CLASSIFICATION) public void testSomeChildrenBundled_summaryNotCanceled() throws Exception { when(mAssistants.isClassificationTypeAllowed(anyInt(), anyInt())).thenReturn(true); when(mAssistants.isAdjustmentAllowedForPackage(anyInt(), anyString(), anyString())).thenReturn(true); when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true); // Create a group with 2 children and a summary final String originalGroupName = "originalGroup"; final int summaryId = 0; // Post the child notifications first and bundle one of them final NotificationRecord r1 = generateNotificationRecord(mTestNotificationChannel, summaryId + 1, originalGroupName, false); mService.addNotification(r1); Bundle signals = new Bundle(); signals.putInt(KEY_TYPE, TYPE_NEWS); Adjustment adjustment = new Adjustment(r1.getSbn().getPackageName(), r1.getKey(), signals, "", r1.getUser().getIdentifier()); mBinderService.applyAdjustmentFromAssistant(null, adjustment); waitForIdle(); r1.applyAdjustments(); r1.setOverrideGroupKey("newsBundleGroup"); assertThat(r1.getChannel().getId()).isEqualTo(NEWS_ID); final NotificationRecord r2 = generateNotificationRecord(mTestNotificationChannel, summaryId + 2, originalGroupName, false); mService.addNotification(r2); waitForIdle(); // Post summary final NotificationRecord summary = generateNotificationRecord(mTestNotificationChannel, summaryId, originalGroupName, true); mService.addEnqueuedNotification(summary); mService.new PostNotificationRunnable(summary.getKey(), summary.getSbn().getPackageName(), summary.getUid(), mPostNotificationTrackerFactory.newTracker(null)).run(); moveTimeForwardAndWaitForIdle(DELAY_FORCE_REGROUP_TIME); // Check that the summary was not canceled and does NOT have FLAG_SILENT set NotificationRecord s = mService.findNotificationLocked(summary.getSbn().getPackageName(), summary.getSbn().getTag(), summary.getSbn().getId(), summary.getSbn().getUserId()); assertThat(s).isEqualTo(summary); assertThat(s.getNotification().flags & FLAG_SILENT).isEqualTo(0); } @Test @Test @EnableFlags({FLAG_NM_SUMMARIZATION}) @EnableFlags({FLAG_NM_SUMMARIZATION}) public void testDisableBundleAdjustment_unsummarizesNotifications() throws Exception { public void testDisableBundleAdjustment_unsummarizesNotifications() throws Exception {