Merge "Prevent FGS notification from exceeding allowed"

This commit is contained in:
Julia Reynolds 2022-09-07 18:00:43 +00:00 committed by Gerrit Code Review
commit 6ef438e786
2 changed files with 111 additions and 13 deletions

View File

@ -6275,21 +6275,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);
}
}
}
});
@ -6967,6 +6986,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;

View File

@ -6038,6 +6038,62 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
assertEquals(0, captor.getValue().getNotification().flags);
}
@Test
public void testCannotRemoveForegroundFlagWhenOverLimit_enqueued() {
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() {
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";