Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(183)

Unified Diff: content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java

Issue 2863063002: Making ChildConnectionAllocator simpler. (Closed)
Patch Set: Fixed tests. Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 be6e4f0bb7b919e5d27ef3dc3865ccc564ee0742..440978993fc28f09af0872d98ad3fc596de7a75c 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
@@ -9,6 +9,7 @@ import android.content.Context;
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;
@@ -20,8 +21,10 @@ 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.SandboxedProcessService;
import org.chromium.content.common.ContentSwitches;
+import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -35,6 +38,15 @@ import java.util.concurrent.ConcurrentHashMap;
public class ChildProcessLauncher {
private static final String TAG = "ChildProcLauncher";
+ private static final String NUM_SANDBOXED_SERVICES_KEY =
+ "org.chromium.content.browser.NUM_SANDBOXED_SERVICES";
+ private static final String SANDBOXED_SERVICES_NAME_KEY =
+ "org.chromium.content.browser.SANDBOXED_SERVICES_NAME";
+ private static final String NUM_PRIVILEGED_SERVICES_KEY =
+ "org.chromium.content.browser.NUM_PRIVILEGED_SERVICES";
+ private static final String PRIVILEGED_SERVICES_NAME_KEY =
+ "org.chromium.content.browser.PRIVILEGED_SERVICES_NAME";
+
/**
* Implemented by ChildProcessLauncherHelper.
*/
@@ -44,6 +56,60 @@ public class ChildProcessLauncher {
private static final boolean SPARE_CONNECTION_ALWAYS_IN_FOREGROUND = false;
+ // Map from package name to ChildConnectionAllocator.
+ private static final Map<String, ChildConnectionAllocator>
+ sSandboxedChildConnectionAllocatorMap = new HashMap<>();
+
+ // Map from a connection to its ChildConnectionAllocator.
+ private static final Map<BaseChildProcessConnection, ChildConnectionAllocator>
+ sConnectionsToAllocatorMap = new HashMap<>();
+
+ // Allocator used for non-sandboxed services.
+ private static ChildConnectionAllocator sPrivilegedChildConnectionAllocator;
+
+ // Used by test to override the default sandboxed service allocator settings.
+ private static int sSandboxedServicesCountForTesting = -1;
+ private static String sSandboxedServicesNameForTesting;
+
+ @SuppressFBWarnings("LI_LAZY_INIT_STATIC") // Method is single thread.
+ public static ChildConnectionAllocator getConnectionAllocator(
+ Context context, String packageName, boolean sandboxed) {
+ assert LauncherThread.runningOnLauncherThread();
+ if (!sandboxed) {
+ if (sPrivilegedChildConnectionAllocator == null) {
+ sPrivilegedChildConnectionAllocator = ChildConnectionAllocator.create(context,
+ ImportantChildProcessConnection.FACTORY, packageName,
+ PRIVILEGED_SERVICES_NAME_KEY, NUM_PRIVILEGED_SERVICES_KEY);
+ }
+ return sPrivilegedChildConnectionAllocator;
+ }
+
+ if (!sSandboxedChildConnectionAllocatorMap.containsKey(packageName)) {
+ Log.w(TAG,
+ "Create a new ChildConnectionAllocator with package name = %s,"
+ + " inSandbox = true",
+ packageName);
+ ChildConnectionAllocator connectionAllocator = null;
+ if (sSandboxedServicesCountForTesting != -1) {
+ // Testing case where allocator settings are overriden.
+ String serviceName = !TextUtils.isEmpty(sSandboxedServicesNameForTesting)
+ ? sSandboxedServicesNameForTesting
+ : SandboxedProcessService.class.getName();
+ connectionAllocator = ChildConnectionAllocator.createForTest(
+ ManagedChildProcessConnection.FACTORY, packageName, serviceName,
+ sSandboxedServicesCountForTesting);
+ } else {
+ connectionAllocator = ChildConnectionAllocator.create(context,
+ ManagedChildProcessConnection.FACTORY, packageName,
+ SANDBOXED_SERVICES_NAME_KEY, NUM_SANDBOXED_SERVICES_KEY);
+ }
+ sSandboxedChildConnectionAllocatorMap.put(packageName, connectionAllocator);
+ }
+ return sSandboxedChildConnectionAllocatorMap.get(packageName);
+ // TODO(pkotwicz|hanxi): Figure out when old allocators should be removed from
+ // {@code sSandboxedChildConnectionAllocatorMap}.
+ }
+
@VisibleForTesting
static BaseChildProcessConnection allocateConnection(
ChildSpawnData spawnData, Bundle childProcessCommonParams, boolean forWarmUp) {
@@ -65,8 +131,12 @@ public class ChildProcessLauncher {
final boolean inSandbox = spawnData.isInSandbox();
String packageName =
creationParams != null ? creationParams.getPackageName() : context.getPackageName();
- return ChildConnectionAllocator.getAllocator(context, packageName, inSandbox)
- .allocate(spawnData, deathCallback, childProcessCommonParams, !forWarmUp);
+ ChildConnectionAllocator allocator =
+ getConnectionAllocator(context, packageName, inSandbox);
+ BaseChildProcessConnection connection =
+ allocator.allocate(spawnData, deathCallback, childProcessCommonParams, !forWarmUp);
+ sConnectionsToAllocatorMap.put(connection, allocator);
+ return connection;
}
private static boolean sLinkerInitialized;
@@ -125,8 +195,7 @@ public class ChildProcessLauncher {
String packageName = creationParams != null ? creationParams.getPackageName()
: context.getPackageName();
if (inSandbox
- && !ChildConnectionAllocator
- .getAllocator(context, packageName, true /* sandboxed */)
+ && !getConnectionAllocator(context, packageName, true /* sandboxed */)
.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
@@ -152,14 +221,7 @@ public class ChildProcessLauncher {
LauncherThread.postDelayed(new Runnable() {
@Override
public void run() {
- // TODO(jcivelli): it should be safe to pass a null Context here as it is used to
- // initialize 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.isSandboxed());
+ ChildConnectionAllocator allocator = sConnectionsToAllocatorMap.remove(conn);
assert allocator != null;
final ChildSpawnData pendingSpawn = allocator.free(conn);
if (pendingSpawn != null) {
@@ -282,9 +344,10 @@ public class ChildProcessLauncher {
LauncherThread.post(new Runnable() {
@Override
public void run() {
- getBindingManager().startModerateBindingManagement(context,
- ChildConnectionAllocator.getNumberOfServices(
- context, true, context.getPackageName()));
+ ChildConnectionAllocator allocator = getConnectionAllocator(
+ context, context.getPackageName(), true /* sandboxed */);
+ getBindingManager().startModerateBindingManagement(
+ context, allocator.getNumberOfServices());
}
});
}
@@ -538,12 +601,27 @@ public class ChildProcessLauncher {
freeConnection(connection);
}
+ public static int getNumberOfSandboxedServices(Context context, String packageName) {
+ assert ThreadUtils.runningOnUiThread();
+ if (sSandboxedServicesCountForTesting != -1) {
+ return sSandboxedServicesCountForTesting;
+ }
+ return ChildConnectionAllocator.getNumberOfServices(
+ context, packageName, NUM_SANDBOXED_SERVICES_KEY);
+ }
+
/** @return the count of services set up and working */
@VisibleForTesting
static int connectedServicesCountForTesting() {
return sServiceMap.size();
}
+ @VisibleForTesting
+ public static void setSandboxServicesSettingsForTesting(int serviceCount, String serviceName) {
+ sSandboxedServicesCountForTesting = serviceCount;
+ sSandboxedServicesNameForTesting = serviceName;
+ }
+
/**
* Kills the child process for testing.
* @return true iff the process was killed as expected

Powered by Google App Engine
This is Rietveld 408576698