Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(782)

Side by Side Diff: mojo/runner/host/child_process_host.cc

Issue 1387963004: Create a broker interface for the new Mojo EDK so that the browser can create and duplicate messa... (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: presubmit whitespace error Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "mojo/runner/host/child_process_host.h" 5 #include "mojo/runner/host/child_process_host.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/location.h" 9 #include "base/location.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 21 matching lines...) Expand all
32 32
33 ChildProcessHost::ChildProcessHost(base::TaskRunner* launch_process_runner, 33 ChildProcessHost::ChildProcessHost(base::TaskRunner* launch_process_runner,
34 bool start_sandboxed, 34 bool start_sandboxed,
35 const base::FilePath& app_path) 35 const base::FilePath& app_path)
36 : launch_process_runner_(launch_process_runner), 36 : launch_process_runner_(launch_process_runner),
37 start_sandboxed_(start_sandboxed), 37 start_sandboxed_(start_sandboxed),
38 app_path_(app_path), 38 app_path_(app_path),
39 channel_info_(nullptr), 39 channel_info_(nullptr),
40 start_child_process_event_(false, false), 40 start_child_process_event_(false, false),
41 weak_factory_(this) { 41 weak_factory_(this) {
42 platform_channel_ = platform_channel_pair_.PassServerHandle(); 42 #if defined(OS_WIN)
43 CHECK(platform_channel_.is_valid()); 43 if (base::CommandLine::ForCurrentProcess()->HasSwitch("use-new-edk"))
44 serializer_platform_channel_pair_.reset(new edk::PlatformChannelPair(true));
45 #endif
46
47 child_message_pipe_ = embedder::CreateChannel(
48 platform_channel_pair_.PassServerHandle(),
49 base::Bind(&ChildProcessHost::DidCreateChannel, base::Unretained(this)),
50 base::ThreadTaskRunnerHandle::Get());
44 } 51 }
45 52
46 ChildProcessHost::ChildProcessHost(ScopedHandle channel) 53 ChildProcessHost::ChildProcessHost(ScopedHandle channel)
47 : launch_process_runner_(nullptr), 54 : launch_process_runner_(nullptr),
48 start_sandboxed_(false), 55 start_sandboxed_(false),
49 channel_info_(nullptr), 56 channel_info_(nullptr),
50 start_child_process_event_(false, false), 57 start_child_process_event_(false, false),
51 weak_factory_(this) { 58 weak_factory_(this) {
52 CHECK(channel.is_valid()); 59 CHECK(channel.is_valid());
53 ScopedMessagePipeHandle handle(MessagePipeHandle(channel.release().value())); 60 ScopedMessagePipeHandle handle(MessagePipeHandle(channel.release().value()));
54 controller_.Bind(InterfacePtrInfo<ChildController>(handle.Pass(), 0u)); 61 controller_.Bind(InterfacePtrInfo<ChildController>(handle.Pass(), 0u));
55 } 62 }
56 63
57 ChildProcessHost::~ChildProcessHost() { 64 ChildProcessHost::~ChildProcessHost() {
58 if (!app_path_.empty()) 65 if (!app_path_.empty())
59 CHECK(!controller_) << "Destroying ChildProcessHost before calling Join"; 66 CHECK(!controller_) << "Destroying ChildProcessHost before calling Join";
60 } 67 }
61 68
62 void ChildProcessHost::Start() { 69 void ChildProcessHost::Start() {
63 DCHECK(!child_process_.IsValid()); 70 DCHECK(!child_process_.IsValid());
64 DCHECK(platform_channel_.is_valid()); 71 DCHECK(child_message_pipe_.is_valid());
65 72
66 ScopedMessagePipeHandle handle(embedder::CreateChannel( 73 #if defined(OS_WIN)
67 platform_channel_.Pass(), base::Bind(&ChildProcessHost::DidCreateChannel, 74 if (base::CommandLine::ForCurrentProcess()->HasSwitch("use-new-edk")) {
68 weak_factory_.GetWeakPtr()), 75 std::string client_handle_as_string =
69 base::ThreadTaskRunnerHandle::Get())); 76 serializer_platform_channel_pair_
77 ->PrepareToPassClientHandleToChildProcessAsString(
78 &handle_passing_info_);
79 // We can't send the MP for the token serializer implementation as a
80 // platform handle, because that would require the other side to use the
81 // token initializer itself! So instead we send it as a string.
82 MojoResult rv = MojoWriteMessage(
83 child_message_pipe_.get().value(), client_handle_as_string.c_str(),
84 static_cast<uint32_t>(client_handle_as_string.size()), nullptr, 0,
85 MOJO_WRITE_MESSAGE_FLAG_NONE);
86 DCHECK_EQ(rv, MOJO_RESULT_OK);
87 }
88 #endif
70 89
71 controller_.Bind(InterfacePtrInfo<ChildController>(handle.Pass(), 0u)); 90 controller_.Bind(
91 InterfacePtrInfo<ChildController>(child_message_pipe_.Pass(), 0u));
72 92
73 launch_process_runner_->PostTaskAndReply( 93 launch_process_runner_->PostTaskAndReply(
74 FROM_HERE, 94 FROM_HERE,
75 base::Bind(&ChildProcessHost::DoLaunch, base::Unretained(this)), 95 base::Bind(&ChildProcessHost::DoLaunch, base::Unretained(this)),
76 base::Bind(&ChildProcessHost::DidStart, weak_factory_.GetWeakPtr())); 96 base::Bind(&ChildProcessHost::DidStart, weak_factory_.GetWeakPtr()));
77 } 97 }
78 98
79 int ChildProcessHost::Join() { 99 int ChildProcessHost::Join() {
80 if (controller_) // We use this as a signal that Start was called. 100 if (controller_) // We use this as a signal that Start was called.
81 start_child_process_event_.Wait(); 101 start_child_process_event_.Wait();
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 146
127 base::CommandLine child_command_line(target_path); 147 base::CommandLine child_command_line(target_path);
128 child_command_line.AppendArguments(*parent_command_line, false); 148 child_command_line.AppendArguments(*parent_command_line, false);
129 149
130 if (target_path != app_path_) 150 if (target_path != app_path_)
131 child_command_line.AppendSwitchPath(switches::kChildProcess, app_path_); 151 child_command_line.AppendSwitchPath(switches::kChildProcess, app_path_);
132 152
133 if (start_sandboxed_) 153 if (start_sandboxed_)
134 child_command_line.AppendSwitch(switches::kEnableSandbox); 154 child_command_line.AppendSwitch(switches::kEnableSandbox);
135 155
136 embedder::HandlePassingInformation handle_passing_info;
137 platform_channel_pair_.PrepareToPassClientHandleToChildProcess( 156 platform_channel_pair_.PrepareToPassClientHandleToChildProcess(
138 &child_command_line, &handle_passing_info); 157 &child_command_line, &handle_passing_info_);
139 158
140 base::LaunchOptions options; 159 base::LaunchOptions options;
141 #if defined(OS_WIN) 160 #if defined(OS_WIN)
142 if (base::win::GetVersion() >= base::win::VERSION_VISTA) { 161 if (base::win::GetVersion() >= base::win::VERSION_VISTA) {
143 options.handles_to_inherit = &handle_passing_info; 162 options.handles_to_inherit = &handle_passing_info_;
144 } else { 163 } else {
145 #if defined(OFFICIAL_BUILD) 164 #if defined(OFFICIAL_BUILD)
146 CHECK(false) << "Launching mojo process with inherit_handles is insecure!"; 165 CHECK(false) << "Launching mojo process with inherit_handles is insecure!";
147 #endif 166 #endif
148 options.inherit_handles = true; 167 options.inherit_handles = true;
149 } 168 }
150 options.stdin_handle = INVALID_HANDLE_VALUE; 169 options.stdin_handle = INVALID_HANDLE_VALUE;
151 options.stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); 170 options.stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
152 options.stderr_handle = GetStdHandle(STD_ERROR_HANDLE); 171 options.stderr_handle = GetStdHandle(STD_ERROR_HANDLE);
153 172
154 // Pseudo handles are used when stdout and stderr redirect to the console. In 173 // Pseudo handles are used when stdout and stderr redirect to the console. In
155 // that case, they're automatically inherited by child processes. See 174 // that case, they're automatically inherited by child processes. See
156 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms682075.aspx 175 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms682075.aspx
157 // Trying to add them to the list of handles to inherit causes CreateProcess 176 // Trying to add them to the list of handles to inherit causes CreateProcess
158 // to fail. When this process is launched from Python 177 // to fail. When this process is launched from Python
159 // (i.e. by apptest_runner.py) then a real handle is used. In that case, we do 178 // (i.e. by apptest_runner.py) then a real handle is used. In that case, we do
160 // want to add it to the list of handles that is inherited. 179 // want to add it to the list of handles that is inherited.
161 if (GetFileType(options.stdout_handle) != FILE_TYPE_CHAR) 180 if (GetFileType(options.stdout_handle) != FILE_TYPE_CHAR)
162 handle_passing_info.push_back(options.stdout_handle); 181 handle_passing_info_.push_back(options.stdout_handle);
163 if (GetFileType(options.stderr_handle) != FILE_TYPE_CHAR && 182 if (GetFileType(options.stderr_handle) != FILE_TYPE_CHAR &&
164 options.stdout_handle != options.stdout_handle) { 183 options.stdout_handle != options.stdout_handle) {
165 handle_passing_info.push_back(options.stderr_handle); 184 handle_passing_info_.push_back(options.stderr_handle);
166 } 185 }
167 #elif defined(OS_POSIX) 186 #elif defined(OS_POSIX)
168 handle_passing_info.push_back(std::make_pair(STDIN_FILENO, STDIN_FILENO)); 187 handle_passing_info_.push_back(std::make_pair(STDIN_FILENO, STDIN_FILENO));
169 handle_passing_info.push_back(std::make_pair(STDOUT_FILENO, STDOUT_FILENO)); 188 handle_passing_info_.push_back(std::make_pair(STDOUT_FILENO, STDOUT_FILENO));
170 handle_passing_info.push_back(std::make_pair(STDERR_FILENO, STDERR_FILENO)); 189 handle_passing_info_.push_back(std::make_pair(STDERR_FILENO, STDERR_FILENO));
171 options.fds_to_remap = &handle_passing_info; 190 options.fds_to_remap = &handle_passing_info_;
172 #endif 191 #endif
173 DVLOG(2) << "Launching child with command line: " 192 DVLOG(2) << "Launching child with command line: "
174 << child_command_line.GetCommandLineString(); 193 << child_command_line.GetCommandLineString();
175 #if defined(OS_LINUX) && !defined(OS_ANDROID) 194 #if defined(OS_LINUX) && !defined(OS_ANDROID)
176 if (start_sandboxed_) { 195 if (start_sandboxed_) {
177 child_process_ = 196 child_process_ =
178 sandbox::NamespaceSandbox::LaunchProcess(child_command_line, options); 197 sandbox::NamespaceSandbox::LaunchProcess(child_command_line, options);
179 if (!child_process_.IsValid()) { 198 if (!child_process_.IsValid()) {
180 LOG(ERROR) << "Starting the process with a sandbox failed. Missing kernel" 199 LOG(ERROR) << "Starting the process with a sandbox failed. Missing kernel"
181 << " support."; 200 << " support.";
182 } 201 }
183 } else 202 } else
184 #endif 203 #endif
185 child_process_ = base::LaunchProcess(child_command_line, options); 204 child_process_ = base::LaunchProcess(child_command_line, options);
186 205
187 if (child_process_.IsValid()) 206 if (child_process_.IsValid()) {
188 platform_channel_pair_.ChildProcessLaunched(); 207 platform_channel_pair_.ChildProcessLaunched();
208 #if defined(OS_WIN)
209 if (serializer_platform_channel_pair_.get()) {
210 serializer_platform_channel_pair_->ChildProcessLaunched();
211 mojo::embedder::ChildProcessLaunched(
212 child_process_.Handle(),
213 serializer_platform_channel_pair_->PassServerHandle()
214 .release()
215 .handle);
216 }
217 #endif
218 }
189 start_child_process_event_.Signal(); 219 start_child_process_event_.Signal();
190 } 220 }
191 221
192 void ChildProcessHost::AppCompleted(int32_t result) { 222 void ChildProcessHost::AppCompleted(int32_t result) {
193 if (!on_app_complete_.is_null()) { 223 if (!on_app_complete_.is_null()) {
194 auto on_app_complete = on_app_complete_; 224 auto on_app_complete = on_app_complete_;
195 on_app_complete_.reset(); 225 on_app_complete_.reset();
196 on_app_complete.Run(result); 226 on_app_complete.Run(result);
197 } 227 }
198 } 228 }
199 229
200 void ChildProcessHost::DidCreateChannel(embedder::ChannelInfo* channel_info) { 230 void ChildProcessHost::DidCreateChannel(embedder::ChannelInfo* channel_info) {
201 DVLOG(2) << "AppChildProcessHost::DidCreateChannel()"; 231 DVLOG(2) << "AppChildProcessHost::DidCreateChannel()";
202 232
203 DCHECK(channel_info || 233 DCHECK(channel_info ||
204 base::CommandLine::ForCurrentProcess()->HasSwitch("use-new-edk")); 234 base::CommandLine::ForCurrentProcess()->HasSwitch("use-new-edk"));
205 channel_info_ = channel_info; 235 channel_info_ = channel_info;
206 } 236 }
207 237
208 } // namespace runner 238 } // namespace runner
209 } // namespace mojo 239 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698