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

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

Issue 2784353002: Android: Remove GetApplicationContext part 2 (Closed)
Patch Set: remove extra file Created 3 years, 8 months 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
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.base; 5 package org.chromium.base;
6 6
7 import android.content.ComponentName; 7 import android.content.ComponentName;
8 import android.content.Context; 8 import android.content.Context;
9 import android.content.Intent; 9 import android.content.Intent;
10 import android.content.ServiceConnection; 10 import android.content.ServiceConnection;
(...skipping 18 matching lines...) Expand all
29 */ 29 */
30 @JNINamespace("base::android") 30 @JNINamespace("base::android")
31 public final class MultiprocessTestClientLauncher { 31 public final class MultiprocessTestClientLauncher {
32 private static final String TAG = "cr_MProcTCLauncher"; 32 private static final String TAG = "cr_MProcTCLauncher";
33 33
34 private static ConnectionAllocator sConnectionAllocator = new ConnectionAllo cator(); 34 private static ConnectionAllocator sConnectionAllocator = new ConnectionAllo cator();
35 35
36 // Not supposed to be instantiated. 36 // Not supposed to be instantiated.
37 private MultiprocessTestClientLauncher() {} 37 private MultiprocessTestClientLauncher() {}
38 38
39 /**
40 * Spawns and connects to a child process.
41 * May not be called from the main thread.
42 *
43 * @param commandLine the child process command line argv.
44 * @return the PID of the started process or 0 if the process could not be s tarted.
45 */
46 @CalledByNative
47 private static int launchClient(
agrieve 2017/03/31 14:34:28 Not sure if this was caused by you or a cl in betw
Peter Wen 2017/04/04 19:08:36 Done.
48 final String[] commandLine, final FileDescriptorInfo[] filesToMap) {
49 if (ThreadUtils.runningOnUiThread()) {
50 // This can't be called on the main thread as the native side will b lock until
51 // onServiceConnected above is called, which cannot happen if the ma in thread is
52 // blocked.
53 throw new RuntimeException("launchClient cannot be called on the mai n thread");
54 }
55
56 ClientServiceConnection connection =
57 sConnectionAllocator.allocateConnection(commandLine, filesToMap) ;
58 Intent intent = new Intent();
59 String className = connection.getServiceClassName();
60 String packageName = ContextUtils.getApplicationContext().getPackageName ();
61 intent.setComponent(new ComponentName(packageName, className));
62 if (!ContextUtils.getApplicationContext().bindService(
63 intent, connection, Context.BIND_AUTO_CREATE | Context.BIND_ IMPORTANT)) {
64 Log.e(TAG, "Failed to bind service: " + packageName + "." + classNam e);
65 sConnectionAllocator.freeConnection(connection);
66 return 0;
67 }
68
69 connection.waitForConnection();
70
71 return connection.getPid();
72 }
73
74 /**
75 * Blocks until the main method invoked by a previous call to launchClient t erminates or until
76 * the specified time-out expires.
77 * Returns immediately if main has already returned.
78 *
79 * @param pid the process ID that was returned by the call to launchCl ient
80 * @param timeoutMs the timeout in milliseconds after which the method retur ns even if main has
81 * not returned.
82 * @return the return code returned by the main method or whether it timed-o ut.
83 */
84 @CalledByNative
85 private static MainReturnCodeResult waitForMainToReturn(int pid, int timeout Ms) {
86 ClientServiceConnection connection = sConnectionAllocator.getConnectionB yPid(pid);
87 if (connection == null) {
88 Log.e(TAG, "waitForMainToReturn called on unknown connection for pid " + pid);
89 return null;
90 }
91 try {
92 return connection.getService().waitForMainToReturn(timeoutMs);
93 } catch (RemoteException e) {
94 Log.e(TAG, "Remote call to waitForMainToReturn failed.");
95 return null;
96 } finally {
97 freeConnection(connection);
98 }
99 }
100
101 @CalledByNative
102 private static boolean terminate(int pid, int exitCode, boolean wait) {
103 ClientServiceConnection connection = sConnectionAllocator.getConnectionB yPid(pid);
104 if (connection == null) {
105 Log.e(TAG, "terminate called on unknown connection for pid " + pid);
106 return false;
107 }
108 try {
109 if (wait) {
110 connection.getService().forceStopSynchronous(exitCode);
111 } else {
112 connection.getService().forceStop(exitCode);
113 }
114 } catch (RemoteException e) {
115 // We expect this failure, since the forceStop's service implementat ion calls
116 // System.exit().
117 } finally {
118 freeConnection(connection);
119 }
120 return true;
121 }
122
123 private static void freeConnection(ClientServiceConnection connection) {
124 ContextUtils.getApplicationContext().unbindService(connection);
125 sConnectionAllocator.freeConnection(connection);
126 }
127
128 /** Does not take ownership of of fds. */
129 @CalledByNative
130 private static FileDescriptorInfo[] makeFdInfoArray(int[] keys, int[] fds) {
131 FileDescriptorInfo[] fdInfos = new FileDescriptorInfo[keys.length];
132 for (int i = 0; i < keys.length; i++) {
133 FileDescriptorInfo fdInfo = makeFdInfo(keys[i], fds[i]);
134 if (fdInfo == null) {
135 Log.e(TAG, "Failed to make file descriptor (" + keys[i] + ", " + fds[i] + ").");
136 return null;
137 }
138 fdInfos[i] = fdInfo;
139 }
140 return fdInfos;
141 }
142
143 private static FileDescriptorInfo makeFdInfo(int id, int fd) {
144 ParcelFileDescriptor parcelableFd;
145 try {
146 parcelableFd = ParcelFileDescriptor.fromFd(fd);
147 } catch (IOException e) {
148 Log.e(TAG, "Invalid FD provided for process connection, aborting con nection.", e);
149 return null;
150 }
151 return new FileDescriptorInfo(id, parcelableFd, 0 /* offset */, 0 /* siz e */);
152 }
153
39 private static class ConnectionAllocator { 154 private static class ConnectionAllocator {
40 // Services are identified by a slot number, which is used in the servic e name to 155 // Services are identified by a slot number, which is used in the servic e name to
41 // differentiate them (MultiprocessTestClientService0, MultiprocessTestC lientService1, ...). 156 // differentiate them (MultiprocessTestClientService0, MultiprocessTestC lientService1, ...).
42 // They are stored in a FIFO queue in order to minimize the risk of the framework reusing a 157 // They are stored in a FIFO queue in order to minimize the risk of the framework reusing a
43 // service without restarting its associated process (which can cause al l kind of problems 158 // service without restarting its associated process (which can cause al l kind of problems
44 // with static native variables already being initialized). 159 // with static native variables already being initialized).
45 private static final int MAX_SUBPROCESS_COUNT = 5; 160 private static final int MAX_SUBPROCESS_COUNT = 5;
46 161
47 private final Object mLock = new Object(); 162 private final Object mLock = new Object();
48 163
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 } 283 }
169 284
170 public int getSlot() { 285 public int getSlot() {
171 return mSlot; 286 return mSlot;
172 } 287 }
173 288
174 public int getPid() { 289 public int getPid() {
175 return mPid; 290 return mPid;
176 } 291 }
177 } 292 }
178
179 /**
180 * Spawns and connects to a child process.
181 * May not be called from the main thread.
182 *
183 * @param context context used to obtain the application context.
184 * @param commandLine the child process command line argv.
185 * @return the PID of the started process or 0 if the process could not be s tarted.
186 */
187 @CalledByNative
188 private static int launchClient(final Context context, final String[] comman dLine,
189 final FileDescriptorInfo[] filesToMap) {
190 if (ThreadUtils.runningOnUiThread()) {
191 // This can't be called on the main thread as the native side will b lock until
192 // onServiceConnected above is called, which cannot happen if the ma in thread is
193 // blocked.
194 throw new RuntimeException("launchClient cannot be called on the mai n thread");
195 }
196
197 ClientServiceConnection connection =
198 sConnectionAllocator.allocateConnection(commandLine, filesToMap) ;
199 Intent intent = new Intent();
200 String className = connection.getServiceClassName();
201 intent.setComponent(new ComponentName(context.getPackageName(), classNam e));
202 if (!context.bindService(
203 intent, connection, Context.BIND_AUTO_CREATE | Context.BIND_ IMPORTANT)) {
204 Log.e(TAG, "Failed to bind service: " + context.getPackageName() + " ." + className);
205 sConnectionAllocator.freeConnection(connection);
206 return 0;
207 }
208
209 connection.waitForConnection();
210
211 return connection.getPid();
212 }
213
214 /**
215 * Blocks until the main method invoked by a previous call to launchClient t erminates or until
216 * the specified time-out expires.
217 * Returns immediately if main has already returned.
218 * @param context context used to obtain the application context.
219 * @param pid the process ID that was returned by the call to launchClient
220 * @param timeoutMs the timeout in milliseconds after which the method retur ns even if main has
221 * not returned.
222 * @return the return code returned by the main method or whether it timed-o ut.
223 */
224 @CalledByNative
225 private static MainReturnCodeResult waitForMainToReturn(
226 Context context, int pid, int timeoutMs) {
227 ClientServiceConnection connection = sConnectionAllocator.getConnectionB yPid(pid);
228 if (connection == null) {
229 Log.e(TAG, "waitForMainToReturn called on unknown connection for pid " + pid);
230 return null;
231 }
232 try {
233 return connection.getService().waitForMainToReturn(timeoutMs);
234 } catch (RemoteException e) {
235 Log.e(TAG, "Remote call to waitForMainToReturn failed.");
236 return null;
237 } finally {
238 freeConnection(context, connection);
239 }
240 }
241
242 @CalledByNative
243 private static boolean terminate(Context context, int pid, int exitCode, boo lean wait) {
244 ClientServiceConnection connection = sConnectionAllocator.getConnectionB yPid(pid);
245 if (connection == null) {
246 Log.e(TAG, "terminate called on unknown connection for pid " + pid);
247 return false;
248 }
249 try {
250 if (wait) {
251 connection.getService().forceStopSynchronous(exitCode);
252 } else {
253 connection.getService().forceStop(exitCode);
254 }
255 } catch (RemoteException e) {
256 // We expect this failure, since the forceStop's service implementat ion calls
257 // System.exit().
258 } finally {
259 freeConnection(context, connection);
260 }
261 return true;
262 }
263
264 private static void freeConnection(Context context, ClientServiceConnection connection) {
265 context.unbindService(connection);
266 sConnectionAllocator.freeConnection(connection);
267 }
268
269 /** Does not take ownership of of fds. */
270 @CalledByNative
271 private static FileDescriptorInfo[] makeFdInfoArray(int[] keys, int[] fds) {
272 FileDescriptorInfo[] fdInfos = new FileDescriptorInfo[keys.length];
273 for (int i = 0; i < keys.length; i++) {
274 FileDescriptorInfo fdInfo = makeFdInfo(keys[i], fds[i]);
275 if (fdInfo == null) {
276 Log.e(TAG, "Failed to make file descriptor (" + keys[i] + ", " + fds[i] + ").");
277 return null;
278 }
279 fdInfos[i] = fdInfo;
280 }
281 return fdInfos;
282 }
283
284 private static FileDescriptorInfo makeFdInfo(int id, int fd) {
285 ParcelFileDescriptor parcelableFd = null;
286 try {
287 parcelableFd = ParcelFileDescriptor.fromFd(fd);
288 } catch (IOException e) {
289 Log.e(TAG, "Invalid FD provided for process connection, aborting con nection.", e);
290 return null;
291 }
292 return new FileDescriptorInfo(id, parcelableFd, 0 /* offset */, 0 /* siz e */);
293 }
294 } 293 }
OLDNEW
« no previous file with comments | « base/test/android/java/src/org/chromium/base/ContentUriTestUtils.java ('k') | base/test/multiprocess_test_android.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698