Loading services/core/java/com/android/server/notification/SnoozeHelper.java +22 −7 Original line number Diff line number Diff line Loading @@ -64,6 +64,9 @@ public class SnoozeHelper { static final int CONCURRENT_SNOOZE_LIMIT = 500; // A safe size for strings to be put in persistent storage, to avoid breaking the XML write. static final int MAX_STRING_LENGTH = 1000; protected static final String XML_TAG_NAME = "snoozed-notifications"; private static final String XML_SNOOZED_NOTIFICATION = "notification"; Loading Loading @@ -152,7 +155,7 @@ public class SnoozeHelper { ArrayMap<String, Long> snoozed = mPersistedSnoozedNotifications.get(getPkgKey(userId, pkg)); if (snoozed != null) { time = snoozed.get(key); time = snoozed.get(getTrimmedString(key)); } } if (time == null) { Loading @@ -166,7 +169,7 @@ public class SnoozeHelper { ArrayMap<String, String> snoozed = mPersistedSnoozedNotificationsWithContext.get(getPkgKey(userId, pkg)); if (snoozed != null) { return snoozed.get(key); return snoozed.get(getTrimmedString(key)); } } return null; Loading Loading @@ -251,7 +254,8 @@ public class SnoozeHelper { scheduleRepost(pkg, key, userId, duration); Long activateAt = System.currentTimeMillis() + duration; synchronized (mLock) { storeRecordLocked(pkg, key, userId, mPersistedSnoozedNotifications, activateAt); storeRecordLocked(pkg, getTrimmedString(key), userId, mPersistedSnoozedNotifications, activateAt); } } Loading @@ -262,8 +266,10 @@ public class SnoozeHelper { int userId = record.getUser().getIdentifier(); if (contextId != null) { synchronized (mLock) { storeRecordLocked(record.getSbn().getPackageName(), record.getKey(), userId, mPersistedSnoozedNotificationsWithContext, contextId); storeRecordLocked(record.getSbn().getPackageName(), getTrimmedString(record.getKey()), userId, mPersistedSnoozedNotificationsWithContext, getTrimmedString(contextId)); } } snooze(record); Loading @@ -280,6 +286,13 @@ public class SnoozeHelper { } } private String getTrimmedString(String key) { if (key != null && key.length() > MAX_STRING_LENGTH) { return key.substring(0, MAX_STRING_LENGTH); } return key; } private <T> void storeRecordLocked(String pkg, String key, Integer userId, ArrayMap<String, ArrayMap<String, T>> targets, T object) { Loading Loading @@ -384,12 +397,14 @@ public class SnoozeHelper { } protected void repost(String key, int userId, boolean muteOnReturn) { final String trimmedKey = getTrimmedString(key); NotificationRecord record; synchronized (mLock) { final String pkg = mPackages.remove(key); mUsers.remove(key); removeRecordLocked(pkg, key, userId, mPersistedSnoozedNotifications); removeRecordLocked(pkg, key, userId, mPersistedSnoozedNotificationsWithContext); removeRecordLocked(pkg, trimmedKey, userId, mPersistedSnoozedNotifications); removeRecordLocked(pkg, trimmedKey, userId, mPersistedSnoozedNotificationsWithContext); ArrayMap<String, NotificationRecord> records = mSnoozedNotifications.get(getPkgKey(userId, pkg)); if (records == null) { Loading services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java +40 −1 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Collections; @SmallTest @RunWith(AndroidJUnit4.class) Loading Loading @@ -247,6 +248,37 @@ public class SnoozeHelperTest extends UiServiceTestCase { assertEquals("key2", captor2.getValue().getIntent().getStringExtra(EXTRA_KEY)); } @Test public void testLongTagPersistedNotification() throws Exception { String longTag = String.join("", Collections.nCopies(66000, "A")); NotificationRecord r = getNotificationRecord("pkg", 1, longTag, UserHandle.SYSTEM); mSnoozeHelper.snooze(r, 0); // We store the full key in temp storage. ArgumentCaptor<PendingIntent> captor = ArgumentCaptor.forClass(PendingIntent.class); verify(mAm).setExactAndAllowWhileIdle(anyInt(), anyLong(), captor.capture()); assertEquals(66010, captor.getValue().getIntent().getStringExtra(EXTRA_KEY).length()); TypedXmlSerializer serializer = Xml.newFastSerializer(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); serializer.setOutput(new BufferedOutputStream(baos), "utf-8"); serializer.startDocument(null, true); mSnoozeHelper.writeXml(serializer); serializer.endDocument(); serializer.flush(); TypedXmlPullParser parser = Xml.newFastPullParser(); parser.setInput(new BufferedInputStream( new ByteArrayInputStream(baos.toByteArray())), "utf-8"); mSnoozeHelper.readXml(parser, 4); mSnoozeHelper.scheduleRepostsForPersistedNotifications(5); // We trim the key in persistent storage. verify(mAm, times(2)).setExactAndAllowWhileIdle(anyInt(), anyLong(), captor.capture()); assertEquals(1000, captor.getValue().getIntent().getStringExtra(EXTRA_KEY).length()); } @Test public void testSnoozeForTime() throws Exception { NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM); Loading Loading @@ -595,13 +627,20 @@ public class SnoozeHelperTest extends UiServiceTestCase { public void testClearData() { // snooze 2 from same package NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM); NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.SYSTEM); NotificationRecord r2 = getNotificationRecord("pkg", 2, "two" + String.join("", Collections.nCopies(66000, "2")), UserHandle.SYSTEM); mSnoozeHelper.snooze(r, 1000); mSnoozeHelper.snooze(r2, 1000); assertTrue(mSnoozeHelper.isSnoozed( UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey())); assertTrue(mSnoozeHelper.isSnoozed( UserHandle.USER_SYSTEM, r2.getSbn().getPackageName(), r2.getKey())); assertFalse(0L == mSnoozeHelper.getSnoozeTimeForUnpostedNotification( r.getUser().getIdentifier(), r.getSbn().getPackageName(), r.getSbn().getKey())); assertFalse(0L == mSnoozeHelper.getSnoozeTimeForUnpostedNotification( r2.getUser().getIdentifier(), r2.getSbn().getPackageName(), r2.getSbn().getKey())); // clear data mSnoozeHelper.clearData(UserHandle.USER_SYSTEM, "pkg"); Loading Loading
services/core/java/com/android/server/notification/SnoozeHelper.java +22 −7 Original line number Diff line number Diff line Loading @@ -64,6 +64,9 @@ public class SnoozeHelper { static final int CONCURRENT_SNOOZE_LIMIT = 500; // A safe size for strings to be put in persistent storage, to avoid breaking the XML write. static final int MAX_STRING_LENGTH = 1000; protected static final String XML_TAG_NAME = "snoozed-notifications"; private static final String XML_SNOOZED_NOTIFICATION = "notification"; Loading Loading @@ -152,7 +155,7 @@ public class SnoozeHelper { ArrayMap<String, Long> snoozed = mPersistedSnoozedNotifications.get(getPkgKey(userId, pkg)); if (snoozed != null) { time = snoozed.get(key); time = snoozed.get(getTrimmedString(key)); } } if (time == null) { Loading @@ -166,7 +169,7 @@ public class SnoozeHelper { ArrayMap<String, String> snoozed = mPersistedSnoozedNotificationsWithContext.get(getPkgKey(userId, pkg)); if (snoozed != null) { return snoozed.get(key); return snoozed.get(getTrimmedString(key)); } } return null; Loading Loading @@ -251,7 +254,8 @@ public class SnoozeHelper { scheduleRepost(pkg, key, userId, duration); Long activateAt = System.currentTimeMillis() + duration; synchronized (mLock) { storeRecordLocked(pkg, key, userId, mPersistedSnoozedNotifications, activateAt); storeRecordLocked(pkg, getTrimmedString(key), userId, mPersistedSnoozedNotifications, activateAt); } } Loading @@ -262,8 +266,10 @@ public class SnoozeHelper { int userId = record.getUser().getIdentifier(); if (contextId != null) { synchronized (mLock) { storeRecordLocked(record.getSbn().getPackageName(), record.getKey(), userId, mPersistedSnoozedNotificationsWithContext, contextId); storeRecordLocked(record.getSbn().getPackageName(), getTrimmedString(record.getKey()), userId, mPersistedSnoozedNotificationsWithContext, getTrimmedString(contextId)); } } snooze(record); Loading @@ -280,6 +286,13 @@ public class SnoozeHelper { } } private String getTrimmedString(String key) { if (key != null && key.length() > MAX_STRING_LENGTH) { return key.substring(0, MAX_STRING_LENGTH); } return key; } private <T> void storeRecordLocked(String pkg, String key, Integer userId, ArrayMap<String, ArrayMap<String, T>> targets, T object) { Loading Loading @@ -384,12 +397,14 @@ public class SnoozeHelper { } protected void repost(String key, int userId, boolean muteOnReturn) { final String trimmedKey = getTrimmedString(key); NotificationRecord record; synchronized (mLock) { final String pkg = mPackages.remove(key); mUsers.remove(key); removeRecordLocked(pkg, key, userId, mPersistedSnoozedNotifications); removeRecordLocked(pkg, key, userId, mPersistedSnoozedNotificationsWithContext); removeRecordLocked(pkg, trimmedKey, userId, mPersistedSnoozedNotifications); removeRecordLocked(pkg, trimmedKey, userId, mPersistedSnoozedNotificationsWithContext); ArrayMap<String, NotificationRecord> records = mSnoozedNotifications.get(getPkgKey(userId, pkg)); if (records == null) { Loading
services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java +40 −1 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Collections; @SmallTest @RunWith(AndroidJUnit4.class) Loading Loading @@ -247,6 +248,37 @@ public class SnoozeHelperTest extends UiServiceTestCase { assertEquals("key2", captor2.getValue().getIntent().getStringExtra(EXTRA_KEY)); } @Test public void testLongTagPersistedNotification() throws Exception { String longTag = String.join("", Collections.nCopies(66000, "A")); NotificationRecord r = getNotificationRecord("pkg", 1, longTag, UserHandle.SYSTEM); mSnoozeHelper.snooze(r, 0); // We store the full key in temp storage. ArgumentCaptor<PendingIntent> captor = ArgumentCaptor.forClass(PendingIntent.class); verify(mAm).setExactAndAllowWhileIdle(anyInt(), anyLong(), captor.capture()); assertEquals(66010, captor.getValue().getIntent().getStringExtra(EXTRA_KEY).length()); TypedXmlSerializer serializer = Xml.newFastSerializer(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); serializer.setOutput(new BufferedOutputStream(baos), "utf-8"); serializer.startDocument(null, true); mSnoozeHelper.writeXml(serializer); serializer.endDocument(); serializer.flush(); TypedXmlPullParser parser = Xml.newFastPullParser(); parser.setInput(new BufferedInputStream( new ByteArrayInputStream(baos.toByteArray())), "utf-8"); mSnoozeHelper.readXml(parser, 4); mSnoozeHelper.scheduleRepostsForPersistedNotifications(5); // We trim the key in persistent storage. verify(mAm, times(2)).setExactAndAllowWhileIdle(anyInt(), anyLong(), captor.capture()); assertEquals(1000, captor.getValue().getIntent().getStringExtra(EXTRA_KEY).length()); } @Test public void testSnoozeForTime() throws Exception { NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM); Loading Loading @@ -595,13 +627,20 @@ public class SnoozeHelperTest extends UiServiceTestCase { public void testClearData() { // snooze 2 from same package NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM); NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.SYSTEM); NotificationRecord r2 = getNotificationRecord("pkg", 2, "two" + String.join("", Collections.nCopies(66000, "2")), UserHandle.SYSTEM); mSnoozeHelper.snooze(r, 1000); mSnoozeHelper.snooze(r2, 1000); assertTrue(mSnoozeHelper.isSnoozed( UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey())); assertTrue(mSnoozeHelper.isSnoozed( UserHandle.USER_SYSTEM, r2.getSbn().getPackageName(), r2.getKey())); assertFalse(0L == mSnoozeHelper.getSnoozeTimeForUnpostedNotification( r.getUser().getIdentifier(), r.getSbn().getPackageName(), r.getSbn().getKey())); assertFalse(0L == mSnoozeHelper.getSnoozeTimeForUnpostedNotification( r2.getUser().getIdentifier(), r2.getSbn().getPackageName(), r2.getSbn().getKey())); // clear data mSnoozeHelper.clearData(UserHandle.USER_SYSTEM, "pkg"); Loading