From 40239d9eccc0c91e4d477f06366b4bbae71b0bb5 Mon Sep 17 00:00:00 2001 From: Beverly Date: Fri, 7 Jul 2017 10:20:41 -0400 Subject: [PATCH] Clear all won't clear group notifs with no clear flag Change-Id: I9df0d3a147c787fb7bad99a5f0bce4b67bbd2813 Fixes: 63367265 Test: runtest systemui-notification --- .../notification/NotificationManagerService.java | 23 +++--- .../NotificationManagerServiceTest.java | 89 ++++++++++++++++++++++ 2 files changed, 101 insertions(+), 11 deletions(-) diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 48b4c5724b5f..4690d649f272 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -573,7 +573,8 @@ public class NotificationManagerService extends SystemService { } } - private final NotificationDelegate mNotificationDelegate = new NotificationDelegate() { + @VisibleForTesting + final NotificationDelegate mNotificationDelegate = new NotificationDelegate() { @Override public void onSetDisabled(int status) { @@ -3830,7 +3831,8 @@ public class NotificationManagerService extends SystemService { // notification was a summary and the new one isn't, or when the old // notification was a summary and its group key changed. if (oldIsSummary && (!isSummary || !oldGroup.equals(group))) { - cancelGroupChildrenLocked(old, callingUid, callingPid, null, false /* sendDelete */); + cancelGroupChildrenLocked(old, callingUid, callingPid, null, false /* sendDelete */, + null); } } @@ -4581,7 +4583,7 @@ public class NotificationManagerService extends SystemService { boolean wasPosted = removeFromNotificationListsLocked(r); cancelNotificationLocked(r, sendDelete, reason, wasPosted); cancelGroupChildrenLocked(r, callingUid, callingPid, listenerName, - sendDelete); + sendDelete, null); updateLightsLocked(); } else { // No notification was found, assume that it is snoozed and cancel it. @@ -4652,7 +4654,6 @@ public class NotificationManagerService extends SystemService { } return true; }; - cancelAllNotificationsByListLocked(mNotificationList, callingUid, callingPid, pkg, true /*nullPkgIndicatesUserSwitch*/, channelId, flagChecker, false /*includeCurrentProfiles*/, userId, false /*sendDelete*/, reason, @@ -4700,7 +4701,6 @@ public class NotificationManagerService extends SystemService { if (channelId != null && !channelId.equals(r.getChannel().getId())) { continue; } - if (canceledNotifications == null) { canceledNotifications = new ArrayList<>(); } @@ -4712,7 +4712,7 @@ public class NotificationManagerService extends SystemService { final int M = canceledNotifications.size(); for (int i = 0; i < M; i++) { cancelGroupChildrenLocked(canceledNotifications.get(i), callingUid, callingPid, - listenerName, false /* sendDelete */); + listenerName, false /* sendDelete */, flagChecker); } updateLightsLocked(); } @@ -4779,7 +4779,7 @@ public class NotificationManagerService extends SystemService { // Warning: The caller is responsible for invoking updateLightsLocked(). @GuardedBy("mNotificationLock") private void cancelGroupChildrenLocked(NotificationRecord r, int callingUid, int callingPid, - String listenerName, boolean sendDelete) { + String listenerName, boolean sendDelete, FlagChecker flagChecker) { Notification n = r.getNotification(); if (!n.isGroupSummary()) { return; @@ -4793,15 +4793,15 @@ public class NotificationManagerService extends SystemService { } cancelGroupChildrenByListLocked(mNotificationList, r, callingUid, callingPid, listenerName, - sendDelete, true); + sendDelete, true, flagChecker); cancelGroupChildrenByListLocked(mEnqueuedNotifications, r, callingUid, callingPid, - listenerName, sendDelete, false); + listenerName, sendDelete, false, flagChecker); } @GuardedBy("mNotificationLock") private void cancelGroupChildrenByListLocked(ArrayList notificationList, NotificationRecord parentNotification, int callingUid, int callingPid, - String listenerName, boolean sendDelete, boolean wasPosted) { + String listenerName, boolean sendDelete, boolean wasPosted, FlagChecker flagChecker) { final String pkg = parentNotification.sbn.getPackageName(); final int userId = parentNotification.getUserId(); final int reason = REASON_GROUP_SUMMARY_CANCELED; @@ -4810,7 +4810,8 @@ public class NotificationManagerService extends SystemService { final StatusBarNotification childSbn = childR.sbn; if ((childSbn.isGroup() && !childSbn.getNotification().isGroupSummary()) && childR.getGroupKey().equals(parentNotification.getGroupKey()) - && (childR.getFlags() & Notification.FLAG_FOREGROUND_SERVICE) == 0) { + && (childR.getFlags() & Notification.FLAG_FOREGROUND_SERVICE) == 0 + && (flagChecker == null || flagChecker.apply(childR.getFlags()))) { EventLogTags.writeNotificationCancel(callingUid, callingPid, pkg, childSbn.getId(), childSbn.getTag(), userId, 0, 0, reason, listenerName); notificationList.remove(i); diff --git a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java index 8ff46394db14..63cf024d4efd 100644 --- a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -18,6 +18,7 @@ package com.android.server.notification; import static android.app.NotificationManager.IMPORTANCE_LOW; import static android.app.NotificationManager.IMPORTANCE_NONE; +import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; @@ -483,6 +484,93 @@ public class NotificationManagerServiceTest extends NotificationTestCase { } @Test + public void testAppInitiatedCancelAllNotifications_CancelsNoClearFlag() throws Exception { + final StatusBarNotification sbn = generateNotificationRecord(null).sbn; + sbn.getNotification().flags |= Notification.FLAG_NO_CLEAR; + mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", + sbn.getId(), sbn.getNotification(), sbn.getUserId()); + mBinderService.cancelAllNotifications(PKG, sbn.getUserId()); + waitForIdle(); + StatusBarNotification[] notifs = + mBinderService.getActiveNotifications(sbn.getPackageName()); + assertEquals(0, notifs.length); + } + + @Test + public void testCancelAllNotifications_CancelsNoClearFlag() throws Exception { + final NotificationRecord notif = generateNotificationRecord( + mTestNotificationChannel, 1, "group", true); + notif.getNotification().flags |= Notification.FLAG_NO_CLEAR; + mNotificationManagerService.addNotification(notif); + mNotificationManagerService.cancelAllNotificationsInt(uid, 0, PKG, null, 0, 0, true, + notif.getUserId(), 0, null); + waitForIdle(); + StatusBarNotification[] notifs = + mBinderService.getActiveNotifications(notif.sbn.getPackageName()); + assertEquals(0, notifs.length); + } + + @Test + public void testUserInitiatedCancelAllOnClearAll_NoClearFlag() throws Exception { + final NotificationRecord notif = generateNotificationRecord( + mTestNotificationChannel, 1, "group", true); + notif.getNotification().flags |= Notification.FLAG_NO_CLEAR; + mNotificationManagerService.addNotification(notif); + + mNotificationManagerService.mNotificationDelegate.onClearAll(uid, Binder.getCallingPid(), + notif.getUserId()); + waitForIdle(); + StatusBarNotification[] notifs = + mBinderService.getActiveNotifications(notif.sbn.getPackageName()); + assertEquals(1, notifs.length); + } + + @Test + public void testCancelAllCancelNotificationsFromListener_NoClearFlag() throws Exception { + final NotificationRecord parent = generateNotificationRecord( + mTestNotificationChannel, 1, "group", true); + final NotificationRecord child = generateNotificationRecord( + mTestNotificationChannel, 2, "group", false); + final NotificationRecord child2 = generateNotificationRecord( + mTestNotificationChannel, 3, "group", false); + child2.getNotification().flags |= Notification.FLAG_NO_CLEAR; + final NotificationRecord newGroup = generateNotificationRecord( + mTestNotificationChannel, 4, "group2", false); + mNotificationManagerService.addNotification(parent); + mNotificationManagerService.addNotification(child); + mNotificationManagerService.addNotification(child2); + mNotificationManagerService.addNotification(newGroup); + mNotificationManagerService.getBinderService().cancelNotificationsFromListener(null, null); + waitForIdle(); + StatusBarNotification[] notifs = + mBinderService.getActiveNotifications(parent.sbn.getPackageName()); + assertEquals(1, notifs.length); + } + + @Test + public void testUserInitiatedCancelAllWithGroup_NoClearFlag() throws Exception { + final NotificationRecord parent = generateNotificationRecord( + mTestNotificationChannel, 1, "group", true); + final NotificationRecord child = generateNotificationRecord( + mTestNotificationChannel, 2, "group", false); + final NotificationRecord child2 = generateNotificationRecord( + mTestNotificationChannel, 3, "group", false); + child2.getNotification().flags |= Notification.FLAG_NO_CLEAR; + final NotificationRecord newGroup = generateNotificationRecord( + mTestNotificationChannel, 4, "group2", false); + mNotificationManagerService.addNotification(parent); + mNotificationManagerService.addNotification(child); + mNotificationManagerService.addNotification(child2); + mNotificationManagerService.addNotification(newGroup); + mNotificationManagerService.mNotificationDelegate.onClearAll(uid, Binder.getCallingPid(), + parent.getUserId()); + waitForIdle(); + StatusBarNotification[] notifs = + mBinderService.getActiveNotifications(parent.sbn.getPackageName()); + assertEquals(1, notifs.length); + } + + @Test public void testRemoveForegroundServiceFlag_ImmediatelyAfterEnqueue() throws Exception { final StatusBarNotification sbn = generateNotificationRecord(null).sbn; sbn.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE; @@ -1130,4 +1218,5 @@ public class NotificationManagerServiceTest extends NotificationTestCase { verify(mGroupHelper, never()).onNotificationPosted(any()); } + } -- 2.11.0