Skip to content

Commit

Permalink
Implement CreateInstanceForHandle.
Browse files Browse the repository at this point in the history
A method on ApplicationManager that allows a process that launches another process to register the launched process with the ApplicationManager. In the Shell, this creates an ApplicationInstance, OutOfProcessNativeRunner and ChildProcessHost. This change makes it possible for a ChildProcessHost to be created for an existing process rather than one it must launch.

I think in a future CL I should refactor this class more to make the difference between the type the shell starts and the type someone else starts a bit clearer. Currently it just triggers on whether or not app_path_ is empty which I think is a bit brittle.

Adds an apptest for this that:
- exposes a service from the apptest
- apptest starts a native exe ("driver") via the shell
- native exe ("driver") starts another native exe ("target") via base::LaunchProcess
- driver creates platform channel and passes one side to target and the other side to the shell via CreateInstanceForHandle
- target connects to service exposed by the apptest.

R=jam@chromium.org
http://crbug.com/551253

Review URL: https://codereview.chromium.org/1434083002

Cr-Commit-Position: refs/heads/master@{#359502}
  • Loading branch information
ben authored and Commit bot committed Nov 13, 2015
1 parent 6592c08 commit 0cfab1b
Show file tree
Hide file tree
Showing 23 changed files with 611 additions and 90 deletions.
1 change: 1 addition & 0 deletions mojo/runner/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ source_set("init") {
deps = [
"//mojo/runner/host:switches",
"//base",
"//base:base_static",
"//base:i18n",
]
}
Expand Down
27 changes: 21 additions & 6 deletions mojo/runner/child/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,26 @@ mojom("interfaces") {
import_dirs = [ "//mojo/services" ]
}

source_set("test_native_main") {
sources = [
"test_native_main.cc",
"test_native_main.h",
]

public_deps = [
"//mojo/runner:init",
]

deps = [
"//base",
"//mojo/application/public/cpp",
"//mojo/gles2",
"//mojo/message_pump",
"//mojo/runner/child:lib",
"//third_party/mojo/src/mojo/edk/system",
]
}

mojom("apptest_interfaces") {
sources = [
"test_native_service.mojom",
Expand Down Expand Up @@ -89,14 +109,9 @@ executable("native_target") {
deps = [
":apptest_interfaces",
":lib",
":test_native_main",
"//base",
"//base:base_static",
"//mojo/application/public/cpp",
"//mojo/application/public/interfaces",
"//mojo/common:common_base",
"//mojo/gles2",
"//mojo/message_pump",
"//mojo/runner:init",
"//third_party/mojo/src/mojo/edk/system",
]
}
66 changes: 3 additions & 63 deletions mojo/runner/child/native_apptest_target.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,14 @@

#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/debug/stack_trace.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/process/launch.h"
#include "base/threading/thread.h"
#include "build/build_config.h"
#include "mojo/application/public/cpp/application_connection.h"
#include "mojo/application/public/cpp/application_delegate.h"
#include "mojo/application/public/cpp/application_impl.h"
#include "mojo/application/public/cpp/interface_factory.h"
#include "mojo/application/public/interfaces/application.mojom.h"
#include "mojo/common/weak_binding_set.h"
#include "mojo/message_pump/message_pump_mojo.h"
#include "mojo/runner/child/runner_connection.h"
#include "mojo/runner/child/test_native_main.h"
#include "mojo/runner/child/test_native_service.mojom.h"
#include "mojo/runner/init.h"
#include "third_party/mojo/src/mojo/edk/embedder/embedder.h"
#include "third_party/mojo/src/mojo/edk/embedder/process_delegate.h"

#if defined(OS_WIN)
#include <windows.h>
#endif

namespace {

Expand Down Expand Up @@ -63,60 +49,14 @@ class TargetApplicationDelegate
DISALLOW_COPY_AND_ASSIGN(TargetApplicationDelegate);
};

class ProcessDelegate : public mojo::embedder::ProcessDelegate {
public:
ProcessDelegate() {}
~ProcessDelegate() override {}

private:
void OnShutdownComplete() override {}

DISALLOW_COPY_AND_ASSIGN(ProcessDelegate);
};

} // namespace

int main(int argc, char** argv) {
base::AtExitManager at_exit;
base::CommandLine::Init(argc, argv);

mojo::runner::InitializeLogging();
mojo::runner::WaitForDebuggerIfNecessary();

#if !defined(OFFICIAL_BUILD)
base::debug::EnableInProcessStackDumping();
#if defined(OS_WIN)
base::RouteStdioToConsole(false);
#endif
#endif

{
mojo::embedder::Init();

ProcessDelegate process_delegate;
base::Thread io_thread("io_thread");
base::Thread::Options io_thread_options(base::MessageLoop::TYPE_IO, 0);
CHECK(io_thread.StartWithOptions(io_thread_options));

mojo::embedder::InitIPCSupport(
mojo::embedder::ProcessType::NONE, &process_delegate,
io_thread.task_runner().get(), mojo::embedder::ScopedPlatformHandle());

mojo::InterfaceRequest<mojo::Application> application_request;
scoped_ptr<mojo::runner::RunnerConnection> connection(
mojo::runner::RunnerConnection::ConnectToRunner(&application_request));

TargetApplicationDelegate delegate;
{
base::MessageLoop loop(mojo::common::MessagePumpMojo::Create());
mojo::ApplicationImpl impl(&delegate, application_request.Pass());
loop.Run();
}

connection.reset();

mojo::embedder::ShutdownIPCSupport();
}

return 0;
TargetApplicationDelegate delegate;
return mojo::runner::TestNativeMain(&delegate);
}
79 changes: 79 additions & 0 deletions mojo/runner/child/test_native_main.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright 2015 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.

#include "mojo/runner/child/test_native_main.h"

#include "base/debug/stack_trace.h"
#include "base/message_loop/message_loop.h"
#include "base/process/launch.h"
#include "base/threading/thread.h"
#include "build/build_config.h"
#include "mojo/application/public/cpp/application_delegate.h"
#include "mojo/application/public/cpp/application_impl.h"
#include "mojo/message_pump/message_pump_mojo.h"
#include "mojo/runner/child/runner_connection.h"
#include "mojo/runner/init.h"
#include "third_party/mojo/src/mojo/edk/embedder/embedder.h"
#include "third_party/mojo/src/mojo/edk/embedder/process_delegate.h"

namespace mojo {
namespace runner {
namespace {

class ProcessDelegate : public mojo::embedder::ProcessDelegate {
public:
ProcessDelegate() {}
~ProcessDelegate() override {}

private:
void OnShutdownComplete() override {}

DISALLOW_COPY_AND_ASSIGN(ProcessDelegate);
};

} // namespace

int TestNativeMain(mojo::ApplicationDelegate* application_delegate) {
mojo::runner::WaitForDebuggerIfNecessary();

#if !defined(OFFICIAL_BUILD)
base::debug::EnableInProcessStackDumping();
#if defined(OS_WIN)
base::RouteStdioToConsole(false);
#endif
#endif

{
mojo::embedder::Init();

ProcessDelegate process_delegate;
base::Thread io_thread("io_thread");
base::Thread::Options io_thread_options(base::MessageLoop::TYPE_IO, 0);
CHECK(io_thread.StartWithOptions(io_thread_options));

mojo::embedder::InitIPCSupport(
mojo::embedder::ProcessType::NONE, &process_delegate,
io_thread.task_runner().get(), mojo::embedder::ScopedPlatformHandle());

mojo::InterfaceRequest<mojo::Application> application_request;
scoped_ptr<mojo::runner::RunnerConnection> connection(
mojo::runner::RunnerConnection::ConnectToRunner(&application_request));

base::MessageLoop loop(mojo::common::MessagePumpMojo::Create());
{
mojo::ApplicationImpl impl(application_delegate,
application_request.Pass());
loop.Run();
}

connection.reset();

mojo::embedder::ShutdownIPCSupport();
}

return 0;
}

} // namespace runner
} // namespace mojo
17 changes: 17 additions & 0 deletions mojo/runner/child/test_native_main.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2015 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.

#ifndef MOJO_RUNNER_CHILD_TEST_NATIVE_MAIN_H_
#define MOJO_RUNNER_CHILD_TEST_NATIVE_MAIN_H_

namespace mojo {
class ApplicationDelegate;
namespace runner {

int TestNativeMain(mojo::ApplicationDelegate* application_delegate);

} // namespace runner
} // namespace mojo

#endif // MOJO_RUNNER_CHILD_TEST_NATIVE_MAIN_H_
14 changes: 13 additions & 1 deletion mojo/runner/host/child_process_host.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,20 @@ ChildProcessHost::ChildProcessHost(base::TaskRunner* launch_process_runner,
CHECK(platform_channel_.is_valid());
}

ChildProcessHost::ChildProcessHost(ScopedHandle channel)
: launch_process_runner_(nullptr),
start_sandboxed_(false),
channel_info_(nullptr),
start_child_process_event_(false, false),
weak_factory_(this) {
CHECK(channel.is_valid());
ScopedMessagePipeHandle handle(MessagePipeHandle(channel.release().value()));
controller_.Bind(InterfacePtrInfo<ChildController>(handle.Pass(), 0u));
}

ChildProcessHost::~ChildProcessHost() {
CHECK(!controller_) << "Destroying ChildProcessHost before calling Join";
if (!app_path_.empty())
CHECK(!controller_) << "Destroying ChildProcessHost before calling Join";
}

void ChildProcessHost::Start() {
Expand Down
3 changes: 3 additions & 0 deletions mojo/runner/host/child_process_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ class ChildProcessHost {
ChildProcessHost(base::TaskRunner* launch_process_runner,
bool start_sandboxed,
const base::FilePath& app_path);
// Allows a ChildProcessHost to be instantiated for an existing channel
// created by someone else (e.g. an app that launched its own process).
explicit ChildProcessHost(ScopedHandle channel);
virtual ~ChildProcessHost();

// |Start()|s the child process; calls |DidStart()| (on the thread on which
Expand Down
6 changes: 6 additions & 0 deletions mojo/runner/host/in_process_native_runner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ void InProcessNativeRunner::Start(
thread_->Start();
}

void InProcessNativeRunner::InitHost(
ScopedHandle channel,
InterfaceRequest<Application> application_request) {
NOTREACHED(); // Can't host another process in this runner.
}

void InProcessNativeRunner::Run() {
DVLOG(2) << "Loading/running Mojo app in process from library: "
<< app_path_.value()
Expand Down
4 changes: 3 additions & 1 deletion mojo/runner/host/in_process_native_runner.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@ class InProcessNativeRunner : public shell::NativeRunner,
InProcessNativeRunner();
~InProcessNativeRunner() override;

// |NativeRunner| method:
// NativeRunner:
void Start(const base::FilePath& app_path,
bool start_sandboxed,
InterfaceRequest<Application> application_request,
const base::Closure& app_completed_callback) override;
void InitHost(ScopedHandle channel,
InterfaceRequest<Application> application_request) override;

private:
// |base::DelegateSimpleThread::Delegate| method:
Expand Down
12 changes: 11 additions & 1 deletion mojo/runner/host/out_of_process_native_runner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ OutOfProcessNativeRunner::OutOfProcessNativeRunner(
: launch_process_runner_(launch_process_runner) {}

OutOfProcessNativeRunner::~OutOfProcessNativeRunner() {
if (child_process_host_)
if (child_process_host_ && !app_path_.empty())
child_process_host_->Join();
}

Expand All @@ -44,6 +44,16 @@ void OutOfProcessNativeRunner::Start(
base::Unretained(this)));
}

void OutOfProcessNativeRunner::InitHost(
ScopedHandle channel,
InterfaceRequest<Application> application_request) {
child_process_host_.reset(new ChildProcessHost(channel.Pass()));
child_process_host_->StartApp(
application_request.Pass(),
base::Bind(&OutOfProcessNativeRunner::AppCompleted,
base::Unretained(this)));
}

void OutOfProcessNativeRunner::AppCompleted(int32_t result) {
DVLOG(2) << "OutOfProcessNativeRunner::AppCompleted(" << result << ")";

Expand Down
4 changes: 3 additions & 1 deletion mojo/runner/host/out_of_process_native_runner.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@ class OutOfProcessNativeRunner : public shell::NativeRunner {
explicit OutOfProcessNativeRunner(base::TaskRunner* launch_process_runner);
~OutOfProcessNativeRunner() override;

// |NativeRunner| method:
// NativeRunner:
void Start(const base::FilePath& app_path,
bool start_sandboxed,
InterfaceRequest<Application> application_request,
const base::Closure& app_completed_callback) override;
void InitHost(ScopedHandle channel,
InterfaceRequest<Application> application_request) override;

private:
// |ChildController::StartApp()| callback:
Expand Down
Loading

0 comments on commit 0cfab1b

Please sign in to comment.