Loading services/core/java/com/android/server/notification/NotificationManagerService.java +20 −7 Original line number Diff line number Diff line Loading @@ -4892,9 +4892,7 @@ public class NotificationManagerService extends SystemService { List<NotificationRecord> enqueued = findAppNotificationByListLocked( mEnqueuedNotifications, pkg, UserHandle.getUserId(uid)); for (NotificationRecord r : enqueued) { if (promote && r.getNotification().hasPromotableCharacteristics() && r.getImportance() > IMPORTANCE_MIN) { if (promote && isPromotable(r)) { r.getNotification().flags |= FLAG_PROMOTED_ONGOING; } else if (!promote) { r.getNotification().flags &= ~FLAG_PROMOTED_ONGOING; Loading @@ -4906,8 +4904,7 @@ public class NotificationManagerService extends SystemService { for (NotificationRecord r : posted) { if (promote && !hasFlag(r.getNotification().flags, FLAG_PROMOTED_ONGOING) && r.getNotification().hasPromotableCharacteristics() && r.getImportance() > IMPORTANCE_MIN) { && isPromotable(r)) { r.getNotification().flags |= FLAG_PROMOTED_ONGOING; // we could set a wake lock here but this value should only change // in response to user action, so the device should be awake long enough Loading Loading @@ -9216,6 +9213,23 @@ public class NotificationManagerService extends SystemService { } } private boolean isPromotable(NotificationRecord record) { return isPromotable(record.getNotification(), record.getChannel()); } private static boolean isPromotable(Notification notification, NotificationChannel channel) { if (!notification.hasPromotableCharacteristics()) { return false; } if (channel.getImportance() <= IMPORTANCE_MIN) { return false; } if (android.service.notification.Flags.notificationClassification() && NotificationChannel.SYSTEM_RESERVED_IDS.contains(channel.getId())) { return false; } return true; } /** * Final notification fixup that can only be performed once channel info is available. Loading @@ -9229,8 +9243,7 @@ public class NotificationManagerService extends SystemService { protected void fixNotificationWithChannel(Notification notification, NotificationChannel channel, int notificationUid, String pkg) { if (android.app.Flags.apiRichOngoing()) { if (notification.hasPromotableCharacteristics() && channel.getImportance() > IMPORTANCE_MIN) { if (isPromotable(notification, channel)) { // Check permission last - after we make sure this is actually an attempted usage // of promotion - since AppOps tracks usage attempts. boolean canPostPromoted; Loading services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +38 −22 Original line number Diff line number Diff line Loading @@ -522,6 +522,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { NotificationChannel mMinChannel = new NotificationChannel("min", "min", IMPORTANCE_MIN); NotificationChannel mNewsChannel = new NotificationChannel(NEWS_ID, "News", IMPORTANCE_LOW); private static final int NOTIFICATION_LOCATION_UNKNOWN = 0; private static final String VALID_CONVO_SHORTCUT_ID = "shortcut"; Loading Loading @@ -15553,38 +15555,48 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertFalse(n.hasColorizedPermission()); } @Test @EnableFlags({FLAG_API_RICH_ONGOING, FLAG_API_RICH_ONGOING_PERMISSION}) public void testPromotion_permissionDenied() throws Exception { private void testPromotion(int postPromotedNotificationsPermissionState, NotificationChannel channel, boolean expectPromoted) { when(mPermissionManager.checkPermissionForDataDelivery( eq(Manifest.permission.POST_PROMOTED_NOTIFICATIONS), any(), any())) .thenReturn(PermissionManager.PERMISSION_SOFT_DENIED); .thenReturn(postPromotedNotificationsPermissionState); Notification n = createPromotableNotification(); NotificationChannel channel = new NotificationChannel( "ChannelId", "TestChannel", NotificationManager.IMPORTANCE_HIGH); Notification n = createPromotableNotification(channel); mService.fixNotificationWithChannel(n, channel, mUid, mPkg); final int promotedOngoing = n.flags & FLAG_PROMOTED_ONGOING; assertEquals(0, promotedOngoing); final boolean isPromoted = (n.flags & FLAG_PROMOTED_ONGOING) != 0; assertEquals(expectPromoted, isPromoted); } @Test @EnableFlags({FLAG_API_RICH_ONGOING, FLAG_API_RICH_ONGOING_PERMISSION}) @EnableFlags({FLAG_API_RICH_ONGOING, FLAG_UI_RICH_ONGOING}) public void testPromotion_permissionAllowed() throws Exception { when(mPermissionManager.checkPermissionForDataDelivery( eq(Manifest.permission.POST_PROMOTED_NOTIFICATIONS), any(), any())) .thenReturn(PermissionManager.PERMISSION_GRANTED); testPromotion(PermissionManager.PERMISSION_GRANTED, mTestNotificationChannel, true); } Notification n = createPromotableNotification(); NotificationChannel channel = new NotificationChannel( "ChannelId", "TestChannel", NotificationManager.IMPORTANCE_HIGH); @Test @EnableFlags({FLAG_API_RICH_ONGOING, FLAG_UI_RICH_ONGOING}) public void testPromotion_permissionDenied() throws Exception { testPromotion(PermissionManager.PERMISSION_SOFT_DENIED, mTestNotificationChannel, false); } mService.fixNotificationWithChannel(n, channel, mUid, mPkg); @Test @EnableFlags({FLAG_API_RICH_ONGOING, FLAG_UI_RICH_ONGOING}) public void testPromotion_bundledNotification() throws Exception { testPromotion(PermissionManager.PERMISSION_GRANTED, mNewsChannel, false); } @Test @EnableFlags({FLAG_API_RICH_ONGOING, FLAG_UI_RICH_ONGOING}) public void testPromotion_silentChannel() throws Exception { testPromotion(PermissionManager.PERMISSION_GRANTED, mSilentChannel, true); } final int promotedOngoing = n.flags & FLAG_PROMOTED_ONGOING; assertNotEquals(0, promotedOngoing); @Test @EnableFlags({FLAG_API_RICH_ONGOING, FLAG_UI_RICH_ONGOING}) public void testPromotion_minimizedChannel() throws Exception { testPromotion(PermissionManager.PERMISSION_GRANTED, mMinChannel, false); } @Test Loading Loading @@ -19080,7 +19092,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @EnableFlags({FLAG_API_RICH_ONGOING}) public void testPostPromotableNotification_unimportantNotification() throws Exception { mBinderService.setCanBePromoted(mPkg, mUid, true, true); Notification n = createPromotableNotification(/* addFlagManually= */ false, mMinChannel); Notification n = createPromotableNotification(mMinChannel); StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 9, null, mUid, 0, n, UserHandle.getUserHandleForUid(mUid), null, 0); Loading @@ -19106,6 +19118,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { return createPromotableNotification(addFlagManually, mTestNotificationChannel); } private Notification createPromotableNotification(NotificationChannel channel) { return createPromotableNotification(/* addFlagManually= */ false, channel); } private Notification createPromotableNotification( boolean addFlagManually, NotificationChannel channel) { boolean newEligibilityCriteria = android.app.Flags.uiRichOngoing(); Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +20 −7 Original line number Diff line number Diff line Loading @@ -4892,9 +4892,7 @@ public class NotificationManagerService extends SystemService { List<NotificationRecord> enqueued = findAppNotificationByListLocked( mEnqueuedNotifications, pkg, UserHandle.getUserId(uid)); for (NotificationRecord r : enqueued) { if (promote && r.getNotification().hasPromotableCharacteristics() && r.getImportance() > IMPORTANCE_MIN) { if (promote && isPromotable(r)) { r.getNotification().flags |= FLAG_PROMOTED_ONGOING; } else if (!promote) { r.getNotification().flags &= ~FLAG_PROMOTED_ONGOING; Loading @@ -4906,8 +4904,7 @@ public class NotificationManagerService extends SystemService { for (NotificationRecord r : posted) { if (promote && !hasFlag(r.getNotification().flags, FLAG_PROMOTED_ONGOING) && r.getNotification().hasPromotableCharacteristics() && r.getImportance() > IMPORTANCE_MIN) { && isPromotable(r)) { r.getNotification().flags |= FLAG_PROMOTED_ONGOING; // we could set a wake lock here but this value should only change // in response to user action, so the device should be awake long enough Loading Loading @@ -9216,6 +9213,23 @@ public class NotificationManagerService extends SystemService { } } private boolean isPromotable(NotificationRecord record) { return isPromotable(record.getNotification(), record.getChannel()); } private static boolean isPromotable(Notification notification, NotificationChannel channel) { if (!notification.hasPromotableCharacteristics()) { return false; } if (channel.getImportance() <= IMPORTANCE_MIN) { return false; } if (android.service.notification.Flags.notificationClassification() && NotificationChannel.SYSTEM_RESERVED_IDS.contains(channel.getId())) { return false; } return true; } /** * Final notification fixup that can only be performed once channel info is available. Loading @@ -9229,8 +9243,7 @@ public class NotificationManagerService extends SystemService { protected void fixNotificationWithChannel(Notification notification, NotificationChannel channel, int notificationUid, String pkg) { if (android.app.Flags.apiRichOngoing()) { if (notification.hasPromotableCharacteristics() && channel.getImportance() > IMPORTANCE_MIN) { if (isPromotable(notification, channel)) { // Check permission last - after we make sure this is actually an attempted usage // of promotion - since AppOps tracks usage attempts. boolean canPostPromoted; Loading
services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +38 −22 Original line number Diff line number Diff line Loading @@ -522,6 +522,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { NotificationChannel mMinChannel = new NotificationChannel("min", "min", IMPORTANCE_MIN); NotificationChannel mNewsChannel = new NotificationChannel(NEWS_ID, "News", IMPORTANCE_LOW); private static final int NOTIFICATION_LOCATION_UNKNOWN = 0; private static final String VALID_CONVO_SHORTCUT_ID = "shortcut"; Loading Loading @@ -15553,38 +15555,48 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertFalse(n.hasColorizedPermission()); } @Test @EnableFlags({FLAG_API_RICH_ONGOING, FLAG_API_RICH_ONGOING_PERMISSION}) public void testPromotion_permissionDenied() throws Exception { private void testPromotion(int postPromotedNotificationsPermissionState, NotificationChannel channel, boolean expectPromoted) { when(mPermissionManager.checkPermissionForDataDelivery( eq(Manifest.permission.POST_PROMOTED_NOTIFICATIONS), any(), any())) .thenReturn(PermissionManager.PERMISSION_SOFT_DENIED); .thenReturn(postPromotedNotificationsPermissionState); Notification n = createPromotableNotification(); NotificationChannel channel = new NotificationChannel( "ChannelId", "TestChannel", NotificationManager.IMPORTANCE_HIGH); Notification n = createPromotableNotification(channel); mService.fixNotificationWithChannel(n, channel, mUid, mPkg); final int promotedOngoing = n.flags & FLAG_PROMOTED_ONGOING; assertEquals(0, promotedOngoing); final boolean isPromoted = (n.flags & FLAG_PROMOTED_ONGOING) != 0; assertEquals(expectPromoted, isPromoted); } @Test @EnableFlags({FLAG_API_RICH_ONGOING, FLAG_API_RICH_ONGOING_PERMISSION}) @EnableFlags({FLAG_API_RICH_ONGOING, FLAG_UI_RICH_ONGOING}) public void testPromotion_permissionAllowed() throws Exception { when(mPermissionManager.checkPermissionForDataDelivery( eq(Manifest.permission.POST_PROMOTED_NOTIFICATIONS), any(), any())) .thenReturn(PermissionManager.PERMISSION_GRANTED); testPromotion(PermissionManager.PERMISSION_GRANTED, mTestNotificationChannel, true); } Notification n = createPromotableNotification(); NotificationChannel channel = new NotificationChannel( "ChannelId", "TestChannel", NotificationManager.IMPORTANCE_HIGH); @Test @EnableFlags({FLAG_API_RICH_ONGOING, FLAG_UI_RICH_ONGOING}) public void testPromotion_permissionDenied() throws Exception { testPromotion(PermissionManager.PERMISSION_SOFT_DENIED, mTestNotificationChannel, false); } mService.fixNotificationWithChannel(n, channel, mUid, mPkg); @Test @EnableFlags({FLAG_API_RICH_ONGOING, FLAG_UI_RICH_ONGOING}) public void testPromotion_bundledNotification() throws Exception { testPromotion(PermissionManager.PERMISSION_GRANTED, mNewsChannel, false); } @Test @EnableFlags({FLAG_API_RICH_ONGOING, FLAG_UI_RICH_ONGOING}) public void testPromotion_silentChannel() throws Exception { testPromotion(PermissionManager.PERMISSION_GRANTED, mSilentChannel, true); } final int promotedOngoing = n.flags & FLAG_PROMOTED_ONGOING; assertNotEquals(0, promotedOngoing); @Test @EnableFlags({FLAG_API_RICH_ONGOING, FLAG_UI_RICH_ONGOING}) public void testPromotion_minimizedChannel() throws Exception { testPromotion(PermissionManager.PERMISSION_GRANTED, mMinChannel, false); } @Test Loading Loading @@ -19080,7 +19092,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @EnableFlags({FLAG_API_RICH_ONGOING}) public void testPostPromotableNotification_unimportantNotification() throws Exception { mBinderService.setCanBePromoted(mPkg, mUid, true, true); Notification n = createPromotableNotification(/* addFlagManually= */ false, mMinChannel); Notification n = createPromotableNotification(mMinChannel); StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 9, null, mUid, 0, n, UserHandle.getUserHandleForUid(mUid), null, 0); Loading @@ -19106,6 +19118,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { return createPromotableNotification(addFlagManually, mTestNotificationChannel); } private Notification createPromotableNotification(NotificationChannel channel) { return createPromotableNotification(/* addFlagManually= */ false, channel); } private Notification createPromotableNotification( boolean addFlagManually, NotificationChannel channel) { boolean newEligibilityCriteria = android.app.Flags.uiRichOngoing();