Fixes for Android GN build input/outputs
[chromium-blink-merge.git] / mojo / runner / child_process_host.cc
blobcd35da98851527486e31c52aaa41cd1e969f152a
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "mojo/runner/child_process_host.h"
7 #include "base/base_switches.h"
8 #include "base/bind.h"
9 #include "base/command_line.h"
10 #include "base/location.h"
11 #include "base/logging.h"
12 #include "base/macros.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/process/kill.h"
15 #include "base/process/launch.h"
16 #include "base/task_runner.h"
17 #include "base/task_runner_util.h"
18 #include "mojo/edk/embedder/embedder.h"
19 #include "mojo/public/cpp/bindings/interface_ptr_info.h"
20 #include "mojo/public/cpp/system/core.h"
21 #include "mojo/runner/context.h"
22 #include "mojo/runner/switches.h"
23 #include "mojo/runner/task_runners.h"
24 #include "ui/gl/gl_switches.h"
26 namespace mojo {
27 namespace runner {
29 ChildProcessHost::ChildProcessHost(Context* context, const std::string& name)
30 : context_(context), name_(name), channel_info_(nullptr) {
31 platform_channel_ = platform_channel_pair_.PassServerHandle();
32 DCHECK(!name.empty());
33 CHECK(platform_channel_.is_valid());
36 ChildProcessHost::~ChildProcessHost() {
37 if (child_process_.IsValid()) {
38 LOG(WARNING) << "Destroying ChildProcessHost with unjoined child";
39 child_process_.Close();
43 void ChildProcessHost::Start() {
44 DCHECK(!child_process_.IsValid());
45 DCHECK(platform_channel_.is_valid());
47 ScopedMessagePipeHandle handle(embedder::CreateChannel(
48 platform_channel_.Pass(), context_->task_runners()->io_runner(),
49 base::Bind(&ChildProcessHost::DidCreateChannel, base::Unretained(this)),
50 base::MessageLoop::current()->message_loop_proxy()));
52 controller_.Bind(InterfacePtrInfo<ChildController>(handle.Pass(), 0u));
54 CHECK(base::PostTaskAndReplyWithResult(
55 context_->task_runners()->blocking_pool(), FROM_HERE,
56 base::Bind(&ChildProcessHost::DoLaunch, base::Unretained(this)),
57 base::Bind(&ChildProcessHost::DidStart, base::Unretained(this))));
60 int ChildProcessHost::Join() {
61 DCHECK(child_process_.IsValid());
62 int rv = -1;
63 LOG_IF(ERROR, !child_process_.WaitForExit(&rv))
64 << "Failed to wait for child process";
65 child_process_.Close();
66 return rv;
69 void ChildProcessHost::StartApp(
70 const String& app_path,
71 bool clean_app_path,
72 InterfaceRequest<Application> application_request,
73 const ChildController::StartAppCallback& on_app_complete) {
74 DCHECK(controller_);
76 on_app_complete_ = on_app_complete;
77 controller_->StartApp(
78 app_path, clean_app_path, application_request.Pass(),
79 base::Bind(&ChildProcessHost::AppCompleted, base::Unretained(this)));
82 void ChildProcessHost::ExitNow(int32_t exit_code) {
83 DCHECK(controller_);
85 controller_->ExitNow(exit_code);
88 void ChildProcessHost::DidStart(bool success) {
89 DVLOG(2) << "ChildProcessHost::DidStart()";
91 if (!success) {
92 LOG(ERROR) << "Failed to start child process";
93 AppCompleted(MOJO_RESULT_UNKNOWN);
94 return;
98 bool ChildProcessHost::DoLaunch() {
99 static const char* kForwardSwitches[] = {
100 switches::kOverrideUseGLWithOSMesaForTests,
101 switches::kTraceToConsole,
102 switches::kV,
103 switches::kVModule,
104 switches::kWaitForDebugger,
107 const base::CommandLine* parent_command_line =
108 base::CommandLine::ForCurrentProcess();
109 base::CommandLine child_command_line(parent_command_line->GetProgram());
110 child_command_line.CopySwitchesFrom(*parent_command_line, kForwardSwitches,
111 arraysize(kForwardSwitches));
112 child_command_line.AppendSwitchASCII(switches::kApp, name_);
113 child_command_line.AppendSwitch(switches::kChildProcess);
115 auto args = parent_command_line->GetArgs();
116 for (const auto& arg : args)
117 child_command_line.AppendArgNative(arg);
119 embedder::HandlePassingInformation handle_passing_info;
120 platform_channel_pair_.PrepareToPassClientHandleToChildProcess(
121 &child_command_line, &handle_passing_info);
123 base::LaunchOptions options;
124 #if defined(OS_WIN)
125 options.handles_to_inherit = &handle_passing_info;
126 #elif defined(OS_POSIX)
127 options.fds_to_remap = &handle_passing_info;
128 #endif
129 DVLOG(2) << "Launching child with command line: "
130 << child_command_line.GetCommandLineString();
131 child_process_ = base::LaunchProcess(child_command_line, options);
132 if (!child_process_.IsValid())
133 return false;
135 platform_channel_pair_.ChildProcessLaunched();
136 return true;
139 void ChildProcessHost::AppCompleted(int32_t result) {
140 if (!on_app_complete_.is_null()) {
141 auto on_app_complete = on_app_complete_;
142 on_app_complete_.reset();
143 on_app_complete.Run(result);
147 void ChildProcessHost::DidCreateChannel(embedder::ChannelInfo* channel_info) {
148 DVLOG(2) << "AppChildProcessHost::DidCreateChannel()";
150 CHECK(channel_info);
151 channel_info_ = channel_info;
154 } // namespace runner
155 } // namespace mojo