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

Commit 3d08ca95 authored by Kunal's avatar Kunal Committed by Varun Shah
Browse files

Restrict some FGS starts from BOOT_COMPLETED broadcast.

Don't allow foreground services of any type outside of location, health,
connected_device, remote_messaging, system_exempted, and special_use to
start from the BOOT_COMPLETED broadcast.

Bug: 296558535
Test: atest BootCompletedFgsTest
Change-Id: I8f4520746dccb381addb6df244705861cff1e5f8
parent 12430ba4
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -303,6 +303,23 @@ public final class ActiveServices {
    @Retention(RetentionPolicy.SOURCE)
    @interface FgsStopReason {}

    /**
     * Disables foreground service background starts from BOOT_COMPLETED broadcasts for all types
     * except:
     * <ul>
     *     <li>{@link android.content.pm.ServiceInfo#FOREGROUND_SERVICE_TYPE_LOCATION}</li>
     *     <li>{@link android.content.pm.ServiceInfo#FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE}</li>
     *     <li>{@link android.content.pm.ServiceInfo#FOREGROUND_SERVICE_TYPE_REMOTE_MESSAGING}</li>
     *     <li>{@link android.content.pm.ServiceInfo#FOREGROUND_SERVICE_TYPE_HEALTH}</li>
     *     <li>{@link android.content.pm.ServiceInfo#FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED}</li>
     *     <li>{@link android.content.pm.ServiceInfo#FOREGROUND_SERVICE_TYPE_SPECIAL_USE}</li>
     * </ul>
     */
    @ChangeId
    @EnabledSince(targetSdkVersion = VERSION_CODES.VANILLA_ICE_CREAM)
    @Overridable
    public static final long FGS_BOOT_COMPLETED_RESTRICTIONS = 296558535L;

    final ActivityManagerService mAm;

    // Maximum number of services that we allow to start in the background
@@ -1053,6 +1070,20 @@ public final class ActiveServices {
        }
    }

    private boolean shouldAllowBootCompletedStart(ServiceRecord r, int foregroundServiceType) {
        @PowerExemptionManager.ReasonCode final int fgsStartReasonCode =
                r.mInfoTempFgsAllowListReason != null ? r.mInfoTempFgsAllowListReason.mReasonCode
                                                      : REASON_DENIED;
        if (Flags.fgsBootCompleted()
                && CompatChanges.isChangeEnabled(FGS_BOOT_COMPLETED_RESTRICTIONS, r.appInfo.uid)
                && fgsStartReasonCode == PowerExemptionManager.REASON_BOOT_COMPLETED) {
            // Filter through types
            return ((foregroundServiceType & mAm.mConstants.FGS_BOOT_COMPLETED_ALLOWLIST) != 0);
        }
        // Not BOOT_COMPLETED
        return true;
    }

    private ComponentName startServiceInnerLocked(ServiceRecord r, Intent service,
            int callingUid, int callingPid, String callingProcessName,
            int callingProcessState, boolean fgRequired, boolean callerFg,
@@ -2087,6 +2118,11 @@ public final class ActiveServices {
                // anyway, so we just remove the SHORT_SERVICE type.
                foregroundServiceType &= ~FOREGROUND_SERVICE_TYPE_SHORT_SERVICE;
            }
            if (!shouldAllowBootCompletedStart(r, foregroundServiceType)) {
                throw new ForegroundServiceStartNotAllowedException("FGS type "
                        + ServiceInfo.foregroundServiceTypeToLabel(foregroundServiceType)
                        + " not allowed to start from BOOT_COMPLETED!");
            }

            boolean alreadyStartedOp = false;
            boolean stopProcStatsOp = false;
+25 −0
Original line number Diff line number Diff line
@@ -16,6 +16,12 @@

package com.android.server.am;

import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_HEALTH;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_REMOTE_MESSAGING;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED;
import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED;
import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_NONE;

@@ -73,6 +79,9 @@ final class ActivityManagerConstants extends ContentObserver {
            = "fgservice_screen_on_before_time";
    private static final String KEY_FGSERVICE_SCREEN_ON_AFTER_TIME
            = "fgservice_screen_on_after_time";

    private static final String KEY_FGS_BOOT_COMPLETED_ALLOWLIST = "fgs_boot_completed_allowlist";

    private static final String KEY_CONTENT_PROVIDER_RETAIN_TIME = "content_provider_retain_time";
    private static final String KEY_GC_TIMEOUT = "gc_timeout";
    private static final String KEY_GC_MIN_INTERVAL = "gc_min_interval";
@@ -166,6 +175,15 @@ final class ActivityManagerConstants extends ContentObserver {
    private static final long DEFAULT_FGSERVICE_MIN_REPORT_TIME = 3*1000;
    private static final long DEFAULT_FGSERVICE_SCREEN_ON_BEFORE_TIME = 1*1000;
    private static final long DEFAULT_FGSERVICE_SCREEN_ON_AFTER_TIME = 5*1000;

    private static final int DEFAULT_FGS_BOOT_COMPLETED_ALLOWLIST =
            FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE
                | FOREGROUND_SERVICE_TYPE_HEALTH
                | FOREGROUND_SERVICE_TYPE_REMOTE_MESSAGING
                | FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED
                | FOREGROUND_SERVICE_TYPE_SPECIAL_USE
                | FOREGROUND_SERVICE_TYPE_LOCATION;

    private static final long DEFAULT_CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
    private static final long DEFAULT_GC_TIMEOUT = 5*1000;
    private static final long DEFAULT_GC_MIN_INTERVAL = 60*1000;
@@ -446,6 +464,9 @@ final class ActivityManagerConstants extends ContentObserver {
    // on until we will stop reporting it.
    public long FGSERVICE_SCREEN_ON_AFTER_TIME = DEFAULT_FGSERVICE_SCREEN_ON_AFTER_TIME;

    // Allow-list for FGS types that are allowed to start from BOOT_COMPLETED.
    public int FGS_BOOT_COMPLETED_ALLOWLIST = DEFAULT_FGS_BOOT_COMPLETED_ALLOWLIST;

    // How long we will retain processes hosting content providers in the "last activity"
    // state before allowing them to drop down to the regular cached LRU list.  This is
    // to avoid thrashing of provider processes under low memory situations.
@@ -1450,6 +1471,8 @@ final class ActivityManagerConstants extends ContentObserver {
                    DEFAULT_FGSERVICE_SCREEN_ON_BEFORE_TIME);
            FGSERVICE_SCREEN_ON_AFTER_TIME = mParser.getLong(KEY_FGSERVICE_SCREEN_ON_AFTER_TIME,
                    DEFAULT_FGSERVICE_SCREEN_ON_AFTER_TIME);
            FGS_BOOT_COMPLETED_ALLOWLIST = mParser.getInt(KEY_FGS_BOOT_COMPLETED_ALLOWLIST,
                    DEFAULT_FGS_BOOT_COMPLETED_ALLOWLIST);
            CONTENT_PROVIDER_RETAIN_TIME = mParser.getLong(KEY_CONTENT_PROVIDER_RETAIN_TIME,
                    DEFAULT_CONTENT_PROVIDER_RETAIN_TIME);
            GC_TIMEOUT = mParser.getLong(KEY_GC_TIMEOUT,
@@ -2091,6 +2114,8 @@ final class ActivityManagerConstants extends ContentObserver {
        pw.println(FGSERVICE_SCREEN_ON_BEFORE_TIME);
        pw.print("  "); pw.print(KEY_FGSERVICE_SCREEN_ON_AFTER_TIME); pw.print("=");
        pw.println(FGSERVICE_SCREEN_ON_AFTER_TIME);
        pw.print("  "); pw.print(KEY_FGS_BOOT_COMPLETED_ALLOWLIST); pw.print("=");
        pw.println(FGS_BOOT_COMPLETED_ALLOWLIST);
        pw.print("  "); pw.print(KEY_CONTENT_PROVIDER_RETAIN_TIME); pw.print("=");
        pw.println(CONTENT_PROVIDER_RETAIN_TIME);
        pw.print("  "); pw.print(KEY_GC_TIMEOUT); pw.print("=");
+8 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.app.usage.UsageStatsManager.REASON_MAIN_FORCED_BY_USER;
import static android.app.usage.UsageStatsManager.REASON_SUB_FORCED_SYSTEM_FLAG_UNDEFINED;
import static android.content.pm.PackageManager.MATCH_ANY_USER;
import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
import static android.os.Process.INVALID_UID;
import static android.view.Display.INVALID_DISPLAY;
import static android.window.DisplayAreaOrganizer.FEATURE_UNDEFINED;
@@ -555,6 +556,13 @@ final class ActivityManagerShellCommand extends ShellCommand {
                } else if (opt.equals("--dismiss-keyguard-if-insecure")
                      || opt.equals("--dismiss-keyguard")) {
                    mDismissKeyguardIfInsecure = true;
                } else if (opt.equals("--allow-fgs-start-reason")) {
                    final int reasonCode = Integer.parseInt(getNextArgRequired());
                    mBroadcastOptions = BroadcastOptions.makeBasic();
                    mBroadcastOptions.setTemporaryAppAllowlist(10_000,
                            TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
                            reasonCode,
                            "");
                } else {
                    return false;
                }