James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 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. |
| 4 | |
Viet-Trung Luu | f3e4e33 | 2015-03-03 14:11:14 -0800 | [diff] [blame] | 5 | #include <unistd.h> |
| 6 | |
Viet-Trung Luu | e0a4a18 | 2015-04-07 16:28:01 -0700 | [diff] [blame] | 7 | #include "base/at_exit.h" |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 8 | #include "base/bind.h" |
| 9 | #include "base/callback_helpers.h" |
Viet-Trung Luu | 1e23c67 | 2015-04-01 14:46:29 -0700 | [diff] [blame] | 10 | #include "base/command_line.h" |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 11 | #include "base/files/file_path.h" |
| 12 | #include "base/location.h" |
| 13 | #include "base/logging.h" |
| 14 | #include "base/macros.h" |
| 15 | #include "base/memory/ref_counted.h" |
| 16 | #include "base/memory/scoped_ptr.h" |
| 17 | #include "base/message_loop/message_loop.h" |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 18 | #include "base/single_thread_task_runner.h" |
| 19 | #include "base/synchronization/waitable_event.h" |
| 20 | #include "base/threading/thread.h" |
| 21 | #include "base/threading/thread_checker.h" |
| 22 | #include "mojo/common/message_pump_mojo.h" |
| 23 | #include "mojo/edk/embedder/embedder.h" |
Viet-Trung Luu | 1e23c67 | 2015-04-01 14:46:29 -0700 | [diff] [blame] | 24 | #include "mojo/edk/embedder/platform_channel_pair.h" |
Viet-Trung Luu | f3e4e33 | 2015-03-03 14:11:14 -0800 | [diff] [blame] | 25 | #include "mojo/edk/embedder/process_delegate.h" |
Viet-Trung Luu | 1e23c67 | 2015-04-01 14:46:29 -0700 | [diff] [blame] | 26 | #include "mojo/edk/embedder/scoped_platform_handle.h" |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 27 | #include "mojo/edk/embedder/simple_platform_support.h" |
| 28 | #include "mojo/public/cpp/system/core.h" |
Viet-Trung Luu | f09c0d9 | 2015-04-01 14:38:57 -0700 | [diff] [blame] | 29 | #include "shell/child_controller.mojom.h" |
Viet-Trung Luu | e0a4a18 | 2015-04-07 16:28:01 -0700 | [diff] [blame] | 30 | #include "shell/init.h" |
Viet-Trung Luu | e126c86 | 2015-03-30 19:20:45 -0700 | [diff] [blame] | 31 | #include "shell/native_application_support.h" |
Viet-Trung Luu | e0a4a18 | 2015-04-07 16:28:01 -0700 | [diff] [blame] | 32 | #include "shell/switches.h" |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 33 | |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 34 | namespace shell { |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 35 | namespace { |
| 36 | |
| 37 | // Blocker --------------------------------------------------------------------- |
| 38 | |
| 39 | // Blocks a thread until another thread unblocks it, at which point it unblocks |
| 40 | // and runs a closure provided by that thread. |
| 41 | class Blocker { |
| 42 | public: |
| 43 | class Unblocker { |
| 44 | public: |
Viet-Trung Luu | f3e4e33 | 2015-03-03 14:11:14 -0800 | [diff] [blame] | 45 | explicit Unblocker(Blocker* blocker = nullptr) : blocker_(blocker) {} |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 46 | ~Unblocker() {} |
| 47 | |
| 48 | void Unblock(base::Closure run_after) { |
| 49 | DCHECK(blocker_); |
| 50 | DCHECK(blocker_->run_after_.is_null()); |
| 51 | blocker_->run_after_ = run_after; |
| 52 | blocker_->event_.Signal(); |
Viet-Trung Luu | f3e4e33 | 2015-03-03 14:11:14 -0800 | [diff] [blame] | 53 | blocker_ = nullptr; |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 54 | } |
| 55 | |
| 56 | private: |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 57 | Blocker* blocker_; |
| 58 | |
| 59 | // Copy and assign allowed. |
| 60 | }; |
| 61 | |
| 62 | Blocker() : event_(true, false) {} |
| 63 | ~Blocker() {} |
| 64 | |
| 65 | void Block() { |
| 66 | DCHECK(run_after_.is_null()); |
| 67 | event_.Wait(); |
Viet-Trung Luu | 2629298 | 2015-04-14 18:06:55 -0700 | [diff] [blame] | 68 | if (!run_after_.is_null()) |
| 69 | run_after_.Run(); |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 70 | } |
| 71 | |
James Robinson | b4b7af2 | 2014-12-05 11:21:01 -0800 | [diff] [blame] | 72 | Unblocker GetUnblocker() { return Unblocker(this); } |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 73 | |
| 74 | private: |
| 75 | base::WaitableEvent event_; |
| 76 | base::Closure run_after_; |
| 77 | |
| 78 | DISALLOW_COPY_AND_ASSIGN(Blocker); |
| 79 | }; |
| 80 | |
| 81 | // AppContext ------------------------------------------------------------------ |
| 82 | |
Viet-Trung Luu | f09c0d9 | 2015-04-01 14:38:57 -0700 | [diff] [blame] | 83 | class ChildControllerImpl; |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 84 | |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 85 | // Should be created and initialized on the main thread. |
Viet-Trung Luu | bd07e3a | 2015-04-09 12:43:29 -0700 | [diff] [blame] | 86 | class AppContext : public mojo::embedder::ProcessDelegate { |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 87 | public: |
| 88 | AppContext() |
James Robinson | b4b7af2 | 2014-12-05 11:21:01 -0800 | [diff] [blame] | 89 | : io_thread_("io_thread"), controller_thread_("controller_thread") {} |
Dave Moore | cc0e4f9 | 2015-03-10 15:23:04 -0700 | [diff] [blame] | 90 | ~AppContext() override {} |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 91 | |
| 92 | void Init() { |
| 93 | // Initialize Mojo before starting any threads. |
Viet-Trung Luu | bd07e3a | 2015-04-09 12:43:29 -0700 | [diff] [blame] | 94 | mojo::embedder::Init( |
| 95 | make_scoped_ptr(new mojo::embedder::SimplePlatformSupport())); |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 96 | |
| 97 | // Create and start our I/O thread. |
| 98 | base::Thread::Options io_thread_options(base::MessageLoop::TYPE_IO, 0); |
| 99 | CHECK(io_thread_.StartWithOptions(io_thread_options)); |
| 100 | io_runner_ = io_thread_.message_loop_proxy().get(); |
| 101 | CHECK(io_runner_.get()); |
| 102 | |
| 103 | // Create and start our controller thread. |
| 104 | base::Thread::Options controller_thread_options; |
| 105 | controller_thread_options.message_loop_type = |
| 106 | base::MessageLoop::TYPE_CUSTOM; |
| 107 | controller_thread_options.message_pump_factory = |
Viet-Trung Luu | bd07e3a | 2015-04-09 12:43:29 -0700 | [diff] [blame] | 108 | base::Bind(&mojo::common::MessagePumpMojo::Create); |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 109 | CHECK(controller_thread_.StartWithOptions(controller_thread_options)); |
| 110 | controller_runner_ = controller_thread_.message_loop_proxy().get(); |
| 111 | CHECK(controller_runner_.get()); |
Viet-Trung Luu | f3e4e33 | 2015-03-03 14:11:14 -0800 | [diff] [blame] | 112 | |
| 113 | // TODO(vtl): This should be SLAVE, not NONE. |
Viet-Trung Luu | bd07e3a | 2015-04-09 12:43:29 -0700 | [diff] [blame] | 114 | mojo::embedder::InitIPCSupport(mojo::embedder::ProcessType::NONE, |
| 115 | controller_runner_, this, io_runner_, |
| 116 | mojo::embedder::ScopedPlatformHandle()); |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 117 | } |
| 118 | |
| 119 | void Shutdown() { |
Viet-Trung Luu | f3e4e33 | 2015-03-03 14:11:14 -0800 | [diff] [blame] | 120 | Blocker blocker; |
| 121 | shutdown_unblocker_ = blocker.GetUnblocker(); |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 122 | controller_runner_->PostTask( |
Viet-Trung Luu | f3e4e33 | 2015-03-03 14:11:14 -0800 | [diff] [blame] | 123 | FROM_HERE, base::Bind(&AppContext::ShutdownOnControllerThread, |
| 124 | base::Unretained(this))); |
| 125 | blocker.Block(); |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 126 | } |
| 127 | |
James Robinson | b4b7af2 | 2014-12-05 11:21:01 -0800 | [diff] [blame] | 128 | base::SingleThreadTaskRunner* io_runner() const { return io_runner_.get(); } |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 129 | |
| 130 | base::SingleThreadTaskRunner* controller_runner() const { |
| 131 | return controller_runner_.get(); |
| 132 | } |
| 133 | |
Viet-Trung Luu | f09c0d9 | 2015-04-01 14:38:57 -0700 | [diff] [blame] | 134 | ChildControllerImpl* controller() const { return controller_.get(); } |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 135 | |
Viet-Trung Luu | f09c0d9 | 2015-04-01 14:38:57 -0700 | [diff] [blame] | 136 | void set_controller(scoped_ptr<ChildControllerImpl> controller) { |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 137 | controller_ = controller.Pass(); |
| 138 | } |
| 139 | |
| 140 | private: |
Viet-Trung Luu | f3e4e33 | 2015-03-03 14:11:14 -0800 | [diff] [blame] | 141 | void ShutdownOnControllerThread() { |
| 142 | // First, destroy the controller. |
| 143 | controller_.reset(); |
| 144 | |
| 145 | // Next shutdown IPC. We'll unblock the main thread in OnShutdownComplete(). |
Viet-Trung Luu | bd07e3a | 2015-04-09 12:43:29 -0700 | [diff] [blame] | 146 | mojo::embedder::ShutdownIPCSupport(); |
Viet-Trung Luu | f3e4e33 | 2015-03-03 14:11:14 -0800 | [diff] [blame] | 147 | } |
| 148 | |
| 149 | // ProcessDelegate implementation. |
| 150 | void OnShutdownComplete() override { |
| 151 | shutdown_unblocker_.Unblock(base::Closure()); |
| 152 | } |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 153 | |
| 154 | base::Thread io_thread_; |
| 155 | scoped_refptr<base::SingleThreadTaskRunner> io_runner_; |
| 156 | |
| 157 | base::Thread controller_thread_; |
| 158 | scoped_refptr<base::SingleThreadTaskRunner> controller_runner_; |
| 159 | |
Viet-Trung Luu | f3e4e33 | 2015-03-03 14:11:14 -0800 | [diff] [blame] | 160 | // Accessed only on the controller thread. |
Viet-Trung Luu | f09c0d9 | 2015-04-01 14:38:57 -0700 | [diff] [blame] | 161 | scoped_ptr<ChildControllerImpl> controller_; |
Viet-Trung Luu | f3e4e33 | 2015-03-03 14:11:14 -0800 | [diff] [blame] | 162 | |
| 163 | // Used to unblock the main thread on shutdown. |
| 164 | Blocker::Unblocker shutdown_unblocker_; |
| 165 | |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 166 | DISALLOW_COPY_AND_ASSIGN(AppContext); |
| 167 | }; |
| 168 | |
Viet-Trung Luu | f09c0d9 | 2015-04-01 14:38:57 -0700 | [diff] [blame] | 169 | // ChildControllerImpl --------------------------------------------------------- |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 170 | |
Viet-Trung Luu | bd07e3a | 2015-04-09 12:43:29 -0700 | [diff] [blame] | 171 | class ChildControllerImpl : public ChildController, public mojo::ErrorHandler { |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 172 | public: |
Viet-Trung Luu | f09c0d9 | 2015-04-01 14:38:57 -0700 | [diff] [blame] | 173 | ~ChildControllerImpl() override { |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 174 | DCHECK(thread_checker_.CalledOnValidThread()); |
| 175 | |
| 176 | // TODO(vtl): Pass in the result from |MainMain()|. |
Benjamin Lerman | ab0a8dd | 2015-02-05 12:56:09 +0100 | [diff] [blame] | 177 | on_app_complete_.Run(MOJO_RESULT_UNIMPLEMENTED); |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 178 | } |
| 179 | |
Viet-Trung Luu | f09c0d9 | 2015-04-01 14:38:57 -0700 | [diff] [blame] | 180 | // To be executed on the controller thread. Creates the |ChildController|, |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 181 | // etc. |
James Robinson | b4b7af2 | 2014-12-05 11:21:01 -0800 | [diff] [blame] | 182 | static void Init(AppContext* app_context, |
Viet-Trung Luu | bd07e3a | 2015-04-09 12:43:29 -0700 | [diff] [blame] | 183 | mojo::embedder::ScopedPlatformHandle platform_channel, |
James Robinson | b4b7af2 | 2014-12-05 11:21:01 -0800 | [diff] [blame] | 184 | const Blocker::Unblocker& unblocker) { |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 185 | DCHECK(app_context); |
| 186 | DCHECK(platform_channel.is_valid()); |
| 187 | |
| 188 | DCHECK(!app_context->controller()); |
| 189 | |
Viet-Trung Luu | f09c0d9 | 2015-04-01 14:38:57 -0700 | [diff] [blame] | 190 | scoped_ptr<ChildControllerImpl> impl( |
| 191 | new ChildControllerImpl(app_context, unblocker)); |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 192 | |
Viet-Trung Luu | bd07e3a | 2015-04-09 12:43:29 -0700 | [diff] [blame] | 193 | mojo::ScopedMessagePipeHandle host_message_pipe( |
| 194 | mojo::embedder::CreateChannel( |
| 195 | platform_channel.Pass(), app_context->io_runner(), |
| 196 | base::Bind(&ChildControllerImpl::DidCreateChannel, |
| 197 | base::Unretained(impl.get())), |
| 198 | base::MessageLoopProxy::current())); |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 199 | |
James Robinson | f2a8720 | 2015-02-12 17:03:49 -0800 | [diff] [blame] | 200 | impl->Bind(host_message_pipe.Pass()); |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 201 | |
| 202 | app_context->set_controller(impl.Pass()); |
| 203 | } |
| 204 | |
Viet-Trung Luu | bd07e3a | 2015-04-09 12:43:29 -0700 | [diff] [blame] | 205 | void Bind(mojo::ScopedMessagePipeHandle handle) { |
| 206 | binding_.Bind(handle.Pass()); |
| 207 | } |
James Robinson | f2a8720 | 2015-02-12 17:03:49 -0800 | [diff] [blame] | 208 | |
Viet-Trung Luu | bd07e3a | 2015-04-09 12:43:29 -0700 | [diff] [blame] | 209 | // |mojo::ErrorHandler| methods: |
James Robinson | e1b30cf | 2014-10-21 12:25:40 -0700 | [diff] [blame] | 210 | void OnConnectionError() override { |
Benjamin Lerman | ab0a8dd | 2015-02-05 12:56:09 +0100 | [diff] [blame] | 211 | // A connection error means the connection to the shell is lost. This is not |
| 212 | // recoverable. |
Viet-Trung Luu | f3e4e33 | 2015-03-03 14:11:14 -0800 | [diff] [blame] | 213 | LOG(ERROR) << "Connection error to the shell."; |
| 214 | _exit(1); |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 215 | } |
| 216 | |
Viet-Trung Luu | f09c0d9 | 2015-04-01 14:38:57 -0700 | [diff] [blame] | 217 | // |ChildController| methods: |
Viet-Trung Luu | bd07e3a | 2015-04-09 12:43:29 -0700 | [diff] [blame] | 218 | void StartApp(const mojo::String& app_path, |
Viet-Trung Luu | bd07e3a | 2015-04-09 12:43:29 -0700 | [diff] [blame] | 219 | mojo::InterfaceRequest<mojo::Application> application_request, |
Benjamin Lerman | ab0a8dd | 2015-02-05 12:56:09 +0100 | [diff] [blame] | 220 | const StartAppCallback& on_app_complete) override { |
Viet-Trung Luu | f09c0d9 | 2015-04-01 14:38:57 -0700 | [diff] [blame] | 221 | DVLOG(2) << "ChildControllerImpl::StartApp(" << app_path << ", ...)"; |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 222 | DCHECK(thread_checker_.CalledOnValidThread()); |
| 223 | |
Benjamin Lerman | ab0a8dd | 2015-02-05 12:56:09 +0100 | [diff] [blame] | 224 | on_app_complete_ = on_app_complete; |
Viet-Trung Luu | f09c0d9 | 2015-04-01 14:38:57 -0700 | [diff] [blame] | 225 | unblocker_.Unblock(base::Bind(&ChildControllerImpl::StartAppOnMainThread, |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 226 | base::FilePath::FromUTF8Unsafe(app_path), |
James Robinson | e5ae9e4 | 2015-01-26 17:53:08 -0800 | [diff] [blame] | 227 | base::Passed(&application_request))); |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 228 | } |
| 229 | |
Viet-Trung Luu | 6d948cc | 2015-03-31 10:48:02 -0700 | [diff] [blame] | 230 | void ExitNow(int32_t exit_code) override { |
Viet-Trung Luu | f09c0d9 | 2015-04-01 14:38:57 -0700 | [diff] [blame] | 231 | DVLOG(2) << "ChildControllerImpl::ExitNow(" << exit_code << ")"; |
Viet-Trung Luu | 6d948cc | 2015-03-31 10:48:02 -0700 | [diff] [blame] | 232 | _exit(exit_code); |
| 233 | } |
| 234 | |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 235 | private: |
Viet-Trung Luu | f09c0d9 | 2015-04-01 14:38:57 -0700 | [diff] [blame] | 236 | ChildControllerImpl(AppContext* app_context, |
| 237 | const Blocker::Unblocker& unblocker) |
James Robinson | f2a8720 | 2015-02-12 17:03:49 -0800 | [diff] [blame] | 238 | : app_context_(app_context), |
| 239 | unblocker_(unblocker), |
| 240 | channel_info_(nullptr), |
| 241 | binding_(this) { |
| 242 | binding_.set_error_handler(this); |
| 243 | } |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 244 | |
Viet-Trung Luu | bd07e3a | 2015-04-09 12:43:29 -0700 | [diff] [blame] | 245 | // Callback for |mojo::embedder::CreateChannel()|. |
| 246 | void DidCreateChannel(mojo::embedder::ChannelInfo* channel_info) { |
Viet-Trung Luu | f09c0d9 | 2015-04-01 14:38:57 -0700 | [diff] [blame] | 247 | DVLOG(2) << "ChildControllerImpl::DidCreateChannel()"; |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 248 | DCHECK(thread_checker_.CalledOnValidThread()); |
| 249 | channel_info_ = channel_info; |
| 250 | } |
| 251 | |
James Robinson | e5ae9e4 | 2015-01-26 17:53:08 -0800 | [diff] [blame] | 252 | static void StartAppOnMainThread( |
| 253 | const base::FilePath& app_path, |
Viet-Trung Luu | bd07e3a | 2015-04-09 12:43:29 -0700 | [diff] [blame] | 254 | mojo::InterfaceRequest<mojo::Application> application_request) { |
Viet-Trung Luu | 47e2e35 | 2015-03-04 16:38:18 -0800 | [diff] [blame] | 255 | // TODO(vtl): This is copied from in_process_native_runner.cc. |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 256 | DVLOG(2) << "Loading/running Mojo app from " << app_path.value() |
| 257 | << " out of process"; |
| 258 | |
Dave Moore | 3a99b93 | 2014-10-30 08:38:23 -0700 | [diff] [blame] | 259 | // We intentionally don't unload the native library as its lifetime is the |
| 260 | // same as that of the process. |
Benjamin Lerman | 5d429aa | 2015-05-07 16:21:00 +0200 | [diff] [blame] | 261 | base::NativeLibrary app_library = LoadNativeApplication(app_path); |
Viet-Trung Luu | e126c86 | 2015-03-30 19:20:45 -0700 | [diff] [blame] | 262 | RunNativeApplication(app_library, application_request.Pass()); |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 263 | } |
| 264 | |
| 265 | base::ThreadChecker thread_checker_; |
| 266 | AppContext* const app_context_; |
| 267 | Blocker::Unblocker unblocker_; |
Benjamin Lerman | ab0a8dd | 2015-02-05 12:56:09 +0100 | [diff] [blame] | 268 | StartAppCallback on_app_complete_; |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 269 | |
Viet-Trung Luu | bd07e3a | 2015-04-09 12:43:29 -0700 | [diff] [blame] | 270 | mojo::embedder::ChannelInfo* channel_info_; |
| 271 | mojo::Binding<ChildController> binding_; |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 272 | |
Viet-Trung Luu | f09c0d9 | 2015-04-01 14:38:57 -0700 | [diff] [blame] | 273 | DISALLOW_COPY_AND_ASSIGN(ChildControllerImpl); |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 274 | }; |
| 275 | |
| 276 | } // namespace |
Viet-Trung Luu | e0a4a18 | 2015-04-07 16:28:01 -0700 | [diff] [blame] | 277 | } // namespace shell |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 278 | |
Viet-Trung Luu | e0a4a18 | 2015-04-07 16:28:01 -0700 | [diff] [blame] | 279 | int main(int argc, char** argv) { |
| 280 | base::AtExitManager at_exit; |
| 281 | base::CommandLine::Init(argc, argv); |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 282 | |
Viet-Trung Luu | bd07e3a | 2015-04-09 12:43:29 -0700 | [diff] [blame] | 283 | shell::InitializeLogging(); |
Viet-Trung Luu | 6d948cc | 2015-03-31 10:48:02 -0700 | [diff] [blame] | 284 | |
Viet-Trung Luu | e0a4a18 | 2015-04-07 16:28:01 -0700 | [diff] [blame] | 285 | // Make sure that we're really meant to be invoked as the child process. |
| 286 | CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 287 | switches::kChildProcess)); |
| 288 | |
| 289 | mojo::embedder::ScopedPlatformHandle platform_channel = |
| 290 | mojo::embedder::PlatformChannelPair::PassClientHandleFromParentProcess( |
Viet-Trung Luu | 1e23c67 | 2015-04-01 14:46:29 -0700 | [diff] [blame] | 291 | *base::CommandLine::ForCurrentProcess()); |
| 292 | CHECK(platform_channel.is_valid()); |
| 293 | |
Viet-Trung Luu | bd07e3a | 2015-04-09 12:43:29 -0700 | [diff] [blame] | 294 | shell::AppContext app_context; |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 295 | app_context.Init(); |
| 296 | |
Viet-Trung Luu | bd07e3a | 2015-04-09 12:43:29 -0700 | [diff] [blame] | 297 | shell::Blocker blocker; |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 298 | app_context.controller_runner()->PostTask( |
| 299 | FROM_HERE, |
Viet-Trung Luu | bd07e3a | 2015-04-09 12:43:29 -0700 | [diff] [blame] | 300 | base::Bind(&shell::ChildControllerImpl::Init, |
Viet-Trung Luu | e0a4a18 | 2015-04-07 16:28:01 -0700 | [diff] [blame] | 301 | base::Unretained(&app_context), |
Viet-Trung Luu | 1e23c67 | 2015-04-01 14:46:29 -0700 | [diff] [blame] | 302 | base::Passed(&platform_channel), blocker.GetUnblocker())); |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 303 | // This will block, then run whatever the controller wants. |
| 304 | blocker.Block(); |
| 305 | |
| 306 | app_context.Shutdown(); |
Viet-Trung Luu | 1e23c67 | 2015-04-01 14:46:29 -0700 | [diff] [blame] | 307 | |
| 308 | return 0; |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 309 | } |