Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c8588e3a authored by Jan Tomljanovic's avatar Jan Tomljanovic
Browse files

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
parent 85b41414
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -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;
                                }
+26 −0
Original line number Diff line number Diff line
@@ -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);