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.annotation.SuppressLint; | 7 import android.annotation.SuppressLint; |
8 import android.content.Context; | 8 import android.content.Context; |
9 import android.os.Bundle; | 9 import android.os.Bundle; |
10 import android.os.IBinder; | 10 import android.os.IBinder; |
11 import android.os.RemoteException; | 11 import android.os.RemoteException; |
12 import android.text.TextUtils; | 12 import android.text.TextUtils; |
13 | 13 |
14 import org.chromium.base.CpuFeatures; | |
15 import org.chromium.base.Log; | 14 import org.chromium.base.Log; |
16 import org.chromium.base.ThreadUtils; | 15 import org.chromium.base.ThreadUtils; |
17 import org.chromium.base.TraceEvent; | 16 import org.chromium.base.TraceEvent; |
18 import org.chromium.base.VisibleForTesting; | 17 import org.chromium.base.VisibleForTesting; |
19 import org.chromium.base.annotations.SuppressFBWarnings; | 18 import org.chromium.base.annotations.SuppressFBWarnings; |
20 import org.chromium.base.library_loader.Linker; | |
21 import org.chromium.base.process_launcher.ChildProcessCreationParams; | 19 import org.chromium.base.process_launcher.ChildProcessCreationParams; |
22 import org.chromium.base.process_launcher.FileDescriptorInfo; | |
23 import org.chromium.content.app.ChromiumLinkerParams; | |
24 import org.chromium.content.app.SandboxedProcessService; | 20 import org.chromium.content.app.SandboxedProcessService; |
25 import org.chromium.content.common.ContentSwitches; | |
26 | 21 |
27 import java.util.HashMap; | 22 import java.util.HashMap; |
28 import java.util.Map; | 23 import java.util.Map; |
29 import java.util.concurrent.ConcurrentHashMap; | 24 import java.util.concurrent.ConcurrentHashMap; |
30 | 25 |
31 /** | 26 /** |
32 * This class provides the method to start/stop ChildProcess called by native. | 27 * This class provides the method to start/stop ChildProcess called by native. |
33 * | 28 * |
34 * Note about threading. The threading here is complicated and not well document
ed. | 29 * Note about threading. The threading here is complicated and not well document
ed. |
35 * Code can run on these threads: UI, Launcher, async thread pool, binder, and o
ne-off | 30 * Code can run on these threads: UI, Launcher, async thread pool, binder, and o
ne-off |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 sSandboxedServiceFactoryForTesting); | 101 sSandboxedServiceFactoryForTesting); |
107 } | 102 } |
108 sSandboxedChildConnectionAllocatorMap.put(packageName, connectionAll
ocator); | 103 sSandboxedChildConnectionAllocatorMap.put(packageName, connectionAll
ocator); |
109 } | 104 } |
110 return sSandboxedChildConnectionAllocatorMap.get(packageName); | 105 return sSandboxedChildConnectionAllocatorMap.get(packageName); |
111 // TODO(pkotwicz|hanxi): Figure out when old allocators should be remove
d from | 106 // TODO(pkotwicz|hanxi): Figure out when old allocators should be remove
d from |
112 // {@code sSandboxedChildConnectionAllocatorMap}. | 107 // {@code sSandboxedChildConnectionAllocatorMap}. |
113 } | 108 } |
114 | 109 |
115 @VisibleForTesting | 110 @VisibleForTesting |
116 static ChildProcessConnection allocateConnection( | 111 static ChildProcessConnection allocateConnection(ChildSpawnData spawnData, b
oolean forWarmUp) { |
117 ChildSpawnData spawnData, Bundle childProcessCommonParams, boolean f
orWarmUp) { | |
118 assert LauncherThread.runningOnLauncherThread(); | 112 assert LauncherThread.runningOnLauncherThread(); |
119 ChildProcessConnection.DeathCallback deathCallback = | 113 ChildProcessConnection.DeathCallback deathCallback = |
120 new ChildProcessConnection.DeathCallback() { | 114 new ChildProcessConnection.DeathCallback() { |
121 @Override | 115 @Override |
122 public void onChildProcessDied(ChildProcessConnection connec
tion) { | 116 public void onChildProcessDied(ChildProcessConnection connec
tion) { |
123 assert LauncherThread.runningOnLauncherThread(); | 117 assert LauncherThread.runningOnLauncherThread(); |
124 if (connection.getPid() != 0) { | 118 if (connection.getPid() != 0) { |
125 stop(connection.getPid()); | 119 stop(connection.getPid()); |
126 } else { | 120 } else { |
127 freeConnection(connection); | 121 freeConnection(connection); |
128 } | 122 } |
129 } | 123 } |
130 }; | 124 }; |
131 final ChildProcessCreationParams creationParams = spawnData.getCreationP
arams(); | 125 final ChildProcessCreationParams creationParams = spawnData.getCreationP
arams(); |
132 final Context context = spawnData.getContext(); | 126 final Context context = spawnData.getContext(); |
133 final boolean inSandbox = spawnData.isInSandbox(); | 127 final boolean inSandbox = spawnData.isInSandbox(); |
134 String packageName = | 128 String packageName = |
135 creationParams != null ? creationParams.getPackageName() : conte
xt.getPackageName(); | 129 creationParams != null ? creationParams.getPackageName() : conte
xt.getPackageName(); |
136 ChildConnectionAllocator allocator = | 130 ChildConnectionAllocator allocator = |
137 getConnectionAllocator(context, packageName, inSandbox); | 131 getConnectionAllocator(context, packageName, inSandbox); |
138 ChildProcessConnection connection = | 132 ChildProcessConnection connection = |
139 allocator.allocate(spawnData, deathCallback, childProcessCommonP
arams, !forWarmUp); | 133 allocator.allocate(spawnData, deathCallback, !forWarmUp); |
140 sConnectionsToAllocatorMap.put(connection, allocator); | 134 sConnectionsToAllocatorMap.put(connection, allocator); |
141 return connection; | 135 return connection; |
142 } | 136 } |
143 | 137 |
144 private static boolean sLinkerInitialized; | |
145 private static long sLinkerLoadAddress; | |
146 | |
147 private static ChromiumLinkerParams getLinkerParamsForNewConnection() { | |
148 if (!sLinkerInitialized) { | |
149 if (Linker.isUsed()) { | |
150 sLinkerLoadAddress = Linker.getInstance().getBaseLoadAddress(); | |
151 if (sLinkerLoadAddress == 0) { | |
152 Log.i(TAG, "Shared RELRO support disabled!"); | |
153 } | |
154 } | |
155 sLinkerInitialized = true; | |
156 } | |
157 | |
158 if (sLinkerLoadAddress == 0) return null; | |
159 | |
160 // Always wait for the shared RELROs in service processes. | |
161 final boolean waitForSharedRelros = true; | |
162 if (Linker.areTestsEnabled()) { | |
163 Linker linker = Linker.getInstance(); | |
164 return new ChromiumLinkerParams(sLinkerLoadAddress, | |
165 waitForSharedRelros, | |
166 linker.getTestRunnerClassNameForTest
ing(), | |
167 linker.getImplementationForTesting()
); | |
168 } else { | |
169 return new ChromiumLinkerParams(sLinkerLoadAddress, | |
170 waitForSharedRelros); | |
171 } | |
172 } | |
173 | |
174 @VisibleForTesting | |
175 static Bundle createCommonParamsBundle(ChildProcessCreationParams params) { | |
176 Bundle commonParams = new Bundle(); | |
177 commonParams.putParcelable( | |
178 ChildProcessConstants.EXTRA_LINKER_PARAMS, getLinkerParamsForNew
Connection()); | |
179 final boolean bindToCallerCheck = params == null ? false : params.getBin
dToCallerCheck(); | |
180 commonParams.putBoolean(ChildProcessConstants.EXTRA_BIND_TO_CALLER, bind
ToCallerCheck); | |
181 return commonParams; | |
182 } | |
183 | |
184 @VisibleForTesting | 138 @VisibleForTesting |
185 static ChildProcessConnection allocateBoundConnection(ChildSpawnData spawnDa
ta, | 139 static ChildProcessConnection allocateBoundConnection(ChildSpawnData spawnDa
ta, |
186 ChildProcessConnection.StartCallback startCallback, boolean forWarmU
p) { | 140 ChildProcessConnection.StartCallback startCallback, boolean forWarmU
p) { |
187 assert LauncherThread.runningOnLauncherThread(); | 141 assert LauncherThread.runningOnLauncherThread(); |
188 final Context context = spawnData.getContext(); | 142 final Context context = spawnData.getContext(); |
189 final boolean inSandbox = spawnData.isInSandbox(); | 143 final boolean inSandbox = spawnData.isInSandbox(); |
190 final ChildProcessCreationParams creationParams = spawnData.getCreationP
arams(); | 144 final ChildProcessCreationParams creationParams = spawnData.getCreationP
arams(); |
191 | 145 |
192 ChildProcessConnection connection = allocateConnection( | 146 ChildProcessConnection connection = allocateConnection(spawnData, forWar
mUp); |
193 spawnData, createCommonParamsBundle(spawnData.getCreationParams(
)), forWarmUp); | |
194 if (connection != null) { | 147 if (connection != null) { |
195 // Non sandboxed processes are privileged processes that should be s
trongly bound. | 148 // Non sandboxed processes are privileged processes that should be s
trongly bound. |
196 boolean useStrongBinding = !inSandbox; | 149 boolean useStrongBinding = !inSandbox; |
197 connection.start(useStrongBinding, startCallback); | 150 connection.start(useStrongBinding, startCallback); |
198 | 151 |
199 String packageName = creationParams != null ? creationParams.getPack
ageName() | 152 String packageName = creationParams != null ? creationParams.getPack
ageName() |
200 : context.getPackageName
(); | 153 : context.getPackageName
(); |
201 if (inSandbox | 154 if (inSandbox |
202 && !getConnectionAllocator(context, packageName, true /* san
dboxed */) | 155 && !getConnectionAllocator(context, packageName, true /* san
dboxed */) |
203 .isFreeConnectionAvailable()) { | 156 .isFreeConnectionAvailable()) { |
(...skipping 21 matching lines...) Expand all Loading... |
225 LauncherThread.postDelayed(new Runnable() { | 178 LauncherThread.postDelayed(new Runnable() { |
226 @Override | 179 @Override |
227 public void run() { | 180 public void run() { |
228 ChildConnectionAllocator allocator = sConnectionsToAllocatorMap.
remove(conn); | 181 ChildConnectionAllocator allocator = sConnectionsToAllocatorMap.
remove(conn); |
229 assert allocator != null; | 182 assert allocator != null; |
230 final ChildSpawnData pendingSpawn = allocator.free(conn); | 183 final ChildSpawnData pendingSpawn = allocator.free(conn); |
231 if (pendingSpawn != null) { | 184 if (pendingSpawn != null) { |
232 LauncherThread.post(new Runnable() { | 185 LauncherThread.post(new Runnable() { |
233 @Override | 186 @Override |
234 public void run() { | 187 public void run() { |
235 startInternal(pendingSpawn.getContext(), pendingSpaw
n.getCommandLine(), | 188 start(pendingSpawn.getContext(), pendingSpawn.getSer
viceBundle(), |
236 pendingSpawn.getFilesToBeMapped(), | 189 pendingSpawn.getConnectionBundle(), |
237 pendingSpawn.getLaunchCallback(), | 190 pendingSpawn.getLaunchCallback(), |
238 pendingSpawn.getChildProcessCallback(), | 191 pendingSpawn.getChildProcessCallback(), |
239 pendingSpawn.isInSandbox(), pendingSpawn.isA
lwaysInForeground(), | 192 pendingSpawn.isInSandbox(), pendingSpawn.isA
lwaysInForeground(), |
240 pendingSpawn.getCreationParams()); | 193 pendingSpawn.getCreationParams()); |
241 } | 194 } |
242 }); | 195 }); |
243 } | 196 } |
244 } | 197 } |
245 }, FREE_CONNECTION_DELAY_MILLIS); | 198 }, FREE_CONNECTION_DELAY_MILLIS); |
246 } | 199 } |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
371 @Override | 324 @Override |
372 public void onChildStartFailed() { | 325 public void onChildStartFailed() { |
373 assert LauncherThread.runningOnLauncherThread(); | 326 assert LauncherThread.runningOnLauncherThread(); |
374 Log.e(TAG, "Failed to warm up the spare sandbox
service"); | 327 Log.e(TAG, "Failed to warm up the spare sandbox
service"); |
375 if (sSpareConnectionStartCallback != null) { | 328 if (sSpareConnectionStartCallback != null) { |
376 sSpareConnectionStartCallback.onChildStartFa
iled(); | 329 sSpareConnectionStartCallback.onChildStartFa
iled(); |
377 } | 330 } |
378 clearSpareConnection(); | 331 clearSpareConnection(); |
379 } | 332 } |
380 }; | 333 }; |
381 ChildSpawnData spawnData = new ChildSpawnData(context, null /* c
ommandLine */, | 334 boolean bindToCallerCheck = params == null ? false : params.getB
indToCallerCheck(); |
382 null /* filesToBeMapped */, null /* launchCallback */, | 335 ChildSpawnData spawnData = new ChildSpawnData(context, |
| 336 ChildProcessLauncherHelper.createServiceBundle(bindToCal
lerCheck), |
| 337 null /* connectionBundle */, null /* launchCallback */, |
383 null /* child process callback */, true /* inSandbox */, | 338 null /* child process callback */, true /* inSandbox */, |
384 SPARE_CONNECTION_ALWAYS_IN_FOREGROUND, params); | 339 SPARE_CONNECTION_ALWAYS_IN_FOREGROUND, params); |
385 sSpareSandboxedConnection = | 340 sSpareSandboxedConnection = |
386 allocateBoundConnection(spawnData, startCallback, true /
* forWarmUp */); | 341 allocateBoundConnection(spawnData, startCallback, true /
* forWarmUp */); |
387 sSpareConnectionStarting = sSpareSandboxedConnection != null; | 342 sSpareConnectionStarting = sSpareSandboxedConnection != null; |
388 } | 343 } |
389 }); | 344 }); |
390 } | 345 } |
391 | 346 |
392 private static void clearSpareConnection() { | 347 private static void clearSpareConnection() { |
393 assert LauncherThread.runningOnLauncherThread(); | 348 assert LauncherThread.runningOnLauncherThread(); |
394 sSpareSandboxedConnection = null; | 349 sSpareSandboxedConnection = null; |
395 sSpareConnectionStarting = false; | 350 sSpareConnectionStarting = false; |
396 sSpareConnectionStartCallback = null; | 351 sSpareConnectionStartCallback = null; |
397 } | 352 } |
398 | 353 |
399 /** | 354 /** |
400 * Spawns and connects to a child process. It will not block, but will inste
ad callback to | 355 * Spawns and connects to a child process. It will not block, but will inste
ad callback to |
401 * {@link #LaunchCallback} on the launcher thread when the connection is est
ablished on. | 356 * {@link #LaunchCallback} on the launcher thread when the connection is est
ablished on. |
402 * | 357 * |
403 * @param context Context used to obtain the application context. | 358 * @param context Context used to obtain the application context. |
404 * @param paramId Key used to retrieve ChildProcessCreationParams. | 359 * @param paramId Key used to retrieve ChildProcessCreationParams. |
405 * @param commandLine The child process command line argv. | 360 * @param serviceBundle The Bundle passed in the intent used to bind to the
service. |
406 * @param filesToBeMapped File IDs, FDs, offsets, and lengths to pass throug
h. | 361 * @param connectionBundle The Bundle passed in setupConnection call. |
407 * @param launchCallback Callback invoked when the connection is established
. | 362 * @param launchCallback Callback invoked when the connection is established
. |
| 363 * @param childProcessCallback IBinder callback passed to the service. |
408 */ | 364 */ |
409 static void start(Context context, int paramId, final String[] commandLine, | |
410 FileDescriptorInfo[] filesToBeMapped, LaunchCallback launchCallback)
{ | |
411 assert LauncherThread.runningOnLauncherThread(); | |
412 IBinder childProcessCallback = null; | |
413 boolean inSandbox = true; | |
414 boolean alwaysInForeground = false; | |
415 String processType = | |
416 ContentSwitches.getSwitchValue(commandLine, ContentSwitches.SWIT
CH_PROCESS_TYPE); | |
417 ChildProcessCreationParams params = ChildProcessCreationParams.get(param
Id); | |
418 if (paramId != ChildProcessCreationParams.DEFAULT_ID && params == null)
{ | |
419 throw new RuntimeException("CreationParams id " + paramId + " not fo
und"); | |
420 } | |
421 if (!ContentSwitches.SWITCH_RENDERER_PROCESS.equals(processType)) { | |
422 if (params != null && !params.getPackageName().equals(context.getPac
kageName())) { | |
423 // WebViews and WebAPKs have renderer processes running in their
applications. | |
424 // When launching these renderer processes, {@link ChildProcessC
onnection} | |
425 // requires the package name of the application which holds the
renderer process. | |
426 // Therefore, the package name in ChildProcessCreationParams cou
ld be the package | |
427 // name of WebViews, WebAPKs, or Chrome, depending on the host a
pplication. | |
428 // Except renderer process, all other child processes should use
Chrome's package | |
429 // name. In WebAPK, ChildProcessCreationParams are initialized w
ith WebAPK's | |
430 // package name. Make a copy of the WebAPK's params, but replace
the package with | |
431 // Chrome's package to use when initializing a non-renderer proc
esses. | |
432 // TODO(boliu): Should fold into |paramId|. Investigate why this
is needed. | |
433 params = new ChildProcessCreationParams(context.getPackageName()
, | |
434 params.getIsExternalService(), params.getLibraryProcessT
ype(), | |
435 params.getBindToCallerCheck()); | |
436 } | |
437 if (ContentSwitches.SWITCH_GPU_PROCESS.equals(processType)) { | |
438 childProcessCallback = new GpuProcessCallback(); | |
439 inSandbox = false; | |
440 alwaysInForeground = true; | |
441 } else { | |
442 // We only support sandboxed utility processes now. | |
443 assert ContentSwitches.SWITCH_UTILITY_PROCESS.equals(processType
); | |
444 } | |
445 } | |
446 | |
447 startInternal(context, commandLine, filesToBeMapped, launchCallback, chi
ldProcessCallback, | |
448 inSandbox, alwaysInForeground, params); | |
449 } | |
450 | |
451 @VisibleForTesting | 365 @VisibleForTesting |
452 public static ChildProcessConnection startInternal(final Context context, | 366 public static boolean start(final Context context, final Bundle serviceBundl
e, |
453 final String[] commandLine, final FileDescriptorInfo[] filesToBeMapp
ed, | 367 final Bundle connectionBundle, final LaunchCallback launchCallback, |
454 final LaunchCallback launchCallback, final IBinder childProcessCallb
ack, | 368 final IBinder childProcessCallback, final boolean inSandbox, |
455 final boolean inSandbox, final boolean alwaysInForeground, | 369 final boolean alwaysInForeground, final ChildProcessCreationParams c
reationParams) { |
456 final ChildProcessCreationParams creationParams) { | |
457 assert LauncherThread.runningOnLauncherThread(); | 370 assert LauncherThread.runningOnLauncherThread(); |
458 try { | 371 try { |
459 TraceEvent.begin("ChildProcessLauncher.startInternal"); | 372 TraceEvent.begin("ChildProcessLauncher.start"); |
460 | 373 |
461 ChildProcessConnection allocatedConnection = null; | 374 ChildProcessConnection allocatedConnection = null; |
462 String packageName = creationParams != null ? creationParams.getPack
ageName() | 375 String packageName = creationParams != null ? creationParams.getPack
ageName() |
463 : context.getPackageName(); | 376 : context.getPackageName(); |
464 ChildProcessConnection.StartCallback startCallback = | 377 ChildProcessConnection.StartCallback startCallback = |
465 new ChildProcessConnection.StartCallback() { | 378 new ChildProcessConnection.StartCallback() { |
466 @Override | 379 @Override |
467 public void onChildStarted() {} | 380 public void onChildStarted() {} |
468 | 381 |
469 @Override | 382 @Override |
470 public void onChildStartFailed() { | 383 public void onChildStartFailed() { |
471 assert LauncherThread.runningOnLauncherThread(); | 384 assert LauncherThread.runningOnLauncherThread(); |
472 Log.e(TAG, "ChildProcessConnection.start failed, try
ing again"); | 385 Log.e(TAG, "ChildProcessConnection.start failed, try
ing again"); |
473 LauncherThread.post(new Runnable() { | 386 LauncherThread.post(new Runnable() { |
474 @Override | 387 @Override |
475 public void run() { | 388 public void run() { |
476 // The child process may already be bound to
another client | 389 // The child process may already be bound to
another client |
477 // (this can happen if multi-process WebView
is used in more | 390 // (this can happen if multi-process WebView
is used in more |
478 // than one process), so try starting the pr
ocess again. | 391 // than one process), so try starting the pr
ocess again. |
479 // This connection that failed to start has
not been freed, | 392 // This connection that failed to start has
not been freed, |
480 // so a new bound connection will be allocat
ed. | 393 // so a new bound connection will be allocat
ed. |
481 startInternal(context, commandLine, filesToB
eMapped, | 394 start(context, serviceBundle, connectionBund
le, launchCallback, |
482 launchCallback, childProcessCallback
, inSandbox, | 395 childProcessCallback, inSandbox, alw
aysInForeground, |
483 alwaysInForeground, creationParams); | 396 creationParams); |
484 } | 397 } |
485 }); | 398 }); |
486 } | 399 } |
487 }; | 400 }; |
488 | 401 |
489 if (inSandbox && sSpareSandboxedConnection != null | 402 if (inSandbox && sSpareSandboxedConnection != null |
490 && sSpareConnectionStartCallback == null | 403 && sSpareConnectionStartCallback == null |
491 && SPARE_CONNECTION_ALWAYS_IN_FOREGROUND == alwaysInForegrou
nd | 404 && SPARE_CONNECTION_ALWAYS_IN_FOREGROUND == alwaysInForegrou
nd |
492 && sSpareSandboxedConnection.getPackageName().equals(package
Name) | 405 && sSpareSandboxedConnection.getPackageName().equals(package
Name) |
493 // Object identity check for getDefault should be enough. Th
e default is | 406 // Object identity check for getDefault should be enough. Th
e default is |
494 // not supposed to change once set. | 407 // not supposed to change once set. |
495 && creationParams == ChildProcessCreationParams.getDefault()
) { | 408 && creationParams == ChildProcessCreationParams.getDefault()
) { |
496 allocatedConnection = sSpareSandboxedConnection; | 409 allocatedConnection = sSpareSandboxedConnection; |
497 if (sSpareConnectionStarting) { | 410 if (sSpareConnectionStarting) { |
498 sSpareConnectionStartCallback = startCallback; | 411 sSpareConnectionStartCallback = startCallback; |
499 } else { | 412 } else { |
500 clearSpareConnection(); | 413 clearSpareConnection(); |
501 } | 414 } |
502 } | 415 } |
503 if (allocatedConnection == null) { | 416 if (allocatedConnection == null) { |
504 ChildSpawnData spawnData = new ChildSpawnData(context, commandLi
ne, filesToBeMapped, | 417 ChildSpawnData spawnData = new ChildSpawnData(context, serviceBu
ndle, |
505 launchCallback, childProcessCallback, inSandbox, alwaysI
nForeground, | 418 connectionBundle, launchCallback, childProcessCallback,
inSandbox, |
506 creationParams); | 419 alwaysInForeground, creationParams); |
507 allocatedConnection = | 420 allocatedConnection = |
508 allocateBoundConnection(spawnData, startCallback, false
/* forWarmUp */); | 421 allocateBoundConnection(spawnData, startCallback, false
/* forWarmUp */); |
509 if (allocatedConnection == null) { | 422 if (allocatedConnection == null) { |
510 return null; | 423 return false; |
511 } | 424 } |
512 } | 425 } |
513 | |
514 boolean addToBindingmanager = inSandbox; | 426 boolean addToBindingmanager = inSandbox; |
515 triggerConnectionSetup(allocatedConnection, commandLine, filesToBeMa
pped, | 427 triggerConnectionSetup(allocatedConnection, connectionBundle, childP
rocessCallback, |
516 childProcessCallback, launchCallback, addToBindingmanager); | 428 launchCallback, addToBindingmanager); |
517 return allocatedConnection; | 429 return true; |
518 } finally { | 430 } finally { |
519 TraceEvent.end("ChildProcessLauncher.startInternal"); | 431 TraceEvent.end("ChildProcessLauncher.start"); |
520 } | 432 } |
521 } | 433 } |
522 | 434 |
523 /** | |
524 * Create the common bundle to be passed to child processes. | |
525 * @param context Application context. | |
526 * @param commandLine Command line params to be passed to the service. | |
527 * @param linkerParams Linker params to start the service. | |
528 */ | |
529 protected static Bundle createsServiceBundle( | |
530 String[] commandLine, FileDescriptorInfo[] filesToBeMapped) { | |
531 Bundle bundle = new Bundle(); | |
532 bundle.putStringArray(ChildProcessConstants.EXTRA_COMMAND_LINE, commandL
ine); | |
533 bundle.putParcelableArray(ChildProcessConstants.EXTRA_FILES, filesToBeMa
pped); | |
534 bundle.putInt(ChildProcessConstants.EXTRA_CPU_COUNT, CpuFeatures.getCoun
t()); | |
535 bundle.putLong(ChildProcessConstants.EXTRA_CPU_FEATURES, CpuFeatures.get
Mask()); | |
536 bundle.putBundle(Linker.EXTRA_LINKER_SHARED_RELROS, Linker.getInstance()
.getSharedRelros()); | |
537 return bundle; | |
538 } | |
539 | |
540 @VisibleForTesting | 435 @VisibleForTesting |
541 static void triggerConnectionSetup(final ChildProcessConnection connection, | 436 static void triggerConnectionSetup(final ChildProcessConnection connection, |
542 String[] commandLine, FileDescriptorInfo[] filesToBeMapped, | 437 Bundle connectionBundle, final IBinder childProcessCallback, |
543 final IBinder childProcessCallback, final LaunchCallback launchCallb
ack, | 438 final LaunchCallback launchCallback, final boolean addToBindingmanag
er) { |
544 final boolean addToBindingmanager) { | |
545 assert LauncherThread.runningOnLauncherThread(); | 439 assert LauncherThread.runningOnLauncherThread(); |
546 Log.d(TAG, "Setting up connection to process, connection name=%s", | 440 Log.d(TAG, "Setting up connection to process, connection name=%s", |
547 connection.getServiceName()); | 441 connection.getServiceName()); |
548 ChildProcessConnection.ConnectionCallback connectionCallback = | 442 ChildProcessConnection.ConnectionCallback connectionCallback = |
549 new ChildProcessConnection.ConnectionCallback() { | 443 new ChildProcessConnection.ConnectionCallback() { |
550 @Override | 444 @Override |
551 public void onConnected(ChildProcessConnection connection) { | 445 public void onConnected(ChildProcessConnection connection) { |
552 assert LauncherThread.runningOnLauncherThread(); | 446 assert LauncherThread.runningOnLauncherThread(); |
553 if (connection != null) { | 447 if (connection != null) { |
554 int pid = connection.getPid(); | 448 int pid = connection.getPid(); |
555 Log.d(TAG, "on connect callback, pid=%d", pid); | 449 Log.d(TAG, "on connect callback, pid=%d", pid); |
556 if (addToBindingmanager) { | 450 if (addToBindingmanager) { |
557 getBindingManager().addNewConnection(pid, connec
tion); | 451 getBindingManager().addNewConnection(pid, connec
tion); |
558 } | 452 } |
559 sServiceMap.put(pid, connection); | 453 sServiceMap.put(pid, connection); |
560 } | 454 } |
561 // If the connection fails and pid == 0, the Java-side c
leanup was already | 455 // If the connection fails and pid == 0, the Java-side c
leanup was already |
562 // handled by DeathCallback. We still have to call back
to native for | 456 // handled by DeathCallback. We still have to call back
to native for |
563 // cleanup there. | 457 // cleanup there. |
564 if (launchCallback != null) { // Will be null in Java in
strumentation tests. | 458 if (launchCallback != null) { // Will be null in Java in
strumentation tests. |
565 launchCallback.onChildProcessStarted(connection); | 459 launchCallback.onChildProcessStarted(connection); |
566 } | 460 } |
567 } | 461 } |
568 }; | 462 }; |
569 | 463 |
570 connection.setupConnection( | 464 connection.setupConnection(connectionBundle, childProcessCallback, conne
ctionCallback); |
571 commandLine, filesToBeMapped, childProcessCallback, connectionCa
llback); | |
572 } | 465 } |
573 | 466 |
574 /** | 467 /** |
575 * Terminates a child process. This may be called from any thread. | 468 * Terminates a child process. This may be called from any thread. |
576 * | 469 * |
577 * @param pid The pid (process handle) of the service connection obtained fr
om {@link #start}. | 470 * @param pid The pid (process handle) of the service connection obtained fr
om {@link #start}. |
578 */ | 471 */ |
579 static void stop(int pid) { | 472 static void stop(int pid) { |
580 assert LauncherThread.runningOnLauncherThread(); | 473 assert LauncherThread.runningOnLauncherThread(); |
581 Log.d(TAG, "stopping child connection: pid=%d", pid); | 474 Log.d(TAG, "stopping child connection: pid=%d", pid); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
623 | 516 |
624 try { | 517 try { |
625 sServiceMap.get(pid).crashServiceForTesting(); | 518 sServiceMap.get(pid).crashServiceForTesting(); |
626 } catch (RemoteException ex) { | 519 } catch (RemoteException ex) { |
627 return false; | 520 return false; |
628 } | 521 } |
629 | 522 |
630 return true; | 523 return true; |
631 } | 524 } |
632 } | 525 } |
OLD | NEW |