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

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

Issue 2549363004: Multiprocess test client: Android child process launcher rework. (Closed)
Patch Set: Addressed comments + synced 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.base;
6
7 import android.app.Service;
8 import android.content.Intent;
9 import android.os.Handler;
10 import android.os.IBinder;
11 import android.os.Process;
12
13 import org.chromium.base.annotations.CalledByNative;
14 import org.chromium.base.annotations.JNINamespace;
15 import org.chromium.base.annotations.SuppressFBWarnings;
16 import org.chromium.base.library_loader.LibraryLoader;
17 import org.chromium.base.library_loader.LibraryProcessType;
18 import org.chromium.base.library_loader.ProcessInitException;
19
20 import javax.annotation.concurrent.GuardedBy;
21
22 /**
23 * The service implementation used to host all multiprocess test client code.
24 */
25 @JNINamespace("base::android")
26 public class MultiprocessTestClientService extends Service {
27 private static final String TAG = "cr_TestClient";
28
29 private static boolean sAlreadyInitialized = false;
30
31 private final Handler mHandler = new Handler();
32
33 private final Object mResultLock = new Object();
34
35 @GuardedBy("mResultLock")
36 private MainReturnCodeResult mResult;
Robert Sesek 2016/12/20 20:44:34 Could you use a Future<MainResultCodeResult> inste
Jay Civelli 2016/12/20 23:07:26 Do you mean having a FutureTask<MainResultCodeResu
Robert Sesek 2016/12/21 19:26:07 Ah, I see your point. I was actually thinking of C
37
38 private final ITestClient.Stub mBinder = new ITestClient.Stub() {
39 @Override
40 public int launch(final String[] commandLine, FileDescriptorInfo[] fdsTo Map) {
41 final int[] fdIds = new int[fdsToMap.length];
42 final int[] fdFds = new int[fdsToMap.length];
43 for (int i = 0; i < fdsToMap.length; i++) {
44 fdIds[i] = fdsToMap[i].id;
45 // Take ownership of the file descriptor so they outlive the Fil eDescriptorInfo
46 // instances. Native code will own them.
47 fdFds[i] = fdsToMap[i].fd.detachFd();
48 }
49 // Don't run main directly, it would block and the response would no t be returned.
50 // We post to the main thread as this thread does not have a Looper.
51 mHandler.post(new Runnable() {
52 @Override
53 public void run() {
54 nativeRunMain(commandLine, fdIds, fdFds);
55 }
56 });
57 return Process.myPid();
58 }
59
60 @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE")
61 @Override
62 public MainReturnCodeResult waitForMainToReturn(int timeoutMs) {
63 synchronized (mResultLock) {
64 while (mResult == null) {
65 try {
66 mResultLock.wait(timeoutMs);
67 } catch (InterruptedException ie) {
68 continue;
69 }
70 // Check if we timed-out.
71 if (mResult == null) {
72 Log.e(TAG, "Failed to wait for main return value.");
73 return new MainReturnCodeResult(0, true /* timed-out */) ;
74 }
75 }
76 return mResult;
77 }
78 }
79
80 @SuppressFBWarnings("DM_EXIT")
81 @Override
82 public boolean forceStopSynchronous(int exitCode) {
83 System.exit(exitCode);
84 return true;
85 }
86
87 @SuppressFBWarnings("DM_EXIT")
88 @Override
89 public void forceStop(int exitCode) {
90 System.exit(exitCode);
91 }
92 };
93
94 @SuppressFBWarnings("DM_EXIT")
95 @Override
96 public void onCreate() {
97 super.onCreate();
98
99 if (sAlreadyInitialized) {
100 // The framework controls how services are reused and even though no thing is bound to a
101 // service it might be kept around. Since we really want to fork a n ew process when we
102 // bind, we'll kill the process early when a service is reused, forc ing the framework to
103 // recreate the service in a new process.
104 // This is not ideal, but there are no clear alternatives at this po int.
105 Log.e(TAG, "Service being reused, forcing stoppage.");
106 System.exit(0);
107 return;
108 }
109 markInitialized();
110
111 ContextUtils.initApplicationContext(getApplicationContext());
112
113 PathUtils.setPrivateDataDirectorySuffix("chrome_multiprocess_test_client _service");
114
115 loadLibraries();
116 }
117
118 @Override
119 public IBinder onBind(Intent intent) {
120 return mBinder;
121 }
122
123 private void loadLibraries() {
124 try {
125 LibraryLoader.get(LibraryProcessType.PROCESS_CHILD).loadNow();
126 } catch (ProcessInitException pie) {
127 Log.e(TAG, "Unable to load native libraries.", pie);
128 }
129 ContextUtils.initApplicationContextForNative();
130 }
131
132 @CalledByNative
133 private void setMainReturnValue(int result) {
134 synchronized (mResultLock) {
135 mResult = new MainReturnCodeResult(result, false /* timed-out */);
136 mResultLock.notifyAll();
137 }
138 }
139
140 private static void markInitialized() {
Robert Sesek 2016/12/20 20:44:34 This is called exactly once, so inline it?
Jay Civelli 2016/12/20 23:07:26 Is to avoid FindBugs complaining that a static fie
141 sAlreadyInitialized = true;
142 }
143
144 private native void nativeRunMain(String[] commandLine, int[] fdsToMapIds, i nt[] fdsToMapFds);
145 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698