Index: mojo/shell/runner/host/child_process_host.cc |
diff --git a/mojo/shell/runner/host/child_process_host.cc b/mojo/shell/runner/host/child_process_host.cc |
index 60a9947778da8f95312a5ec7ba7d2d0131c77d1d..1083128a8a6dd501b982e4b498fe84c8fdc0ce6a 100644 |
--- a/mojo/shell/runner/host/child_process_host.cc |
+++ b/mojo/shell/runner/host/child_process_host.cc |
@@ -22,6 +22,7 @@ |
#include "mojo/public/cpp/bindings/interface_ptr_info.h" |
#include "mojo/public/cpp/system/core.h" |
#include "mojo/shell/native_runner_delegate.h" |
+#include "mojo/shell/runner/common/client_util.h" |
#include "mojo/shell/runner/common/switches.h" |
#if defined(OS_LINUX) && !defined(OS_ANDROID) |
@@ -47,47 +48,64 @@ ChildProcessHost::ChildProcessHost(base::TaskRunner* launch_process_runner, |
app_path_(app_path), |
start_child_process_event_(false, false), |
weak_factory_(this) { |
- node_channel_.reset(new edk::PlatformChannelPair); |
- primordial_pipe_token_ = edk::GenerateRandomToken(); |
- factory_.Bind(InterfacePtrInfo<mojom::ShellClientFactory>( |
- edk::CreateParentMessagePipe(primordial_pipe_token_), 0u)); |
} |
ChildProcessHost::~ChildProcessHost() { |
- if (!app_path_.empty()) |
- CHECK(!factory_) << "Destroying ChildProcessHost before calling Join"; |
+ if (!app_path_.empty()) { |
+ CHECK(!mojo_ipc_channel_) |
+ << "Destroying ChildProcessHost before calling Join"; |
+ } |
} |
-void ChildProcessHost::Start(mojom::ShellClientRequest request, |
- const String& name, |
- const ProcessReadyCallback& callback, |
- const base::Closure& quit_closure) { |
+mojom::ShellClientPtr ChildProcessHost::Start( |
+ const String& name, |
+ const ProcessReadyCallback& callback, |
+ const base::Closure& quit_closure) { |
DCHECK(!child_process_.IsValid()); |
- // Request is invalid in child_process_host_unittest. |
- if (request.is_pending()) { |
- factory_->CreateShellClient(std::move(request), name); |
- factory_.set_connection_error_handler(quit_closure); |
+ |
+ const base::CommandLine* parent_command_line = |
+ base::CommandLine::ForCurrentProcess(); |
+ base::FilePath target_path = parent_command_line->GetProgram(); |
+ // |app_path_| can be empty in tests. |
+ if (!app_path_.MatchesExtension(FILE_PATH_LITERAL(".mojo")) && |
+ !app_path_.empty()) { |
+ target_path = app_path_; |
} |
+ |
+ scoped_ptr<base::CommandLine> child_command_line( |
+ new base::CommandLine(target_path)); |
+ |
+ child_command_line->AppendArguments(*parent_command_line, false); |
+ |
+ if (target_path != app_path_) |
+ child_command_line->AppendSwitchPath(switches::kChildProcess, app_path_); |
+ |
+ if (start_sandboxed_) |
+ child_command_line->AppendSwitch(switches::kEnableSandbox); |
+ |
+ mojo_ipc_channel_.reset(new edk::PlatformChannelPair); |
+ mojo_ipc_channel_->PrepareToPassClientHandleToChildProcess( |
+ child_command_line.get(), &handle_passing_info_); |
+ |
+ mojom::ShellClientPtr client = |
+ PassShellClientRequestOnCommandLine(child_command_line.get()); |
launch_process_runner_->PostTaskAndReply( |
FROM_HERE, |
- base::Bind(&ChildProcessHost::DoLaunch, base::Unretained(this)), |
+ base::Bind(&ChildProcessHost::DoLaunch, base::Unretained(this), |
+ base::Passed(&child_command_line)), |
base::Bind(&ChildProcessHost::DidStart, |
weak_factory_.GetWeakPtr(), callback)); |
+ return client; |
} |
void ChildProcessHost::Join() { |
- if (factory_) |
+ if (mojo_ipc_channel_) |
start_child_process_event_.Wait(); |
- |
- factory_.reset(); |
- |
- // This host may be hosting a child process whose lifetime is controlled |
- // elsewhere. In this case we have no known process handle to wait on. |
+ mojo_ipc_channel_.reset(); |
if (child_process_.IsValid()) { |
int rv = -1; |
LOG_IF(ERROR, !child_process_.WaitForExit(&rv)) |
<< "Failed to wait for child process"; |
- |
child_process_.Close(); |
} |
} |
@@ -97,52 +115,24 @@ void ChildProcessHost::DidStart(const ProcessReadyCallback& callback) { |
callback.Run(child_process_.Pid()); |
} else { |
LOG(ERROR) << "Failed to start child process"; |
- factory_.reset(); |
+ mojo_ipc_channel_.reset(); |
} |
} |
-void ChildProcessHost::DoLaunch() { |
- const base::CommandLine* parent_command_line = |
- base::CommandLine::ForCurrentProcess(); |
- base::FilePath target_path = parent_command_line->GetProgram(); |
- // |app_path_| can be empty in tests. |
- if (!app_path_.MatchesExtension(FILE_PATH_LITERAL(".mojo")) && |
- !app_path_.empty()) { |
- target_path = app_path_; |
- } |
- |
- base::CommandLine child_command_line(target_path); |
- child_command_line.AppendArguments(*parent_command_line, false); |
- |
- if (target_path != app_path_) |
- child_command_line.AppendSwitchPath(switches::kChildProcess, app_path_); |
- |
- if (start_sandboxed_) |
- child_command_line.AppendSwitch(switches::kEnableSandbox); |
- |
- if (node_channel_.get()) { |
- node_channel_->PrepareToPassClientHandleToChildProcess( |
- &child_command_line, &handle_passing_info_); |
- } |
- |
- child_command_line.AppendSwitchASCII(switches::kPrimordialPipeToken, |
- primordial_pipe_token_); |
- |
+void ChildProcessHost::DoLaunch( |
+ scoped_ptr<base::CommandLine> child_command_line) { |
if (delegate_) { |
delegate_->AdjustCommandLineArgumentsForTarget(target_, |
- &child_command_line); |
+ child_command_line.get()); |
} |
base::LaunchOptions options; |
#if defined(OS_WIN) |
- if (base::win::GetVersion() >= base::win::VERSION_VISTA) { |
- options.handles_to_inherit = &handle_passing_info_; |
- } else { |
+ options.handles_to_inherit = &handle_passing_info_; |
#if defined(OFFICIAL_BUILD) |
- CHECK(false) << "Launching mojo process with inherit_handles is insecure!"; |
+ CHECK(false) << "Launching mojo process with inherit_handles is insecure!"; |
#endif |
- options.inherit_handles = true; |
- } |
+ options.inherit_handles = true; |
options.stdin_handle = INVALID_HANDLE_VALUE; |
options.stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); |
options.stderr_handle = GetStdHandle(STD_ERROR_HANDLE); |
@@ -173,27 +163,26 @@ void ChildProcessHost::DoLaunch() { |
options.fds_to_remap = &handle_passing_info_; |
#endif |
DVLOG(2) << "Launching child with command line: " |
- << child_command_line.GetCommandLineString(); |
+ << child_command_line->GetCommandLineString(); |
#if defined(OS_LINUX) && !defined(OS_ANDROID) |
if (start_sandboxed_) { |
child_process_ = |
- sandbox::NamespaceSandbox::LaunchProcess(child_command_line, options); |
+ sandbox::NamespaceSandbox::LaunchProcess(*child_command_line, options); |
if (!child_process_.IsValid()) { |
LOG(ERROR) << "Starting the process with a sandbox failed. Missing kernel" |
<< " support."; |
} |
} else |
#endif |
- child_process_ = base::LaunchProcess(child_command_line, options); |
+ child_process_ = base::LaunchProcess(*child_command_line, options); |
if (child_process_.IsValid()) { |
- platform_channel_pair_.ChildProcessLaunched(); |
- if (node_channel_.get()) { |
- node_channel_->ChildProcessLaunched(); |
+ if (mojo_ipc_channel_.get()) { |
+ mojo_ipc_channel_->ChildProcessLaunched(); |
mojo::edk::ChildProcessLaunched( |
child_process_.Handle(), |
mojo::edk::ScopedPlatformHandle(mojo::edk::PlatformHandle( |
- node_channel_->PassServerHandle().release().handle))); |
+ mojo_ipc_channel_->PassServerHandle().release().handle))); |
} |
} |
start_child_process_event_.Signal(); |