Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit de7e4588 authored by Makoto Onuki's avatar Makoto Onuki
Browse files

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
parent 17028b3d
Loading
Loading
Loading
Loading
+50 −26
Original line number Diff line number Diff line
@@ -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,19 +2062,28 @@ 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.
                                // The timeout will stop later, in
                                // maybeUpdateShortFgsTrackingLocked().
                            }
                        } else {
                            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,6 +2137,7 @@ public final class ActiveServices {
                                        + "location/camera/microphone access: service "
                                        + r.shortInstanceName);
                    }
                    if (!bypassBfslCheck) {
                        logFgsBackgroundStart(r);
                        if (r.mAllowStartForeground == REASON_DENIED
                                && isBgFgsRestrictionEnabledForService) {
@@ -2144,6 +2157,7 @@ public final class ActiveServices {
                                throw new ForegroundServiceStartNotAllowedException(msg);
                            }
                        }
                    }

                    if (!ignoreForeground) {
                        Pair<Integer, RuntimeException> fgsTypeResult = null;
@@ -3084,11 +3098,17 @@ public final class ActiveServices {
            unscheduleShortFgsTimeoutLocked(sr);
            return;
        }

        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);
                }

        if (extendTimeout || !sr.hasShortFgsInfo()) {
            }
            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.