diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 8181a74e8f95e..ec2115c2baedf 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -1998,7 +1998,7 @@ 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 and - // ActivityManagerService.LocalService.startAndBindSupplementalProcessService + // ActivityManagerLocal.bindSupplementalProcessService IServiceConnection sd; if (conn == null) { throw new IllegalArgumentException("connection is null"); diff --git a/services/api/current.txt b/services/api/current.txt index dcf7e64479dac..e46c972476810 100644 --- a/services/api/current.txt +++ b/services/api/current.txt @@ -38,8 +38,8 @@ package com.android.server { package com.android.server.am { public interface ActivityManagerLocal { + method public boolean bindSupplementalProcessService(@NonNull android.content.Intent, @NonNull android.content.ServiceConnection, int, @NonNull String, int) throws android.os.RemoteException; 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; } } diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 9353dd832bbab..dc64d800c8c03 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -3411,9 +3411,11 @@ public final class ActiveServices { final Intent.FilterComparison filter = new Intent.FilterComparison(service.cloneFilter()); final ServiceRestarter res = new ServiceRestarter(); + String supplementalProcessName = isSupplementalProcessService ? instanceName + : null; r = new ServiceRecord(mAm, className, name, definingPackageName, definingUid, filter, sInfo, callingFromFg, res, - isSupplementalProcessService); + supplementalProcessName); res.setService(r); smap.mServicesByInstanceName.put(name, r); smap.mServicesByIntent.put(filter, r); diff --git a/services/core/java/com/android/server/am/ActivityManagerLocal.java b/services/core/java/com/android/server/am/ActivityManagerLocal.java index d9ee7d974864b..535340b4c9c10 100644 --- a/services/core/java/com/android/server/am/ActivityManagerLocal.java +++ b/services/core/java/com/android/server/am/ActivityManagerLocal.java @@ -17,10 +17,12 @@ package com.android.server.am; import android.annotation.NonNull; +import android.annotation.SuppressLint; import android.annotation.SystemApi; +import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; -import android.os.TransactionTooLargeException; +import android.os.RemoteException; /** * Interface for in-process calls into @@ -63,22 +65,28 @@ public interface ActivityManagerLocal { 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 userAppUid you provide here identifies the different instances - each - * unique uid is attributed to a supplemental process. + * Binds to a supplemental process service, creating it if needed. You can through the arguments + * here have the system bring up multiple concurrent processes hosting their own instance of + * that service. The {@code processName} you provide here identifies the different instances. * * @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. + * @param processName Unique identifier for the service instance. Each unique name here will + * result in a different service instance being created. Identifiers must only contain + * ASCII letters, digits, underscores, and periods. + * @param flags Operation options provided by Context class for the binding. * @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. + * @throws RemoteException If the service could not be brought up. + * @see Context#bindService(Intent, ServiceConnection, int) */ - boolean startAndBindSupplementalProcessService(@NonNull Intent service, - @NonNull ServiceConnection conn, int userAppUid) throws TransactionTooLargeException; - + @SuppressLint("RethrowRemoteException") + boolean bindSupplementalProcessService(@NonNull Intent service, @NonNull ServiceConnection conn, + int userAppUid, @NonNull String processName, @Context.BindServiceFlags int flags) + throws RemoteException; } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 5cc163ddfe9d7..54f462aa8ae05 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -15951,14 +15951,17 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override - public boolean startAndBindSupplementalProcessService(Intent service, - ServiceConnection conn, int userAppUid) throws TransactionTooLargeException { + public boolean bindSupplementalProcessService(Intent service, ServiceConnection conn, + int userAppUid, String processName, int flags) throws RemoteException { if (service == null) { throw new IllegalArgumentException("intent is null"); } if (conn == null) { throw new IllegalArgumentException("connection is null"); } + if (processName == null) { + throw new IllegalArgumentException("processName is null"); + } if (service.getComponent() == null) { throw new IllegalArgumentException("service must specify explicit component"); } @@ -15967,15 +15970,14 @@ public class ActivityManagerService extends IActivityManager.Stub } Handler handler = mContext.getMainThreadHandler(); - int flags = Context.BIND_AUTO_CREATE; final IServiceConnection sd = mContext.getServiceDispatcher(conn, handler, flags); service.prepareToLeaveProcess(mContext); return ActivityManagerService.this.bindServiceInstance( - mContext.getIApplicationThread(), mContext.getActivityToken(), service, - service.resolveTypeIfNeeded(mContext.getContentResolver()), sd, flags, - Integer.toString(userAppUid), /*isSupplementalProcessService*/ true, - mContext.getOpPackageName(), UserHandle.getUserId(userAppUid)) != 0; + mContext.getIApplicationThread(), mContext.getActivityToken(), service, + service.resolveTypeIfNeeded(mContext.getContentResolver()), sd, flags, + processName, /*isSupplementalProcessService*/ true, mContext.getOpPackageName(), + UserHandle.getUserId(userAppUid)) != 0; } @Override diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java index da78e2d7504ef..d3b57529834a0 100644 --- a/services/core/java/com/android/server/am/ServiceRecord.java +++ b/services/core/java/com/android/server/am/ServiceRecord.java @@ -571,13 +571,13 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN Intent.FilterComparison intent, ServiceInfo sInfo, boolean callerIsFg, Runnable restarter) { this(ams, name, instanceName, definingPackageName, definingUid, intent, sInfo, callerIsFg, - restarter, false); + restarter, null); } ServiceRecord(ActivityManagerService ams, ComponentName name, ComponentName instanceName, String definingPackageName, int definingUid, Intent.FilterComparison intent, ServiceInfo sInfo, boolean callerIsFg, - Runnable restarter, boolean isSupplementalProcessService) { + Runnable restarter, String supplementalProcessName) { this.ams = ams; this.name = name; this.instanceName = instanceName; @@ -588,9 +588,10 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN serviceInfo = sInfo; appInfo = sInfo.applicationInfo; packageName = sInfo.applicationInfo.packageName; - if ((sInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) != 0 - || isSupplementalProcessService) { + if ((sInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) != 0) { processName = sInfo.processName + ":" + instanceName.getClassName(); + } else if (supplementalProcessName != null) { + processName = supplementalProcessName; } else { processName = sInfo.processName; }