Merge "Fix cancellation of foreground service notifications"
This commit is contained in:
committed by
Android (Google) Code Review
commit
990bee9c92
@@ -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) {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user