summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Iavor-Valentin Iftime <valiiftime@google.com> 2023-11-29 11:21:23 +0000
committer Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> 2023-11-29 11:21:23 +0000
commit772f6c9946089a06da99e3b31806886b56f12c17 (patch)
treedd4027de1b6614e4fa3876c711d0307639faf9c3
parente311a0803f2282ee811562ce0f55a65c0d2efe88 (diff)
parenta596d7b2aafb2f68d1bbc535a9ee591a4f14dc6f (diff)
Merge "Enforce persisted snoozed notifications limits" into sc-dev am: 5ac423b8c2 am: 40272384d0 am: a596d7b2aa
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/25387217 Change-Id: I4f59805d331d96c923cce0c6b146d3030f42a8c3 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--services/core/java/com/android/server/notification/SnoozeHelper.java23
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java104
2 files changed, 124 insertions, 3 deletions
diff --git a/services/core/java/com/android/server/notification/SnoozeHelper.java b/services/core/java/com/android/server/notification/SnoozeHelper.java
index ffce13f41f24..f76ae51c5bcb 100644
--- a/services/core/java/com/android/server/notification/SnoozeHelper.java
+++ b/services/core/java/com/android/server/notification/SnoozeHelper.java
@@ -142,13 +142,29 @@ public class SnoozeHelper {
protected boolean canSnooze(int numberToSnooze) {
synchronized (mLock) {
- if ((mPackages.size() + numberToSnooze) > CONCURRENT_SNOOZE_LIMIT) {
+ if ((mPackages.size() + numberToSnooze) > CONCURRENT_SNOOZE_LIMIT
+ || (countPersistedNotificationsLocked() + numberToSnooze)
+ > CONCURRENT_SNOOZE_LIMIT) {
return false;
}
}
return true;
}
+ private int countPersistedNotificationsLocked() {
+ int numNotifications = 0;
+ for (ArrayMap<String, String> persistedWithContext :
+ mPersistedSnoozedNotificationsWithContext.values()) {
+ numNotifications += persistedWithContext.size();
+ }
+ for (ArrayMap<String, Long> persistedWithDuration :
+ mPersistedSnoozedNotifications.values()) {
+ numNotifications += persistedWithDuration.size();
+ }
+ return numNotifications;
+ }
+
+
@NonNull
protected Long getSnoozeTimeForUnpostedNotification(int userId, String pkg, String key) {
Long time = null;
@@ -451,6 +467,11 @@ public class SnoozeHelper {
mPackages.remove(groupSummaryKey);
mUsers.remove(groupSummaryKey);
+ final String trimmedKey = getTrimmedString(groupSummaryKey);
+ removeRecordLocked(pkg, trimmedKey, userId, mPersistedSnoozedNotifications);
+ removeRecordLocked(pkg, trimmedKey, userId,
+ mPersistedSnoozedNotificationsWithContext);
+
if (record != null && !record.isCanceled) {
Runnable runnable = () -> {
MetricsLogger.action(record.getLogMaker()
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
index 8d559fea3dc7..fd2265ae81de 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
@@ -18,6 +18,8 @@ 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.google.common.truth.Truth.assertThat;
+
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNull;
@@ -75,6 +77,16 @@ import java.io.IOException;
public class SnoozeHelperTest extends UiServiceTestCase {
private static final String TEST_CHANNEL_ID = "test_channel_id";
+ private static final String XML_TAG_NAME = "snoozed-notifications";
+ private static final String XML_SNOOZED_NOTIFICATION = "notification";
+ private static final String XML_SNOOZED_NOTIFICATION_CONTEXT = "context";
+ private static final String XML_SNOOZED_NOTIFICATION_KEY = "key";
+ private static final String XML_SNOOZED_NOTIFICATION_TIME = "time";
+ private static final String XML_SNOOZED_NOTIFICATION_CONTEXT_ID = "id";
+ private static final String XML_SNOOZED_NOTIFICATION_VERSION_LABEL = "version";
+ private static final String XML_SNOOZED_NOTIFICATION_PKG = "pkg";
+ private static final String XML_SNOOZED_NOTIFICATION_USER_ID = "user-id";
+
@Mock SnoozeHelper.Callback mCallback;
@Mock AlarmManager mAm;
@Mock ManagedServices.UserProfiles mUserProfiles;
@@ -329,6 +341,56 @@ public class SnoozeHelperTest extends UiServiceTestCase {
}
@Test
+ public void testSnoozeLimit_maximumPersisted() throws XmlPullParserException, IOException {
+ final long snoozeTimeout = 1234;
+ final String snoozeContext = "ctx";
+ // Serialize & deserialize notifications so that only persisted lists are used
+ TypedXmlSerializer serializer = Xml.newFastSerializer();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
+ serializer.startDocument(null, true);
+ serializer.startTag(null, XML_TAG_NAME);
+ // Serialize maximum number of timed + context snoozed notifications, half of each
+ for (int i = 0; i < CONCURRENT_SNOOZE_LIMIT; i++) {
+ final boolean timedNotification = i % 2 == 0;
+ if (timedNotification) {
+ serializer.startTag(null, XML_SNOOZED_NOTIFICATION);
+ } else {
+ serializer.startTag(null, XML_SNOOZED_NOTIFICATION_CONTEXT);
+ }
+ serializer.attribute(null, XML_SNOOZED_NOTIFICATION_PKG, "pkg");
+ serializer.attributeInt(null, XML_SNOOZED_NOTIFICATION_USER_ID,
+ UserHandle.USER_SYSTEM);
+ serializer.attributeInt(null, XML_SNOOZED_NOTIFICATION_VERSION_LABEL, 1);
+ serializer.attribute(null, XML_SNOOZED_NOTIFICATION_KEY, "key" + i);
+ if (timedNotification) {
+ serializer.attributeLong(null, XML_SNOOZED_NOTIFICATION_TIME, snoozeTimeout);
+ serializer.endTag(null, XML_SNOOZED_NOTIFICATION);
+ } else {
+ serializer.attribute(null, XML_SNOOZED_NOTIFICATION_CONTEXT_ID, snoozeContext);
+ serializer.endTag(null, XML_SNOOZED_NOTIFICATION_CONTEXT);
+ }
+ }
+ serializer.endTag(null, XML_TAG_NAME);
+ serializer.endDocument();
+ serializer.flush();
+
+ TypedXmlPullParser parser = Xml.newFastPullParser();
+ parser.setInput(new BufferedInputStream(
+ new ByteArrayInputStream(baos.toByteArray())), "utf-8");
+ mSnoozeHelper.readXml(parser, 1);
+ // Verify that we can't snooze any more notifications
+ // and that the limit is caused by persisted notifications
+ assertThat(mSnoozeHelper.canSnooze(1)).isFalse();
+ assertThat(mSnoozeHelper.isSnoozed(UserHandle.USER_SYSTEM, "pkg", "key0")).isFalse();
+ assertThat(mSnoozeHelper.getSnoozeTimeForUnpostedNotification(UserHandle.USER_SYSTEM,
+ "pkg", "key0")).isEqualTo(snoozeTimeout);
+ assertThat(
+ mSnoozeHelper.getSnoozeContextForUnpostedNotification(UserHandle.USER_SYSTEM, "pkg",
+ "key1")).isEqualTo(snoozeContext);
+ }
+
+ @Test
public void testCancelByApp() throws Exception {
NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.SYSTEM);
@@ -601,6 +663,7 @@ public class SnoozeHelperTest extends UiServiceTestCase {
@Test
public void repostGroupSummary_repostsSummary() throws Exception {
+ final int snoozeDuration = 1000;
IntArray profileIds = new IntArray();
profileIds.add(UserHandle.USER_SYSTEM);
when(mUserProfiles.getCurrentProfileIds()).thenReturn(profileIds);
@@ -608,10 +671,44 @@ public class SnoozeHelperTest extends UiServiceTestCase {
"pkg", 1, "one", UserHandle.SYSTEM, "group1", true);
NotificationRecord r2 = getNotificationRecord(
"pkg", 2, "two", UserHandle.SYSTEM, "group1", false);
- mSnoozeHelper.snooze(r, 1000);
- mSnoozeHelper.snooze(r2, 1000);
+ final long snoozeTime = System.currentTimeMillis() + snoozeDuration;
+ mSnoozeHelper.snooze(r, snoozeDuration);
+ mSnoozeHelper.snooze(r2, snoozeDuration);
+ assertEquals(2, mSnoozeHelper.getSnoozed().size());
+ assertEquals(2, mSnoozeHelper.getSnoozed(UserHandle.USER_SYSTEM, "pkg").size());
+ // Verify that summary notification was added to the persisted list
+ assertThat(mSnoozeHelper.getSnoozeTimeForUnpostedNotification(UserHandle.USER_SYSTEM, "pkg",
+ r.getKey())).isAtLeast(snoozeTime);
+
+ mSnoozeHelper.repostGroupSummary("pkg", UserHandle.USER_SYSTEM, r.getGroupKey());
+
+ verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r, false);
+ verify(mCallback, never()).repost(UserHandle.USER_SYSTEM, r2, false);
+
+ assertEquals(1, mSnoozeHelper.getSnoozed().size());
+ assertEquals(1, mSnoozeHelper.getSnoozed(UserHandle.USER_SYSTEM, "pkg").size());
+ // Verify that summary notification was removed from the persisted list
+ assertThat(mSnoozeHelper.getSnoozeTimeForUnpostedNotification(UserHandle.USER_SYSTEM, "pkg",
+ r.getKey())).isEqualTo(0);
+ }
+
+ @Test
+ public void snoozeWithContext_repostGroupSummary_removesPersisted() throws Exception {
+ final String snoozeContext = "zzzzz";
+ IntArray profileIds = new IntArray();
+ profileIds.add(UserHandle.USER_SYSTEM);
+ when(mUserProfiles.getCurrentProfileIds()).thenReturn(profileIds);
+ NotificationRecord r = getNotificationRecord(
+ "pkg", 1, "one", UserHandle.SYSTEM, "group1", true);
+ NotificationRecord r2 = getNotificationRecord(
+ "pkg", 2, "two", UserHandle.SYSTEM, "group1", false);
+ mSnoozeHelper.snooze(r, snoozeContext);
+ mSnoozeHelper.snooze(r2, snoozeContext);
assertEquals(2, mSnoozeHelper.getSnoozed().size());
assertEquals(2, mSnoozeHelper.getSnoozed(UserHandle.USER_SYSTEM, "pkg").size());
+ // Verify that summary notification was added to the persisted list
+ assertThat(mSnoozeHelper.getSnoozeContextForUnpostedNotification(UserHandle.USER_SYSTEM,
+ "pkg", r.getKey())).isEqualTo(snoozeContext);
mSnoozeHelper.repostGroupSummary("pkg", UserHandle.USER_SYSTEM, r.getGroupKey());
@@ -620,6 +717,9 @@ public class SnoozeHelperTest extends UiServiceTestCase {
assertEquals(1, mSnoozeHelper.getSnoozed().size());
assertEquals(1, mSnoozeHelper.getSnoozed(UserHandle.USER_SYSTEM, "pkg").size());
+ // Verify that summary notification was removed from the persisted list
+ assertThat(mSnoozeHelper.getSnoozeContextForUnpostedNotification(UserHandle.USER_SYSTEM,
+ "pkg", r.getKey())).isNull();
}
@Test