diff options
| -rw-r--r-- | core/java/android/app/NotificationManager.java | 18 | ||||
| -rw-r--r-- | core/tests/coretests/src/android/app/NotificationManagerTest.java | 78 |
2 files changed, 93 insertions, 3 deletions
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index 2da71471488c..ec10913360af 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -768,6 +768,10 @@ public class NotificationManager { INotificationManager service = service(); String sender = mContext.getPackageName(); + if (discardNotify(mContext.getUser(), targetPackage, tag, id, notification)) { + return; + } + try { if (localLOGV) Log.v(TAG, sender + ": notify(" + id + ", " + notification + ")"); service.enqueueNotificationWithTag(targetPackage, sender, tag, id, @@ -918,6 +922,10 @@ public class NotificationManager { * @param id An identifier for this notification. */ public void cancelAsPackage(@NonNull String targetPackage, @Nullable String tag, int id) { + if (discardCancel(mContext.getUser(), targetPackage, tag, id)) { + return; + } + INotificationManager service = service(); try { service.cancelNotificationWithTag(targetPackage, mContext.getOpPackageName(), @@ -981,16 +989,20 @@ public class NotificationManager { */ public void cancelAll() { + String pkg = mContext.getPackageName(); + UserHandle user = mContext.getUser(); + if (Flags.nmBinderPerfThrottleNotify()) { synchronized (mThrottleLock) { for (NotificationKey key : mKnownNotifications.snapshot().keySet()) { - mKnownNotifications.put(key, KNOWN_STATUS_CANCELLED); + if (key.pkg.equals(pkg) && key.user.equals(user)) { + mKnownNotifications.put(key, KNOWN_STATUS_CANCELLED); + } } } } INotificationManager service = service(); - String pkg = mContext.getPackageName(); if (localLOGV) Log.v(TAG, pkg + ": cancelAll()"); try { service.cancelAllNotifications(pkg, mContext.getUserId()); @@ -1014,7 +1026,7 @@ public class NotificationManager { public void setNotificationDelegate(@Nullable String delegate) { INotificationManager service = service(); String pkg = mContext.getPackageName(); - if (localLOGV) Log.v(TAG, pkg + ": cancelAll()"); + if (localLOGV) Log.v(TAG, pkg + ": setNotificationDelegate()"); try { service.setNotificationDelegate(pkg, delegate); } catch (RemoteException e) { diff --git a/core/tests/coretests/src/android/app/NotificationManagerTest.java b/core/tests/coretests/src/android/app/NotificationManagerTest.java index a47fc9436226..6538ce85457c 100644 --- a/core/tests/coretests/src/android/app/NotificationManagerTest.java +++ b/core/tests/coretests/src/android/app/NotificationManagerTest.java @@ -18,9 +18,11 @@ package android.app; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.atMost; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.reset; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -104,6 +106,22 @@ public class NotificationManagerTest { @Test @EnableFlags(Flags.FLAG_NM_BINDER_PERF_THROTTLE_NOTIFY) + public void notifyAsPackage_rapidUpdate_isThrottled() throws Exception { + Notification n = exampleNotification(); + + for (int i = 0; i < 100; i++) { + mNotificationManager.notifyAsPackage("some.package.name", "tag", 1, n); + mClock.advanceByMillis(5); + } + + verify(mNotificationManager.mBackendService, atLeast(20)).enqueueNotificationWithTag( + eq("some.package.name"), any(), any(), anyInt(), any(), anyInt()); + verify(mNotificationManager.mBackendService, atMost(30)).enqueueNotificationWithTag( + eq("some.package.name"), any(), any(), anyInt(), any(), anyInt()); + } + + @Test + @EnableFlags(Flags.FLAG_NM_BINDER_PERF_THROTTLE_NOTIFY) public void cancel_unnecessaryAndRapid_isThrottled() throws Exception { for (int i = 0; i < 100; i++) { @@ -165,6 +183,66 @@ public class NotificationManagerTest { any(), any(), anyInt(), anyInt()); } + @Test + @EnableFlags(Flags.FLAG_NM_BINDER_PERF_THROTTLE_NOTIFY) + public void enqueue_afterCancel_isNotUpdateAndIsNotThrottled() throws Exception { + // First, hit the enqueue threshold. + Notification n = exampleNotification(); + for (int i = 0; i < 100; i++) { + mNotificationManager.notify(1, n); + mClock.advanceByMillis(1); + } + verify(mNotificationManager.mBackendService, atMost(30)).enqueueNotificationWithTag(any(), + any(), any(), anyInt(), any(), anyInt()); + reset(mNotificationManager.mBackendService); + + // Now cancel that notification and then post it again. That should work. + mNotificationManager.cancel(1); + mNotificationManager.notify(1, n); + verify(mNotificationManager.mBackendService).enqueueNotificationWithTag(any(), any(), any(), + anyInt(), any(), anyInt()); + } + + @Test + @EnableFlags(Flags.FLAG_NM_BINDER_PERF_THROTTLE_NOTIFY) + public void enqueue_afterCancelAsPackage_isNotUpdateAndIsNotThrottled() throws Exception { + // First, hit the enqueue threshold. + Notification n = exampleNotification(); + for (int i = 0; i < 100; i++) { + mNotificationManager.notify(1, n); + mClock.advanceByMillis(1); + } + verify(mNotificationManager.mBackendService, atMost(30)).enqueueNotificationWithTag(any(), + any(), any(), anyInt(), any(), anyInt()); + reset(mNotificationManager.mBackendService); + + // Now cancel that notification and then post it again. That should work. + mNotificationManager.cancelAsPackage(mContext.getPackageName(), /* tag= */ null, 1); + mNotificationManager.notify(1, n); + verify(mNotificationManager.mBackendService).enqueueNotificationWithTag(any(), any(), any(), + anyInt(), any(), anyInt()); + } + + @Test + @EnableFlags(Flags.FLAG_NM_BINDER_PERF_THROTTLE_NOTIFY) + public void enqueue_afterCancelAll_isNotUpdateAndIsNotThrottled() throws Exception { + // First, hit the enqueue threshold. + Notification n = exampleNotification(); + for (int i = 0; i < 100; i++) { + mNotificationManager.notify(1, n); + mClock.advanceByMillis(1); + } + verify(mNotificationManager.mBackendService, atMost(30)).enqueueNotificationWithTag(any(), + any(), any(), anyInt(), any(), anyInt()); + reset(mNotificationManager.mBackendService); + + // Now cancel all notifications and then post it again. That should work. + mNotificationManager.cancelAll(); + mNotificationManager.notify(1, n); + verify(mNotificationManager.mBackendService).enqueueNotificationWithTag(any(), any(), any(), + anyInt(), any(), anyInt()); + } + private Notification exampleNotification() { return new Notification.Builder(mContext, "channel") .setSmallIcon(android.R.drawable.star_big_on) |