Loading core/java/android/app/Notification.java +10 −0 Original line number Diff line number Diff line Loading @@ -703,6 +703,16 @@ public class Notification implements Parcelable */ public static final int FLAG_BUBBLE = 0x00001000; /** * Bit to be bitswised-ored into the {@link #flags} field that should be * set by the system if this notification is not dismissible. * * This flag is for internal use only; applications cannot set this flag directly. * @hide */ public static final int FLAG_NO_DISMISS = 0x00002000; private static final List<Class<? extends Style>> PLATFORM_STYLE_CLASSES = Arrays.asList( BigTextStyle.class, BigPictureStyle.class, InboxStyle.class, MediaStyle.class, DecoratedCustomViewStyle.class, DecoratedMediaCustomViewStyle.class, Loading services/core/java/com/android/server/notification/NotificationManagerService.java +38 −4 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static android.app.Notification.FLAG_BUBBLE; import static android.app.Notification.FLAG_FOREGROUND_SERVICE; import static android.app.Notification.FLAG_INSISTENT; import static android.app.Notification.FLAG_NO_CLEAR; import static android.app.Notification.FLAG_NO_DISMISS; import static android.app.Notification.FLAG_ONGOING_EVENT; import static android.app.Notification.FLAG_ONLY_ALERT_ONCE; import static android.app.NotificationChannel.CONVERSATION_CHANNEL_ID_FORMAT; Loading Loading @@ -576,6 +577,9 @@ public class NotificationManagerService extends SystemService { private float mInCallNotificationVolume; private Binder mCallNotificationToken = null; private static final boolean ONGOING_DISMISSAL = SystemProperties.getBoolean( "persist.sysui.notification.ongoing_dismissal", true); // used as a mutex for access to all active notifications & listeners final Object mNotificationLock = new Object(); @GuardedBy("mNotificationLock") Loading Loading @@ -1201,10 +1205,13 @@ public class NotificationManagerService extends SystemService { id = r.getSbn().getId(); } } int mustNotHaveFlags = FLAG_ONGOING_EVENT; cancelNotification(callingUid, callingPid, pkg, tag, id, 0, mustNotHaveFlags, true, userId, REASON_CANCEL, nv.rank, nv.count,null); int mustNotHaveFlags = ONGOING_DISMISSAL ? FLAG_NO_DISMISS : FLAG_ONGOING_EVENT; cancelNotification(callingUid, callingPid, pkg, tag, id, /* mustHaveFlags= */ 0, /* mustNotHaveFlags= */ mustNotHaveFlags, /* sendDelete= */ true, userId, REASON_CANCEL, nv.rank, nv.count, /* listener= */ null); nv.recycle(); } Loading Loading @@ -6689,6 +6696,16 @@ public class NotificationManagerService extends SystemService { (userId == UserHandle.USER_ALL) ? USER_SYSTEM : userId); Notification.addFieldsFromContext(ai, notification); // Only notifications that can be non-dismissible can have the flag FLAG_NO_DISMISS if (ONGOING_DISMISSAL) { if (((notification.flags & FLAG_ONGOING_EVENT) > 0) && canBeNonDismissible(ai, notification)) { notification.flags |= FLAG_NO_DISMISS; } else { notification.flags &= ~FLAG_NO_DISMISS; } } int canColorize = mPackageManagerClient.checkPermission( android.Manifest.permission.USE_COLORIZED_NOTIFICATIONS, pkg); if (canColorize == PERMISSION_GRANTED) { Loading Loading @@ -6775,6 +6792,23 @@ public class NotificationManagerService extends SystemService { checkRemoteViews(pkg, tag, id, notification); } /** * Whether a notification can be non-dismissible. * A notification should be dismissible, unless it's exempted for some reason. */ private boolean canBeNonDismissible(ApplicationInfo ai, Notification notification) { // Check if the app is on the system partition, or an update to an app on the system // partition. boolean isSystemAppExempt = (ai.flags & (ApplicationInfo.FLAG_UPDATED_SYSTEM_APP | ApplicationInfo.FLAG_SYSTEM)) > 0; return isSystemAppExempt || notification.isMediaNotification() || isEnterpriseExempted(); } // TODO: b/266237746 Enterprise app exemptions private boolean isEnterpriseExempted() { return false; } private void checkRemoteViews(String pkg, String tag, int id, Notification notification) { if (removeRemoteView(pkg, tag, id, notification.contentView)) { notification.contentView = null; Loading services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +208 −0 Original line number Diff line number Diff line Loading @@ -78,6 +78,7 @@ import static com.google.common.truth.Truth.assertThat; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertNotSame; import static junit.framework.Assert.assertNull; import static junit.framework.Assert.assertTrue; import static junit.framework.Assert.fail; Loading Loading @@ -10083,4 +10084,211 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mInternalService.sendReviewPermissionsNotification(); verify(mMockNm, never()).notify(anyString(), anyInt(), any(Notification.class)); } @Test public void fixSystemNotification_withOnGoingFlag_shouldBeNonDismissible() throws Exception { // Given: a notification from an app on the system partition has the flag // FLAG_ONGOING_EVENT set // feature flag: NOTIFICATION_ONGOING_DISMISSAL is on mService.setOngoingDismissal(true); Notification n = new Notification.Builder(mContext, "test") .setOngoing(true) .build(); final ApplicationInfo systemAppInfo = new ApplicationInfo(); systemAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM; when(mPackageManagerClient.getApplicationInfoAsUser(anyString(), anyInt(), anyInt())) .thenReturn(systemAppInfo); // When: fix the notification with NotificationManagerService mService.fixNotification(n, PKG, "tag", 9, 0); // Then: the notification's flag FLAG_NO_DISMISS should be set assertNotSame(0, n.flags & Notification.FLAG_NO_DISMISS); // Avoid affecting other tests mService.setOngoingDismissal(false); } @Test public void fixMediaNotification_withOnGoingFlag_shouldBeNonDismissible() throws Exception { // Given: a media notification has the flag FLAG_ONGOING_EVENT set // feature flag: NOTIFICATION_ONGOING_DISMISSAL is on mService.setOngoingDismissal(true); Notification n = new Notification.Builder(mContext, "test") .setOngoing(true) .setStyle(new Notification.MediaStyle() .setMediaSession(mock(MediaSession.Token.class))) .build(); // When: fix the notification with NotificationManagerService mService.fixNotification(n, PKG, "tag", 9, 0); // Then: the notification's flag FLAG_NO_DISMISS should be set assertNotSame(0, n.flags & Notification.FLAG_NO_DISMISS); // Avoid affecting other tests mService.setOngoingDismissal(false); } @Test public void fixNonExemptNotification_withOnGoingFlag_shouldBeDismissible() throws Exception { // Given: a non-exempt notification has the flag FLAG_ONGOING_EVENT set // feature flag: NOTIFICATION_ONGOING_DISMISSAL is on mService.setOngoingDismissal(true); Notification n = new Notification.Builder(mContext, "test") .setOngoing(true) .build(); // When: fix the notification with NotificationManagerService mService.fixNotification(n, PKG, "tag", 9, 0); // Then: the notification's flag FLAG_NO_DISMISS should not be set assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS); // Avoid affecting other tests mService.setOngoingDismissal(false); } @Test public void fixNonExemptNotification_withNoDismissFlag_shouldBeDismissible() throws Exception { // Given: a non-exempt notification has the flag FLAG_NO_DISMISS set (even though this is // not allowed) // feature flag: NOTIFICATION_ONGOING_DISMISSAL is on mService.setOngoingDismissal(true); Notification n = new Notification.Builder(mContext, "test") .build(); n.flags |= Notification.FLAG_NO_DISMISS; // When: fix the notification with NotificationManagerService mService.fixNotification(n, PKG, "tag", 9, 0); // Then: the notification's flag FLAG_NO_DISMISS should be cleared assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS); // Avoid affecting other tests mService.setOngoingDismissal(false); } @Test public void fixSystemNotification_withoutOnGoingFlag_shouldBeDismissible() throws Exception { // Given: a notification from an app on the system partition doesn't have the flag // FLAG_ONGOING_EVENT set // feature flag: NOTIFICATION_ONGOING_DISMISSAL is on mService.setOngoingDismissal(true); Notification n = new Notification.Builder(mContext, "test") .setOngoing(false) .build(); final ApplicationInfo systemAppInfo = new ApplicationInfo(); systemAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM; when(mPackageManagerClient.getApplicationInfoAsUser(anyString(), anyInt(), anyInt())) .thenReturn(systemAppInfo); // When: fix the notification with NotificationManagerService mService.fixNotification(n, PKG, "tag", 9, 0); // Then: the notification's flag FLAG_NO_DISMISS should not be set assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS); // Avoid affecting other tests mService.setOngoingDismissal(false); } @Test public void fixSystemNotification_withoutOnGoingFlag_withNoDismissFlag_shouldBeDismissible() throws Exception { // Given: a notification from an app on the system partition doesn't have the flag // FLAG_ONGOING_EVENT set, but has the flag FLAG_NO_DISMISS set // feature flag: NOTIFICATION_ONGOING_DISMISSAL is on mService.setOngoingDismissal(true); Notification n = new Notification.Builder(mContext, "test") .setOngoing(false) .build(); n.flags |= Notification.FLAG_NO_DISMISS; final ApplicationInfo systemAppInfo = new ApplicationInfo(); systemAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM; when(mPackageManagerClient.getApplicationInfoAsUser(anyString(), anyInt(), anyInt())) .thenReturn(systemAppInfo); // When: fix the notification with NotificationManagerService mService.fixNotification(n, PKG, "tag", 9, 0); // Then: the notification's flag FLAG_NO_DISMISS should be cleared assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS); // Avoid affecting other tests mService.setOngoingDismissal(false); } @Test public void fixMediaNotification_withoutOnGoingFlag_shouldBeDismissible() throws Exception { // Given: a media notification doesn't have the flag FLAG_ONGOING_EVENT set // feature flag: NOTIFICATION_ONGOING_DISMISSAL is on mService.setOngoingDismissal(true); Notification n = new Notification.Builder(mContext, "test") .setOngoing(false) .setStyle(new Notification.MediaStyle() .setMediaSession(mock(MediaSession.Token.class))) .build(); // When: fix the notification with NotificationManagerService mService.fixNotification(n, PKG, "tag", 9, 0); // Then: the notification's flag FLAG_NO_DISMISS should not be set assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS); // Avoid affecting other tests mService.setOngoingDismissal(false); } @Test public void fixMediaNotification_withoutOnGoingFlag_withNoDismissFlag_shouldBeDismissible() throws Exception { // Given: a media notification doesn't have the flag FLAG_ONGOING_EVENT set, // but has the flag FLAG_NO_DISMISS set // feature flag: NOTIFICATION_ONGOING_DISMISSAL is on mService.setOngoingDismissal(true); Notification n = new Notification.Builder(mContext, "test") .setOngoing(false) .setStyle(new Notification.MediaStyle() .setMediaSession(mock(MediaSession.Token.class))) .build(); n.flags |= Notification.FLAG_NO_DISMISS; // When: fix the notification with NotificationManagerService mService.fixNotification(n, PKG, "tag", 9, 0); // Then: the notification's flag FLAG_NO_DISMISS should be cleared assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS); // Avoid affecting other tests mService.setOngoingDismissal(false); } @Test public void fixNonExempt_Notification_withoutOnGoingFlag_shouldBeDismissible() throws Exception { // Given: a non-exempt notification has the flag FLAG_ONGOING_EVENT set // feature flag: NOTIFICATION_ONGOING_DISMISSAL is on mService.setOngoingDismissal(true); mService.setOngoingDismissal(true); Notification n = new Notification.Builder(mContext, "test") .setOngoing(false) .build(); // When: fix the notification with NotificationManagerService mService.fixNotification(n, PKG, "tag", 9, 0); // Then: the notification's flag FLAG_NO_DISMISS should not be set assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS); // Avoid affecting other tests mService.setOngoingDismissal(false); } } services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java +7 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,8 @@ public class TestableNotificationManagerService extends NotificationManagerServi int countLogSmartSuggestionsVisible = 0; Set<Integer> mChannelToastsSent = new HashSet<>(); public boolean ONGOING_DISMISSAL = false; String stringArrayResourceValue; @Nullable NotificationAssistantAccessGrantedCallback mNotificationAssistantAccessGrantedCallback; Loading Loading @@ -159,4 +161,9 @@ public class TestableNotificationManagerService extends NotificationManagerServi return mGetStrongAuthForUserReturnValue; } } // Mock SystemProperties protected void setOngoingDismissal(boolean ongoingDismissal) { ONGOING_DISMISSAL = ongoingDismissal; } } Loading
core/java/android/app/Notification.java +10 −0 Original line number Diff line number Diff line Loading @@ -703,6 +703,16 @@ public class Notification implements Parcelable */ public static final int FLAG_BUBBLE = 0x00001000; /** * Bit to be bitswised-ored into the {@link #flags} field that should be * set by the system if this notification is not dismissible. * * This flag is for internal use only; applications cannot set this flag directly. * @hide */ public static final int FLAG_NO_DISMISS = 0x00002000; private static final List<Class<? extends Style>> PLATFORM_STYLE_CLASSES = Arrays.asList( BigTextStyle.class, BigPictureStyle.class, InboxStyle.class, MediaStyle.class, DecoratedCustomViewStyle.class, DecoratedMediaCustomViewStyle.class, Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +38 −4 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static android.app.Notification.FLAG_BUBBLE; import static android.app.Notification.FLAG_FOREGROUND_SERVICE; import static android.app.Notification.FLAG_INSISTENT; import static android.app.Notification.FLAG_NO_CLEAR; import static android.app.Notification.FLAG_NO_DISMISS; import static android.app.Notification.FLAG_ONGOING_EVENT; import static android.app.Notification.FLAG_ONLY_ALERT_ONCE; import static android.app.NotificationChannel.CONVERSATION_CHANNEL_ID_FORMAT; Loading Loading @@ -576,6 +577,9 @@ public class NotificationManagerService extends SystemService { private float mInCallNotificationVolume; private Binder mCallNotificationToken = null; private static final boolean ONGOING_DISMISSAL = SystemProperties.getBoolean( "persist.sysui.notification.ongoing_dismissal", true); // used as a mutex for access to all active notifications & listeners final Object mNotificationLock = new Object(); @GuardedBy("mNotificationLock") Loading Loading @@ -1201,10 +1205,13 @@ public class NotificationManagerService extends SystemService { id = r.getSbn().getId(); } } int mustNotHaveFlags = FLAG_ONGOING_EVENT; cancelNotification(callingUid, callingPid, pkg, tag, id, 0, mustNotHaveFlags, true, userId, REASON_CANCEL, nv.rank, nv.count,null); int mustNotHaveFlags = ONGOING_DISMISSAL ? FLAG_NO_DISMISS : FLAG_ONGOING_EVENT; cancelNotification(callingUid, callingPid, pkg, tag, id, /* mustHaveFlags= */ 0, /* mustNotHaveFlags= */ mustNotHaveFlags, /* sendDelete= */ true, userId, REASON_CANCEL, nv.rank, nv.count, /* listener= */ null); nv.recycle(); } Loading Loading @@ -6689,6 +6696,16 @@ public class NotificationManagerService extends SystemService { (userId == UserHandle.USER_ALL) ? USER_SYSTEM : userId); Notification.addFieldsFromContext(ai, notification); // Only notifications that can be non-dismissible can have the flag FLAG_NO_DISMISS if (ONGOING_DISMISSAL) { if (((notification.flags & FLAG_ONGOING_EVENT) > 0) && canBeNonDismissible(ai, notification)) { notification.flags |= FLAG_NO_DISMISS; } else { notification.flags &= ~FLAG_NO_DISMISS; } } int canColorize = mPackageManagerClient.checkPermission( android.Manifest.permission.USE_COLORIZED_NOTIFICATIONS, pkg); if (canColorize == PERMISSION_GRANTED) { Loading Loading @@ -6775,6 +6792,23 @@ public class NotificationManagerService extends SystemService { checkRemoteViews(pkg, tag, id, notification); } /** * Whether a notification can be non-dismissible. * A notification should be dismissible, unless it's exempted for some reason. */ private boolean canBeNonDismissible(ApplicationInfo ai, Notification notification) { // Check if the app is on the system partition, or an update to an app on the system // partition. boolean isSystemAppExempt = (ai.flags & (ApplicationInfo.FLAG_UPDATED_SYSTEM_APP | ApplicationInfo.FLAG_SYSTEM)) > 0; return isSystemAppExempt || notification.isMediaNotification() || isEnterpriseExempted(); } // TODO: b/266237746 Enterprise app exemptions private boolean isEnterpriseExempted() { return false; } private void checkRemoteViews(String pkg, String tag, int id, Notification notification) { if (removeRemoteView(pkg, tag, id, notification.contentView)) { notification.contentView = null; Loading
services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +208 −0 Original line number Diff line number Diff line Loading @@ -78,6 +78,7 @@ import static com.google.common.truth.Truth.assertThat; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertNotSame; import static junit.framework.Assert.assertNull; import static junit.framework.Assert.assertTrue; import static junit.framework.Assert.fail; Loading Loading @@ -10083,4 +10084,211 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mInternalService.sendReviewPermissionsNotification(); verify(mMockNm, never()).notify(anyString(), anyInt(), any(Notification.class)); } @Test public void fixSystemNotification_withOnGoingFlag_shouldBeNonDismissible() throws Exception { // Given: a notification from an app on the system partition has the flag // FLAG_ONGOING_EVENT set // feature flag: NOTIFICATION_ONGOING_DISMISSAL is on mService.setOngoingDismissal(true); Notification n = new Notification.Builder(mContext, "test") .setOngoing(true) .build(); final ApplicationInfo systemAppInfo = new ApplicationInfo(); systemAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM; when(mPackageManagerClient.getApplicationInfoAsUser(anyString(), anyInt(), anyInt())) .thenReturn(systemAppInfo); // When: fix the notification with NotificationManagerService mService.fixNotification(n, PKG, "tag", 9, 0); // Then: the notification's flag FLAG_NO_DISMISS should be set assertNotSame(0, n.flags & Notification.FLAG_NO_DISMISS); // Avoid affecting other tests mService.setOngoingDismissal(false); } @Test public void fixMediaNotification_withOnGoingFlag_shouldBeNonDismissible() throws Exception { // Given: a media notification has the flag FLAG_ONGOING_EVENT set // feature flag: NOTIFICATION_ONGOING_DISMISSAL is on mService.setOngoingDismissal(true); Notification n = new Notification.Builder(mContext, "test") .setOngoing(true) .setStyle(new Notification.MediaStyle() .setMediaSession(mock(MediaSession.Token.class))) .build(); // When: fix the notification with NotificationManagerService mService.fixNotification(n, PKG, "tag", 9, 0); // Then: the notification's flag FLAG_NO_DISMISS should be set assertNotSame(0, n.flags & Notification.FLAG_NO_DISMISS); // Avoid affecting other tests mService.setOngoingDismissal(false); } @Test public void fixNonExemptNotification_withOnGoingFlag_shouldBeDismissible() throws Exception { // Given: a non-exempt notification has the flag FLAG_ONGOING_EVENT set // feature flag: NOTIFICATION_ONGOING_DISMISSAL is on mService.setOngoingDismissal(true); Notification n = new Notification.Builder(mContext, "test") .setOngoing(true) .build(); // When: fix the notification with NotificationManagerService mService.fixNotification(n, PKG, "tag", 9, 0); // Then: the notification's flag FLAG_NO_DISMISS should not be set assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS); // Avoid affecting other tests mService.setOngoingDismissal(false); } @Test public void fixNonExemptNotification_withNoDismissFlag_shouldBeDismissible() throws Exception { // Given: a non-exempt notification has the flag FLAG_NO_DISMISS set (even though this is // not allowed) // feature flag: NOTIFICATION_ONGOING_DISMISSAL is on mService.setOngoingDismissal(true); Notification n = new Notification.Builder(mContext, "test") .build(); n.flags |= Notification.FLAG_NO_DISMISS; // When: fix the notification with NotificationManagerService mService.fixNotification(n, PKG, "tag", 9, 0); // Then: the notification's flag FLAG_NO_DISMISS should be cleared assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS); // Avoid affecting other tests mService.setOngoingDismissal(false); } @Test public void fixSystemNotification_withoutOnGoingFlag_shouldBeDismissible() throws Exception { // Given: a notification from an app on the system partition doesn't have the flag // FLAG_ONGOING_EVENT set // feature flag: NOTIFICATION_ONGOING_DISMISSAL is on mService.setOngoingDismissal(true); Notification n = new Notification.Builder(mContext, "test") .setOngoing(false) .build(); final ApplicationInfo systemAppInfo = new ApplicationInfo(); systemAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM; when(mPackageManagerClient.getApplicationInfoAsUser(anyString(), anyInt(), anyInt())) .thenReturn(systemAppInfo); // When: fix the notification with NotificationManagerService mService.fixNotification(n, PKG, "tag", 9, 0); // Then: the notification's flag FLAG_NO_DISMISS should not be set assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS); // Avoid affecting other tests mService.setOngoingDismissal(false); } @Test public void fixSystemNotification_withoutOnGoingFlag_withNoDismissFlag_shouldBeDismissible() throws Exception { // Given: a notification from an app on the system partition doesn't have the flag // FLAG_ONGOING_EVENT set, but has the flag FLAG_NO_DISMISS set // feature flag: NOTIFICATION_ONGOING_DISMISSAL is on mService.setOngoingDismissal(true); Notification n = new Notification.Builder(mContext, "test") .setOngoing(false) .build(); n.flags |= Notification.FLAG_NO_DISMISS; final ApplicationInfo systemAppInfo = new ApplicationInfo(); systemAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM; when(mPackageManagerClient.getApplicationInfoAsUser(anyString(), anyInt(), anyInt())) .thenReturn(systemAppInfo); // When: fix the notification with NotificationManagerService mService.fixNotification(n, PKG, "tag", 9, 0); // Then: the notification's flag FLAG_NO_DISMISS should be cleared assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS); // Avoid affecting other tests mService.setOngoingDismissal(false); } @Test public void fixMediaNotification_withoutOnGoingFlag_shouldBeDismissible() throws Exception { // Given: a media notification doesn't have the flag FLAG_ONGOING_EVENT set // feature flag: NOTIFICATION_ONGOING_DISMISSAL is on mService.setOngoingDismissal(true); Notification n = new Notification.Builder(mContext, "test") .setOngoing(false) .setStyle(new Notification.MediaStyle() .setMediaSession(mock(MediaSession.Token.class))) .build(); // When: fix the notification with NotificationManagerService mService.fixNotification(n, PKG, "tag", 9, 0); // Then: the notification's flag FLAG_NO_DISMISS should not be set assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS); // Avoid affecting other tests mService.setOngoingDismissal(false); } @Test public void fixMediaNotification_withoutOnGoingFlag_withNoDismissFlag_shouldBeDismissible() throws Exception { // Given: a media notification doesn't have the flag FLAG_ONGOING_EVENT set, // but has the flag FLAG_NO_DISMISS set // feature flag: NOTIFICATION_ONGOING_DISMISSAL is on mService.setOngoingDismissal(true); Notification n = new Notification.Builder(mContext, "test") .setOngoing(false) .setStyle(new Notification.MediaStyle() .setMediaSession(mock(MediaSession.Token.class))) .build(); n.flags |= Notification.FLAG_NO_DISMISS; // When: fix the notification with NotificationManagerService mService.fixNotification(n, PKG, "tag", 9, 0); // Then: the notification's flag FLAG_NO_DISMISS should be cleared assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS); // Avoid affecting other tests mService.setOngoingDismissal(false); } @Test public void fixNonExempt_Notification_withoutOnGoingFlag_shouldBeDismissible() throws Exception { // Given: a non-exempt notification has the flag FLAG_ONGOING_EVENT set // feature flag: NOTIFICATION_ONGOING_DISMISSAL is on mService.setOngoingDismissal(true); mService.setOngoingDismissal(true); Notification n = new Notification.Builder(mContext, "test") .setOngoing(false) .build(); // When: fix the notification with NotificationManagerService mService.fixNotification(n, PKG, "tag", 9, 0); // Then: the notification's flag FLAG_NO_DISMISS should not be set assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS); // Avoid affecting other tests mService.setOngoingDismissal(false); } }
services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java +7 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,8 @@ public class TestableNotificationManagerService extends NotificationManagerServi int countLogSmartSuggestionsVisible = 0; Set<Integer> mChannelToastsSent = new HashSet<>(); public boolean ONGOING_DISMISSAL = false; String stringArrayResourceValue; @Nullable NotificationAssistantAccessGrantedCallback mNotificationAssistantAccessGrantedCallback; Loading Loading @@ -159,4 +161,9 @@ public class TestableNotificationManagerService extends NotificationManagerServi return mGetStrongAuthForUserReturnValue; } } // Mock SystemProperties protected void setOngoingDismissal(boolean ongoingDismissal) { ONGOING_DISMISSAL = ongoingDismissal; } }