Ensure notification visibility on stopForeground(false)

If an FGS notification has been deferred but the app needs it to remain
present after the service exits the FGS mode, make sure that it gets
shown.

Bug: 193665032
Test: atest CtsAppTestCases:android.app.cts.ServiceTest#testForegroundService_deferThenKeepNotification
Change-Id: I1e9c5f1b27dd670639bd5e02b7f79839cfb5362e
This commit is contained in:
Christopher Tate
2021-07-14 14:18:38 -07:00
parent b42f19e297
commit 075de7ea1d

View File

@@ -1934,6 +1934,28 @@ public final class ActiveServices {
if (smap != null) {
decActiveForegroundAppLocked(smap, r);
}
// Adjust notification handling before setting isForeground to false, because
// that state is relevant to the notification policy side.
// Leave the time-to-display as already set: re-entering foreground mode will
// only resume the previous quiet timeout, or will display immediately if the
// deferral period had already passed.
if ((flags & Service.STOP_FOREGROUND_REMOVE) != 0) {
cancelForegroundNotificationLocked(r);
r.foregroundId = 0;
r.foregroundNoti = null;
} else if (r.appInfo.targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
// if it's been deferred, force to visibility
if (!r.mFgsNotificationShown) {
r.postNotification();
}
dropFgsNotificationStateLocked(r);
if ((flags & Service.STOP_FOREGROUND_DETACH) != 0) {
r.foregroundId = 0;
r.foregroundNoti = null;
}
}
r.isForeground = false;
r.mFgsExitTime = SystemClock.uptimeMillis();
ServiceState stracker = r.getTracker();
@@ -1957,20 +1979,6 @@ public final class ActiveServices {
updateServiceForegroundLocked(r.app.mServices, true);
}
}
// Leave the time-to-display as already set: re-entering foreground mode will
// only resume the previous quiet timeout, or will display immediately if the
// deferral period had already passed.
if ((flags & Service.STOP_FOREGROUND_REMOVE) != 0) {
cancelForegroundNotificationLocked(r);
r.foregroundId = 0;
r.foregroundNoti = null;
} else if (r.appInfo.targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
dropFgsNotificationStateLocked(r);
if ((flags & Service.STOP_FOREGROUND_DETACH) != 0) {
r.foregroundId = 0;
r.foregroundNoti = null;
}
}
}
}