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

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

Issue 2828793002: Refactoring ChildProcessConnection. (Closed)
Patch Set: More test fixing. 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 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.os.Bundle; 8 import android.os.Bundle;
9 import android.os.IBinder; 9 import android.os.IBinder;
10 import android.os.RemoteException; 10 import android.os.RemoteException;
(...skipping 18 matching lines...) Expand all
29 * 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.
30 * 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
31 * background threads. 31 * background threads.
32 */ 32 */
33 public class ChildProcessLauncher { 33 public class ChildProcessLauncher {
34 private static final String TAG = "ChildProcLauncher"; 34 private static final String TAG = "ChildProcLauncher";
35 35
36 /** 36 /**
37 * Implemented by ChildProcessLauncherHelper. 37 * Implemented by ChildProcessLauncherHelper.
38 */ 38 */
39 public interface LaunchCallback { void onChildProcessStarted(int pid); } 39 public interface LaunchCallback {
40 void onChildProcessStarted(BaseChildProcessConnection connection);
41 }
40 42
41 private static final boolean SPARE_CONNECTION_ALWAYS_IN_FOREGROUND = false; 43 private static final boolean SPARE_CONNECTION_ALWAYS_IN_FOREGROUND = false;
42 44
43 @VisibleForTesting 45 @VisibleForTesting
44 static ChildProcessConnection allocateConnection( 46 static BaseChildProcessConnection allocateConnection(
45 ChildSpawnData spawnData, Bundle childProcessCommonParams, boolean f orWarmUp) { 47 ChildSpawnData spawnData, Bundle childProcessCommonParams, boolean f orWarmUp) {
46 assert LauncherThread.runningOnLauncherThread(); 48 assert LauncherThread.runningOnLauncherThread();
47 ChildProcessConnection.DeathCallback deathCallback = 49 BaseChildProcessConnection.DeathCallback deathCallback =
48 new ChildProcessConnection.DeathCallback() { 50 new BaseChildProcessConnection.DeathCallback() {
49 @Override 51 @Override
50 public void onChildProcessDied(ChildProcessConnection connec tion) { 52 public void onChildProcessDied(BaseChildProcessConnection co nnection) {
51 assert LauncherThread.runningOnLauncherThread(); 53 assert LauncherThread.runningOnLauncherThread();
52 if (connection.getPid() != 0) { 54 if (connection.getPid() != 0) {
53 stop(connection.getPid()); 55 stop(connection.getPid());
54 } else { 56 } else {
55 freeConnection(connection); 57 freeConnection(connection);
56 } 58 }
57 } 59 }
58 }; 60 };
59 final ChildProcessCreationParams creationParams = spawnData.getCreationP arams(); 61 final ChildProcessCreationParams creationParams = spawnData.getCreationP arams();
60 final Context context = spawnData.getContext(); 62 final Context context = spawnData.getContext();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 static Bundle createCommonParamsBundle(ChildProcessCreationParams params) { 101 static Bundle createCommonParamsBundle(ChildProcessCreationParams params) {
100 Bundle commonParams = new Bundle(); 102 Bundle commonParams = new Bundle();
101 commonParams.putParcelable( 103 commonParams.putParcelable(
102 ChildProcessConstants.EXTRA_LINKER_PARAMS, getLinkerParamsForNew Connection()); 104 ChildProcessConstants.EXTRA_LINKER_PARAMS, getLinkerParamsForNew Connection());
103 final boolean bindToCallerCheck = params == null ? false : params.getBin dToCallerCheck(); 105 final boolean bindToCallerCheck = params == null ? false : params.getBin dToCallerCheck();
104 commonParams.putBoolean(ChildProcessConstants.EXTRA_BIND_TO_CALLER, bind ToCallerCheck); 106 commonParams.putBoolean(ChildProcessConstants.EXTRA_BIND_TO_CALLER, bind ToCallerCheck);
105 return commonParams; 107 return commonParams;
106 } 108 }
107 109
108 @VisibleForTesting 110 @VisibleForTesting
109 static ChildProcessConnection allocateBoundConnection(ChildSpawnData spawnDa ta, 111 static BaseChildProcessConnection allocateBoundConnection(ChildSpawnData spa wnData,
110 ChildProcessConnection.StartCallback startCallback, boolean forWarmU p) { 112 BaseChildProcessConnection.StartCallback startCallback, boolean forW armUp) {
111 assert LauncherThread.runningOnLauncherThread(); 113 assert LauncherThread.runningOnLauncherThread();
112 final Context context = spawnData.getContext(); 114 final Context context = spawnData.getContext();
113 final boolean inSandbox = spawnData.isInSandbox(); 115 final boolean inSandbox = spawnData.isInSandbox();
114 final ChildProcessCreationParams creationParams = spawnData.getCreationP arams(); 116 final ChildProcessCreationParams creationParams = spawnData.getCreationP arams();
115 117
116 ChildProcessConnection connection = allocateConnection( 118 BaseChildProcessConnection connection = allocateConnection(
117 spawnData, createCommonParamsBundle(spawnData.getCreationParams( )), forWarmUp); 119 spawnData, createCommonParamsBundle(spawnData.getCreationParams( )), forWarmUp);
118 if (connection != null) { 120 if (connection != null) {
119 connection.start(startCallback); 121 connection.start(startCallback);
120 122
121 String packageName = creationParams != null ? creationParams.getPack ageName() 123 String packageName = creationParams != null ? creationParams.getPack ageName()
122 : context.getPackageName (); 124 : context.getPackageName ();
123 if (inSandbox 125 if (inSandbox
124 && !ChildConnectionAllocator.getAllocator(context, packageNa me, inSandbox) 126 && !ChildConnectionAllocator
127 .getAllocator(context, packageName, true /* sand boxed */)
125 .isFreeConnectionAvailable()) { 128 .isFreeConnectionAvailable()) {
126 // Proactively releases all the moderate bindings once all the s andboxed services 129 // Proactively releases all the moderate bindings once all the s andboxed services
127 // are allocated, which will be very likely to have some of them killed by OOM 130 // are allocated, which will be very likely to have some of them killed by OOM
128 // killer. 131 // killer.
129 getBindingManager().releaseAllModerateBindings(); 132 getBindingManager().releaseAllModerateBindings();
130 } 133 }
131 } 134 }
132 return connection; 135 return connection;
133 } 136 }
134 137
135 private static final long FREE_CONNECTION_DELAY_MILLIS = 1; 138 private static final long FREE_CONNECTION_DELAY_MILLIS = 1;
136 139
137 private static void freeConnection(ChildProcessConnection connection) { 140 private static void freeConnection(BaseChildProcessConnection connection) {
138 assert LauncherThread.runningOnLauncherThread(); 141 assert LauncherThread.runningOnLauncherThread();
139 if (connection == sSpareSandboxedConnection) clearSpareConnection(); 142 if (connection == sSpareSandboxedConnection) clearSpareConnection();
140 143
141 // Freeing a service should be delayed. This is so that we avoid immedia tely reusing the 144 // Freeing a service should be delayed. This is so that we avoid immedia tely reusing the
142 // freed service (see http://crbug.com/164069): the framework might keep a service process 145 // freed service (see http://crbug.com/164069): the framework might keep a service process
143 // alive when it's been unbound for a short time. If a new connection to the same service 146 // alive when it's been unbound for a short time. If a new connection to the same service
144 // is bound at that point, the process is reused and bad things happen ( mostly static 147 // is bound at that point, the process is reused and bad things happen ( mostly static
145 // variables are set when we don't expect them to). 148 // variables are set when we don't expect them to).
146 final ChildProcessConnection conn = connection; 149 final BaseChildProcessConnection conn = connection;
147 LauncherThread.postDelayed(new Runnable() { 150 LauncherThread.postDelayed(new Runnable() {
148 @Override 151 @Override
149 public void run() { 152 public void run() {
150 // TODO(jcivelli): it should be safe to pass a null Context here as it is used to 153 // TODO(jcivelli): it should be safe to pass a null Context here as it is used to
151 // initialize the ChildConnectionAllocator object and if we are freeing a 154 // initialize the ChildConnectionAllocator object and if we are freeing a
152 // connection, we must have allocated one previously guaranteein g it is already 155 // connection, we must have allocated one previously guaranteein g it is already
153 // initialized. When we consolidate ChildProcessLauncher and 156 // initialized. When we consolidate ChildProcessLauncher and
154 // ChildProcessLauncherHelper, we'll have a context around that we can pass in 157 // ChildProcessLauncherHelper, we'll have a context around that we can pass in
155 // there. 158 // there.
156 ChildConnectionAllocator allocator = ChildConnectionAllocator.ge tAllocator( 159 ChildConnectionAllocator allocator = ChildConnectionAllocator.ge tAllocator(
157 null /* context */, conn.getPackageName(), conn.isInSand box()); 160 null /* context */, conn.getPackageName(), conn.isSandbo xed());
158 assert allocator != null; 161 assert allocator != null;
159 final ChildSpawnData pendingSpawn = allocator.free(conn); 162 final ChildSpawnData pendingSpawn = allocator.free(conn);
160 if (pendingSpawn != null) { 163 if (pendingSpawn != null) {
161 LauncherThread.post(new Runnable() { 164 LauncherThread.post(new Runnable() {
162 @Override 165 @Override
163 public void run() { 166 public void run() {
164 startInternal(pendingSpawn.getContext(), pendingSpaw n.getCommandLine(), 167 startInternal(pendingSpawn.getContext(), pendingSpaw n.getCommandLine(),
165 pendingSpawn.getChildProcessId(), 168 pendingSpawn.getChildProcessId(),
166 pendingSpawn.getFilesToBeMapped(), 169 pendingSpawn.getFilesToBeMapped(),
167 pendingSpawn.getLaunchCallback(), 170 pendingSpawn.getLaunchCallback(),
168 pendingSpawn.getChildProcessCallback(), 171 pendingSpawn.getChildProcessCallback(),
169 pendingSpawn.isInSandbox(), pendingSpawn.isA lwaysInForeground(), 172 pendingSpawn.isInSandbox(), pendingSpawn.isA lwaysInForeground(),
170 pendingSpawn.getCreationParams()); 173 pendingSpawn.getCreationParams());
171 } 174 }
172 }); 175 });
173 } 176 }
174 } 177 }
175 }, FREE_CONNECTION_DELAY_MILLIS); 178 }, FREE_CONNECTION_DELAY_MILLIS);
176 } 179 }
177 180
178 // Represents an invalid process handle; same as base/process/process.h kNul lProcessHandle.
179 private static final int NULL_PROCESS_HANDLE = 0;
180
181 // Map from pid to ChildService connection. 181 // Map from pid to ChildService connection.
182 private static Map<Integer, ChildProcessConnection> sServiceMap = 182 private static Map<Integer, BaseChildProcessConnection> sServiceMap =
183 new ConcurrentHashMap<Integer, ChildProcessConnection>(); 183 new ConcurrentHashMap<Integer, BaseChildProcessConnection>();
184 184
185 // Lock for getBindingManager() 185 // Lock for getBindingManager()
186 private static final Object sBindingManagerLock = new Object(); 186 private static final Object sBindingManagerLock = new Object();
187 187
188 // These variables are used for the warm up sandboxed connection. 188 // These variables are used for the warm up sandboxed connection.
189 // |sSpareSandboxedConnection| is non-null when there is a pending connectio n. Note it's cleared 189 // |sSpareSandboxedConnection| is non-null when there is a pending connectio n. Note it's cleared
190 // to null again after the connection is used for a real child process. 190 // to null again after the connection is used for a real child process.
191 // |sSpareConnectionStarting| is true if ChildProcessConnection.StartCallbac k has not fired. 191 // |sSpareConnectionStarting| is true if ChildProcessConnection.StartCallbac k has not fired.
192 // This is used for a child process allocation to determine if StartCallback should be chained. 192 // This is used for a child process allocation to determine if StartCallback should be chained.
193 // |sSpareConnectionStartCallback| is the chained StartCallback. This is als o used to determine 193 // |sSpareConnectionStartCallback| is the chained StartCallback. This is als o used to determine
194 // if there is already a child process launch that's used this this connecti on. 194 // if there is already a child process launch that's used this this connecti on.
195 private static ChildProcessConnection sSpareSandboxedConnection; 195 private static BaseChildProcessConnection sSpareSandboxedConnection;
196 private static boolean sSpareConnectionStarting; 196 private static boolean sSpareConnectionStarting;
197 private static ChildProcessConnection.StartCallback sSpareConnectionStartCal lback; 197 private static BaseChildProcessConnection.StartCallback sSpareConnectionStar tCallback;
198 198
199 // Manages oom bindings used to bind chind services. Lazily initialized by g etBindingManager() 199 // Manages oom bindings used to bind chind services. Lazily initialized by g etBindingManager()
200 private static BindingManager sBindingManager; 200 private static BindingManager sBindingManager;
201 201
202 // Whether the main application is currently brought to the foreground. 202 // Whether the main application is currently brought to the foreground.
203 private static boolean sApplicationInForeground = true; 203 private static boolean sApplicationInForeground = true;
204 204
205 // Lazy initialize sBindingManager 205 // Lazy initialize sBindingManager
206 // TODO(boliu): This should be internal to content. 206 // TODO(boliu): This should be internal to content.
207 public static BindingManager getBindingManager() { 207 public static BindingManager getBindingManager() {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 * @param context the application context used for the connection. 271 * @param context the application context used for the connection.
272 */ 272 */
273 public static void warmUp(final Context context) { 273 public static void warmUp(final Context context) {
274 assert ThreadUtils.runningOnUiThread(); 274 assert ThreadUtils.runningOnUiThread();
275 LauncherThread.post(new Runnable() { 275 LauncherThread.post(new Runnable() {
276 @Override 276 @Override
277 public void run() { 277 public void run() {
278 if (sSpareSandboxedConnection != null) return; 278 if (sSpareSandboxedConnection != null) return;
279 ChildProcessCreationParams params = ChildProcessCreationParams.g etDefault(); 279 ChildProcessCreationParams params = ChildProcessCreationParams.g etDefault();
280 280
281 ChildProcessConnection.StartCallback startCallback = 281 BaseChildProcessConnection.StartCallback startCallback =
282 new ChildProcessConnection.StartCallback() { 282 new BaseChildProcessConnection.StartCallback() {
283 @Override 283 @Override
284 public void onChildStarted() { 284 public void onChildStarted() {
285 assert LauncherThread.runningOnLauncherThread(); 285 assert LauncherThread.runningOnLauncherThread();
286 sSpareConnectionStarting = false; 286 sSpareConnectionStarting = false;
287 if (sSpareConnectionStartCallback != null) { 287 if (sSpareConnectionStartCallback != null) {
288 sSpareConnectionStartCallback.onChildStarted (); 288 sSpareConnectionStartCallback.onChildStarted ();
289 clearSpareConnection(); 289 clearSpareConnection();
290 } 290 }
291 // If there is no chained callback, that means n othing has tried to 291 // If there is no chained callback, that means n othing has tried to
292 // use the spare connection yet. It will be clea red when it is used 292 // use the spare connection yet. It will be clea red when it is used
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 boolean alwaysInForeground = false; 340 boolean alwaysInForeground = false;
341 String processType = 341 String processType =
342 ContentSwitches.getSwitchValue(commandLine, ContentSwitches.SWIT CH_PROCESS_TYPE); 342 ContentSwitches.getSwitchValue(commandLine, ContentSwitches.SWIT CH_PROCESS_TYPE);
343 ChildProcessCreationParams params = ChildProcessCreationParams.get(param Id); 343 ChildProcessCreationParams params = ChildProcessCreationParams.get(param Id);
344 if (paramId != ChildProcessCreationParams.DEFAULT_ID && params == null) { 344 if (paramId != ChildProcessCreationParams.DEFAULT_ID && params == null) {
345 throw new RuntimeException("CreationParams id " + paramId + " not fo und"); 345 throw new RuntimeException("CreationParams id " + paramId + " not fo und");
346 } 346 }
347 if (!ContentSwitches.SWITCH_RENDERER_PROCESS.equals(processType)) { 347 if (!ContentSwitches.SWITCH_RENDERER_PROCESS.equals(processType)) {
348 if (params != null && !params.getPackageName().equals(context.getPac kageName())) { 348 if (params != null && !params.getPackageName().equals(context.getPac kageName())) {
349 // WebViews and WebAPKs have renderer processes running in their applications. 349 // WebViews and WebAPKs have renderer processes running in their applications.
350 // When launching these renderer processes, {@link ChildProcessC onnectionImpl} 350 // When launching these renderer processes, {@link ManagedChildP rocessConnection}
351 // requires the package name of the application which holds the renderer process. 351 // requires the package name of the application which holds the renderer process.
352 // Therefore, the package name in ChildProcessCreationParams cou ld be the package 352 // Therefore, the package name in ChildProcessCreationParams cou ld be the package
353 // name of WebViews, WebAPKs, or Chrome, depending on the host a pplication. 353 // name of WebViews, WebAPKs, or Chrome, depending on the host a pplication.
354 // Except renderer process, all other child processes should use Chrome's package 354 // Except renderer process, all other child processes should use Chrome's package
355 // name. In WebAPK, ChildProcessCreationParams are initialized w ith WebAPK's 355 // name. In WebAPK, ChildProcessCreationParams are initialized w ith WebAPK's
356 // package name. Make a copy of the WebAPK's params, but replace the package with 356 // package name. Make a copy of the WebAPK's params, but replace the package with
357 // Chrome's package to use when initializing a non-renderer proc esses. 357 // Chrome's package to use when initializing a non-renderer proc esses.
358 // TODO(boliu): Should fold into |paramId|. Investigate why this is needed. 358 // TODO(boliu): Should fold into |paramId|. Investigate why this is needed.
359 params = new ChildProcessCreationParams(context.getPackageName() , 359 params = new ChildProcessCreationParams(context.getPackageName() ,
360 params.getIsExternalService(), params.getLibraryProcessT ype(), 360 params.getIsExternalService(), params.getLibraryProcessT ype(),
361 params.getBindToCallerCheck()); 361 params.getBindToCallerCheck());
362 } 362 }
363 if (ContentSwitches.SWITCH_GPU_PROCESS.equals(processType)) { 363 if (ContentSwitches.SWITCH_GPU_PROCESS.equals(processType)) {
364 childProcessCallback = new GpuProcessCallback(); 364 childProcessCallback = new GpuProcessCallback();
365 inSandbox = false; 365 inSandbox = false;
366 alwaysInForeground = true; 366 alwaysInForeground = true;
367 } else { 367 } else {
368 // We only support sandboxed utility processes now. 368 // We only support sandboxed utility processes now.
369 assert ContentSwitches.SWITCH_UTILITY_PROCESS.equals(processType ); 369 assert ContentSwitches.SWITCH_UTILITY_PROCESS.equals(processType );
370 } 370 }
371 } 371 }
372 372
373 startInternal(context, commandLine, childProcessId, filesToBeMapped, lau nchCallback, 373 startInternal(context, commandLine, childProcessId, filesToBeMapped, lau nchCallback,
374 childProcessCallback, inSandbox, alwaysInForeground, params); 374 childProcessCallback, inSandbox, alwaysInForeground, params);
375 } 375 }
376 376
377 @VisibleForTesting 377 @VisibleForTesting
378 public static ChildProcessConnection startInternal(final Context context, 378 public static BaseChildProcessConnection startInternal(final Context context ,
379 final String[] commandLine, final int childProcessId, 379 final String[] commandLine, final int childProcessId,
380 final FileDescriptorInfo[] filesToBeMapped, final LaunchCallback lau nchCallback, 380 final FileDescriptorInfo[] filesToBeMapped, final LaunchCallback lau nchCallback,
381 final IBinder childProcessCallback, final boolean inSandbox, 381 final IBinder childProcessCallback, final boolean inSandbox,
382 final boolean alwaysInForeground, final ChildProcessCreationParams c reationParams) { 382 final boolean alwaysInForeground, final ChildProcessCreationParams c reationParams) {
383 assert LauncherThread.runningOnLauncherThread(); 383 assert LauncherThread.runningOnLauncherThread();
384 try { 384 try {
385 TraceEvent.begin("ChildProcessLauncher.startInternal"); 385 TraceEvent.begin("ChildProcessLauncher.startInternal");
386 386
387 ChildProcessConnection allocatedConnection = null; 387 BaseChildProcessConnection allocatedConnection = null;
388 String packageName = creationParams != null ? creationParams.getPack ageName() 388 String packageName = creationParams != null ? creationParams.getPack ageName()
389 : context.getPackageName(); 389 : context.getPackageName();
390 ChildProcessConnection.StartCallback startCallback = 390 BaseChildProcessConnection.StartCallback startCallback =
391 new ChildProcessConnection.StartCallback() { 391 new BaseChildProcessConnection.StartCallback() {
392 @Override 392 @Override
393 public void onChildStarted() {} 393 public void onChildStarted() {}
394 394
395 @Override 395 @Override
396 public void onChildStartFailed() { 396 public void onChildStartFailed() {
397 assert LauncherThread.runningOnLauncherThread(); 397 assert LauncherThread.runningOnLauncherThread();
398 Log.e(TAG, "ChildProcessConnection.start failed, try ing again"); 398 Log.e(TAG, "BaseChildProcessConnection.start failed, trying again");
399 LauncherThread.post(new Runnable() { 399 LauncherThread.post(new Runnable() {
400 @Override 400 @Override
401 public void run() { 401 public void run() {
402 // The child process may already be bound to another client 402 // The child process may already be bound to another client
403 // (this can happen if multi-process WebView is used in more 403 // (this can happen if multi-process WebView is used in more
404 // than one process), so try starting the pr ocess again. 404 // than one process), so try starting the pr ocess again.
405 // This connection that failed to start has not been freed, 405 // This connection that failed to start has not been freed,
406 // so a new bound connection will be allocat ed. 406 // so a new bound connection will be allocat ed.
407 startInternal(context, commandLine, childPro cessId, 407 startInternal(context, commandLine, childPro cessId,
408 filesToBeMapped, launchCallback, chi ldProcessCallback, 408 filesToBeMapped, launchCallback, chi ldProcessCallback,
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 Bundle bundle = new Bundle(); 457 Bundle bundle = new Bundle();
458 bundle.putStringArray(ChildProcessConstants.EXTRA_COMMAND_LINE, commandL ine); 458 bundle.putStringArray(ChildProcessConstants.EXTRA_COMMAND_LINE, commandL ine);
459 bundle.putParcelableArray(ChildProcessConstants.EXTRA_FILES, filesToBeMa pped); 459 bundle.putParcelableArray(ChildProcessConstants.EXTRA_FILES, filesToBeMa pped);
460 bundle.putInt(ChildProcessConstants.EXTRA_CPU_COUNT, CpuFeatures.getCoun t()); 460 bundle.putInt(ChildProcessConstants.EXTRA_CPU_COUNT, CpuFeatures.getCoun t());
461 bundle.putLong(ChildProcessConstants.EXTRA_CPU_FEATURES, CpuFeatures.get Mask()); 461 bundle.putLong(ChildProcessConstants.EXTRA_CPU_FEATURES, CpuFeatures.get Mask());
462 bundle.putBundle(Linker.EXTRA_LINKER_SHARED_RELROS, Linker.getInstance() .getSharedRelros()); 462 bundle.putBundle(Linker.EXTRA_LINKER_SHARED_RELROS, Linker.getInstance() .getSharedRelros());
463 return bundle; 463 return bundle;
464 } 464 }
465 465
466 @VisibleForTesting 466 @VisibleForTesting
467 static void triggerConnectionSetup(final ChildProcessConnection connection, 467 static void triggerConnectionSetup(final BaseChildProcessConnection connecti on,
468 String[] commandLine, int childProcessId, FileDescriptorInfo[] files ToBeMapped, 468 String[] commandLine, int childProcessId, FileDescriptorInfo[] files ToBeMapped,
469 final IBinder childProcessCallback, final LaunchCallback launchCallb ack) { 469 final IBinder childProcessCallback, final LaunchCallback launchCallb ack) {
470 assert LauncherThread.runningOnLauncherThread(); 470 assert LauncherThread.runningOnLauncherThread();
471 Log.d(TAG, "Setting up connection to process: slot=%d", connection.getSe rviceNumber()); 471 Log.d(TAG, "Setting up connection to process: slot=%d", connection.getSe rviceNumber());
472 ChildProcessConnection.ConnectionCallback connectionCallback = 472 BaseChildProcessConnection.ConnectionCallback connectionCallback =
473 new ChildProcessConnection.ConnectionCallback() { 473 new BaseChildProcessConnection.ConnectionCallback() {
474 @Override 474 @Override
475 public void onConnected(int pid) { 475 public void onConnected(BaseChildProcessConnection connectio n) {
476 Log.d(TAG, "on connect callback, pid=%d", pid); 476 if (connection != null) {
477 if (pid != NULL_PROCESS_HANDLE) { 477 int pid = connection.getPid();
478 getBindingManager().addNewConnection(pid, connection ); 478 Log.d(TAG, "on connect callback, pid=%d", pid);
479 if (connection instanceof ManagedChildProcessConnect ion) {
480 getBindingManager().addNewConnection(
481 pid, (ManagedChildProcessConnection) con nection);
482 }
479 sServiceMap.put(pid, connection); 483 sServiceMap.put(pid, connection);
480 } 484 }
481 // If the connection fails and pid == 0, the Java-side c leanup was already 485 // If the connection fails and pid == 0, the Java-side c leanup was already
482 // handled by DeathCallback. We still have to call back to native for 486 // handled by DeathCallback. We still have to call back to native for
483 // cleanup there. 487 // cleanup there.
484 if (launchCallback != null) { // Will be null in Java in strumentation tests. 488 if (launchCallback != null) { // Will be null in Java in strumentation tests.
485 launchCallback.onChildProcessStarted(pid); 489 launchCallback.onChildProcessStarted(connection);
486 } 490 }
487 } 491 }
488 }; 492 };
489 493
490 connection.setupConnection( 494 connection.setupConnection(
491 commandLine, filesToBeMapped, childProcessCallback, connectionCa llback); 495 commandLine, filesToBeMapped, childProcessCallback, connectionCa llback);
492 } 496 }
493 497
494 /** 498 /**
495 * Terminates a child process. This may be called from any thread. 499 * Terminates a child process. This may be called from any thread.
496 * 500 *
497 * @param pid The pid (process handle) of the service connection obtained fr om {@link #start}. 501 * @param pid The pid (process handle) of the service connection obtained fr om {@link #start}.
498 */ 502 */
499 static void stop(int pid) { 503 static void stop(int pid) {
500 assert LauncherThread.runningOnLauncherThread(); 504 assert LauncherThread.runningOnLauncherThread();
501 Log.d(TAG, "stopping child connection: pid=%d", pid); 505 Log.d(TAG, "stopping child connection: pid=%d", pid);
502 ChildProcessConnection connection = sServiceMap.remove(pid); 506 BaseChildProcessConnection connection = sServiceMap.remove(pid);
503 if (connection == null) { 507 if (connection == null) {
504 // Can happen for single process. 508 // Can happen for single process.
505 return; 509 return;
506 } 510 }
507 getBindingManager().clearConnection(pid); 511 getBindingManager().removeConnection(pid);
508 connection.stop(); 512 connection.stop();
509 freeConnection(connection); 513 freeConnection(connection);
510 } 514 }
511 515
512 /** @return the count of services set up and working */ 516 /** @return the count of services set up and working */
513 @VisibleForTesting 517 @VisibleForTesting
514 static int connectedServicesCountForTesting() { 518 static int connectedServicesCountForTesting() {
515 return sServiceMap.size(); 519 return sServiceMap.size();
516 } 520 }
517 521
518 /** 522 /**
519 * Kills the child process for testing. 523 * Kills the child process for testing.
520 * @return true iff the process was killed as expected 524 * @return true iff the process was killed as expected
521 */ 525 */
522 @VisibleForTesting 526 @VisibleForTesting
523 public static boolean crashProcessForTesting(int pid) { 527 public static boolean crashProcessForTesting(int pid) {
524 if (sServiceMap.get(pid) == null) return false; 528 if (sServiceMap.get(pid) == null) return false;
525 529
526 try { 530 try {
527 ((ChildProcessConnectionImpl) sServiceMap.get(pid)).crashServiceForT esting(); 531 ((ManagedChildProcessConnection) sServiceMap.get(pid)).crashServiceF orTesting();
528 } catch (RemoteException ex) { 532 } catch (RemoteException ex) {
529 return false; 533 return false;
530 } 534 }
531 535
532 return true; 536 return true;
533 } 537 }
534 } 538 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698