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

Commit 292f9373 authored by Hui Yu's avatar Hui Yu
Browse files

Limit the max number of service connection a process can bind to

services to be 3000.

This limits the max number of outgoing ServiceConnection a process is allowed to bind to a service (or multiple services) by bindService() calls.

1. Add device_config key "max_service_connections_per_process" to set
  mMaxServiceConnectionsPerProcess, the default value is 3000.
2. If the per process max session connection is exceeded, Context.bindService()
   calls returns false and the service connection is not connected.

Bug: 236039413
Test: atest cts/tests/app/src/android/app/cts/ServiceTest.java#testMaxServiceConnections
Change-Id: I9a4e97a4edaa8f2a52bf67b19ce3948d0ebcfdea
parent b37c41d3
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -2855,6 +2855,14 @@ public final class ActiveServices {
            return -1;
        }
        ServiceRecord s = res.record;
        final AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
        final ProcessServiceRecord clientPsr = b.client.mServices;
        if (clientPsr.numberOfConnections() >= mAm.mConstants.mMaxServiceConnectionsPerProcess) {
            Slog.w(TAG, "bindService exceeded max service connection number per process, "
                    + "callerApp:" + callerApp.processName
                    + " intent:" + service);
            return 0;
        }

        // The package could be frozen (meaning it's doing surgery), defer the actual
        // binding until the package is unfrozen.
@@ -2905,7 +2913,6 @@ public final class ActiveServices {
            mAm.grantImplicitAccess(callerApp.userId, service,
                    callerApp.uid, UserHandle.getAppId(s.appInfo.uid));

            AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
            ConnectionRecord c = new ConnectionRecord(b, activity,
                    connection, flags, clientLabel, clientIntent,
                    callerApp.uid, callerApp.processName, callingPackage, res.aliasComponent);
@@ -2916,7 +2923,6 @@ public final class ActiveServices {
            if (activity != null) {
                activity.addConnection(c);
            }
            final ProcessServiceRecord clientPsr = b.client.mServices;
            clientPsr.addConnection(c);
            c.startAssociationIfNeeded();
            if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
+23 −0
Original line number Diff line number Diff line
@@ -196,6 +196,8 @@ final class ActivityManagerConstants extends ContentObserver {
    static final long DEFAULT_KILL_BG_RESTRICTED_CACHED_IDLE_SETTLE_TIME_MS = 60 * 1000;
    static final boolean DEFAULT_KILL_BG_RESTRICTED_CACHED_IDLE = true;

    static final int DEFAULT_MAX_SERVICE_CONNECTIONS_PER_PROCESS = 3000;

    /**
     * Same as {@link TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED}
     */
@@ -335,6 +337,9 @@ final class ActivityManagerConstants extends ContentObserver {
    private static final String KEY_SERVICE_BIND_ALMOST_PERCEPTIBLE_TIMEOUT_MS =
            "service_bind_almost_perceptible_timeout_ms";

    private static final String KEY_MAX_SERVICE_CONNECTIONS_PER_PROCESS =
            "max_service_connections_per_process";

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

@@ -687,6 +692,12 @@ final class ActivityManagerConstants extends ContentObserver {
     */
    volatile String mComponentAliasOverrides = DEFAULT_COMPONENT_ALIAS_OVERRIDES;

    /**
     *  The max number of outgoing ServiceConnection a process is allowed to bind to a service
     *  (or multiple services).
     */
    volatile int mMaxServiceConnectionsPerProcess = DEFAULT_MAX_SERVICE_CONNECTIONS_PER_PROCESS;

    private final ActivityManagerService mService;
    private ContentResolver mResolver;
    private final KeyValueListParser mParser = new KeyValueListParser(',');
@@ -990,6 +1001,9 @@ final class ActivityManagerConstants extends ContentObserver {
                            case KEY_NETWORK_ACCESS_TIMEOUT_MS:
                                updateNetworkAccessTimeoutMs();
                                break;
                            case KEY_MAX_SERVICE_CONNECTIONS_PER_PROCESS:
                                updateMaxServiceConnectionsPerProcess();
                                break;
                            default:
                                break;
                        }
@@ -1633,6 +1647,13 @@ final class ActivityManagerConstants extends ContentObserver {
        }
    }

    private void updateMaxServiceConnectionsPerProcess() {
        mMaxServiceConnectionsPerProcess = DeviceConfig.getInt(
                DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
                KEY_MAX_SERVICE_CONNECTIONS_PER_PROCESS,
                DEFAULT_MAX_SERVICE_CONNECTIONS_PER_PROCESS);
    }

    @NeverCompile // Avoid size overhead of debugging code.
    void dump(PrintWriter pw) {
        pw.println("ACTIVITY MANAGER SETTINGS (dumpsys activity settings) "
@@ -1779,6 +1800,8 @@ final class ActivityManagerConstants extends ContentObserver {
        pw.print("="); pw.println(mServiceBindAlmostPerceptibleTimeoutMs);
        pw.print("  "); pw.print(KEY_NETWORK_ACCESS_TIMEOUT_MS);
        pw.print("="); pw.println(mNetworkAccessTimeoutMs);
        pw.print("  "); pw.print(KEY_MAX_SERVICE_CONNECTIONS_PER_PROCESS);
        pw.print("="); pw.println(mMaxServiceConnectionsPerProcess);

        pw.println();
        if (mOverrideMaxCachedProcesses >= 0) {