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

Side by Side Diff: content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java

Issue 704573002: Android: Use a spawning queue for child processes while we are at capacity. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix for assert message. Created 6 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
« no previous file with comments | « no previous file | content/public/android/javatests/src/org/chromium/content/browser/ChildProcessLauncherTest.java » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 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.content.browser; 5 package org.chromium.content.browser;
6 6
7 import android.content.Context; 7 import android.content.Context;
8 import android.content.pm.ApplicationInfo; 8 import android.content.pm.ApplicationInfo;
9 import android.content.pm.PackageManager; 9 import android.content.pm.PackageManager;
10 import android.graphics.SurfaceTexture; 10 import android.graphics.SurfaceTexture;
11 import android.os.RemoteException; 11 import android.os.RemoteException;
12 import android.util.Log; 12 import android.util.Log;
13 import android.util.Pair; 13 import android.util.Pair;
14 import android.view.Surface; 14 import android.view.Surface;
15 15
16 import org.chromium.base.CalledByNative; 16 import org.chromium.base.CalledByNative;
17 import org.chromium.base.JNINamespace; 17 import org.chromium.base.JNINamespace;
18 import org.chromium.base.ThreadUtils; 18 import org.chromium.base.ThreadUtils;
19 import org.chromium.base.TraceEvent; 19 import org.chromium.base.TraceEvent;
20 import org.chromium.base.VisibleForTesting; 20 import org.chromium.base.VisibleForTesting;
21 import org.chromium.base.library_loader.Linker; 21 import org.chromium.base.library_loader.Linker;
22 import org.chromium.content.app.ChildProcessService; 22 import org.chromium.content.app.ChildProcessService;
23 import org.chromium.content.app.ChromiumLinkerParams; 23 import org.chromium.content.app.ChromiumLinkerParams;
24 import org.chromium.content.app.PrivilegedProcessService; 24 import org.chromium.content.app.PrivilegedProcessService;
25 import org.chromium.content.app.SandboxedProcessService; 25 import org.chromium.content.app.SandboxedProcessService;
26 import org.chromium.content.common.IChildProcessCallback; 26 import org.chromium.content.common.IChildProcessCallback;
27 import org.chromium.content.common.SurfaceWrapper; 27 import org.chromium.content.common.SurfaceWrapper;
28 28
29 import java.util.ArrayList; 29 import java.util.ArrayList;
30 import java.util.LinkedList;
30 import java.util.Map; 31 import java.util.Map;
32 import java.util.Queue;
31 import java.util.concurrent.ConcurrentHashMap; 33 import java.util.concurrent.ConcurrentHashMap;
32 34
33 /** 35 /**
34 * This class provides the method to start/stop ChildProcess called by native. 36 * This class provides the method to start/stop ChildProcess called by native.
35 */ 37 */
36 @JNINamespace("content") 38 @JNINamespace("content")
37 public class ChildProcessLauncher { 39 public class ChildProcessLauncher {
38 private static final String TAG = "ChildProcessLauncher"; 40 private static final String TAG = "ChildProcessLauncher";
39 41
40 static final int CALLBACK_FOR_UNKNOWN_PROCESS = 0; 42 static final int CALLBACK_FOR_UNKNOWN_PROCESS = 0;
41 static final int CALLBACK_FOR_GPU_PROCESS = 1; 43 static final int CALLBACK_FOR_GPU_PROCESS = 1;
42 static final int CALLBACK_FOR_RENDERER_PROCESS = 2; 44 static final int CALLBACK_FOR_RENDERER_PROCESS = 2;
43 static final int CALLBACK_FOR_UTILITY_PROCESS = 3; 45 static final int CALLBACK_FOR_UTILITY_PROCESS = 3;
44 46
45 private static final String SWITCH_PROCESS_TYPE = "type"; 47 private static final String SWITCH_PROCESS_TYPE = "type";
46 private static final String SWITCH_RENDERER_PROCESS = "renderer"; 48 private static final String SWITCH_RENDERER_PROCESS = "renderer";
47 private static final String SWITCH_UTILITY_PROCESS = "utility"; 49 private static final String SWITCH_UTILITY_PROCESS = "utility";
48 private static final String SWITCH_GPU_PROCESS = "gpu-process"; 50 private static final String SWITCH_GPU_PROCESS = "gpu-process";
49 51
50 private static class ChildConnectionAllocator { 52 private static class ChildConnectionAllocator {
51 // Connections to services. Indices of the array correspond to the servi ce numbers. 53 // Connections to services. Indices of the array correspond to the servi ce numbers.
52 private final ChildProcessConnection[] mChildProcessConnections; 54 private final ChildProcessConnection[] mChildProcessConnections;
53 55
54 // The list of free (not bound) service indices. When looking for a free service, the first 56 // The list of free (not bound) service indices.
55 // index in that list should be used. When a service is unbound, its ind ex is added to the
56 // end of the list. This is so that we avoid immediately reusing the fre ed service (see
57 // http://crbug.com/164069): the framework might keep a service process alive when it's been
58 // unbound for a short time. If a new connection to the same service is bound at that point,
59 // the process is reused and bad things happen (mostly static variables are set when we
60 // don't expect them to).
61 // SHOULD BE ACCESSED WITH mConnectionLock. 57 // SHOULD BE ACCESSED WITH mConnectionLock.
62 private final ArrayList<Integer> mFreeConnectionIndices; 58 private final ArrayList<Integer> mFreeConnectionIndices;
63 private final Object mConnectionLock = new Object(); 59 private final Object mConnectionLock = new Object();
64 60
65 private Class<? extends ChildProcessService> mChildClass; 61 private Class<? extends ChildProcessService> mChildClass;
66 private final boolean mInSandbox; 62 private final boolean mInSandbox;
67 63
68 public ChildConnectionAllocator(boolean inSandbox, int numChildServices) { 64 public ChildConnectionAllocator(boolean inSandbox, int numChildServices) {
69 mChildProcessConnections = new ChildProcessConnectionImpl[numChildSe rvices]; 65 mChildProcessConnections = new ChildProcessConnectionImpl[numChildSe rvices];
70 mFreeConnectionIndices = new ArrayList<Integer>(numChildServices); 66 mFreeConnectionIndices = new ArrayList<Integer>(numChildServices);
71 for (int i = 0; i < numChildServices; i++) { 67 for (int i = 0; i < numChildServices; i++) {
72 mFreeConnectionIndices.add(i); 68 mFreeConnectionIndices.add(i);
73 } 69 }
74 mChildClass = 70 mChildClass =
75 inSandbox ? SandboxedProcessService.class : PrivilegedProcessSer vice.class; 71 inSandbox ? SandboxedProcessService.class : PrivilegedProcessSer vice.class;
76 mInSandbox = inSandbox; 72 mInSandbox = inSandbox;
77 } 73 }
78 74
79 public ChildProcessConnection allocate( 75 public ChildProcessConnection allocate(
80 Context context, ChildProcessConnection.DeathCallback deathCallb ack, 76 Context context, ChildProcessConnection.DeathCallback deathCallb ack,
81 ChromiumLinkerParams chromiumLinkerParams) { 77 ChromiumLinkerParams chromiumLinkerParams) {
82 synchronized (mConnectionLock) { 78 synchronized (mConnectionLock) {
83 if (mFreeConnectionIndices.isEmpty()) { 79 if (mFreeConnectionIndices.isEmpty()) {
84 Log.e(TAG, "Ran out of services to allocate."); 80 Log.d(TAG, "Ran out of services to allocate.");
85 assert false;
86 return null; 81 return null;
87 } 82 }
88 int slot = mFreeConnectionIndices.remove(0); 83 int slot = mFreeConnectionIndices.remove(0);
89 assert mChildProcessConnections[slot] == null; 84 assert mChildProcessConnections[slot] == null;
90 mChildProcessConnections[slot] = new ChildProcessConnectionImpl( context, slot, 85 mChildProcessConnections[slot] = new ChildProcessConnectionImpl( context, slot,
91 mInSandbox, deathCallback, mChildClass, chromiumLinkerPa rams); 86 mInSandbox, deathCallback, mChildClass, chromiumLinkerPa rams);
92 Log.d(TAG, "Allocator allocated a connection, sandbox: " + mInSa ndbox 87 Log.d(TAG, "Allocator allocated a connection, sandbox: " + mInSa ndbox
93 + ", slot: " + slot); 88 + ", slot: " + slot);
94 return mChildProcessConnections[slot]; 89 return mChildProcessConnections[slot];
95 } 90 }
(...skipping 18 matching lines...) Expand all
114 } 109 }
115 } 110 }
116 111
117 /** @return the count of connections managed by the allocator */ 112 /** @return the count of connections managed by the allocator */
118 @VisibleForTesting 113 @VisibleForTesting
119 int allocatedConnectionsCountForTesting() { 114 int allocatedConnectionsCountForTesting() {
120 return mChildProcessConnections.length - mFreeConnectionIndices.size (); 115 return mChildProcessConnections.length - mFreeConnectionIndices.size ();
121 } 116 }
122 } 117 }
123 118
119 private static class PendingSpawnData {
120 private final Context mContext;
121 private final String[] mCommandLine;
122 private final int mChildProcessId;
123 private final FileDescriptorInfo[] mFilesToBeMapped;
124 private final long mClientContext;
125 private final int mCallbackType;
126 private final boolean mInSandbox;
127
128 private PendingSpawnData(
129 Context context,
130 String[] commandLine,
131 int childProcessId,
132 FileDescriptorInfo[] filesToBeMapped,
133 long clientContext,
134 int callbackType,
135 boolean inSandbox) {
136 mContext = context;
137 mCommandLine = commandLine;
138 mChildProcessId = childProcessId;
139 mFilesToBeMapped = filesToBeMapped;
140 mClientContext = clientContext;
141 mCallbackType = callbackType;
142 mInSandbox = inSandbox;
143 }
144
145 private Context context() {
146 return mContext;
147 }
148 private String[] commandLine() {
149 return mCommandLine;
150 }
151 private int childProcessId() {
152 return mChildProcessId;
153 }
154 private FileDescriptorInfo[] filesToBeMapped() {
155 return mFilesToBeMapped;
156 }
157 private long clientContext() {
158 return mClientContext;
159 }
160 private int callbackType() {
161 return mCallbackType;
162 }
163 private boolean inSandbox() {
164 return mInSandbox;
165 }
166 }
167
168 private static class PendingSpawnQueue {
169 // The list of pending process spawn requests and its lock.
170 private static Queue<PendingSpawnData> sPendingSpawns =
171 new LinkedList<PendingSpawnData>();
172 static final Object sPendingSpawnsLock = new Object();
173
174 /**
175 * Queue up a spawn requests to be processed once a free service is avai lable.
176 * Called when a spawn is requested while we are at the capacity.
177 */
178 public void enqueue(final PendingSpawnData pendingSpawn) {
179 synchronized (sPendingSpawnsLock) {
180 sPendingSpawns.add(pendingSpawn);
181 }
182 }
183
184 /**
185 * Pop the next request from the queue. Called when a free service is av ailable.
186 * @return the next spawn request waiting in the queue.
187 */
188 public PendingSpawnData dequeue() {
189 synchronized (sPendingSpawnsLock) {
190 return sPendingSpawns.poll();
191 }
192 }
193
194 /** @return the count of pending spawns in the queue */
195 public int size() {
196 synchronized (sPendingSpawnsLock) {
197 return sPendingSpawns.size();
198 }
199 }
200 }
201
202 private static final PendingSpawnQueue sPendingSpawnQueue = new PendingSpawn Queue();
203
124 // Service class for child process. As the default value it uses SandboxedPr ocessService0 and 204 // Service class for child process. As the default value it uses SandboxedPr ocessService0 and
125 // PrivilegedProcessService0. 205 // PrivilegedProcessService0.
126 private static ChildConnectionAllocator sSandboxedChildConnectionAllocator; 206 private static ChildConnectionAllocator sSandboxedChildConnectionAllocator;
127 private static ChildConnectionAllocator sPrivilegedChildConnectionAllocator; 207 private static ChildConnectionAllocator sPrivilegedChildConnectionAllocator;
128 208
129 private static final String NUM_SANDBOXED_SERVICES_KEY = 209 private static final String NUM_SANDBOXED_SERVICES_KEY =
130 "org.chromium.content.browser.NUM_SANDBOXED_SERVICES"; 210 "org.chromium.content.browser.NUM_SANDBOXED_SERVICES";
131 private static final String NUM_PRIVILEGED_SERVICES_KEY = 211 private static final String NUM_PRIVILEGED_SERVICES_KEY =
132 "org.chromium.content.browser.NUM_PRIVILEGED_SERVICES"; 212 "org.chromium.content.browser.NUM_PRIVILEGED_SERVICES";
133 213
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 String[] commandLine, boolean inSandbox) { 291 String[] commandLine, boolean inSandbox) {
212 ChromiumLinkerParams chromiumLinkerParams = getLinkerParamsForNewConnect ion(); 292 ChromiumLinkerParams chromiumLinkerParams = getLinkerParamsForNewConnect ion();
213 ChildProcessConnection connection = 293 ChildProcessConnection connection =
214 allocateConnection(context, inSandbox, chromiumLinkerParams); 294 allocateConnection(context, inSandbox, chromiumLinkerParams);
215 if (connection != null) { 295 if (connection != null) {
216 connection.start(commandLine); 296 connection.start(commandLine);
217 } 297 }
218 return connection; 298 return connection;
219 } 299 }
220 300
301 private static final long FREE_CONNECTION_DELAY_MILLIS = 1;
302
221 private static void freeConnection(ChildProcessConnection connection) { 303 private static void freeConnection(ChildProcessConnection connection) {
222 getConnectionAllocator(connection.isInSandbox()).free(connection); 304 // Freeing a service should be delayed. This is so that we avoid immedia tely reusing the
305 // freed service (see http://crbug.com/164069): the framework might keep a service process
306 // alive when it's been unbound for a short time. If a new connection to the same service
307 // is bound at that point, the process is reused and bad things happen ( mostly static
308 // variables are set when we don't expect them to).
309 final ChildProcessConnection conn = connection;
310 ThreadUtils.postOnUiThreadDelayed(new Runnable() {
311 @Override
312 public void run() {
313 getConnectionAllocator(conn.isInSandbox()).free(conn);
314
315 final PendingSpawnData pendingSpawn = sPendingSpawnQueue.dequeue ();
316 if (pendingSpawn != null) {
317 new Thread(new Runnable() {
318 @Override
319 public void run() {
320 startInternal(pendingSpawn.context(), pendingSpawn.c ommandLine(),
321 pendingSpawn.childProcessId(), pendingSpawn. filesToBeMapped(),
322 pendingSpawn.clientContext(), pendingSpawn.c allbackType(),
323 pendingSpawn.inSandbox());
324 }
325 }).start();
326 }
327 }
328 }, FREE_CONNECTION_DELAY_MILLIS);
223 } 329 }
224 330
225 // Represents an invalid process handle; same as base/process/process.h kNul lProcessHandle. 331 // Represents an invalid process handle; same as base/process/process.h kNul lProcessHandle.
226 private static final int NULL_PROCESS_HANDLE = 0; 332 private static final int NULL_PROCESS_HANDLE = 0;
227 333
228 // Map from pid to ChildService connection. 334 // Map from pid to ChildService connection.
229 private static Map<Integer, ChildProcessConnection> sServiceMap = 335 private static Map<Integer, ChildProcessConnection> sServiceMap =
230 new ConcurrentHashMap<Integer, ChildProcessConnection>(); 336 new ConcurrentHashMap<Integer, ChildProcessConnection>();
231 337
232 // A pre-allocated and pre-bound connection ready for connection setup, or n ull. 338 // A pre-allocated and pre-bound connection ready for connection setup, or n ull.
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 */ 486 */
381 @CalledByNative 487 @CalledByNative
382 static void start( 488 static void start(
383 Context context, 489 Context context,
384 final String[] commandLine, 490 final String[] commandLine,
385 int childProcessId, 491 int childProcessId,
386 int[] fileIds, 492 int[] fileIds,
387 int[] fileFds, 493 int[] fileFds,
388 boolean[] fileAutoClose, 494 boolean[] fileAutoClose,
389 long clientContext) { 495 long clientContext) {
496 assert fileIds.length == fileFds.length && fileFds.length == fileAutoClo se.length;
497 FileDescriptorInfo[] filesToBeMapped = new FileDescriptorInfo[fileFds.le ngth];
498 for (int i = 0; i < fileFds.length; i++) {
499 filesToBeMapped[i] =
500 new FileDescriptorInfo(fileIds[i], fileFds[i], fileAutoClose [i]);
501 }
502 assert clientContext != 0;
503
504 int callbackType = CALLBACK_FOR_UNKNOWN_PROCESS;
505 boolean inSandbox = true;
506 String processType = getSwitchValue(commandLine, SWITCH_PROCESS_TYPE);
507 if (SWITCH_RENDERER_PROCESS.equals(processType)) {
508 callbackType = CALLBACK_FOR_RENDERER_PROCESS;
509 } else if (SWITCH_GPU_PROCESS.equals(processType)) {
510 callbackType = CALLBACK_FOR_GPU_PROCESS;
511 inSandbox = false;
512 } else if (SWITCH_UTILITY_PROCESS.equals(processType)) {
513 // We only support sandboxed right now.
514 callbackType = CALLBACK_FOR_UTILITY_PROCESS;
515 } else {
516 assert false;
517 }
518
519 startInternal(context, commandLine, childProcessId, filesToBeMapped, cli entContext,
520 callbackType, inSandbox);
521 }
522
523 private static void startInternal(
524 Context context,
525 final String[] commandLine,
526 int childProcessId,
527 FileDescriptorInfo[] filesToBeMapped,
528 long clientContext,
529 int callbackType,
530 boolean inSandbox) {
390 try { 531 try {
391 TraceEvent.begin("ChildProcessLauncher.start"); 532 TraceEvent.begin("ChildProcessLauncher.startInternal");
392 assert fileIds.length == fileFds.length && fileFds.length == fileAut oClose.length;
393 FileDescriptorInfo[] filesToBeMapped = new FileDescriptorInfo[fileFd s.length];
394 for (int i = 0; i < fileFds.length; i++) {
395 filesToBeMapped[i] =
396 new FileDescriptorInfo(fileIds[i], fileFds[i], fileAutoC lose[i]);
397 }
398 assert clientContext != 0;
399
400 int callbackType = CALLBACK_FOR_UNKNOWN_PROCESS;
401 boolean inSandbox = true;
402 String processType = getSwitchValue(commandLine, SWITCH_PROCESS_TYPE );
403 if (SWITCH_RENDERER_PROCESS.equals(processType)) {
404 callbackType = CALLBACK_FOR_RENDERER_PROCESS;
405 } else if (SWITCH_GPU_PROCESS.equals(processType)) {
406 callbackType = CALLBACK_FOR_GPU_PROCESS;
407 inSandbox = false;
408 } else if (SWITCH_UTILITY_PROCESS.equals(processType)) {
409 // We only support sandboxed right now.
410 callbackType = CALLBACK_FOR_UTILITY_PROCESS;
411 } else {
412 assert false;
413 }
414 533
415 ChildProcessConnection allocatedConnection = null; 534 ChildProcessConnection allocatedConnection = null;
416 synchronized (ChildProcessLauncher.class) { 535 synchronized (ChildProcessLauncher.class) {
417 if (inSandbox) { 536 if (inSandbox) {
418 allocatedConnection = sSpareSandboxedConnection; 537 allocatedConnection = sSpareSandboxedConnection;
419 sSpareSandboxedConnection = null; 538 sSpareSandboxedConnection = null;
420 } 539 }
421 } 540 }
422 if (allocatedConnection == null) { 541 if (allocatedConnection == null) {
423 allocatedConnection = allocateBoundConnection(context, commandLi ne, inSandbox); 542 allocatedConnection = allocateBoundConnection(context, commandLi ne, inSandbox);
424 if (allocatedConnection == null) { 543 if (allocatedConnection == null) {
425 // Notify the native code so it can free the heap allocated callback. 544 Log.d(TAG, "Allocation of new service failed. Queuing up pen ding spawn.");
426 nativeOnChildProcessStarted(clientContext, 0); 545 sPendingSpawnQueue.enqueue(new PendingSpawnData(context, com mandLine,
427 Log.e(TAG, "Allocation of new service failed."); 546 childProcessId, filesToBeMapped, clientContext, call backType,
547 inSandbox));
428 return; 548 return;
429 } 549 }
430 } 550 }
431 551
432 Log.d(TAG, "Setting up connection to process: slot=" 552 Log.d(TAG, "Setting up connection to process: slot="
433 + allocatedConnection.getServiceNumber()); 553 + allocatedConnection.getServiceNumber());
434 triggerConnectionSetup(allocatedConnection, commandLine, childProces sId, 554 triggerConnectionSetup(allocatedConnection, commandLine, childProces sId,
435 filesToBeMapped, callbackType, clientContext); 555 filesToBeMapped, callbackType, clientContext);
436 } finally { 556 } finally {
437 TraceEvent.end("ChildProcessLauncher.start"); 557 TraceEvent.end("ChildProcessLauncher.startInternal");
438 } 558 }
439 } 559 }
440 560
441 @VisibleForTesting 561 @VisibleForTesting
442 static void triggerConnectionSetup( 562 static void triggerConnectionSetup(
443 final ChildProcessConnection connection, 563 final ChildProcessConnection connection,
444 String[] commandLine, 564 String[] commandLine,
445 int childProcessId, 565 int childProcessId,
446 FileDescriptorInfo[] filesToBeMapped, 566 FileDescriptorInfo[] filesToBeMapped,
447 int callbackType, 567 int callbackType,
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 if (pid > 0 && !nativeIsSingleProcess()) { 693 if (pid > 0 && !nativeIsSingleProcess()) {
574 Log.w(TAG, message + ", pid=" + pid); 694 Log.w(TAG, message + ", pid=" + pid);
575 } 695 }
576 } 696 }
577 697
578 @VisibleForTesting 698 @VisibleForTesting
579 static ChildProcessConnection allocateBoundConnectionForTesting(Context cont ext) { 699 static ChildProcessConnection allocateBoundConnectionForTesting(Context cont ext) {
580 return allocateBoundConnection(context, null, true); 700 return allocateBoundConnection(context, null, true);
581 } 701 }
582 702
703 /**
704 * Queue up a spawn requests for testing.
705 */
706 @VisibleForTesting
707 static void enqueuePendingSpawnForTesting(Context context) {
708 sPendingSpawnQueue.enqueue(new PendingSpawnData(context, new String[0], 1,
709 new FileDescriptorInfo[0], 0, CALLBACK_FOR_RENDERER_PROCESS, tru e));
710 }
711
583 /** @return the count of sandboxed connections managed by the allocator */ 712 /** @return the count of sandboxed connections managed by the allocator */
584 @VisibleForTesting 713 @VisibleForTesting
585 static int allocatedConnectionsCountForTesting(Context context) { 714 static int allocatedConnectionsCountForTesting(Context context) {
586 initConnectionAllocatorsIfNecessary(context); 715 initConnectionAllocatorsIfNecessary(context);
587 return sSandboxedChildConnectionAllocator.allocatedConnectionsCountForTe sting(); 716 return sSandboxedChildConnectionAllocator.allocatedConnectionsCountForTe sting();
588 } 717 }
589 718
590 /** @return the count of services set up and working */ 719 /** @return the count of services set up and working */
591 @VisibleForTesting 720 @VisibleForTesting
592 static int connectedServicesCountForTesting() { 721 static int connectedServicesCountForTesting() {
593 return sServiceMap.size(); 722 return sServiceMap.size();
594 } 723 }
595 724
725 /** @return the count of pending spawns in the queue */
726 @VisibleForTesting
727 static int pendingSpawnsCountForTesting() {
728 return sPendingSpawnQueue.size();
729 }
730
596 /** 731 /**
597 * Kills the child process for testing. 732 * Kills the child process for testing.
598 * @return true iff the process was killed as expected 733 * @return true iff the process was killed as expected
599 */ 734 */
600 @VisibleForTesting 735 @VisibleForTesting
601 public static boolean crashProcessForTesting(int pid) { 736 public static boolean crashProcessForTesting(int pid) {
602 if (sServiceMap.get(pid) == null) return false; 737 if (sServiceMap.get(pid) == null) return false;
603 738
604 try { 739 try {
605 ((ChildProcessConnectionImpl) sServiceMap.get(pid)).crashServiceForT esting(); 740 ((ChildProcessConnectionImpl) sServiceMap.get(pid)).crashServiceForT esting();
606 } catch (RemoteException ex) { 741 } catch (RemoteException ex) {
607 return false; 742 return false;
608 } 743 }
609 744
610 return true; 745 return true;
611 } 746 }
612 747
613 private static native void nativeOnChildProcessStarted(long clientContext, i nt pid); 748 private static native void nativeOnChildProcessStarted(long clientContext, i nt pid);
614 private static native void nativeEstablishSurfacePeer( 749 private static native void nativeEstablishSurfacePeer(
615 int pid, Surface surface, int primaryID, int secondaryID); 750 int pid, Surface surface, int primaryID, int secondaryID);
616 private static native boolean nativeIsSingleProcess(); 751 private static native boolean nativeIsSingleProcess();
617 } 752 }
OLDNEW
« no previous file with comments | « no previous file | content/public/android/javatests/src/org/chromium/content/browser/ChildProcessLauncherTest.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698