Commit 7d1779db authored by Bo Liu's avatar Bo Liu Committed by Commit Bot

android: Kill child process when out of service slots

Kill the lowest ranked connection when there are no more service slots
when trying to allocate a new connection.

Remove the hack solution that passed down the number of service slots
to RenderProcessHost::GetMaxRendererProcessCount.
Remove releaseAllModerateBindings when the last service is allocated.
Add a test in content that verifies intentional kill works.

Refactored ChildConnectionAllocator to make the queuing of requests
explicit. Then add a callback when Allocator runs out of slots for
allocation which content layer handles by killing the lowest ranked
connection. This implementation ensures there is only one connection
being killed waiting to be noticed.

Change-Id: I5f670dfcf6ce645ab2681ec97d095eca98b2b5a2
Reviewed-on: https://chromium-review.googlesource.com/1002193
Commit-Queue: Bo <boliu@chromium.org>
Reviewed-by: default avatarYaron Friedman <yfriedman@chromium.org>
Reviewed-by: default avatarMaria Khomenko <mariakhomenko@chromium.org>
Cr-Commit-Position: refs/heads/master@{#556329}
parent 6f3313d8
......@@ -13,11 +13,12 @@ import android.os.Handler;
import android.os.Looper;
import org.chromium.base.Log;
import org.chromium.base.ObserverList;
import org.chromium.base.VisibleForTesting;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Queue;
/**
* This class is responsible for allocating and managing connections to child
......@@ -27,17 +28,6 @@ import java.util.Arrays;
public class ChildConnectionAllocator {
private static final String TAG = "ChildConnAllocator";
/** Listener that clients can use to get notified when connections get allocated/freed. */
public abstract static class Listener {
/** Called when a connection has been allocated, before it gets bound. */
public void onConnectionAllocated(
ChildConnectionAllocator allocator, ChildProcessConnection connection) {}
/** Called when a connection has been freed. */
public void onConnectionFreed(
ChildConnectionAllocator allocator, ChildProcessConnection connection) {}
}
/** Factory interface. Used by tests to specialize created connections. */
@VisibleForTesting
public interface ConnectionFactory {
......@@ -64,6 +54,9 @@ public class ChildConnectionAllocator {
// Connections to services. Indices of the array correspond to the service numbers.
private final ChildProcessConnection[] mChildProcessConnections;
// Runnable which will be called when allocator wants to allocate a new connection, but does
// not have any more free slots. May be null.
private final Runnable mFreeSlotCallback;
private final String mPackageName;
private final String mServiceClassName;
private final boolean mBindToCaller;
......@@ -73,7 +66,7 @@ public class ChildConnectionAllocator {
// The list of free (not bound) service indices.
private final ArrayList<Integer> mFreeConnectionIndices;
private final ObserverList<Listener> mListeners = new ObserverList<>();
private final Queue<Runnable> mPendingAllocations = new ArrayDeque<>();
private ConnectionFactory mConnectionFactory = new ConnectionFactoryImpl();
......@@ -82,8 +75,9 @@ public class ChildConnectionAllocator {
* AndroidManifest.xml.
*/
public static ChildConnectionAllocator create(Context context, Handler launcherHandler,
String packageName, String serviceClassName, String numChildServicesManifestKey,
boolean bindToCaller, boolean bindAsExternalService, boolean useStrongBinding) {
Runnable freeSlotCallback, String packageName, String serviceClassName,
String numChildServicesManifestKey, boolean bindToCaller, boolean bindAsExternalService,
boolean useStrongBinding) {
int numServices = -1;
PackageManager packageManager = context.getPackageManager();
try {
......@@ -109,28 +103,9 @@ public class ChildConnectionAllocator {
throw new RuntimeException("Illegal meta data value: the child service doesn't exist");
}
return new ChildConnectionAllocator(launcherHandler, packageName, serviceClassName,
bindToCaller, bindAsExternalService, useStrongBinding, numServices);
}
// TODO(jcivelli): remove this method once crbug.com/693484 has been addressed.
public static int getNumberOfServices(
Context context, String packageName, String numChildServicesManifestKey) {
int numServices = -1;
try {
PackageManager packageManager = context.getPackageManager();
ApplicationInfo appInfo =
packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
if (appInfo.metaData != null) {
numServices = appInfo.metaData.getInt(numChildServicesManifestKey, -1);
}
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException("Could not get application info", e);
}
if (numServices < 0) {
throw new RuntimeException("Illegal meta data value for number of child services");
}
return numServices;
return new ChildConnectionAllocator(launcherHandler, freeSlotCallback, packageName,
serviceClassName, bindToCaller, bindAsExternalService, useStrongBinding,
numServices);
}
/**
......@@ -138,16 +113,18 @@ public class ChildConnectionAllocator {
* instead of being retrieved from the AndroidManifest.xml.
*/
@VisibleForTesting
public static ChildConnectionAllocator createForTest(String packageName,
String serviceClassName, int serviceCount, boolean bindToCaller,
public static ChildConnectionAllocator createForTest(Runnable freeSlotCallback,
String packageName, String serviceClassName, int serviceCount, boolean bindToCaller,
boolean bindAsExternalService, boolean useStrongBinding) {
return new ChildConnectionAllocator(new Handler(), packageName, serviceClassName,
bindToCaller, bindAsExternalService, useStrongBinding, serviceCount);
return new ChildConnectionAllocator(new Handler(), freeSlotCallback, packageName,
serviceClassName, bindToCaller, bindAsExternalService, useStrongBinding,
serviceCount);
}
private ChildConnectionAllocator(Handler launcherHandler, String packageName,
String serviceClassName, boolean bindToCaller, boolean bindAsExternalService,
boolean useStrongBinding, int numChildServices) {
private ChildConnectionAllocator(Handler launcherHandler, Runnable freeSlotCallback,
String packageName, String serviceClassName, boolean bindToCaller,
boolean bindAsExternalService, boolean useStrongBinding, int numChildServices) {
mFreeSlotCallback = freeSlotCallback;
mLauncherHandler = launcherHandler;
assert isRunningOnLauncherThread();
mPackageName = packageName;
......@@ -242,10 +219,6 @@ public class ChildConnectionAllocator {
context, serviceName, mBindToCaller, mBindAsExternalService, serviceBundle);
mChildProcessConnections[slot] = connection;
for (Listener listener : mListeners) {
listener.onConnectionAllocated(this, connection);
}
connection.start(mUseStrongBinding, serviceCallbackWrapper);
Log.d(TAG, "Allocator allocated and bound a connection, name: %s, slot: %d",
mServiceClassName, slot);
......@@ -269,9 +242,20 @@ public class ChildConnectionAllocator {
Log.d(TAG, "Allocator freed a connection, name: %s, slot: %d", mServiceClassName, slot);
}
for (Listener listener : mListeners) {
listener.onConnectionFreed(this, connection);
}
if (mPendingAllocations.isEmpty()) return;
mPendingAllocations.remove().run();
assert mFreeConnectionIndices.isEmpty();
if (!mPendingAllocations.isEmpty() && mFreeSlotCallback != null) mFreeSlotCallback.run();
}
// Can only be called once all slots are full, ie when allocate returns null.
// The callback will be called when a slot becomes free, and should synchronous call
// allocate to take the slot.
public void queueAllocation(Runnable runnable) {
assert mFreeConnectionIndices.isEmpty();
boolean wasEmpty = mPendingAllocations.isEmpty();
mPendingAllocations.add(runnable);
if (wasEmpty && mFreeSlotCallback != null) mFreeSlotCallback.run();
}
public String getPackageName() {
......@@ -291,16 +275,6 @@ public class ChildConnectionAllocator {
return mChildProcessConnections.length;
}
public void addListener(Listener listener) {
assert !mListeners.hasObserver(listener);
mListeners.addObserver(listener);
}
public void removeListener(Listener listener) {
boolean removed = mListeners.removeObserver(listener);
assert removed;
}
public boolean isConnectionFromAllocator(ChildProcessConnection connection) {
for (ChildProcessConnection existingConnection : mChildProcessConnections) {
if (existingConnection == connection) return true;
......
......@@ -200,19 +200,9 @@ public class ChildProcessLauncher {
Log.d(TAG, "Failed to allocate a child connection (no queuing).");
return false;
}
// No connection is available at this time. Add a listener so when one becomes
// available we can create the service.
mConnectionAllocator.addListener(new ChildConnectionAllocator.Listener() {
@Override
public void onConnectionFreed(
ChildConnectionAllocator allocator, ChildProcessConnection connection) {
assert allocator == mConnectionAllocator;
if (!allocator.isFreeConnectionAvailable()) return;
allocator.removeListener(this);
allocateAndSetupConnection(
serviceCallback, setupConnection, queueIfNoFreeConnection);
}
});
mConnectionAllocator.queueAllocation(
() -> allocateAndSetupConnection(
serviceCallback, setupConnection, queueIfNoFreeConnection));
return false;
}
......
......@@ -132,9 +132,9 @@ public class ChildConnectionAllocatorTest {
public void setUp() {
MockitoAnnotations.initMocks(this);
mAllocator = ChildConnectionAllocator.createForTest(TEST_PACKAGE_NAME, "AllocatorTest",
MAX_CONNECTION_NUMBER, true /* bindToCaller */, false /* bindAsExternalService */,
false /* useStrongBinding */);
mAllocator = ChildConnectionAllocator.createForTest(null, TEST_PACKAGE_NAME,
"AllocatorTest", MAX_CONNECTION_NUMBER, true /* bindToCaller */,
false /* bindAsExternalService */, false /* useStrongBinding */);
mAllocator.setConnectionFactoryForTesting(mTestConnectionFactory);
}
......@@ -144,9 +144,6 @@ public class ChildConnectionAllocatorTest {
assertFalse(mAllocator.anyConnectionAllocated());
assertEquals(MAX_CONNECTION_NUMBER, mAllocator.getNumberOfServices());
ChildConnectionAllocator.Listener listener = mock(ChildConnectionAllocator.Listener.class);
mAllocator.addListener(listener);
ChildProcessConnection connection =
mAllocator.allocate(null /* context */, null /* serviceBundle */, mServiceCallback);
assertNotNull(connection);
......@@ -154,7 +151,6 @@ public class ChildConnectionAllocatorTest {
verify(connection, times(1))
.start(eq(false) /* useStrongBinding */,
any(ChildProcessConnection.ServiceCallback.class));
verify(listener, times(1)).onConnectionAllocated(mAllocator, connection);
assertTrue(mAllocator.anyConnectionAllocated());
}
......@@ -177,6 +173,44 @@ public class ChildConnectionAllocatorTest {
null /* context */, null /* serviceBundle */, mServiceCallback));
}
@Test
@Feature({"ProcessManagement"})
public void testQueueAllocation() {
Runnable freeConnectionCallback = mock(Runnable.class);
mAllocator = ChildConnectionAllocator.createForTest(freeConnectionCallback,
TEST_PACKAGE_NAME, "AllocatorTest", 1, true /* bindToCaller */,
false /* bindAsExternalService */, false /* useStrongBinding */);
mAllocator.setConnectionFactoryForTesting(mTestConnectionFactory);
// Occupy all slots.
ChildProcessConnection connection =
mAllocator.allocate(null /* context */, null /* serviceBundle */, mServiceCallback);
assertNotNull(connection);
assertFalse(mAllocator.isFreeConnectionAvailable());
final ChildProcessConnection newConnection[] = new ChildProcessConnection[2];
Runnable allocate1 = () -> {
newConnection[0] = mAllocator.allocate(
null /* context */, null /* serviceBundle */, mServiceCallback);
};
Runnable allocate2 = () -> {
newConnection[1] = mAllocator.allocate(
null /* context */, null /* serviceBundle */, mServiceCallback);
};
mAllocator.queueAllocation(allocate1);
mAllocator.queueAllocation(allocate2);
verify(freeConnectionCallback, times(1)).run();
assertNull(newConnection[0]);
mTestConnectionFactory.simulateServiceProcessDying();
ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
assertNotNull(newConnection[0]);
assertNull(newConnection[1]);
mTestConnectionFactory.simulateServiceProcessDying();
ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
assertNotNull(newConnection[1]);
}
/**
* Tests that the connection is created with the useStrongBinding parameter specified in the
* allocator.
......@@ -185,7 +219,7 @@ public class ChildConnectionAllocatorTest {
@Feature({"ProcessManagement"})
public void testStrongBindingParam() {
for (boolean useStrongBinding : new boolean[] {true, false}) {
ChildConnectionAllocator allocator = ChildConnectionAllocator.createForTest(
ChildConnectionAllocator allocator = ChildConnectionAllocator.createForTest(null,
TEST_PACKAGE_NAME, "AllocatorTest", MAX_CONNECTION_NUMBER,
true /* bindToCaller */, false /* bindAsExternalService */, useStrongBinding);
allocator.setConnectionFactoryForTesting(mTestConnectionFactory);
......@@ -242,12 +276,9 @@ public class ChildConnectionAllocatorTest {
}
/**
* Tests that the allocator clears the connection when it fails to bind/process dies and that
* the listener gets invoked.
* Tests that the allocator clears the connection when it fails to bind/process dies.
*/
private void testFreeConnection(int callbackType) {
ChildConnectionAllocator.Listener listener = mock(ChildConnectionAllocator.Listener.class);
mAllocator.addListener(listener);
ChildProcessConnection connection =
mAllocator.allocate(null /* context */, null /* serviceBundle */, mServiceCallback);
......@@ -274,7 +305,6 @@ public class ChildConnectionAllocatorTest {
}
ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
assertFalse(mAllocator.anyConnectionAllocated());
verify(listener, times(1)).onConnectionFreed(mAllocator, connection);
verify(mServiceCallback, never()).onChildStarted();
verify(mServiceCallback, times(onChildStartFailedExpectedCount))
.onChildStartFailed(connection);
......
......@@ -134,7 +134,7 @@ public final class MultiprocessTestClientLauncher {
if (sConnectionAllocator == null) {
sConnectionAllocator = ChildConnectionAllocator.create(
ContextUtils.getApplicationContext(), sLauncherHandler,
ContextUtils.getApplicationContext(), sLauncherHandler, null,
"org.chromium.native_test", "org.chromium.base.MultiprocessTestClientService",
"org.chromium.native_test.NUM_TEST_CLIENT_SERVICES", false /* bindToCaller */,
false /* bindAsExternalService */, false /* useStrongBinding */);
......
......@@ -160,13 +160,6 @@ void ChildProcessLauncher::ResetRegisteredFilesForTesting() {
ChildProcessLauncherHelper::ResetRegisteredFilesForTesting();
}
#if defined(OS_ANDROID)
// static
size_t ChildProcessLauncher::GetNumberOfRendererSlots() {
return ChildProcessLauncherHelper::GetNumberOfRendererSlots();
}
#endif // OS_ANDROID
ChildProcessLauncher::Client* ChildProcessLauncher::ReplaceClientForTest(
Client* client) {
Client* ret = client_;
......
......@@ -152,11 +152,6 @@ class CONTENT_EXPORT ChildProcessLauncher {
// support multiple shell context creation in unit_tests.
static void ResetRegisteredFilesForTesting();
#if defined(OS_ANDROID)
// Temporary until crbug.com/693484 is fixed.
static size_t GetNumberOfRendererSlots();
#endif // OS_ANDROID
private:
friend class internal::ChildProcessLauncherHelper;
......
......@@ -179,7 +179,6 @@ class ChildProcessLauncherHelper :
void OnChildProcessStarted(JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
jint handle);
static size_t GetNumberOfRendererSlots();
#endif // OS_ANDROID
private:
......
......@@ -241,13 +241,6 @@ void ChildProcessLauncherHelper::OnChildProcessStarted(
PostLaunchOnLauncherThread(std::move(process), launch_result);
}
// static
size_t ChildProcessLauncherHelper::GetNumberOfRendererSlots() {
return static_cast<size_t>(
Java_ChildProcessLauncherHelper_getNumberOfRendererSlots(
AttachCurrentThread()));
}
} // namespace internal
} // namespace content
......@@ -1273,13 +1273,7 @@ size_t RenderProcessHost::GetMaxRendererProcessCount() {
// On Android we don't maintain a limit of renderer process hosts - we are
// happy with keeping a lot of these, as long as the number of live renderer
// processes remains reasonable, and on Android the OS takes care of that.
// TODO(boliu): This is a short term workaround before ChildProcessLauncher
// can actively kill child processes in LRU order. Bug and process is tracked
// in crbug.com/693484. Note this workaround is not perfect and still has
// corner case problems.
static const size_t kNumRendererSlots =
ChildProcessLauncher::GetNumberOfRendererSlots();
return kNumRendererSlots;
return std::numeric_limits<size_t>::max();
#endif
#if defined(OS_CHROMEOS)
// On Chrome OS new renderer processes are very cheap and there's no OS
......
......@@ -29,7 +29,4 @@ interface BindingManager {
/** Called when the embedding application is brought to foreground. */
void onBroughtToForeground();
/** Releases all moderate bindings. */
void releaseAllModerateBindings();
}
......@@ -168,10 +168,4 @@ class BindingManagerImpl implements BindingManager, ComponentCallbacks2 {
assert LauncherThread.runningOnLauncherThread();
removeConnection(connection);
}
@Override
public void releaseAllModerateBindings() {
assert LauncherThread.runningOnLauncherThread();
removeAllConnections();
}
}
......@@ -214,11 +214,10 @@ public class ChildProcessLauncherHelper {
? new GpuProcessCallback()
: null;
ChildProcessLauncherHelper processLauncher = new ChildProcessLauncherHelper(
ChildProcessLauncherHelper helper = new ChildProcessLauncherHelper(
nativePointer, commandLine, filesToBeMapped, sandboxed, binderCallback);
processLauncher.mLauncher.start(
true /* doSetupConnection */, true /* queueIfNoFreeConnection */);
return processLauncher;
helper.start();
return helper;
}
/**
......@@ -327,7 +326,7 @@ public class ChildProcessLauncherHelper {
if (!sandboxed) {
if (sPrivilegedChildConnectionAllocator == null) {
sPrivilegedChildConnectionAllocator =
ChildConnectionAllocator.create(context, LauncherThread.getHandler(),
ChildConnectionAllocator.create(context, LauncherThread.getHandler(), null,
packageName, PRIVILEGED_SERVICES_NAME, NUM_PRIVILEGED_SERVICES_KEY,
bindToCaller, bindAsExternalService, true /* useStrongBinding */);
}
......@@ -339,20 +338,28 @@ public class ChildProcessLauncherHelper {
"Create a new ChildConnectionAllocator with package name = %s,"
+ " sandboxed = true",
packageName);
Runnable freeSlotRunnable = () -> {
ChildProcessConnection lowestRank =
sSandboxedChildConnectionRanking.getLowestRankedConnection();
if (lowestRank != null) {
lowestRank.kill();
}
};
ChildConnectionAllocator connectionAllocator = null;
if (sSandboxedServicesCountForTesting != -1) {
// Testing case where allocator settings are overriden.
String serviceName = !TextUtils.isEmpty(sSandboxedServicesNameForTesting)
? sSandboxedServicesNameForTesting
: SandboxedProcessService.class.getName();
connectionAllocator = ChildConnectionAllocator.createForTest(packageName,
serviceName, sSandboxedServicesCountForTesting, bindToCaller,
connectionAllocator = ChildConnectionAllocator.createForTest(freeSlotRunnable,
packageName, serviceName, sSandboxedServicesCountForTesting, bindToCaller,
bindAsExternalService, false /* useStrongBinding */);
} else {
connectionAllocator =
ChildConnectionAllocator.create(context, LauncherThread.getHandler(),
packageName, SANDBOXED_SERVICES_NAME, NUM_SANDBOXED_SERVICES_KEY,
bindToCaller, bindAsExternalService, false /* useStrongBinding */);
connectionAllocator = ChildConnectionAllocator.create(context,
LauncherThread.getHandler(), freeSlotRunnable, packageName,
SANDBOXED_SERVICES_NAME, NUM_SANDBOXED_SERVICES_KEY, bindToCaller,
bindAsExternalService, false /* useStrongBinding */);
}
if (sSandboxedServiceFactoryForTesting != null) {
connectionAllocator.setConnectionFactoryForTesting(
......@@ -361,25 +368,6 @@ public class ChildProcessLauncherHelper {
sSandboxedChildConnectionAllocator = connectionAllocator;
sSandboxedChildConnectionRanking = new ChildProcessRanking(
sSandboxedChildConnectionAllocator.getNumberOfServices());
final ChildConnectionAllocator finalConnectionAllocator = connectionAllocator;
connectionAllocator.addListener(new ChildConnectionAllocator.Listener() {
@Override
public void onConnectionAllocated(
ChildConnectionAllocator allocator, ChildProcessConnection connection) {
assert connection != null;
assert allocator == finalConnectionAllocator;
if (!allocator.isFreeConnectionAvailable()) {
// Proactively releases all the moderate bindings once all the sandboxed
// services are allocated, which will be very likely to have some of them
// killed by OOM killer.
BindingManager manager = getBindingManager();
if (manager != null) {
manager.releaseAllModerateBindings();
}
}
}
});
}
return sSandboxedChildConnectionAllocator;
}
......@@ -407,6 +395,10 @@ public class ChildProcessLauncherHelper {
}
}
private void start() {
mLauncher.start(true /* doSetupConnection */, true /* queueIfNoFreeConnection */);
}
/**
* @return The type of process as specified in the command line at
* {@link ContentSwitches#SWITCH_PROCESS_TYPE}.
......@@ -548,25 +540,6 @@ public class ChildProcessLauncherHelper {
}
}
@CalledByNative
private static int getNumberOfRendererSlots() {
assert ThreadUtils.runningOnUiThread();
if (sSandboxedServicesCountForTesting != -1) {
return sSandboxedServicesCountForTesting;
}
final Context context = ContextUtils.getApplicationContext();
final String packageName = ChildProcessCreationParams.getPackageNameForService();
try {
return ChildConnectionAllocator.getNumberOfServices(
context, packageName, NUM_SANDBOXED_SERVICES_KEY);
} catch (RuntimeException e) {
// Unittest packages do not declare services. Some tests require a realistic number
// to test child process policies, so pick a high-ish number here.
return 65535;
}
}
// Can be called on a number of threads, including launcher, and binder.
private static native void nativeOnChildProcessStarted(
long nativeChildProcessLauncherHelper, int pid);
......
......@@ -137,4 +137,36 @@ public class ChildProcessLauncherIntegrationTest {
}
});
}
@Test
@MediumTest
public void testIntentionalKillToFreeServiceSlot() throws Throwable {
final TestChildProcessConnectionFactory factory = new TestChildProcessConnectionFactory();
final List<TestChildProcessConnection> connections = factory.getConnections();
ChildProcessLauncherHelper.setSandboxServicesSettingsForTesting(
factory, 1, null /* use default service name */);
// Doing a cross-domain navigation would need to kill the first process in order to create
// the second process.
ContentShellActivity activity = mActivityTestRule.launchContentShellWithUrlSync(
"content/test/data/android/vsync.html");
NavigationController navigationController =
mActivityTestRule.getWebContents().getNavigationController();
TestCallbackHelperContainer testCallbackHelperContainer =
new TestCallbackHelperContainer(activity.getActiveWebContents());
mActivityTestRule.loadUrl(navigationController, testCallbackHelperContainer,
new LoadUrlParams(UrlUtils.getIsolatedTestFileUrl(
"content/test/data/android/geolocation.html")));
mActivityTestRule.loadUrl(
navigationController, testCallbackHelperContainer, new LoadUrlParams("data:,foo"));
ChildProcessLauncherTestUtils.runOnLauncherThreadBlocking(new Runnable() {
@Override
public void run() {
Assert.assertEquals(2, connections.size());
Assert.assertTrue(connections.get(0).isKilledByUs());
}
});
}
}
......@@ -107,9 +107,9 @@ public class ChildProcessLauncherTest {
public ChildConnectionAllocator call() {
Context context = InstrumentationRegistry.getTargetContext();
return ChildConnectionAllocator.create(context, LauncherThread.getHandler(),
SERVICE_PACKAGE_NAME, SERVICE_NAME, SERVICE_COUNT_META_DATA_KEY,
false /* bindToCaller */, false /* bindAsExternalService */,
false /* useStrongBinding */);
null, SERVICE_PACKAGE_NAME, SERVICE_NAME,
SERVICE_COUNT_META_DATA_KEY, false /* bindToCaller */,
false /* bindAsExternalService */, false /* useStrongBinding */);
}
});
}
......@@ -356,7 +356,7 @@ public class ChildProcessLauncherTest {
new Callable<ChildConnectionAllocator>() {
@Override
public ChildConnectionAllocator call() {
return ChildConnectionAllocator.createForTest(
return ChildConnectionAllocator.createForTest(null,
"org.chromium.wrong_package", "WrongService",
2 /* serviceCount */, false /* bindToCaller */,
false /* bindAsExternalService */,
......
......@@ -188,33 +188,6 @@ public class BindingManagerImplTest {
}
}
/**
* Verifies that BindingManager.releaseAllModerateBindings() drops all the moderate bindings.
*/
@Test
@Feature({"ProcessManagement"})
public void testModerateBindingDropOnReleaseAllModerateBindings() {
final BindingManagerImpl manager = mManager;
ChildProcessConnection[] connections = new ChildProcessConnection[4];
for (int i = 0; i < connections.length; i++) {
connections[i] = createTestChildProcessConnection(i + 1 /* pid */, manager);
}
// Verify that each connection has a moderate binding after binding and releasing a strong
// binding.
for (ChildProcessConnection connection : connections) {
Assert.assertTrue(connection.isModerateBindingBound());
}
// Call BindingManager.releaseAllModerateBindings() and verify that all the moderate
// bindings drop.
manager.releaseAllModerateBindings();
for (ChildProcessConnection connection : connections) {
Assert.assertFalse(connection.isModerateBindingBound());
}
}
/*
* Test that Chrome is sent to the background, that the initially added moderate bindings are
* removed and are not re-added when Chrome is brought back to the foreground.
......
......@@ -40,7 +40,7 @@ public class SpareChildConnectionTest {
// A connection allocator not used to create connections.
private final ChildConnectionAllocator mWrongConnectionAllocator =
ChildConnectionAllocator.createForTest("org.chromium.test", "TestServiceName",
ChildConnectionAllocator.createForTest(null, "org.chromium.test", "TestServiceName",
3 /* serviceCount */, false /* bindToCaller */,
false /* bindAsExternalService */, false /* useStrongBinding */);
......@@ -87,7 +87,7 @@ public class SpareChildConnectionTest {
LauncherThread.setCurrentThreadAsLauncherThread();
mConnectionAllocator =
ChildConnectionAllocator.createForTest("org.chromium.test.spare_connection",
ChildConnectionAllocator.createForTest(null, "org.chromium.test.spare_connection",
"TestServiceName", 5 /* serviceCount */, false /* bindToCaller */,
false /* bindAsExternalService */, false /* useStrongBinding */);
mConnectionAllocator.setConnectionFactoryForTesting(mTestConnectionFactory);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment