Loading services/core/java/com/android/server/am/ActiveServices.java +52 −0 Original line number Diff line number Diff line Loading @@ -1790,6 +1790,44 @@ public final class ActiveServices { } if (!ignoreForeground) { if (r.mStartForegroundCount == 0) { /* If the service was started with startService(), not startForegroundService(), and if startForeground() isn't called within mFgsStartForegroundTimeoutMs, then we check the state of the app (who owns the service, which is the app that called startForeground()) again. If the app is in the foreground, or in any other cases where FGS-starts are allowed, then we still allow the FGS to be started. Otherwise, startForeground() would fail. If the service was started with startForegroundService(), then the service must call startForeground() within a timeout anyway, so we don't need this check. */ if (!r.fgRequired) { final long delayMs = SystemClock.elapsedRealtime() - r.createRealTime; if (delayMs > mAm.mConstants.mFgsStartForegroundTimeoutMs) { setFgsRestrictionLocked(r.serviceInfo.packageName, r.app.getPid(), r.appInfo.uid, r.intent.getIntent(), r, false); final String temp = "startForegroundDelayMs:" + delayMs; if (r.mInfoAllowStartForeground != null) { r.mInfoAllowStartForeground += "; " + temp; } else { r.mInfoAllowStartForeground = temp; } r.mLoggedInfoAllowStartForeground = false; } } } else if (r.mStartForegroundCount >= 1) { // The second or later time startForeground() is called after service is // started. Check for app state again. final long delayMs = SystemClock.elapsedRealtime() - r.mLastSetFgsRestrictionTime; if (delayMs > mAm.mConstants.mFgsStartForegroundTimeoutMs) { setFgsRestrictionLocked(r.serviceInfo.packageName, r.app.getPid(), r.appInfo.uid, r.intent.getIntent(), r, false); } } logFgsBackgroundStart(r); if (r.mAllowStartForeground == REASON_DENIED && isBgFgsRestrictionEnabled(r)) { final String msg = "Service.startForeground() not allowed due to " Loading Loading @@ -1843,6 +1881,7 @@ public final class ActiveServices { active.mNumActive++; } r.isForeground = true; r.mStartForegroundCount++; if (!stopProcStatsOp) { ServiceState stracker = r.getTracker(); if (stracker != null) { Loading Loading @@ -1901,6 +1940,7 @@ public final class ActiveServices { decActiveForegroundAppLocked(smap, r); } r.isForeground = false; resetFgsRestrictionLocked(r); ServiceState stracker = r.getTracker(); if (stracker != null) { stracker.setForeground(false, mAm.mProcessStats.getMemFactorLocked(), Loading Loading @@ -3892,6 +3932,7 @@ public final class ActiveServices { r.foregroundId = 0; r.foregroundNoti = null; r.mAllowWhileInUsePermissionInFgs = false; r.mAllowStartForeground = REASON_DENIED; // Clear start entries. r.clearDeliveredStartsLocked(); Loading Loading @@ -5430,6 +5471,7 @@ public final class ActiveServices { private void setFgsRestrictionLocked(String callingPackage, int callingPid, int callingUid, Intent intent, ServiceRecord r, boolean allowBackgroundActivityStarts) { r.mLastSetFgsRestrictionTime = SystemClock.elapsedRealtime(); // Check DeviceConfig flag. if (!mAm.mConstants.mFlagBackgroundFgsStartRestrictionEnabled) { r.mAllowWhileInUsePermissionInFgs = true; Loading @@ -5450,6 +5492,15 @@ public final class ActiveServices { } } void resetFgsRestrictionLocked(ServiceRecord r) { r.mAllowWhileInUsePermissionInFgs = false; r.mAllowStartForeground = REASON_DENIED; r.mInfoAllowStartForeground = null; r.mInfoTempFgsAllowListReason = null; r.mLoggedInfoAllowStartForeground = false; r.mLastSetFgsRestrictionTime = 0; } boolean canStartForegroundServiceLocked(int callingPid, int callingUid, String callingPackage) { if (!mAm.mConstants.mFlagBackgroundFgsStartRestrictionEnabled) { return true; Loading Loading @@ -5601,6 +5652,7 @@ public final class ActiveServices { + ",callingUid:" + tempAllowListReason.mCallingUid)) + ">" + "; targetSdkVersion:" + r.appInfo.targetSdkVersion + "; startForegroundCount:" + r.mStartForegroundCount + "]"; if (!debugInfo.equals(r.mInfoAllowStartForeground)) { r.mLoggedInfoAllowStartForeground = false; Loading services/core/java/com/android/server/am/ActivityManagerConstants.java +20 −1 Original line number Diff line number Diff line Loading @@ -96,6 +96,7 @@ final class ActivityManagerConstants extends ContentObserver { static final String KEY_PROCESS_CRASH_COUNT_LIMIT = "process_crash_count_limit"; static final String KEY_BOOT_TIME_TEMP_ALLOWLIST_DURATION = "boot_time_temp_allowlist_duration"; static final String KEY_FG_TO_BG_FGS_GRACE_DURATION = "fg_to_bg_fgs_grace_duration"; static final String KEY_FGS_START_FOREGROUND_TIMEOUT = "fgs_start_foreground_timeout"; private static final int DEFAULT_MAX_CACHED_PROCESSES = 32; private static final long DEFAULT_BACKGROUND_SETTLE_TIME = 60*1000; Loading Loading @@ -135,7 +136,7 @@ final class ActivityManagerConstants extends ContentObserver { private static final int DEFAULT_PROCESS_CRASH_COUNT_LIMIT = 12; private static final int DEFAULT_BOOT_TIME_TEMP_ALLOWLIST_DURATION = 10 * 1000; private static final long DEFAULT_FG_TO_BG_FGS_GRACE_DURATION = 5 * 1000; private static final int DEFAULT_FGS_START_FOREGROUND_TIMEOUT_MS = 10 * 1000; // Flag stored in the DeviceConfig API. /** Loading Loading @@ -396,6 +397,12 @@ final class ActivityManagerConstants extends ContentObserver { */ volatile long mFgToBgFgsGraceDuration = DEFAULT_FG_TO_BG_FGS_GRACE_DURATION; /** * When service started from background, before the timeout it can be promoted to FGS by calling * Service.startForeground(). */ volatile long mFgsStartForegroundTimeoutMs = DEFAULT_FGS_START_FOREGROUND_TIMEOUT_MS; private final ActivityManagerService mService; private ContentResolver mResolver; private final KeyValueListParser mParser = new KeyValueListParser(','); Loading Loading @@ -586,6 +593,9 @@ final class ActivityManagerConstants extends ContentObserver { case KEY_FG_TO_BG_FGS_GRACE_DURATION: updateFgToBgFgsGraceDuration(); break; case KEY_FGS_START_FOREGROUND_TIMEOUT: updateFgsStartForegroundTimeout(); break; default: break; } Loading Loading @@ -869,6 +879,13 @@ final class ActivityManagerConstants extends ContentObserver { DEFAULT_FG_TO_BG_FGS_GRACE_DURATION); } private void updateFgsStartForegroundTimeout() { mFgsStartForegroundTimeoutMs = DeviceConfig.getLong( DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, KEY_FGS_START_FOREGROUND_TIMEOUT, DEFAULT_FGS_START_FOREGROUND_TIMEOUT_MS); } private void updateImperceptibleKillExemptions() { IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.clear(); IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.addAll(mDefaultImperceptibleKillExemptPackages); Loading Loading @@ -1071,6 +1088,8 @@ final class ActivityManagerConstants extends ContentObserver { pw.println(mBootTimeTempAllowlistDuration); pw.print(" "); pw.print(KEY_FG_TO_BG_FGS_GRACE_DURATION); pw.print("="); pw.println(mFgToBgFgsGraceDuration); pw.print(" "); pw.print(KEY_FGS_START_FOREGROUND_TIMEOUT); pw.print("="); pw.println(mFgsStartForegroundTimeoutMs); pw.println(); if (mOverrideMaxCachedProcesses >= 0) { Loading services/core/java/com/android/server/am/ServiceRecord.java +9 −0 Original line number Diff line number Diff line Loading @@ -165,9 +165,16 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN // allow the service becomes foreground service? Service started from background may not be // allowed to become a foreground service. @PowerWhitelistManager.ReasonCode int mAllowStartForeground = REASON_DENIED; // Debug info why mAllowStartForeground is allowed or denied. String mInfoAllowStartForeground; // Debug info if mAllowStartForeground is allowed because of a temp-allowlist. FgsStartTempAllowList.TempFgsAllowListEntry mInfoTempFgsAllowListReason; // Is the same mInfoAllowStartForeground string has been logged before? Used for dedup. boolean mLoggedInfoAllowStartForeground; // The number of times Service.startForeground() is called; int mStartForegroundCount; // Last time mAllowWhileInUsePermissionInFgs or mAllowStartForeground is set. long mLastSetFgsRestrictionTime; String stringName; // caching of toString Loading Loading @@ -439,6 +446,8 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN pw.println(mRecentCallingUid); pw.print(prefix); pw.print("allowStartForeground="); pw.println(mAllowStartForeground); pw.print(prefix); pw.print("startForegroundCount="); pw.println(mStartForegroundCount); pw.print(prefix); pw.print("infoAllowStartForeground="); pw.println(mInfoAllowStartForeground); if (delayed) { Loading Loading
services/core/java/com/android/server/am/ActiveServices.java +52 −0 Original line number Diff line number Diff line Loading @@ -1790,6 +1790,44 @@ public final class ActiveServices { } if (!ignoreForeground) { if (r.mStartForegroundCount == 0) { /* If the service was started with startService(), not startForegroundService(), and if startForeground() isn't called within mFgsStartForegroundTimeoutMs, then we check the state of the app (who owns the service, which is the app that called startForeground()) again. If the app is in the foreground, or in any other cases where FGS-starts are allowed, then we still allow the FGS to be started. Otherwise, startForeground() would fail. If the service was started with startForegroundService(), then the service must call startForeground() within a timeout anyway, so we don't need this check. */ if (!r.fgRequired) { final long delayMs = SystemClock.elapsedRealtime() - r.createRealTime; if (delayMs > mAm.mConstants.mFgsStartForegroundTimeoutMs) { setFgsRestrictionLocked(r.serviceInfo.packageName, r.app.getPid(), r.appInfo.uid, r.intent.getIntent(), r, false); final String temp = "startForegroundDelayMs:" + delayMs; if (r.mInfoAllowStartForeground != null) { r.mInfoAllowStartForeground += "; " + temp; } else { r.mInfoAllowStartForeground = temp; } r.mLoggedInfoAllowStartForeground = false; } } } else if (r.mStartForegroundCount >= 1) { // The second or later time startForeground() is called after service is // started. Check for app state again. final long delayMs = SystemClock.elapsedRealtime() - r.mLastSetFgsRestrictionTime; if (delayMs > mAm.mConstants.mFgsStartForegroundTimeoutMs) { setFgsRestrictionLocked(r.serviceInfo.packageName, r.app.getPid(), r.appInfo.uid, r.intent.getIntent(), r, false); } } logFgsBackgroundStart(r); if (r.mAllowStartForeground == REASON_DENIED && isBgFgsRestrictionEnabled(r)) { final String msg = "Service.startForeground() not allowed due to " Loading Loading @@ -1843,6 +1881,7 @@ public final class ActiveServices { active.mNumActive++; } r.isForeground = true; r.mStartForegroundCount++; if (!stopProcStatsOp) { ServiceState stracker = r.getTracker(); if (stracker != null) { Loading Loading @@ -1901,6 +1940,7 @@ public final class ActiveServices { decActiveForegroundAppLocked(smap, r); } r.isForeground = false; resetFgsRestrictionLocked(r); ServiceState stracker = r.getTracker(); if (stracker != null) { stracker.setForeground(false, mAm.mProcessStats.getMemFactorLocked(), Loading Loading @@ -3892,6 +3932,7 @@ public final class ActiveServices { r.foregroundId = 0; r.foregroundNoti = null; r.mAllowWhileInUsePermissionInFgs = false; r.mAllowStartForeground = REASON_DENIED; // Clear start entries. r.clearDeliveredStartsLocked(); Loading Loading @@ -5430,6 +5471,7 @@ public final class ActiveServices { private void setFgsRestrictionLocked(String callingPackage, int callingPid, int callingUid, Intent intent, ServiceRecord r, boolean allowBackgroundActivityStarts) { r.mLastSetFgsRestrictionTime = SystemClock.elapsedRealtime(); // Check DeviceConfig flag. if (!mAm.mConstants.mFlagBackgroundFgsStartRestrictionEnabled) { r.mAllowWhileInUsePermissionInFgs = true; Loading @@ -5450,6 +5492,15 @@ public final class ActiveServices { } } void resetFgsRestrictionLocked(ServiceRecord r) { r.mAllowWhileInUsePermissionInFgs = false; r.mAllowStartForeground = REASON_DENIED; r.mInfoAllowStartForeground = null; r.mInfoTempFgsAllowListReason = null; r.mLoggedInfoAllowStartForeground = false; r.mLastSetFgsRestrictionTime = 0; } boolean canStartForegroundServiceLocked(int callingPid, int callingUid, String callingPackage) { if (!mAm.mConstants.mFlagBackgroundFgsStartRestrictionEnabled) { return true; Loading Loading @@ -5601,6 +5652,7 @@ public final class ActiveServices { + ",callingUid:" + tempAllowListReason.mCallingUid)) + ">" + "; targetSdkVersion:" + r.appInfo.targetSdkVersion + "; startForegroundCount:" + r.mStartForegroundCount + "]"; if (!debugInfo.equals(r.mInfoAllowStartForeground)) { r.mLoggedInfoAllowStartForeground = false; Loading
services/core/java/com/android/server/am/ActivityManagerConstants.java +20 −1 Original line number Diff line number Diff line Loading @@ -96,6 +96,7 @@ final class ActivityManagerConstants extends ContentObserver { static final String KEY_PROCESS_CRASH_COUNT_LIMIT = "process_crash_count_limit"; static final String KEY_BOOT_TIME_TEMP_ALLOWLIST_DURATION = "boot_time_temp_allowlist_duration"; static final String KEY_FG_TO_BG_FGS_GRACE_DURATION = "fg_to_bg_fgs_grace_duration"; static final String KEY_FGS_START_FOREGROUND_TIMEOUT = "fgs_start_foreground_timeout"; private static final int DEFAULT_MAX_CACHED_PROCESSES = 32; private static final long DEFAULT_BACKGROUND_SETTLE_TIME = 60*1000; Loading Loading @@ -135,7 +136,7 @@ final class ActivityManagerConstants extends ContentObserver { private static final int DEFAULT_PROCESS_CRASH_COUNT_LIMIT = 12; private static final int DEFAULT_BOOT_TIME_TEMP_ALLOWLIST_DURATION = 10 * 1000; private static final long DEFAULT_FG_TO_BG_FGS_GRACE_DURATION = 5 * 1000; private static final int DEFAULT_FGS_START_FOREGROUND_TIMEOUT_MS = 10 * 1000; // Flag stored in the DeviceConfig API. /** Loading Loading @@ -396,6 +397,12 @@ final class ActivityManagerConstants extends ContentObserver { */ volatile long mFgToBgFgsGraceDuration = DEFAULT_FG_TO_BG_FGS_GRACE_DURATION; /** * When service started from background, before the timeout it can be promoted to FGS by calling * Service.startForeground(). */ volatile long mFgsStartForegroundTimeoutMs = DEFAULT_FGS_START_FOREGROUND_TIMEOUT_MS; private final ActivityManagerService mService; private ContentResolver mResolver; private final KeyValueListParser mParser = new KeyValueListParser(','); Loading Loading @@ -586,6 +593,9 @@ final class ActivityManagerConstants extends ContentObserver { case KEY_FG_TO_BG_FGS_GRACE_DURATION: updateFgToBgFgsGraceDuration(); break; case KEY_FGS_START_FOREGROUND_TIMEOUT: updateFgsStartForegroundTimeout(); break; default: break; } Loading Loading @@ -869,6 +879,13 @@ final class ActivityManagerConstants extends ContentObserver { DEFAULT_FG_TO_BG_FGS_GRACE_DURATION); } private void updateFgsStartForegroundTimeout() { mFgsStartForegroundTimeoutMs = DeviceConfig.getLong( DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, KEY_FGS_START_FOREGROUND_TIMEOUT, DEFAULT_FGS_START_FOREGROUND_TIMEOUT_MS); } private void updateImperceptibleKillExemptions() { IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.clear(); IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.addAll(mDefaultImperceptibleKillExemptPackages); Loading Loading @@ -1071,6 +1088,8 @@ final class ActivityManagerConstants extends ContentObserver { pw.println(mBootTimeTempAllowlistDuration); pw.print(" "); pw.print(KEY_FG_TO_BG_FGS_GRACE_DURATION); pw.print("="); pw.println(mFgToBgFgsGraceDuration); pw.print(" "); pw.print(KEY_FGS_START_FOREGROUND_TIMEOUT); pw.print("="); pw.println(mFgsStartForegroundTimeoutMs); pw.println(); if (mOverrideMaxCachedProcesses >= 0) { Loading
services/core/java/com/android/server/am/ServiceRecord.java +9 −0 Original line number Diff line number Diff line Loading @@ -165,9 +165,16 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN // allow the service becomes foreground service? Service started from background may not be // allowed to become a foreground service. @PowerWhitelistManager.ReasonCode int mAllowStartForeground = REASON_DENIED; // Debug info why mAllowStartForeground is allowed or denied. String mInfoAllowStartForeground; // Debug info if mAllowStartForeground is allowed because of a temp-allowlist. FgsStartTempAllowList.TempFgsAllowListEntry mInfoTempFgsAllowListReason; // Is the same mInfoAllowStartForeground string has been logged before? Used for dedup. boolean mLoggedInfoAllowStartForeground; // The number of times Service.startForeground() is called; int mStartForegroundCount; // Last time mAllowWhileInUsePermissionInFgs or mAllowStartForeground is set. long mLastSetFgsRestrictionTime; String stringName; // caching of toString Loading Loading @@ -439,6 +446,8 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN pw.println(mRecentCallingUid); pw.print(prefix); pw.print("allowStartForeground="); pw.println(mAllowStartForeground); pw.print(prefix); pw.print("startForegroundCount="); pw.println(mStartForegroundCount); pw.print(prefix); pw.print("infoAllowStartForeground="); pw.println(mInfoAllowStartForeground); if (delayed) { Loading