| 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/child_process.h" | 5 #include "mojo/runner/child_process.h" |
| 6 | 6 |
| 7 #include "base/base_switches.h" | 7 #include "base/base_switches.h" |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/callback_helpers.h" | 9 #include "base/callback_helpers.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 ~ChildControllerImpl() override { | 175 ~ChildControllerImpl() override { |
| 176 DCHECK(thread_checker_.CalledOnValidThread()); | 176 DCHECK(thread_checker_.CalledOnValidThread()); |
| 177 | 177 |
| 178 // TODO(vtl): Pass in the result from |MainMain()|. | 178 // TODO(vtl): Pass in the result from |MainMain()|. |
| 179 on_app_complete_.Run(MOJO_RESULT_UNIMPLEMENTED); | 179 on_app_complete_.Run(MOJO_RESULT_UNIMPLEMENTED); |
| 180 } | 180 } |
| 181 | 181 |
| 182 // To be executed on the controller thread. Creates the |ChildController|, | 182 // To be executed on the controller thread. Creates the |ChildController|, |
| 183 // etc. | 183 // etc. |
| 184 static void Init(AppContext* app_context, | 184 static void Init(AppContext* app_context, |
| 185 base::NativeLibrary app_library, |
| 185 embedder::ScopedPlatformHandle platform_channel, | 186 embedder::ScopedPlatformHandle platform_channel, |
| 186 const Blocker::Unblocker& unblocker) { | 187 const Blocker::Unblocker& unblocker) { |
| 187 DCHECK(app_context); | 188 DCHECK(app_context); |
| 188 DCHECK(platform_channel.is_valid()); | 189 DCHECK(platform_channel.is_valid()); |
| 189 | 190 |
| 190 DCHECK(!app_context->controller()); | 191 DCHECK(!app_context->controller()); |
| 191 | 192 |
| 192 scoped_ptr<ChildControllerImpl> impl( | 193 scoped_ptr<ChildControllerImpl> impl( |
| 193 new ChildControllerImpl(app_context, unblocker)); | 194 new ChildControllerImpl(app_context, app_library, unblocker)); |
| 194 | 195 |
| 195 ScopedMessagePipeHandle host_message_pipe(embedder::CreateChannel( | 196 ScopedMessagePipeHandle host_message_pipe(embedder::CreateChannel( |
| 196 platform_channel.Pass(), | 197 platform_channel.Pass(), |
| 197 base::Bind(&ChildControllerImpl::DidCreateChannel, | 198 base::Bind(&ChildControllerImpl::DidCreateChannel, |
| 198 base::Unretained(impl.get())), | 199 base::Unretained(impl.get())), |
| 199 base::ThreadTaskRunnerHandle::Get())); | 200 base::ThreadTaskRunnerHandle::Get())); |
| 200 | 201 |
| 201 impl->Bind(host_message_pipe.Pass()); | 202 impl->Bind(host_message_pipe.Pass()); |
| 202 | 203 |
| 203 app_context->set_controller(impl.Pass()); | 204 app_context->set_controller(impl.Pass()); |
| 204 } | 205 } |
| 205 | 206 |
| 206 void Bind(ScopedMessagePipeHandle handle) { binding_.Bind(handle.Pass()); } | 207 void Bind(ScopedMessagePipeHandle handle) { binding_.Bind(handle.Pass()); } |
| 207 | 208 |
| 208 void OnConnectionError() { | 209 void OnConnectionError() { |
| 209 // A connection error means the connection to the shell is lost. This is not | 210 // A connection error means the connection to the shell is lost. This is not |
| 210 // recoverable. | 211 // recoverable. |
| 211 LOG(ERROR) << "Connection error to the shell."; | 212 LOG(ERROR) << "Connection error to the shell."; |
| 212 _exit(1); | 213 _exit(1); |
| 213 } | 214 } |
| 214 | 215 |
| 215 // |ChildController| methods: | 216 // |ChildController| methods: |
| 216 void StartApp(const String& app_path, | 217 void StartApp(InterfaceRequest<Application> application_request, |
| 217 bool clean_app_path, | |
| 218 InterfaceRequest<Application> application_request, | |
| 219 const StartAppCallback& on_app_complete) override { | 218 const StartAppCallback& on_app_complete) override { |
| 220 DVLOG(2) << "ChildControllerImpl::StartApp(" << app_path << ", ...)"; | |
| 221 DCHECK(thread_checker_.CalledOnValidThread()); | 219 DCHECK(thread_checker_.CalledOnValidThread()); |
| 222 | 220 |
| 223 on_app_complete_ = on_app_complete; | 221 on_app_complete_ = on_app_complete; |
| 224 unblocker_.Unblock(base::Bind( | 222 unblocker_.Unblock(base::Bind(&ChildControllerImpl::StartAppOnMainThread, |
| 225 &ChildControllerImpl::StartAppOnMainThread, | 223 base::Unretained(app_library_), |
| 226 base::FilePath::FromUTF8Unsafe(app_path), | 224 base::Passed(&application_request))); |
| 227 clean_app_path ? shell::NativeApplicationCleanup::DELETE | |
| 228 : shell::NativeApplicationCleanup::DONT_DELETE, | |
| 229 base::Passed(&application_request))); | |
| 230 } | 225 } |
| 231 | 226 |
| 232 void ExitNow(int32_t exit_code) override { | 227 void ExitNow(int32_t exit_code) override { |
| 233 DVLOG(2) << "ChildControllerImpl::ExitNow(" << exit_code << ")"; | 228 DVLOG(2) << "ChildControllerImpl::ExitNow(" << exit_code << ")"; |
| 234 _exit(exit_code); | 229 _exit(exit_code); |
| 235 } | 230 } |
| 236 | 231 |
| 237 private: | 232 private: |
| 238 ChildControllerImpl(AppContext* app_context, | 233 ChildControllerImpl(AppContext* app_context, |
| 234 base::NativeLibrary app_library, |
| 239 const Blocker::Unblocker& unblocker) | 235 const Blocker::Unblocker& unblocker) |
| 240 : app_context_(app_context), | 236 : app_context_(app_context), |
| 237 app_library_(app_library), |
| 241 unblocker_(unblocker), | 238 unblocker_(unblocker), |
| 242 channel_info_(nullptr), | 239 channel_info_(nullptr), |
| 243 binding_(this) { | 240 binding_(this) { |
| 244 binding_.set_connection_error_handler([this]() { OnConnectionError(); }); | 241 binding_.set_connection_error_handler([this]() { OnConnectionError(); }); |
| 245 } | 242 } |
| 246 | 243 |
| 247 // Callback for |embedder::CreateChannel()|. | 244 // Callback for |embedder::CreateChannel()|. |
| 248 void DidCreateChannel(embedder::ChannelInfo* channel_info) { | 245 void DidCreateChannel(embedder::ChannelInfo* channel_info) { |
| 249 DVLOG(2) << "ChildControllerImpl::DidCreateChannel()"; | 246 DVLOG(2) << "ChildControllerImpl::DidCreateChannel()"; |
| 250 DCHECK(thread_checker_.CalledOnValidThread()); | 247 DCHECK(thread_checker_.CalledOnValidThread()); |
| 251 channel_info_ = channel_info; | 248 channel_info_ = channel_info; |
| 252 } | 249 } |
| 253 | 250 |
| 254 static void StartAppOnMainThread( | 251 static void StartAppOnMainThread( |
| 255 const base::FilePath& app_path, | 252 base::NativeLibrary app_library, |
| 256 shell::NativeApplicationCleanup cleanup, | |
| 257 InterfaceRequest<Application> application_request) { | 253 InterfaceRequest<Application> application_request) { |
| 258 // TODO(vtl): This is copied from in_process_native_runner.cc. | 254 if (!RunNativeApplication(app_library, application_request.Pass())) { |
| 259 DVLOG(2) << "Loading/running Mojo app from " << app_path.value() | 255 LOG(ERROR) << "Failure to RunNativeApplication()"; |
| 260 << " out of process"; | 256 } |
| 261 | |
| 262 // We intentionally don't unload the native library as its lifetime is the | |
| 263 // same as that of the process. | |
| 264 base::NativeLibrary app_library = LoadNativeApplication(app_path, cleanup); | |
| 265 RunNativeApplication(app_library, application_request.Pass()); | |
| 266 } | 257 } |
| 267 | 258 |
| 268 base::ThreadChecker thread_checker_; | 259 base::ThreadChecker thread_checker_; |
| 269 AppContext* const app_context_; | 260 AppContext* const app_context_; |
| 261 base::NativeLibrary app_library_; |
| 270 Blocker::Unblocker unblocker_; | 262 Blocker::Unblocker unblocker_; |
| 271 StartAppCallback on_app_complete_; | 263 StartAppCallback on_app_complete_; |
| 272 | 264 |
| 273 embedder::ChannelInfo* channel_info_; | 265 embedder::ChannelInfo* channel_info_; |
| 274 Binding<ChildController> binding_; | 266 Binding<ChildController> binding_; |
| 275 | 267 |
| 276 DISALLOW_COPY_AND_ASSIGN(ChildControllerImpl); | 268 DISALLOW_COPY_AND_ASSIGN(ChildControllerImpl); |
| 277 }; | 269 }; |
| 278 | 270 |
| 279 } // namespace | 271 } // namespace |
| 280 | 272 |
| 281 int ChildProcessMain() { | 273 int ChildProcessMain(base::NativeLibrary app_library) { |
| 282 DVLOG(2) << "ChildProcessMain()"; | 274 DVLOG(2) << "ChildProcessMain()"; |
| 283 const base::CommandLine& command_line = | 275 const base::CommandLine& command_line = |
| 284 *base::CommandLine::ForCurrentProcess(); | 276 *base::CommandLine::ForCurrentProcess(); |
| 285 embedder::ScopedPlatformHandle platform_channel = | 277 embedder::ScopedPlatformHandle platform_channel = |
| 286 embedder::PlatformChannelPair::PassClientHandleFromParentProcess( | 278 embedder::PlatformChannelPair::PassClientHandleFromParentProcess( |
| 287 command_line); | 279 command_line); |
| 288 CHECK(platform_channel.is_valid()); | 280 CHECK(platform_channel.is_valid()); |
| 289 | 281 |
| 290 DCHECK(!base::MessageLoop::current()); | 282 DCHECK(!base::MessageLoop::current()); |
| 291 | 283 |
| 292 AppContext app_context; | 284 AppContext app_context; |
| 293 app_context.Init(); | 285 app_context.Init(); |
| 294 | 286 |
| 295 Blocker blocker; | 287 Blocker blocker; |
| 296 app_context.controller_runner()->PostTask( | 288 app_context.controller_runner()->PostTask( |
| 297 FROM_HERE, | 289 FROM_HERE, |
| 298 base::Bind(&ChildControllerImpl::Init, base::Unretained(&app_context), | 290 base::Bind(&ChildControllerImpl::Init, base::Unretained(&app_context), |
| 299 base::Passed(&platform_channel), blocker.GetUnblocker())); | 291 base::Unretained(app_library), base::Passed(&platform_channel), |
| 292 blocker.GetUnblocker())); |
| 300 // This will block, then run whatever the controller wants. | 293 // This will block, then run whatever the controller wants. |
| 301 blocker.Block(); | 294 blocker.Block(); |
| 302 | 295 |
| 303 app_context.Shutdown(); | 296 app_context.Shutdown(); |
| 304 | 297 |
| 305 return 0; | 298 return 0; |
| 306 } | 299 } |
| 307 | 300 |
| 308 } // namespace runner | 301 } // namespace runner |
| 309 } // namespace mojo | 302 } // namespace mojo |
| OLD | NEW |