Chromium Code Reviews| Index: content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java |
| diff --git a/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java b/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java |
| index db717bfcc52f6f32ea769d49eec437c164d70f8c..6fbc3ed6a12953831fd75b05c7bdacd6ba9cb186 100644 |
| --- a/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java |
| +++ b/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java |
| @@ -4,14 +4,10 @@ |
| package org.chromium.content.browser; |
| -import android.content.ComponentName; |
| import android.content.Context; |
| -import android.content.pm.ApplicationInfo; |
| -import android.content.pm.PackageManager; |
| import android.os.Bundle; |
| import android.os.IBinder; |
| import android.os.RemoteException; |
| -import android.text.TextUtils; |
| import org.chromium.base.CpuFeatures; |
| import org.chromium.base.Log; |
| @@ -22,14 +18,9 @@ import org.chromium.base.library_loader.Linker; |
| import org.chromium.base.process_launcher.ChildProcessCreationParams; |
| import org.chromium.base.process_launcher.FileDescriptorInfo; |
| import org.chromium.content.app.ChromiumLinkerParams; |
| -import org.chromium.content.app.PrivilegedProcessService; |
| -import org.chromium.content.app.SandboxedProcessService; |
| import org.chromium.content.common.ContentSwitches; |
| -import java.util.ArrayList; |
| -import java.util.LinkedList; |
| import java.util.Map; |
| -import java.util.Queue; |
| import java.util.concurrent.ConcurrentHashMap; |
| /** |
| @@ -42,310 +33,15 @@ import java.util.concurrent.ConcurrentHashMap; |
| public class ChildProcessLauncher { |
| private static final String TAG = "ChildProcLauncher"; |
| - private static class ChildConnectionAllocator { |
| - // Connections to services. Indices of the array correspond to the service numbers. |
| - private final ChildProcessConnection[] mChildProcessConnections; |
| - |
| - // The list of free (not bound) service indices. |
| - // SHOULD BE ACCESSED WITH mConnectionLock. |
| - private final ArrayList<Integer> mFreeConnectionIndices; |
| - private final Object mConnectionLock = new Object(); |
| - |
| - private final String mChildClassName; |
| - private final boolean mInSandbox; |
| - // Each Allocator keeps a queue for the pending spawn data. Once a connection is free, we |
| - // dequeue the pending spawn data from the same allocator as the connection. |
| - // SHOULD BE ACCESSED WITH mConnectionLock. |
| - private final Queue<SpawnData> mPendingSpawnQueue = new LinkedList<>(); |
| - |
| - public ChildConnectionAllocator(boolean inSandbox, int numChildServices, |
| - String serviceClassName) { |
| - mChildProcessConnections = new ChildProcessConnectionImpl[numChildServices]; |
| - mFreeConnectionIndices = new ArrayList<Integer>(numChildServices); |
| - for (int i = 0; i < numChildServices; i++) { |
| - mFreeConnectionIndices.add(i); |
| - } |
| - mChildClassName = serviceClassName; |
| - mInSandbox = inSandbox; |
| - } |
| - |
| - // Allocate or enqueue. If there are no free slots, return null and enqueue the spawn data. |
| - public ChildProcessConnection allocate(SpawnData spawnData, |
| - ChildProcessConnection.DeathCallback deathCallback, |
| - Bundle childProcessCommonParameters) { |
| - assert spawnData.isInSandbox() == mInSandbox; |
| - synchronized (mConnectionLock) { |
| - if (mFreeConnectionIndices.isEmpty()) { |
| - Log.d(TAG, "Ran out of services to allocate."); |
| - if (!spawnData.isForWarmUp()) { |
| - mPendingSpawnQueue.add(spawnData); |
| - } |
| - return null; |
| - } |
| - int slot = mFreeConnectionIndices.remove(0); |
| - assert mChildProcessConnections[slot] == null; |
| - mChildProcessConnections[slot] = |
| - new ChildProcessConnectionImpl(spawnData.getContext(), slot, mInSandbox, |
| - deathCallback, mChildClassName, childProcessCommonParameters, |
| - spawnData.isAlwaysInForeground(), spawnData.getCreationParams()); |
| - Log.d(TAG, "Allocator allocated a connection, sandbox: %b, slot: %d", mInSandbox, |
| - slot); |
| - return mChildProcessConnections[slot]; |
| - } |
| - } |
| - |
| - // Also return the first SpawnData in the pending queue, if any. |
| - public SpawnData free(ChildProcessConnection connection) { |
| - synchronized (mConnectionLock) { |
| - int slot = connection.getServiceNumber(); |
| - if (mChildProcessConnections[slot] != connection) { |
| - int occupier = mChildProcessConnections[slot] == null |
| - ? -1 : mChildProcessConnections[slot].getServiceNumber(); |
| - Log.e(TAG, "Unable to find connection to free in slot: %d " |
| - + "already occupied by service: %d", slot, occupier); |
| - assert false; |
| - } else { |
| - mChildProcessConnections[slot] = null; |
| - assert !mFreeConnectionIndices.contains(slot); |
| - mFreeConnectionIndices.add(slot); |
| - Log.d(TAG, "Allocator freed a connection, sandbox: %b, slot: %d", mInSandbox, |
| - slot); |
| - } |
| - return mPendingSpawnQueue.poll(); |
| - } |
| - } |
| - |
| - public boolean isFreeConnectionAvailable() { |
| - synchronized (mConnectionLock) { |
| - return !mFreeConnectionIndices.isEmpty(); |
| - } |
| - } |
| - |
| - /** @return the count of connections managed by the allocator */ |
| - @VisibleForTesting |
| - int allocatedConnectionsCountForTesting() { |
| - return mChildProcessConnections.length - mFreeConnectionIndices.size(); |
| - } |
| - |
| - @VisibleForTesting |
| - ChildProcessConnection[] connectionArrayForTesting() { |
| - return mChildProcessConnections; |
| - } |
| - |
| - @VisibleForTesting |
| - void enqueuePendingQueueForTesting(SpawnData spawnData) { |
| - synchronized (mConnectionLock) { |
| - mPendingSpawnQueue.add(spawnData); |
| - } |
| - } |
| - |
| - @VisibleForTesting |
| - int pendingSpawnsCountForTesting() { |
| - synchronized (mConnectionLock) { |
| - return mPendingSpawnQueue.size(); |
| - } |
| - } |
| - } |
| - |
| - private static class SpawnData { |
| - private final boolean mForWarmup; // Do not queue up if failed. |
| - private final Context mContext; |
| - private final String[] mCommandLine; |
| - private final int mChildProcessId; |
| - private final FileDescriptorInfo[] mFilesToBeMapped; |
| - private final LaunchCallback mLaunchCallback; |
| - private final IBinder mChildProcessCallback; |
| - private final boolean mInSandbox; |
| - private final boolean mAlwaysInForeground; |
| - private final ChildProcessCreationParams mCreationParams; |
| - |
| - private SpawnData(boolean forWarmUp, Context context, String[] commandLine, |
| - int childProcessId, FileDescriptorInfo[] filesToBeMapped, |
| - LaunchCallback launchCallback, IBinder childProcessCallback, boolean inSandbox, |
| - boolean alwaysInForeground, ChildProcessCreationParams creationParams) { |
| - mForWarmup = forWarmUp; |
| - mContext = context; |
| - mCommandLine = commandLine; |
| - mChildProcessId = childProcessId; |
| - mFilesToBeMapped = filesToBeMapped; |
| - mLaunchCallback = launchCallback; |
| - mChildProcessCallback = childProcessCallback; |
| - mInSandbox = inSandbox; |
| - mAlwaysInForeground = alwaysInForeground; |
| - mCreationParams = creationParams; |
| - } |
| - |
| - private boolean isForWarmUp() { |
| - return mForWarmup; |
| - } |
| - private Context getContext() { |
| - return mContext; |
| - } |
| - private String[] getCommandLine() { |
| - return mCommandLine; |
| - } |
| - private int getChildProcessId() { |
| - return mChildProcessId; |
| - } |
| - private FileDescriptorInfo[] getFilesToBeMapped() { |
| - return mFilesToBeMapped; |
| - } |
| - private LaunchCallback getLaunchCallback() { |
| - return mLaunchCallback; |
| - } |
| - private IBinder getChildProcessCallback() { |
| - return mChildProcessCallback; |
| - } |
| - private boolean isInSandbox() { |
| - return mInSandbox; |
| - } |
| - private boolean isAlwaysInForeground() { |
| - return mAlwaysInForeground; |
| - } |
| - private ChildProcessCreationParams getCreationParams() { |
| - return mCreationParams; |
| - } |
| - } |
| - |
| /** |
| * Implemented by ChildProcessLauncherHelper. |
| */ |
| public interface LaunchCallback { void onChildProcessStarted(int pid); } |
| - // Service class for child process. |
| - // Map from package name to ChildConnectionAllocator. |
| - private static Map<String, ChildConnectionAllocator> sSandboxedChildConnectionAllocatorMap; |
| - // As the default value it uses PrivilegedProcessService0. |
| - private static ChildConnectionAllocator sPrivilegedChildConnectionAllocator; |
| - |
| private static final boolean SPARE_CONNECTION_ALWAYS_IN_FOREGROUND = false; |
| - private static final String NUM_SANDBOXED_SERVICES_KEY = |
| - "org.chromium.content.browser.NUM_SANDBOXED_SERVICES"; |
| - private static final String NUM_PRIVILEGED_SERVICES_KEY = |
| - "org.chromium.content.browser.NUM_PRIVILEGED_SERVICES"; |
| - private static final String SANDBOXED_SERVICES_NAME_KEY = |
| - "org.chromium.content.browser.SANDBOXED_SERVICES_NAME"; |
| - |
| - // Used by tests to override the default sandboxed service settings. |
| - private static int sSandboxedServicesCountForTesting = -1; |
| - private static String sSandboxedServicesNameForTesting; |
| - |
| - @VisibleForTesting |
| - public static void setSanboxServicesSettingsForTesting(int serviceCount, String serviceName) { |
| - sSandboxedServicesCountForTesting = serviceCount; |
| - sSandboxedServicesNameForTesting = serviceName; |
| - } |
| - |
| - static int getNumberOfServices(Context context, boolean inSandbox, String packageName) { |
| - int numServices = -1; |
| - if (inSandbox && sSandboxedServicesCountForTesting != -1) { |
| - numServices = sSandboxedServicesCountForTesting; |
| - } else { |
| - try { |
| - PackageManager packageManager = context.getPackageManager(); |
| - ApplicationInfo appInfo = packageManager.getApplicationInfo(packageName, |
| - PackageManager.GET_META_DATA); |
| - if (appInfo.metaData != null) { |
| - numServices = appInfo.metaData.getInt(inSandbox |
| - ? NUM_SANDBOXED_SERVICES_KEY : NUM_PRIVILEGED_SERVICES_KEY, -1); |
| - } |
| - } catch (PackageManager.NameNotFoundException e) { |
| - throw new RuntimeException("Could not get application info"); |
| - } |
| - } |
| - if (numServices < 0) { |
| - throw new RuntimeException("Illegal meta data value for number of child services"); |
| - } |
| - return numServices; |
| - } |
| - |
| - private static String getClassNameOfService(Context context, boolean inSandbox, |
| - String packageName) { |
| - if (!inSandbox) { |
| - return PrivilegedProcessService.class.getName(); |
| - } |
| - |
| - if (!TextUtils.isEmpty(sSandboxedServicesNameForTesting)) { |
| - return sSandboxedServicesNameForTesting; |
| - } |
| - |
| - String serviceName = null; |
| - try { |
| - PackageManager packageManager = context.getPackageManager(); |
| - ApplicationInfo appInfo = |
| - packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA); |
| - if (appInfo.metaData != null) { |
| - serviceName = appInfo.metaData.getString(SANDBOXED_SERVICES_NAME_KEY); |
| - } |
| - } catch (PackageManager.NameNotFoundException e) { |
| - throw new RuntimeException("Could not get application info."); |
| - } |
| - |
| - if (serviceName != null) { |
| - // Check that the service exists. |
| - try { |
| - PackageManager packageManager = context.getPackageManager(); |
| - // PackageManager#getServiceInfo() throws an exception if the service does not |
| - // exist. |
| - packageManager.getServiceInfo(new ComponentName(packageName, serviceName + "0"), 0); |
| - return serviceName; |
| - } catch (PackageManager.NameNotFoundException e) { |
| - throw new RuntimeException( |
| - "Illegal meta data value: the child service doesn't exist"); |
| - } |
| - } |
| - return SandboxedProcessService.class.getName(); |
| - } |
| - |
| - private static void initConnectionAllocatorsIfNecessary( |
| - Context context, boolean inSandbox, String packageName) { |
| - // TODO(mariakhomenko): Uses an Object to lock the access. |
| - synchronized (ChildProcessLauncher.class) { |
| - if (inSandbox) { |
| - if (sSandboxedChildConnectionAllocatorMap == null) { |
| - sSandboxedChildConnectionAllocatorMap = |
| - new ConcurrentHashMap<String, ChildConnectionAllocator>(); |
| - } |
| - if (!sSandboxedChildConnectionAllocatorMap.containsKey(packageName)) { |
| - Log.w(TAG, "Create a new ChildConnectionAllocator with package name = %s," |
| - + " inSandbox = true", |
| - packageName); |
| - sSandboxedChildConnectionAllocatorMap.put(packageName, |
| - new ChildConnectionAllocator(true, |
| - getNumberOfServices(context, true, packageName), |
| - getClassNameOfService(context, true, packageName))); |
| - } |
| - } else if (sPrivilegedChildConnectionAllocator == null) { |
| - sPrivilegedChildConnectionAllocator = new ChildConnectionAllocator(false, |
| - getNumberOfServices(context, false, packageName), |
| - getClassNameOfService(context, false, packageName)); |
| - } |
| - // TODO(pkotwicz|hanxi): Figure out when old allocators should be removed from |
| - // {@code sSandboxedChildConnectionAllocatorMap}. |
| - } |
| - } |
| - |
| - /** |
| - * Note: please make sure that the Allocator has been initialized before calling this function. |
| - * Otherwise, always calls {@link initConnectionAllocatorsIfNecessary} first. |
| - */ |
| - private static ChildConnectionAllocator getConnectionAllocator( |
| - String packageName, boolean inSandbox) { |
| - if (!inSandbox) { |
| - return sPrivilegedChildConnectionAllocator; |
| - } |
| - return sSandboxedChildConnectionAllocatorMap.get(packageName); |
| - } |
| - |
| - private static ChildConnectionAllocator getAllocatorForTesting( |
| - Context context, String packageName, boolean inSandbox) { |
| - initConnectionAllocatorsIfNecessary(context, inSandbox, packageName); |
| - return getConnectionAllocator(packageName, inSandbox); |
| - } |
| - |
| private static ChildProcessConnection allocateConnection( |
| - SpawnData spawnData, Bundle childProcessCommonParams) { |
| + ChildSpawnData spawnData, Bundle childProcessCommonParams, boolean forWarmUp) { |
| ChildProcessConnection.DeathCallback deathCallback = |
| new ChildProcessConnection.DeathCallback() { |
| @Override |
| @@ -362,9 +58,8 @@ public class ChildProcessLauncher { |
| final boolean inSandbox = spawnData.isInSandbox(); |
| String packageName = |
| creationParams != null ? creationParams.getPackageName() : context.getPackageName(); |
| - initConnectionAllocatorsIfNecessary(context, inSandbox, packageName); |
| - return getConnectionAllocator(packageName, inSandbox) |
| - .allocate(spawnData, deathCallback, childProcessCommonParams); |
| + return ChildConnectionAllocator.getAllocator(context, packageName, inSandbox) |
| + .allocate(spawnData, deathCallback, childProcessCommonParams, !forWarmUp); |
| } |
| private static boolean sLinkerInitialized; |
| @@ -406,20 +101,21 @@ public class ChildProcessLauncher { |
| return commonParams; |
| } |
| - private static ChildProcessConnection allocateBoundConnection( |
| - SpawnData spawnData, ChildProcessConnection.StartCallback startCallback) { |
| + private static ChildProcessConnection allocateBoundConnection(ChildSpawnData spawnData, |
| + ChildProcessConnection.StartCallback startCallback, boolean forWarmUp) { |
| final Context context = spawnData.getContext(); |
| final boolean inSandbox = spawnData.isInSandbox(); |
| final ChildProcessCreationParams creationParams = spawnData.getCreationParams(); |
| + |
| ChildProcessConnection connection = allocateConnection( |
| - spawnData, createCommonParamsBundle(spawnData.getCreationParams())); |
| + spawnData, createCommonParamsBundle(spawnData.getCreationParams()), forWarmUp); |
| if (connection != null) { |
| connection.start(startCallback); |
| String packageName = creationParams != null ? creationParams.getPackageName() |
| : context.getPackageName(); |
| if (inSandbox |
| - && !getConnectionAllocator(packageName, inSandbox) |
| + && !ChildConnectionAllocator.getAllocator(context, packageName, inSandbox) |
| .isFreeConnectionAvailable()) { |
| // Proactively releases all the moderate bindings once all the sandboxed services |
| // are allocated, which will be very likely to have some of them killed by OOM |
| @@ -446,7 +142,7 @@ public class ChildProcessLauncher { |
| ThreadUtils.postOnUiThreadDelayed(new Runnable() { |
| @Override |
| public void run() { |
| - final SpawnData pendingSpawn = freeConnectionAndDequeuePending(conn); |
| + final ChildSpawnData pendingSpawn = freeConnectionAndDequeuePending(conn); |
| if (pendingSpawn != null) { |
| LauncherThread.post(new Runnable() { |
| @Override |
| @@ -465,9 +161,14 @@ public class ChildProcessLauncher { |
| }, FREE_CONNECTION_DELAY_MILLIS); |
| } |
| - private static SpawnData freeConnectionAndDequeuePending(ChildProcessConnection conn) { |
| - ChildConnectionAllocator allocator = getConnectionAllocator( |
| - conn.getPackageName(), conn.isInSandbox()); |
| + private static ChildSpawnData freeConnectionAndDequeuePending(ChildProcessConnection conn) { |
| + // TODO(jcivelli): it should be safe to pass a null Context here as it is used to initialize |
|
boliu
2017/04/12 00:20:16
assert in getAllocator that the cases where a new
Jay Civelli
2017/04/12 00:47:15
We could, but you'll get an NPE with a nice stack-
|
| + // the ChildConnectionAllocator object and if we are freeing a connection, we must have |
| + // allocated one previously guaranteeing it is already initialized. |
| + // When we consolidate ChildProcessLauncher and ChildProcessLauncherHelper, we'll have a |
| + // context around that we can pass in there. |
| + ChildConnectionAllocator allocator = ChildConnectionAllocator.getAllocator( |
| + null /* context */, conn.getPackageName(), conn.isInSandbox()); |
| assert allocator != null; |
| return allocator.free(conn); |
| } |
| @@ -533,8 +234,9 @@ public class ChildProcessLauncher { |
| * sent to the background. |
| */ |
| public static void startModerateBindingManagement(Context context) { |
| - sBindingManager.startModerateBindingManagement( |
| - context, getNumberOfServices(context, true, context.getPackageName())); |
| + sBindingManager.startModerateBindingManagement(context, |
| + ChildConnectionAllocator.getNumberOfServices( |
| + context, true, context.getPackageName())); |
| } |
| /** |
| @@ -587,13 +289,13 @@ public class ChildProcessLauncher { |
| } |
| } |
| }; |
| - SpawnData spawnData = new SpawnData(true /* forWarmUp*/, context, |
| + ChildSpawnData spawnData = new ChildSpawnData(context, |
| null /* commandLine */, -1 /* child process id */, |
| null /* filesToBeMapped */, null /* launchCallback */, |
| null /* child process callback */, true /* inSandbox */, |
| SPARE_CONNECTION_ALWAYS_IN_FOREGROUND, params); |
| - sSpareSandboxedConnection = |
| - allocateBoundConnection(spawnData, startCallback); |
| + sSpareSandboxedConnection = allocateBoundConnection( |
| + spawnData, startCallback, true /* forWarmUp */); |
| } |
| } |
| } |
| @@ -707,10 +409,11 @@ public class ChildProcessLauncher { |
| } |
| }; |
| - SpawnData spawnData = new SpawnData(false /* forWarmUp */, context, commandLine, |
| - childProcessId, filesToBeMapped, launchCallback, childProcessCallback, |
| - inSandbox, alwaysInForeground, creationParams); |
| - allocatedConnection = allocateBoundConnection(spawnData, startCallback); |
| + ChildSpawnData spawnData = new ChildSpawnData(context, commandLine, childProcessId, |
| + filesToBeMapped, launchCallback, childProcessCallback, inSandbox, |
| + alwaysInForeground, creationParams); |
| + allocatedConnection = |
| + allocateBoundConnection(spawnData, startCallback, false /* forWarmUp */); |
| if (allocatedConnection == null) { |
| return null; |
| } |
| @@ -798,22 +501,22 @@ public class ChildProcessLauncher { |
| static ChildProcessConnection allocateBoundConnectionForTesting(Context context, |
| ChildProcessCreationParams creationParams) { |
| return allocateBoundConnection( |
| - new SpawnData(false /* forWarmUp */, context, null /* commandLine */, |
| - 0 /* childProcessId */, null /* filesToBeMapped */, |
| - null /* LaunchCallback */, null /* childProcessCallback */, |
| - true /* inSandbox */, false /* alwaysInForeground */, creationParams), |
| - null /* startCallback */); |
| + new ChildSpawnData(context, null /* commandLine */, 0 /* childProcessId */, |
| + null /* filesToBeMapped */, null /* LaunchCallback */, |
| + null /* childProcessCallback */, true /* inSandbox */, |
| + false /* alwaysInForeground */, creationParams), |
| + null /* startCallback */, false /* forWarmUp */); |
| } |
| @VisibleForTesting |
| static ChildProcessConnection allocateConnectionForTesting( |
| Context context, ChildProcessCreationParams creationParams) { |
| return allocateConnection( |
| - new SpawnData(false /* forWarmUp */, context, null /* commandLine */, |
| - 0 /* childProcessId */, null /* filesToBeMapped */, |
| - null /* launchCallback */, null /* childProcessCallback */, |
| - true /* inSandbox */, false /* alwaysInForeground */, creationParams), |
| - createCommonParamsBundle(creationParams)); |
| + new ChildSpawnData(context, null /* commandLine */, 0 /* childProcessId */, |
| + null /* filesToBeMapped */, null /* launchCallback */, |
| + null /* childProcessCallback */, true /* inSandbox */, |
| + false /* alwaysInForeground */, creationParams), |
| + createCommonParamsBundle(creationParams), false /* forWarmUp */); |
| } |
| /** |
| @@ -825,10 +528,10 @@ public class ChildProcessLauncher { |
| String packageName = creationParams != null ? creationParams.getPackageName() |
| : context.getPackageName(); |
| ChildConnectionAllocator allocator = |
| - getAllocatorForTesting(context, packageName, inSandbox); |
| - allocator.enqueuePendingQueueForTesting(new SpawnData(false /* forWarmUp*/, context, |
| - commandLine, 1 /* childProcessId */, new FileDescriptorInfo[0], |
| - null /* launchCallback */, null /* childProcessCallback */, true /* inSandbox */, |
| + ChildConnectionAllocator.getAllocator(context, packageName, inSandbox); |
| + allocator.enqueuePendingQueueForTesting(new ChildSpawnData(context, commandLine, |
| + 1 /* childProcessId */, new FileDescriptorInfo[0], null /* launchCallback */, |
| + null /* childProcessCallback */, true /* inSandbox */, |
| false /* alwaysInForeground */, creationParams)); |
| } |
| @@ -838,8 +541,7 @@ public class ChildProcessLauncher { |
| */ |
| @VisibleForTesting |
| static int allocatedSandboxedConnectionsCountForTesting(Context context, String packageName) { |
| - initConnectionAllocatorsIfNecessary(context, true, packageName); |
| - return sSandboxedChildConnectionAllocatorMap.get(packageName) |
| + return ChildConnectionAllocator.getAllocator(context, packageName, true /*isSandboxed */) |
| .allocatedConnectionsCountForTesting(); |
| } |
| @@ -847,8 +549,10 @@ public class ChildProcessLauncher { |
| * @return gets the service connection array for a specific package name. |
| */ |
| @VisibleForTesting |
| - static ChildProcessConnection[] getSandboxedConnectionArrayForTesting(String packageName) { |
| - return sSandboxedChildConnectionAllocatorMap.get(packageName).connectionArrayForTesting(); |
| + static ChildProcessConnection[] getSandboxedConnectionArrayForTesting( |
| + Context context, String packageName) { |
| + return ChildConnectionAllocator.getAllocator(context, packageName, true /*isSandboxed */) |
| + .connectionArrayForTesting(); |
| } |
| /** @return the count of services set up and working */ |
| @@ -866,9 +570,8 @@ public class ChildProcessLauncher { |
| @VisibleForTesting |
| static int pendingSpawnsCountForTesting( |
| Context context, String packageName, boolean inSandbox) { |
| - ChildConnectionAllocator allocator = |
| - getAllocatorForTesting(context, packageName, inSandbox); |
| - return allocator.pendingSpawnsCountForTesting(); |
| + return ChildConnectionAllocator.getAllocator(context, packageName, inSandbox) |
| + .pendingSpawnsCountForTesting(); |
| } |
| /** |