Loading core/java/android/app/Notification.java +2 −2 Original line number Diff line number Diff line Loading @@ -4634,8 +4634,8 @@ public class Notification implements Parcelable * Set whether this is an "ongoing" notification. * * Ongoing notifications cannot be dismissed by the user on locked devices, or by * notification listeners, and some notifications cannnot be dismissed on unlocked * devices (system, device management, media), so your application or service must take * notification listeners, and some notifications (device management, media) cannot be * dismissed on unlocked devices, so your application or service must take * care of canceling them. * * They are typically used to indicate a background task that the user is actively engaged Loading services/core/java/com/android/server/notification/NotificationManagerService.java +1 −5 Original line number Diff line number Diff line Loading @@ -6863,11 +6863,7 @@ public class NotificationManagerService extends SystemService { * 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(ai); return notification.isMediaNotification() || isEnterpriseExempted(ai); } private boolean isEnterpriseExempted(ApplicationInfo ai) { Loading services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +31 −65 Original line number Diff line number Diff line Loading @@ -443,6 +443,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { doNothing().when(mContext).sendBroadcastAsUser(any(), any(), any()); setDpmAppOppsExemptFromDismissal(false); mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger, mNotificationInstanceIdSequence); Loading Loading @@ -10319,8 +10321,18 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test public void fixSystemNotification_withOnGoingFlag_shouldBeNonDismissible() public void fixSystemNotification_withOnGoingFlag_shouldBeDismissible() throws Exception { final ApplicationInfo ai = new ApplicationInfo(); ai.packageName = "pkg"; ai.uid = mUid; ai.flags |= ApplicationInfo.FLAG_SYSTEM; when(mPackageManagerClient.getApplicationInfoAsUser(anyString(), anyInt(), anyInt())) .thenReturn(ai); when(mAppOpsManager.checkOpNoThrow( AppOpsManager.OP_SYSTEM_EXEMPT_FROM_DISMISSIBLE_NOTIFICATIONS, ai.uid, ai.packageName)).thenReturn(AppOpsManager.MODE_IGNORED); // Given: a notification from an app on the system partition has the flag // FLAG_ONGOING_EVENT set // feature flag: ALLOW_DISMISS_ONGOING is on Loading @@ -10329,16 +10341,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { .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, mUid, NOT_FOREGROUND_SERVICE); // Then: the notification's flag FLAG_NO_DISMISS should be set assertNotSame(0, n.flags & Notification.FLAG_NO_DISMISS); // Then: the notification's flag FLAG_NO_DISMISS should not be set assertSame(0, n.flags & Notification.FLAG_NO_DISMISS); } @Test Loading Loading @@ -10394,52 +10401,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS); } @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: ALLOW_DISMISS_ONGOING is on mTestFlagResolver.setFlagOverride(ALLOW_DISMISS_ONGOING, 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, mUid, NOT_FOREGROUND_SERVICE); // Then: the notification's flag FLAG_NO_DISMISS should not be set assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS); } @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: ALLOW_DISMISS_ONGOING is on mTestFlagResolver.setFlagOverride(ALLOW_DISMISS_ONGOING, 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, mUid, NOT_FOREGROUND_SERVICE); // Then: the notification's flag FLAG_NO_DISMISS should be cleared assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS); } @Test public void fixMediaNotification_withoutOnGoingFlag_shouldBeDismissible() throws Exception { // Given: a media notification doesn't have the flag FLAG_ONGOING_EVENT set Loading Loading @@ -10503,7 +10464,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { // Given: a notification has the flag FLAG_ONGOING_EVENT set // feature flag: ALLOW_DISMISS_ONGOING is on mTestFlagResolver.setFlagOverride(ALLOW_DISMISS_ONGOING, true); setSystemExemptFromDismissal(false); setDpmAppOppsExemptFromDismissal(false); Notification n = new Notification.Builder(mContext, "test") .setOngoing(true) .build(); Loading @@ -10516,15 +10477,22 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test public void fixSystemExemptAppOpNotification_withFlag_shouldBeNonDismissible() public void fixExemptAppOpNotification_withFlag_shouldBeNonDismissible() throws Exception { final ApplicationInfo ai = new ApplicationInfo(); ai.packageName = PKG; ai.uid = mUid; ai.flags |= ApplicationInfo.FLAG_SYSTEM; when(mPackageManagerClient.getApplicationInfoAsUser(anyString(), anyInt(), anyInt())) .thenReturn(ai); when(mAppOpsManager.checkOpNoThrow( AppOpsManager.OP_SYSTEM_EXEMPT_FROM_DISMISSIBLE_NOTIFICATIONS, mUid, PKG)).thenReturn(AppOpsManager.MODE_ALLOWED); // Given: a notification has the flag FLAG_ONGOING_EVENT set // feature flag: ALLOW_DISMISS_ONGOING is on mTestFlagResolver.setFlagOverride(ALLOW_DISMISS_ONGOING, true); setSystemExemptFromDismissal(true); setDpmAppOppsExemptFromDismissal(true); Notification n = new Notification.Builder(mContext, "test") .setOngoing(true) .build(); Loading @@ -10532,14 +10500,12 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { // When: fix the notification with NotificationManagerService mService.fixNotification(n, PKG, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE); // Then: the notification's flag FLAG_NO_DISMISS should be set assertNotSame(0, n.flags & Notification.FLAG_NO_DISMISS); setSystemExemptFromDismissal(false); // Then: the notification's flag FLAG_NO_DISMISS should be cleared assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS); } @Test public void fixSystemExemptAppOpNotification_withoutFlag_shouldBeNonDismissible() public void fixExemptAppOpNotification_withoutAppOpsFlag_shouldBeDismissible() throws Exception { when(mAppOpsManager.checkOpNoThrow( AppOpsManager.OP_SYSTEM_EXEMPT_FROM_DISMISSIBLE_NOTIFICATIONS, mUid, Loading @@ -10547,7 +10513,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { // Given: a notification has the flag FLAG_ONGOING_EVENT set // feature flag: ALLOW_DISMISS_ONGOING is on mTestFlagResolver.setFlagOverride(ALLOW_DISMISS_ONGOING, true); setSystemExemptFromDismissal(false); setDpmAppOppsExemptFromDismissal(false); Notification n = new Notification.Builder(mContext, "test") .setOngoing(true) .build(); Loading @@ -10556,10 +10522,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mService.fixNotification(n, PKG, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE); // Then: the notification's flag FLAG_NO_DISMISS should not be set assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS); assertSame(0, n.flags & Notification.FLAG_NO_DISMISS); } private void setSystemExemptFromDismissal(boolean isOn) { private void setDpmAppOppsExemptFromDismissal(boolean isOn) { DeviceConfig.setProperty( DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER, /* name= */ "application_exemptions", Loading Loading
core/java/android/app/Notification.java +2 −2 Original line number Diff line number Diff line Loading @@ -4634,8 +4634,8 @@ public class Notification implements Parcelable * Set whether this is an "ongoing" notification. * * Ongoing notifications cannot be dismissed by the user on locked devices, or by * notification listeners, and some notifications cannnot be dismissed on unlocked * devices (system, device management, media), so your application or service must take * notification listeners, and some notifications (device management, media) cannot be * dismissed on unlocked devices, so your application or service must take * care of canceling them. * * They are typically used to indicate a background task that the user is actively engaged Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +1 −5 Original line number Diff line number Diff line Loading @@ -6863,11 +6863,7 @@ public class NotificationManagerService extends SystemService { * 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(ai); return notification.isMediaNotification() || isEnterpriseExempted(ai); } private boolean isEnterpriseExempted(ApplicationInfo ai) { Loading
services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +31 −65 Original line number Diff line number Diff line Loading @@ -443,6 +443,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { doNothing().when(mContext).sendBroadcastAsUser(any(), any(), any()); setDpmAppOppsExemptFromDismissal(false); mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger, mNotificationInstanceIdSequence); Loading Loading @@ -10319,8 +10321,18 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test public void fixSystemNotification_withOnGoingFlag_shouldBeNonDismissible() public void fixSystemNotification_withOnGoingFlag_shouldBeDismissible() throws Exception { final ApplicationInfo ai = new ApplicationInfo(); ai.packageName = "pkg"; ai.uid = mUid; ai.flags |= ApplicationInfo.FLAG_SYSTEM; when(mPackageManagerClient.getApplicationInfoAsUser(anyString(), anyInt(), anyInt())) .thenReturn(ai); when(mAppOpsManager.checkOpNoThrow( AppOpsManager.OP_SYSTEM_EXEMPT_FROM_DISMISSIBLE_NOTIFICATIONS, ai.uid, ai.packageName)).thenReturn(AppOpsManager.MODE_IGNORED); // Given: a notification from an app on the system partition has the flag // FLAG_ONGOING_EVENT set // feature flag: ALLOW_DISMISS_ONGOING is on Loading @@ -10329,16 +10341,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { .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, mUid, NOT_FOREGROUND_SERVICE); // Then: the notification's flag FLAG_NO_DISMISS should be set assertNotSame(0, n.flags & Notification.FLAG_NO_DISMISS); // Then: the notification's flag FLAG_NO_DISMISS should not be set assertSame(0, n.flags & Notification.FLAG_NO_DISMISS); } @Test Loading Loading @@ -10394,52 +10401,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS); } @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: ALLOW_DISMISS_ONGOING is on mTestFlagResolver.setFlagOverride(ALLOW_DISMISS_ONGOING, 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, mUid, NOT_FOREGROUND_SERVICE); // Then: the notification's flag FLAG_NO_DISMISS should not be set assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS); } @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: ALLOW_DISMISS_ONGOING is on mTestFlagResolver.setFlagOverride(ALLOW_DISMISS_ONGOING, 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, mUid, NOT_FOREGROUND_SERVICE); // Then: the notification's flag FLAG_NO_DISMISS should be cleared assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS); } @Test public void fixMediaNotification_withoutOnGoingFlag_shouldBeDismissible() throws Exception { // Given: a media notification doesn't have the flag FLAG_ONGOING_EVENT set Loading Loading @@ -10503,7 +10464,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { // Given: a notification has the flag FLAG_ONGOING_EVENT set // feature flag: ALLOW_DISMISS_ONGOING is on mTestFlagResolver.setFlagOverride(ALLOW_DISMISS_ONGOING, true); setSystemExemptFromDismissal(false); setDpmAppOppsExemptFromDismissal(false); Notification n = new Notification.Builder(mContext, "test") .setOngoing(true) .build(); Loading @@ -10516,15 +10477,22 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test public void fixSystemExemptAppOpNotification_withFlag_shouldBeNonDismissible() public void fixExemptAppOpNotification_withFlag_shouldBeNonDismissible() throws Exception { final ApplicationInfo ai = new ApplicationInfo(); ai.packageName = PKG; ai.uid = mUid; ai.flags |= ApplicationInfo.FLAG_SYSTEM; when(mPackageManagerClient.getApplicationInfoAsUser(anyString(), anyInt(), anyInt())) .thenReturn(ai); when(mAppOpsManager.checkOpNoThrow( AppOpsManager.OP_SYSTEM_EXEMPT_FROM_DISMISSIBLE_NOTIFICATIONS, mUid, PKG)).thenReturn(AppOpsManager.MODE_ALLOWED); // Given: a notification has the flag FLAG_ONGOING_EVENT set // feature flag: ALLOW_DISMISS_ONGOING is on mTestFlagResolver.setFlagOverride(ALLOW_DISMISS_ONGOING, true); setSystemExemptFromDismissal(true); setDpmAppOppsExemptFromDismissal(true); Notification n = new Notification.Builder(mContext, "test") .setOngoing(true) .build(); Loading @@ -10532,14 +10500,12 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { // When: fix the notification with NotificationManagerService mService.fixNotification(n, PKG, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE); // Then: the notification's flag FLAG_NO_DISMISS should be set assertNotSame(0, n.flags & Notification.FLAG_NO_DISMISS); setSystemExemptFromDismissal(false); // Then: the notification's flag FLAG_NO_DISMISS should be cleared assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS); } @Test public void fixSystemExemptAppOpNotification_withoutFlag_shouldBeNonDismissible() public void fixExemptAppOpNotification_withoutAppOpsFlag_shouldBeDismissible() throws Exception { when(mAppOpsManager.checkOpNoThrow( AppOpsManager.OP_SYSTEM_EXEMPT_FROM_DISMISSIBLE_NOTIFICATIONS, mUid, Loading @@ -10547,7 +10513,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { // Given: a notification has the flag FLAG_ONGOING_EVENT set // feature flag: ALLOW_DISMISS_ONGOING is on mTestFlagResolver.setFlagOverride(ALLOW_DISMISS_ONGOING, true); setSystemExemptFromDismissal(false); setDpmAppOppsExemptFromDismissal(false); Notification n = new Notification.Builder(mContext, "test") .setOngoing(true) .build(); Loading @@ -10556,10 +10522,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mService.fixNotification(n, PKG, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE); // Then: the notification's flag FLAG_NO_DISMISS should not be set assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS); assertSame(0, n.flags & Notification.FLAG_NO_DISMISS); } private void setSystemExemptFromDismissal(boolean isOn) { private void setDpmAppOppsExemptFromDismissal(boolean isOn) { DeviceConfig.setProperty( DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER, /* name= */ "application_exemptions", Loading