Trim strings added to persistent snoozed notification storage.

This is a backport of ag/20581190 and includes the fix in ag/20778075.
Note that on this branch, clearData doesn't seem to actually clear persistent storage.

Bug: 258422365
Test: atest NotificationManagerServiceTest SnoozeHelperTest
Change-Id: If7c7db6694330ffbac551d044efadb26219fe17f
Merged-In: I5a2823f10053ea8c83c612a567d6d4f1b6af23e7
Merged-In: Ie809cb4d648a40622618e0fb374f36b6d8dc972a
Merged-In: If7c7db6694330ffbac551d044efadb26219fe17f
This commit is contained in:
Ioana Alexandru
2023-01-05 22:45:21 +00:00
parent 41c877702a
commit 6b587717ce
2 changed files with 62 additions and 8 deletions

View File

@@ -62,6 +62,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";
@@ -150,7 +153,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) {
@@ -164,7 +167,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;
@@ -249,7 +252,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);
}
}
@@ -260,8 +264,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);
@@ -278,6 +284,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) {
@@ -382,12 +395,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) {

View File

@@ -67,6 +67,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)
@@ -245,6 +246,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());
XmlSerializer serializer = Xml.newSerializer();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
serializer.startDocument(null, true);
mSnoozeHelper.writeXml(serializer);
serializer.endDocument();
serializer.flush();
XmlPullParser parser = Xml.newPullParser();
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);
@@ -593,13 +625,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");