Commit 9cf15708 authored by Jay Civelli's avatar Jay Civelli Committed by Commit Bot

Splitting ChildProcessLauncherHelper before move to base.

Extracting the launching code that will go to base from
ChildProcessLauncherHelper (CPLH) to ChildProcessLauncher (CPL).
CPLH now creates a CPL that takes care of creating the connection and
setting it up and delegates back to the CPLH for content specific behavior.

Adding tests to validate the CPL API and moving some existing tests to
use CPL instead of CPLH. The new tests use a new test service
(TestChildProcessService) that echoes back the delegate calls called
on it.  
Also removing the CPLH tests validating strong binding connections as
this is already tested in ChildConnectionAllocatorTest.

Bug: 702316
Change-Id: Ic2bda3f621530616cacc60e22007ca36464a0159
Reviewed-on: https://chromium-review.googlesource.com/557890
Commit-Queue: Jay Civelli <jcivelli@chromium.org>
Reviewed-by: default avatarBo Liu <boliu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#485140}
parent bedfe36d
......@@ -114,6 +114,7 @@ android_library("content_java") {
"java/src/org/chromium/content/browser/BrowserStartupController.java",
"java/src/org/chromium/content/browser/ChildConnectionAllocator.java",
"java/src/org/chromium/content/browser/ChildProcessConnection.java",
"java/src/org/chromium/content/browser/ChildProcessLauncher.java",
"java/src/org/chromium/content/browser/ChildProcessLauncherHelper.java",
"java/src/org/chromium/content/browser/ContentChildProcessConstants.java",
"java/src/org/chromium/content/browser/ContentClassFactory.java",
......@@ -373,6 +374,9 @@ group("jni") {
android_library("content_javatests") {
testonly = true
srcjar_deps = [ "//content/shell/android:content_javatests_aidl" ]
deps = [
":content_java",
"//base:base_java",
......@@ -396,6 +400,7 @@ android_library("content_javatests") {
"//net/android:net_java_test_support",
"//third_party/android_support_test_runner:rules_java",
"//third_party/android_support_test_runner:runner_java",
"//third_party/jsr-305:jsr_305_javalib",
"//third_party/junit",
"//ui/android:ui_java",
"//ui/gfx/geometry/mojo:mojo_java",
......@@ -405,6 +410,7 @@ android_library("content_javatests") {
"javatests/src/org/chromium/content/browser/BrowserStartupControllerTest.java",
"javatests/src/org/chromium/content/browser/ChildProcessLauncherIntegrationTest.java",
"javatests/src/org/chromium/content/browser/ChildProcessLauncherTest.java",
"javatests/src/org/chromium/content/browser/ChildProcessLauncherHelperTest.java",
"javatests/src/org/chromium/content/browser/ClipboardTest.java",
"javatests/src/org/chromium/content/browser/ContentCommandLineTest.java",
"javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java",
......
......@@ -27,14 +27,14 @@ public class ChildConnectionAllocator {
private static final String TAG = "ChildConnAllocator";
/** Listener that clients can use to get notified when connections get allocated/freed. */
public interface Listener {
public abstract static class Listener {
/** Called when a connection has been allocated, before it gets bound. */
void onConnectionAllocated(
ChildConnectionAllocator allocator, ChildProcessConnection connection);
public void onConnectionAllocated(
ChildConnectionAllocator allocator, ChildProcessConnection connection) {}
/** Called when a connection has been freed. */
void onConnectionFreed(
ChildConnectionAllocator allocator, ChildProcessConnection connection);
public void onConnectionFreed(
ChildConnectionAllocator allocator, ChildProcessConnection connection) {}
}
/** Factory interface. Used by tests to specialize created connections. */
......@@ -103,8 +103,7 @@ public class ChildConnectionAllocator {
// Check that the service exists.
try {
// PackageManager#getServiceInfo() throws an exception if the service does not
// exist.
// PackageManager#getServiceInfo() throws an exception if the service does not exist.
packageManager.getServiceInfo(
new ComponentName(packageName, serviceClassName + "0"), 0);
} catch (PackageManager.NameNotFoundException e) {
......
......@@ -84,8 +84,7 @@ public class SpareChildConnection {
public ChildProcessConnection getConnection(ChildConnectionAllocator allocator,
@NonNull final ChildProcessConnection.ServiceCallback serviceCallback) {
assert LauncherThread.runningOnLauncherThread();
if (mConnection == null || allocator != mConnectionAllocator
|| mConnectionServiceCallback != null) {
if (isEmpty() || !isForAllocator(allocator) || mConnectionServiceCallback != null) {
return null;
}
......@@ -117,6 +116,11 @@ public class SpareChildConnection {
return mConnection == null || mConnectionServiceCallback != null;
}
/** Returns true if this spare connection uses {@param allocator}. */
public boolean isForAllocator(ChildConnectionAllocator allocator) {
return mConnectionAllocator == allocator;
}
private void clearConnection() {
assert LauncherThread.runningOnLauncherThread();
mConnection = null;
......
......@@ -99,6 +99,9 @@ android_resources("content_shell_apk_resources") {
android_library("content_shell_apk_java") {
testonly = true
srcjar_deps = [ ":content_javatests_aidl" ]
deps = [
":content_shell_apk_resources",
":content_shell_java",
......@@ -107,6 +110,7 @@ android_library("content_shell_apk_java") {
"//content/public/android:content_java",
"//media/capture/video/android:capture_java",
"//net/android:net_java",
"//third_party/jsr-305:jsr_305_javalib",
"//ui/android:ui_java",
]
......@@ -118,6 +122,16 @@ android_library("content_shell_apk_java") {
"shell_apk/src/org/chromium/content_shell_apk/ChildProcessLauncherTestUtils.java",
"shell_apk/src/org/chromium/content_shell_apk/ContentShellActivity.java",
"shell_apk/src/org/chromium/content_shell_apk/ContentShellApplication.java",
"shell_apk/src/org/chromium/content_shell_apk/TestChildProcessService.java",
"shell_apk/src/org/chromium/content_shell_apk/TestChildProcessService0.java",
"shell_apk/src/org/chromium/content_shell_apk/TestChildProcessService1.java",
]
}
android_aidl("content_javatests_aidl") {
import_include = [ "shell_apk/src" ]
sources = [
"shell_apk/src/org/chromium/content_shell_apk/IChildProcessTest.aidl",
]
}
......
......@@ -67,5 +67,20 @@
<service android:name="org.chromium.content_shell_apk.ChildProcessLauncherTestHelperService"
android:process=":ChildProcessLauncherHelper" />
<!-- The following entries are for ChildProcessLauncherTest. They should eventually be moved
to base. -->
{% set num_test_services = 2 %}
<meta-data android:name="org.chromium.content.browser.NUM_TEST_SERVICES"
android:value="{{ num_test_services }}"/>
<meta-data android:name="org.chromium.content.browser.TEST_SERVICES_NAME"
android:value="org.chromium.content_shell_apk.TestChildProcessService"/>
{% for i in range(num_test_services) %}
<service android:name="org.chromium.content_shell_apk.TestChildProcessService{{ i }}"
android:process=":test_child_service_process{{ i }}"
android:isolatedProcess="true"
android:exported="false" />
{% endfor %}
</application>
</manifest>
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.content_shell_apk;
import android.os.Bundle;
/**
* Interface provided to the TestChildProcessService. Used to echo back the calls made on the
* ChildProcessServiceDelegate to the test process.
*/
interface IChildProcessTest {
// Called by the service when onConnectionSetup is received. Echos back the parameters received
// so far.
oneway void onConnectionSetup(boolean serviceCreatedCalled, in Bundle serviceBundle, in Bundle connectionBundle);
oneway void onLoadNativeLibrary(boolean loadedSuccessfully);
oneway void onBeforeMain(in String[] commandLine);
oneway void onRunMain();
oneway void onDestroy();
}
per-file *.aidl=set noparent
per-file *.aidl=file://ipc/SECURITY_OWNERS
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.content_shell_apk;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.util.SparseArray;
import org.chromium.base.CommandLine;
import org.chromium.base.Log;
import org.chromium.base.library_loader.LibraryLoader;
import org.chromium.base.library_loader.LibraryProcessType;
import org.chromium.base.library_loader.ProcessInitException;
import org.chromium.base.process_launcher.ChildProcessService;
import org.chromium.base.process_launcher.ChildProcessServiceDelegate;
import javax.annotation.concurrent.GuardedBy;
/**
* Child service started by ChildProcessLauncherTest.
*/
public class TestChildProcessService extends ChildProcessService {
private static final String TAG = "TestProcessService";
private static final long MAIN_BLOCKING_DURATION_MS = 5000;
private static class TestChildProcessServiceDelegate implements ChildProcessServiceDelegate {
private final Object mConnectionSetupLock = new Object();
@GuardedBy("mConnectionSetupLock")
private boolean mConnectionSetup;
private boolean mServiceCreated;
private Bundle mServiceBundle;
private String[] mCommandLine;
private IChildProcessTest mIChildProcessTest;
@Override
public void onServiceCreated() {
mServiceCreated = true;
}
@Override
public void onServiceBound(Intent intent) {
mServiceBundle = intent.getExtras();
}
@Override
public void onConnectionSetup(Bundle connectionBundle, IBinder callback) {
if (callback != null) {
mIChildProcessTest = IChildProcessTest.Stub.asInterface(callback);
}
if (mIChildProcessTest != null) {
try {
mIChildProcessTest.onConnectionSetup(
mServiceCreated, mServiceBundle, connectionBundle);
} catch (RemoteException re) {
Log.e(TAG, "Failed to call IChildProcessTest.onConnectionSetup.", re);
}
}
synchronized (mConnectionSetupLock) {
mConnectionSetup = true;
mConnectionSetupLock.notifyAll();
}
}
@Override
public void onDestroy() {
if (mIChildProcessTest == null) return;
try {
mIChildProcessTest.onDestroy();
} catch (RemoteException re) {
Log.e(TAG, "Failed to call IChildProcessTest.onDestroy.", re);
}
}
@Override
public boolean loadNativeLibrary(Context hostContext) {
// Store the command line before loading the library to avoid an assert in CommandLine.
mCommandLine = CommandLine.getJavaSwitchesOrNull();
LibraryLoader libraryLoader = null;
boolean isLoaded = false;
try {
libraryLoader = LibraryLoader.get(LibraryProcessType.PROCESS_CHILD);
libraryLoader.loadNow();
libraryLoader.ensureInitialized();
isLoaded = true;
} catch (ProcessInitException e) {
Log.e(TAG, "Failed to load native library.", e);
}
// Loading the library happen on the main thread and onConnectionSetup is called from
// the client. Wait for onConnectionSetup so mIChildProcessTest is set.
synchronized (mConnectionSetupLock) {
while (!mConnectionSetup) {
try {
mConnectionSetupLock.wait();
} catch (InterruptedException e) {
// Ignore.
}
}
}
if (mIChildProcessTest != null) {
try {
mIChildProcessTest.onLoadNativeLibrary(isLoaded);
} catch (RemoteException re) {
Log.e(TAG, "Failed to call IChildProcessTest.onLoadNativeLibrary.", re);
}
}
return true;
}
@Override
public SparseArray<String> getFileDescriptorsIdsToKeys() {
return null;
}
@Override
public void onBeforeMain() {
if (mIChildProcessTest == null) return;
try {
mIChildProcessTest.onBeforeMain(mCommandLine);
} catch (RemoteException re) {
Log.e(TAG, "Failed to call IChildProcessTest.onBeforeMain.", re);
}
}
@Override
public void runMain() {
if (mIChildProcessTest != null) {
try {
mIChildProcessTest.onRunMain();
} catch (RemoteException re) {
Log.e(TAG, "Failed to call IChildProcessTest.onRunMain.", re);
}
}
// Run a message loop to keep the service from exiting.
Looper.prepare();
Looper.loop();
}
};
public TestChildProcessService() {
super(new TestChildProcessServiceDelegate());
}
}
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.content_shell_apk;
/** One of the TestChildProcessService defined in the AndroidManifest.xml. */
public class TestChildProcessService0 extends TestChildProcessService {}
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.content_shell_apk;
/** One of the TestChildProcessService defined in the AndroidManifest.xml. */
public class TestChildProcessService1 extends TestChildProcessService {}
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