Merge "Fix cancellation of foreground service notifications"

This commit is contained in:
Julia Reynolds
2019-06-13 13:30:42 +00:00
committed by Android (Google) Code Review
3 changed files with 48 additions and 32 deletions

View File

@@ -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) {
}
}
});

View File

@@ -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);
}

View File

@@ -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) {