Fix issue #29506774: Foreground Service Can Avoid Notification Requirement
Don't cancel the notification if there are other foreground services using the same notification ID. Change-Id: I02a49d9a07af0203e59e70be2dc6773f3cefee47
This commit is contained in:
@@ -699,7 +699,7 @@ public final class ActiveServices {
|
||||
throw new IllegalArgumentException("null notification");
|
||||
}
|
||||
if (r.foregroundId != id) {
|
||||
r.cancelNotification();
|
||||
cancelForegroudNotificationLocked(r);
|
||||
r.foregroundId = id;
|
||||
}
|
||||
notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
|
||||
@@ -721,7 +721,7 @@ public final class ActiveServices {
|
||||
}
|
||||
}
|
||||
if ((flags & Service.STOP_FOREGROUND_REMOVE) != 0) {
|
||||
r.cancelNotification();
|
||||
cancelForegroudNotificationLocked(r);
|
||||
r.foregroundId = 0;
|
||||
r.foregroundNoti = null;
|
||||
} else if (r.appInfo.targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
@@ -738,6 +738,27 @@ public final class ActiveServices {
|
||||
}
|
||||
}
|
||||
|
||||
private void cancelForegroudNotificationLocked(ServiceRecord r) {
|
||||
if (r.foregroundId != 0) {
|
||||
// First check to see if this app has any other active foreground services
|
||||
// with the same notification ID. If so, we shouldn't actually cancel it,
|
||||
// because that would wipe away the notification that still needs to be shown
|
||||
// due the other service.
|
||||
ServiceMap sm = getServiceMap(r.userId);
|
||||
if (sm != null) {
|
||||
for (int i = sm.mServicesByName.size()-1; i >= 0; i--) {
|
||||
ServiceRecord other = sm.mServicesByName.valueAt(i);
|
||||
if (other.foregroundId == r.foregroundId
|
||||
&& other.packageName.equals(r.packageName)) {
|
||||
// Found one! Abort the cancel.
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
r.cancelNotification();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
|
||||
boolean anyForeground = false;
|
||||
for (int i=proc.services.size()-1; i>=0; i--) {
|
||||
@@ -1560,7 +1581,7 @@ public final class ActiveServices {
|
||||
r.makeRestarting(mAm.mProcessStats.getMemFactorLocked(), now);
|
||||
}
|
||||
|
||||
r.cancelNotification();
|
||||
cancelForegroudNotificationLocked(r);
|
||||
|
||||
mAm.mHandler.removeCallbacks(r.restarter);
|
||||
mAm.mHandler.postAtTime(r.restarter, r.nextRestartTime);
|
||||
@@ -2022,7 +2043,7 @@ public final class ActiveServices {
|
||||
}
|
||||
}
|
||||
|
||||
r.cancelNotification();
|
||||
cancelForegroudNotificationLocked(r);
|
||||
r.isForeground = false;
|
||||
r.foregroundId = 0;
|
||||
r.foregroundNoti = null;
|
||||
|
||||
@@ -543,27 +543,25 @@ final class ServiceRecord extends Binder {
|
||||
}
|
||||
|
||||
public void cancelNotification() {
|
||||
if (foregroundId != 0) {
|
||||
// Do asynchronous communication with notification manager to
|
||||
// avoid deadlocks.
|
||||
final String localPackageName = packageName;
|
||||
final int localForegroundId = foregroundId;
|
||||
ams.mHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
INotificationManager inm = NotificationManager.getService();
|
||||
if (inm == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
inm.cancelNotificationWithTag(localPackageName, null,
|
||||
localForegroundId, userId);
|
||||
} catch (RuntimeException e) {
|
||||
Slog.w(TAG, "Error canceling notification for service", e);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
// Do asynchronous communication with notification manager to
|
||||
// avoid deadlocks.
|
||||
final String localPackageName = packageName;
|
||||
final int localForegroundId = foregroundId;
|
||||
ams.mHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
INotificationManager inm = NotificationManager.getService();
|
||||
if (inm == null) {
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
try {
|
||||
inm.cancelNotificationWithTag(localPackageName, null,
|
||||
localForegroundId, userId);
|
||||
} catch (RuntimeException e) {
|
||||
Slog.w(TAG, "Error canceling notification for service", e);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void stripForegroundServiceFlagFromNotification() {
|
||||
|
||||
Reference in New Issue
Block a user