From c8588e3a0eb2497e6504f77bc4cbd062c6fe6613 Mon Sep 17 00:00:00 2001 From: Jan Tomljanovic Date: Wed, 11 Nov 2020 13:40:36 +0000 Subject: [PATCH] Limit the number of posted toasts by package to 5. We consider posting a toast many seconds after it was triggered bad UX, this change limits that behaviour. Test: atest NotificationManagerServiceTest Test: atest android.widget.cts.ToastTest Bug: 171959286 Change-Id: I5d8cded37fbc9e5d4dca195436e1dff81c7f0e9e --- .../NotificationManagerService.java | 7 +++-- .../NotificationManagerServiceTest.java | 26 +++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 1516cded50a6a..1bcf1acae056f 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -330,6 +330,9 @@ public class NotificationManagerService extends SystemService { static final int MAX_PACKAGE_NOTIFICATIONS = 50; static final float DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE = 5f; + // To limit bad UX of seeing a toast many seconds after if was triggered. + static final int MAX_PACKAGE_TOASTS = 5; + // message codes static final int MESSAGE_DURATION_REACHED = 2; // 3: removed to a different handler @@ -2945,8 +2948,8 @@ public class NotificationManagerService extends SystemService { final ToastRecord r = mToastQueue.get(i); if (r.pkg.equals(pkg)) { count++; - if (count >= MAX_PACKAGE_NOTIFICATIONS) { - Slog.e(TAG, "Package has already posted " + count + if (count >= MAX_PACKAGE_TOASTS) { + Slog.e(TAG, "Package has already queued " + count + " toasts. Not showing more. Package=" + pkg); 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 87aaba2b164a7..0b001688df0cf 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -5102,6 +5102,32 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertEquals(1, mService.mToastQueue.size()); } + @Test + public void testLimitNumberOfQueuedToastsFromPackage() throws Exception { + final String testPackage = "testPackageName"; + assertEquals(0, mService.mToastQueue.size()); + mService.isSystemUid = false; + + // package is not suspended + when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid))) + .thenReturn(false); + + INotificationManager nmService = (INotificationManager) mService.mService; + + // Trying to quickly enqueue more toast than allowed. + for (int i = 0; i < NotificationManagerService.MAX_PACKAGE_TOASTS + 1; i++) { + nmService.enqueueTextToast( + testPackage, + new Binder(), + "Text", + /* duration */ 2000, + /* displayId */ 0, + /* callback */ null); + } + // Only allowed number enqueued, rest ignored. + assertEquals(NotificationManagerService.MAX_PACKAGE_TOASTS, mService.mToastQueue.size()); + } + private void setAppInForegroundForToasts(int uid, boolean inForeground) { int importance = (inForeground) ? IMPORTANCE_FOREGROUND : IMPORTANCE_NONE; when(mActivityManager.getUidImportance(mUid)).thenReturn(importance);