From 6aab623ad82439125fbd2ac96c07153f1d8d6710 Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Tue, 23 Apr 2019 11:13:35 -0700 Subject: Top apps may start fg services even when under bg restriction We now apply bg restriction policy (appop) on being able to enter a foreground service lifecycle only when the app is not in a "top" i.e. directly user-facing state. This avoids breaking existing supported lifecycle guarantees involving the order of calls to startService(), startForeground(), and startForegroundService(). Briefly: there is a designed behavior in the following sequence: 1. startService(intent); 2. startForeground() on that service; then 3. startForegroundService(intent) The intentional behavior is that after step 3, the app is not required to call startForeground() *again,* redundantly; because that service is already in a fg lifecycle. However, new-in-Q code broke this pattern in the case where the user had imposed bg service restrictions on the app. For this and for semantic/model reasons, we now do not apply fg service start restrictions to the user-facing app, even if the at app is under bg execution restrictions. The app is not background at that time, so should not be expected to face a different execution environment. Bug: 130048629 Test: Foreground use of GPM under bg restrictions Change-Id: I0e8c308ac26211082a90c165a64d66b31ab804df --- .../java/com/android/server/am/ActiveServices.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 24f8fc26ae22..76136dfc81a0 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -828,6 +828,13 @@ public final class ActiveServices { sb.append(compName); Slog.w(TAG, sb.toString()); stopping.add(service); + + // If the app is under bg restrictions, also make sure that + // any notification is dismissed + if (appRestrictedAnyInBackground( + service.appInfo.uid, service.packageName)) { + cancelForegroundNotificationLocked(service); + } } } } @@ -1232,6 +1239,10 @@ public final class ActiveServices { } } + private boolean appIsTopLocked(int uid) { + return mAm.getUidState(uid) <= ActivityManager.PROCESS_STATE_TOP; + } + /** * @param id Notification ID. Zero === exit foreground state for the given service. */ @@ -1318,8 +1329,11 @@ public final class ActiveServices { throw new SecurityException("Foreground not allowed as per app op"); } - if (!ignoreForeground && - appRestrictedAnyInBackground(r.appInfo.uid, r.packageName)) { + // Apps that are TOP or effectively similar may call startForeground() on + // their services even if they are restricted from doing that while in bg. + if (!ignoreForeground + && !appIsTopLocked(r.appInfo.uid) + && appRestrictedAnyInBackground(r.appInfo.uid, r.packageName)) { Slog.w(TAG, "Service.startForeground() not allowed due to bg restriction: service " + r.shortInstanceName); -- cgit v1.2.3-59-g8ed1b