Remove 'RemoveTrailingSeparators' function from SimpleMenuModel
[chromium-blink-merge.git] / mojo / shell / child_process_host.cc
blob9d955e22e0556d2cc5877b7efec0d399a0cb7387
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/shell/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/system/core.h"
20 #include "mojo/shell/context.h"
21 #include "mojo/shell/switches.h"
22 #include "mojo/shell/task_runners.h"
24 namespace mojo {
25 namespace shell {
27 ChildProcessHost::ChildProcessHost(Context* context)
28 : context_(context), channel_info_(nullptr) {
29 platform_channel_ = platform_channel_pair_.PassServerHandle();
30 CHECK(platform_channel_.is_valid());
33 ChildProcessHost::~ChildProcessHost() {
34 if (child_process_.IsValid()) {
35 LOG(WARNING) << "Destroying ChildProcessHost with unjoined child";
36 child_process_.Close();
40 void ChildProcessHost::Start() {
41 DCHECK(!child_process_.IsValid());
42 DCHECK(platform_channel_.is_valid());
44 ScopedMessagePipeHandle handle(embedder::CreateChannel(
45 platform_channel_.Pass(), context_->task_runners()->io_runner(),
46 base::Bind(&ChildProcessHost::DidCreateChannel, base::Unretained(this)),
47 base::MessageLoop::current()->message_loop_proxy()));
49 controller_.Bind(handle.Pass());
51 CHECK(base::PostTaskAndReplyWithResult(
52 context_->task_runners()->blocking_pool(), FROM_HERE,
53 base::Bind(&ChildProcessHost::DoLaunch, base::Unretained(this)),
54 base::Bind(&ChildProcessHost::DidStart, base::Unretained(this))));
57 int ChildProcessHost::Join() {
58 DCHECK(child_process_.IsValid());
59 int rv = -1;
60 LOG_IF(ERROR, !child_process_.WaitForExit(&rv))
61 << "Failed to wait for child process";
62 child_process_.Close();
63 return rv;
66 void ChildProcessHost::StartApp(
67 const String& app_path,
68 bool clean_app_path,
69 InterfaceRequest<Application> application_request,
70 const ChildController::StartAppCallback& on_app_complete) {
71 DCHECK(controller_);
73 on_app_complete_ = on_app_complete;
74 controller_->StartApp(
75 app_path, clean_app_path, application_request.Pass(),
76 base::Bind(&ChildProcessHost::AppCompleted, base::Unretained(this)));
79 void ChildProcessHost::ExitNow(int32_t exit_code) {
80 DCHECK(controller_);
82 controller_->ExitNow(exit_code);
85 void ChildProcessHost::DidStart(bool success) {
86 DVLOG(2) << "ChildProcessHost::DidStart()";
88 if (!success) {
89 LOG(ERROR) << "Failed to start child process";
90 AppCompleted(MOJO_RESULT_UNKNOWN);
91 return;
95 bool ChildProcessHost::DoLaunch() {
96 static const char* kForwardSwitches[] = {
97 switches::kTraceToConsole, switches::kV, switches::kVModule,
100 const base::CommandLine* parent_command_line =
101 base::CommandLine::ForCurrentProcess();
102 base::CommandLine child_command_line(parent_command_line->GetProgram());
103 child_command_line.CopySwitchesFrom(*parent_command_line, kForwardSwitches,
104 arraysize(kForwardSwitches));
105 child_command_line.AppendSwitch(switches::kChildProcess);
107 embedder::HandlePassingInformation handle_passing_info;
108 platform_channel_pair_.PrepareToPassClientHandleToChildProcess(
109 &child_command_line, &handle_passing_info);
111 base::LaunchOptions options;
112 #if defined(OS_WIN)
113 options.start_hidden = true;
114 options.handles_to_inherit = &handle_passing_info;
115 #elif defined(OS_POSIX)
116 options.fds_to_remap = &handle_passing_info;
117 #endif
118 DVLOG(2) << "Launching child with command line: "
119 << child_command_line.GetCommandLineString();
120 child_process_ = base::LaunchProcess(child_command_line, options);
121 if (!child_process_.IsValid())
122 return false;
124 platform_channel_pair_.ChildProcessLaunched();
125 return true;
128 void ChildProcessHost::AppCompleted(int32_t result) {
129 if (!on_app_complete_.is_null()) {
130 auto on_app_complete = on_app_complete_;
131 on_app_complete_.reset();
132 on_app_complete.Run(result);
136 void ChildProcessHost::DidCreateChannel(embedder::ChannelInfo* channel_info) {
137 DVLOG(2) << "AppChildProcessHost::DidCreateChannel()";
139 CHECK(channel_info);
140 channel_info_ = channel_info;
143 } // namespace shell
144 } // namespace mojo