Merge "Fix issue #29506774: Foreground Service Can Avoid Notification Requirement" into nyc-mr1-dev

This commit is contained in:
Dianne Hackborn
2016-08-02 16:47:42 +00:00
committed by Android (Google) Code Review
2 changed files with 43 additions and 24 deletions

View File

@@ -699,7 +699,7 @@ public final class ActiveServices {
throw new IllegalArgumentException("null notification"); throw new IllegalArgumentException("null notification");
} }
if (r.foregroundId != id) { if (r.foregroundId != id) {
r.cancelNotification(); cancelForegroudNotificationLocked(r);
r.foregroundId = id; r.foregroundId = id;
} }
notification.flags |= Notification.FLAG_FOREGROUND_SERVICE; notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
@@ -721,7 +721,7 @@ public final class ActiveServices {
} }
} }
if ((flags & Service.STOP_FOREGROUND_REMOVE) != 0) { if ((flags & Service.STOP_FOREGROUND_REMOVE) != 0) {
r.cancelNotification(); cancelForegroudNotificationLocked(r);
r.foregroundId = 0; r.foregroundId = 0;
r.foregroundNoti = null; r.foregroundNoti = null;
} else if (r.appInfo.targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) { } 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) { private void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
boolean anyForeground = false; boolean anyForeground = false;
for (int i=proc.services.size()-1; i>=0; i--) { 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.makeRestarting(mAm.mProcessStats.getMemFactorLocked(), now);
} }
r.cancelNotification(); cancelForegroudNotificationLocked(r);
mAm.mHandler.removeCallbacks(r.restarter); mAm.mHandler.removeCallbacks(r.restarter);
mAm.mHandler.postAtTime(r.restarter, r.nextRestartTime); mAm.mHandler.postAtTime(r.restarter, r.nextRestartTime);
@@ -2022,7 +2043,7 @@ public final class ActiveServices {
} }
} }
r.cancelNotification(); cancelForegroudNotificationLocked(r);
r.isForeground = false; r.isForeground = false;
r.foregroundId = 0; r.foregroundId = 0;
r.foregroundNoti = null; r.foregroundNoti = null;

View File

@@ -543,7 +543,6 @@ final class ServiceRecord extends Binder {
} }
public void cancelNotification() { public void cancelNotification() {
if (foregroundId != 0) {
// Do asynchronous communication with notification manager to // Do asynchronous communication with notification manager to
// avoid deadlocks. // avoid deadlocks.
final String localPackageName = packageName; final String localPackageName = packageName;
@@ -564,7 +563,6 @@ final class ServiceRecord extends Binder {
} }
}); });
} }
}
public void stripForegroundServiceFlagFromNotification() { public void stripForegroundServiceFlagFromNotification() {
if (foregroundId == 0) { if (foregroundId == 0) {