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

Commit a81b4259 authored by Hui Yu's avatar Hui Yu Committed by Android (Google) Code Review
Browse files

Merge "Prototyping background started FGS startForeground() restriction."

parents 9bbf860b 853f6132
Loading
Loading
Loading
Loading
+70 −19
Original line number Diff line number Diff line
@@ -694,12 +694,8 @@ public final class ActiveServices {
        }
        ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);

        if (!r.mAllowWhileInUsePermissionInFgs) {
            r.mAllowWhileInUsePermissionInFgs =
                    shouldAllowWhileInUsePermissionInFgsLocked(callingPackage, callingPid,
        setFgsRestrictionLocked(callingPackage, callingPid,
                callingUid, service, r, allowBackgroundActivityStarts);
        }

        return cmp;
    }

@@ -1369,6 +1365,7 @@ public final class ActiveServices {
                                    + r.shortInstanceName);
                }
            }

            boolean alreadyStartedOp = false;
            boolean stopProcStatsOp = false;
            if (r.fgRequired) {
@@ -1415,6 +1412,24 @@ public final class ActiveServices {
                    ignoreForeground = true;
                }

                if (!ignoreForeground) {
                    if (!r.mAllowStartForeground) {
                        if (!r.mLoggedInfoAllowStartForeground) {
                            Slog.wtf(TAG, "Background started FGS "
                                    + r.mInfoAllowStartForeground);
                            r.mLoggedInfoAllowStartForeground = true;
                        }
                        if (mAm.mConstants.mFlagFgsStartRestrictionEnabled) {
                            Slog.w(TAG,
                                    "Service.startForeground() not allowed due to "
                                    + " mAllowStartForeground false: service "
                                    + r.shortInstanceName);
                            updateServiceForegroundLocked(r.app, true);
                            ignoreForeground = true;
                        }
                    }
                }

                // Apps under strict background restrictions simply don't get to have foreground
                // services, so now that we've enforced the startForegroundService() contract
                // we only do the machinery of making the service foreground when the app
@@ -2067,12 +2082,7 @@ public final class ActiveServices {
                }
            }

            if (!s.mAllowWhileInUsePermissionInFgs) {
                s.mAllowWhileInUsePermissionInFgs =
                        shouldAllowWhileInUsePermissionInFgsLocked(callingPackage,
                                callingPid, callingUid,
                                service, s, false);
            }
            setFgsRestrictionLocked(callingPackage, callingPid, callingUid, service, s, false);

            if (s.app != null) {
                if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
@@ -4840,21 +4850,48 @@ public final class ActiveServices {
    }

    /**
     * Should allow while-in-use permissions in foreground service or not.
     * while-in-use permissions in FGS started from background might be restricted.
     * There are two FGS restrictions:
     * In R, mAllowWhileInUsePermissionInFgs is to allow while-in-use permissions in foreground
     *  service or not. while-in-use permissions in FGS started from background might be restricted.
     * In S, mAllowStartForeground is to allow FGS to startForeground or not. Service started
     * from background may not become a FGS.
     * @param callingPackage caller app's package name.
     * @param callingUid caller app's uid.
     * @param intent intent to start/bind service.
     * @param r the service to start.
     * @return true if allow, false otherwise.
     */
    private boolean shouldAllowWhileInUsePermissionInFgsLocked(String callingPackage,
    private void setFgsRestrictionLocked(String callingPackage,
            int callingPid, int callingUid, Intent intent, ServiceRecord r,
            boolean allowBackgroundActivityStarts) {
        // Is the background FGS start restriction turned on?
        // Check DeviceConfig flag.
        if (!mAm.mConstants.mFlagBackgroundFgsStartRestrictionEnabled) {
            return true;
            r.mAllowWhileInUsePermissionInFgs = true;
        }

        if (!r.mAllowWhileInUsePermissionInFgs || !r.mAllowStartForeground) {
            final boolean temp = shouldAllowFgsFeatureLocked(callingPackage, callingPid,
                    callingUid, intent, r, allowBackgroundActivityStarts);
            if (!r.mAllowWhileInUsePermissionInFgs) {
                r.mAllowWhileInUsePermissionInFgs = temp;
            }
            if (!r.mAllowStartForeground) {
                r.mAllowStartForeground = temp;
            }
        }
    }

    /**
     * Should allow FGS feature or not.
     * @param callingPackage caller app's package name.
     * @param callingUid caller app's uid.
     * @param intent intent to start/bind service.
     * @param r the service to start.
     * @return true if allow, false otherwise.
     */
    private boolean shouldAllowFgsFeatureLocked(String callingPackage,
            int callingPid, int callingUid, Intent intent, ServiceRecord r,
            boolean allowBackgroundActivityStarts) {
        // Is the allow activity background start flag on?
        if (allowBackgroundActivityStarts) {
            return true;
@@ -4894,10 +4931,11 @@ public final class ActiveServices {
        }

        // Is the calling UID at PROCESS_STATE_TOP or above?
        final boolean isCallingUidTopApp = appIsTopLocked(callingUid);
        if (isCallingUidTopApp) {
        final int uidState = mAm.getUidState(callingUid);
        if (uidState <= ActivityManager.PROCESS_STATE_TOP) {
            return true;
        }

        // Does the calling UID have any visible activity?
        final boolean isCallingUidVisible = mAm.mAtmInternal.isUidForeground(callingUid);
        if (isCallingUidVisible) {
@@ -4915,6 +4953,19 @@ public final class ActiveServices {
        if (isDeviceOwner) {
            return true;
        }

        final String info =
                "[callingPackage: " + callingPackage
                        + "; callingUid: " + callingUid
                        + "; uidState: " + ProcessList.makeProcStateString(uidState)
                        + "; intent: " + intent
                        + "; targetSdkVersion:" + r.appInfo.targetSdkVersion
                        + "]";
        if (!info.equals(r.mInfoAllowStartForeground)) {
            r.mLoggedInfoAllowStartForeground = false;
            r.mInfoAllowStartForeground = info;
        }

        return false;
    }
}
+23 −0
Original line number Diff line number Diff line
@@ -144,6 +144,13 @@ final class ActivityManagerConstants extends ContentObserver {
    private static final String KEY_DEFAULT_BACKGROUND_FGS_STARTS_RESTRICTION_ENABLED =
            "default_background_fgs_starts_restriction_enabled";

    /**
     * Default value for mFlagFgsStartRestrictionEnabled if not explicitly set in
     * Settings.Global.
     */
    private static final String KEY_DEFAULT_FGS_STARTS_RESTRICTION_ENABLED =
            "default_fgs_starts_restriction_enabled";

    // Maximum number of cached processes we will allow.
    public int MAX_CACHED_PROCESSES = DEFAULT_MAX_CACHED_PROCESSES;

@@ -293,6 +300,11 @@ final class ActivityManagerConstants extends ContentObserver {
    // started, the restriction is on while-in-use permissions.)
    volatile boolean mFlagBackgroundFgsStartRestrictionEnabled = true;

    // Indicates whether the foreground service background start restriction is enabled.
    // When the restriction is enabled, service is not allowed to startForeground from background
    // at all.
    volatile boolean mFlagFgsStartRestrictionEnabled = false;

    private final ActivityManagerService mService;
    private ContentResolver mResolver;
    private final KeyValueListParser mParser = new KeyValueListParser(',');
@@ -436,6 +448,9 @@ final class ActivityManagerConstants extends ContentObserver {
                            case KEY_DEFAULT_BACKGROUND_FGS_STARTS_RESTRICTION_ENABLED:
                                updateBackgroundFgsStartsRestriction();
                                break;
                            case KEY_DEFAULT_FGS_STARTS_RESTRICTION_ENABLED:
                                updateFgsStartsRestriction();
                                break;
                            case KEY_OOMADJ_UPDATE_POLICY:
                                updateOomAdjUpdatePolicy();
                                break;
@@ -659,6 +674,7 @@ final class ActivityManagerConstants extends ContentObserver {
        mFlagForegroundServiceStartsLoggingEnabled = Settings.Global.getInt(mResolver,
                Settings.Global.FOREGROUND_SERVICE_STARTS_LOGGING_ENABLED, 1) == 1;
    }

    private void updateBackgroundFgsStartsRestriction() {
        mFlagBackgroundFgsStartRestrictionEnabled = DeviceConfig.getBoolean(
                DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
@@ -666,6 +682,13 @@ final class ActivityManagerConstants extends ContentObserver {
                /*defaultValue*/ true);
    }

    private void updateFgsStartsRestriction() {
        mFlagFgsStartRestrictionEnabled = DeviceConfig.getBoolean(
                DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
                KEY_DEFAULT_FGS_STARTS_RESTRICTION_ENABLED,
                /*defaultValue*/ false);
    }

    private void updateOomAdjUpdatePolicy() {
        OOMADJ_UPDATE_QUICK = DeviceConfig.getInt(
                DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+10 −0
Original line number Diff line number Diff line
@@ -146,6 +146,12 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
    // the most recent package that start/bind this service.
    String mRecentCallingPackage;

    // allow the service becomes foreground service? Service started from background may not be
    // allowed to become a foreground service.
    boolean mAllowStartForeground;
    String mInfoAllowStartForeground;
    boolean mLoggedInfoAllowStartForeground;

    String stringName;      // caching of toString

    private int lastStartId;    // identifier of most recent start request.
@@ -408,6 +414,10 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
                pw.println(mAllowWhileInUsePermissionInFgs);
        pw.print(prefix); pw.print("recentCallingPackage=");
                pw.println(mRecentCallingPackage);
        pw.print(prefix); pw.print("allowStartForeground=");
        pw.println(mAllowStartForeground);
        pw.print(prefix); pw.print("infoAllowStartForeground=");
        pw.println(mInfoAllowStartForeground);
        if (delayed) {
            pw.print(prefix); pw.print("delayed="); pw.println(delayed);
        }