Limit the number of concurrently snoozed notifications am: bc808de2f8 am: 0753020228
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19205942 Change-Id: I9644735c6e9a8b4836b8eb35fba5f78862c13695 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -6816,6 +6816,7 @@ public class NotificationManagerService extends SystemService {
|
|||||||
|
|
||||||
@GuardedBy("mNotificationLock")
|
@GuardedBy("mNotificationLock")
|
||||||
void snoozeLocked(NotificationRecord r) {
|
void snoozeLocked(NotificationRecord r) {
|
||||||
|
final List<NotificationRecord> recordsToSnooze = new ArrayList<>();
|
||||||
if (r.getSbn().isGroup()) {
|
if (r.getSbn().isGroup()) {
|
||||||
final List<NotificationRecord> groupNotifications =
|
final List<NotificationRecord> groupNotifications =
|
||||||
findCurrentAndSnoozedGroupNotificationsLocked(
|
findCurrentAndSnoozedGroupNotificationsLocked(
|
||||||
@@ -6824,8 +6825,8 @@ public class NotificationManagerService extends SystemService {
|
|||||||
if (r.getNotification().isGroupSummary()) {
|
if (r.getNotification().isGroupSummary()) {
|
||||||
// snooze all children
|
// snooze all children
|
||||||
for (int i = 0; i < groupNotifications.size(); i++) {
|
for (int i = 0; i < groupNotifications.size(); i++) {
|
||||||
if (mKey != groupNotifications.get(i).getKey()) {
|
if (!mKey.equals(groupNotifications.get(i).getKey())) {
|
||||||
snoozeNotificationLocked(groupNotifications.get(i));
|
recordsToSnooze.add(groupNotifications.get(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -6835,8 +6836,8 @@ public class NotificationManagerService extends SystemService {
|
|||||||
if (groupNotifications.size() == 2) {
|
if (groupNotifications.size() == 2) {
|
||||||
// snooze summary and the one child
|
// snooze summary and the one child
|
||||||
for (int i = 0; i < groupNotifications.size(); i++) {
|
for (int i = 0; i < groupNotifications.size(); i++) {
|
||||||
if (mKey != groupNotifications.get(i).getKey()) {
|
if (!mKey.equals(groupNotifications.get(i).getKey())) {
|
||||||
snoozeNotificationLocked(groupNotifications.get(i));
|
recordsToSnooze.add(groupNotifications.get(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6844,7 +6845,15 @@ public class NotificationManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// snooze the notification
|
// snooze the notification
|
||||||
snoozeNotificationLocked(r);
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,6 +62,8 @@ import java.util.Set;
|
|||||||
public class SnoozeHelper {
|
public class SnoozeHelper {
|
||||||
public static final int XML_SNOOZED_NOTIFICATION_VERSION = 1;
|
public static final int XML_SNOOZED_NOTIFICATION_VERSION = 1;
|
||||||
|
|
||||||
|
static final int CONCURRENT_SNOOZE_LIMIT = 500;
|
||||||
|
|
||||||
protected static final String XML_TAG_NAME = "snoozed-notifications";
|
protected static final String XML_TAG_NAME = "snoozed-notifications";
|
||||||
|
|
||||||
private static final String XML_SNOOZED_NOTIFICATION = "notification";
|
private static final String XML_SNOOZED_NOTIFICATION = "notification";
|
||||||
@@ -134,6 +136,15 @@ public class SnoozeHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean canSnooze(int numberToSnooze) {
|
||||||
|
synchronized (mLock) {
|
||||||
|
if ((mPackages.size() + numberToSnooze) > CONCURRENT_SNOOZE_LIMIT) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
protected Long getSnoozeTimeForUnpostedNotification(int userId, String pkg, String key) {
|
protected Long getSnoozeTimeForUnpostedNotification(int userId, String pkg, String key) {
|
||||||
Long time = null;
|
Long time = null;
|
||||||
|
|||||||
@@ -2778,20 +2778,81 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
|||||||
assertFalse(noManService.hasCompanionDevice(mListener));
|
assertFalse(noManService.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
|
@Test
|
||||||
public void testSnoozeRunnable_reSnoozeASingleSnoozedNotification() throws Exception {
|
public void testSnoozeRunnable_reSnoozeASingleSnoozedNotification() throws Exception {
|
||||||
final NotificationRecord notification = generateNotificationRecord(
|
final NotificationRecord notification = generateNotificationRecord(
|
||||||
mTestNotificationChannel, 1, null, true);
|
mTestNotificationChannel, 1, null, true);
|
||||||
mService.addNotification(notification);
|
mService.addNotification(notification);
|
||||||
when(mSnoozeHelper.getNotification(any())).thenReturn(notification);
|
when(mSnoozeHelper.getNotification(any())).thenReturn(notification);
|
||||||
|
when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
|
||||||
|
|
||||||
NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
|
NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
|
||||||
mService.new SnoozeNotificationRunnable(
|
mService.new SnoozeNotificationRunnable(
|
||||||
notification.getKey(), 100, null);
|
notification.getKey(), 100, null);
|
||||||
snoozeNotificationRunnable.run();
|
snoozeNotificationRunnable.run();
|
||||||
NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable2 =
|
|
||||||
mService.new SnoozeNotificationRunnable(
|
|
||||||
notification.getKey(), 100, null);
|
|
||||||
snoozeNotificationRunnable.run();
|
snoozeNotificationRunnable.run();
|
||||||
|
|
||||||
// snooze twice
|
// snooze twice
|
||||||
@@ -2799,19 +2860,17 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSnoozeRunnable_reSnoozeASnoozedNotificationWithGroupKey() throws Exception {
|
public void testSnoozeRunnable_reSnoozeASnoozedNotificationWithGroupKey() {
|
||||||
final NotificationRecord notification = generateNotificationRecord(
|
final NotificationRecord notification = generateNotificationRecord(
|
||||||
mTestNotificationChannel, 1, "group", true);
|
mTestNotificationChannel, 1, "group", true);
|
||||||
mService.addNotification(notification);
|
mService.addNotification(notification);
|
||||||
when(mSnoozeHelper.getNotification(any())).thenReturn(notification);
|
when(mSnoozeHelper.getNotification(any())).thenReturn(notification);
|
||||||
|
when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
|
||||||
|
|
||||||
NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
|
NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
|
||||||
mService.new SnoozeNotificationRunnable(
|
mService.new SnoozeNotificationRunnable(
|
||||||
notification.getKey(), 100, null);
|
notification.getKey(), 100, null);
|
||||||
snoozeNotificationRunnable.run();
|
snoozeNotificationRunnable.run();
|
||||||
NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable2 =
|
|
||||||
mService.new SnoozeNotificationRunnable(
|
|
||||||
notification.getKey(), 100, null);
|
|
||||||
snoozeNotificationRunnable.run();
|
snoozeNotificationRunnable.run();
|
||||||
|
|
||||||
// snooze twice
|
// snooze twice
|
||||||
@@ -2829,6 +2888,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
|||||||
when(mSnoozeHelper.getNotification(any())).thenReturn(notification);
|
when(mSnoozeHelper.getNotification(any())).thenReturn(notification);
|
||||||
when(mSnoozeHelper.getNotifications(
|
when(mSnoozeHelper.getNotifications(
|
||||||
anyString(), anyString(), anyInt())).thenReturn(new ArrayList<>());
|
anyString(), anyString(), anyInt())).thenReturn(new ArrayList<>());
|
||||||
|
when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
|
||||||
|
|
||||||
NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
|
NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
|
||||||
mService.new SnoozeNotificationRunnable(
|
mService.new SnoozeNotificationRunnable(
|
||||||
@@ -2838,8 +2898,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
|||||||
.thenReturn(new ArrayList<>(Arrays.asList(notification, notification2)));
|
.thenReturn(new ArrayList<>(Arrays.asList(notification, notification2)));
|
||||||
NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable2 =
|
NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable2 =
|
||||||
mService.new SnoozeNotificationRunnable(
|
mService.new SnoozeNotificationRunnable(
|
||||||
notification.getKey(), 100, null);
|
notification2.getKey(), 100, null);
|
||||||
snoozeNotificationRunnable.run();
|
snoozeNotificationRunnable2.run();
|
||||||
|
|
||||||
// snooze twice
|
// snooze twice
|
||||||
verify(mSnoozeHelper, times(4)).snooze(any(NotificationRecord.class), anyLong());
|
verify(mSnoozeHelper, times(4)).snooze(any(NotificationRecord.class), anyLong());
|
||||||
@@ -2853,6 +2913,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
|||||||
mTestNotificationChannel, 2, "group", false);
|
mTestNotificationChannel, 2, "group", false);
|
||||||
mService.addNotification(grouped);
|
mService.addNotification(grouped);
|
||||||
mService.addNotification(nonGrouped);
|
mService.addNotification(nonGrouped);
|
||||||
|
when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
|
||||||
|
|
||||||
NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
|
NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
|
||||||
mService.new SnoozeNotificationRunnable(
|
mService.new SnoozeNotificationRunnable(
|
||||||
@@ -2882,6 +2943,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
|||||||
mService.addNotification(parent);
|
mService.addNotification(parent);
|
||||||
mService.addNotification(child);
|
mService.addNotification(child);
|
||||||
mService.addNotification(child2);
|
mService.addNotification(child2);
|
||||||
|
when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
|
||||||
|
|
||||||
NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
|
NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
|
||||||
mService.new SnoozeNotificationRunnable(
|
mService.new SnoozeNotificationRunnable(
|
||||||
@@ -2903,6 +2965,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
|||||||
mService.addNotification(parent);
|
mService.addNotification(parent);
|
||||||
mService.addNotification(child);
|
mService.addNotification(child);
|
||||||
mService.addNotification(child2);
|
mService.addNotification(child2);
|
||||||
|
when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
|
||||||
|
|
||||||
NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
|
NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
|
||||||
mService.new SnoozeNotificationRunnable(
|
mService.new SnoozeNotificationRunnable(
|
||||||
@@ -2928,6 +2991,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
|||||||
mTestNotificationChannel, 2, "group", false);
|
mTestNotificationChannel, 2, "group", false);
|
||||||
mService.addNotification(parent);
|
mService.addNotification(parent);
|
||||||
mService.addNotification(child);
|
mService.addNotification(child);
|
||||||
|
when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
|
||||||
|
|
||||||
NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
|
NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
|
||||||
mService.new SnoozeNotificationRunnable(
|
mService.new SnoozeNotificationRunnable(
|
||||||
@@ -2955,6 +3019,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
|||||||
final NotificationRecord child = generateNotificationRecord(
|
final NotificationRecord child = generateNotificationRecord(
|
||||||
mTestNotificationChannel, 2, "group", false);
|
mTestNotificationChannel, 2, "group", false);
|
||||||
mService.addNotification(child);
|
mService.addNotification(child);
|
||||||
|
when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
|
||||||
|
|
||||||
NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
|
NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
|
||||||
mService.new SnoozeNotificationRunnable(
|
mService.new SnoozeNotificationRunnable(
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.server.notification;
|
package com.android.server.notification;
|
||||||
|
|
||||||
|
import static com.android.server.notification.SnoozeHelper.CONCURRENT_SNOOZE_LIMIT;
|
||||||
import static com.android.server.notification.SnoozeHelper.EXTRA_KEY;
|
import static com.android.server.notification.SnoozeHelper.EXTRA_KEY;
|
||||||
|
|
||||||
import static junit.framework.Assert.assertEquals;
|
import static junit.framework.Assert.assertEquals;
|
||||||
@@ -280,6 +281,22 @@ public class SnoozeHelperTest extends UiServiceTestCase {
|
|||||||
UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
|
UserHandle.USER_SYSTEM, r.getSbn().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, null);
|
||||||
|
} else {
|
||||||
|
mSnoozeHelper.snooze(r, 9000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertFalse(mSnoozeHelper.canSnooze(1));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCancelByApp() throws Exception {
|
public void testCancelByApp() throws Exception {
|
||||||
NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
|
NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
|
||||||
|
|||||||
Reference in New Issue
Block a user