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; |
} |
} |