Merge "Remove the tentative FGS logic" into udc-dev

This commit is contained in:
Makoto Onuki
2023-05-30 20:42:57 +00:00
committed by Android (Google) Code Review
3 changed files with 7 additions and 231 deletions

View File

@@ -2156,7 +2156,6 @@ public final class ActiveServices {
}
}
final boolean enableFgsWhileInUseFix = mAm.mConstants.mEnableFgsWhileInUseFix;
final boolean fgsTypeChangingFromShortFgs = r.isForeground && isOldTypeShortFgs;
if (fgsTypeChangingFromShortFgs) {
@@ -2214,19 +2213,7 @@ public final class ActiveServices {
}
}
boolean resetNeededForLogging = false;
// Re-evaluate mAllowWhileInUsePermissionInFgs and mAllowStartForeground
// (i.e. while-in-use and BFSL flags) if needed.
//
// Consider the below if-else section to be in the else of the above
// `if (fgsTypeChangingFromShortFgs)`.
// Using an else would increase the indent further, so we don't use it here
// and instead just add !fgsTypeChangingFromShortFgs to all if's.
//
// The first if's are for the original while-in-use logic.
if (!fgsTypeChangingFromShortFgs && !enableFgsWhileInUseFix
&& r.mStartForegroundCount == 0) {
if (!fgsTypeChangingFromShortFgs && r.mStartForegroundCount == 0) {
/*
If the service was started with startService(), not
startForegroundService(), and if startForeground() isn't called within
@@ -2257,8 +2244,7 @@ public final class ActiveServices {
r.mLoggedInfoAllowStartForeground = false;
}
}
} else if (!fgsTypeChangingFromShortFgs && !enableFgsWhileInUseFix
&& r.mStartForegroundCount >= 1) {
} else if (!fgsTypeChangingFromShortFgs && r.mStartForegroundCount >= 1) {
// We get here if startForeground() is called multiple times
// on the same service after it's created, regardless of whether
// stopForeground() has been called or not.
@@ -2269,100 +2255,6 @@ public final class ActiveServices {
r.appInfo.uid, r.intent.getIntent(), r, r.userId,
BackgroundStartPrivileges.NONE,
false /* isBindService */, false /* isStartService */);
} else if (!fgsTypeChangingFromShortFgs && enableFgsWhileInUseFix) {
// The new while-in-use logic.
//
// When startForeground() is called, we _always_ call
// setFgsRestrictionLocked() to set the restrictions according to the
// current state of the app.
// (So if the app is now in TOP, for example, the service will now always
// get while-in-use permissions.)
//
// Note, setFgsRestrictionLocked() will never disallow
// mAllowWhileInUsePermissionInFgs nor mAllowStartForeground
// (i.e. while-in-use and BFSL flags) once they're set to "allowed".
//
// HOWEVER, if these flags were set to "allowed" in Context.startService()
// (as opposed to startForegroundService()), when the service wasn't yet
// a foreground service, then we may not always
// want to trust them -- for example, if the service has been running as a
// BG service or a bound service for a long time when the app is not longer
// in the foreground, then we shouldn't grant while-in-user nor BFSL.
// So in that case, we need to reset it first.
final long delayMs =
(r.mLastUntrustedSetFgsRestrictionAllowedTime == 0) ? 0
: (SystemClock.elapsedRealtime()
- r.mLastUntrustedSetFgsRestrictionAllowedTime);
final boolean resetNeeded =
!r.isForeground
&& delayMs > mAm.mConstants.mFgsStartForegroundTimeoutMs;
if (resetNeeded) {
// We don't want to reset mDebugWhileInUseReasonInBindService here --
// we'll instead reset it in the following code, using the simulated
// legacy logic.
resetFgsRestrictionLocked(r,
/*resetDebugWhileInUseReasonInBindService=*/ false);
}
// Simulate the reset flow in the legacy logic to reset
// mDebugWhileInUseReasonInBindService.
// (Which is only used to compare to the old logic.)
final long legacyDelayMs = SystemClock.elapsedRealtime() - r.createRealTime;
if ((r.mStartForegroundCount == 0)
&& (legacyDelayMs > mAm.mConstants.mFgsStartForegroundTimeoutMs)) {
r.mDebugWhileInUseReasonInBindService = REASON_DENIED;
}
setFgsRestrictionLocked(r.serviceInfo.packageName, r.app.getPid(),
r.appInfo.uid, r.intent.getIntent(), r, r.userId,
BackgroundStartPrivileges.NONE,
false /* isBindService */, false /* isStartService */);
final String temp = "startForegroundDelayMs:" + delayMs
+ "; started: " + r.startRequested
+ "; num_bindings: " + r.getConnections().size()
+ "; wasForeground: " + r.isForeground
+ "; resetNeeded:" + resetNeeded;
if (r.mInfoAllowStartForeground != null) {
r.mInfoAllowStartForeground += "; " + temp;
} else {
r.mInfoAllowStartForeground = temp;
}
r.mLoggedInfoAllowStartForeground = false;
resetNeededForLogging = resetNeeded;
}
// If the service has any bindings and it's not yet a FGS
// we compare the new and old while-in-use logics.
// (If it's not the first startForeground() call, we already reset the
// while-in-use and BFSL flags, so the logic change wouldn't matter.)
//
// Note, mDebugWhileInUseReasonInBindService does *not* fully simulate the
// legacy logic, because we'll only set it in bindService(), but the actual
// mAllowWhileInUsePermissionInFgsReason can change afterwards, in a subsequent
// Service.startForeground(). This check will only provide "rough" check.
// But if mDebugWhileInUseReasonInBindService is _not_ DENIED, and
// mDebugWhileInUseReasonInStartForeground _is_ DENIED, then that means we'd
// now detected a behavior change.
// OTOH, if it's changing from non-DENIED to another non-DENIED, that may
// not be a problem.
if (enableFgsWhileInUseFix
&& !r.isForeground
&& (r.getConnections().size() > 0)
&& (r.mDebugWhileInUseReasonInBindService
!= r.mDebugWhileInUseReasonInStartForeground)) {
logWhileInUseChangeWtf("FGS while-in-use changed (b/276963716): old="
+ reasonCodeToString(r.mDebugWhileInUseReasonInBindService)
+ " new="
+ reasonCodeToString(r.mDebugWhileInUseReasonInStartForeground)
+ " startForegroundCount=" + r.mStartForegroundCount
+ " started=" + r.startRequested
+ " num_bindings=" + r.getConnections().size()
+ " resetNeeded=" + resetNeededForLogging
+ " "
+ r.shortInstanceName);
}
// If the foreground service is not started from TOP process, do not allow it to
@@ -2471,10 +2363,6 @@ public final class ActiveServices {
}
r.isForeground = true;
// Once the service becomes a foreground service,
// the FGS restriction information always becomes "trustable".
r.mLastUntrustedSetFgsRestrictionAllowedTime = 0;
// The logging of FOREGROUND_SERVICE_STATE_CHANGED__STATE__ENTER event could
// be deferred, make a copy of mAllowStartForeground and
// mAllowWhileInUsePermissionInFgs.
@@ -2620,13 +2508,6 @@ public final class ActiveServices {
}
}
/**
* It just does a wtf, but extracted to a method, so we can do a signature search on pitot.
*/
private void logWhileInUseChangeWtf(String message) {
Slog.wtf(TAG, message);
}
private boolean withinFgsDeferRateLimit(ServiceRecord sr, final long now) {
// If we're still within the service's deferral period, then by definition
// deferral is not rate limited.
@@ -3839,25 +3720,9 @@ public final class ActiveServices {
return 0;
}
}
if (!mAm.mConstants.mEnableFgsWhileInUseFix) {
// Old while-in-use logic.
setFgsRestrictionLocked(callingPackage, callingPid, callingUid, service, s, userId,
BackgroundStartPrivileges.NONE, true /* isBindService */,
false /* isStartService */);
} else {
// New logic will not call setFgsRestrictionLocked() here, but we still
// keep track of the allow reason from the old logic here, so we can compare to
// the new logic.
// Once we're confident enough in the new logic, we should remove it.
if (s.mDebugWhileInUseReasonInBindService == REASON_DENIED) {
s.mDebugWhileInUseReasonInBindService =
shouldAllowFgsWhileInUsePermissionLocked(
callingPackage, callingPid, callingUid, s.app,
BackgroundStartPrivileges.NONE,
true /* isBindService */,
false /* DO NOT enableFgsWhileInUseFix; use the old logic */);
}
}
setFgsRestrictionLocked(callingPackage, callingPid, callingUid, service, s, userId,
BackgroundStartPrivileges.NONE, true /* isBindService */,
false /* isStartService */);
if (s.app != null) {
ProcessServiceRecord servicePsr = s.app.mServices;
@@ -7554,15 +7419,13 @@ public final class ActiveServices {
* @param r the service to start.
* @param isStartService True if it's called from Context.startService().
* False if it's called from Context.startForegroundService() or
* Service.startService().
* Service.startForeground().
* @return true if allow, false otherwise.
*/
private void setFgsRestrictionLocked(String callingPackage,
int callingPid, int callingUid, Intent intent, ServiceRecord r, int userId,
BackgroundStartPrivileges backgroundStartPrivileges, boolean isBindService,
boolean isStartService) {
final long now = SystemClock.elapsedRealtime();
// Check DeviceConfig flag.
if (!mAm.mConstants.mFlagBackgroundFgsStartRestrictionEnabled) {
r.mAllowWhileInUsePermissionInFgs = true;
@@ -7580,60 +7443,30 @@ public final class ActiveServices {
isBindService);
// We store them to compare the old and new while-in-use logics to each other.
// (They're not used for any other purposes.)
if (isBindService) {
r.mDebugWhileInUseReasonInBindService = allowWhileInUse;
} else {
r.mDebugWhileInUseReasonInStartForeground = allowWhileInUse;
}
if (!r.mAllowWhileInUsePermissionInFgs) {
r.mAllowWhileInUsePermissionInFgs = (allowWhileInUse != REASON_DENIED);
newlyAllowed |= r.mAllowWhileInUsePermissionInFgs;
}
if (r.mAllowStartForeground == REASON_DENIED) {
r.mAllowStartForeground = shouldAllowFgsStartForegroundWithBindingCheckLocked(
allowWhileInUse, callingPackage, callingPid, callingUid, intent, r,
backgroundStartPrivileges, isBindService);
newlyAllowed |= r.mAllowStartForeground != REASON_DENIED;
}
} else {
allowWhileInUse = REASON_UNKNOWN;
}
r.mAllowWhileInUsePermissionInFgsReason = allowWhileInUse;
if (isStartService && !r.isForeground && newlyAllowed) {
// If it's called by Context.startService() (not by startForegroundService()),
// and we're setting "allowed", then we can't fully trust it yet -- we'll need to reset
// the restrictions if startForeground() is called after the grace period.
r.mLastUntrustedSetFgsRestrictionAllowedTime = now;
}
}
/**
* Reset various while-in-use and BFSL related information.
*/
void resetFgsRestrictionLocked(ServiceRecord r) {
resetFgsRestrictionLocked(r, /*resetDebugWhileInUseReasonInBindService=*/ true);
}
/**
* Reset various while-in-use and BFSL related information.
*/
void resetFgsRestrictionLocked(ServiceRecord r,
boolean resetDebugWhileInUseReasonInBindService) {
r.mAllowWhileInUsePermissionInFgs = false;
r.mAllowWhileInUsePermissionInFgsReason = REASON_DENIED;
r.mDebugWhileInUseReasonInStartForeground = REASON_DENIED;
// In Service.startForeground(), we reset this field using a legacy logic,
// so resetting this field is optional.
if (resetDebugWhileInUseReasonInBindService) {
r.mDebugWhileInUseReasonInBindService = REASON_DENIED;
}
r.mAllowStartForeground = REASON_DENIED;
r.mInfoAllowStartForeground = null;
r.mInfoTempFgsAllowListReason = null;
r.mLoggedInfoAllowStartForeground = false;
r.mLastUntrustedSetFgsRestrictionAllowedTime = 0;
r.updateAllowUiJobScheduling(r.mAllowWhileInUsePermissionInFgs);
}
@@ -7668,22 +7501,11 @@ public final class ActiveServices {
private @ReasonCode int shouldAllowFgsWhileInUsePermissionLocked(String callingPackage,
int callingPid, int callingUid, @Nullable ProcessRecord targetProcess,
BackgroundStartPrivileges backgroundStartPrivileges, boolean isBindService) {
return shouldAllowFgsWhileInUsePermissionLocked(callingPackage,
callingPid, callingUid, targetProcess, backgroundStartPrivileges, isBindService,
/* enableFgsWhileInUseFix =*/ mAm.mConstants.mEnableFgsWhileInUseFix);
}
private @ReasonCode int shouldAllowFgsWhileInUsePermissionLocked(String callingPackage,
int callingPid, int callingUid, @Nullable ProcessRecord targetProcess,
BackgroundStartPrivileges backgroundStartPrivileges, boolean isBindService,
boolean enableFgsWhileInUseFix) {
int ret = REASON_DENIED;
// Define some local variables for better readability...
final boolean useOldLogic = !enableFgsWhileInUseFix;
final boolean forStartForeground = !isBindService;
if (useOldLogic || forStartForeground) {
if (forStartForeground) {
final int uidState = mAm.getUidStateLocked(callingUid);
if (ret == REASON_DENIED) {
// Allow FGS while-in-use if the caller's process state is PROCESS_STATE_PERSISTENT,
@@ -7733,10 +7555,6 @@ public final class ActiveServices {
}
}
if (enableFgsWhileInUseFix && ret == REASON_DENIED) {
ret = shouldAllowFgsWhileInUsePermissionByBindingsLocked(callingUid);
}
if (ret == REASON_DENIED) {
// Allow FGS while-in-use if the WindowManager allows background activity start.
// This is mainly to get the 10 seconds grace period if any activity in the caller has

View File

@@ -1058,13 +1058,6 @@ final class ActivityManagerConstants extends ContentObserver {
/** @see #KEY_USE_MODERN_TRIM */
public boolean USE_MODERN_TRIM = DEFAULT_USE_MODERN_TRIM;
private static final String KEY_ENABLE_FGS_WHILE_IN_USE_FIX =
"key_enable_fgs_while_in_use_fix";
private static final boolean DEFAULT_ENABLE_FGS_WHILE_IN_USE_FIX = false;
public volatile boolean mEnableFgsWhileInUseFix = DEFAULT_ENABLE_FGS_WHILE_IN_USE_FIX;
private final OnPropertiesChangedListener mOnDeviceConfigChangedListener =
new OnPropertiesChangedListener() {
@Override
@@ -1233,9 +1226,6 @@ final class ActivityManagerConstants extends ContentObserver {
case KEY_ENABLE_WAIT_FOR_FINISH_ATTACH_APPLICATION:
updateEnableWaitForFinishAttachApplication();
break;
case KEY_ENABLE_FGS_WHILE_IN_USE_FIX:
updateEnableFgsWhileInUseFix();
break;
case KEY_MAX_PREVIOUS_TIME:
updateMaxPreviousTime();
break;
@@ -2005,12 +1995,6 @@ final class ActivityManagerConstants extends ContentObserver {
DEFAULT_ENABLE_WAIT_FOR_FINISH_ATTACH_APPLICATION);
}
private void updateEnableFgsWhileInUseFix() {
mEnableFgsWhileInUseFix = DeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
KEY_ENABLE_FGS_WHILE_IN_USE_FIX,
DEFAULT_ENABLE_FGS_WHILE_IN_USE_FIX);
}
private void updateUseTieredCachedAdj() {
USE_TIERED_CACHED_ADJ = DeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
@@ -2211,9 +2195,6 @@ final class ActivityManagerConstants extends ContentObserver {
pw.print(" "); pw.print(KEY_SYSTEM_EXEMPT_POWER_RESTRICTIONS_ENABLED);
pw.print("="); pw.println(mFlagSystemExemptPowerRestrictionsEnabled);
pw.print(" "); pw.print(KEY_ENABLE_FGS_WHILE_IN_USE_FIX);
pw.print("="); pw.println(mEnableFgsWhileInUseFix);
pw.print(" "); pw.print(KEY_SHORT_FGS_TIMEOUT_DURATION);
pw.print("="); pw.println(mShortFgsTimeoutDuration);
pw.print(" "); pw.print(KEY_SHORT_FGS_PROC_STATE_EXTRA_WAIT_DURATION);

View File

@@ -177,12 +177,6 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
@PowerExemptionManager.ReasonCode
int mAllowWhileInUsePermissionInFgsReason = REASON_DENIED;
// Integer version of mAllowWhileInUsePermissionInFgs that we keep track to compare
// the old and new logics.
// TODO: Remove them once we're confident in the new logic.
int mDebugWhileInUseReasonInStartForeground = REASON_DENIED;
int mDebugWhileInUseReasonInBindService = REASON_DENIED;
// A copy of mAllowWhileInUsePermissionInFgs's value when the service is entering FGS state.
boolean mAllowWhileInUsePermissionInFgsAtEntering;
/** Allow scheduling user-initiated jobs from the background. */
@@ -224,13 +218,6 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
// is called.
int mStartForegroundCount;
// Last time mAllowWhileInUsePermissionInFgs or mAllowStartForeground was set to "allowed"
// from "disallowed" when the service was _not_ already a foreground service.
// this means they're set in startService(). (not startForegroundService)
// In startForeground(), if this timestamp is too old, we can't trust these flags, so
// we need to reset them.
long mLastUntrustedSetFgsRestrictionAllowedTime;
// This is a service record of a FGS delegate (not a service record of a real service)
boolean mIsFgsDelegate;
@Nullable ForegroundServiceDelegation mFgsDelegation;
@@ -624,12 +611,6 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
pw.print(prefix); pw.print("mAllowWhileInUsePermissionInFgsReason=");
pw.println(PowerExemptionManager.reasonCodeToString(mAllowWhileInUsePermissionInFgsReason));
pw.print(prefix); pw.print("debugWhileInUseReasonInStartForeground=");
pw.println(PowerExemptionManager.reasonCodeToString(
mDebugWhileInUseReasonInStartForeground));
pw.print(prefix); pw.print("debugWhileInUseReasonInBindService=");
pw.println(PowerExemptionManager.reasonCodeToString(mDebugWhileInUseReasonInBindService));
pw.print(prefix); pw.print("allowUiJobScheduling="); pw.println(mAllowUiJobScheduling);
pw.print(prefix); pw.print("recentCallingPackage=");
pw.println(mRecentCallingPackage);
@@ -642,10 +623,6 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
pw.print(prefix); pw.print("infoAllowStartForeground=");
pw.println(mInfoAllowStartForeground);
pw.print(prefix); pw.print("lastUntrustedSetFgsRestrictionAllowedTime=");
TimeUtils.formatDuration(mLastUntrustedSetFgsRestrictionAllowedTime, now, pw);
pw.println();
if (delayed) {
pw.print(prefix); pw.print("delayed="); pw.println(delayed);
}