Trim strings added to persistent snoozed notification storage.
Fix: 258422365 Test: atest NotificationManagerServiceTest SnoozeHelperTest; Also tested the reproduction steps in b/258422365#comment6 manually to check that the issue doesn't happen anymore. Change-Id: I5a2823f10053ea8c83c612a567d6d4f1b6af23e7
This commit is contained in:
@@ -59,6 +59,9 @@ public final class SnoozeHelper {
|
|||||||
|
|
||||||
static final int CONCURRENT_SNOOZE_LIMIT = 500;
|
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";
|
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";
|
||||||
@@ -200,7 +203,7 @@ public final class SnoozeHelper {
|
|||||||
scheduleRepost(key, duration);
|
scheduleRepost(key, duration);
|
||||||
Long activateAt = System.currentTimeMillis() + duration;
|
Long activateAt = System.currentTimeMillis() + duration;
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
mPersistedSnoozedNotifications.put(key, activateAt);
|
mPersistedSnoozedNotifications.put(getTrimmedString(key), activateAt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,7 +213,10 @@ public final class SnoozeHelper {
|
|||||||
protected void snooze(NotificationRecord record, String contextId) {
|
protected void snooze(NotificationRecord record, String contextId) {
|
||||||
if (contextId != null) {
|
if (contextId != null) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
mPersistedSnoozedNotificationsWithContext.put(record.getKey(), contextId);
|
mPersistedSnoozedNotificationsWithContext.put(
|
||||||
|
getTrimmedString(record.getKey()),
|
||||||
|
getTrimmedString(contextId)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
snooze(record);
|
snooze(record);
|
||||||
@@ -225,6 +231,13 @@ public final class SnoozeHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getTrimmedString(String key) {
|
||||||
|
if (key != null && key.length() > MAX_STRING_LENGTH) {
|
||||||
|
return key.substring(0, MAX_STRING_LENGTH);
|
||||||
|
}
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
protected boolean cancel(int userId, String pkg, String tag, int id) {
|
protected boolean cancel(int userId, String pkg, String tag, int id) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
final Set<Map.Entry<String, NotificationRecord>> records =
|
final Set<Map.Entry<String, NotificationRecord>> records =
|
||||||
@@ -293,10 +306,12 @@ public final class SnoozeHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void repost(String key, int userId, boolean muteOnReturn) {
|
protected void repost(String key, int userId, boolean muteOnReturn) {
|
||||||
|
final String trimmedKey = getTrimmedString(key);
|
||||||
|
|
||||||
NotificationRecord record;
|
NotificationRecord record;
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
mPersistedSnoozedNotifications.remove(key);
|
mPersistedSnoozedNotifications.remove(trimmedKey);
|
||||||
mPersistedSnoozedNotificationsWithContext.remove(key);
|
mPersistedSnoozedNotificationsWithContext.remove(trimmedKey);
|
||||||
record = mSnoozedNotifications.remove(key);
|
record = mSnoozedNotifications.remove(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -233,6 +233,37 @@ public class SnoozeHelperTest extends UiServiceTestCase {
|
|||||||
assertEquals("key2", captor2.getValue().getIntent().getStringExtra(EXTRA_KEY));
|
assertEquals("key2", captor2.getValue().getIntent().getStringExtra(EXTRA_KEY));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testScheduleRepostsForLongTagPersistedNotification() throws Exception {
|
||||||
|
String longTag = "A".repeat(66000);
|
||||||
|
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
|
@Test
|
||||||
public void testSnoozeForTime() throws Exception {
|
public void testSnoozeForTime() 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