| Index: content/public/android/java/src/org/chromium/content/browser/ChildProcessConnection.java
|
| diff --git a/content/public/android/java/src/org/chromium/content/browser/SandboxedProcessConnection.java b/content/public/android/java/src/org/chromium/content/browser/ChildProcessConnection.java
|
| similarity index 65%
|
| rename from content/public/android/java/src/org/chromium/content/browser/SandboxedProcessConnection.java
|
| rename to content/public/android/java/src/org/chromium/content/browser/ChildProcessConnection.java
|
| index c28a3c4d66b8997a439e8e4c9e4650c044714ab1..66012c5919515eb7a65f862af3b2bd2b85137d99 100644
|
| --- a/content/public/android/java/src/org/chromium/content/browser/SandboxedProcessConnection.java
|
| +++ b/content/public/android/java/src/org/chromium/content/browser/ChildProcessConnection.java
|
| @@ -22,62 +22,63 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
| import org.chromium.base.CalledByNative;
|
| import org.chromium.base.CpuFeatures;
|
| import org.chromium.base.ThreadUtils;
|
| -import org.chromium.content.app.SandboxedProcessService;
|
| +import org.chromium.content.app.ChildProcessService;
|
| import org.chromium.content.common.CommandLine;
|
| -import org.chromium.content.common.ISandboxedProcessCallback;
|
| -import org.chromium.content.common.ISandboxedProcessService;
|
| +import org.chromium.content.common.IChildProcessCallback;
|
| +import org.chromium.content.common.IChildProcessService;
|
| import org.chromium.content.common.TraceEvent;
|
|
|
| -public class SandboxedProcessConnection implements ServiceConnection {
|
| +public class ChildProcessConnection implements ServiceConnection {
|
| interface DeathCallback {
|
| - void onSandboxedProcessDied(int pid);
|
| + void onChildProcessDied(int pid);
|
| }
|
|
|
| // Names of items placed in the bind intent or connection bundle.
|
| public static final String EXTRA_COMMAND_LINE =
|
| - "com.google.android.apps.chrome.extra.sandbox_command_line";
|
| + "com.google.android.apps.chrome.extra.command_line";
|
| public static final String EXTRA_NATIVE_LIBRARY_NAME =
|
| - "com.google.android.apps.chrome.extra.sandbox_native_library_name";
|
| + "com.google.android.apps.chrome.extra.native_library_name";
|
| // Note the FDs may only be passed in the connection bundle.
|
| public static final String EXTRA_FILES_PREFIX =
|
| - "com.google.android.apps.chrome.extra.sandbox_extraFile_";
|
| + "com.google.android.apps.chrome.extra.extraFile_";
|
| public static final String EXTRA_FILES_ID_SUFFIX = "_id";
|
| public static final String EXTRA_FILES_FD_SUFFIX = "_fd";
|
|
|
| - // Used to pass the CPU core count to sandboxed processes.
|
| + // Used to pass the CPU core count to child processes.
|
| public static final String EXTRA_CPU_COUNT =
|
| "com.google.android.apps.chrome.extra.cpu_count";
|
| - // Used to pass the CPU features mask to sandboxed processes.
|
| + // Used to pass the CPU features mask to child processes.
|
| public static final String EXTRA_CPU_FEATURES =
|
| "com.google.android.apps.chrome.extra.cpu_features";
|
|
|
| private final Context mContext;
|
| private final int mServiceNumber;
|
| - private final SandboxedProcessConnection.DeathCallback mDeathCallback;
|
| - private final Class<? extends SandboxedProcessService> mServiceClass;
|
| + private final ChildProcessConnection.DeathCallback mDeathCallback;
|
| + private final Class<? extends ChildProcessService> mServiceClass;
|
|
|
| // Synchronization: While most internal flow occurs on the UI thread, the public API
|
| // (specifically bind and unbind) may be called from any thread, hence all entry point methods
|
| - // into the class are synchronized on the SandboxedProcessConnection instance to protect access
|
| + // into the class are synchronized on the ChildProcessConnection instance to protect access
|
| // to these members. But see also the TODO where AsyncBoundServiceConnection is created.
|
| - private ISandboxedProcessService mService = null;
|
| + private final Object mUiThreadLock = new Object();
|
| + private IChildProcessService mService = null;
|
| private boolean mServiceConnectComplete = false;
|
| - private int mPID = 0; // Process ID of the corresponding sandboxed process.
|
| + private int mPID = 0; // Process ID of the corresponding child process.
|
| private HighPriorityConnection mHighPriorityConnection = null;
|
| private int mHighPriorityConnectionCount = 0;
|
|
|
| - private static final String TAG = "SandboxedProcessConnection";
|
| + private static final String TAG = "ChildProcessConnection";
|
|
|
| private static class ConnectionParams {
|
| final String[] mCommandLine;
|
| final FileDescriptorInfo[] mFilesToBeMapped;
|
| - final ISandboxedProcessCallback mCallback;
|
| + final IChildProcessCallback mCallback;
|
| final Runnable mOnConnectionCallback;
|
|
|
| ConnectionParams(
|
| String[] commandLine,
|
| FileDescriptorInfo[] filesToBeMapped,
|
| - ISandboxedProcessCallback callback,
|
| + IChildProcessCallback callback,
|
| Runnable onConnectionCallback) {
|
| mCommandLine = commandLine;
|
| mFilesToBeMapped = filesToBeMapped;
|
| @@ -90,9 +91,9 @@ public class SandboxedProcessConnection implements ServiceConnection {
|
| private ConnectionParams mConnectionParams;
|
| private boolean mIsBound;
|
|
|
| - SandboxedProcessConnection(Context context, int number,
|
| - SandboxedProcessConnection.DeathCallback deathCallback,
|
| - Class<? extends SandboxedProcessService> serviceClass) {
|
| + ChildProcessConnection(Context context, int number,
|
| + ChildProcessConnection.DeathCallback deathCallback,
|
| + Class<? extends ChildProcessService> serviceClass) {
|
| mContext = context;
|
| mServiceNumber = number;
|
| mDeathCallback = deathCallback;
|
| @@ -103,43 +104,48 @@ public class SandboxedProcessConnection implements ServiceConnection {
|
| return mServiceNumber;
|
| }
|
|
|
| - synchronized ISandboxedProcessService getService() {
|
| - return mService;
|
| + IChildProcessService getService() {
|
| + synchronized(mUiThreadLock) {
|
| + return mService;
|
| + }
|
| }
|
|
|
| private Intent createServiceBindIntent() {
|
| Intent intent = new Intent();
|
| - intent.setClassName(mContext, mServiceClass.getName() + mServiceNumber);
|
| + String serviceClassNameBase = mServiceClass.getName().replaceAll("[0-9]*$", "");
|
| + intent.setClassName(mContext, serviceClassNameBase + mServiceNumber);
|
| intent.setPackage(mContext.getPackageName());
|
| return intent;
|
| }
|
|
|
| /**
|
| - * Bind to an ISandboxedProcessService. This must be followed by a call to setupConnection()
|
| + * Bind to an IChildProcessService. This must be followed by a call to setupConnection()
|
| * to setup the connection parameters. (These methods are separated to allow the client
|
| * to pass whatever parameters they have available here, and complete the remainder
|
| * later while reducing the connection setup latency).
|
| * @param nativeLibraryName The name of the shared native library to be loaded for the
|
| - * sandboxed process.
|
| - * @param commandLine (Optional) Command line for the sandboxed process. If omitted, then
|
| + * child process.
|
| + * @param commandLine (Optional) Command line for the child process. If omitted, then
|
| * the command line parameters must instead be passed to setupConnection().
|
| */
|
| - synchronized void bind(String nativeLibraryName, String[] commandLine) {
|
| - TraceEvent.begin();
|
| - assert !ThreadUtils.runningOnUiThread();
|
| + void bind(String nativeLibraryName, String[] commandLine) {
|
| + synchronized(mUiThreadLock) {
|
| + TraceEvent.begin();
|
| + assert !ThreadUtils.runningOnUiThread();
|
|
|
| - final Intent intent = createServiceBindIntent();
|
| + final Intent intent = createServiceBindIntent();
|
|
|
| - intent.putExtra(EXTRA_NATIVE_LIBRARY_NAME, nativeLibraryName);
|
| - if (commandLine != null) {
|
| - intent.putExtra(EXTRA_COMMAND_LINE, commandLine);
|
| - }
|
| + intent.putExtra(EXTRA_NATIVE_LIBRARY_NAME, nativeLibraryName);
|
| + if (commandLine != null) {
|
| + intent.putExtra(EXTRA_COMMAND_LINE, commandLine);
|
| + }
|
|
|
| - mIsBound = mContext.bindService(intent, this, Context.BIND_AUTO_CREATE);
|
| - if (!mIsBound) {
|
| - onBindFailed();
|
| + mIsBound = mContext.bindService(intent, this, Context.BIND_AUTO_CREATE);
|
| + if (!mIsBound) {
|
| + onBindFailed();
|
| + }
|
| + TraceEvent.end();
|
| }
|
| - TraceEvent.end();
|
| }
|
|
|
| /** Setup a connection previous bound via a call to bind().
|
| @@ -150,50 +156,56 @@ public class SandboxedProcessConnection implements ServiceConnection {
|
| * @param callback Used for status updates regarding this process connection.
|
| * @param onConnectionCallback will be run when the connection is setup and ready to use.
|
| */
|
| - synchronized void setupConnection(
|
| + void setupConnection(
|
| String[] commandLine,
|
| FileDescriptorInfo[] filesToBeMapped,
|
| - ISandboxedProcessCallback callback,
|
| + IChildProcessCallback callback,
|
| Runnable onConnectionCallback) {
|
| - TraceEvent.begin();
|
| - assert mConnectionParams == null;
|
| - mConnectionParams = new ConnectionParams(commandLine, filesToBeMapped, callback,
|
| - onConnectionCallback);
|
| - if (mServiceConnectComplete) {
|
| - doConnectionSetup();
|
| + synchronized(mUiThreadLock) {
|
| + TraceEvent.begin();
|
| + assert mConnectionParams == null;
|
| + mConnectionParams = new ConnectionParams(commandLine, filesToBeMapped, callback,
|
| + onConnectionCallback);
|
| + if (mServiceConnectComplete) {
|
| + doConnectionSetup();
|
| + }
|
| + TraceEvent.end();
|
| }
|
| - TraceEvent.end();
|
| }
|
|
|
| /**
|
| - * Unbind the ISandboxedProcessService. It is safe to call this multiple times.
|
| + * Unbind the IChildProcessService. It is safe to call this multiple times.
|
| */
|
| - synchronized void unbind() {
|
| - if (mIsBound) {
|
| - mContext.unbindService(this);
|
| - mIsBound = false;
|
| - }
|
| - if (mService != null) {
|
| - if (mHighPriorityConnection != null) {
|
| - unbindHighPriority(true);
|
| + void unbind() {
|
| + synchronized(mUiThreadLock) {
|
| + if (mIsBound) {
|
| + mContext.unbindService(this);
|
| + mIsBound = false;
|
| + }
|
| + if (mService != null) {
|
| + if (mHighPriorityConnection != null) {
|
| + unbindHighPriority(true);
|
| + }
|
| + mService = null;
|
| + mPID = 0;
|
| }
|
| - mService = null;
|
| - mPID = 0;
|
| + mConnectionParams = null;
|
| + mServiceConnectComplete = false;
|
| }
|
| - mConnectionParams = null;
|
| - mServiceConnectComplete = false;
|
| }
|
|
|
| // Called on the main thread to notify that the service is connected.
|
| @Override
|
| public void onServiceConnected(ComponentName className, IBinder service) {
|
| - TraceEvent.begin();
|
| - mServiceConnectComplete = true;
|
| - mService = ISandboxedProcessService.Stub.asInterface(service);
|
| - if (mConnectionParams != null) {
|
| - doConnectionSetup();
|
| + synchronized(mUiThreadLock) {
|
| + TraceEvent.begin();
|
| + mServiceConnectComplete = true;
|
| + mService = IChildProcessService.Stub.asInterface(service);
|
| + if (mConnectionParams != null) {
|
| + doConnectionSetup();
|
| + }
|
| + TraceEvent.end();
|
| }
|
| - TraceEvent.end();
|
| }
|
|
|
| // Called on the main thread to notify that the bindService() call failed (returned false).
|
| @@ -212,8 +224,7 @@ public class SandboxedProcessConnection implements ServiceConnection {
|
| TraceEvent.begin();
|
| assert mServiceConnectComplete && mConnectionParams != null;
|
| // Capture the callback before it is potentially nulled in unbind().
|
| - Runnable onConnectionCallback =
|
| - mConnectionParams != null ? mConnectionParams.mOnConnectionCallback : null;
|
| + Runnable onConnectionCallback = mConnectionParams.mOnConnectionCallback;
|
| if (onConnectionCallback == null) {
|
| unbind();
|
| } else if (mService != null) {
|
| @@ -273,7 +284,7 @@ public class SandboxedProcessConnection implements ServiceConnection {
|
| TraceEvent.end();
|
| }
|
|
|
| - // Called on the main thread to notify that the sandboxed service did not disconnect gracefully.
|
| + // Called on the main thread to notify that the child service did not disconnect gracefully.
|
| @Override
|
| public void onServiceDisconnected(ComponentName className) {
|
| int pid = mPID; // Stash pid & connection callback since unbind() will clear them.
|
| @@ -282,7 +293,7 @@ public class SandboxedProcessConnection implements ServiceConnection {
|
| Log.w(TAG, "onServiceDisconnected (crash?): pid=" + pid);
|
| unbind(); // We don't want to auto-restart on crash. Let the browser do that.
|
| if (pid != 0) {
|
| - mDeathCallback.onSandboxedProcessDied(pid);
|
| + mDeathCallback.onChildProcessDied(pid);
|
| }
|
| if (onConnectionCallback != null) {
|
| onConnectionCallback.run();
|
| @@ -293,30 +304,34 @@ public class SandboxedProcessConnection implements ServiceConnection {
|
| * Bind the service with a new high priority connection. This will make the service
|
| * as important as the main process.
|
| */
|
| - synchronized void bindHighPriority() {
|
| - if (mService == null) {
|
| - Log.w(TAG, "The connection is not bound for " + mPID);
|
| - return;
|
| - }
|
| - if (mHighPriorityConnection == null) {
|
| - mHighPriorityConnection = new HighPriorityConnection();
|
| - mHighPriorityConnection.bind();
|
| + void bindHighPriority() {
|
| + synchronized(mUiThreadLock) {
|
| + if (mService == null) {
|
| + Log.w(TAG, "The connection is not bound for " + mPID);
|
| + return;
|
| + }
|
| + if (mHighPriorityConnection == null) {
|
| + mHighPriorityConnection = new HighPriorityConnection();
|
| + mHighPriorityConnection.bind();
|
| + }
|
| + mHighPriorityConnectionCount++;
|
| }
|
| - mHighPriorityConnectionCount++;
|
| }
|
|
|
| /**
|
| * Unbind the service as the high priority connection.
|
| */
|
| - synchronized void unbindHighPriority(boolean force) {
|
| - if (mService == null) {
|
| - Log.w(TAG, "The connection is not bound for " + mPID);
|
| - return;
|
| - }
|
| - mHighPriorityConnectionCount--;
|
| - if (force || (mHighPriorityConnectionCount == 0 && mHighPriorityConnection != null)) {
|
| - mHighPriorityConnection.unbind();
|
| - mHighPriorityConnection = null;
|
| + void unbindHighPriority(boolean force) {
|
| + synchronized(mUiThreadLock) {
|
| + if (mService == null) {
|
| + Log.w(TAG, "The connection is not bound for " + mPID);
|
| + return;
|
| + }
|
| + mHighPriorityConnectionCount--;
|
| + if (force || (mHighPriorityConnectionCount == 0 && mHighPriorityConnection != null)) {
|
| + mHighPriorityConnection.unbind();
|
| + mHighPriorityConnection = null;
|
| + }
|
| }
|
| }
|
|
|
| @@ -350,7 +365,9 @@ public class SandboxedProcessConnection implements ServiceConnection {
|
| /**
|
| * @return The connection PID, or 0 if not yet connected.
|
| */
|
| - synchronized public int getPid() {
|
| - return mPID;
|
| + public int getPid() {
|
| + synchronized(mUiThreadLock) {
|
| + return mPID;
|
| + }
|
| }
|
| }
|
|
|