Loading services/core/java/com/android/server/notification/NotificationManagerInternal.java +1 −1 Original line number Diff line number Diff line Loading @@ -44,7 +44,7 @@ public interface NotificationManagerInternal { void onConversationRemoved(String pkg, int uid, Set<String> shortcuts); /** Get the number of notification channels for a given package */ /** Get the number of app created notification channels for a given package */ int getNumNotificationChannelsForPackage(String pkg, int uid, boolean includeDeleted); /** Does the specified package/uid have permission to post notifications? */ Loading services/core/java/com/android/server/notification/NotificationManagerService.java +26 −14 Original line number Diff line number Diff line Loading @@ -4392,8 +4392,9 @@ public class NotificationManagerService extends SystemService { List<NotificationChannel> channels = channelsList.getList(); final int channelsSize = channels.size(); ParceledListSlice<NotificationChannel> oldChannels = mPreferencesHelper.getNotificationChannels(pkg, uid, true); final boolean hadChannel = oldChannels != null && !oldChannels.getList().isEmpty(); mPreferencesHelper.getNotificationChannels(pkg, uid, true, false); final boolean hadNonBundleChannel = oldChannels != null && !oldChannels.getList().isEmpty(); boolean needsPolicyFileChange = false; boolean hasRequestedNotificationPermission = false; for (int i = 0; i < channelsSize; i++) { Loading @@ -4410,13 +4411,18 @@ public class NotificationManagerService extends SystemService { mPreferencesHelper.getNotificationChannel(pkg, uid, channel.getId(), false), NOTIFICATION_CHANNEL_OR_GROUP_ADDED); boolean hasChannel = hadChannel || hasRequestedNotificationPermission; if (!hasChannel) { boolean hasNonBundleChannel = hadNonBundleChannel || hasRequestedNotificationPermission; if (!hasNonBundleChannel) { ParceledListSlice<NotificationChannel> currChannels = mPreferencesHelper.getNotificationChannels(pkg, uid, true); hasChannel = currChannels != null && !currChannels.getList().isEmpty(); } if (!hadChannel && hasChannel && !hasRequestedNotificationPermission mPreferencesHelper.getNotificationChannels(pkg, uid, true, false); hasNonBundleChannel = currChannels != null && !currChannels.getList().isEmpty(); } // show perm prompt if new non-bundle channel added and the user has not // seen the prompt if (!hadNonBundleChannel && hasNonBundleChannel && !hasRequestedNotificationPermission && startingTaskId != ActivityTaskManager.INVALID_TASK_ID) { hasRequestedNotificationPermission = true; if (mPermissionPolicyInternal == null) { Loading Loading @@ -4651,7 +4657,7 @@ public class NotificationManagerService extends SystemService { public ParceledListSlice<NotificationChannel> getNotificationChannelsForPackage(String pkg, int uid, boolean includeDeleted) { enforceSystemOrSystemUI("getNotificationChannelsForPackage"); return mPreferencesHelper.getNotificationChannels(pkg, uid, includeDeleted); return mPreferencesHelper.getNotificationChannels(pkg, uid, includeDeleted, true); } @Override Loading Loading @@ -4783,7 +4789,7 @@ public class NotificationManagerService extends SystemService { /* ignore */ } return mPreferencesHelper.getNotificationChannels( targetPkg, targetUid, false /* includeDeleted */); targetPkg, targetUid, false /* includeDeleted */, true); } throw new SecurityException("Pkg " + callingPkg + " cannot read channels for " + targetPkg + " in " + userId); Loading Loading @@ -6652,7 +6658,7 @@ public class NotificationManagerService extends SystemService { verifyPrivilegedListener(token, user, true); return mPreferencesHelper.getNotificationChannels(pkg, getUidForPackageAndUser(pkg, user), false /* includeDeleted */); getUidForPackageAndUser(pkg, user), false /* includeDeleted */, true); } @Override Loading Loading @@ -7693,8 +7699,9 @@ public class NotificationManagerService extends SystemService { } int getNumNotificationChannelsForPackage(String pkg, int uid, boolean includeDeleted) { return mPreferencesHelper.getNotificationChannels(pkg, uid, includeDeleted).getList() .size(); // don't show perm prompt if the only channels are bundle channels return mPreferencesHelper.getNotificationChannels( pkg, uid, includeDeleted, false).getList().size(); } void cancelNotificationInternal(String pkg, String opPkg, int callingUid, int callingPid, Loading Loading @@ -8005,11 +8012,16 @@ public class NotificationManagerService extends SystemService { } /** * Returns a channel, if exists, and restores deleted conversation channels. * Returns a channel, if exists and is not a bundle channel, and restores deleted * conversation channels. */ @Nullable private NotificationChannel getNotificationChannelRestoreDeleted(String pkg, int callingUid, int notificationUid, String channelId, String conversationId) { if (SYSTEM_RESERVED_IDS.contains(channelId)) { // apps cannot post to these channels directly, in case they post incorrect content return null; } // Restore a deleted conversation channel, if exists. Otherwise use the parent channel. NotificationChannel channel = mPreferencesHelper.getConversationNotificationChannel( pkg, notificationUid, channelId, conversationId, Loading services/core/java/com/android/server/notification/PreferencesHelper.java +4 −2 Original line number Diff line number Diff line Loading @@ -1870,7 +1870,7 @@ public class PreferencesHelper implements RankingConfig { @Override public ParceledListSlice<NotificationChannel> getNotificationChannels(String pkg, int uid, boolean includeDeleted) { boolean includeDeleted, boolean includeBundles) { Objects.requireNonNull(pkg); List<NotificationChannel> channels = new ArrayList<>(); synchronized (mLock) { Loading @@ -1882,9 +1882,11 @@ public class PreferencesHelper implements RankingConfig { for (int i = 0; i < N; i++) { final NotificationChannel nc = r.channels.valueAt(i); if (includeDeleted || !nc.isDeleted()) { if (includeBundles || !SYSTEM_RESERVED_IDS.contains(nc.getId())) { channels.add(nc); } } } return new ParceledListSlice<>(channels); } } Loading services/core/java/com/android/server/notification/RankingConfig.java +1 −1 Original line number Diff line number Diff line Loading @@ -55,5 +55,5 @@ public interface RankingConfig { void permanentlyDeleteNotificationChannel(String pkg, int uid, String channelId); void permanentlyDeleteNotificationChannels(String pkg, int uid); ParceledListSlice<NotificationChannel> getNotificationChannels(String pkg, int uid, boolean includeDeleted); boolean includeDeleted, boolean includeBundles); } services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +21 −5 Original line number Diff line number Diff line Loading @@ -4838,7 +4838,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { null, mPkg, Process.myUserHandle()); verify(mPreferencesHelper, times(1)).getNotificationChannels( anyString(), anyInt(), anyBoolean()); anyString(), anyInt(), anyBoolean(), anyBoolean()); } @Test Loading @@ -4856,7 +4856,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } verify(mPreferencesHelper, never()).getNotificationChannels( anyString(), anyInt(), anyBoolean()); anyString(), anyInt(), anyBoolean(), anyBoolean()); } @Test Loading @@ -4871,7 +4871,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { null, mPkg, Process.myUserHandle()); verify(mPreferencesHelper, times(1)).getNotificationChannels( anyString(), anyInt(), anyBoolean()); anyString(), anyInt(), anyBoolean(), anyBoolean()); } @Test Loading @@ -4891,7 +4891,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } verify(mPreferencesHelper, never()).getNotificationChannels( anyString(), anyInt(), anyBoolean()); anyString(), anyInt(), anyBoolean(), anyBoolean()); } @Test Loading @@ -4913,7 +4913,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } verify(mPreferencesHelper, never()).getNotificationChannels( anyString(), anyInt(), anyBoolean()); anyString(), anyInt(), anyBoolean(), anyBoolean()); } @Test Loading Loading @@ -17062,4 +17062,20 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertThat(mService.hasFlag(captor.getValue().getNotification().flags, FLAG_PROMOTED_ONGOING)).isFalse(); } @Test @EnableFlags(FLAG_NOTIFICATION_CLASSIFICATION) public void testAppCannotUseReservedBundleChannels() throws Exception { mBinderService.getBubblePreferenceForPackage(mPkg, mUid); NotificationChannel news = mBinderService.getNotificationChannel( mPkg, mContext.getUserId(), mPkg, NEWS_ID); assertThat(news).isNotNull(); NotificationRecord nr = generateNotificationRecord(news); mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(), nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId()); waitForIdle(); assertThat(mService.mNotificationList).isEmpty(); } } Loading
services/core/java/com/android/server/notification/NotificationManagerInternal.java +1 −1 Original line number Diff line number Diff line Loading @@ -44,7 +44,7 @@ public interface NotificationManagerInternal { void onConversationRemoved(String pkg, int uid, Set<String> shortcuts); /** Get the number of notification channels for a given package */ /** Get the number of app created notification channels for a given package */ int getNumNotificationChannelsForPackage(String pkg, int uid, boolean includeDeleted); /** Does the specified package/uid have permission to post notifications? */ Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +26 −14 Original line number Diff line number Diff line Loading @@ -4392,8 +4392,9 @@ public class NotificationManagerService extends SystemService { List<NotificationChannel> channels = channelsList.getList(); final int channelsSize = channels.size(); ParceledListSlice<NotificationChannel> oldChannels = mPreferencesHelper.getNotificationChannels(pkg, uid, true); final boolean hadChannel = oldChannels != null && !oldChannels.getList().isEmpty(); mPreferencesHelper.getNotificationChannels(pkg, uid, true, false); final boolean hadNonBundleChannel = oldChannels != null && !oldChannels.getList().isEmpty(); boolean needsPolicyFileChange = false; boolean hasRequestedNotificationPermission = false; for (int i = 0; i < channelsSize; i++) { Loading @@ -4410,13 +4411,18 @@ public class NotificationManagerService extends SystemService { mPreferencesHelper.getNotificationChannel(pkg, uid, channel.getId(), false), NOTIFICATION_CHANNEL_OR_GROUP_ADDED); boolean hasChannel = hadChannel || hasRequestedNotificationPermission; if (!hasChannel) { boolean hasNonBundleChannel = hadNonBundleChannel || hasRequestedNotificationPermission; if (!hasNonBundleChannel) { ParceledListSlice<NotificationChannel> currChannels = mPreferencesHelper.getNotificationChannels(pkg, uid, true); hasChannel = currChannels != null && !currChannels.getList().isEmpty(); } if (!hadChannel && hasChannel && !hasRequestedNotificationPermission mPreferencesHelper.getNotificationChannels(pkg, uid, true, false); hasNonBundleChannel = currChannels != null && !currChannels.getList().isEmpty(); } // show perm prompt if new non-bundle channel added and the user has not // seen the prompt if (!hadNonBundleChannel && hasNonBundleChannel && !hasRequestedNotificationPermission && startingTaskId != ActivityTaskManager.INVALID_TASK_ID) { hasRequestedNotificationPermission = true; if (mPermissionPolicyInternal == null) { Loading Loading @@ -4651,7 +4657,7 @@ public class NotificationManagerService extends SystemService { public ParceledListSlice<NotificationChannel> getNotificationChannelsForPackage(String pkg, int uid, boolean includeDeleted) { enforceSystemOrSystemUI("getNotificationChannelsForPackage"); return mPreferencesHelper.getNotificationChannels(pkg, uid, includeDeleted); return mPreferencesHelper.getNotificationChannels(pkg, uid, includeDeleted, true); } @Override Loading Loading @@ -4783,7 +4789,7 @@ public class NotificationManagerService extends SystemService { /* ignore */ } return mPreferencesHelper.getNotificationChannels( targetPkg, targetUid, false /* includeDeleted */); targetPkg, targetUid, false /* includeDeleted */, true); } throw new SecurityException("Pkg " + callingPkg + " cannot read channels for " + targetPkg + " in " + userId); Loading Loading @@ -6652,7 +6658,7 @@ public class NotificationManagerService extends SystemService { verifyPrivilegedListener(token, user, true); return mPreferencesHelper.getNotificationChannels(pkg, getUidForPackageAndUser(pkg, user), false /* includeDeleted */); getUidForPackageAndUser(pkg, user), false /* includeDeleted */, true); } @Override Loading Loading @@ -7693,8 +7699,9 @@ public class NotificationManagerService extends SystemService { } int getNumNotificationChannelsForPackage(String pkg, int uid, boolean includeDeleted) { return mPreferencesHelper.getNotificationChannels(pkg, uid, includeDeleted).getList() .size(); // don't show perm prompt if the only channels are bundle channels return mPreferencesHelper.getNotificationChannels( pkg, uid, includeDeleted, false).getList().size(); } void cancelNotificationInternal(String pkg, String opPkg, int callingUid, int callingPid, Loading Loading @@ -8005,11 +8012,16 @@ public class NotificationManagerService extends SystemService { } /** * Returns a channel, if exists, and restores deleted conversation channels. * Returns a channel, if exists and is not a bundle channel, and restores deleted * conversation channels. */ @Nullable private NotificationChannel getNotificationChannelRestoreDeleted(String pkg, int callingUid, int notificationUid, String channelId, String conversationId) { if (SYSTEM_RESERVED_IDS.contains(channelId)) { // apps cannot post to these channels directly, in case they post incorrect content return null; } // Restore a deleted conversation channel, if exists. Otherwise use the parent channel. NotificationChannel channel = mPreferencesHelper.getConversationNotificationChannel( pkg, notificationUid, channelId, conversationId, Loading
services/core/java/com/android/server/notification/PreferencesHelper.java +4 −2 Original line number Diff line number Diff line Loading @@ -1870,7 +1870,7 @@ public class PreferencesHelper implements RankingConfig { @Override public ParceledListSlice<NotificationChannel> getNotificationChannels(String pkg, int uid, boolean includeDeleted) { boolean includeDeleted, boolean includeBundles) { Objects.requireNonNull(pkg); List<NotificationChannel> channels = new ArrayList<>(); synchronized (mLock) { Loading @@ -1882,9 +1882,11 @@ public class PreferencesHelper implements RankingConfig { for (int i = 0; i < N; i++) { final NotificationChannel nc = r.channels.valueAt(i); if (includeDeleted || !nc.isDeleted()) { if (includeBundles || !SYSTEM_RESERVED_IDS.contains(nc.getId())) { channels.add(nc); } } } return new ParceledListSlice<>(channels); } } Loading
services/core/java/com/android/server/notification/RankingConfig.java +1 −1 Original line number Diff line number Diff line Loading @@ -55,5 +55,5 @@ public interface RankingConfig { void permanentlyDeleteNotificationChannel(String pkg, int uid, String channelId); void permanentlyDeleteNotificationChannels(String pkg, int uid); ParceledListSlice<NotificationChannel> getNotificationChannels(String pkg, int uid, boolean includeDeleted); boolean includeDeleted, boolean includeBundles); }
services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +21 −5 Original line number Diff line number Diff line Loading @@ -4838,7 +4838,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { null, mPkg, Process.myUserHandle()); verify(mPreferencesHelper, times(1)).getNotificationChannels( anyString(), anyInt(), anyBoolean()); anyString(), anyInt(), anyBoolean(), anyBoolean()); } @Test Loading @@ -4856,7 +4856,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } verify(mPreferencesHelper, never()).getNotificationChannels( anyString(), anyInt(), anyBoolean()); anyString(), anyInt(), anyBoolean(), anyBoolean()); } @Test Loading @@ -4871,7 +4871,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { null, mPkg, Process.myUserHandle()); verify(mPreferencesHelper, times(1)).getNotificationChannels( anyString(), anyInt(), anyBoolean()); anyString(), anyInt(), anyBoolean(), anyBoolean()); } @Test Loading @@ -4891,7 +4891,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } verify(mPreferencesHelper, never()).getNotificationChannels( anyString(), anyInt(), anyBoolean()); anyString(), anyInt(), anyBoolean(), anyBoolean()); } @Test Loading @@ -4913,7 +4913,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } verify(mPreferencesHelper, never()).getNotificationChannels( anyString(), anyInt(), anyBoolean()); anyString(), anyInt(), anyBoolean(), anyBoolean()); } @Test Loading Loading @@ -17062,4 +17062,20 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertThat(mService.hasFlag(captor.getValue().getNotification().flags, FLAG_PROMOTED_ONGOING)).isFalse(); } @Test @EnableFlags(FLAG_NOTIFICATION_CLASSIFICATION) public void testAppCannotUseReservedBundleChannels() throws Exception { mBinderService.getBubblePreferenceForPackage(mPkg, mUid); NotificationChannel news = mBinderService.getNotificationChannel( mPkg, mContext.getUserId(), mPkg, NEWS_ID); assertThat(news).isNotNull(); NotificationRecord nr = generateNotificationRecord(news); mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(), nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId()); waitForIdle(); assertThat(mService.mNotificationList).isEmpty(); } }