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

Commit 147a42bf authored by Julia Reynolds's avatar Julia Reynolds Committed by Android Build Coastguard Worker
Browse files

DO NOT MERGE Limit the number of concurrently snoozed notifications

Test: atest FrameworksUiServicesTests
Bug: 234441463
Change-Id: I005b43979d1c708fd505c8b33ae0c8cb03ddbb35
Merged-In: I005b43979d1c708fd505c8b33ae0c8cb03ddbb35
(cherry picked from commit 7c38394a)
(cherry picked from commit c38cc3e3)
Merged-In: I005b43979d1c708fd505c8b33ae0c8cb03ddbb35
parent c0dcd86a
Loading
Loading
Loading
Loading
+21 −4
Original line number Diff line number Diff line
@@ -5262,13 +5262,17 @@ public class NotificationManagerService extends SystemService {

        @GuardedBy("mNotificationLock")
        void snoozeLocked(NotificationRecord r) {
            final List<NotificationRecord> recordsToSnooze = new ArrayList<>();
            if (r.sbn.isGroup()) {
                final List<NotificationRecord> groupNotifications = findGroupNotificationsLocked(
                        r.sbn.getPackageName(), r.sbn.getGroupKey(), r.sbn.getUserId());
                final List<NotificationRecord> groupNotifications =
                        findGroupNotificationsLocked(r.sbn.getPackageName(),
                                r.sbn.getGroupKey(), r.sbn.getUserId());
                if (r.getNotification().isGroupSummary()) {
                    // snooze summary and all children
                    for (int i = 0; i < groupNotifications.size(); i++) {
                        snoozeNotificationLocked(groupNotifications.get(i));
                        if (!mKey.equals(groupNotifications.get(i).getKey())) {
                            recordsToSnooze.add(groupNotifications.get(i));
                        }
                    }
                } else {
                    // if there is a valid summary for this group, and we are snoozing the only
@@ -5279,7 +5283,9 @@ public class NotificationManagerService extends SystemService {
                        } else {
                            // snooze summary and the one child
                            for (int i = 0; i < groupNotifications.size(); i++) {
                                snoozeNotificationLocked(groupNotifications.get(i));
                                if (!mKey.equals(groupNotifications.get(i).getKey())) {
                                    recordsToSnooze.add(groupNotifications.get(i));
                                }
                            }
                        }
                    } else {
@@ -5290,6 +5296,17 @@ public class NotificationManagerService extends SystemService {
                // just snooze the one notification
                snoozeNotificationLocked(r);
            }

            // snooze the notification
            recordsToSnooze.add(r);

            if (mSnoozeHelper.canSnooze(recordsToSnooze.size())) {
                for (int i = 0; i < recordsToSnooze.size(); i++) {
                    snoozeNotificationLocked(recordsToSnooze.get(i));
                }
            } else {
                Log.w(TAG, "Cannot snooze " + r.getKey() + ": too many snoozed notifications");
            }
        }

        @GuardedBy("mNotificationLock")
+9 −0
Original line number Diff line number Diff line
@@ -57,6 +57,8 @@ import java.util.Set;
 * NotificationManagerService helper for handling snoozed notifications.
 */
public class SnoozeHelper {
    static final int CONCURRENT_SNOOZE_LIMIT = 500;

    private static final String TAG = "SnoozeHelper";
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
    private static final String INDENT = "    ";
@@ -91,6 +93,13 @@ public class SnoozeHelper {
        mUserProfiles = userProfiles;
    }

    protected boolean canSnooze(int numberToSnooze) {
        if ((mPackages.size() + numberToSnooze) > CONCURRENT_SNOOZE_LIMIT) {
            return false;
        }
        return true;
    }

    protected boolean isSnoozed(int userId, String pkg, String key) {
        return mSnoozedNotifications.containsKey(userId)
                && mSnoozedNotifications.get(userId).containsKey(pkg)
+68 −0
Original line number Diff line number Diff line
@@ -2100,6 +2100,69 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        assertFalse(mService.hasCompanionDevice(mListener));
    }

    @Test
    public void testSnoozeRunnable_tooManySnoozed_singleNotification() {
        final NotificationRecord notification = generateNotificationRecord(
                mTestNotificationChannel, 1, null, true);
        mService.addNotification(notification);

        when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
        when(mSnoozeHelper.canSnooze(1)).thenReturn(false);

        NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
                mService.new SnoozeNotificationRunnable(
                        notification.getKey(), 100, null);
        snoozeNotificationRunnable.run();

        verify(mSnoozeHelper, never()).snooze(any(NotificationRecord.class), anyLong());
        assertEquals(1, mService.getNotificationRecordCount());
    }

    @Test
    public void testSnoozeRunnable_tooManySnoozed_singleGroupChildNotification() {
        final NotificationRecord notification = generateNotificationRecord(
                mTestNotificationChannel, 1, "group", true);
        final NotificationRecord notificationChild = generateNotificationRecord(
                mTestNotificationChannel, 1, "group", false);
        mService.addNotification(notification);
        mService.addNotification(notificationChild);

        when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
        when(mSnoozeHelper.canSnooze(2)).thenReturn(false);

        NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
                mService.new SnoozeNotificationRunnable(
                        notificationChild.getKey(), 100, null);
        snoozeNotificationRunnable.run();

        verify(mSnoozeHelper, never()).snooze(any(NotificationRecord.class), anyLong());
        assertEquals(2, mService.getNotificationRecordCount());
    }

    @Test
    public void testSnoozeRunnable_tooManySnoozed_summaryNotification() {
        final NotificationRecord notification = generateNotificationRecord(
                mTestNotificationChannel, 1, "group", true);
        final NotificationRecord notificationChild = generateNotificationRecord(
                mTestNotificationChannel, 12, "group", false);
        final NotificationRecord notificationChild2 = generateNotificationRecord(
                mTestNotificationChannel, 13, "group", false);
        mService.addNotification(notification);
        mService.addNotification(notificationChild);
        mService.addNotification(notificationChild2);

        when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
        when(mSnoozeHelper.canSnooze(3)).thenReturn(false);

        NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
                mService.new SnoozeNotificationRunnable(
                        notification.getKey(), 100, null);
        snoozeNotificationRunnable.run();

        verify(mSnoozeHelper, never()).snooze(any(NotificationRecord.class), anyLong());
        assertEquals(3, mService.getNotificationRecordCount());
    }

    @Test
    public void testSnoozeRunnable_snoozeNonGrouped() throws Exception {
        final NotificationRecord nonGrouped = generateNotificationRecord(
@@ -2108,6 +2171,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
                mTestNotificationChannel, 2, "group", false);
        mService.addNotification(grouped);
        mService.addNotification(nonGrouped);
        when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);

        NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
                mService.new SnoozeNotificationRunnable(
@@ -2130,6 +2194,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        mService.addNotification(parent);
        mService.addNotification(child);
        mService.addNotification(child2);
        when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);

        NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
                mService.new SnoozeNotificationRunnable(
@@ -2151,6 +2216,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        mService.addNotification(parent);
        mService.addNotification(child);
        mService.addNotification(child2);
        when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);

        NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
                mService.new SnoozeNotificationRunnable(
@@ -2170,6 +2236,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
                mTestNotificationChannel, 2, "group", false);
        mService.addNotification(parent);
        mService.addNotification(child);
        when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);

        NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
                mService.new SnoozeNotificationRunnable(
@@ -2185,6 +2252,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        final NotificationRecord child = generateNotificationRecord(
                mTestNotificationChannel, 2, "group", false);
        mService.addNotification(child);
        when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);

        NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
                mService.new SnoozeNotificationRunnable(
+18 −0
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
 */
package com.android.server.notification;

import static com.android.server.notification.SnoozeHelper.CONCURRENT_SNOOZE_LIMIT;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
@@ -103,6 +105,22 @@ public class SnoozeHelperTest extends UiServiceTestCase {
                UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
    }

    @Test
    public void testSnoozeLimit() {
        for (int i = 0; i < CONCURRENT_SNOOZE_LIMIT; i++ ) {
            NotificationRecord r = getNotificationRecord("pkg", i, i+"", UserHandle.SYSTEM);

            assertTrue("cannot snooze record " + i, mSnoozeHelper.canSnooze(1));

            if (i % 2 == 0) {
                mSnoozeHelper.snooze(r, 1000);
            } else {
                mSnoozeHelper.snooze(r, 9000);
            }
        }
        assertFalse(mSnoozeHelper.canSnooze(1));
    }

    @Test
    public void testCancelByApp() throws Exception {
        NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);