Chromium Code Reviews| Index: base/android/java/src/org/chromium/base/process_launcher/BaseChildProcessConnection.java |
| diff --git a/content/public/android/java/src/org/chromium/content/browser/BaseChildProcessConnection.java b/base/android/java/src/org/chromium/base/process_launcher/BaseChildProcessConnection.java |
| similarity index 86% |
| rename from content/public/android/java/src/org/chromium/content/browser/BaseChildProcessConnection.java |
| rename to base/android/java/src/org/chromium/base/process_launcher/BaseChildProcessConnection.java |
| index c719dd774b3d196b6de36af09120c6708c3e5978..755c9cfb40e96e62b23fa0b632e2c1d05a60def3 100644 |
| --- a/content/public/android/java/src/org/chromium/content/browser/BaseChildProcessConnection.java |
| +++ b/base/android/java/src/org/chromium/base/process_launcher/BaseChildProcessConnection.java |
| @@ -2,7 +2,7 @@ |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| -package org.chromium.content.browser; |
| +package org.chromium.base.process_launcher; |
| import android.content.ComponentName; |
| import android.content.Context; |
| @@ -12,16 +12,14 @@ import android.content.pm.PackageManager; |
| import android.content.pm.ServiceInfo; |
| import android.os.Build; |
| import android.os.Bundle; |
| +import android.os.Handler; |
| import android.os.IBinder; |
| +import android.os.Looper; |
| import android.os.RemoteException; |
| import org.chromium.base.Log; |
| import org.chromium.base.TraceEvent; |
| import org.chromium.base.VisibleForTesting; |
| -import org.chromium.base.process_launcher.ChildProcessCreationParams; |
| -import org.chromium.base.process_launcher.FileDescriptorInfo; |
| -import org.chromium.base.process_launcher.ICallbackInt; |
| -import org.chromium.base.process_launcher.IChildProcessService; |
| import java.io.IOException; |
| @@ -29,6 +27,7 @@ import javax.annotation.Nullable; |
| /** |
| * Manages a connection between the browser activity and a child service. |
| + * Most calls should happen on the connection's thread, the one specified in the constructor. |
| */ |
| public abstract class BaseChildProcessConnection { |
| private static final String TAG = "BaseChildProcessConn"; |
| @@ -38,8 +37,8 @@ public abstract class BaseChildProcessConnection { |
| * earlier than ConnectionCallbacks below, as a child process might die before the connection is |
| * fully set up. |
| */ |
| - interface DeathCallback { |
| - // Called on Launcher thread. |
| + public interface DeathCallback { |
| + // Called on the connection's thread. |
| void onChildProcessDied(BaseChildProcessConnection connection); |
| } |
| @@ -47,7 +46,7 @@ public abstract class BaseChildProcessConnection { |
| * Used to notify the consumer about the process start. These callbacks will be invoked before |
| * the ConnectionCallbacks. |
| */ |
| - interface StartCallback { |
| + public interface StartCallback { |
| /** |
| * Called when the child process has successfully started and is ready for connection |
| * setup. |
| @@ -62,20 +61,27 @@ public abstract class BaseChildProcessConnection { |
| } |
| /** |
| - * Used to notify the consumer about the connection being established. |
| + * Used to notify the consumer about the connection being setup and established. |
| */ |
| - interface ConnectionCallback { |
| + public interface ConnectionCallback { |
| + /** |
| + * Called before the connection to the service is established. This gives clients an |
| + * opportunity to add custom parameters to params which is passed on to the service. |
| + * @param params a bundle passed to the service. |
| + */ |
| + void onConnectionSetup(Bundle params); |
| + |
| /** |
| * Called when the connection to the service is established. |
| - * @param connecion the connection object to the child process |
| + * @param connection the connection object to the child process |
| */ |
| void onConnected(BaseChildProcessConnection connection); |
| } |
| - /** Used to create specialization connection instances. */ |
| - interface Factory { |
| - BaseChildProcessConnection create(Context context, int number, boolean sandboxed, |
| - DeathCallback deathCallback, String serviceClassName, |
| + /** Used to create specialization of connection instances. */ |
| + public interface Factory { |
| + BaseChildProcessConnection create(Handler handler, Context context, int number, |
| + boolean sandboxed, DeathCallback deathCallback, String serviceClassName, |
| Bundle childProcessCommonParameters, ChildProcessCreationParams creationParams); |
| } |
| @@ -137,10 +143,10 @@ public abstract class BaseChildProcessConnection { |
| @Override |
| public void onServiceConnected(ComponentName className, final IBinder service) { |
| - LauncherThread.post(new Runnable() { |
| + mHandler.post(new Runnable() { |
| @Override |
| public void run() { |
| - BaseChildProcessConnection.this.onServiceConnectedOnLauncherThread(service); |
| + BaseChildProcessConnection.this.onServiceConnected(service); |
| } |
| }); |
| } |
| @@ -148,10 +154,10 @@ public abstract class BaseChildProcessConnection { |
| // Called on the main thread to notify that the child service did not disconnect gracefully. |
| @Override |
| public void onServiceDisconnected(ComponentName className) { |
| - LauncherThread.post(new Runnable() { |
| + mHandler.post(new Runnable() { |
| @Override |
| public void run() { |
| - BaseChildProcessConnection.this.onServiceDisconnectedOnLauncherThread(); |
| + BaseChildProcessConnection.this.onServiceDisconnected(); |
| } |
| }); |
| } |
| @@ -187,6 +193,9 @@ public abstract class BaseChildProcessConnection { |
| } |
| } |
| + // The handler for the thread the connection should be accessed on. |
| + private final Handler mHandler; |
| + |
| // This is set in start() and is used in onServiceConnected(). |
| private StartCallback mStartCallback; |
| @@ -216,10 +225,10 @@ public abstract class BaseChildProcessConnection { |
| // Process ID of the corresponding child process. |
| private int mPid; |
| - protected BaseChildProcessConnection(Context context, int number, boolean sandboxed, |
| - DeathCallback deathCallback, String serviceClassName, |
| + protected BaseChildProcessConnection(Handler handler, Context context, int number, |
| + boolean sandboxed, DeathCallback deathCallback, String serviceClassName, |
| Bundle childProcessCommonParameters, ChildProcessCreationParams creationParams) { |
| - assert LauncherThread.runningOnLauncherThread(); |
| + mHandler = handler; |
| mContext = context; |
| mServiceNumber = number; |
| mSandboxed = sandboxed; |
| @@ -232,38 +241,38 @@ public abstract class BaseChildProcessConnection { |
| } |
| public final Context getContext() { |
| - assert LauncherThread.runningOnLauncherThread(); |
| + checkOnValidThread(); |
| return mContext; |
| } |
| public final int getServiceNumber() { |
| - assert LauncherThread.runningOnLauncherThread(); |
| + checkOnValidThread(); |
| return mServiceNumber; |
| } |
| public final boolean isSandboxed() { |
| - assert LauncherThread.runningOnLauncherThread(); |
| + checkOnValidThread(); |
| return mSandboxed; |
| } |
| public final String getPackageName() { |
| - assert LauncherThread.runningOnLauncherThread(); |
| + checkOnValidThread(); |
| return mCreationParams != null ? mCreationParams.getPackageName() |
| : mContext.getPackageName(); |
| } |
| public final ChildProcessCreationParams getCreationParams() { |
| - assert LauncherThread.runningOnLauncherThread(); |
| + checkOnValidThread(); |
| return mCreationParams; |
| } |
| public final IChildProcessService getService() { |
| - assert LauncherThread.runningOnLauncherThread(); |
| + checkOnValidThread(); |
| return mService; |
| } |
| public final ComponentName getServiceName() { |
| - assert LauncherThread.runningOnLauncherThread(); |
| + checkOnValidThread(); |
| return mServiceName; |
| } |
| @@ -271,7 +280,7 @@ public abstract class BaseChildProcessConnection { |
| * @return the connection pid, or 0 if not yet connected |
| */ |
| public int getPid() { |
| - assert LauncherThread.runningOnLauncherThread(); |
| + checkOnValidThread(); |
| return mPid; |
| } |
| @@ -283,10 +292,10 @@ public abstract class BaseChildProcessConnection { |
| * @param startCallback (optional) callback when the child process starts or fails to start. |
| */ |
| public void start(StartCallback startCallback) { |
| - assert LauncherThread.runningOnLauncherThread(); |
| + checkOnValidThread(); |
| try { |
| TraceEvent.begin("BaseChildProcessConnection.start"); |
| - assert LauncherThread.runningOnLauncherThread(); |
| + checkOnValidThread(); |
|
boliu
2017/04/28 17:16:27
no need to repeat this :p
|
| assert mConnectionParams |
| == null |
| : "setupConnection() called before start() in BaseChildProcessConnection."; |
| @@ -315,7 +324,7 @@ public abstract class BaseChildProcessConnection { |
| */ |
| public void setupConnection(String[] commandLine, FileDescriptorInfo[] filesToBeMapped, |
| @Nullable IBinder callback, ConnectionCallback connectionCallback) { |
| - assert LauncherThread.runningOnLauncherThread(); |
| + checkOnValidThread(); |
| assert mConnectionParams == null; |
| if (mServiceDisconnected) { |
| Log.w(TAG, "Tried to setup a connection that already disconnected."); |
| @@ -341,14 +350,14 @@ public abstract class BaseChildProcessConnection { |
| * this multiple times. |
| */ |
| public void stop() { |
| - assert LauncherThread.runningOnLauncherThread(); |
| + checkOnValidThread(); |
| unbind(); |
| mService = null; |
| mConnectionParams = null; |
| } |
| - private void onServiceConnectedOnLauncherThread(IBinder service) { |
| - assert LauncherThread.runningOnLauncherThread(); |
| + private void onServiceConnected(IBinder service) { |
| + checkOnValidThread(); |
| // A flag from the parent class ensures we run the post-connection logic only once |
| // (instead of once per each ChildServiceConnection). |
| if (mDidOnServiceConnected) { |
| @@ -399,8 +408,8 @@ public abstract class BaseChildProcessConnection { |
| } |
| } |
| - private void onServiceDisconnectedOnLauncherThread() { |
| - assert LauncherThread.runningOnLauncherThread(); |
| + private void onServiceDisconnected() { |
| + checkOnValidThread(); |
| // Ensure that the disconnection logic runs only once (instead of once per each |
| // ChildServiceConnection). |
| if (mServiceDisconnected) { |
| @@ -439,12 +448,20 @@ public abstract class BaseChildProcessConnection { |
| assert mServiceConnectComplete && mService != null; |
| assert mConnectionParams != null; |
| - Bundle bundle = ChildProcessLauncher.createsServiceBundle( |
| - mConnectionParams.mCommandLine, mConnectionParams.mFilesToBeMapped); |
| + Bundle bundle = new Bundle(); |
| + bundle.putStringArray( |
| + ChildProcessConstants.EXTRA_COMMAND_LINE, mConnectionParams.mCommandLine); |
| + bundle.putParcelableArray( |
| + ChildProcessConstants.EXTRA_FILES, mConnectionParams.mFilesToBeMapped); |
| + |
| + if (mConnectionCallback != null) { |
|
boliu
2017/04/28 17:16:27
is this check needed? should this be an assert ins
|
| + mConnectionCallback.onConnectionSetup(bundle); |
| + } |
| + |
| ICallbackInt pidCallback = new ICallbackInt.Stub() { |
| @Override |
| public void call(final int pid) { |
| - LauncherThread.post(new Runnable() { |
| + mHandler.post(new Runnable() { |
| @Override |
| public void run() { |
| onSetupConnectionResult(pid); |
| @@ -476,12 +493,12 @@ public abstract class BaseChildProcessConnection { |
| protected abstract void unbind(); |
| protected ChildServiceConnection createServiceConnection(int bindFlags) { |
| - assert LauncherThread.runningOnLauncherThread(); |
| + checkOnValidThread(); |
| return new ChildServiceConnectionImpl(bindFlags); |
| } |
| protected boolean shouldBindAsExportedService() { |
| - assert LauncherThread.runningOnLauncherThread(); |
| + checkOnValidThread(); |
| return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && getCreationParams() != null |
| && getCreationParams().getIsExternalService() |
| && isExportedService(isSandboxed(), getContext(), getServiceName()); |
| @@ -507,13 +524,18 @@ public abstract class BaseChildProcessConnection { |
| return result; |
| } |
| + /** Checks whether the caller is running on the thread specified at creation time. */ |
| + protected final void checkOnValidThread() { |
| + assert mHandler.getLooper() == Looper.myLooper(); |
| + } |
| + |
| @VisibleForTesting |
| public void crashServiceForTesting() throws RemoteException { |
| mService.crashIntentionallyForTesting(); |
| } |
| @VisibleForTesting |
| - boolean isConnected() { |
| + public boolean isConnected() { |
| return mService != null; |
| } |
| } |