Loading services/core/java/com/android/server/notification/NotificationManagerService.java +31 −10 Original line number Diff line number Diff line Loading @@ -4450,10 +4450,14 @@ public class NotificationManagerService extends SystemService { public void allowAssistantAdjustment(String adjustmentType) { checkCallerIsSystemOrSystemUiOrShell(); mAssistants.allowAdjustmentType(adjustmentType); int userId = UserHandle.getUserId(Binder.getCallingUid()); if ((notificationClassificationUi() && notificationRegroupOnClassification())) { if (KEY_TYPE.equals(adjustmentType)) { applyNotificationUpdateForUser(userId, if (notificationClassification()) { // restore any existing channels if they previously existed mPreferencesHelper.updateReservedChannels( mAssistants.getAllowedClassificationTypeList(), true); } if ((notificationClassificationUi() && notificationRegroupOnClassification())) { applyNotificationUpdateForUser(UserHandle.getUserId(Binder.getCallingUid()), NotificationManagerService.this::reclassifyNotificationLocked); } } Loading @@ -4466,8 +4470,13 @@ public class NotificationManagerService extends SystemService { checkCallerIsSystemOrSystemUiOrShell(); mAssistants.disallowAdjustmentType(adjustmentType); int userId = UserHandle.getUserId(Binder.getCallingUid()); if ((notificationClassificationUi() && notificationRegroupOnClassification())) { if (KEY_TYPE.equals(adjustmentType)) { if (notificationClassification()) { // mark any existing channels for all currently allowed types as deleted mPreferencesHelper.updateReservedChannels( mAssistants.getAllowedClassificationTypeList(), false); } if ((notificationClassificationUi() && notificationRegroupOnClassification())) { applyNotificationUpdateForUser(userId, NotificationManagerService.this::unclassifyNotificationLocked); } Loading Loading @@ -4522,14 +4531,16 @@ public class NotificationManagerService extends SystemService { public void setAssistantAdjustmentKeyTypeState(int type, boolean enabled) { checkCallerIsSystemOrSystemUiOrShell(); mAssistants.setAssistantAdjustmentKeyTypeState(type, enabled); int userId = UserHandle.getUserId(Binder.getCallingUid()); if (notificationClassification()) { mPreferencesHelper.updateReservedChannels(List.of(type), enabled); } if ((notificationClassificationUi() && notificationRegroupOnClassification())) { if (enabled) { applyNotificationUpdateForUserAndType( UserHandle.getUserId(Binder.getCallingUid()), type, applyNotificationUpdateForUserAndType(userId, type, NotificationManagerService.this::reclassifyNotificationLocked); } else { applyNotificationUpdateForUserAndChannelType( UserHandle.getUserId(Binder.getCallingUid()), type, applyNotificationUpdateForUserAndChannelType(userId, type, NotificationManagerService.this::unclassifyNotificationLocked); } } Loading Loading @@ -12270,6 +12281,16 @@ public class NotificationManagerService extends SystemService { return new int[]{}; } @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION) protected @NonNull List<Integer> getAllowedClassificationTypeList() { synchronized (mLock) { if (notificationClassification()) { return mAllowedClassificationTypes.stream().toList(); } } return new ArrayList<>(); } @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION) public void setAssistantAdjustmentKeyTypeState(@Adjustment.Types int type, boolean enabled) { services/core/java/com/android/server/notification/PreferencesHelper.java +31 −6 Original line number Diff line number Diff line Loading @@ -476,12 +476,6 @@ public class PreferencesHelper implements RankingConfig { channel.setImportanceLockedByCriticalDeviceFunction( r.defaultAppLockedImportance || r.fixedImportance); if (notificationClassification()) { if (SYSTEM_RESERVED_IDS.contains(id) && channel.isDeleted() ) { channel.setDeleted(false); } } if (isShortcutOk(channel) && isDeletionOk(channel)) { r.channels.put(id, channel); } Loading Loading @@ -1610,6 +1604,37 @@ public class PreferencesHelper implements RankingConfig { } } // Update all reserved channels for the given adjustment type(s) when enabled or disabled. // If disabled, all relevant channels are marked as deleted until the type is re-enabled. @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION) void updateReservedChannels(List<Integer> changedTypes, boolean enabled) { if (!notificationClassification()) { return; } boolean shouldBeDeleted = !enabled; // just for ease of reading boolean logic boolean updated = false; synchronized (mLock) { for (PackagePreferences p : mPackagePreferences.values()) { for (int type : changedTypes) { String channelId = NotificationChannel.getChannelIdForBundleType(type); NotificationChannel c = p.channels.get(channelId); if (c != null && c.isDeleted() != shouldBeDeleted) { c.setDeleted(shouldBeDeleted); c.setDeletedTimeMs(shouldBeDeleted ? System.currentTimeMillis() : -1); updated = true; } } } } if (updated) { // We shouldn't need to sort upon update: if any current notifications are affected // they should be reclassified as part of the enable/disable operation. if (android.app.Flags.nmBinderPerfCacheChannels()) { invalidateNotificationChannelCache(); } } } public boolean shouldHideSilentStatusIcons() { return mHideSilentStatusBarIcons; } Loading services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +51 −0 Original line number Diff line number Diff line Loading @@ -18712,6 +18712,57 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } } @Test @EnableFlags(FLAG_NOTIFICATION_CLASSIFICATION) public void testAllowAndDisallowBundling_updatesChannels() throws Exception { NotificationManagerService.WorkerHandler handler = mock( NotificationManagerService.WorkerHandler.class); mService.setHandler(handler); when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true); when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true); when(mAssistants.isAdjustmentAllowedForPackage(anyString(), anyString())).thenReturn(true); List<Integer> allowedTypes = List.of(Adjustment.TYPE_NEWS, Adjustment.TYPE_SOCIAL_MEDIA); when(mAssistants.getAllowedClassificationTypeList()).thenReturn(allowedTypes); // set mock preferences helper mService.setPreferencesHelper(mPreferencesHelper); // Disable KEY_TYPE adjustment mBinderService.disallowAssistantAdjustment(Adjustment.KEY_TYPE); waitForIdle(); verify(mPreferencesHelper).updateReservedChannels(allowedTypes, false); mBinderService.allowAssistantAdjustment(Adjustment.KEY_TYPE); waitForIdle(); verify(mPreferencesHelper).updateReservedChannels(allowedTypes, true); } @Test @EnableFlags(FLAG_NOTIFICATION_CLASSIFICATION) public void testAllowBundleTypes_updatesChannels() throws Exception { NotificationManagerService.WorkerHandler handler = mock( NotificationManagerService.WorkerHandler.class); mService.setHandler(handler); when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true); when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true); when(mAssistants.isAdjustmentAllowedForPackage(anyString(), anyString())).thenReturn(true); // set mock preferences helper mService.setPreferencesHelper(mPreferencesHelper); mBinderService.setAssistantAdjustmentKeyTypeState(Adjustment.TYPE_NEWS, true); waitForIdle(); verify(mPreferencesHelper).updateReservedChannels(List.of(Adjustment.TYPE_NEWS), true); mBinderService.setAssistantAdjustmentKeyTypeState(Adjustment.TYPE_SOCIAL_MEDIA, false); waitForIdle(); verify(mPreferencesHelper).updateReservedChannels(List.of(Adjustment.TYPE_SOCIAL_MEDIA), false); } @Test @EnableFlags({FLAG_NM_SUMMARIZATION}) public void testDisableBundleAdjustment_unsummarizesNotifications() throws Exception { services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java +25 −14 Original line number Diff line number Diff line Loading @@ -50,7 +50,6 @@ import static android.media.AudioAttributes.CONTENT_TYPE_SONIFICATION; import static android.media.AudioAttributes.USAGE_NOTIFICATION; import static android.os.UserHandle.USER_ALL; import static android.os.UserHandle.USER_SYSTEM; import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT; import static android.service.notification.Adjustment.TYPE_CONTENT_RECOMMENDATION; import static android.service.notification.Adjustment.TYPE_NEWS; Loading @@ -64,7 +63,6 @@ import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.No import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES__FSI_STATE__DENIED; import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES__FSI_STATE__GRANTED; import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES__FSI_STATE__NOT_REQUESTED; import static com.android.server.notification.Flags.FLAG_ALL_NOTIFS_NEED_TTL; import static com.android.server.notification.Flags.FLAG_PERSIST_INCOMPLETE_RESTORE_DATA; import static com.android.server.notification.NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_UPDATED_BY_USER; import static com.android.server.notification.PreferencesHelper.DEFAULT_BUBBLE_PREFERENCE; Loading Loading @@ -164,7 +162,6 @@ import com.android.os.AtomsProto.PackageNotificationPreferences; import com.android.os.notification.NotificationProtoEnums; import com.android.server.UiServiceTestCase; import com.android.server.notification.PermissionHelper.PackagePermission; import com.android.server.uri.UriGrantsManagerInternal; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; Loading Loading @@ -6631,18 +6628,32 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test @EnableFlags(FLAG_NOTIFICATION_CLASSIFICATION) public void testUnDeleteBundleChannelsOnLoadIfNotUserChange() throws Exception { // the public create/update methods should prevent this, so take advantage of the fact that // the object is in the same process mHelper.createReservedChannel(PKG_N_MR1, UID_N_MR1, TYPE_SOCIAL_MEDIA).setDeleted(true); ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false, UserHandle.USER_ALL, SOCIAL_MEDIA_ID); loadStreamXml(baos, false, UserHandle.USER_ALL); public void testUpdateReservedChannels_disableAndEnable() { mHelper.createReservedChannel(PKG_O, UID_O, TYPE_NEWS); mHelper.createReservedChannel(PKG_O, UID_O, TYPE_SOCIAL_MEDIA); mHelper.createReservedChannel(PKG_O, UID_O, TYPE_CONTENT_RECOMMENDATION); assertThat(mXmlHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, SOCIAL_MEDIA_ID, true) .isDeleted()).isFalse(); // Ban news & social media types, leave recs as-is mHelper.updateReservedChannels(List.of(TYPE_NEWS, TYPE_SOCIAL_MEDIA), false); assertThat( mHelper.getNotificationChannel(PKG_O, UID_O, NEWS_ID, true).isDeleted()).isTrue(); assertThat(mHelper.getNotificationChannel(PKG_O, UID_O, SOCIAL_MEDIA_ID, true).isDeleted()).isTrue(); assertThat( mHelper.getNotificationChannel(PKG_O, UID_O, RECS_ID, true).isDeleted()).isFalse(); // Enable news (re-enable) and promos (no existing channel; should do nothing) mHelper.updateReservedChannels(List.of(TYPE_NEWS, TYPE_PROMOTION), true); assertThat( mHelper.getNotificationChannel(PKG_O, UID_O, NEWS_ID, true).isDeleted()).isFalse(); assertThat(mHelper.getNotificationChannel(PKG_O, UID_O, PROMOTIONS_ID, true)).isNull(); // Other channels unaffected assertThat(mHelper.getNotificationChannel(PKG_O, UID_O, SOCIAL_MEDIA_ID, true).isDeleted()).isTrue(); assertThat( mHelper.getNotificationChannel(PKG_O, UID_O, RECS_ID, true).isDeleted()).isFalse(); } @Test Loading Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +31 −10 Original line number Diff line number Diff line Loading @@ -4450,10 +4450,14 @@ public class NotificationManagerService extends SystemService { public void allowAssistantAdjustment(String adjustmentType) { checkCallerIsSystemOrSystemUiOrShell(); mAssistants.allowAdjustmentType(adjustmentType); int userId = UserHandle.getUserId(Binder.getCallingUid()); if ((notificationClassificationUi() && notificationRegroupOnClassification())) { if (KEY_TYPE.equals(adjustmentType)) { applyNotificationUpdateForUser(userId, if (notificationClassification()) { // restore any existing channels if they previously existed mPreferencesHelper.updateReservedChannels( mAssistants.getAllowedClassificationTypeList(), true); } if ((notificationClassificationUi() && notificationRegroupOnClassification())) { applyNotificationUpdateForUser(UserHandle.getUserId(Binder.getCallingUid()), NotificationManagerService.this::reclassifyNotificationLocked); } } Loading @@ -4466,8 +4470,13 @@ public class NotificationManagerService extends SystemService { checkCallerIsSystemOrSystemUiOrShell(); mAssistants.disallowAdjustmentType(adjustmentType); int userId = UserHandle.getUserId(Binder.getCallingUid()); if ((notificationClassificationUi() && notificationRegroupOnClassification())) { if (KEY_TYPE.equals(adjustmentType)) { if (notificationClassification()) { // mark any existing channels for all currently allowed types as deleted mPreferencesHelper.updateReservedChannels( mAssistants.getAllowedClassificationTypeList(), false); } if ((notificationClassificationUi() && notificationRegroupOnClassification())) { applyNotificationUpdateForUser(userId, NotificationManagerService.this::unclassifyNotificationLocked); } Loading Loading @@ -4522,14 +4531,16 @@ public class NotificationManagerService extends SystemService { public void setAssistantAdjustmentKeyTypeState(int type, boolean enabled) { checkCallerIsSystemOrSystemUiOrShell(); mAssistants.setAssistantAdjustmentKeyTypeState(type, enabled); int userId = UserHandle.getUserId(Binder.getCallingUid()); if (notificationClassification()) { mPreferencesHelper.updateReservedChannels(List.of(type), enabled); } if ((notificationClassificationUi() && notificationRegroupOnClassification())) { if (enabled) { applyNotificationUpdateForUserAndType( UserHandle.getUserId(Binder.getCallingUid()), type, applyNotificationUpdateForUserAndType(userId, type, NotificationManagerService.this::reclassifyNotificationLocked); } else { applyNotificationUpdateForUserAndChannelType( UserHandle.getUserId(Binder.getCallingUid()), type, applyNotificationUpdateForUserAndChannelType(userId, type, NotificationManagerService.this::unclassifyNotificationLocked); } } Loading Loading @@ -12270,6 +12281,16 @@ public class NotificationManagerService extends SystemService { return new int[]{}; } @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION) protected @NonNull List<Integer> getAllowedClassificationTypeList() { synchronized (mLock) { if (notificationClassification()) { return mAllowedClassificationTypes.stream().toList(); } } return new ArrayList<>(); } @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION) public void setAssistantAdjustmentKeyTypeState(@Adjustment.Types int type, boolean enabled) {
services/core/java/com/android/server/notification/PreferencesHelper.java +31 −6 Original line number Diff line number Diff line Loading @@ -476,12 +476,6 @@ public class PreferencesHelper implements RankingConfig { channel.setImportanceLockedByCriticalDeviceFunction( r.defaultAppLockedImportance || r.fixedImportance); if (notificationClassification()) { if (SYSTEM_RESERVED_IDS.contains(id) && channel.isDeleted() ) { channel.setDeleted(false); } } if (isShortcutOk(channel) && isDeletionOk(channel)) { r.channels.put(id, channel); } Loading Loading @@ -1610,6 +1604,37 @@ public class PreferencesHelper implements RankingConfig { } } // Update all reserved channels for the given adjustment type(s) when enabled or disabled. // If disabled, all relevant channels are marked as deleted until the type is re-enabled. @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION) void updateReservedChannels(List<Integer> changedTypes, boolean enabled) { if (!notificationClassification()) { return; } boolean shouldBeDeleted = !enabled; // just for ease of reading boolean logic boolean updated = false; synchronized (mLock) { for (PackagePreferences p : mPackagePreferences.values()) { for (int type : changedTypes) { String channelId = NotificationChannel.getChannelIdForBundleType(type); NotificationChannel c = p.channels.get(channelId); if (c != null && c.isDeleted() != shouldBeDeleted) { c.setDeleted(shouldBeDeleted); c.setDeletedTimeMs(shouldBeDeleted ? System.currentTimeMillis() : -1); updated = true; } } } } if (updated) { // We shouldn't need to sort upon update: if any current notifications are affected // they should be reclassified as part of the enable/disable operation. if (android.app.Flags.nmBinderPerfCacheChannels()) { invalidateNotificationChannelCache(); } } } public boolean shouldHideSilentStatusIcons() { return mHideSilentStatusBarIcons; } Loading
services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +51 −0 Original line number Diff line number Diff line Loading @@ -18712,6 +18712,57 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } } @Test @EnableFlags(FLAG_NOTIFICATION_CLASSIFICATION) public void testAllowAndDisallowBundling_updatesChannels() throws Exception { NotificationManagerService.WorkerHandler handler = mock( NotificationManagerService.WorkerHandler.class); mService.setHandler(handler); when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true); when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true); when(mAssistants.isAdjustmentAllowedForPackage(anyString(), anyString())).thenReturn(true); List<Integer> allowedTypes = List.of(Adjustment.TYPE_NEWS, Adjustment.TYPE_SOCIAL_MEDIA); when(mAssistants.getAllowedClassificationTypeList()).thenReturn(allowedTypes); // set mock preferences helper mService.setPreferencesHelper(mPreferencesHelper); // Disable KEY_TYPE adjustment mBinderService.disallowAssistantAdjustment(Adjustment.KEY_TYPE); waitForIdle(); verify(mPreferencesHelper).updateReservedChannels(allowedTypes, false); mBinderService.allowAssistantAdjustment(Adjustment.KEY_TYPE); waitForIdle(); verify(mPreferencesHelper).updateReservedChannels(allowedTypes, true); } @Test @EnableFlags(FLAG_NOTIFICATION_CLASSIFICATION) public void testAllowBundleTypes_updatesChannels() throws Exception { NotificationManagerService.WorkerHandler handler = mock( NotificationManagerService.WorkerHandler.class); mService.setHandler(handler); when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true); when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true); when(mAssistants.isAdjustmentAllowedForPackage(anyString(), anyString())).thenReturn(true); // set mock preferences helper mService.setPreferencesHelper(mPreferencesHelper); mBinderService.setAssistantAdjustmentKeyTypeState(Adjustment.TYPE_NEWS, true); waitForIdle(); verify(mPreferencesHelper).updateReservedChannels(List.of(Adjustment.TYPE_NEWS), true); mBinderService.setAssistantAdjustmentKeyTypeState(Adjustment.TYPE_SOCIAL_MEDIA, false); waitForIdle(); verify(mPreferencesHelper).updateReservedChannels(List.of(Adjustment.TYPE_SOCIAL_MEDIA), false); } @Test @EnableFlags({FLAG_NM_SUMMARIZATION}) public void testDisableBundleAdjustment_unsummarizesNotifications() throws Exception {
services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java +25 −14 Original line number Diff line number Diff line Loading @@ -50,7 +50,6 @@ import static android.media.AudioAttributes.CONTENT_TYPE_SONIFICATION; import static android.media.AudioAttributes.USAGE_NOTIFICATION; import static android.os.UserHandle.USER_ALL; import static android.os.UserHandle.USER_SYSTEM; import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT; import static android.service.notification.Adjustment.TYPE_CONTENT_RECOMMENDATION; import static android.service.notification.Adjustment.TYPE_NEWS; Loading @@ -64,7 +63,6 @@ import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.No import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES__FSI_STATE__DENIED; import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES__FSI_STATE__GRANTED; import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES__FSI_STATE__NOT_REQUESTED; import static com.android.server.notification.Flags.FLAG_ALL_NOTIFS_NEED_TTL; import static com.android.server.notification.Flags.FLAG_PERSIST_INCOMPLETE_RESTORE_DATA; import static com.android.server.notification.NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_UPDATED_BY_USER; import static com.android.server.notification.PreferencesHelper.DEFAULT_BUBBLE_PREFERENCE; Loading Loading @@ -164,7 +162,6 @@ import com.android.os.AtomsProto.PackageNotificationPreferences; import com.android.os.notification.NotificationProtoEnums; import com.android.server.UiServiceTestCase; import com.android.server.notification.PermissionHelper.PackagePermission; import com.android.server.uri.UriGrantsManagerInternal; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; Loading Loading @@ -6631,18 +6628,32 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test @EnableFlags(FLAG_NOTIFICATION_CLASSIFICATION) public void testUnDeleteBundleChannelsOnLoadIfNotUserChange() throws Exception { // the public create/update methods should prevent this, so take advantage of the fact that // the object is in the same process mHelper.createReservedChannel(PKG_N_MR1, UID_N_MR1, TYPE_SOCIAL_MEDIA).setDeleted(true); ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false, UserHandle.USER_ALL, SOCIAL_MEDIA_ID); loadStreamXml(baos, false, UserHandle.USER_ALL); public void testUpdateReservedChannels_disableAndEnable() { mHelper.createReservedChannel(PKG_O, UID_O, TYPE_NEWS); mHelper.createReservedChannel(PKG_O, UID_O, TYPE_SOCIAL_MEDIA); mHelper.createReservedChannel(PKG_O, UID_O, TYPE_CONTENT_RECOMMENDATION); assertThat(mXmlHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, SOCIAL_MEDIA_ID, true) .isDeleted()).isFalse(); // Ban news & social media types, leave recs as-is mHelper.updateReservedChannels(List.of(TYPE_NEWS, TYPE_SOCIAL_MEDIA), false); assertThat( mHelper.getNotificationChannel(PKG_O, UID_O, NEWS_ID, true).isDeleted()).isTrue(); assertThat(mHelper.getNotificationChannel(PKG_O, UID_O, SOCIAL_MEDIA_ID, true).isDeleted()).isTrue(); assertThat( mHelper.getNotificationChannel(PKG_O, UID_O, RECS_ID, true).isDeleted()).isFalse(); // Enable news (re-enable) and promos (no existing channel; should do nothing) mHelper.updateReservedChannels(List.of(TYPE_NEWS, TYPE_PROMOTION), true); assertThat( mHelper.getNotificationChannel(PKG_O, UID_O, NEWS_ID, true).isDeleted()).isFalse(); assertThat(mHelper.getNotificationChannel(PKG_O, UID_O, PROMOTIONS_ID, true)).isNull(); // Other channels unaffected assertThat(mHelper.getNotificationChannel(PKG_O, UID_O, SOCIAL_MEDIA_ID, true).isDeleted()).isTrue(); assertThat( mHelper.getNotificationChannel(PKG_O, UID_O, RECS_ID, true).isDeleted()).isFalse(); } @Test Loading