Index: content/shell/android/shell_apk/src/org/chromium/content_shell_apk/ChildProcessLauncherTestHelperService.java |
diff --git a/content/shell/android/shell_apk/src/org/chromium/content_shell_apk/ChildProcessLauncherTestHelperService.java b/content/shell/android/shell_apk/src/org/chromium/content_shell_apk/ChildProcessLauncherTestHelperService.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..9da9eb38c4eedc4627cdef68046a71ae789c63bb |
--- /dev/null |
+++ b/content/shell/android/shell_apk/src/org/chromium/content_shell_apk/ChildProcessLauncherTestHelperService.java |
@@ -0,0 +1,99 @@ |
+// Copyright 2017 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+package org.chromium.content_shell_apk; |
+ |
+import android.app.Service; |
+import android.content.Intent; |
+import android.os.Handler; |
+import android.os.HandlerThread; |
+import android.os.IBinder; |
+import android.os.Message; |
+import android.os.Messenger; |
+import android.os.RemoteException; |
+ |
+import org.chromium.base.BaseSwitches; |
+import org.chromium.base.CommandLine; |
+import org.chromium.base.library_loader.LibraryLoader; |
+import org.chromium.base.library_loader.LibraryProcessType; |
+import org.chromium.base.library_loader.ProcessInitException; |
+import org.chromium.content.browser.ChildProcessConnection; |
+import org.chromium.content.browser.ChildProcessCreationParams; |
+import org.chromium.content.browser.ChildProcessLauncher; |
+import org.chromium.content.common.FileDescriptorInfo; |
+ |
+/** |
+ * A Service that assists the ChildProcessLauncherTest that responds to one message, which |
+ * starts a sandboxed service process via the ChildProcessLauncher. This is required to test |
+ * the behavior when two independent processes in the same package try and bind to the same |
+ * sandboxed service process. |
+ */ |
+public class ChildProcessLauncherTestHelperService extends Service { |
+ public static final int MSG_BIND_SERVICE = IBinder.FIRST_CALL_TRANSACTION + 1; |
+ public static final int MSG_BIND_SERVICE_REPLY = MSG_BIND_SERVICE + 1; |
+ |
+ private final Handler.Callback mHandlerCallback = new Handler.Callback() { |
+ @Override |
+ public boolean handleMessage(Message msg) { |
+ switch (msg.what) { |
+ case MSG_BIND_SERVICE: |
+ doBindService(msg); |
+ return true; |
+ } |
+ return false; |
+ } |
+ }; |
+ |
+ private final HandlerThread mHandlerThread = new HandlerThread("Helper Service Handler"); |
+ |
+ @Override |
+ public void onCreate() { |
+ CommandLine.init(null); |
+ try { |
+ LibraryLoader.get(LibraryProcessType.PROCESS_CHILD).ensureInitialized(); |
+ } catch (ProcessInitException ex) { |
+ throw new RuntimeException(ex); |
+ } |
+ |
+ mHandlerThread.start(); |
+ } |
+ |
+ @Override |
+ public IBinder onBind(Intent intent) { |
+ Messenger messenger = |
+ new Messenger(new Handler(mHandlerThread.getLooper(), mHandlerCallback)); |
+ return messenger.getBinder(); |
+ } |
+ |
+ private void doBindService(final Message msg) { |
+ String[] commandLine = { "_", "--" + BaseSwitches.RENDERER_WAIT_FOR_JAVA_DEBUGGER }; |
+ ChildProcessCreationParams params = new ChildProcessCreationParams(getPackageName(), false, |
+ LibraryProcessType.PROCESS_CHILD); |
+ final ChildProcessConnection conn = ChildProcessLauncher.startForTesting(this, commandLine, |
+ new FileDescriptorInfo[0], params); |
+ |
+ // Poll the connection until it is set up. The main test in ChildProcessLauncherTest, which |
+ // has bound the connection to this service, manages the timeout via the lifetime of this |
+ // service. |
+ final Handler handler = new Handler(); |
+ final Runnable task = new Runnable() { |
+ final Messenger mReplyTo = msg.replyTo; |
+ |
+ @Override |
+ public void run() { |
+ if (conn.getPid() != 0) { |
+ try { |
+ mReplyTo.send(Message.obtain(null, MSG_BIND_SERVICE_REPLY, conn.getPid(), |
+ conn.getServiceNumber())); |
+ } catch (RemoteException ex) { |
+ throw new RuntimeException(ex); |
+ } |
+ } else { |
+ handler.postDelayed(this, 10 /* milliseconds */); |
+ } |
+ } |
+ }; |
+ handler.postDelayed(task, 10); |
+ } |
+} |