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

Unified Diff: base/test/android/java/src/org/chromium/base/MultiprocessTestClientService.java

Issue 2549363004: Multiprocess test client: Android child process launcher rework. (Closed)
Patch Set: Fixed tests Created 4 years 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: base/test/android/java/src/org/chromium/base/MultiprocessTestClientService.java
diff --git a/base/test/android/java/src/org/chromium/base/MultiprocessTestClientService.java b/base/test/android/java/src/org/chromium/base/MultiprocessTestClientService.java
new file mode 100644
index 0000000000000000000000000000000000000000..e75182da43b1149e1856207543d28723f1d1ab00
--- /dev/null
+++ b/base/test/android/java/src/org/chromium/base/MultiprocessTestClientService.java
@@ -0,0 +1,139 @@
+// Copyright 2016 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.base;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Process;
+
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.base.annotations.JNINamespace;
+import org.chromium.base.annotations.SuppressFBWarnings;
+import org.chromium.base.library_loader.NativeLibraries;
+
+/**
+ * The service implementation used to host all multiprocess test client code.
+ */
+@JNINamespace("base::android")
+public class MultiprocessTestClientService extends Service {
+ private static final String TAG = "TestClient";
+
+ private final Handler mHandler = new Handler();
+
+ private final Object mResultLock = new Object();
+ private MainReturnCodeResult mResult;
+
+ private final ITestClient.Stub mBinder = new ITestClient.Stub() {
+ @Override
+ public int launch(final String[] commandLine, FileDescriptorInfo[] fdsToMap) {
+ final int[] fdIds = new int[fdsToMap.length];
+ final int[] fdFds = new int[fdsToMap.length];
+ for (int i = 0; i < fdsToMap.length; i++) {
+ fdIds[i] = fdsToMap[i].mId;
+ fdFds[i] = fdsToMap[i].mFd.detachFd();
+ }
+ // Don't run main directly, it would block and the response would not be returned.
+ // We post to the main thread as this thread does not have a Looper.
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ nativeRunMain(commandLine, fdIds, fdFds);
+ }
+ });
+ return Process.myPid();
+ }
+
+ @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE")
+ @Override
+ public MainReturnCodeResult waitForMainToReturn(int timeoutMs) {
+ synchronized (mResultLock) {
+ if (mResult != null) return mResult;
+ try {
+ mResultLock.wait(timeoutMs);
+ } catch (InterruptedException ie) {
+ Log.e(TAG, "Failed to wait for main return value.");
+ return new MainReturnCodeResult(0, true /* timed-out */);
+ }
+ assert mResult != null;
+ return mResult;
+ }
+ }
+
+ @SuppressFBWarnings("DM_EXIT")
+ @Override
+ public boolean forceStopSynchronous(int exitCode) {
+ System.exit(exitCode);
+ return true;
+ }
+
+ @SuppressFBWarnings("DM_EXIT")
+ @Override
+ public void forceStop(int exitCode) {
+ System.exit(exitCode);
+ }
+ };
+
+ static boolean sAlreadyInitialized = false;
+
+ @SuppressFBWarnings({"ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", "DM_EXIT"})
+ @Override
+ public void onCreate() {
+ super.onCreate();
+
+ if (sAlreadyInitialized) {
+ // The framework controls how services are reused and even though nothing is bound to a
+ // service it might be kept around. Since we really want to fork a new process when we
+ // bind, we'll kill the process early when a service is reused, forcing the framework to
+ // recreate the service in a new process.
+ // This is not ideal, but there are no clear alternatives at this point.
+ Log.e(TAG, "Service being reused, forcing stoppage.");
+ System.exit(0);
+ }
+ sAlreadyInitialized = true;
+
+ ContextUtils.initApplicationContext(getApplicationContext());
+
+ PathUtils.setPrivateDataDirectorySuffix("chrome_multiprocess_test_client_service");
+
+ loadLibraries();
+
+ Log.e(TAG, "onCreate");
+ }
+
+ @Override
+ public void onDestroy() {
+ Log.e(TAG, "onDestroy");
+ super.onDestroy();
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ // Only bind the first incoming request.
+ stopSelf();
+
+ return mBinder;
+ }
+
+ private void loadLibraries() {
+ for (String library : NativeLibraries.LIBRARIES) {
+ Log.i(TAG, "loading: %s", library);
+ System.loadLibrary(library);
+ Log.i(TAG, "loaded: %s", library);
+ }
+ ContextUtils.initApplicationContextForNative();
+ }
+
+ @CalledByNative
+ private void setMainReturnValue(int result) {
+ synchronized (mResultLock) {
+ mResult = new MainReturnCodeResult(result, false /* timed-out */);
+ mResultLock.notifyAll();
+ }
+ }
+
+ private native void nativeRunMain(String[] commandLine, int[] fdsToMapIds, int[] fdsToMapFds);
+}

Powered by Google App Engine
This is Rietveld 408576698