From 675570af1dcf9fa5827b8dddc6e79319c2565e80 Mon Sep 17 00:00:00 2001 From: Lyn Han Date: Fri, 5 Jun 2020 23:31:22 -0700 Subject: [PATCH] Suppress bubble notifs instead of cancel Bubble notifs in the Launcher icon popup can't be swiped away because NotificationManagerService skips bubble notifs during cancellation. This change suppresses the notif instead of skipping it, which results in a post event. ag/11727210 set canShowBadge=false for suppressed notifs. Launcher removes notifs with canShowBadge=false, so it will remove the suppressed notif upon receiving the post event. Fixes: 131926652 Test: atest NotificationManagerServiceTest Test: manual 1) Have notif in shade with bubble 2) Swipe notif away in launcher popup 3) Shade notif goes away Change-Id: I6609d1209be6686c9286f939bf420d4f09351af4 --- .../NotificationManagerService.java | 9 +++- .../NotificationManagerServiceTest.java | 48 ++++++++++++++----- 2 files changed, 44 insertions(+), 13 deletions(-) diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 5585e98167832..0a8155a819b3a 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -4015,7 +4015,7 @@ public class NotificationManagerService extends SystemService { private void cancelNotificationFromListenerLocked(ManagedServiceInfo info, int callingUid, int callingPid, String pkg, String tag, int id, int userId) { cancelNotification(callingUid, callingPid, pkg, tag, id, 0, - FLAG_ONGOING_EVENT | FLAG_FOREGROUND_SERVICE | FLAG_BUBBLE, + FLAG_ONGOING_EVENT | FLAG_FOREGROUND_SERVICE, true, userId, REASON_LISTENER_CANCEL, info); } @@ -6248,6 +6248,13 @@ public class NotificationManagerService extends SystemService { mUsageStats.registerClickedByUser(r); } + if (mReason == REASON_LISTENER_CANCEL + && (r.getNotification().flags & FLAG_BUBBLE) != 0) { + mNotificationDelegate.onBubbleNotificationSuppressionChanged( + r.getKey(), /* suppressed */ true); + return; + } + if ((r.getNotification().flags & mMustHaveFlags) != mMustHaveFlags) { return; } 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 de9b77c683365..ae22b2be0c69d 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -5455,25 +5455,49 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test - public void testCancelNotificationsFromListener_ignoresBubbles() throws Exception { - final NotificationRecord nrNormal = generateNotificationRecord(mTestNotificationChannel); - final NotificationRecord nrBubble = generateNotificationRecord(mTestNotificationChannel); - nrBubble.getSbn().getNotification().flags |= FLAG_BUBBLE; + public void testCancelNotificationsFromListener_cancelsNonBubble() throws Exception { + // Add non-bubble notif + final NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel); + mService.addNotification(nr); - mService.addNotification(nrNormal); - mService.addNotification(nrBubble); - - String[] keys = {nrNormal.getSbn().getKey(), nrBubble.getSbn().getKey()}; + // Cancel via listener + String[] keys = {nr.getSbn().getKey()}; mService.getBinderService().cancelNotificationsFromListener(null, keys); waitForIdle(); + // Notif not active anymore + StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG); + assertEquals(0, notifs.length); + assertEquals(0, mService.getNotificationRecordCount()); + // Cancel event is logged + assertEquals(1, mNotificationRecordLogger.numCalls()); + assertEquals(NotificationRecordLogger.NotificationCancelledEvent + .NOTIFICATION_CANCEL_LISTENER_CANCEL, mNotificationRecordLogger.event(0)); + } + + @Test + public void testCancelNotificationsFromListener_suppressesBubble() throws Exception { + // Add bubble notif + setUpPrefsForBubbles(PKG, mUid, + true /* global */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); + NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel, "tag"); + + mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(), + nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId()); + waitForIdle(); + + // Cancel via listener + String[] keys = {nr.getSbn().getKey()}; + mService.getBinderService().cancelNotificationsFromListener(null, keys); + waitForIdle(); + + // Bubble notif active and suppressed StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG); assertEquals(1, notifs.length); assertEquals(1, mService.getNotificationRecordCount()); - - assertEquals(1, mNotificationRecordLogger.numCalls()); - assertEquals(NotificationRecordLogger.NotificationCancelledEvent - .NOTIFICATION_CANCEL_LISTENER_CANCEL, mNotificationRecordLogger.event(0)); + assertTrue(notifs[0].getNotification().getBubbleMetadata().isNotificationSuppressed()); } @Test