From 458213839d86cd1b9b98e2c49329cb5e2e9eeabf Mon Sep 17 00:00:00 2001 From: Hui Yu Date: Sat, 22 Apr 2023 00:29:19 +0000 Subject: [PATCH] Allow background-restricted app to start FGS from alarm-clock. Check FGS start temp allowlist reasonCode, with REASON_ALARM_MANAGER_ALARM_CLOCK, the FGS can start even the app is background-restricted (With other reasonCode, FGS can not start if the app is background-restricted). With REASON_ALARM_MANAGER_ALARM_CLOCK, after FGS is started, if the app is changed to background-restricted, the FGS can keep running (With other reasonCode, FGS will be stopped if the app is changed to background-restricted). Bug: 279233038 Test: atest cts/tests/app/src/android/app/cts/ActivityManagerFgsBgStartTest.java#testTempAllowListReasonCodeAlarmClock atest cts/tests/app/src/android/app/cts/ActivityManagerFgsBgStartTest.java#testAlarmClockFgsNotStoppedByBackgroundRestricted Change-Id: I909b15ba93735ff06787efc9c1e40c1c033a41ab --- .../com/android/server/am/ActiveServices.java | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index df3c95bdfaf3b..5f10d96a7644b 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -52,6 +52,7 @@ import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVI import static android.os.PowerExemptionManager.REASON_ACTIVE_DEVICE_ADMIN; import static android.os.PowerExemptionManager.REASON_ACTIVITY_STARTER; import static android.os.PowerExemptionManager.REASON_ACTIVITY_VISIBILITY_GRACE_PERIOD; +import static android.os.PowerExemptionManager.REASON_ALARM_MANAGER_ALARM_CLOCK; import static android.os.PowerExemptionManager.REASON_ALLOWLISTED_PACKAGE; import static android.os.PowerExemptionManager.REASON_BACKGROUND_ACTIVITY_PERMISSION; import static android.os.PowerExemptionManager.REASON_BACKGROUND_FGS_PERMISSION; @@ -458,11 +459,12 @@ public final class ActiveServices { public void updateBackgroundRestrictedForUidPackage(int uid, String packageName, boolean restricted) { synchronized (mAm) { - if (!isForegroundServiceAllowedInBackgroundRestricted(uid, packageName)) { - stopAllForegroundServicesLocked(uid, packageName); - } mAm.mProcessList.updateBackgroundRestrictedForUidPackageLocked( uid, packageName, restricted); + if (!isForegroundServiceAllowedInBackgroundRestricted(uid, packageName) + && !isTempAllowedByAlarmClock(uid)) { + stopAllForegroundServicesLocked(uid, packageName); + } } } } @@ -475,7 +477,11 @@ public final class ActiveServices { final ServiceRecord r = smap.mServicesByInstanceName.valueAt(i); if (uid == r.serviceInfo.applicationInfo.uid || packageName.equals(r.serviceInfo.packageName)) { - if (r.isForeground) { + // If the FGS is started by temp allowlist of alarm-clock + // (REASON_ALARM_MANAGER_ALARM_CLOCK), allow it to continue and do not stop it, + // even the app is background-restricted. + if (r.isForeground + && r.mAllowStartForegroundAtEntering != REASON_ALARM_MANAGER_ALARM_CLOCK) { toStop.add(r); } } @@ -860,7 +866,9 @@ public final class ActiveServices { // start analogously to the legacy-app forced-restrictions case, regardless // of its target SDK version. boolean forcedStandby = false; - if (bgLaunch && appRestrictedAnyInBackground(appUid, appPackageName)) { + if (bgLaunch + && appRestrictedAnyInBackground(appUid, appPackageName) + && !isTempAllowedByAlarmClock(appUid)) { if (DEBUG_FOREGROUND_SERVICE) { Slog.d(TAG, "Forcing bg-only service start only for " + r.shortInstanceName + " : bgLaunch=" + bgLaunch + " callerFg=" + callerFg); @@ -1918,6 +1926,20 @@ public final class ActiveServices { && isForegroundServiceAllowedInBackgroundRestricted(app); } + /* + * If the FGS start is temp allowlisted by alarm-clock(REASON_ALARM_MANAGER_ALARM_CLOCK), it is + * allowed even the app is background-restricted. + */ + private boolean isTempAllowedByAlarmClock(int uid) { + final ActivityManagerService.FgsTempAllowListItem item = + mAm.isAllowlistedForFgsStartLOSP(uid); + if (item != null) { + return item.mReasonCode == REASON_ALARM_MANAGER_ALARM_CLOCK; + } else { + return false; + } + } + void logFgsApiBeginLocked(int uid, int pid, int apiType) { synchronized (mFGSLogger) { mFGSLogger.logForegroundServiceApiEventBegin(uid, pid, apiType, ""); @@ -2050,7 +2072,8 @@ public final class ActiveServices { // 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 - && !isForegroundServiceAllowedInBackgroundRestricted(r.app)) { + && !isForegroundServiceAllowedInBackgroundRestricted(r.app) + && !isTempAllowedByAlarmClock(r.app.uid)) { Slog.w(TAG, "Service.startForeground() not allowed due to bg restriction: service " + r.shortInstanceName);