Merge "Properly reset FGS notification associations" into sc-dev

This commit is contained in:
Chris Tate
2021-06-25 00:36:50 +00:00
committed by Android (Google) Code Review
2 changed files with 38 additions and 7 deletions

View File

@@ -1976,7 +1976,7 @@ public final class ActiveServices {
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) {
r.stripForegroundServiceFlagFromNotification(); dropFgsNotificationStateLocked(r);
if ((flags & Service.STOP_FOREGROUND_DETACH) != 0) { if ((flags & Service.STOP_FOREGROUND_DETACH) != 0) {
r.foregroundId = 0; r.foregroundId = 0;
r.foregroundNoti = null; r.foregroundNoti = null;
@@ -4225,9 +4225,10 @@ public final class ActiveServices {
} }
r.isForeground = false; r.isForeground = false;
r.mFgsNotificationWasDeferred = false;
dropFgsNotificationStateLocked(r);
r.foregroundId = 0; r.foregroundId = 0;
r.foregroundNoti = null; r.foregroundNoti = null;
r.mFgsNotificationWasDeferred = false;
resetFgsRestrictionLocked(r); resetFgsRestrictionLocked(r);
// Clear start entries. // Clear start entries.
@@ -4291,6 +4292,35 @@ public final class ActiveServices {
smap.ensureNotStartingBackgroundLocked(r); smap.ensureNotStartingBackgroundLocked(r);
} }
private void dropFgsNotificationStateLocked(ServiceRecord r) {
// If this is the only FGS using this notification, clear its FGS flag
boolean shared = false;
final ServiceMap smap = mServiceMap.get(r.userId);
if (smap != null) {
// Is any other FGS using this notification?
final int numServices = smap.mServicesByInstanceName.size();
for (int i = 0; i < numServices; i++) {
final ServiceRecord sr = smap.mServicesByInstanceName.valueAt(i);
if (sr == r) {
continue;
}
if (sr.isForeground
&& r.foregroundId == sr.foregroundId
&& r.appInfo.packageName.equals(sr.appInfo.packageName)) {
shared = true;
break;
}
}
} else {
Slog.wtf(TAG, "FGS " + r + " not found!");
}
// No other FGS is sharing this notification, so we're done with it
if (!shared) {
r.stripForegroundServiceFlagFromNotification();
}
}
void removeConnectionLocked(ConnectionRecord c, ProcessRecord skipApp, void removeConnectionLocked(ConnectionRecord c, ProcessRecord skipApp,
ActivityServiceConnectionsHolder skipAct, boolean enqueueOomAdj) { ActivityServiceConnectionsHolder skipAct, boolean enqueueOomAdj) {
IBinder binder = c.conn.asBinder(); IBinder binder = c.conn.asBinder();

View File

@@ -20,6 +20,7 @@ import static android.app.PendingIntent.FLAG_IMMUTABLE;
import static android.app.PendingIntent.FLAG_UPDATE_CURRENT; import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
import static android.os.PowerExemptionManager.REASON_DENIED; import static android.os.PowerExemptionManager.REASON_DENIED;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOREGROUND_SERVICE;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -928,13 +929,17 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
public void postNotification() { public void postNotification() {
final int appUid = appInfo.uid; final int appUid = appInfo.uid;
final int appPid = app.getPid(); final int appPid = app.getPid();
if (foregroundId != 0 && foregroundNoti != null) { if (isForeground && foregroundNoti != null) {
// 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;
final Notification _foregroundNoti = foregroundNoti; final Notification _foregroundNoti = foregroundNoti;
final ServiceRecord record = this; final ServiceRecord record = this;
if (DEBUG_FOREGROUND_SERVICE) {
Slog.d(TAG, "Posting notification " + _foregroundNoti
+ " for foreground service " + this);
}
ams.mHandler.post(new Runnable() { ams.mHandler.post(new Runnable() {
public void run() { public void run() {
NotificationManagerInternal nm = LocalServices.getService( NotificationManagerInternal nm = LocalServices.getService(
@@ -1066,10 +1071,6 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
} }
public void stripForegroundServiceFlagFromNotification() { public void stripForegroundServiceFlagFromNotification() {
if (foregroundId == 0) {
return;
}
final int localForegroundId = foregroundId; final int localForegroundId = foregroundId;
final int localUserId = userId; final int localUserId = userId;
final String localPackageName = packageName; final String localPackageName = packageName;