diff options
author | Julia Reynolds <juliacr@google.com> | 2018-09-13 15:53:11 -0400 |
---|---|---|
committer | Julia Reynolds <juliacr@google.com> | 2019-01-14 21:35:26 +0000 |
commit | ac3f14ef089478a6985cb362092c8a86b0e2c3e6 (patch) | |
tree | fb4fa583173686e1810f563637e8bb0a9c181d60 | |
parent | b9596e5febccbaf1452de7e7a681a4619f9c3825 (diff) | |
download | base-ac3f14ef089478a6985cb362092c8a86b0e2c3e6.tar.gz |
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
2 files changed, 75 insertions, 15 deletions
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<NotificationRecord> 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<NotificationRecord> 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<NotificationRecord> findNotificationsByListLocked( + ArrayList<NotificationRecord> list, String pkg, String tag, int id, int userId) { + List<NotificationRecord> 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<NotificationRecord> 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<NotificationRecord> captor = + ArgumentCaptor.forClass(NotificationRecord.class); + verify(mListeners, times(1)).notifyPostedLocked(captor.capture(), any()); + + assertEquals(0, captor.getValue().getNotification().flags); + } } |