@Override
public void onNotificationError(int callingUid, int callingPid, String pkg, String tag, int id,
int uid, int initialPid, String message, int userId) {
- Slog.d(TAG, "onNotification error pkg=" + pkg + " tag=" + tag + " id=" + id
- + "; will crashApplication(uid=" + uid + ", pid=" + initialPid + ")");
+ final boolean fgService;
+ synchronized (mNotificationLock) {
+ NotificationRecord r = findNotificationLocked(pkg, tag, id, userId);
+ fgService = r != null
+ && (r.getNotification().flags&Notification.FLAG_FOREGROUND_SERVICE) != 0;
+ }
cancelNotification(callingUid, callingPid, pkg, tag, id, 0, 0, false, userId,
REASON_ERROR, null);
- long ident = Binder.clearCallingIdentity();
- try {
- ActivityManager.getService().crashApplication(uid, initialPid, pkg, -1,
- "Bad notification posted from package " + pkg
- + ": " + message);
- } catch (RemoteException e) {
+ if (fgService) {
+ // Still crash for foreground services, preventing the not-crash behaviour abused
+ // by apps to give us a garbage notification and silently start a fg service.
+ Binder.withCleanCallingIdentity(
+ () -> mAm.crashApplication(uid, initialPid, pkg, -1,
+ "Bad notification(tag=" + tag + ", id=" + id + ") posted from package "
+ + pkg + ", crashing app(uid=" + uid + ", pid=" + initialPid + "): "
+ + message, true /* force */));
}
- Binder.restoreCallingIdentity(ident);
}
@Override