| 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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 _exit(exit_code); | 240 _exit(exit_code); |
| 251 } | 241 } |
| 252 | 242 |
| 253 private: | 243 private: |
| 254 ChildControllerImpl(AppContext* app_context, | 244 ChildControllerImpl(AppContext* app_context, |
| 255 base::NativeLibrary app_library, | 245 base::NativeLibrary app_library, |
| 256 const Blocker::Unblocker& unblocker) | 246 const Blocker::Unblocker& unblocker) |
| 257 : app_context_(app_context), | 247 : app_context_(app_context), |
| 258 app_library_(app_library), | 248 app_library_(app_library), |
| 259 unblocker_(unblocker), | 249 unblocker_(unblocker), |
| 260 channel_info_(nullptr), | |
| 261 binding_(this) {} | 250 binding_(this) {} |
| 262 | 251 |
| 263 static void StartAppOnMainThread( | 252 static void StartAppOnMainThread( |
| 264 base::NativeLibrary app_library, | 253 base::NativeLibrary app_library, |
| 265 InterfaceRequest<Application> application_request) { | 254 InterfaceRequest<Application> application_request) { |
| 266 if (!RunNativeApplication(app_library, std::move(application_request))) { | 255 if (!RunNativeApplication(app_library, std::move(application_request))) { |
| 267 LOG(ERROR) << "Failure to RunNativeApplication()"; | 256 LOG(ERROR) << "Failure to RunNativeApplication()"; |
| 268 } | 257 } |
| 269 } | 258 } |
| 270 | 259 |
| 271 base::ThreadChecker thread_checker_; | 260 base::ThreadChecker thread_checker_; |
| 272 AppContext* const app_context_; | 261 AppContext* const app_context_; |
| 273 base::NativeLibrary app_library_; | 262 base::NativeLibrary app_library_; |
| 274 Blocker::Unblocker unblocker_; | 263 Blocker::Unblocker unblocker_; |
| 275 StartAppCallback on_app_complete_; | 264 StartAppCallback on_app_complete_; |
| 276 | 265 |
| 277 embedder::ChannelInfo* channel_info_; | |
| 278 Binding<ChildController> binding_; | 266 Binding<ChildController> binding_; |
| 279 | 267 |
| 280 DISALLOW_COPY_AND_ASSIGN(ChildControllerImpl); | 268 DISALLOW_COPY_AND_ASSIGN(ChildControllerImpl); |
| 281 }; | 269 }; |
| 282 | 270 |
| 283 #if defined(OS_LINUX) && !defined(OS_ANDROID) | 271 #if defined(OS_LINUX) && !defined(OS_ANDROID) |
| 284 scoped_ptr<mojo::runner::LinuxSandbox> InitializeSandbox() { | 272 scoped_ptr<mojo::runner::LinuxSandbox> InitializeSandbox() { |
| 285 using sandbox::syscall_broker::BrokerFilePermission; | 273 using sandbox::syscall_broker::BrokerFilePermission; |
| 286 // Warm parts of base in the copy of base in the mojo runner. | 274 // Warm parts of base in the copy of base in the mojo runner. |
| 287 base::RandUint64(); | 275 base::RandUint64(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 300 new mojo::runner::LinuxSandbox(permissions)); | 288 new mojo::runner::LinuxSandbox(permissions)); |
| 301 sandbox->Warmup(); | 289 sandbox->Warmup(); |
| 302 sandbox->EngageNamespaceSandbox(); | 290 sandbox->EngageNamespaceSandbox(); |
| 303 sandbox->EngageSeccompSandbox(); | 291 sandbox->EngageSeccompSandbox(); |
| 304 sandbox->Seal(); | 292 sandbox->Seal(); |
| 305 return sandbox; | 293 return sandbox; |
| 306 } | 294 } |
| 307 #endif | 295 #endif |
| 308 | 296 |
| 309 ScopedMessagePipeHandle InitializeHostMessagePipe( | 297 ScopedMessagePipeHandle InitializeHostMessagePipe( |
| 310 embedder::ScopedPlatformHandle platform_channel, | 298 edk::ScopedPlatformHandle platform_channel, |
| 311 scoped_refptr<base::TaskRunner> io_task_runner) { | 299 scoped_refptr<base::TaskRunner> io_task_runner) { |
| 312 ScopedMessagePipeHandle host_message_pipe( | 300 ScopedMessagePipeHandle host_message_pipe(edk::CreateMessagePipe( |
| 313 embedder::CreateChannel(std::move(platform_channel), | 301 std::move(platform_channel))); |
| 314 base::Bind(&DidCreateChannel), io_task_runner)); | |
| 315 | 302 |
| 316 if (base::CommandLine::ForCurrentProcess()->HasSwitch("use-new-edk")) { | 303 // When using the new Mojo EDK, each message pipe is backed by a platform |
| 317 // When using the new Mojo EDK, each message pipe is backed by a platform | 304 // handle. The one platform handle that comes on the command line is used |
| 318 // handle. The one platform handle that comes on the command line is used | 305 // to bind to the ChildController interface. However we also want a |
| 319 // to bind to the ChildController interface. However we also want a | 306 // platform handle to setup the communication channel by which we exchange |
| 320 // platform handle to setup the communication channel by which we exchange | 307 // handles to/from tokens, which is needed for sandboxed Windows |
| 321 // handles to/from tokens, which is needed for sandboxed Windows | 308 // processes. |
| 322 // processes. | 309 char broker_handle[10]; |
| 323 char broker_handle[10]; | 310 MojoHandleSignalsState state; |
| 324 MojoHandleSignalsState state; | 311 MojoResult rv = |
| 325 MojoResult rv = | 312 MojoWait(host_message_pipe.get().value(), MOJO_HANDLE_SIGNAL_READABLE, |
| 326 MojoWait(host_message_pipe.get().value(), MOJO_HANDLE_SIGNAL_READABLE, | 313 MOJO_DEADLINE_INDEFINITE, &state); |
| 327 MOJO_DEADLINE_INDEFINITE, &state); | 314 CHECK_EQ(MOJO_RESULT_OK, rv); |
| 328 CHECK_EQ(MOJO_RESULT_OK, rv); | 315 uint32_t num_bytes = arraysize(broker_handle); |
| 329 uint32_t num_bytes = arraysize(broker_handle); | 316 rv = MojoReadMessage(host_message_pipe.get().value(), |
| 330 rv = MojoReadMessage(host_message_pipe.get().value(), | 317 broker_handle, &num_bytes, nullptr, 0, |
| 331 broker_handle, &num_bytes, nullptr, 0, | 318 MOJO_READ_MESSAGE_FLAG_NONE); |
| 332 MOJO_READ_MESSAGE_FLAG_NONE); | 319 CHECK_EQ(MOJO_RESULT_OK, rv); |
| 333 CHECK_EQ(MOJO_RESULT_OK, rv); | |
| 334 | 320 |
| 335 edk::ScopedPlatformHandle broker_channel = | 321 edk::ScopedPlatformHandle broker_channel = |
| 336 edk::PlatformChannelPair::PassClientHandleFromParentProcessFromString( | 322 edk::PlatformChannelPair::PassClientHandleFromParentProcessFromString( |
| 337 std::string(broker_handle, num_bytes)); | 323 std::string(broker_handle, num_bytes)); |
| 338 CHECK(broker_channel.is_valid()); | 324 CHECK(broker_channel.is_valid()); |
| 339 embedder::SetParentPipeHandle( | 325 edk::SetParentPipeHandle(std::move(broker_channel)) ; |
| 340 mojo::embedder::ScopedPlatformHandle(mojo::embedder::PlatformHandle( | |
| 341 broker_channel.release().handle))); | |
| 342 } | |
| 343 | 326 |
| 344 return host_message_pipe; | 327 return host_message_pipe; |
| 345 } | 328 } |
| 346 | 329 |
| 347 } // namespace | 330 } // namespace |
| 348 | 331 |
| 349 int ChildProcessMain() { | 332 int ChildProcessMain() { |
| 350 DVLOG(2) << "ChildProcessMain()"; | 333 DVLOG(2) << "ChildProcessMain()"; |
| 351 const base::CommandLine& command_line = | 334 const base::CommandLine& command_line = |
| 352 *base::CommandLine::ForCurrentProcess(); | 335 *base::CommandLine::ForCurrentProcess(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 364 #if !defined(OFFICIAL_BUILD) | 347 #if !defined(OFFICIAL_BUILD) |
| 365 // Initialize stack dumping just before initializing sandbox to make | 348 // Initialize stack dumping just before initializing sandbox to make |
| 366 // sure symbol names in all loaded libraries will be cached. | 349 // sure symbol names in all loaded libraries will be cached. |
| 367 base::debug::EnableInProcessStackDumping(); | 350 base::debug::EnableInProcessStackDumping(); |
| 368 #endif | 351 #endif |
| 369 #if defined(OS_LINUX) && !defined(OS_ANDROID) | 352 #if defined(OS_LINUX) && !defined(OS_ANDROID) |
| 370 if (command_line.HasSwitch(switches::kEnableSandbox)) | 353 if (command_line.HasSwitch(switches::kEnableSandbox)) |
| 371 sandbox = InitializeSandbox(); | 354 sandbox = InitializeSandbox(); |
| 372 #endif | 355 #endif |
| 373 | 356 |
| 374 embedder::ScopedPlatformHandle platform_channel = | 357 edk::ScopedPlatformHandle platform_channel = |
| 375 embedder::PlatformChannelPair::PassClientHandleFromParentProcess( | 358 edk::PlatformChannelPair::PassClientHandleFromParentProcess( |
| 376 command_line); | 359 command_line); |
| 377 CHECK(platform_channel.is_valid()); | 360 CHECK(platform_channel.is_valid()); |
| 378 | 361 |
| 379 DCHECK(!base::MessageLoop::current()); | 362 DCHECK(!base::MessageLoop::current()); |
| 380 | 363 |
| 381 AppContext app_context; | 364 AppContext app_context; |
| 382 app_context.Init(); | 365 app_context.Init(); |
| 383 ScopedMessagePipeHandle host_message_pipe = InitializeHostMessagePipe( | 366 ScopedMessagePipeHandle host_message_pipe = InitializeHostMessagePipe( |
| 384 std::move(platform_channel), app_context.io_runner()); | 367 std::move(platform_channel), app_context.io_runner()); |
| 385 app_context.StartControllerThread(); | 368 app_context.StartControllerThread(); |
| 386 Blocker blocker; | 369 Blocker blocker; |
| 387 app_context.controller_runner()->PostTask( | 370 app_context.controller_runner()->PostTask( |
| 388 FROM_HERE, | 371 FROM_HERE, |
| 389 base::Bind(&ChildControllerImpl::Init, base::Unretained(&app_context), | 372 base::Bind(&ChildControllerImpl::Init, base::Unretained(&app_context), |
| 390 base::Unretained(app_library), | 373 base::Unretained(app_library), |
| 391 base::Passed(&host_message_pipe), blocker.GetUnblocker())); | 374 base::Passed(&host_message_pipe), blocker.GetUnblocker())); |
| 392 // This will block, then run whatever the controller wants. | 375 // This will block, then run whatever the controller wants. |
| 393 blocker.Block(); | 376 blocker.Block(); |
| 394 | 377 |
| 395 app_context.Shutdown(); | 378 app_context.Shutdown(); |
| 396 | 379 |
| 397 return 0; | 380 return 0; |
| 398 } | 381 } |
| 399 | 382 |
| 400 } // namespace runner | 383 } // namespace runner |
| 401 } // namespace mojo | 384 } // namespace mojo |
| OLD | NEW |