From: Julia Reynolds Date: Thu, 13 Sep 2018 19:53:11 +0000 (-0400) Subject: Fix stuck notifications X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=ac3f14ef089478a6985cb362092c8a86b0e2c3e6;p=android-x86%2Fframeworks-base.git Fix stuck notifications Don't tell listeners about changes to enqueued notifications; they'll pick up the changes in the post notification runnable. Change-Id: I56c4ba79bcf42c30ad9a0da936eb0b774a6f3f08 Merged-In: I56c4ba79bcf42c30ad9a0da936eb0b774a6f3f08 Fixes: 74236718 Test: runtest systemui-notification --- diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index b7247166855d..cfb1235ac9e6 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -3960,25 +3960,30 @@ public class NotificationManagerService extends SystemService { public void removeForegroundServiceFlagFromNotification(String pkg, int notificationId, int userId) { checkCallerIsSystem(); - mHandler.post(new Runnable() { - @Override - public void run() { - synchronized (mNotificationLock) { - removeForegroundServiceFlagByListLocked( - mEnqueuedNotifications, pkg, notificationId, userId); - removeForegroundServiceFlagByListLocked( - mNotificationList, pkg, notificationId, userId); + mHandler.post(() -> { + synchronized (mNotificationLock) { + // strip flag from all enqueued notifications. listeners will be informed + // in post runnable. + List enqueued = findNotificationsByListLocked( + mEnqueuedNotifications, pkg, null, notificationId, userId); + for (int i = 0; i < enqueued.size(); i++) { + removeForegroundServiceFlagLocked(enqueued.get(i)); + } + + // if posted notification exists, strip its flag and tell listeners + NotificationRecord r = findNotificationByListLocked( + mNotificationList, pkg, null, notificationId, userId); + if (r != null) { + removeForegroundServiceFlagLocked(r); + mRankingHelper.sort(mNotificationList); + mListeners.notifyPostedLocked(r, r); } } }); } @GuardedBy("mNotificationLock") - private void removeForegroundServiceFlagByListLocked( - ArrayList notificationList, String pkg, int notificationId, - int userId) { - NotificationRecord r = findNotificationByListLocked( - notificationList, pkg, null, notificationId, userId); + private void removeForegroundServiceFlagLocked(NotificationRecord r) { if (r == null) { return; } @@ -3989,8 +3994,6 @@ public class NotificationManagerService extends SystemService { // initially *and* force remove FLAG_FOREGROUND_SERVICE. sbn.getNotification().flags = (r.mOriginalFlags & ~FLAG_FOREGROUND_SERVICE); - mRankingHelper.sort(mNotificationList); - mListeners.notifyPostedLocked(r, r); } }; @@ -6074,6 +6077,21 @@ public class NotificationManagerService extends SystemService { } @GuardedBy("mNotificationLock") + private List findNotificationsByListLocked( + ArrayList list, String pkg, String tag, int id, int userId) { + List matching = new ArrayList<>(); + final int len = list.size(); + for (int i = 0; i < len; i++) { + NotificationRecord r = list.get(i); + if (notificationMatchesUserId(r, userId) && r.sbn.getId() == id && + TextUtils.equals(r.sbn.getTag(), tag) && r.sbn.getPackageName().equals(pkg)) { + matching.add(r); + } + } + return matching; + } + + @GuardedBy("mNotificationLock") private NotificationRecord findNotificationByListLocked(ArrayList list, String key) { final int N = list.size(); 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 955e2477fc66..f02c3f062f35 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -3103,4 +3103,46 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { verify(mAppUsageStats, times(1)).reportInterruptiveNotification( anyString(), anyString(), anyInt()); } + + @Test + public void testRemoveForegroundServiceFlagFromNotification_enqueued() { + Notification n = new Notification.Builder(mContext, "").build(); + n.flags |= FLAG_FOREGROUND_SERVICE; + + StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 9, null, mUid, 0, + n, new UserHandle(mUid), null, 0); + NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); + + mService.addEnqueuedNotification(r); + + mInternalService.removeForegroundServiceFlagFromNotification( + PKG, r.sbn.getId(), r.sbn.getUserId()); + + waitForIdle(); + + verify(mListeners, timeout(200).times(0)).notifyPostedLocked(any(), any()); + } + + @Test + public void testRemoveForegroundServiceFlagFromNotification_posted() { + Notification n = new Notification.Builder(mContext, "").build(); + n.flags |= FLAG_FOREGROUND_SERVICE; + + StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 9, null, mUid, 0, + n, new UserHandle(mUid), null, 0); + NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); + + mService.addNotification(r); + + mInternalService.removeForegroundServiceFlagFromNotification( + PKG, r.sbn.getId(), r.sbn.getUserId()); + + waitForIdle(); + + ArgumentCaptor captor = + ArgumentCaptor.forClass(NotificationRecord.class); + verify(mListeners, times(1)).notifyPostedLocked(captor.capture(), any()); + + assertEquals(0, captor.getValue().getNotification().flags); + } }