diff options
| -rwxr-xr-x | services/core/java/com/android/server/am/ActiveServices.java | 29 | ||||
| -rw-r--r-- | services/core/java/com/android/server/am/ServiceRecord.java | 38 |
2 files changed, 43 insertions, 24 deletions
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index ee2fa51c8666..a3d2ebbba9c3 100755 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -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; diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java index 2bfc4021f887..71c7fd348fb3 100644 --- a/services/core/java/com/android/server/am/ServiceRecord.java +++ b/services/core/java/com/android/server/am/ServiceRecord.java @@ -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() { |