Merge "Fix issue #29506774: Foreground Service Can Avoid Notification Requirement" into nyc-mr1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
b008ff14ac
@@ -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;
|
||||||
|
|||||||
@@ -543,27 +543,25 @@ 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;
|
final int localForegroundId = foregroundId;
|
||||||
final int localForegroundId = foregroundId;
|
ams.mHandler.post(new Runnable() {
|
||||||
ams.mHandler.post(new Runnable() {
|
public void run() {
|
||||||
public void run() {
|
INotificationManager inm = NotificationManager.getService();
|
||||||
INotificationManager inm = NotificationManager.getService();
|
if (inm == null) {
|
||||||
if (inm == null) {
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
inm.cancelNotificationWithTag(localPackageName, null,
|
|
||||||
localForegroundId, userId);
|
|
||||||
} catch (RuntimeException e) {
|
|
||||||
Slog.w(TAG, "Error canceling notification for service", e);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
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() {
|
public void stripForegroundServiceFlagFromNotification() {
|
||||||
|
|||||||
Reference in New Issue
Block a user