| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |