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:
@@ -62,6 +62,9 @@ public 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";
|
||||||
@@ -150,7 +153,7 @@ public class SnoozeHelper {
|
|||||||
ArrayMap<String, Long> snoozed =
|
ArrayMap<String, Long> snoozed =
|
||||||
mPersistedSnoozedNotifications.get(getPkgKey(userId, pkg));
|
mPersistedSnoozedNotifications.get(getPkgKey(userId, pkg));
|
||||||
if (snoozed != null) {
|
if (snoozed != null) {
|
||||||
time = snoozed.get(key);
|
time = snoozed.get(getTrimmedString(key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (time == null) {
|
if (time == null) {
|
||||||
@@ -164,7 +167,7 @@ public class SnoozeHelper {
|
|||||||
ArrayMap<String, String> snoozed =
|
ArrayMap<String, String> snoozed =
|
||||||
mPersistedSnoozedNotificationsWithContext.get(getPkgKey(userId, pkg));
|
mPersistedSnoozedNotificationsWithContext.get(getPkgKey(userId, pkg));
|
||||||
if (snoozed != null) {
|
if (snoozed != null) {
|
||||||
return snoozed.get(key);
|
return snoozed.get(getTrimmedString(key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -249,7 +252,8 @@ public class SnoozeHelper {
|
|||||||
scheduleRepost(pkg, key, userId, duration);
|
scheduleRepost(pkg, key, userId, duration);
|
||||||
Long activateAt = System.currentTimeMillis() + duration;
|
Long activateAt = System.currentTimeMillis() + duration;
|
||||||
synchronized (mLock) {
|
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();
|
int userId = record.getUser().getIdentifier();
|
||||||
if (contextId != null) {
|
if (contextId != null) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
storeRecordLocked(record.getSbn().getPackageName(), record.getKey(),
|
storeRecordLocked(record.getSbn().getPackageName(),
|
||||||
userId, mPersistedSnoozedNotificationsWithContext, contextId);
|
getTrimmedString(record.getKey()),
|
||||||
|
userId, mPersistedSnoozedNotificationsWithContext,
|
||||||
|
getTrimmedString(contextId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
snooze(record);
|
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,
|
private <T> void storeRecordLocked(String pkg, String key, Integer userId,
|
||||||
ArrayMap<String, ArrayMap<String, T>> targets, T object) {
|
ArrayMap<String, ArrayMap<String, T>> targets, T object) {
|
||||||
|
|
||||||
@@ -382,12 +395,14 @@ public 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) {
|
||||||
final String pkg = mPackages.remove(key);
|
final String pkg = mPackages.remove(key);
|
||||||
mUsers.remove(key);
|
mUsers.remove(key);
|
||||||
removeRecordLocked(pkg, key, userId, mPersistedSnoozedNotifications);
|
removeRecordLocked(pkg, trimmedKey, userId, mPersistedSnoozedNotifications);
|
||||||
removeRecordLocked(pkg, key, userId, mPersistedSnoozedNotificationsWithContext);
|
removeRecordLocked(pkg, trimmedKey, userId, mPersistedSnoozedNotificationsWithContext);
|
||||||
ArrayMap<String, NotificationRecord> records =
|
ArrayMap<String, NotificationRecord> records =
|
||||||
mSnoozedNotifications.get(getPkgKey(userId, pkg));
|
mSnoozedNotifications.get(getPkgKey(userId, pkg));
|
||||||
if (records == null) {
|
if (records == null) {
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ import java.io.BufferedOutputStream;
|
|||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
@@ -245,6 +246,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 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
|
@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);
|
||||||
@@ -593,13 +625,20 @@ public class SnoozeHelperTest extends UiServiceTestCase {
|
|||||||
public void testClearData() {
|
public void testClearData() {
|
||||||
// snooze 2 from same package
|
// snooze 2 from same package
|
||||||
NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
|
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(r, 1000);
|
||||||
mSnoozeHelper.snooze(r2, 1000);
|
mSnoozeHelper.snooze(r2, 1000);
|
||||||
assertTrue(mSnoozeHelper.isSnoozed(
|
assertTrue(mSnoozeHelper.isSnoozed(
|
||||||
UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
|
UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
|
||||||
assertTrue(mSnoozeHelper.isSnoozed(
|
assertTrue(mSnoozeHelper.isSnoozed(
|
||||||
UserHandle.USER_SYSTEM, r2.getSbn().getPackageName(), r2.getKey()));
|
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
|
// clear data
|
||||||
mSnoozeHelper.clearData(UserHandle.USER_SYSTEM, "pkg");
|
mSnoozeHelper.clearData(UserHandle.USER_SYSTEM, "pkg");
|
||||||
|
|||||||
Reference in New Issue
Block a user