Always allow startForeground(SHORT_SERVICE) on running short FGS

- Previously, call to `startForeground(SHORT_SERVICE)` to an already
running short FGS was only allowed when the app was in a BFSL-allowed
situation.

- Now, this call is always allowed. However, we extend the short FGS
timeout, only when the app is in a BFSL-allowed situation.

Fix: 269369028
Bug: 257270313
Test: Manually tested with a test app, but with the ACTIVITY_STARTER
  BFSL check disabled. It seems like ToT udc-dev has a bug where it's
  triggered for BG activities too.
Test: atest CtsShortFgsTestCases
Change-Id: Ife0527236ab5ccbc55c7a7759251fa4a16664297
This commit is contained in:
Makoto Onuki
2023-02-22 10:23:26 -08:00
parent 17028b3d45
commit de7e4588e3

View File

@@ -2029,6 +2029,9 @@ public final class ActiveServices {
foregroundServiceType == FOREGROUND_SERVICE_TYPE_SHORT_SERVICE;
final boolean isOldTypeShortFgsAndTimedOut = r.shouldTriggerShortFgsTimeout();
// If true, we skip the BFSL check.
boolean bypassBfslCheck = false;
if (r.isForeground && (isOldTypeShortFgs || isNewTypeShortFgs)) {
if (DEBUG_SHORT_SERVICE) {
Slog.i(TAG_SERVICE, String.format(
@@ -2059,9 +2062,6 @@ public final class ActiveServices {
if (isNewTypeShortFgs) {
// Only in this case, we extend the SHORT_SERVICE time out.
extendShortServiceTimeout = true;
if (DEBUG_SHORT_SERVICE) {
Slog.i(TAG_SERVICE, "Extending SHORT_SERVICE time out: " + r);
}
} else {
// FGS type is changing from SHORT_SERVICE to another type when
// an app is allowed to start FGS, so this will succeed.
@@ -2069,8 +2069,20 @@ public final class ActiveServices {
// maybeUpdateShortFgsTrackingLocked().
}
} else {
// We catch this case later, in the
// "if (r.mAllowStartForeground == REASON_DENIED...)" block below.
if (isNewTypeShortFgs) {
// startForeground(SHORT_SERVICE) is called on an already running
// SHORT_SERVICE FGS, when BFSL is not allowed.
// In this case, the call should succeed
// (== ForegroundServiceStartNotAllowedException shouldn't be
// thrown), but the short service timeout shouldn't extend
// (== extendShortServiceTimeout should be false).
// We still do everything else -- e.g. we still need to update
// the notification.
bypassBfslCheck = true;
} else {
// We catch this case later, in the
// "if (r.mAllowStartForeground == REASON_DENIED...)" block below.
}
}
} else if (r.mStartForegroundCount == 0) {
@@ -2125,23 +2137,25 @@ public final class ActiveServices {
+ "location/camera/microphone access: service "
+ r.shortInstanceName);
}
logFgsBackgroundStart(r);
if (r.mAllowStartForeground == REASON_DENIED
&& isBgFgsRestrictionEnabledForService) {
final String msg = "Service.startForeground() not allowed due to "
+ "mAllowStartForeground false: service "
+ r.shortInstanceName
+ (isOldTypeShortFgs ? " (Called on SHORT_SERVICE)" : "");
Slog.w(TAG, msg);
showFgsBgRestrictedNotificationLocked(r);
updateServiceForegroundLocked(psr, true);
ignoreForeground = true;
logFGSStateChangeLocked(r,
FOREGROUND_SERVICE_STATE_CHANGED__STATE__DENIED,
0, FGS_STOP_REASON_UNKNOWN, FGS_TYPE_POLICY_CHECK_UNKNOWN);
if (CompatChanges.isChangeEnabled(FGS_START_EXCEPTION_CHANGE_ID,
r.appInfo.uid)) {
throw new ForegroundServiceStartNotAllowedException(msg);
if (!bypassBfslCheck) {
logFgsBackgroundStart(r);
if (r.mAllowStartForeground == REASON_DENIED
&& isBgFgsRestrictionEnabledForService) {
final String msg = "Service.startForeground() not allowed due to "
+ "mAllowStartForeground false: service "
+ r.shortInstanceName
+ (isOldTypeShortFgs ? " (Called on SHORT_SERVICE)" : "");
Slog.w(TAG, msg);
showFgsBgRestrictedNotificationLocked(r);
updateServiceForegroundLocked(psr, true);
ignoreForeground = true;
logFGSStateChangeLocked(r,
FOREGROUND_SERVICE_STATE_CHANGED__STATE__DENIED,
0, FGS_STOP_REASON_UNKNOWN, FGS_TYPE_POLICY_CHECK_UNKNOWN);
if (CompatChanges.isChangeEnabled(FGS_START_EXCEPTION_CHANGE_ID,
r.appInfo.uid)) {
throw new ForegroundServiceStartNotAllowedException(msg);
}
}
}
@@ -3084,11 +3098,17 @@ public final class ActiveServices {
unscheduleShortFgsTimeoutLocked(sr);
return;
}
if (DEBUG_SHORT_SERVICE) {
Slog.i(TAG_SERVICE, "Short FGS started: " + sr);
}
if (extendTimeout || !sr.hasShortFgsInfo()) {
final boolean isAlreadyShortFgs = sr.hasShortFgsInfo();
if (extendTimeout || !isAlreadyShortFgs) {
if (DEBUG_SHORT_SERVICE) {
if (isAlreadyShortFgs) {
Slog.i(TAG_SERVICE, "Extending SHORT_SERVICE time out: " + sr);
} else {
Slog.i(TAG_SERVICE, "Short FGS started: " + sr);
}
}
sr.setShortFgsInfo(SystemClock.uptimeMillis());
// We'll restart the timeout.
@@ -3098,6 +3118,10 @@ public final class ActiveServices {
ActivityManagerService.SERVICE_SHORT_FGS_TIMEOUT_MSG, sr);
mAm.mHandler.sendMessageAtTime(msg, sr.getShortFgsInfo().getTimeoutTime());
} else {
if (DEBUG_SHORT_SERVICE) {
Slog.w(TAG_SERVICE, "NOT extending SHORT_SERVICE time out: " + sr);
}
// We only (potentially) update the start command, start count, but not the timeout
// time.
// In this case, we keep the existing timeout running.