From ee9739cd7ef7971221782938f1066f6720af32d7 Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Fri, 20 Sep 2019 17:30:12 -0700 Subject: Services exit fg when bg-restricted app leaves top Apps under bg restrictions can still start foreground services while they are the top/frontmost UI. However, this was not being reexamined when the app was no longer the top UI. This is now fixed: when an app under bg restrictions exits the top state, any foreground services it is hosting are demoted out of the foreground state. At this point the service lifecycle is just like any other ordinary service that an app has left running after it is no longer the active UI: the service is stopped by the OS after the standard grace period. Bug: 139436349 Test: repro app supplied with the bug Test: foreground use of GPM under bg restrictions Test: atest CtsAppTestCases:android.app.cts.ActivityManagerProcessStateTest\#testBgRestrictedForegroundService Change-Id: I6d0e954c961f7c547c1f5d98e3926586f3071bca Merged-In: I6d0e954c961f7c547c1f5d98e3926586f3071bca --- .../java/com/android/server/am/ActiveServices.java | 73 +++++++++++++--------- 1 file changed, 44 insertions(+), 29 deletions(-) diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 7bc2e6d647b..6cbbcddc2b3 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -192,34 +192,38 @@ public final class ActiveServices { @Override public void stopForegroundServicesForUidPackage(final int uid, final String packageName) { synchronized (mAm) { - final ServiceMap smap = getServiceMapLocked(UserHandle.getUserId(uid)); - final int N = smap.mServicesByInstanceName.size(); - final ArrayList toStop = new ArrayList<>(N); - for (int i = 0; i < N; i++) { - final ServiceRecord r = smap.mServicesByInstanceName.valueAt(i); - if (uid == r.serviceInfo.applicationInfo.uid - || packageName.equals(r.serviceInfo.packageName)) { - if (r.isForeground) { - toStop.add(r); - } - } - } + stopAllForegroundServicesLocked(uid, packageName); + } + } + } - // Now stop them all - final int numToStop = toStop.size(); - if (numToStop > 0 && DEBUG_FOREGROUND_SERVICE) { - Slog.i(TAG, "Package " + packageName + "/" + uid - + " entering FAS with foreground services"); - } - for (int i = 0; i < numToStop; i++) { - final ServiceRecord r = toStop.get(i); - if (DEBUG_FOREGROUND_SERVICE) { - Slog.i(TAG, " Stopping fg for service " + r); - } - setServiceForegroundInnerLocked(r, 0, null, 0, 0); + void stopAllForegroundServicesLocked(final int uid, final String packageName) { + final ServiceMap smap = getServiceMapLocked(UserHandle.getUserId(uid)); + final int N = smap.mServicesByInstanceName.size(); + final ArrayList toStop = new ArrayList<>(N); + for (int i = 0; i < N; i++) { + final ServiceRecord r = smap.mServicesByInstanceName.valueAt(i); + if (uid == r.serviceInfo.applicationInfo.uid + || packageName.equals(r.serviceInfo.packageName)) { + if (r.isForeground) { + toStop.add(r); } } } + + // Now stop them all + final int numToStop = toStop.size(); + if (numToStop > 0 && DEBUG_FOREGROUND_SERVICE) { + Slog.i(TAG, "Package " + packageName + "/" + uid + + " in FAS with foreground services"); + } + for (int i = 0; i < numToStop; i++) { + final ServiceRecord r = toStop.get(i); + if (DEBUG_FOREGROUND_SERVICE) { + Slog.i(TAG, " Stopping fg for service " + r); + } + setServiceForegroundInnerLocked(r, 0, null, 0, 0); + } } /** @@ -1010,12 +1014,23 @@ public final class ActiveServices { } } if (!aa.mAppOnTop) { - if (active == null) { - active = new ArrayList<>(); + // Transitioning a fg-service host app out of top: if it's bg restricted, + // it loses the fg service state now. + if (!appRestrictedAnyInBackground(aa.mUid, aa.mPackageName)) { + if (active == null) { + active = new ArrayList<>(); + } + if (DEBUG_FOREGROUND_SERVICE) Slog.d(TAG, "Adding active: pkg=" + + aa.mPackageName + ", uid=" + aa.mUid); + active.add(aa); + } else { + if (DEBUG_FOREGROUND_SERVICE) { + Slog.d(TAG, "bg-restricted app " + + aa.mPackageName + "/" + aa.mUid + + " exiting top; demoting fg services "); + } + stopAllForegroundServicesLocked(aa.mUid, aa.mPackageName); } - if (DEBUG_FOREGROUND_SERVICE) Slog.d(TAG, "Adding active: pkg=" - + aa.mPackageName + ", uid=" + aa.mUid); - active.add(aa); } } smap.removeMessages(ServiceMap.MSG_UPDATE_FOREGROUND_APPS); -- cgit v1.2.3