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

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

Issue 2017963003: Upstream: ChildProcessLauncher connects renderer processes of WebAPKs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix the MockChildProcessConnection. Created 4 years, 6 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.annotation.SuppressLint; 7 import android.annotation.SuppressLint;
8 import android.content.Context; 8 import android.content.Context;
9 import android.content.Intent; 9 import android.content.Intent;
10 import android.content.pm.ApplicationInfo; 10 import android.content.pm.ApplicationInfo;
11 import android.content.pm.PackageManager; 11 import android.content.pm.PackageManager;
12 import android.graphics.SurfaceTexture; 12 import android.graphics.SurfaceTexture;
13 import android.os.Build; 13 import android.os.Build;
14 import android.os.Bundle; 14 import android.os.Bundle;
15 import android.os.ParcelFileDescriptor; 15 import android.os.ParcelFileDescriptor;
16 import android.os.RemoteException; 16 import android.os.RemoteException;
17 import android.text.TextUtils; 17 import android.text.TextUtils;
18 import android.util.Pair; 18 import android.util.Pair;
19 import android.view.Surface; 19 import android.view.Surface;
20 20
21 import org.chromium.base.CommandLine; 21 import org.chromium.base.CommandLine;
22 import org.chromium.base.CpuFeatures; 22 import org.chromium.base.CpuFeatures;
23 import org.chromium.base.Log; 23 import org.chromium.base.Log;
24 import org.chromium.base.ThreadUtils; 24 import org.chromium.base.ThreadUtils;
25 import org.chromium.base.TraceEvent; 25 import org.chromium.base.TraceEvent;
26 import org.chromium.base.VisibleForTesting; 26 import org.chromium.base.VisibleForTesting;
27 import org.chromium.base.annotations.CalledByNative; 27 import org.chromium.base.annotations.CalledByNative;
28 import org.chromium.base.annotations.JNINamespace; 28 import org.chromium.base.annotations.JNINamespace;
29 import org.chromium.base.library_loader.LibraryProcessType;
29 import org.chromium.base.library_loader.Linker; 30 import org.chromium.base.library_loader.Linker;
30 import org.chromium.content.app.ChildProcessService; 31 import org.chromium.content.app.ChildProcessService;
31 import org.chromium.content.app.ChromiumLinkerParams; 32 import org.chromium.content.app.ChromiumLinkerParams;
32 import org.chromium.content.app.DownloadProcessService; 33 import org.chromium.content.app.DownloadProcessService;
33 import org.chromium.content.app.PrivilegedProcessService; 34 import org.chromium.content.app.PrivilegedProcessService;
34 import org.chromium.content.app.SandboxedProcessService; 35 import org.chromium.content.app.SandboxedProcessService;
35 import org.chromium.content.common.ContentSwitches; 36 import org.chromium.content.common.ContentSwitches;
36 import org.chromium.content.common.IChildProcessCallback; 37 import org.chromium.content.common.IChildProcessCallback;
37 import org.chromium.content.common.SurfaceWrapper; 38 import org.chromium.content.common.SurfaceWrapper;
38 39
39 import java.io.IOException; 40 import java.io.IOException;
40 import java.util.ArrayList; 41 import java.util.ArrayList;
42 import java.util.HashMap;
41 import java.util.LinkedList; 43 import java.util.LinkedList;
42 import java.util.Map; 44 import java.util.Map;
43 import java.util.Queue; 45 import java.util.Queue;
44 import java.util.concurrent.ConcurrentHashMap; 46 import java.util.concurrent.ConcurrentHashMap;
45 47
46 /** 48 /**
47 * This class provides the method to start/stop ChildProcess called by native. 49 * This class provides the method to start/stop ChildProcess called by native.
48 */ 50 */
49 @JNINamespace("content") 51 @JNINamespace("content")
50 public class ChildProcessLauncher { 52 public class ChildProcessLauncher {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 } 120 }
119 } 121 }
120 } 122 }
121 123
122 public boolean isFreeConnectionAvailable() { 124 public boolean isFreeConnectionAvailable() {
123 synchronized (mConnectionLock) { 125 synchronized (mConnectionLock) {
124 return !mFreeConnectionIndices.isEmpty(); 126 return !mFreeConnectionIndices.isEmpty();
125 } 127 }
126 } 128 }
127 129
128 /** @return the count of connections managed by the allocator */ 130 /** Returns the count of connections managed by the allocator */
pkotwicz 2016/05/28 01:04:14 Why this change?
Xi Han 2016/05/30 19:59:30 Due to the java style guide. I will revert them ba
pkotwicz 2016/05/31 00:38:58 My bad. Yes, the Java style guide says you should
129 @VisibleForTesting 131 @VisibleForTesting
130 int allocatedConnectionsCountForTesting() { 132 int allocatedConnectionsCountForTesting() {
131 return mChildProcessConnections.length - mFreeConnectionIndices.size (); 133 return mChildProcessConnections.length - mFreeConnectionIndices.size ();
132 } 134 }
133 } 135 }
134 136
135 private static class PendingSpawnData { 137 private static class PendingSpawnData {
136 private final Context mContext; 138 private final Context mContext;
137 private final String[] mCommandLine; 139 private final String[] mCommandLine;
138 private final int mChildProcessId; 140 private final int mChildProcessId;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 201
200 /** 202 /**
201 * Pop the next request from the queue. Called when a free service is av ailable. 203 * Pop the next request from the queue. Called when a free service is av ailable.
202 * @return the next spawn request waiting in the queue. 204 * @return the next spawn request waiting in the queue.
203 */ 205 */
204 public PendingSpawnData dequeueLocked() { 206 public PendingSpawnData dequeueLocked() {
205 assert Thread.holdsLock(sPendingSpawnsLock); 207 assert Thread.holdsLock(sPendingSpawnsLock);
206 return sPendingSpawns.poll(); 208 return sPendingSpawns.poll();
207 } 209 }
208 210
209 /** @return the count of pending spawns in the queue */ 211 /** Returns the count of pending spawns in the queue */
pkotwicz 2016/05/28 01:04:14 Why this change?
Xi Han 2016/05/30 19:59:31 Done.
210 public int sizeLocked() { 212 public int sizeLocked() {
211 assert Thread.holdsLock(sPendingSpawnsLock); 213 assert Thread.holdsLock(sPendingSpawnsLock);
212 return sPendingSpawns.size(); 214 return sPendingSpawns.size();
213 } 215 }
214 } 216 }
215 217
216 private static final PendingSpawnQueue sPendingSpawnQueue = new PendingSpawn Queue(); 218 private static final PendingSpawnQueue sPendingSpawnQueue = new PendingSpawn Queue();
217 219
218 // Service class for child process. As the default value it uses SandboxedPr ocessService0 and 220 // Service class for child process.
219 // PrivilegedProcessService0. 221 // Map from package name to ChildConnectionAllocator;
220 private static ChildConnectionAllocator sSandboxedChildConnectionAllocator; 222 private static Map<String, ChildConnectionAllocator> sSandboxedChildConnecti onAllocatorMap;
223 // As the default value it uses PrivilegedProcessService0.
221 private static ChildConnectionAllocator sPrivilegedChildConnectionAllocator; 224 private static ChildConnectionAllocator sPrivilegedChildConnectionAllocator;
222 225
223 private static final String NUM_SANDBOXED_SERVICES_KEY = 226 private static final String NUM_SANDBOXED_SERVICES_KEY =
224 "org.chromium.content.browser.NUM_SANDBOXED_SERVICES"; 227 "org.chromium.content.browser.NUM_SANDBOXED_SERVICES";
225 private static final String NUM_PRIVILEGED_SERVICES_KEY = 228 private static final String NUM_PRIVILEGED_SERVICES_KEY =
226 "org.chromium.content.browser.NUM_PRIVILEGED_SERVICES"; 229 "org.chromium.content.browser.NUM_PRIVILEGED_SERVICES";
227 // Overrides the number of available sandboxed services. 230 // Overrides the number of available sandboxed services.
228 @VisibleForTesting 231 @VisibleForTesting
229 public static final String SWITCH_NUM_SANDBOXED_SERVICES_FOR_TESTING = "num- sandboxed-services"; 232 public static final String SWITCH_NUM_SANDBOXED_SERVICES_FOR_TESTING = "num- sandboxed-services";
230 233
231 private static int getNumberOfServices(Context context, boolean inSandbox) { 234 private static int getNumberOfServices(Context context, boolean inSandbox, S tring packageName) {
232 try { 235 try {
233 PackageManager packageManager = context.getPackageManager(); 236 PackageManager packageManager = context.getPackageManager();
234 ChildProcessCreationParams childProcessCreationParams =
235 ChildProcessCreationParams.get();
236 final String packageName = childProcessCreationParams != null
237 ? childProcessCreationParams.getPackageName() : context.getP ackageName();
238 ApplicationInfo appInfo = packageManager.getApplicationInfo(packageN ame, 237 ApplicationInfo appInfo = packageManager.getApplicationInfo(packageN ame,
239 PackageManager.GET_META_DATA); 238 PackageManager.GET_META_DATA);
240 int numServices = appInfo.metaData.getInt(inSandbox ? NUM_SANDBOXED_ SERVICES_KEY 239 int numServices = -1;
241 : NUM_PRIVILEGED_SERVICES_KEY, -1); 240 if (appInfo.metaData != null) {
241 numServices = appInfo.metaData.getInt(
242 inSandbox ? NUM_SANDBOXED_SERVICES_KEY : NUM_PRIVILEGED_ SERVICES_KEY, -1);
243 }
242 if (inSandbox 244 if (inSandbox
243 && CommandLine.getInstance().hasSwitch( 245 && CommandLine.getInstance().hasSwitch(
244 SWITCH_NUM_SANDBOXED_SERVICES_FOR_TESTING)) { 246 SWITCH_NUM_SANDBOXED_SERVICES_FOR_TESTING)) {
245 String value = CommandLine.getInstance().getSwitchValue( 247 String value = CommandLine.getInstance().getSwitchValue(
246 SWITCH_NUM_SANDBOXED_SERVICES_FOR_TESTING); 248 SWITCH_NUM_SANDBOXED_SERVICES_FOR_TESTING);
247 if (!TextUtils.isEmpty(value)) { 249 if (!TextUtils.isEmpty(value)) {
248 try { 250 try {
249 numServices = Integer.parseInt(value); 251 numServices = Integer.parseInt(value);
250 } catch (NumberFormatException e) { 252 } catch (NumberFormatException e) {
251 Log.w(TAG, "The value of --num-sandboxed-services is for matted wrongly: " 253 Log.w(TAG, "The value of --num-sandboxed-services is for matted wrongly: "
252 + value); 254 + value);
253 } 255 }
254 } 256 }
255 } 257 }
256 if (numServices < 0) { 258 if (numServices < 0) {
257 throw new RuntimeException("Illegal meta data value for number o f child services"); 259 throw new RuntimeException("Illegal meta data value for number o f child services");
258 } 260 }
259 return numServices; 261 return numServices;
260 } catch (PackageManager.NameNotFoundException e) { 262 } catch (PackageManager.NameNotFoundException e) {
261 throw new RuntimeException("Could not get application info"); 263 throw new RuntimeException("Could not get application info");
262 } 264 }
263 } 265 }
264 266
265 private static void initConnectionAllocatorsIfNecessary(Context context) { 267 private static void initConnectionAllocatorsIfNecessary(
268 Context context, boolean inSandbox, String packageName) {
266 synchronized (ChildProcessLauncher.class) { 269 synchronized (ChildProcessLauncher.class) {
267 if (sSandboxedChildConnectionAllocator == null) { 270 if (inSandbox) {
268 sSandboxedChildConnectionAllocator = 271 if (sSandboxedChildConnectionAllocatorMap == null) {
269 new ChildConnectionAllocator(true, getNumberOfServices(c ontext, true)); 272 sSandboxedChildConnectionAllocatorMap =
273 new HashMap<String, ChildConnectionAllocator>();
274 }
275 if (!sSandboxedChildConnectionAllocatorMap.containsKey(packageNa me)) {
276 Log.w(TAG, "Create a new ChildConnectionAllocator with packa ge name = %s,"
277 + " inSandbox = true",
278 packageName);
279 sSandboxedChildConnectionAllocatorMap.put(packageName,
280 new ChildConnectionAllocator(true, getNumberOfServic es(context,
281 inSandbox , packageName)));
282 }
283 } else if (sPrivilegedChildConnectionAllocator == null) {
284 sPrivilegedChildConnectionAllocator = new ChildConnectionAllocat or(
285 false, getNumberOfServices(context, false, packageName)) ;
270 } 286 }
271 if (sPrivilegedChildConnectionAllocator == null) { 287 // TODO(pkotwicz|hanxi): Figure out when old allocators should be re moved from
272 sPrivilegedChildConnectionAllocator = 288 // {@code sSandboxedChildConnectionAllocatorMap}.
273 new ChildConnectionAllocator(false, getNumberOfServices( context, false));
274 }
275 } 289 }
276 } 290 }
277 291
278 private static ChildConnectionAllocator getConnectionAllocator(boolean inSan dbox) { 292 private static ChildConnectionAllocator getConnectionAllocator(
279 return inSandbox 293 String packageName, boolean inSandbox) {
280 ? sSandboxedChildConnectionAllocator : sPrivilegedChildConnectio nAllocator; 294 if (!inSandbox) {
295 return sPrivilegedChildConnectionAllocator;
296 }
297 return sSandboxedChildConnectionAllocatorMap.get(packageName);
281 } 298 }
282 299
283 private static ChildProcessConnection allocateConnection(Context context, bo olean inSandbox, 300 private static ChildProcessConnection allocateConnection(Context context, bo olean inSandbox,
284 ChromiumLinkerParams chromiumLinkerParams, boolean alwaysInForegroun d) { 301 ChromiumLinkerParams chromiumLinkerParams, boolean alwaysInForegroun d,
302 ChildProcessCreationParams creationParams) {
285 ChildProcessConnection.DeathCallback deathCallback = 303 ChildProcessConnection.DeathCallback deathCallback =
286 new ChildProcessConnection.DeathCallback() { 304 new ChildProcessConnection.DeathCallback() {
287 @Override 305 @Override
288 public void onChildProcessDied(ChildProcessConnection connec tion) { 306 public void onChildProcessDied(ChildProcessConnection connec tion) {
289 if (connection.getPid() != 0) { 307 if (connection.getPid() != 0) {
290 stop(connection.getPid()); 308 stop(connection.getPid());
291 } else { 309 } else {
292 freeConnection(connection); 310 freeConnection(connection);
293 } 311 }
294 } 312 }
295 }; 313 };
296 initConnectionAllocatorsIfNecessary(context); 314 String packageName = creationParams.getPackageName();
297 return getConnectionAllocator(inSandbox).allocate(context, deathCallback , 315 initConnectionAllocatorsIfNecessary(context, inSandbox, packageName);
298 chromiumLinkerParams, alwaysInForeground, ChildProcessCreationPa rams.get()); 316 return getConnectionAllocator(packageName, inSandbox)
317 .allocate(context, deathCallback, chromiumLinkerParams, alwaysIn Foreground,
318 creationParams);
299 } 319 }
300 320
301 private static boolean sLinkerInitialized = false; 321 private static boolean sLinkerInitialized = false;
302 private static long sLinkerLoadAddress = 0; 322 private static long sLinkerLoadAddress = 0;
303 323
304 private static ChromiumLinkerParams getLinkerParamsForNewConnection() { 324 private static ChromiumLinkerParams getLinkerParamsForNewConnection() {
305 if (!sLinkerInitialized) { 325 if (!sLinkerInitialized) {
306 if (Linker.isUsed()) { 326 if (Linker.isUsed()) {
307 sLinkerLoadAddress = Linker.getInstance().getBaseLoadAddress(); 327 sLinkerLoadAddress = Linker.getInstance().getBaseLoadAddress();
308 if (sLinkerLoadAddress == 0) { 328 if (sLinkerLoadAddress == 0) {
(...skipping 13 matching lines...) Expand all
322 waitForSharedRelros, 342 waitForSharedRelros,
323 linker.getTestRunnerClassNameForTest ing(), 343 linker.getTestRunnerClassNameForTest ing(),
324 linker.getImplementationForTesting() ); 344 linker.getImplementationForTesting() );
325 } else { 345 } else {
326 return new ChromiumLinkerParams(sLinkerLoadAddress, 346 return new ChromiumLinkerParams(sLinkerLoadAddress,
327 waitForSharedRelros); 347 waitForSharedRelros);
328 } 348 }
329 } 349 }
330 350
331 private static ChildProcessConnection allocateBoundConnection(Context contex t, 351 private static ChildProcessConnection allocateBoundConnection(Context contex t,
332 String[] commandLine, boolean inSandbox, boolean alwaysInForeground) { 352 String[] commandLine, boolean inSandbox, boolean alwaysInForeground,
353 ChildProcessCreationParams creationParams) {
333 ChromiumLinkerParams chromiumLinkerParams = getLinkerParamsForNewConnect ion(); 354 ChromiumLinkerParams chromiumLinkerParams = getLinkerParamsForNewConnect ion();
334 ChildProcessConnection connection = allocateConnection(context, inSandbo x, 355 ChildProcessConnection connection = allocateConnection(
335 chromiumLinkerParams, alwaysInForeground); 356 context, inSandbox, chromiumLinkerParams, alwaysInForeground, cr eationParams);
336 if (connection != null) { 357 if (connection != null) {
337 connection.start(commandLine); 358 connection.start(commandLine);
338 359
339 if (inSandbox && !sSandboxedChildConnectionAllocator.isFreeConnectio nAvailable()) { 360 if (inSandbox
361 && !sSandboxedChildConnectionAllocatorMap.get(creationParams .getPackageName())
pkotwicz 2016/05/28 01:04:14 Nit: Use getConnectionAllocator() instead of sSand
Xi Han 2016/05/30 19:59:31 Done.
362 .isFreeConnectionAvailable()) {
340 // Proactively releases all the moderate bindings once all the s andboxed services 363 // Proactively releases all the moderate bindings once all the s andboxed services
341 // are allocated, which will be very likely to have some of them killed by OOM 364 // are allocated, which will be very likely to have some of them killed by OOM
342 // killer. 365 // killer.
343 sBindingManager.releaseAllModerateBindings(); 366 sBindingManager.releaseAllModerateBindings();
344 } 367 }
345 } 368 }
346 return connection; 369 return connection;
347 } 370 }
348 371
349 private static final long FREE_CONNECTION_DELAY_MILLIS = 1; 372 private static final long FREE_CONNECTION_DELAY_MILLIS = 1;
(...skipping 13 matching lines...) Expand all
363 @Override 386 @Override
364 public void run() { 387 public void run() {
365 final PendingSpawnData pendingSpawn = freeConnectionAndDequeuePe nding(conn); 388 final PendingSpawnData pendingSpawn = freeConnectionAndDequeuePe nding(conn);
366 if (pendingSpawn != null) { 389 if (pendingSpawn != null) {
367 new Thread(new Runnable() { 390 new Thread(new Runnable() {
368 @Override 391 @Override
369 public void run() { 392 public void run() {
370 startInternal(pendingSpawn.context(), pendingSpawn.c ommandLine(), 393 startInternal(pendingSpawn.context(), pendingSpawn.c ommandLine(),
371 pendingSpawn.childProcessId(), pendingSpawn. filesToBeMapped(), 394 pendingSpawn.childProcessId(), pendingSpawn. filesToBeMapped(),
372 pendingSpawn.clientContext(), pendingSpawn.c allbackType(), 395 pendingSpawn.clientContext(), pendingSpawn.c allbackType(),
373 pendingSpawn.inSandbox()); 396 pendingSpawn.inSandbox(), conn.getCreationPa rams());
pkotwicz 2016/05/28 01:04:15 The params of the freed connection may be differen
Xi Han 2016/05/30 19:59:31 Good catch. Store ChildProcessCreationParams in Pe
374 } 397 }
375 }).start(); 398 }).start();
376 } 399 }
377 } 400 }
378 }, FREE_CONNECTION_DELAY_MILLIS); 401 }, FREE_CONNECTION_DELAY_MILLIS);
379 } 402 }
380 403
381 private static PendingSpawnData freeConnectionAndDequeuePending(ChildProcess Connection conn) { 404 private static PendingSpawnData freeConnectionAndDequeuePending(ChildProcess Connection conn) {
382 synchronized (PendingSpawnQueue.sPendingSpawnsLock) { 405 synchronized (PendingSpawnQueue.sPendingSpawnsLock) {
383 getConnectionAllocator(conn.isInSandbox()).free(conn); 406 getConnectionAllocator(conn.getCreationParams().getPackageName(), co nn.isInSandbox())
407 .free(conn);
384 return sPendingSpawnQueue.dequeueLocked(); 408 return sPendingSpawnQueue.dequeueLocked();
385 } 409 }
386 } 410 }
387 411
388 // Represents an invalid process handle; same as base/process/process.h kNul lProcessHandle. 412 // Represents an invalid process handle; same as base/process/process.h kNul lProcessHandle.
389 private static final int NULL_PROCESS_HANDLE = 0; 413 private static final int NULL_PROCESS_HANDLE = 0;
390 414
391 // Map from pid to ChildService connection. 415 // Map from pid to ChildService connection.
392 private static Map<Integer, ChildProcessConnection> sServiceMap = 416 private static Map<Integer, ChildProcessConnection> sServiceMap =
393 new ConcurrentHashMap<Integer, ChildProcessConnection>(); 417 new ConcurrentHashMap<Integer, ChildProcessConnection>();
(...skipping 13 matching lines...) Expand all
407 new ConcurrentHashMap<Pair<Integer, Integer>, Surface>(); 431 new ConcurrentHashMap<Pair<Integer, Integer>, Surface>();
408 432
409 // Whether the main application is currently brought to the foreground. 433 // Whether the main application is currently brought to the foreground.
410 private static boolean sApplicationInForeground = true; 434 private static boolean sApplicationInForeground = true;
411 435
412 @VisibleForTesting 436 @VisibleForTesting
413 public static void setBindingManagerForTesting(BindingManager manager) { 437 public static void setBindingManagerForTesting(BindingManager manager) {
414 sBindingManager = manager; 438 sBindingManager = manager;
415 } 439 }
416 440
417 /** @return true iff the child process is protected from out-of-memory killi ng */ 441 /** Returns true iff the child process is protected from out-of-memory killi ng */
pkotwicz 2016/05/28 01:04:15 Why this change?
Xi Han 2016/05/30 19:59:30 Done.
418 @CalledByNative 442 @CalledByNative
419 private static boolean isOomProtected(int pid) { 443 private static boolean isOomProtected(int pid) {
420 return sBindingManager.isOomProtected(pid); 444 return sBindingManager.isOomProtected(pid);
421 } 445 }
422 446
423 @CalledByNative 447 @CalledByNative
424 private static void registerViewSurface(int surfaceId, Surface surface) { 448 private static void registerViewSurface(int surfaceId, Surface surface) {
425 if (!surface.isValid()) 449 if (!surface.isValid())
426 throw new RuntimeException("Attempting to register invalid Surface." ); 450 throw new RuntimeException("Attempting to register invalid Surface." );
427 sViewSurfaceMap.put(surfaceId, surface); 451 sViewSurfaceMap.put(surfaceId, surface);
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 } 536 }
513 537
514 /** 538 /**
515 * Starts moderate binding management. 539 * Starts moderate binding management.
516 * @param context Android's context. 540 * @param context Android's context.
517 * @param moderateBindingTillBackgrounded true if the BindingManager should add a moderate 541 * @param moderateBindingTillBackgrounded true if the BindingManager should add a moderate
518 * binding to a render process when it is created and remove the moderate bi nding when Chrome is 542 * binding to a render process when it is created and remove the moderate bi nding when Chrome is
519 * sent to the background. 543 * sent to the background.
520 */ 544 */
521 public static void startModerateBindingManagement( 545 public static void startModerateBindingManagement(
522 Context context, boolean moderateBindingTillBackgrounded) { 546 Context context, boolean moderateBindingTillBackgrounded) {
pkotwicz 2016/05/28 01:04:15 {@link sBindingManager} is a singleton. This means
Xi Han 2016/05/30 19:59:31 Added a comment here.
523 sBindingManager.startModerateBindingManagement( 547 sBindingManager.startModerateBindingManagement(context,
524 context, getNumberOfServices(context, true), moderateBindingTill Backgrounded); 548 getNumberOfServices(context, true, context.getPackageName()),
549 moderateBindingTillBackgrounded);
525 } 550 }
526 551
527 /** 552 /**
528 * Called when the embedding application is brought to foreground. 553 * Called when the embedding application is brought to foreground.
529 */ 554 */
530 public static void onBroughtToForeground() { 555 public static void onBroughtToForeground() {
531 sApplicationInForeground = true; 556 sApplicationInForeground = true;
532 sBindingManager.onBroughtToForeground(); 557 sBindingManager.onBroughtToForeground();
533 } 558 }
534 559
535 /** 560 /**
536 * Returns whether the application is currently in the foreground. 561 * Returns whether the application is currently in the foreground.
537 */ 562 */
538 static boolean isApplicationInForeground() { 563 static boolean isApplicationInForeground() {
539 return sApplicationInForeground; 564 return sApplicationInForeground;
540 } 565 }
541 566
542 /** 567 /**
543 * Should be called early in startup so the work needed to spawn the child p rocess can be done 568 * Should be called early in startup so the work needed to spawn the child p rocess can be done
544 * in parallel to other startup work. Must not be called on the UI thread. S pare connection is 569 * in parallel to other startup work. Must not be called on the UI thread. S pare connection is
545 * created in sandboxed child process. 570 * created in sandboxed child process.
546 * @param context the application context used for the connection. 571 * @param context the application context used for the connection.
547 * @param params child process creation params.
548 */ 572 */
549 public static void warmUp(Context context, ChildProcessCreationParams params ) { 573 public static void warmUp(Context context) {
550 ChildProcessCreationParams.set(params);
551 synchronized (ChildProcessLauncher.class) { 574 synchronized (ChildProcessLauncher.class) {
552 assert !ThreadUtils.runningOnUiThread(); 575 assert !ThreadUtils.runningOnUiThread();
553 if (sSpareSandboxedConnection == null) { 576 if (sSpareSandboxedConnection == null) {
554 sSpareSandboxedConnection = allocateBoundConnection(context, nul l, true, false); 577 sSpareSandboxedConnection = allocateBoundConnection(context, nul l, true, false,
578 ChildProcessCreationParams.get().clone());
555 } 579 }
556 } 580 }
557 } 581 }
558 582
559 @CalledByNative 583 @CalledByNative
560 private static FileDescriptorInfo makeFdInfo( 584 private static FileDescriptorInfo makeFdInfo(
561 int id, int fd, boolean autoClose, long offset, long size) { 585 int id, int fd, boolean autoClose, long offset, long size) {
562 ParcelFileDescriptor pFd; 586 ParcelFileDescriptor pFd;
563 if (autoClose) { 587 if (autoClose) {
564 // Adopt the FD, it will be closed when we close the ParcelFileDescr iptor. 588 // Adopt the FD, it will be closed when we close the ParcelFileDescr iptor.
(...skipping 22 matching lines...) Expand all
587 */ 611 */
588 @CalledByNative 612 @CalledByNative
589 private static void start(Context context, final String[] commandLine, int c hildProcessId, 613 private static void start(Context context, final String[] commandLine, int c hildProcessId,
590 FileDescriptorInfo[] filesToBeMapped, long clientContext) { 614 FileDescriptorInfo[] filesToBeMapped, long clientContext) {
591 assert clientContext != 0; 615 assert clientContext != 0;
592 616
593 int callbackType = CALLBACK_FOR_UNKNOWN_PROCESS; 617 int callbackType = CALLBACK_FOR_UNKNOWN_PROCESS;
594 boolean inSandbox = true; 618 boolean inSandbox = true;
595 String processType = 619 String processType =
596 ContentSwitches.getSwitchValue(commandLine, ContentSwitches.SWIT CH_PROCESS_TYPE); 620 ContentSwitches.getSwitchValue(commandLine, ContentSwitches.SWIT CH_PROCESS_TYPE);
621 ChildProcessCreationParams params = ChildProcessCreationParams.get().clo ne();
597 if (ContentSwitches.SWITCH_RENDERER_PROCESS.equals(processType)) { 622 if (ContentSwitches.SWITCH_RENDERER_PROCESS.equals(processType)) {
598 callbackType = CALLBACK_FOR_RENDERER_PROCESS; 623 callbackType = CALLBACK_FOR_RENDERER_PROCESS;
599 } else if (ContentSwitches.SWITCH_GPU_PROCESS.equals(processType)) { 624 } else if (ContentSwitches.SWITCH_GPU_PROCESS.equals(processType)) {
600 callbackType = CALLBACK_FOR_GPU_PROCESS; 625 callbackType = CALLBACK_FOR_GPU_PROCESS;
601 inSandbox = false; 626 inSandbox = false;
627 // For GPU process, always set the Chrome's package name.
628 params = new ChildProcessCreationParams(
629 context.getPackageName(), 0, LibraryProcessType.PROCESS_CHIL D);
602 } else if (ContentSwitches.SWITCH_UTILITY_PROCESS.equals(processType)) { 630 } else if (ContentSwitches.SWITCH_UTILITY_PROCESS.equals(processType)) {
603 // We only support sandboxed right now. 631 // We only support sandboxed right now.
604 callbackType = CALLBACK_FOR_UTILITY_PROCESS; 632 callbackType = CALLBACK_FOR_UTILITY_PROCESS;
605 } else { 633 } else {
606 assert false; 634 assert false;
607 } 635 }
608 636
609 startInternal(context, commandLine, childProcessId, filesToBeMapped, cli entContext, 637 startInternal(context, commandLine, childProcessId, filesToBeMapped, cli entContext,
610 callbackType, inSandbox); 638 callbackType, inSandbox, params);
611 } 639 }
612 640
613 /** 641 /**
614 * Spawns a background download process if it hasn't been started. The downl oad process will 642 * Spawns a background download process if it hasn't been started. The downl oad process will
615 * manage its own lifecyle and can outlive chrome. 643 * manage its own lifecyle and can outlive chrome.
616 * 644 *
617 * @param context Context used to obtain the application context. 645 * @param context Context used to obtain the application context.
618 * @param commandLine The child process command line argv. 646 * @param commandLine The child process command line argv.
619 */ 647 */
620 @SuppressLint("NewApi") 648 @SuppressLint("NewApi")
(...skipping 22 matching lines...) Expand all
643 context.startService(intent); 671 context.startService(intent);
644 } 672 }
645 673
646 private static void startInternal( 674 private static void startInternal(
647 Context context, 675 Context context,
648 final String[] commandLine, 676 final String[] commandLine,
649 int childProcessId, 677 int childProcessId,
650 FileDescriptorInfo[] filesToBeMapped, 678 FileDescriptorInfo[] filesToBeMapped,
651 long clientContext, 679 long clientContext,
652 int callbackType, 680 int callbackType,
653 boolean inSandbox) { 681 boolean inSandbox,
682 ChildProcessCreationParams creationParams) {
654 try { 683 try {
655 TraceEvent.begin("ChildProcessLauncher.startInternal"); 684 TraceEvent.begin("ChildProcessLauncher.startInternal");
656 685
657 ChildProcessConnection allocatedConnection = null; 686 ChildProcessConnection allocatedConnection = null;
658 synchronized (ChildProcessLauncher.class) { 687 synchronized (ChildProcessLauncher.class) {
659 if (inSandbox) { 688 if (inSandbox) {
660 allocatedConnection = sSpareSandboxedConnection; 689 allocatedConnection = sSpareSandboxedConnection;
661 sSpareSandboxedConnection = null; 690 sSpareSandboxedConnection = null;
pkotwicz 2016/05/28 01:04:15 We may be wanting to create a connection for a Web
Xi Han 2016/05/30 19:59:30 Add a check here. Only use the SpareSandgoxedConne
662 } 691 }
663 } 692 }
664 if (allocatedConnection == null) { 693 if (allocatedConnection == null) {
665 boolean alwaysInForeground = false; 694 boolean alwaysInForeground = false;
666 if (callbackType == CALLBACK_FOR_GPU_PROCESS) alwaysInForeground = true; 695 if (callbackType == CALLBACK_FOR_GPU_PROCESS) alwaysInForeground = true;
667 synchronized (PendingSpawnQueue.sPendingSpawnsLock) { 696 synchronized (PendingSpawnQueue.sPendingSpawnsLock) {
668 allocatedConnection = allocateBoundConnection( 697 allocatedConnection = allocateBoundConnection(
669 context, commandLine, inSandbox, alwaysInForeground) ; 698 context, commandLine, inSandbox, alwaysInForeground, creationParams);
670 if (allocatedConnection == null) { 699 if (allocatedConnection == null) {
671 Log.d(TAG, "Allocation of new service failed. Queuing up pending spawn."); 700 Log.d(TAG, "Allocation of new service failed. Queuing up pending spawn.");
pkotwicz 2016/05/28 01:04:15 This is suboptimal. There should be a {@link sPend
Xi Han 2016/05/30 19:59:30 Good catch! Make each allocator owns a PendingSpaw
672 sPendingSpawnQueue.enqueueLocked(new PendingSpawnData(co ntext, commandLine, 701 sPendingSpawnQueue.enqueueLocked(new PendingSpawnData(co ntext, commandLine,
673 childProcessId, filesToBeMapped, clientContext, 702 childProcessId, filesToBeMapped, clientContext,
674 callbackType, inSandbox)); 703 callbackType, inSandbox));
675 return; 704 return;
676 } 705 }
677 } 706 }
678 } 707 }
679 708
680 Log.d(TAG, "Setting up connection to process: slot=%d", 709 Log.d(TAG, "Setting up connection to process: slot=%d",
681 allocatedConnection.getServiceNumber()); 710 allocatedConnection.getServiceNumber());
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
841 } 870 }
842 871
843 static void logPidWarning(int pid, String message) { 872 static void logPidWarning(int pid, String message) {
844 // This class is effectively a no-op in single process mode, so don't lo g warnings there. 873 // This class is effectively a no-op in single process mode, so don't lo g warnings there.
845 if (pid > 0 && !nativeIsSingleProcess()) { 874 if (pid > 0 && !nativeIsSingleProcess()) {
846 Log.w(TAG, "%s, pid=%d", message, pid); 875 Log.w(TAG, "%s, pid=%d", message, pid);
847 } 876 }
848 } 877 }
849 878
850 @VisibleForTesting 879 @VisibleForTesting
851 static ChildProcessConnection allocateBoundConnectionForTesting(Context cont ext) { 880 static ChildProcessConnection allocateBoundConnectionForTesting(Context cont ext,
852 return allocateBoundConnection(context, null, true, false); 881 ChildProcessCreationParams creationParams) {
882 return allocateBoundConnection(context, null, true, false, creationParam s);
853 } 883 }
854 884
855 /** 885 /**
856 * Queue up a spawn requests for testing. 886 * Queue up a spawn requests for testing.
857 */ 887 */
858 @VisibleForTesting 888 @VisibleForTesting
859 static void enqueuePendingSpawnForTesting(Context context, String[] commandL ine) { 889 static void enqueuePendingSpawnForTesting(Context context, String[] commandL ine) {
860 synchronized (PendingSpawnQueue.sPendingSpawnsLock) { 890 synchronized (PendingSpawnQueue.sPendingSpawnsLock) {
861 sPendingSpawnQueue.enqueueLocked(new PendingSpawnData(context, comma ndLine, 1, 891 sPendingSpawnQueue.enqueueLocked(new PendingSpawnData(context, comma ndLine, 1,
862 new FileDescriptorInfo[0], 0, CALLBACK_FOR_RENDERER_PROCESS, true)); 892 new FileDescriptorInfo[0], 0, CALLBACK_FOR_RENDERER_PROCESS, true));
863 } 893 }
864 } 894 }
865 895
866 /** @return the count of sandboxed connections managed by the allocator */ 896 /**
897 * Returns the number of sandboxed connections of given {@link packageName} managed by the
898 * allocator.
899 */
867 @VisibleForTesting 900 @VisibleForTesting
868 static int allocatedConnectionsCountForTesting(Context context) { 901 static int allocatedSandboxedConnectionsCountForTesting(Context context, Str ing packageName) {
869 initConnectionAllocatorsIfNecessary(context); 902 initConnectionAllocatorsIfNecessary(context, true, packageName);
870 return sSandboxedChildConnectionAllocator.allocatedConnectionsCountForTe sting(); 903 return sSandboxedChildConnectionAllocatorMap.get(packageName)
904 .allocatedConnectionsCountForTesting();
871 } 905 }
872 906
873 /** @return the count of services set up and working */ 907 /** Returns the count of services set up and working */
874 @VisibleForTesting 908 @VisibleForTesting
875 static int connectedServicesCountForTesting() { 909 static int connectedServicesCountForTesting() {
876 return sServiceMap.size(); 910 return sServiceMap.size();
877 } 911 }
878 912
879 /** @return the count of pending spawns in the queue */ 913 /** Returns the count of pending spawns in the queue */
880 @VisibleForTesting 914 @VisibleForTesting
881 static int pendingSpawnsCountForTesting() { 915 static int pendingSpawnsCountForTesting() {
882 synchronized (PendingSpawnQueue.sPendingSpawnsLock) { 916 synchronized (PendingSpawnQueue.sPendingSpawnsLock) {
883 return sPendingSpawnQueue.sizeLocked(); 917 return sPendingSpawnQueue.sizeLocked();
884 } 918 }
885 } 919 }
886 920
887 /** 921 /**
888 * Kills the child process for testing. 922 * Kills the child process for testing.
889 * @return true iff the process was killed as expected 923 * @return true iff the process was killed as expected
890 */ 924 */
891 @VisibleForTesting 925 @VisibleForTesting
892 public static boolean crashProcessForTesting(int pid) { 926 public static boolean crashProcessForTesting(int pid) {
893 if (sServiceMap.get(pid) == null) return false; 927 if (sServiceMap.get(pid) == null) return false;
894 928
895 try { 929 try {
896 ((ChildProcessConnectionImpl) sServiceMap.get(pid)).crashServiceForT esting(); 930 ((ChildProcessConnectionImpl) sServiceMap.get(pid)).crashServiceForT esting();
897 } catch (RemoteException ex) { 931 } catch (RemoteException ex) {
898 return false; 932 return false;
899 } 933 }
900 934
901 return true; 935 return true;
902 } 936 }
903 937
904 private static native void nativeOnChildProcessStarted(long clientContext, i nt pid); 938 private static native void nativeOnChildProcessStarted(long clientContext, i nt pid);
905 private static native void nativeEstablishSurfacePeer( 939 private static native void nativeEstablishSurfacePeer(
906 int pid, Surface surface, int primaryID, int secondaryID); 940 int pid, Surface surface, int primaryID, int secondaryID);
907 private static native boolean nativeIsSingleProcess(); 941 private static native boolean nativeIsSingleProcess();
908 } 942 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698