diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java index 3f723fc35f30a..043c207aa05b0 100644 --- a/services/core/java/com/android/server/am/ServiceRecord.java +++ b/services/core/java/com/android/server/am/ServiceRecord.java @@ -911,18 +911,20 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN // avoid deadlocks. final String localPackageName = packageName; final int localForegroundId = foregroundId; + final int appUid = appInfo.uid; + final int appPid = app.pid; ams.mHandler.post(new Runnable() { public void run() { - INotificationManager inm = NotificationManager.getService(); - if (inm == null) { + NotificationManagerInternal nm = LocalServices.getService( + NotificationManagerInternal.class); + if (nm == null) { return; } try { - inm.cancelNotificationWithTag(localPackageName, "android", null, - localForegroundId, userId); + nm.cancelNotification(localPackageName, localPackageName, appUid, appPid, + null, localForegroundId, userId); } catch (RuntimeException e) { Slog.w(TAG, "Error canceling notification for service", e); - } catch (RemoteException e) { } } }); diff --git a/services/core/java/com/android/server/notification/NotificationManagerInternal.java b/services/core/java/com/android/server/notification/NotificationManagerInternal.java index f1476b34388b9..fce10e62bc5db 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerInternal.java +++ b/services/core/java/com/android/server/notification/NotificationManagerInternal.java @@ -23,6 +23,8 @@ public interface NotificationManagerInternal { NotificationChannel getNotificationChannel(String pkg, int uid, String channelId); void enqueueNotification(String pkg, String basePkg, int callingUid, int callingPid, String tag, int id, Notification notification, int userId); + void cancelNotification(String pkg, String basePkg, int callingUid, int callingPid, + String tag, int id, int userId); void removeForegroundServiceFlagFromNotification(String pkg, int notificationId, int userId); } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 930b81ee4f325..c3188c87d49e5 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -2380,33 +2380,8 @@ public class NotificationManagerService extends SystemService { @Override public void cancelNotificationWithTag(String pkg, String opPkg, String tag, int id, int userId) { - userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), - Binder.getCallingUid(), userId, true, false, "cancelNotificationWithTag", pkg); - - // ensure opPkg is delegate if does not match pkg - int uid = resolveNotificationUid(opPkg, pkg, Binder.getCallingUid(), userId); - - // if opPkg is not the same as pkg, make sure the notification given was posted - // by opPkg - if (!Objects.equals(pkg, opPkg)) { - synchronized (mNotificationLock) { - // Look for the notification, searching both the posted and enqueued lists. - NotificationRecord r = findNotificationLocked(pkg, tag, id, userId); - if (r != null) { - if (!Objects.equals(opPkg, r.sbn.getOpPkg())) { - throw new SecurityException(opPkg + " does not have permission to " - + "cancel a notification they did not post " + tag + " " + id); - } - } - } - } - - // Don't allow client applications to cancel foreground service notis or autobundled - // summaries. - final int mustNotHaveFlags = isCallingUidSystem() ? 0 : - (FLAG_FOREGROUND_SERVICE | FLAG_AUTOGROUP_SUMMARY); - cancelNotification(uid, Binder.getCallingPid(), pkg, tag, id, 0, - mustNotHaveFlags, false, userId, REASON_APP_CANCEL, null); + cancelNotificationInternal(pkg, opPkg, Binder.getCallingUid(), Binder.getCallingPid(), + tag, id, userId); } @Override @@ -4637,6 +4612,12 @@ public class NotificationManagerService extends SystemService { userId); } + @Override + public void cancelNotification(String pkg, String opPkg, int callingUid, int callingPid, + String tag, int id, int userId) { + cancelNotificationInternal(pkg, opPkg, callingUid, callingPid, tag, id, userId); + } + @Override public void removeForegroundServiceFlagFromNotification(String pkg, int notificationId, int userId) { @@ -4678,6 +4659,37 @@ public class NotificationManagerService extends SystemService { } }; + void cancelNotificationInternal(String pkg, String opPkg, int callingUid, int callingPid, + String tag, int id, int userId) { + userId = ActivityManager.handleIncomingUser(callingPid, + callingUid, userId, true, false, "cancelNotificationWithTag", pkg); + + // ensure opPkg is delegate if does not match pkg + int uid = resolveNotificationUid(opPkg, pkg, callingUid, userId); + + // if opPkg is not the same as pkg, make sure the notification given was posted + // by opPkg + if (!Objects.equals(pkg, opPkg)) { + synchronized (mNotificationLock) { + // Look for the notification, searching both the posted and enqueued lists. + NotificationRecord r = findNotificationLocked(pkg, tag, id, userId); + if (r != null) { + if (!Objects.equals(opPkg, r.sbn.getOpPkg())) { + throw new SecurityException(opPkg + " does not have permission to " + + "cancel a notification they did not post " + tag + " " + id); + } + } + } + } + + // Don't allow client applications to cancel foreground service notis or autobundled + // summaries. + final int mustNotHaveFlags = isCallingUidSystem() ? 0 : + (FLAG_FOREGROUND_SERVICE | FLAG_AUTOGROUP_SUMMARY); + cancelNotification(uid, callingPid, pkg, tag, id, 0, + mustNotHaveFlags, false, userId, REASON_APP_CANCEL, null); + } + void enqueueNotificationInternal(final String pkg, final String opPkg, final int callingUid, final int callingPid, final String tag, final int id, final Notification notification, int incomingUserId) {