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

Commit a1919f78 authored by Sanjana Sunil's avatar Sanjana Sunil Committed by Android (Google) Code Review
Browse files

Merge "Add support for spawning multiple service processes"

parents f0596a59 e5cc81ce
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -1997,7 +1997,8 @@ class ContextImpl extends Context {

    private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
            String instanceName, Handler handler, Executor executor, UserHandle user) {
        // Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser.
        // Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser and
        // ActivityManagerService.LocalService.startAndBindSupplementalProcessService
        IServiceConnection sd;
        if (conn == null) {
            throw new IllegalArgumentException("connection is null");
@@ -2023,7 +2024,7 @@ class ContextImpl extends Context {
                flags |= BIND_WAIVE_PRIORITY;
            }
            service.prepareToLeaveProcess(this);
            int res = ActivityManager.getService().bindIsolatedService(
            int res = ActivityManager.getService().bindServiceInstance(
                    mMainThread.getApplicationThread(), getActivityToken(), service,
                    service.resolveTypeIfNeeded(getContentResolver()),
                    sd, flags, instanceName, getOpPackageName(), user.getIdentifier());
+1 −1
Original line number Diff line number Diff line
@@ -169,7 +169,7 @@ interface IActivityManager {
    int bindService(in IApplicationThread caller, in IBinder token, in Intent service,
            in String resolvedType, in IServiceConnection connection, int flags,
            in String callingPackage, int userId);
    int bindIsolatedService(in IApplicationThread caller, in IBinder token, in Intent service,
    int bindServiceInstance(in IApplicationThread caller, in IBinder token, in Intent service,
            in String resolvedType, in IServiceConnection connection, int flags,
            in String instanceName, in String callingPackage, int userId);
    void updateServiceGroup(in IServiceConnection connection, int group, int importance);
+1 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ package com.android.server.am {

  public interface ActivityManagerLocal {
    method public boolean canStartForegroundService(int, int, @NonNull String);
    method public boolean startAndBindSupplementalProcessService(@NonNull android.content.Intent, @NonNull android.content.ServiceConnection, int) throws android.os.TransactionTooLargeException;
  }

}
+32 −11
Original line number Diff line number Diff line
@@ -2721,7 +2721,8 @@ public final class ActiveServices {

    int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
            String resolvedType, final IServiceConnection connection, int flags,
            String instanceName, String callingPackage, final int userId)
            String instanceName, boolean isSupplementalProcessService, String callingPackage,
            final int userId)
            throws TransactionTooLargeException {
        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "bindService: " + service
                + " type=" + resolvedType + " conn=" + connection.asBinder()
@@ -2805,10 +2806,9 @@ public final class ActiveServices {
        final boolean isBindExternal = (flags & Context.BIND_EXTERNAL_SERVICE) != 0;
        final boolean allowInstant = (flags & Context.BIND_ALLOW_INSTANT) != 0;

        ServiceLookupResult res =
            retrieveServiceLocked(service, instanceName, resolvedType, callingPackage,
                    callingPid, callingUid, userId, true,
                    callerFg, isBindExternal, allowInstant);
        ServiceLookupResult res = retrieveServiceLocked(service, instanceName,
                isSupplementalProcessService, resolvedType, callingPackage, callingPid, callingUid,
                userId, true, callerFg, isBindExternal, allowInstant);
        if (res == null) {
            return 0;
        }
@@ -3228,6 +3228,20 @@ public final class ActiveServices {
            int callingPid, int callingUid, int userId,
            boolean createIfNeeded, boolean callingFromFg, boolean isBindExternal,
            boolean allowInstant) {
        return retrieveServiceLocked(service, instanceName, false, resolvedType, callingPackage,
                callingPid, callingUid, userId, createIfNeeded, callingFromFg, isBindExternal,
                allowInstant);
    }

    private ServiceLookupResult retrieveServiceLocked(Intent service,
            String instanceName, boolean isSupplementalProcessService, String resolvedType,
            String callingPackage, int callingPid, int callingUid, int userId,
            boolean createIfNeeded, boolean callingFromFg, boolean isBindExternal,
            boolean allowInstant) {
        if (isSupplementalProcessService && instanceName == null) {
            throw new IllegalArgumentException("No instanceName provided for supplemental process");
        }

        ServiceRecord r = null;
        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "retrieveServiceLocked: " + service
                + " type=" + resolvedType + " callingUid=" + callingUid);
@@ -3249,7 +3263,6 @@ public final class ActiveServices {
        if (instanceName == null) {
            comp = service.getComponent();
        } else {
            // This is for isolated services
            final ComponentName realComp = service.getComponent();
            if (realComp == null) {
                throw new IllegalArgumentException("Can't use custom instance name '" + instanceName
@@ -3304,12 +3317,19 @@ public final class ActiveServices {
                    return null;
                }
                if (instanceName != null
                        && (sInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) == 0) {
                        && (sInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) == 0
                        && !isSupplementalProcessService) {
                    throw new IllegalArgumentException("Can't use instance name '" + instanceName
                            + "' with non-isolated service '" + sInfo.name + "'");
                            + "' with non-isolated non-supplemental service '" + sInfo.name + "'");
                }
                ComponentName className = new ComponentName(
                        sInfo.applicationInfo.packageName, sInfo.name);
                if (isSupplementalProcessService
                        && (sInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) != 0) {
                    throw new IllegalArgumentException("Service cannot be both supplemental and "
                            + "isolated");
                }

                ComponentName className = new ComponentName(sInfo.applicationInfo.packageName,
                                                            sInfo.name);
                ComponentName name = comp != null ? comp : className;
                if (!mAm.validateAssociationAllowedLocked(callingPackage, callingUid,
                        name.getPackageName(), sInfo.applicationInfo.uid)) {
@@ -3392,7 +3412,8 @@ public final class ActiveServices {
                            = new Intent.FilterComparison(service.cloneFilter());
                    final ServiceRestarter res = new ServiceRestarter();
                    r = new ServiceRecord(mAm, className, name, definingPackageName,
                            definingUid, filter, sInfo, callingFromFg, res);
                            definingUid, filter, sInfo, callingFromFg, res,
                            isSupplementalProcessService);
                    res.setService(r);
                    smap.mServicesByInstanceName.put(name, r);
                    smap.mServicesByIntent.put(filter, r);
+23 −0
Original line number Diff line number Diff line
@@ -18,6 +18,9 @@ package com.android.server.am;

import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.TransactionTooLargeException;

/**
 * Interface for in-process calls into
@@ -58,4 +61,24 @@ public interface ActivityManagerLocal {
     * @hide
     */
    void tempAllowWhileInUsePermissionInFgs(int uid, long durationMs);

    /**
     * Starts a supplemental process service and binds to it. You can through the arguments here
     * have the system bring up multiple concurrent processes hosting their own instance of that
     * service. The <var>userAppUid</var> you provide here identifies the different instances - each
     * unique uid is attributed to a supplemental process.
     *
     * @param service Identifies the supplemental process service to connect to. The Intent must
     *        specify an explicit component name. This value cannot be null.
     * @param conn Receives information as the service is started and stopped.
     *        This must be a valid ServiceConnection object; it must not be null.
     * @param userAppUid Uid of the app for which the supplemental process needs to be spawned.
     * @return {@code true} if the system is in the process of bringing up a
     *         service that your client has permission to bind to; {@code false}
     *         if the system couldn't find the service or if your client doesn't
     *         have permission to bind to it.
     */
    boolean startAndBindSupplementalProcessService(@NonNull Intent service,
            @NonNull ServiceConnection conn, int userAppUid) throws TransactionTooLargeException;

}
Loading