From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Julia Reynolds Date: Tue, 18 Jan 2022 11:59:54 -0500 Subject: [PATCH] Add a limit on channel group creation Same as exists for channels This is a backport of the fix in ag/16659457, including the adjustment from ag/20920023 (changed the max value from 50000 to 6000). Test: PreferencesHelperTest Bug: 210114537 Bug: 261723753 Change-Id: Ic27efba4c54e22eebca16fc948879e652df4467b (cherry picked from commit 37b3549807d15452ac334fae316e615c3b9b8e8b & I3f3a99765c161369e1b026686a0e5f0c83ed839e) Merged-In: I3f3a99765c161369e1b026686a0e5f0c83ed839e Merged-In: Ic27efba4c54e22eebca16fc948879e652df4467b (cherry picked from commit 0f29716ab6fbf236e5d8f688bcdfdadf32429545) Merged-In: Ic27efba4c54e22eebca16fc948879e652df4467b --- .../notification/PreferencesHelper.java | 16 ++++++- .../notification/PreferencesHelperTest.java | 47 +++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java index d4ba51cc3146..1a3779f7c607 100644 --- a/services/core/java/com/android/server/notification/PreferencesHelper.java +++ b/services/core/java/com/android/server/notification/PreferencesHelper.java @@ -73,7 +73,9 @@ public class PreferencesHelper implements RankingConfig { private static final String NON_BLOCKABLE_CHANNEL_DELIM = ":"; @VisibleForTesting - static final int NOTIFICATION_CHANNEL_COUNT_LIMIT = 50000; + static final int NOTIFICATION_CHANNEL_COUNT_LIMIT = 5000; + @VisibleForTesting + static final int NOTIFICATION_CHANNEL_GROUP_COUNT_LIMIT = 6000; @VisibleForTesting static final String TAG_RANKING = "ranking"; @@ -184,6 +186,7 @@ public class PreferencesHelper implements RankingConfig { } } boolean skipWarningLogged = false; + boolean skipGroupWarningLogged = false; PackagePreferences r = getOrCreatePackagePreferencesLocked(name, uid, XmlUtils.readIntAttribute( @@ -220,6 +223,14 @@ public class PreferencesHelper implements RankingConfig { String tagName = parser.getName(); // Channel groups if (TAG_GROUP.equals(tagName)) { + if (r.groups.size() >= NOTIFICATION_CHANNEL_GROUP_COUNT_LIMIT) { + if (!skipGroupWarningLogged) { + Slog.w(TAG, "Skipping further groups for " + r.pkg + + "; app has too many"); + skipGroupWarningLogged = true; + } + continue; + } String id = parser.getAttributeValue(null, ATT_ID); CharSequence groupName = parser.getAttributeValue(null, ATT_NAME); @@ -610,6 +621,9 @@ public class PreferencesHelper implements RankingConfig { } if (fromTargetApp) { group.setBlocked(false); + if (r.groups.size() >= NOTIFICATION_CHANNEL_GROUP_COUNT_LIMIT) { + throw new IllegalStateException("Limit exceed; cannot create more groups"); + } } final NotificationChannelGroup oldGroup = r.groups.get(group.getId()); if (!group.equals(oldGroup)) { diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java index 2cede07de257..dfb62999be5f 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java @@ -23,6 +23,7 @@ import static android.app.NotificationManager.IMPORTANCE_NONE; import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED; import static com.android.server.notification.PreferencesHelper.NOTIFICATION_CHANNEL_COUNT_LIMIT; +import static com.android.server.notification.PreferencesHelper.NOTIFICATION_CHANNEL_GROUP_COUNT_LIMIT; import static junit.framework.Assert.assertNull; import static junit.framework.Assert.fail; @@ -2729,4 +2730,50 @@ public class PreferencesHelperTest extends UiServiceTestCase { assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, extraChannel, true)); assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, extraChannel1, true)); } + + @Test + public void testTooManyGroups() { + for (int i = 0; i < NOTIFICATION_CHANNEL_GROUP_COUNT_LIMIT; i++) { + NotificationChannelGroup group = new NotificationChannelGroup(String.valueOf(i), + String.valueOf(i)); + mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, true); + } + try { + NotificationChannelGroup group = new NotificationChannelGroup( + String.valueOf(NOTIFICATION_CHANNEL_GROUP_COUNT_LIMIT), + String.valueOf(NOTIFICATION_CHANNEL_GROUP_COUNT_LIMIT)); + mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, true); + fail("Allowed to create too many notification channel groups"); + } catch (IllegalStateException e) { + // great + } + } + + @Test + public void testTooManyGroups_xml() throws Exception { + String extraGroup = "EXTRA"; + String extraGroup1 = "EXTRA1"; + + // create first... many... directly so we don't need a big xml blob in this test + for (int i = 0; i < NOTIFICATION_CHANNEL_GROUP_COUNT_LIMIT; i++) { + NotificationChannelGroup group = new NotificationChannelGroup(String.valueOf(i), + String.valueOf(i)); + mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, true); + } + + final String xml = "\n" + + "\n" + + "" + + "" + + "" + + ""; + XmlPullParser parser = Xml.newPullParser(); + parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())), + null); + parser.nextTag(); + mHelper.readXml(parser, false, UserHandle.USER_ALL); + + assertNull(mHelper.getNotificationChannelGroup(extraGroup, PKG_O, UID_O)); + assertNull(mHelper.getNotificationChannelGroup(extraGroup1, PKG_O, UID_O)); + } }