Merge "Background startForeground() improvement." into sc-dev
This commit is contained in:
@@ -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 "
|
||||
@@ -1843,6 +1881,7 @@ public final class ActiveServices {
|
||||
active.mNumActive++;
|
||||
}
|
||||
r.isForeground = true;
|
||||
r.mStartForegroundCount++;
|
||||
if (!stopProcStatsOp) {
|
||||
ServiceState stracker = r.getTracker();
|
||||
if (stracker != null) {
|
||||
@@ -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(),
|
||||
@@ -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();
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
@@ -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.
|
||||
/**
|
||||
@@ -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(',');
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user