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

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

Issue 2626413004: Bind Android ChildProcessServices to a specific client PID. (Closed)
Patch Set: '' Created 3 years, 11 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 aed55c3f5328b61e80ea44f357b26f3418a24258..935d1c3a2b8c193e85507ebf6eccb2641acf83c2 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
@@ -8,6 +8,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
+import android.os.AsyncTask;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
@@ -413,12 +414,13 @@ public class ChildProcessLauncher {
private static ChildProcessConnection allocateBoundConnection(Context context,
String[] commandLine, boolean inSandbox, boolean alwaysInForeground,
- ChildProcessCreationParams creationParams) {
+ ChildProcessCreationParams creationParams,
+ ChildProcessConnection.StartCallback startCallback) {
ChromiumLinkerParams chromiumLinkerParams = getLinkerParamsForNewConnection();
ChildProcessConnection connection = allocateConnection(
context, inSandbox, chromiumLinkerParams, alwaysInForeground, creationParams);
if (connection != null) {
- connection.start(commandLine);
+ connection.start(commandLine, startCallback);
String packageName = creationParams != null ? creationParams.getPackageName()
: context.getPackageName();
@@ -436,7 +438,7 @@ public class ChildProcessLauncher {
private static final long FREE_CONNECTION_DELAY_MILLIS = 1;
private static void freeConnection(ChildProcessConnection connection) {
- synchronized (ChildProcessLauncher.class) {
+ synchronized (sSpareConnectionLock) {
if (connection.equals(sSpareSandboxedConnection)) sSpareSandboxedConnection = null;
}
@@ -483,8 +485,16 @@ public class ChildProcessLauncher {
private static Map<Integer, ChildProcessConnection> sServiceMap =
new ConcurrentHashMap<Integer, ChildProcessConnection>();
+ // Lock and monitor for these members {{{
+ private static final Object sSpareConnectionLock = new Object();
// A pre-allocated and pre-bound connection ready for connection setup, or null.
private static ChildProcessConnection sSpareSandboxedConnection;
+ // If sSpareSandboxedConnection is not null, this indicates whether the service is
+ // ready for connection setup. Wait on the monitor lock to be notified when this
+ // state changes. sSpareSandboxedConnection may be null after waiting, if starting
+ // the service failed.
+ private static boolean sSpareConnectionStarting;
+ // }}}
// Manages oom bindings used to bind chind services.
private static BindingManager sBindingManager = BindingManagerImpl.createBindingManager();
@@ -567,15 +577,38 @@ public class ChildProcessLauncher {
* @param context the application context used for the connection.
*/
public static void warmUp(Context context) {
- synchronized (ChildProcessLauncher.class) {
+ synchronized (sSpareConnectionLock) {
assert !ThreadUtils.runningOnUiThread();
if (sSpareSandboxedConnection == null) {
ChildProcessCreationParams params = ChildProcessCreationParams.get();
if (params != null) {
params = params.copy();
}
+
Tobias Sargeant 2017/01/14 23:24:58 Presumably the fact that warmUp doesn't retry mean
Robert Sesek 2017/01/17 19:51:22 Since warmUp is only used for the first connection
+ sSpareConnectionStarting = true;
+
+ ChildProcessConnection.StartCallback startCallback =
+ new ChildProcessConnection.StartCallback() {
+ @Override
+ public void onChildStarted() {
+ synchronized (sSpareConnectionLock) {
+ sSpareConnectionStarting = false;
+ sSpareConnectionLock.notify();
+ }
+ }
+
+ @Override
+ public void onChildStartFailed() {
+ Log.e(TAG, "Failed to warm up the spare sandbox service");
+ synchronized (sSpareConnectionLock) {
+ sSpareSandboxedConnection = null;
+ sSpareConnectionStarting = false;
+ sSpareConnectionLock.notify();
+ }
+ }
+ };
sSpareSandboxedConnection = allocateBoundConnection(context, null, true, false,
- params);
+ params, startCallback);
}
}
}
@@ -654,23 +687,29 @@ public class ChildProcessLauncher {
}
private static void startInternal(
- Context context,
+ final Context context,
final String[] commandLine,
- int childProcessId,
- FileDescriptorInfo[] filesToBeMapped,
- long clientContext,
- int callbackType,
- boolean inSandbox,
- ChildProcessCreationParams creationParams) {
+ final int childProcessId,
+ final FileDescriptorInfo[] filesToBeMapped,
+ final long clientContext,
+ final int callbackType,
+ final boolean inSandbox,
+ final ChildProcessCreationParams creationParams) {
try {
TraceEvent.begin("ChildProcessLauncher.startInternal");
ChildProcessConnection allocatedConnection = null;
String packageName = creationParams != null ? creationParams.getPackageName()
: context.getPackageName();
- synchronized (ChildProcessLauncher.class) {
+ synchronized (sSpareConnectionLock) {
if (inSandbox && sSpareSandboxedConnection != null
&& sSpareSandboxedConnection.getPackageName().equals(packageName)) {
+ while (sSpareConnectionStarting) {
+ try {
+ sSpareConnectionLock.wait();
+ } catch (InterruptedException ex) {
+ }
+ }
allocatedConnection = sSpareSandboxedConnection;
sSpareSandboxedConnection = null;
}
@@ -680,9 +719,29 @@ public class ChildProcessLauncher {
if (callbackType == CALLBACK_FOR_GPU_PROCESS) alwaysInForeground = true;
PendingSpawnQueue pendingSpawnQueue = getPendingSpawnQueue(
context, packageName, inSandbox);
+ ChildProcessConnection.StartCallback startCallback =
+ new ChildProcessConnection.StartCallback() {
+ @Override
+ public void onChildStarted() {}
+
+ @Override
+ public void onChildStartFailed() {
+ Log.e(TAG, "ChildProcessConnection.start failed, trying again");
+ new AsyncTask<Void, Void, Void>() {
Torne 2017/01/16 12:44:43 If the asynctask only has a doInBackground and is
Robert Sesek 2017/01/17 19:51:22 Done.
+ @Override
+ protected Void doInBackground(Void... params) {
+ startInternal(context, commandLine, childProcessId,
+ filesToBeMapped, clientContext, callbackType,
+ inSandbox, creationParams);
+ return null;
+ }
+ }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+ };
synchronized (pendingSpawnQueue.mPendingSpawnsLock) {
allocatedConnection = allocateBoundConnection(
- context, commandLine, inSandbox, alwaysInForeground, creationParams);
+ context, commandLine, inSandbox, alwaysInForeground, creationParams,
+ startCallback);
if (allocatedConnection == null) {
Log.d(TAG, "Allocation of new service failed. Queuing up pending spawn.");
pendingSpawnQueue.enqueueLocked(new PendingSpawnData(context, commandLine,
@@ -836,7 +895,7 @@ public class ChildProcessLauncher {
@VisibleForTesting
static ChildProcessConnection allocateBoundConnectionForTesting(Context context,
ChildProcessCreationParams creationParams) {
- return allocateBoundConnection(context, null, true, false, creationParams);
+ return allocateBoundConnection(context, null, true, false, creationParams, null);
}
@VisibleForTesting

Powered by Google App Engine
This is Rietveld 408576698