summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/notification/GroupHelper.java47
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java40
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java80
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java53
4 files changed, 167 insertions, 53 deletions
diff --git a/services/core/java/com/android/server/notification/GroupHelper.java b/services/core/java/com/android/server/notification/GroupHelper.java
index 02f817e9cd44..6e5308e56aa8 100644
--- a/services/core/java/com/android/server/notification/GroupHelper.java
+++ b/services/core/java/com/android/server/notification/GroupHelper.java
@@ -35,6 +35,7 @@ import android.app.ActivityManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
+import android.app.PendingIntent;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -130,8 +131,10 @@ public class GroupHelper {
mUngroupedAbuseNotifications = new ArrayMap<>();
// Contains the list of group summaries that were canceled when "singleton groups" were
- // force grouped. Used to remove the original group's children when an app cancels the
- // already removed summary. Key is userId|packageName|g:OriginalGroupName
+ // force grouped. Key is userId|packageName|g:OriginalGroupName. Used to:
+ // 1) remove the original group's children when an app cancels the already removed summary.
+ // 2) perform the same side effects that would happen if the group is removed because
+ // all its force-regrouped children are removed (e.g. firing its deleteIntent).
@GuardedBy("mAggregatedNotifications")
private final ArrayMap<FullyQualifiedGroupKey, CachedSummary>
mCanceledSummaries = new ArrayMap<>();
@@ -278,7 +281,11 @@ public class GroupHelper {
public void onNotificationRemoved(NotificationRecord record) {
try {
if (notificationForceGrouping()) {
- onNotificationRemoved(record, new ArrayList<>());
+ Slog.wtf(TAG,
+ "This overload of onNotificationRemoved() should not be called if "
+ + "notification_force_grouping is enabled!",
+ new Exception("call stack"));
+ onNotificationRemoved(record, new ArrayList<>(), false);
} else {
final StatusBarNotification sbn = record.getSbn();
maybeUngroup(sbn, true, sbn.getUserId());
@@ -926,10 +933,12 @@ public class GroupHelper {
*
* @param record the removed notification
* @param notificationList the full notification list from NotificationManagerService
+ * @param sendingDelete whether the removed notification is being removed in a way that sends
+ * its {@code deleteIntent}
*/
@FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_FORCE_GROUPING)
protected void onNotificationRemoved(final NotificationRecord record,
- final List<NotificationRecord> notificationList) {
+ final List<NotificationRecord> notificationList, boolean sendingDelete) {
final StatusBarNotification sbn = record.getSbn();
final String pkgName = sbn.getPackageName();
final int userId = record.getUserId();
@@ -973,9 +982,11 @@ public class GroupHelper {
}
// Try to cleanup cached summaries if notification was canceled (not snoozed)
+ // If the notification was cancelled by an action that fires its delete intent,
+ // also fire it for the cached summary.
if (record.isCanceled) {
maybeClearCanceledSummariesCache(pkgName, userId,
- record.getNotification().getGroup(), notificationList);
+ record.getNotification().getGroup(), notificationList, sendingDelete);
}
}
}
@@ -1759,13 +1770,18 @@ public class GroupHelper {
private void cacheCanceledSummary(NotificationRecord record) {
final FullyQualifiedGroupKey groupKey = new FullyQualifiedGroupKey(record.getUserId(),
record.getSbn().getPackageName(), record.getNotification().getGroup());
- mCanceledSummaries.put(groupKey, new CachedSummary(record.getSbn().getId(),
- record.getSbn().getTag(), record.getNotification().getGroup(), record.getKey()));
+ mCanceledSummaries.put(groupKey, new CachedSummary(
+ record.getSbn().getId(),
+ record.getSbn().getTag(),
+ record.getNotification().getGroup(),
+ record.getKey(),
+ record.getNotification().deleteIntent));
}
@GuardedBy("mAggregatedNotifications")
private void maybeClearCanceledSummariesCache(String pkgName, int userId,
- String groupName, List<NotificationRecord> notificationList) {
+ String groupName, List<NotificationRecord> notificationList,
+ boolean sendSummaryDelete) {
final FullyQualifiedGroupKey findKey = new FullyQualifiedGroupKey(userId, pkgName,
groupName);
CachedSummary summary = mCanceledSummaries.get(findKey);
@@ -1786,6 +1802,9 @@ public class GroupHelper {
}
if (!stillHasChildren) {
removeCachedSummary(pkgName, userId, summary);
+ if (sendSummaryDelete && summary.deleteIntent != null) {
+ mCallback.sendAppProvidedSummaryDeleteIntent(pkgName, summary.deleteIntent);
+ }
}
}
}
@@ -1965,7 +1984,8 @@ public class GroupHelper {
}
}
- record CachedSummary(int id, String tag, String originalGroupKey, String key) {}
+ record CachedSummary(int id, String tag, String originalGroupKey, String key,
+ @Nullable PendingIntent deleteIntent) { }
protected static class NotificationAttributes {
public final int flags;
@@ -2035,6 +2055,15 @@ public class GroupHelper {
// New callbacks for API abuse grouping
void removeAppProvidedSummary(String key);
+ /**
+ * Send a cached summary's deleteIntent, when the last of its original children is removed.
+ *
+ * <p>While technically the group summary was "canceled" much earlier (because it was the
+ * summary of a sparse group and its children got reparented), the posting package expected
+ * the summary's deleteIntent to fire when the summary is auto-dismissed.
+ */
+ void sendAppProvidedSummaryDeleteIntent(String pkg, PendingIntent deleteIntent);
+
void removeNotificationFromCanceledGroup(int userId, String pkg, String groupKey,
int cancelReason);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 6fddfb5f90a7..60371d751c4a 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -3211,6 +3211,11 @@ public class NotificationManagerService extends SystemService {
}
@Override
+ public void sendAppProvidedSummaryDeleteIntent(String pkg, PendingIntent deleteIntent) {
+ sendDeleteIntent(deleteIntent, pkg);
+ }
+
+ @Override
public void removeNotificationFromCanceledGroup(int userId, String pkg,
String groupKey, int cancelReason) {
synchronized (mNotificationLock) {
@@ -9898,7 +9903,8 @@ public class NotificationManagerService extends SystemService {
if (notificationForceGrouping()) {
mHandler.post(() -> {
synchronized (mNotificationLock) {
- mGroupHelper.onNotificationRemoved(r, mNotificationList);
+ mGroupHelper.onNotificationRemoved(r, mNotificationList,
+ /* sendingDelete= */ false);
}
});
} else {
@@ -10826,20 +10832,7 @@ public class NotificationManagerService extends SystemService {
// tell the app
if (sendDelete) {
- final PendingIntent deleteIntent = r.getNotification().deleteIntent;
- if (deleteIntent != null) {
- try {
- // make sure deleteIntent cannot be used to start activities from background
- LocalServices.getService(ActivityManagerInternal.class)
- .clearPendingIntentAllowBgActivityStarts(deleteIntent.getTarget(),
- ALLOWLIST_TOKEN);
- deleteIntent.send();
- } catch (PendingIntent.CanceledException ex) {
- // do nothing - there's no relevant way to recover, and
- // no reason to let this propagate
- Slog.w(TAG, "canceled PendingIntent for " + r.getSbn().getPackageName(), ex);
- }
- }
+ sendDeleteIntent(r.getNotification().deleteIntent, r.getSbn().getPackageName());
}
// Only cancel these if this notification actually got to be posted.
@@ -10854,7 +10847,7 @@ public class NotificationManagerService extends SystemService {
mHandler.removeCallbacksAndEqualMessages(r.getKey());
mHandler.post(() -> {
synchronized (NotificationManagerService.this.mNotificationLock) {
- mGroupHelper.onNotificationRemoved(r, mNotificationList);
+ mGroupHelper.onNotificationRemoved(r, mNotificationList, sendDelete);
}
});
@@ -10952,6 +10945,21 @@ public class NotificationManagerService extends SystemService {
}
}
+ private static void sendDeleteIntent(@Nullable PendingIntent deleteIntent, String fromPkg) {
+ if (deleteIntent != null) {
+ try {
+ // make sure deleteIntent cannot be used to start activities from background
+ LocalServices.getService(ActivityManagerInternal.class)
+ .clearPendingIntentAllowBgActivityStarts(deleteIntent.getTarget(),
+ ALLOWLIST_TOKEN);
+ deleteIntent.send();
+ } catch (PendingIntent.CanceledException ex) {
+ // There's no relevant way to recover, and no reason to let this propagate
+ Slog.w(TAG, "canceled PendingIntent for " + fromPkg, ex);
+ }
+ }
+ }
+
@VisibleForTesting
void updateUriPermissions(@Nullable NotificationRecord newRecord,
@Nullable NotificationRecord oldRecord, String targetPkg, int targetUserId) {
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
index 4a977be2aad9..4eac1d126202 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
@@ -66,6 +66,8 @@ import static org.mockito.Mockito.when;
import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationChannel;
+import android.app.PendingIntent;
+import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.drawable.AdaptiveIconDrawable;
@@ -620,6 +622,7 @@ public class GroupHelperTest extends UiServiceTestCase {
}
@Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
public void testAutoGrouped_singleOngoing_removeOngoingChild() {
final String pkg = "package";
@@ -639,7 +642,7 @@ public class GroupHelperTest extends UiServiceTestCase {
}
// remove ongoing
- mGroupHelper.onNotificationRemoved(notifications.get(0));
+ mGroupHelper.onNotificationRemoved(notifications.get(0), new ArrayList<>(), false);
// Summary is no longer ongoing
verify(mCallback).updateAutogroupSummary(anyInt(), anyString(), anyString(),
@@ -776,7 +779,7 @@ public class GroupHelperTest extends UiServiceTestCase {
}
// remove ongoing
- mGroupHelper.onNotificationRemoved(notifications.get(1));
+ mGroupHelper.onNotificationRemoved(notifications.get(1), new ArrayList<>(), false);
// Summary is still ongoing
verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
@@ -936,7 +939,7 @@ public class GroupHelperTest extends UiServiceTestCase {
mGroupHelper.onNotificationPosted(r, false);
}
- mGroupHelper.onNotificationRemoved(notifications.get(0));
+ mGroupHelper.onNotificationRemoved(notifications.get(0), new ArrayList<>(), false);
// Summary should still be autocancelable
verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
@@ -944,6 +947,7 @@ public class GroupHelperTest extends UiServiceTestCase {
}
@Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
@DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
public void testDropToZeroRemoveGroup_disableFlag() {
final String pkg = "package";
@@ -963,19 +967,20 @@ public class GroupHelperTest extends UiServiceTestCase {
Mockito.reset(mCallback);
for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
- mGroupHelper.onNotificationRemoved(posted.remove(0));
+ mGroupHelper.onNotificationRemoved(posted.remove(0), new ArrayList<>(), false);
}
verify(mCallback, never()).removeAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
Mockito.reset(mCallback);
- mGroupHelper.onNotificationRemoved(posted.remove(0));
+ mGroupHelper.onNotificationRemoved(posted.remove(0), new ArrayList<>(), false);
verify(mCallback, never()).removeAutoGroup(anyString());
verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString(), anyString());
}
@Test
- @EnableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
+ @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+ android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST})
public void testDropToZeroRemoveGroup() {
final String pkg = "package";
ArrayList<NotificationRecord> posted = new ArrayList<>();
@@ -994,13 +999,13 @@ public class GroupHelperTest extends UiServiceTestCase {
Mockito.reset(mCallback);
for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
- mGroupHelper.onNotificationRemoved(posted.remove(0));
+ mGroupHelper.onNotificationRemoved(posted.remove(0), new ArrayList<>(), false);
}
verify(mCallback, never()).removeAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
Mockito.reset(mCallback);
- mGroupHelper.onNotificationRemoved(posted.remove(0));
+ mGroupHelper.onNotificationRemoved(posted.remove(0), new ArrayList<>(), false);
verify(mCallback, never()).removeAutoGroup(anyString());
verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString(), anyString());
}
@@ -1072,6 +1077,7 @@ public class GroupHelperTest extends UiServiceTestCase {
}
@Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
@DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
public void testNewNotificationsAddedToAutogroup_ifOriginalNotificationsCanceled_alwaysGroup() {
final String pkg = "package";
@@ -1091,7 +1097,7 @@ public class GroupHelperTest extends UiServiceTestCase {
Mockito.reset(mCallback);
for (int i = posted.size() - 2; i >= 0; i--) {
- mGroupHelper.onNotificationRemoved(posted.remove(i));
+ mGroupHelper.onNotificationRemoved(posted.remove(i), new ArrayList<>(), false);
}
verify(mCallback, never()).removeAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
@@ -1114,7 +1120,8 @@ public class GroupHelperTest extends UiServiceTestCase {
}
@Test
- @EnableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
+ @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+ android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST})
public void testNewNotificationsAddedToAutogroup_ifOriginalNotificationsCanceled() {
final String pkg = "package";
ArrayList<NotificationRecord> posted = new ArrayList<>();
@@ -1134,7 +1141,7 @@ public class GroupHelperTest extends UiServiceTestCase {
Mockito.reset(mCallback);
for (int i = posted.size() - 2; i >= 0; i--) {
- mGroupHelper.onNotificationRemoved(posted.remove(i));
+ mGroupHelper.onNotificationRemoved(posted.remove(i), new ArrayList<>(), false);
}
verify(mCallback, never()).removeAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
@@ -1481,7 +1488,7 @@ public class GroupHelperTest extends UiServiceTestCase {
}
// Remove last notification (the only one with different icon and color)
- mGroupHelper.onNotificationRemoved(notifications.get(lastIdx));
+ mGroupHelper.onNotificationRemoved(notifications.get(lastIdx), new ArrayList<>(), false);
// Summary should be updated to the common icon and color
verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
@@ -2162,7 +2169,7 @@ public class GroupHelperTest extends UiServiceTestCase {
NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
UserHandle.SYSTEM, "testGrp " + i, false);
r.setOverrideGroupKey(expectedGroupKey);
- mGroupHelper.onNotificationRemoved(r, notificationList);
+ mGroupHelper.onNotificationRemoved(r, notificationList, false);
}
// Check that the autogroup summary is removed
verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), eq(pkg),
@@ -2206,7 +2213,7 @@ public class GroupHelperTest extends UiServiceTestCase {
Mockito.reset(mCallback);
for (NotificationRecord r: childrenToRemove) {
notificationList.remove(r);
- mGroupHelper.onNotificationRemoved(r, notificationList);
+ mGroupHelper.onNotificationRemoved(r, notificationList, false);
}
// Only call onGroupedNotificationRemovedWithDelay with the summary notification
mGroupHelper.onGroupedNotificationRemovedWithDelay(summary, notificationList,
@@ -2270,7 +2277,7 @@ public class GroupHelperTest extends UiServiceTestCase {
Mockito.reset(mCallback);
for (NotificationRecord r: childrenToRemove) {
notificationList.remove(r);
- mGroupHelper.onNotificationRemoved(r, notificationList);
+ mGroupHelper.onNotificationRemoved(r, notificationList, false);
}
// Only call onGroupedNotificationRemovedWithDelay with the summary notification
mGroupHelper.onGroupedNotificationRemovedWithDelay(summary, notificationList,
@@ -2327,7 +2334,7 @@ public class GroupHelperTest extends UiServiceTestCase {
for (NotificationRecord r: notificationList) {
if (r.getGroupKey().contains(groupToRemove)) {
r.isCanceled = true;
- mGroupHelper.onNotificationRemoved(r, notificationList);
+ mGroupHelper.onNotificationRemoved(r, notificationList, false);
}
}
// Only call onGroupedNotificationRemovedWithDelay with the summary notification
@@ -2452,7 +2459,7 @@ public class GroupHelperTest extends UiServiceTestCase {
true);
assertThat(GroupHelper.getSection(notifToInvalidate)).isNull();
notificationList.remove(notifToInvalidate);
- mGroupHelper.onNotificationRemoved(notifToInvalidate, notificationList);
+ mGroupHelper.onNotificationRemoved(notifToInvalidate, notificationList, false);
// Check that the autogroup was updated
verify(mCallback, never()).removeAutoGroup(anyString());
@@ -4023,7 +4030,7 @@ public class GroupHelperTest extends UiServiceTestCase {
//Cancel child 0 => remove cached summary
childToRemove.isCanceled = true;
notificationListAfterGrouping.remove(childToRemove);
- mGroupHelper.onNotificationRemoved(childToRemove, notificationListAfterGrouping);
+ mGroupHelper.onNotificationRemoved(childToRemove, notificationListAfterGrouping, false);
CachedSummary cachedSummary = mGroupHelper.findCanceledSummary(pkg, String.valueOf(id), id,
UserHandle.SYSTEM.getIdentifier());
assertThat(cachedSummary).isNull();
@@ -4399,4 +4406,41 @@ public class GroupHelperTest extends UiServiceTestCase {
"PeopleSection(priority)");
}
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void onNotificationRemoved_lastChildOfCachedSummary_firesCachedSummaryDeleteIntent() {
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+ final String pkg = "package";
+ NotificationRecord onlyChildOfFirstGroup = null;
+ PendingIntent deleteIntentofFirstSummary = PendingIntent.getActivity(mContext, 1,
+ new Intent(), PendingIntent.FLAG_IMMUTABLE);
+ // Post singleton groups, above forced group limit, so they are force grouped
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+ NotificationRecord summary = getNotificationRecord(pkg, i,
+ String.valueOf(i), UserHandle.SYSTEM, "testGrp " + i, true);
+ notificationList.add(summary);
+ NotificationRecord child = getNotificationRecord(pkg, i + 42,
+ String.valueOf(i + 42), UserHandle.SYSTEM, "testGrp " + i, false);
+ notificationList.add(child);
+ summaryByGroup.put(summary.getGroupKey(), summary);
+ if (i == 0) {
+ onlyChildOfFirstGroup = child;
+ summary.getNotification().deleteIntent = deleteIntentofFirstSummary;
+ }
+ mGroupHelper.onNotificationPostedWithDelay(child, notificationList, summaryByGroup);
+ summary.isCanceled = true; // simulate removing the app summary
+ mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+ }
+ // Sparse group autogrouping would've removed the summary.
+ notificationList.remove(0);
+
+ // Now remove the only child of the first (force-grouped, cuz sparse) group.
+ notificationList.remove(0);
+ onlyChildOfFirstGroup.isCanceled = true;
+ mGroupHelper.onNotificationRemoved(onlyChildOfFirstGroup, notificationList, true);
+
+ verify(mCallback).sendAppProvidedSummaryDeleteIntent(eq(pkg),
+ eq(deleteIntentofFirstSummary));
+ }
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 37ab541f12da..3727bbefb1d3 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -349,6 +349,7 @@ import com.android.server.wm.WindowManagerInternal;
import com.google.android.collect.Lists;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
@@ -2788,8 +2789,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
nr1.getSbn().getId(), nr1.getSbn().getUserId());
waitForIdle();
- verify(mGroupHelper, times(1)).onNotificationRemoved(eq(nr0), any());
- verify(mGroupHelper, times(1)).onNotificationRemoved(eq(nr1), any());
+ verify(mGroupHelper, times(1)).onNotificationRemoved(eq(nr0), any(), eq(false));
+ verify(mGroupHelper, times(1)).onNotificationRemoved(eq(nr1), any(), eq(false));
// GroupHelper would send 'remove summary' event
mService.clearAutogroupSummaryLocked(nr1.getUserId(), nr1.getSbn().getPackageName(),
@@ -3155,8 +3156,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
waitForIdle();
// Check that onGroupedNotificationRemovedWithDelay was called only once
- verify(mGroupHelper, times(1)).onNotificationRemoved(eq(r1), any());
- verify(mGroupHelper, times(1)).onNotificationRemoved(eq(r2), any());
+ verify(mGroupHelper, times(1)).onNotificationRemoved(eq(r1), any(), eq(false));
+ verify(mGroupHelper, times(1)).onNotificationRemoved(eq(r2), any(), eq(false));
verify(mGroupHelper, times(1)).onGroupedNotificationRemovedWithDelay(eq(summary), any(),
any());
}
@@ -3201,9 +3202,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
waitForIdle();
// Check that onGroupedNotificationRemovedWithDelay was never called: summary was canceled
- verify(mGroupHelper, times(1)).onNotificationRemoved(eq(r1), any());
- verify(mGroupHelper, times(1)).onNotificationRemoved(eq(r2), any());
- verify(mGroupHelper, times(1)).onNotificationRemoved(eq(summary), any());
+ verify(mGroupHelper, times(1)).onNotificationRemoved(eq(r1), any(), eq(false));
+ verify(mGroupHelper, times(1)).onNotificationRemoved(eq(r2), any(), eq(false));
+ verify(mGroupHelper, times(1)).onNotificationRemoved(eq(summary), any(), eq(false));
verify(mGroupHelper, never()).onGroupedNotificationRemovedWithDelay(any(), any(), any());
}
@@ -14122,9 +14123,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
waitForIdle();
// Check that child notifications are also removed
- verify(mGroupHelper, times(1)).onNotificationRemoved(eq(aggregateSummary), any());
- verify(mGroupHelper, times(1)).onNotificationRemoved(eq(nr0), any());
- verify(mGroupHelper, times(1)).onNotificationRemoved(eq(nr1), any());
+ verify(mGroupHelper, times(1)).onNotificationRemoved(eq(aggregateSummary), any(),
+ eq(false));
+ verify(mGroupHelper, times(1)).onNotificationRemoved(eq(nr0), any(), eq(false));
+ verify(mGroupHelper, times(1)).onNotificationRemoved(eq(nr1), any(), eq(false));
// Make sure the summary was removed and not re-posted
assertThat(mService.getNotificationRecordCount()).isEqualTo(0);
@@ -18659,4 +18661,35 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
}
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void clearAll_fromUser_willSendDeleteIntentForCachedSummaries() throws Exception {
+ NotificationRecord n = generateNotificationRecord(
+ mTestNotificationChannel, 1, "group", true);
+ mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag",
+ n.getSbn().getId(), n.getSbn().getNotification(), n.getSbn().getUserId());
+ waitForIdle();
+ n = Iterables.getOnlyElement(mService.mNotificationList);
+
+ mService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(), n.getUserId());
+ waitForIdle();
+
+ verify(mGroupHelper).onNotificationRemoved(eq(n), any(), eq(true));
+ }
+
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ public void cancel_fromApp_willNotSendDeleteIntentForCachedSummaries() throws Exception {
+ NotificationRecord n = generateNotificationRecord(
+ mTestNotificationChannel, 1, "group", true);
+ mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag",
+ n.getSbn().getId(), n.getSbn().getNotification(), n.getSbn().getUserId());
+ waitForIdle();
+ n = Iterables.getOnlyElement(mService.mNotificationList);
+
+ mBinderService.cancelAllNotifications(mPkg, mUserId);
+ waitForIdle();
+
+ verify(mGroupHelper).onNotificationRemoved(eq(n), any(), eq(false));
+ }
}