OLD | NEW |
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.h" | 5 #include "mojo/runner/host/child_process.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 10 matching lines...) Expand all Loading... |
21 #include "base/memory/ref_counted.h" | 21 #include "base/memory/ref_counted.h" |
22 #include "base/memory/scoped_ptr.h" | 22 #include "base/memory/scoped_ptr.h" |
23 #include "base/message_loop/message_loop.h" | 23 #include "base/message_loop/message_loop.h" |
24 #include "base/single_thread_task_runner.h" | 24 #include "base/single_thread_task_runner.h" |
25 #include "base/synchronization/waitable_event.h" | 25 #include "base/synchronization/waitable_event.h" |
26 #include "base/thread_task_runner_handle.h" | 26 #include "base/thread_task_runner_handle.h" |
27 #include "base/threading/thread.h" | 27 #include "base/threading/thread.h" |
28 #include "base/threading/thread_checker.h" | 28 #include "base/threading/thread_checker.h" |
29 #include "mojo/edk/embedder/embedder.h" | 29 #include "mojo/edk/embedder/embedder.h" |
30 #include "mojo/edk/embedder/platform_channel_pair.h" | 30 #include "mojo/edk/embedder/platform_channel_pair.h" |
| 31 #include "mojo/edk/embedder/process_delegate.h" |
| 32 #include "mojo/edk/embedder/scoped_platform_handle.h" |
31 #include "mojo/message_pump/message_pump_mojo.h" | 33 #include "mojo/message_pump/message_pump_mojo.h" |
32 #include "mojo/public/cpp/bindings/binding.h" | 34 #include "mojo/public/cpp/bindings/binding.h" |
33 #include "mojo/public/cpp/system/core.h" | 35 #include "mojo/public/cpp/system/core.h" |
34 #include "mojo/runner/child/child_controller.mojom.h" | 36 #include "mojo/runner/child/child_controller.mojom.h" |
35 #include "mojo/runner/host/native_application_support.h" | 37 #include "mojo/runner/host/native_application_support.h" |
36 #include "mojo/runner/host/switches.h" | 38 #include "mojo/runner/host/switches.h" |
37 #include "mojo/runner/init.h" | 39 #include "mojo/runner/init.h" |
38 #include "third_party/mojo/src/mojo/edk/embedder/embedder.h" | |
39 #include "third_party/mojo/src/mojo/edk/embedder/platform_channel_pair.h" | |
40 #include "third_party/mojo/src/mojo/edk/embedder/process_delegate.h" | |
41 #include "third_party/mojo/src/mojo/edk/embedder/scoped_platform_handle.h" | |
42 | 40 |
43 #if defined(OS_LINUX) && !defined(OS_ANDROID) | 41 #if defined(OS_LINUX) && !defined(OS_ANDROID) |
44 #include "base/rand_util.h" | 42 #include "base/rand_util.h" |
45 #include "base/sys_info.h" | 43 #include "base/sys_info.h" |
46 #include "mojo/runner/host/linux_sandbox.h" | 44 #include "mojo/runner/host/linux_sandbox.h" |
47 #endif | 45 #endif |
48 | 46 |
49 namespace mojo { | 47 namespace mojo { |
50 namespace runner { | 48 namespace runner { |
51 | 49 |
52 namespace { | 50 namespace { |
53 | 51 |
54 void DidCreateChannel(embedder::ChannelInfo* channel_info) { | |
55 DVLOG(2) << "ChildControllerImpl::DidCreateChannel()"; | |
56 } | |
57 | |
58 // Blocker --------------------------------------------------------------------- | 52 // Blocker --------------------------------------------------------------------- |
59 | 53 |
60 // Blocks a thread until another thread unblocks it, at which point it unblocks | 54 // Blocks a thread until another thread unblocks it, at which point it unblocks |
61 // and runs a closure provided by that thread. | 55 // and runs a closure provided by that thread. |
62 class Blocker { | 56 class Blocker { |
63 public: | 57 public: |
64 class Unblocker { | 58 class Unblocker { |
65 public: | 59 public: |
66 explicit Unblocker(Blocker* blocker = nullptr) : blocker_(blocker) {} | 60 explicit Unblocker(Blocker* blocker = nullptr) : blocker_(blocker) {} |
67 ~Unblocker() {} | 61 ~Unblocker() {} |
(...skipping 29 matching lines...) Expand all Loading... |
97 base::Closure run_after_; | 91 base::Closure run_after_; |
98 | 92 |
99 DISALLOW_COPY_AND_ASSIGN(Blocker); | 93 DISALLOW_COPY_AND_ASSIGN(Blocker); |
100 }; | 94 }; |
101 | 95 |
102 // AppContext ------------------------------------------------------------------ | 96 // AppContext ------------------------------------------------------------------ |
103 | 97 |
104 class ChildControllerImpl; | 98 class ChildControllerImpl; |
105 | 99 |
106 // Should be created and initialized on the main thread. | 100 // Should be created and initialized on the main thread. |
107 // TODO(use_chrome_edk) | 101 class AppContext : public edk::ProcessDelegate { |
108 // class AppContext : public edk::ProcessDelegate { | |
109 class AppContext : public embedder::ProcessDelegate { | |
110 public: | 102 public: |
111 AppContext() | 103 AppContext() |
112 : io_thread_("io_thread"), controller_thread_("controller_thread") {} | 104 : io_thread_("io_thread"), controller_thread_("controller_thread") {} |
113 ~AppContext() override {} | 105 ~AppContext() override {} |
114 | 106 |
115 void Init() { | 107 void Init() { |
116 embedder::PreInitializeChildProcess(); | 108 edk::PreInitializeChildProcess(); |
117 // Initialize Mojo before starting any threads. | 109 // Initialize Mojo before starting any threads. |
118 embedder::Init(); | 110 edk::Init(); |
119 | 111 |
120 // Create and start our I/O thread. | 112 // Create and start our I/O thread. |
121 base::Thread::Options io_thread_options(base::MessageLoop::TYPE_IO, 0); | 113 base::Thread::Options io_thread_options(base::MessageLoop::TYPE_IO, 0); |
122 CHECK(io_thread_.StartWithOptions(io_thread_options)); | 114 CHECK(io_thread_.StartWithOptions(io_thread_options)); |
123 io_runner_ = io_thread_.task_runner().get(); | 115 io_runner_ = io_thread_.task_runner().get(); |
124 CHECK(io_runner_.get()); | 116 CHECK(io_runner_.get()); |
125 | 117 |
126 // TODO(vtl): This should be SLAVE, not NONE. | |
127 // This must be created before controller_thread_ since MessagePumpMojo will | 118 // This must be created before controller_thread_ since MessagePumpMojo will |
128 // create a message pipe which requires this code to be run first. | 119 // create a message pipe which requires this code to be run first. |
129 embedder::InitIPCSupport(embedder::ProcessType::NONE, this, io_runner_, | 120 edk::InitIPCSupport(this, io_runner_); |
130 embedder::ScopedPlatformHandle()); | |
131 } | 121 } |
132 | 122 |
133 void StartControllerThread() { | 123 void StartControllerThread() { |
134 // Create and start our controller thread. | 124 // Create and start our controller thread. |
135 base::Thread::Options controller_thread_options; | 125 base::Thread::Options controller_thread_options; |
136 controller_thread_options.message_loop_type = | 126 controller_thread_options.message_loop_type = |
137 base::MessageLoop::TYPE_CUSTOM; | 127 base::MessageLoop::TYPE_CUSTOM; |
138 controller_thread_options.message_pump_factory = | 128 controller_thread_options.message_pump_factory = |
139 base::Bind(&common::MessagePumpMojo::Create); | 129 base::Bind(&common::MessagePumpMojo::Create); |
140 CHECK(controller_thread_.StartWithOptions(controller_thread_options)); | 130 CHECK(controller_thread_.StartWithOptions(controller_thread_options)); |
(...skipping 21 matching lines...) Expand all Loading... |
162 void set_controller(scoped_ptr<ChildControllerImpl> controller) { | 152 void set_controller(scoped_ptr<ChildControllerImpl> controller) { |
163 controller_ = std::move(controller); | 153 controller_ = std::move(controller); |
164 } | 154 } |
165 | 155 |
166 private: | 156 private: |
167 void ShutdownOnControllerThread() { | 157 void ShutdownOnControllerThread() { |
168 // First, destroy the controller. | 158 // First, destroy the controller. |
169 controller_.reset(); | 159 controller_.reset(); |
170 | 160 |
171 // Next shutdown IPC. We'll unblock the main thread in OnShutdownComplete(). | 161 // Next shutdown IPC. We'll unblock the main thread in OnShutdownComplete(). |
172 embedder::ShutdownIPCSupport(); | 162 edk::ShutdownIPCSupport(); |
173 } | 163 } |
174 | 164 |
175 // ProcessDelegate implementation. | 165 // ProcessDelegate implementation. |
176 void OnShutdownComplete() override { | 166 void OnShutdownComplete() override { |
177 shutdown_unblocker_.Unblock(base::Closure()); | 167 shutdown_unblocker_.Unblock(base::Closure()); |
178 } | 168 } |
179 | 169 |
180 base::Thread io_thread_; | 170 base::Thread io_thread_; |
181 scoped_refptr<base::SingleThreadTaskRunner> io_runner_; | 171 scoped_refptr<base::SingleThreadTaskRunner> io_runner_; |
182 | 172 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 new mojo::runner::LinuxSandbox(permissions)); | 284 new mojo::runner::LinuxSandbox(permissions)); |
295 sandbox->Warmup(); | 285 sandbox->Warmup(); |
296 sandbox->EngageNamespaceSandbox(); | 286 sandbox->EngageNamespaceSandbox(); |
297 sandbox->EngageSeccompSandbox(); | 287 sandbox->EngageSeccompSandbox(); |
298 sandbox->Seal(); | 288 sandbox->Seal(); |
299 return sandbox; | 289 return sandbox; |
300 } | 290 } |
301 #endif | 291 #endif |
302 | 292 |
303 ScopedMessagePipeHandle InitializeHostMessagePipe( | 293 ScopedMessagePipeHandle InitializeHostMessagePipe( |
304 embedder::ScopedPlatformHandle platform_channel, | 294 edk::ScopedPlatformHandle platform_channel, |
305 scoped_refptr<base::TaskRunner> io_task_runner) { | 295 scoped_refptr<base::TaskRunner> io_task_runner) { |
306 ScopedMessagePipeHandle host_message_pipe( | 296 ScopedMessagePipeHandle host_message_pipe(edk::CreateMessagePipe( |
307 embedder::CreateChannel(std::move(platform_channel), | 297 std::move(platform_channel))); |
308 base::Bind(&DidCreateChannel), io_task_runner)); | |
309 | 298 |
310 if (base::CommandLine::ForCurrentProcess()->HasSwitch("use-new-edk")) { | 299 // When using the new Mojo EDK, each message pipe is backed by a platform |
311 // When using the new Mojo EDK, each message pipe is backed by a platform | 300 // handle. The one platform handle that comes on the command line is used |
312 // handle. The one platform handle that comes on the command line is used | 301 // to bind to the ChildController interface. However we also want a |
313 // to bind to the ChildController interface. However we also want a | 302 // platform handle to setup the communication channel by which we exchange |
314 // platform handle to setup the communication channel by which we exchange | 303 // handles to/from tokens, which is needed for sandboxed Windows |
315 // handles to/from tokens, which is needed for sandboxed Windows | 304 // processes. |
316 // processes. | 305 char broker_handle[10]; |
317 char broker_handle[10]; | 306 MojoHandleSignalsState state; |
318 MojoHandleSignalsState state; | 307 MojoResult rv = |
319 MojoResult rv = | 308 MojoWait(host_message_pipe.get().value(), MOJO_HANDLE_SIGNAL_READABLE, |
320 MojoWait(host_message_pipe.get().value(), MOJO_HANDLE_SIGNAL_READABLE, | 309 MOJO_DEADLINE_INDEFINITE, &state); |
321 MOJO_DEADLINE_INDEFINITE, &state); | 310 CHECK_EQ(MOJO_RESULT_OK, rv); |
322 CHECK_EQ(MOJO_RESULT_OK, rv); | 311 uint32_t num_bytes = arraysize(broker_handle); |
323 uint32_t num_bytes = arraysize(broker_handle); | 312 rv = MojoReadMessage(host_message_pipe.get().value(), |
324 rv = MojoReadMessage(host_message_pipe.get().value(), | 313 broker_handle, &num_bytes, nullptr, 0, |
325 broker_handle, &num_bytes, nullptr, 0, | 314 MOJO_READ_MESSAGE_FLAG_NONE); |
326 MOJO_READ_MESSAGE_FLAG_NONE); | 315 CHECK_EQ(MOJO_RESULT_OK, rv); |
327 CHECK_EQ(MOJO_RESULT_OK, rv); | |
328 | 316 |
329 edk::ScopedPlatformHandle broker_channel = | 317 edk::ScopedPlatformHandle broker_channel = |
330 edk::PlatformChannelPair::PassClientHandleFromParentProcessFromString( | 318 edk::PlatformChannelPair::PassClientHandleFromParentProcessFromString( |
331 std::string(broker_handle, num_bytes)); | 319 std::string(broker_handle, num_bytes)); |
332 CHECK(broker_channel.is_valid()); | 320 CHECK(broker_channel.is_valid()); |
333 embedder::SetParentPipeHandle( | 321 edk::SetParentPipeHandle(std::move(broker_channel)) ; |
334 mojo::embedder::ScopedPlatformHandle(mojo::embedder::PlatformHandle( | |
335 broker_channel.release().handle))); | |
336 } | |
337 | 322 |
338 return host_message_pipe; | 323 return host_message_pipe; |
339 } | 324 } |
340 | 325 |
341 } // namespace | 326 } // namespace |
342 | 327 |
343 int ChildProcessMain() { | 328 int ChildProcessMain() { |
344 DVLOG(2) << "ChildProcessMain()"; | 329 DVLOG(2) << "ChildProcessMain()"; |
345 const base::CommandLine& command_line = | 330 const base::CommandLine& command_line = |
346 *base::CommandLine::ForCurrentProcess(); | 331 *base::CommandLine::ForCurrentProcess(); |
(...skipping 11 matching lines...) Expand all Loading... |
358 #if !defined(OFFICIAL_BUILD) | 343 #if !defined(OFFICIAL_BUILD) |
359 // Initialize stack dumping just before initializing sandbox to make | 344 // Initialize stack dumping just before initializing sandbox to make |
360 // sure symbol names in all loaded libraries will be cached. | 345 // sure symbol names in all loaded libraries will be cached. |
361 base::debug::EnableInProcessStackDumping(); | 346 base::debug::EnableInProcessStackDumping(); |
362 #endif | 347 #endif |
363 #if defined(OS_LINUX) && !defined(OS_ANDROID) | 348 #if defined(OS_LINUX) && !defined(OS_ANDROID) |
364 if (command_line.HasSwitch(switches::kEnableSandbox)) | 349 if (command_line.HasSwitch(switches::kEnableSandbox)) |
365 sandbox = InitializeSandbox(); | 350 sandbox = InitializeSandbox(); |
366 #endif | 351 #endif |
367 | 352 |
368 embedder::ScopedPlatformHandle platform_channel = | 353 edk::ScopedPlatformHandle platform_channel = |
369 embedder::PlatformChannelPair::PassClientHandleFromParentProcess( | 354 edk::PlatformChannelPair::PassClientHandleFromParentProcess( |
370 command_line); | 355 command_line); |
371 CHECK(platform_channel.is_valid()); | 356 CHECK(platform_channel.is_valid()); |
372 | 357 |
373 DCHECK(!base::MessageLoop::current()); | 358 DCHECK(!base::MessageLoop::current()); |
374 | 359 |
375 AppContext app_context; | 360 AppContext app_context; |
376 app_context.Init(); | 361 app_context.Init(); |
377 ScopedMessagePipeHandle host_message_pipe = InitializeHostMessagePipe( | 362 ScopedMessagePipeHandle host_message_pipe = InitializeHostMessagePipe( |
378 std::move(platform_channel), app_context.io_runner()); | 363 std::move(platform_channel), app_context.io_runner()); |
379 app_context.StartControllerThread(); | 364 app_context.StartControllerThread(); |
380 Blocker blocker; | 365 Blocker blocker; |
381 app_context.controller_runner()->PostTask( | 366 app_context.controller_runner()->PostTask( |
382 FROM_HERE, | 367 FROM_HERE, |
383 base::Bind(&ChildControllerImpl::Init, base::Unretained(&app_context), | 368 base::Bind(&ChildControllerImpl::Init, base::Unretained(&app_context), |
384 base::Unretained(app_library), | 369 base::Unretained(app_library), |
385 base::Passed(&host_message_pipe), blocker.GetUnblocker())); | 370 base::Passed(&host_message_pipe), blocker.GetUnblocker())); |
386 // This will block, then run whatever the controller wants. | 371 // This will block, then run whatever the controller wants. |
387 blocker.Block(); | 372 blocker.Block(); |
388 | 373 |
389 app_context.Shutdown(); | 374 app_context.Shutdown(); |
390 | 375 |
391 return 0; | 376 return 0; |
392 } | 377 } |
393 | 378 |
394 } // namespace runner | 379 } // namespace runner |
395 } // namespace mojo | 380 } // namespace mojo |
OLD | NEW |