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

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

Merge "The ability to start FGS can be passed down by service binding."

parents bde6cfbd 631f90a7
Loading
Loading
Loading
Loading
+14 −7
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@ package com.android.server.am;
import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND;
import static android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND;
import static android.Manifest.permission.SYSTEM_ALERT_WINDOW;
import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST;
import static android.os.Process.NFC_UID;
@@ -168,6 +167,7 @@ public final class ActiveServices {
    public static final int FGS_FEATURE_ALLOWED_BY_SYSTEM_ALERT_WINDOW_PERMISSION = 16;
    public static final int FGS_FEATURE_ALLOWED_BY_FGS_BINDING = 17;
    public static final int FGS_FEATURE_ALLOWED_BY_DEVICE_DEMO_MODE = 18;
    public static final int FGS_FEATURE_ALLOWED_BY_PROCESS_RECORD = 19;

    @IntDef(flag = true, prefix = { "FGS_FEATURE_" }, value = {
            FGS_FEATURE_DENIED,
@@ -187,7 +187,8 @@ public final class ActiveServices {
            FGS_FEATURE_ALLOWED_BY_DEVICE_IDLE_ALLOW_LIST,
            FGS_FEATURE_ALLOWED_BY_SYSTEM_ALERT_WINDOW_PERMISSION,
            FGS_FEATURE_ALLOWED_BY_FGS_BINDING,
            FGS_FEATURE_ALLOWED_BY_DEVICE_DEMO_MODE
            FGS_FEATURE_ALLOWED_BY_DEVICE_DEMO_MODE,
            FGS_FEATURE_ALLOWED_BY_PROCESS_RECORD
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface FgsFeatureRetCode {}
@@ -5244,13 +5245,17 @@ public final class ActiveServices {
        if (ret == FGS_FEATURE_DENIED) {
            for (int i = mAm.mProcessList.mLruProcesses.size() - 1; i >= 0; i--) {
                final ProcessRecord pr = mAm.mProcessList.mLruProcesses.get(i);
                if (pr.uid == callingUid
                        && pr.mAllowStartFgsState <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
                if (pr.uid == callingUid) {
                    if (pr.mAllowStartFgs) {
                        ret = FGS_FEATURE_ALLOWED_BY_PROCESS_RECORD;
                        break;
                    } else if (pr.isAllowedStartFgsState()) {
                        ret = FGS_FEATURE_ALLOWED_BY_PROC_STATE;
                        break;
                    }
                }
            }
        }

        if (ret == FGS_FEATURE_DENIED) {
            for (int i = mAm.mProcessList.mLruProcesses.size() - 1; i >= 0; i--) {
@@ -5286,7 +5291,7 @@ public final class ActiveServices {
        }

        if (ret == FGS_FEATURE_DENIED) {
            if (mAm.isWhitelistedForFgsStartLocked(r.appInfo.uid)) {
            if (mAm.isWhitelistedForFgsStartLocked(callingUid)) {
                // uid is on DeviceIdleController's user/system allowlist
                // or AMS's FgsStartTempAllowList.
                ret = FGS_FEATURE_ALLOWED_BY_DEVICE_IDLE_ALLOW_LIST;
@@ -5354,6 +5359,8 @@ public final class ActiveServices {
                return "ALLOWED_BY_FGS_BINDING";
            case FGS_FEATURE_ALLOWED_BY_DEVICE_DEMO_MODE:
                return "ALLOWED_BY_DEVICE_DEMO_MODE";
            case FGS_FEATURE_ALLOWED_BY_PROCESS_RECORD:
                return "ALLOWED_BY_PROCESS_RECORD";
            default:
                return "";
        }
+9 −3
Original line number Diff line number Diff line
@@ -1329,7 +1329,7 @@ public final class OomAdjuster {
        app.setCached(false);
        app.shouldNotFreeze = false;

        app.mAllowStartFgsState = PROCESS_STATE_NONEXISTENT;
        app.resetAllowStartFgs();

        final int appUid = app.info.uid;
        final int logUid = mService.mCurOomAdjUid;
@@ -1351,7 +1351,6 @@ public final class OomAdjuster {
            app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT);
            app.curCapability = PROCESS_CAPABILITY_ALL;
            app.setCurProcState(ActivityManager.PROCESS_STATE_PERSISTENT);
            app.bumpAllowStartFgsState(PROCESS_STATE_PERSISTENT);
            // System processes can do UI, and when they do we want to have
            // them trim their memory after the user leaves the UI.  To
            // facilitate this, here we need to determine whether or not it
@@ -1382,6 +1381,8 @@ public final class OomAdjuster {
            app.setCurRawProcState(app.getCurProcState());
            app.curAdj = app.maxAdj;
            app.completedAdjSeq = app.adjSeq;
            app.bumpAllowStartFgsState(app.getCurProcState());
            app.setAllowStartFgs();
            // if curAdj is less than prevAppAdj, then this process was promoted
            return app.curAdj < prevAppAdj || app.getCurProcState() < prevProcState;
        }
@@ -1773,6 +1774,11 @@ public final class OomAdjuster {
                    int clientAdj = client.getCurRawAdj();
                    int clientProcState = client.getCurRawProcState();

                    // pass client's mAllowStartFgs to the app if client is not persistent process.
                    if (client.mAllowStartFgs && client.maxAdj >= ProcessList.FOREGROUND_APP_ADJ) {
                        app.mAllowStartFgs = true;
                    }

                    if ((cr.flags & Context.BIND_WAIVE_PRIORITY) == 0) {
                        if (shouldSkipDueToCycle(app, client, procState, adj, cycleReEval)) {
                            continue;
@@ -2236,7 +2242,7 @@ public final class OomAdjuster {
        app.setCurRawProcState(procState);
        app.setHasForegroundActivities(foregroundActivities);
        app.completedAdjSeq = mAdjSeq;

        app.setAllowStartFgs();
        // if curAdj or curProcState improved, then this process was promoted
        return app.curAdj < prevAppAdj || app.getCurProcState() < prevProcState
                || app.curCapability != prevCapability ;
+90 −0
Original line number Diff line number Diff line
@@ -16,7 +16,16 @@

package com.android.server.am;

import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND;
import static android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND;
import static android.Manifest.permission.SYSTEM_ALERT_WINDOW;
import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.Process.NFC_UID;
import static android.os.Process.ROOT_UID;
import static android.os.Process.SHELL_UID;
import static android.os.Process.SYSTEM_UID;

import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
@@ -361,6 +370,17 @@ class ProcessRecord implements WindowProcessListener {

    private final ArraySet<Binder> mBackgroundFgsStartTokens = new ArraySet<>();

    // The list of permissions that can start FGS from background.
    private static String[] ALLOW_BG_START_FGS_PERMISSIONS =
            {START_ACTIVITIES_FROM_BACKGROUND, START_FOREGROUND_SERVICES_FROM_BACKGROUND,
                    SYSTEM_ALERT_WINDOW};
    // Does the process has permission to start FGS from background.
    boolean mAllowStartFgsByPermission;
    // Can this process start FGS from background?
    // If this process has the ability to start FGS from background, this ability can be passed to
    // another process through service binding.
    boolean mAllowStartFgs;

    void setStartParams(int startUid, HostingRecord hostingRecord, String seInfo,
            long startTime) {
        this.startUid = startUid;
@@ -476,6 +496,9 @@ class ProcessRecord implements WindowProcessListener {
                pw.println();
        pw.print(prefix); pw.print("allowStartFgsState=");
                pw.println(mAllowStartFgsState);
        if (mAllowStartFgs) {
            pw.print(prefix); pw.print("allowStartFgs="); pw.println(mAllowStartFgs);
        }
        if (hasShownUi || mPendingUiClean || hasAboveClient || treatLikeActivity) {
            pw.print(prefix); pw.print("hasShownUi="); pw.print(hasShownUi);
                    pw.print(" pendingUiClean="); pw.print(mPendingUiClean);
@@ -672,6 +695,7 @@ class ProcessRecord implements WindowProcessListener {
        mWindowProcessController = new WindowProcessController(
                mService.mActivityTaskManager, info, processName, uid, userId, this, this);
        pkgList.put(_info.packageName, new ProcessStats.ProcessStateHolder(_info.longVersionCode));
        setAllowStartFgsByPermission();
    }

    public void setPid(int _pid) {
@@ -1983,12 +2007,78 @@ class ProcessRecord implements WindowProcessListener {
        return mDialogController;
    }

    void resetAllowStartFgs() {
        mAllowStartFgsState = PROCESS_STATE_NONEXISTENT;
        mAllowStartFgs = mAllowStartFgsByPermission;
    }

    void bumpAllowStartFgsState(int newProcState) {
        if (newProcState < mAllowStartFgsState) {
            mAllowStartFgsState = newProcState;
        }
    }

    void setAllowStartFgsByPermission() {
        boolean ret = false;
        if (!ret) {
            boolean isSystem = false;
            final int uid = UserHandle.getAppId(info.uid);
            switch (uid) {
                case ROOT_UID:
                case SYSTEM_UID:
                case NFC_UID:
                case SHELL_UID:
                    isSystem = true;
                    break;
                default:
                    isSystem = false;
                    break;
            }

            if (isSystem) {
                ret = true;
            }
        }

        if (!ret) {
            for (int i = 0; i < ALLOW_BG_START_FGS_PERMISSIONS.length; ++i) {
                if (ActivityManager.checkComponentPermission(ALLOW_BG_START_FGS_PERMISSIONS[i],
                        info.uid, -1, true)
                        == PERMISSION_GRANTED) {
                    ret = true;
                    break;
                }
            }
        }
        mAllowStartFgs = mAllowStartFgsByPermission = ret;
    }

    boolean isAllowedStartFgsState() {
        return mAllowStartFgsState <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
    }

    void setAllowStartFgs() {
        if (mAllowStartFgs) {
            return;
        }
        if (!mAllowStartFgs) {
            mAllowStartFgs = isAllowedStartFgsState();
        }

        if (!mAllowStartFgs) {
            // Is the calling UID a device owner app?
            if (mService.mInternal != null) {
                mAllowStartFgs = mService.mInternal.isDeviceOwner(info.uid);
            }
        }

        if (!mAllowStartFgs) {
            // uid is on DeviceIdleController's user/system allowlist
            // or AMS's FgsStartTempAllowList.
            mAllowStartFgs = mService.isWhitelistedForFgsStartLocked(info.uid);
        }
    }

    /** A controller to generate error dialogs in {@link ProcessRecord} */
    class ErrorDialogController {
        /** dialogs being displayed due to crash */