| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.content.browser; | 5 package org.chromium.content.browser; |
| 6 | 6 |
| 7 import android.content.ComponentName; | 7 import android.content.ComponentName; |
| 8 import android.content.Context; | 8 import android.content.Context; |
| 9 import android.content.pm.ApplicationInfo; | 9 import android.content.pm.ApplicationInfo; |
| 10 import android.content.pm.PackageManager; | 10 import android.content.pm.PackageManager; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 for (int i = 0; i < numChildServices; i++) { | 79 for (int i = 0; i < numChildServices; i++) { |
| 80 mFreeConnectionIndices.add(i); | 80 mFreeConnectionIndices.add(i); |
| 81 } | 81 } |
| 82 mChildClassName = serviceClassName; | 82 mChildClassName = serviceClassName; |
| 83 mInSandbox = inSandbox; | 83 mInSandbox = inSandbox; |
| 84 } | 84 } |
| 85 | 85 |
| 86 // Allocate or enqueue. If there are no free slots, return null and enqu
eue the spawn data. | 86 // Allocate or enqueue. If there are no free slots, return null and enqu
eue the spawn data. |
| 87 public ChildProcessConnection allocate(SpawnData spawnData, | 87 public ChildProcessConnection allocate(SpawnData spawnData, |
| 88 ChildProcessConnection.DeathCallback deathCallback, | 88 ChildProcessConnection.DeathCallback deathCallback, |
| 89 ChromiumLinkerParams chromiumLinkerParams, boolean alwaysInForeg
round) { | 89 Bundle childProcessCommonParameters, boolean alwaysInForeground)
{ |
| 90 assert spawnData.inSandbox() == mInSandbox; | 90 assert spawnData.inSandbox() == mInSandbox; |
| 91 synchronized (mConnectionLock) { | 91 synchronized (mConnectionLock) { |
| 92 if (mFreeConnectionIndices.isEmpty()) { | 92 if (mFreeConnectionIndices.isEmpty()) { |
| 93 Log.d(TAG, "Ran out of services to allocate."); | 93 Log.d(TAG, "Ran out of services to allocate."); |
| 94 if (!spawnData.forWarmUp()) { | 94 if (!spawnData.forWarmUp()) { |
| 95 mPendingSpawnQueue.add(spawnData); | 95 mPendingSpawnQueue.add(spawnData); |
| 96 } | 96 } |
| 97 return null; | 97 return null; |
| 98 } | 98 } |
| 99 int slot = mFreeConnectionIndices.remove(0); | 99 int slot = mFreeConnectionIndices.remove(0); |
| 100 assert mChildProcessConnections[slot] == null; | 100 assert mChildProcessConnections[slot] == null; |
| 101 mChildProcessConnections[slot] = new ChildProcessConnectionImpl(
spawnData.context(), | 101 mChildProcessConnections[slot] = |
| 102 slot, mInSandbox, deathCallback, mChildClassName, chromi
umLinkerParams, | 102 new ChildProcessConnectionImpl(spawnData.context(), slot
, mInSandbox, |
| 103 alwaysInForeground, spawnData.getCreationParams()); | 103 deathCallback, mChildClassName, childProcessComm
onParameters, |
| 104 alwaysInForeground, spawnData.getCreationParams(
)); |
| 104 Log.d(TAG, "Allocator allocated a connection, sandbox: %b, slot:
%d", mInSandbox, | 105 Log.d(TAG, "Allocator allocated a connection, sandbox: %b, slot:
%d", mInSandbox, |
| 105 slot); | 106 slot); |
| 106 return mChildProcessConnections[slot]; | 107 return mChildProcessConnections[slot]; |
| 107 } | 108 } |
| 108 } | 109 } |
| 109 | 110 |
| 110 // Also return the first SpawnData in the pending queue, if any. | 111 // Also return the first SpawnData in the pending queue, if any. |
| 111 public SpawnData free(ChildProcessConnection connection) { | 112 public SpawnData free(ChildProcessConnection connection) { |
| 112 synchronized (mConnectionLock) { | 113 synchronized (mConnectionLock) { |
| 113 int slot = connection.getServiceNumber(); | 114 int slot = connection.getServiceNumber(); |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 344 } | 345 } |
| 345 return sSandboxedChildConnectionAllocatorMap.get(packageName); | 346 return sSandboxedChildConnectionAllocatorMap.get(packageName); |
| 346 } | 347 } |
| 347 | 348 |
| 348 private static ChildConnectionAllocator getAllocatorForTesting( | 349 private static ChildConnectionAllocator getAllocatorForTesting( |
| 349 Context context, String packageName, boolean inSandbox) { | 350 Context context, String packageName, boolean inSandbox) { |
| 350 initConnectionAllocatorsIfNecessary(context, inSandbox, packageName); | 351 initConnectionAllocatorsIfNecessary(context, inSandbox, packageName); |
| 351 return getConnectionAllocator(packageName, inSandbox); | 352 return getConnectionAllocator(packageName, inSandbox); |
| 352 } | 353 } |
| 353 | 354 |
| 354 private static ChildProcessConnection allocateConnection(SpawnData spawnData
, | 355 private static ChildProcessConnection allocateConnection( |
| 355 ChromiumLinkerParams chromiumLinkerParams, boolean alwaysInForegroun
d) { | 356 SpawnData spawnData, Bundle childProcessCommonParams, boolean always
InForeground) { |
| 356 ChildProcessConnection.DeathCallback deathCallback = | 357 ChildProcessConnection.DeathCallback deathCallback = |
| 357 new ChildProcessConnection.DeathCallback() { | 358 new ChildProcessConnection.DeathCallback() { |
| 358 @Override | 359 @Override |
| 359 public void onChildProcessDied(ChildProcessConnection connec
tion) { | 360 public void onChildProcessDied(ChildProcessConnection connec
tion) { |
| 360 if (connection.getPid() != 0) { | 361 if (connection.getPid() != 0) { |
| 361 stop(connection.getPid()); | 362 stop(connection.getPid()); |
| 362 } else { | 363 } else { |
| 363 freeConnection(connection); | 364 freeConnection(connection); |
| 364 } | 365 } |
| 365 } | 366 } |
| 366 }; | 367 }; |
| 367 final ChildProcessCreationParams creationParams = spawnData.getCreationP
arams(); | 368 final ChildProcessCreationParams creationParams = spawnData.getCreationP
arams(); |
| 368 final Context context = spawnData.context(); | 369 final Context context = spawnData.context(); |
| 369 final boolean inSandbox = spawnData.inSandbox(); | 370 final boolean inSandbox = spawnData.inSandbox(); |
| 370 String packageName = | 371 String packageName = |
| 371 creationParams != null ? creationParams.getPackageName() : conte
xt.getPackageName(); | 372 creationParams != null ? creationParams.getPackageName() : conte
xt.getPackageName(); |
| 372 initConnectionAllocatorsIfNecessary(context, inSandbox, packageName); | 373 initConnectionAllocatorsIfNecessary(context, inSandbox, packageName); |
| 373 return getConnectionAllocator(packageName, inSandbox) | 374 return getConnectionAllocator(packageName, inSandbox) |
| 374 .allocate(spawnData, deathCallback, chromiumLinkerParams, always
InForeground); | 375 .allocate(spawnData, deathCallback, childProcessCommonParams, al
waysInForeground); |
| 375 } | 376 } |
| 376 | 377 |
| 377 private static boolean sLinkerInitialized; | 378 private static boolean sLinkerInitialized; |
| 378 private static long sLinkerLoadAddress; | 379 private static long sLinkerLoadAddress; |
| 379 | 380 |
| 380 private static ChromiumLinkerParams getLinkerParamsForNewConnection() { | 381 private static ChromiumLinkerParams getLinkerParamsForNewConnection() { |
| 381 if (!sLinkerInitialized) { | 382 if (!sLinkerInitialized) { |
| 382 if (Linker.isUsed()) { | 383 if (Linker.isUsed()) { |
| 383 sLinkerLoadAddress = Linker.getInstance().getBaseLoadAddress(); | 384 sLinkerLoadAddress = Linker.getInstance().getBaseLoadAddress(); |
| 384 if (sLinkerLoadAddress == 0) { | 385 if (sLinkerLoadAddress == 0) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 402 return new ChromiumLinkerParams(sLinkerLoadAddress, | 403 return new ChromiumLinkerParams(sLinkerLoadAddress, |
| 403 waitForSharedRelros); | 404 waitForSharedRelros); |
| 404 } | 405 } |
| 405 } | 406 } |
| 406 | 407 |
| 407 private static ChildProcessConnection allocateBoundConnection(SpawnData spaw
nData, | 408 private static ChildProcessConnection allocateBoundConnection(SpawnData spaw
nData, |
| 408 boolean alwaysInForeground, ChildProcessConnection.StartCallback sta
rtCallback) { | 409 boolean alwaysInForeground, ChildProcessConnection.StartCallback sta
rtCallback) { |
| 409 final Context context = spawnData.context(); | 410 final Context context = spawnData.context(); |
| 410 final boolean inSandbox = spawnData.inSandbox(); | 411 final boolean inSandbox = spawnData.inSandbox(); |
| 411 final ChildProcessCreationParams creationParams = spawnData.getCreationP
arams(); | 412 final ChildProcessCreationParams creationParams = spawnData.getCreationP
arams(); |
| 412 ChromiumLinkerParams chromiumLinkerParams = getLinkerParamsForNewConnect
ion(); | 413 Bundle commonParams = new Bundle(); |
| 414 commonParams.putParcelable( |
| 415 ChildProcessConstants.EXTRA_LINKER_PARAMS, getLinkerParamsForNew
Connection()); |
| 413 ChildProcessConnection connection = | 416 ChildProcessConnection connection = |
| 414 allocateConnection(spawnData, chromiumLinkerParams, alwaysInFore
ground); | 417 allocateConnection(spawnData, commonParams, alwaysInForeground); |
| 415 if (connection != null) { | 418 if (connection != null) { |
| 416 connection.start(startCallback); | 419 connection.start(startCallback); |
| 417 | 420 |
| 418 String packageName = creationParams != null ? creationParams.getPack
ageName() | 421 String packageName = creationParams != null ? creationParams.getPack
ageName() |
| 419 : context.getPackageName
(); | 422 : context.getPackageName
(); |
| 420 if (inSandbox | 423 if (inSandbox |
| 421 && !getConnectionAllocator(packageName, inSandbox) | 424 && !getConnectionAllocator(packageName, inSandbox) |
| 422 .isFreeConnectionAvailable()) { | 425 .isFreeConnectionAvailable()) { |
| 423 // Proactively releases all the moderate bindings once all the s
andboxed services | 426 // Proactively releases all the moderate bindings once all the s
andboxed services |
| 424 // are allocated, which will be very likely to have some of them
killed by OOM | 427 // are allocated, which will be very likely to have some of them
killed by OOM |
| (...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 881 return allocateBoundConnection( | 884 return allocateBoundConnection( |
| 882 new SpawnData(false /* forWarmUp */, context, null /* commandLin
e */, | 885 new SpawnData(false /* forWarmUp */, context, null /* commandLin
e */, |
| 883 0 /* childProcessId */, null /* filesToBeMapped */, 0 /*
clientContext */, | 886 0 /* childProcessId */, null /* filesToBeMapped */, 0 /*
clientContext */, |
| 884 CALLBACK_FOR_RENDERER_PROCESS, true /* inSandbox */, cre
ationParams), | 887 CALLBACK_FOR_RENDERER_PROCESS, true /* inSandbox */, cre
ationParams), |
| 885 false /* alwaysInForeground */, null); | 888 false /* alwaysInForeground */, null); |
| 886 } | 889 } |
| 887 | 890 |
| 888 @VisibleForTesting | 891 @VisibleForTesting |
| 889 static ChildProcessConnection allocateConnectionForTesting(Context context, | 892 static ChildProcessConnection allocateConnectionForTesting(Context context, |
| 890 ChildProcessCreationParams creationParams) { | 893 ChildProcessCreationParams creationParams) { |
| 894 Bundle commonParams = new Bundle(); |
| 895 commonParams.putParcelable( |
| 896 ChildProcessConstants.EXTRA_LINKER_PARAMS, getLinkerParamsForNew
Connection()); |
| 891 return allocateConnection( | 897 return allocateConnection( |
| 892 new SpawnData(false /* forWarmUp */, context, null /* commandLin
e */, | 898 new SpawnData(false /* forWarmUp */, context, null /* commandLin
e */, |
| 893 0 /* childProcessId */, null /* filesToBeMapped */, 0 /*
clientContext */, | 899 0 /* childProcessId */, null /* filesToBeMapped */, 0 /*
clientContext */, |
| 894 CALLBACK_FOR_RENDERER_PROCESS, true /* inSandbox */, cre
ationParams), | 900 CALLBACK_FOR_RENDERER_PROCESS, true /* inSandbox */, cre
ationParams), |
| 895 getLinkerParamsForNewConnection(), false); | 901 commonParams, false); |
| 896 } | 902 } |
| 897 | 903 |
| 898 /** | 904 /** |
| 899 * Queue up a spawn requests for testing. | 905 * Queue up a spawn requests for testing. |
| 900 */ | 906 */ |
| 901 @VisibleForTesting | 907 @VisibleForTesting |
| 902 static void enqueuePendingSpawnForTesting(Context context, String[] commandL
ine, | 908 static void enqueuePendingSpawnForTesting(Context context, String[] commandL
ine, |
| 903 ChildProcessCreationParams creationParams, boolean inSandbox) { | 909 ChildProcessCreationParams creationParams, boolean inSandbox) { |
| 904 String packageName = creationParams != null ? creationParams.getPackageN
ame() | 910 String packageName = creationParams != null ? creationParams.getPackageN
ame() |
| 905 : context.getPackageName(); | 911 : context.getPackageName(); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 965 | 971 |
| 966 return true; | 972 return true; |
| 967 } | 973 } |
| 968 | 974 |
| 969 private static native void nativeOnChildProcessStarted(long clientContext, i
nt pid); | 975 private static native void nativeOnChildProcessStarted(long clientContext, i
nt pid); |
| 970 private static native void nativeCompleteScopedSurfaceRequest( | 976 private static native void nativeCompleteScopedSurfaceRequest( |
| 971 UnguessableToken requestToken, Surface surface); | 977 UnguessableToken requestToken, Surface surface); |
| 972 private static native boolean nativeIsSingleProcess(); | 978 private static native boolean nativeIsSingleProcess(); |
| 973 private static native Surface nativeGetViewSurface(int surfaceId); | 979 private static native Surface nativeGetViewSurface(int surfaceId); |
| 974 } | 980 } |
| OLD | NEW |