diff options
3 files changed, 256 insertions, 27 deletions
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 0fd80c5698a9..7f48e39a9a79 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -6965,8 +6965,10 @@ public class Notification implements Parcelable /** * Returns whether an app can colorize due to the android.permission.USE_COLORIZED_NOTIFICATIONS * permission. The permission is checked when a notification is enqueued. + * + * @hide */ - private boolean hasColorizedPermission() { + public boolean hasColorizedPermission() { return (flags & Notification.FLAG_CAN_COLORIZE) != 0; } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index ff10cbc19d5f..d11413937f8d 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -17,6 +17,7 @@ package com.android.server.notification; import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; +import static android.app.ActivityManagerInternal.ServiceNotificationPolicy.NOT_FOREGROUND_SERVICE; import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION; import static android.app.Notification.FLAG_AUTOGROUP_SUMMARY; @@ -6323,21 +6324,40 @@ public class NotificationManagerService extends SystemService { checkCallerIsSystem(); mHandler.post(() -> { synchronized (mNotificationLock) { - // strip flag from all enqueued notifications. listeners will be informed - // in post runnable. - List<NotificationRecord> enqueued = findNotificationsByListLocked( - mEnqueuedNotifications, pkg, null, notificationId, userId); - for (int i = 0; i < enqueued.size(); i++) { - removeForegroundServiceFlagLocked(enqueued.get(i)); - } + int count = getNotificationCount(pkg, userId); + boolean removeFgsNotification = false; + if (count > MAX_PACKAGE_NOTIFICATIONS) { + mUsageStats.registerOverCountQuota(pkg); + removeFgsNotification = true; + } + if (removeFgsNotification) { + NotificationRecord r = findNotificationLocked(pkg, null, notificationId, + userId); + if (r != null) { + if (DBG) { + Slog.d(TAG, "Remove FGS flag not allow. Cancel FGS notification"); + } + removeFromNotificationListsLocked(r); + cancelNotificationLocked(r, false, REASON_APP_CANCEL, true, + null, SystemClock.elapsedRealtime()); + } + } else { + // strip flag from all enqueued notifications. listeners will be informed + // in post runnable. + List<NotificationRecord> enqueued = findNotificationsByListLocked( + mEnqueuedNotifications, pkg, null, notificationId, userId); + for (int i = 0; i < enqueued.size(); i++) { + removeForegroundServiceFlagLocked(enqueued.get(i)); + } - // if posted notification exists, strip its flag and tell listeners - NotificationRecord r = findNotificationByListLocked( - mNotificationList, pkg, null, notificationId, userId); - if (r != null) { - removeForegroundServiceFlagLocked(r); - mRankingHelper.sort(mNotificationList); - mListeners.notifyPostedLocked(r, r); + // if posted notification exists, strip its flag and tell listeners + NotificationRecord r = findNotificationByListLocked( + mNotificationList, pkg, null, notificationId, userId); + if (r != null) { + removeForegroundServiceFlagLocked(r); + mRankingHelper.sort(mNotificationList); + mListeners.notifyPostedLocked(r, r); + } } } }); @@ -6483,9 +6503,17 @@ public class NotificationManagerService extends SystemService { checkRestrictedCategories(notification); + // Notifications passed to setForegroundService() have FLAG_FOREGROUND_SERVICE, + // but it's also possible that the app has called notify() with an update to an + // FGS notification that hasn't yet been displayed. Make sure we check for any + // FGS-related situation up front, outside of any locks so it's safe to call into + // the Activity Manager. + final ServiceNotificationPolicy policy = mAmi.applyForegroundServiceNotification( + notification, tag, id, pkg, userId); + // Fix the notification as best we can. try { - fixNotification(notification, pkg, tag, id, userId); + fixNotification(notification, pkg, tag, id, userId, notificationUid, policy); } catch (Exception e) { if (notification.isForegroundService()) { throw new SecurityException("Invalid FGS notification", e); @@ -6494,13 +6522,7 @@ public class NotificationManagerService extends SystemService { return; } - // Notifications passed to setForegroundService() have FLAG_FOREGROUND_SERVICE, - // but it's also possible that the app has called notify() with an update to an - // FGS notification that hasn't yet been displayed. Make sure we check for any - // FGS-related situation up front, outside of any locks so it's safe to call into - // the Activity Manager. - final ServiceNotificationPolicy policy = mAmi.applyForegroundServiceNotification( - notification, tag, id, pkg, userId); + if (policy == ServiceNotificationPolicy.UPDATE_ONLY) { // Proceed if the notification is already showing/known, otherwise ignore // because the service lifecycle logic has retained responsibility for its @@ -6663,14 +6685,20 @@ public class NotificationManagerService extends SystemService { @VisibleForTesting protected void fixNotification(Notification notification, String pkg, String tag, int id, - int userId) throws NameNotFoundException, RemoteException { + @UserIdInt int userId, int notificationUid, ServiceNotificationPolicy fgsPolicy) + throws NameNotFoundException, RemoteException { final ApplicationInfo ai = mPackageManagerClient.getApplicationInfoAsUser( pkg, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, (userId == UserHandle.USER_ALL) ? USER_SYSTEM : userId); Notification.addFieldsFromContext(ai, notification); - int canColorize = mPackageManagerClient.checkPermission( - android.Manifest.permission.USE_COLORIZED_NOTIFICATIONS, pkg); + if (notification.isForegroundService() && fgsPolicy == NOT_FOREGROUND_SERVICE) { + notification.flags &= ~FLAG_FOREGROUND_SERVICE; + } + + int canColorize = getContext().checkPermission( + android.Manifest.permission.USE_COLORIZED_NOTIFICATIONS, -1, notificationUid); + if (canColorize == PERMISSION_GRANTED) { notification.flags |= Notification.FLAG_CAN_COLORIZE; } else { @@ -7059,6 +7087,29 @@ public class NotificationManagerService extends SystemService { return mPermissionHelper.hasPermission(uid); } + private int getNotificationCount(String pkg, int userId) { + int count = 0; + synchronized (mNotificationLock) { + final int numListSize = mNotificationList.size(); + for (int i = 0; i < numListSize; i++) { + final NotificationRecord existing = mNotificationList.get(i); + if (existing.getSbn().getPackageName().equals(pkg) + && existing.getSbn().getUserId() == userId) { + count++; + } + } + final int numEnqSize = mEnqueuedNotifications.size(); + for (int i = 0; i < numEnqSize; i++) { + final NotificationRecord existing = mEnqueuedNotifications.get(i); + if (existing.getSbn().getPackageName().equals(pkg) + && existing.getSbn().getUserId() == userId) { + count++; + } + } + } + return count; + } + protected int getNotificationCount(String pkg, int userId, int excludedId, String excludedTag) { int count = 0; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index 96e2a0916bb1..99a361c03a2a 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -18,6 +18,8 @@ package com.android.server.notification; import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; +import static android.app.ActivityManagerInternal.ServiceNotificationPolicy.NOT_FOREGROUND_SERVICE; +import static android.app.ActivityManagerInternal.ServiceNotificationPolicy.SHOW_IMMEDIATELY; import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.Notification.FLAG_AUTO_CANCEL; import static android.app.Notification.FLAG_BUBBLE; @@ -1160,6 +1162,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { public void testEnqueuedBlockedNotifications_appBlockedChannelForegroundService() throws Exception { when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false); + when(mAmi.applyForegroundServiceNotification( + any(), anyString(), anyInt(), anyString(), anyInt())).thenReturn(SHOW_IMMEDIATELY); NotificationChannel channel = new NotificationChannel("blocked", "name", NotificationManager.IMPORTANCE_NONE); @@ -1182,6 +1186,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { public void testEnqueuedBlockedNotifications_userBlockedChannelForegroundService() throws Exception { when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false); + when(mAmi.applyForegroundServiceNotification( + any(), anyString(), anyInt(), anyString(), anyInt())).thenReturn(SHOW_IMMEDIATELY); NotificationChannel channel = new NotificationChannel("blockedbyuser", "name", IMPORTANCE_HIGH); @@ -1261,6 +1267,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { public void testEnqueuedBlockedNotifications_blockedAppForegroundService() throws Exception { when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false); when(mPermissionHelper.hasPermission(mUid)).thenReturn(false); + when(mAmi.applyForegroundServiceNotification( + any(), anyString(), anyInt(), anyString(), anyInt())).thenReturn(SHOW_IMMEDIATELY); final StatusBarNotification sbn = generateNotificationRecord(null).getSbn(); sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE; @@ -1590,6 +1598,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testEnqueueNotificationWithTag_FgsAddsFlags_dismissalAllowed() throws Exception { + when(mAmi.applyForegroundServiceNotification( + any(), anyString(), anyInt(), anyString(), anyInt())).thenReturn(SHOW_IMMEDIATELY); + mContext.getTestablePermissions().setPermission( + android.Manifest.permission.USE_COLORIZED_NOTIFICATIONS, PERMISSION_GRANTED); DeviceConfig.setProperty( DeviceConfig.NAMESPACE_SYSTEMUI, SystemUiDeviceConfigFlags.TASK_MANAGER_ENABLED, @@ -1618,6 +1630,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testEnqueueNotificationWithTag_FGSaddsFlags_dismissalNotAllowed() throws Exception { + when(mAmi.applyForegroundServiceNotification( + any(), anyString(), anyInt(), anyString(), anyInt())).thenReturn(SHOW_IMMEDIATELY); + mContext.getTestablePermissions().setPermission( + android.Manifest.permission.USE_COLORIZED_NOTIFICATIONS, PERMISSION_GRANTED); DeviceConfig.setProperty( DeviceConfig.NAMESPACE_SYSTEMUI, SystemUiDeviceConfigFlags.TASK_MANAGER_ENABLED, @@ -1904,6 +1920,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testCancelAllNotifications_IgnoreForegroundService() throws Exception { + when(mAmi.applyForegroundServiceNotification( + any(), anyString(), anyInt(), anyString(), anyInt())).thenReturn(SHOW_IMMEDIATELY); final StatusBarNotification sbn = generateNotificationRecord(null).getSbn(); sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE; mBinderService.enqueueNotificationWithTag(PKG, PKG, @@ -1918,7 +1936,27 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test + public void testCancelAllNotifications_FgsFlag_NoFgs_Allowed() throws Exception { + when(mAmi.applyForegroundServiceNotification( + any(), anyString(), anyInt(), anyString(), anyInt())) + .thenReturn(NOT_FOREGROUND_SERVICE); + final StatusBarNotification sbn = generateNotificationRecord(null).getSbn(); + sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE; + mBinderService.enqueueNotificationWithTag(PKG, PKG, + "testCancelAllNotifications_IgnoreForegroundService", + sbn.getId(), sbn.getNotification(), sbn.getUserId()); + mBinderService.cancelAllNotifications(PKG, sbn.getUserId()); + waitForIdle(); + StatusBarNotification[] notifs = + mBinderService.getActiveNotifications(sbn.getPackageName()); + assertEquals(0, notifs.length); + } + + @Test public void testCancelAllNotifications_IgnoreOtherPackages() throws Exception { + when(mAmi.applyForegroundServiceNotification( + any(), anyString(), anyInt(), anyString(), anyInt())) + .thenReturn(SHOW_IMMEDIATELY); final StatusBarNotification sbn = generateNotificationRecord(null).getSbn(); sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE; mBinderService.enqueueNotificationWithTag(PKG, PKG, @@ -2006,6 +2044,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testRemoveForegroundServiceFlag_ImmediatelyAfterEnqueue() throws Exception { + when(mAmi.applyForegroundServiceNotification( + any(), anyString(), anyInt(), anyString(), anyInt())) + .thenReturn(SHOW_IMMEDIATELY); Notification n = new Notification.Builder(mContext, mTestNotificationChannel.getId()) .setSmallIcon(android.R.drawable.sym_def_app_icon) @@ -2043,6 +2084,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testCancelNotificationWithTag_fromApp_cannotCancelFgsChild() throws Exception { + when(mAmi.applyForegroundServiceNotification( + any(), anyString(), anyInt(), anyString(), anyInt())) + .thenReturn(SHOW_IMMEDIATELY); mService.isSystemUid = false; final NotificationRecord parent = generateNotificationRecord( mTestNotificationChannel, 1, "group", true); @@ -2066,6 +2110,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testCancelNotificationWithTag_fromApp_cannotCancelFgsParent() throws Exception { + when(mAmi.applyForegroundServiceNotification( + any(), anyString(), anyInt(), anyString(), anyInt())) + .thenReturn(SHOW_IMMEDIATELY); mService.isSystemUid = false; final NotificationRecord parent = generateNotificationRecord( mTestNotificationChannel, 1, "group", true); @@ -2135,6 +2182,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testCancelAllNotificationsFromApp_cannotCancelFgsChild() throws Exception { + when(mAmi.applyForegroundServiceNotification( + any(), anyString(), anyInt(), anyString(), anyInt())) + .thenReturn(SHOW_IMMEDIATELY); mService.isSystemUid = false; final NotificationRecord parent = generateNotificationRecord( mTestNotificationChannel, 1, "group", true); @@ -2160,6 +2210,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testCancelAllNotifications_fromApp_cannotCancelFgsParent() throws Exception { + when(mAmi.applyForegroundServiceNotification( + any(), anyString(), anyInt(), anyString(), anyInt())) + .thenReturn(SHOW_IMMEDIATELY); mService.isSystemUid = false; final NotificationRecord parent = generateNotificationRecord( mTestNotificationChannel, 1, "group", true); @@ -2281,6 +2334,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testCancelNotificationsFromListener_clearAll_GroupWithFgsParent() throws Exception { + when(mAmi.applyForegroundServiceNotification( + any(), anyString(), anyInt(), anyString(), anyInt())) + .thenReturn(SHOW_IMMEDIATELY); final NotificationRecord parent = generateNotificationRecord( mTestNotificationChannel, 1, "group", true); parent.getNotification().flags |= FLAG_FOREGROUND_SERVICE; @@ -2304,6 +2360,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testCancelNotificationsFromListener_clearAll_GroupWithFgsChild() throws Exception { + when(mAmi.applyForegroundServiceNotification( + any(), anyString(), anyInt(), anyString(), anyInt())) + .thenReturn(SHOW_IMMEDIATELY); final NotificationRecord parent = generateNotificationRecord( mTestNotificationChannel, 1, "group", true); final NotificationRecord child = generateNotificationRecord( @@ -2402,6 +2461,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testCancelNotificationsFromListener_clearAll_Fgs() throws Exception { + when(mAmi.applyForegroundServiceNotification( + any(), anyString(), anyInt(), anyString(), anyInt())) + .thenReturn(SHOW_IMMEDIATELY); final NotificationRecord child2 = generateNotificationRecord( mTestNotificationChannel, 3, null, false); child2.getNotification().flags |= FLAG_FOREGROUND_SERVICE; @@ -2466,6 +2528,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testCancelNotificationsFromListener_byKey_GroupWithFgsParent() throws Exception { + when(mAmi.applyForegroundServiceNotification( + any(), anyString(), anyInt(), anyString(), anyInt())) + .thenReturn(SHOW_IMMEDIATELY); final NotificationRecord parent = generateNotificationRecord( mTestNotificationChannel, 1, "group", true); parent.getNotification().flags |= FLAG_FOREGROUND_SERVICE; @@ -2491,6 +2556,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testCancelNotificationsFromListener_byKey_GroupWithFgsChild() throws Exception { + when(mAmi.applyForegroundServiceNotification( + any(), anyString(), anyInt(), anyString(), anyInt())) + .thenReturn(SHOW_IMMEDIATELY); final NotificationRecord parent = generateNotificationRecord( mTestNotificationChannel, 1, "group", true); final NotificationRecord child = generateNotificationRecord( @@ -2596,6 +2664,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testCancelNotificationsFromListener_byKey_Fgs() throws Exception { + when(mAmi.applyForegroundServiceNotification( + any(), anyString(), anyInt(), anyString(), anyInt())) + .thenReturn(SHOW_IMMEDIATELY); final NotificationRecord child2 = generateNotificationRecord( mTestNotificationChannel, 3, null, false); child2.getNotification().flags |= FLAG_FOREGROUND_SERVICE; @@ -2762,6 +2833,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testUserInitiatedCancelAllWithGroup_ForegroundServiceFlag() throws Exception { + when(mAmi.applyForegroundServiceNotification( + any(), anyString(), anyInt(), anyString(), anyInt())) + .thenReturn(SHOW_IMMEDIATELY); final NotificationRecord parent = generateNotificationRecord( mTestNotificationChannel, 1, "group", true); final NotificationRecord child = generateNotificationRecord( @@ -6199,6 +6273,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testRemoveForegroundServiceFlagFromNotification_enqueued() { + when(mAmi.applyForegroundServiceNotification( + any(), anyString(), anyInt(), anyString(), anyInt())) + .thenReturn(SHOW_IMMEDIATELY); Notification n = new Notification.Builder(mContext, "").build(); n.flags |= FLAG_FOREGROUND_SERVICE; @@ -6218,6 +6295,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testRemoveForegroundServiceFlagFromNotification_posted() { + when(mAmi.applyForegroundServiceNotification( + any(), anyString(), anyInt(), anyString(), anyInt())) + .thenReturn(SHOW_IMMEDIATELY); Notification n = new Notification.Builder(mContext, "").build(); n.flags |= FLAG_FOREGROUND_SERVICE; @@ -6240,6 +6320,68 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test + public void testCannotRemoveForegroundFlagWhenOverLimit_enqueued() { + when(mAmi.applyForegroundServiceNotification( + any(), anyString(), anyInt(), anyString(), anyInt())) + .thenReturn(SHOW_IMMEDIATELY); + for (int i = 0; i < NotificationManagerService.MAX_PACKAGE_NOTIFICATIONS; i++) { + Notification n = new Notification.Builder(mContext, "").build(); + StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, i, null, mUid, 0, + n, UserHandle.getUserHandleForUid(mUid), null, 0); + NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); + mService.addEnqueuedNotification(r); + } + Notification n = new Notification.Builder(mContext, "").build(); + n.flags |= FLAG_FOREGROUND_SERVICE; + + StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, + NotificationManagerService.MAX_PACKAGE_NOTIFICATIONS, null, mUid, 0, + n, UserHandle.getUserHandleForUid(mUid), null, 0); + NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); + + mService.addEnqueuedNotification(r); + + mInternalService.removeForegroundServiceFlagFromNotification( + PKG, r.getSbn().getId(), r.getSbn().getUserId()); + + waitForIdle(); + + assertEquals(NotificationManagerService.MAX_PACKAGE_NOTIFICATIONS, + mService.getNotificationRecordCount()); + } + + @Test + public void testCannotRemoveForegroundFlagWhenOverLimit_posted() { + when(mAmi.applyForegroundServiceNotification( + any(), anyString(), anyInt(), anyString(), anyInt())) + .thenReturn(SHOW_IMMEDIATELY); + for (int i = 0; i < NotificationManagerService.MAX_PACKAGE_NOTIFICATIONS; i++) { + Notification n = new Notification.Builder(mContext, "").build(); + StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, i, null, mUid, 0, + n, UserHandle.getUserHandleForUid(mUid), null, 0); + NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); + mService.addNotification(r); + } + Notification n = new Notification.Builder(mContext, "").build(); + n.flags |= FLAG_FOREGROUND_SERVICE; + + StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, + NotificationManagerService.MAX_PACKAGE_NOTIFICATIONS, null, mUid, 0, + n, UserHandle.getUserHandleForUid(mUid), null, 0); + NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); + + mService.addNotification(r); + + mInternalService.removeForegroundServiceFlagFromNotification( + PKG, r.getSbn().getId(), r.getSbn().getUserId()); + + waitForIdle(); + + assertEquals(NotificationManagerService.MAX_PACKAGE_NOTIFICATIONS, + mService.getNotificationRecordCount()); + } + + @Test public void testAllowForegroundCustomToasts() throws Exception { final String testPackage = "testPackageName"; assertEquals(0, mService.mToastQueue.size()); @@ -8230,7 +8372,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertNotNull(n.publicVersion.bigContentView); assertNotNull(n.publicVersion.headsUpContentView); - mService.fixNotification(n, PKG, "tag", 9, 0); + mService.fixNotification(n, PKG, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE); assertNull(n.contentView); assertNull(n.bigContentView); @@ -8921,6 +9063,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testCanPostFgsWhenOverLimit() throws RemoteException { + when(mAmi.applyForegroundServiceNotification( + any(), anyString(), anyInt(), anyString(), anyInt())) + .thenReturn(SHOW_IMMEDIATELY); for (int i = 0; i < NotificationManagerService.MAX_PACKAGE_NOTIFICATIONS; i++) { StatusBarNotification sbn = generateNotificationRecord(mTestNotificationChannel, i, null, false).getSbn(); @@ -8946,6 +9091,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testCannotPostNonFgsWhenOverLimit() throws RemoteException { + when(mAmi.applyForegroundServiceNotification( + any(), anyString(), anyInt(), anyString(), anyInt())) + .thenReturn(SHOW_IMMEDIATELY); for (int i = 0; i < NotificationManagerService.MAX_PACKAGE_NOTIFICATIONS; i++) { StatusBarNotification sbn = generateNotificationRecord(mTestNotificationChannel, i, null, false).getSbn(); @@ -8968,6 +9116,17 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { "testCanPostFgsWhenOverLimit - non fgs over limit!", sbn2.getId(), sbn2.getNotification(), sbn2.getUserId()); + + when(mAmi.applyForegroundServiceNotification( + any(), anyString(), anyInt(), anyString(), anyInt())) + .thenReturn(NOT_FOREGROUND_SERVICE); + final StatusBarNotification sbn3 = generateNotificationRecord(mTestNotificationChannel, + 101, null, false).getSbn(); + sbn3.getNotification().flags |= FLAG_FOREGROUND_SERVICE; + mBinderService.enqueueNotificationWithTag(PKG, PKG, + "testCanPostFgsWhenOverLimit - fake fgs over limit!", + sbn3.getId(), sbn3.getNotification(), sbn3.getUserId()); + waitForIdle(); StatusBarNotification[] notifs = @@ -10025,4 +10184,21 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mInternalService.sendReviewPermissionsNotification(); verify(mMockNm, never()).notify(anyString(), anyInt(), any(Notification.class)); } + + @Test + public void fixNotification_withFgsFlag_butIsNotFgs() throws Exception { + final ApplicationInfo applicationInfo = new ApplicationInfo(); + when(mPackageManagerClient.getApplicationInfoAsUser(anyString(), anyInt(), anyInt())) + .thenReturn(applicationInfo); + + Notification n = new Notification.Builder(mContext, "test") + .setFlag(FLAG_FOREGROUND_SERVICE, true) + .setFlag(FLAG_CAN_COLORIZE, true) + .build(); + + mService.fixNotification(n, PKG, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE); + + assertFalse(n.isForegroundService()); + assertFalse(n.hasColorizedPermission()); + } } |