Merge "Fix stuck notifications" into pi-dev

This commit is contained in:
TreeHugger Robot
2019-01-15 01:10:33 +00:00
committed by Android (Google) Code Review
2 changed files with 75 additions and 15 deletions

View File

@@ -3960,25 +3960,30 @@ public class NotificationManagerService extends SystemService {
public void removeForegroundServiceFlagFromNotification(String pkg, int notificationId,
int userId) {
checkCallerIsSystem();
mHandler.post(new Runnable() {
@Override
public void run() {
synchronized (mNotificationLock) {
removeForegroundServiceFlagByListLocked(
mEnqueuedNotifications, pkg, notificationId, userId);
removeForegroundServiceFlagByListLocked(
mNotificationList, pkg, notificationId, userId);
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));
}
// 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);
}
}
});
}
@GuardedBy("mNotificationLock")
private void removeForegroundServiceFlagByListLocked(
ArrayList<NotificationRecord> notificationList, String pkg, int notificationId,
int userId) {
NotificationRecord r = findNotificationByListLocked(
notificationList, pkg, null, notificationId, userId);
private void removeForegroundServiceFlagLocked(NotificationRecord r) {
if (r == null) {
return;
}
@@ -3989,8 +3994,6 @@ public class NotificationManagerService extends SystemService {
// initially *and* force remove FLAG_FOREGROUND_SERVICE.
sbn.getNotification().flags =
(r.mOriginalFlags & ~FLAG_FOREGROUND_SERVICE);
mRankingHelper.sort(mNotificationList);
mListeners.notifyPostedLocked(r, r);
}
};
@@ -6073,6 +6076,21 @@ public class NotificationManagerService extends SystemService {
return null;
}
@GuardedBy("mNotificationLock")
private List<NotificationRecord> findNotificationsByListLocked(
ArrayList<NotificationRecord> list, String pkg, String tag, int id, int userId) {
List<NotificationRecord> matching = new ArrayList<>();
final int len = list.size();
for (int i = 0; i < len; i++) {
NotificationRecord r = list.get(i);
if (notificationMatchesUserId(r, userId) && r.sbn.getId() == id &&
TextUtils.equals(r.sbn.getTag(), tag) && r.sbn.getPackageName().equals(pkg)) {
matching.add(r);
}
}
return matching;
}
@GuardedBy("mNotificationLock")
private NotificationRecord findNotificationByListLocked(ArrayList<NotificationRecord> list,
String key) {

View File

@@ -3103,4 +3103,46 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
verify(mAppUsageStats, times(1)).reportInterruptiveNotification(
anyString(), anyString(), anyInt());
}
@Test
public void testRemoveForegroundServiceFlagFromNotification_enqueued() {
Notification n = new Notification.Builder(mContext, "").build();
n.flags |= FLAG_FOREGROUND_SERVICE;
StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 9, null, mUid, 0,
n, new UserHandle(mUid), null, 0);
NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
mService.addEnqueuedNotification(r);
mInternalService.removeForegroundServiceFlagFromNotification(
PKG, r.sbn.getId(), r.sbn.getUserId());
waitForIdle();
verify(mListeners, timeout(200).times(0)).notifyPostedLocked(any(), any());
}
@Test
public void testRemoveForegroundServiceFlagFromNotification_posted() {
Notification n = new Notification.Builder(mContext, "").build();
n.flags |= FLAG_FOREGROUND_SERVICE;
StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 9, null, mUid, 0,
n, new UserHandle(mUid), null, 0);
NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
mService.addNotification(r);
mInternalService.removeForegroundServiceFlagFromNotification(
PKG, r.sbn.getId(), r.sbn.getUserId());
waitForIdle();
ArgumentCaptor<NotificationRecord> captor =
ArgumentCaptor.forClass(NotificationRecord.class);
verify(mListeners, times(1)).notifyPostedLocked(captor.capture(), any());
assertEquals(0, captor.getValue().getNotification().flags);
}
}