Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 990bee9c authored by Julia Reynolds's avatar Julia Reynolds Committed by Android (Google) Code Review
Browse files

Merge "Fix cancellation of foreground service notifications"

parents 7de19a56 b301c4f7
Loading
Loading
Loading
Loading
+7 −5
Original line number Diff line number Diff line
@@ -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) {
                }
            }
        });
+2 −0
Original line number Diff line number Diff line
@@ -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);
}
+39 −27
Original line number Diff line number Diff line
@@ -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) {