1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file. 4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "mojo/shell/app_child_process.h" 6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/bind.h" 8effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/callback_helpers.h" 9effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/files/file_path.h" 1023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/location.h" 11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/logging.h" 1223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/macros.h" 1323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/memory/ref_counted.h" 1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 1523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/message_loop/message_loop.h" 16effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/scoped_native_library.h" 1723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/single_thread_task_runner.h" 18effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/synchronization/waitable_event.h" 1923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/threading/thread.h" 2023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/threading/thread_checker.h" 2123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "mojo/common/message_pump_mojo.h" 2223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "mojo/embedder/embedder.h" 2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "mojo/embedder/simple_platform_support.h" 24effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "mojo/public/cpp/system/core.h" 2523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "mojo/shell/app_child_process.mojom.h" 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace mojo { 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace shell { 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 3023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)namespace { 3123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 32effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Blocker --------------------------------------------------------------------- 33effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 34effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Blocks a thread until another thread unblocks it, at which point it unblocks 35effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// and runs a closure provided by that thread. 36effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochclass Blocker { 37effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch public: 38effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch class Unblocker { 39effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch public: 40effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ~Unblocker() {} 41effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 42effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch void Unblock(base::Closure run_after) { 43effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK(blocker_); 44effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK(blocker_->run_after_.is_null()); 45effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch blocker_->run_after_ = run_after; 46effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch blocker_->event_.Signal(); 47effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch blocker_ = NULL; 48effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 49effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 50effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch private: 51effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch friend class Blocker; 52effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch Unblocker(Blocker* blocker) : blocker_(blocker) { 53effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK(blocker_); 54effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 55effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 56effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch Blocker* blocker_; 57effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 58effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Copy and assign allowed. 59effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch }; 60effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 61effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch Blocker() : event_(true, false) {} 62effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ~Blocker() {} 63effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 64effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch void Block() { 65effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK(run_after_.is_null()); 66effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch event_.Wait(); 67effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch run_after_.Run(); 68effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 69effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 70effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch Unblocker GetUnblocker() { 71effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return Unblocker(this); 72effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 73effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 74effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch private: 75effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::WaitableEvent event_; 76effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Closure run_after_; 77effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 78effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DISALLOW_COPY_AND_ASSIGN(Blocker); 79effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}; 8023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 8123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// AppContext ------------------------------------------------------------------ 8223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 83effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochclass AppChildControllerImpl; 84effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 850de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)static void DestroyController(scoped_ptr<AppChildControllerImpl> controller) { 860de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)} 870de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 8823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Should be created and initialized on the main thread. 8923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)class AppContext { 9023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) public: 9123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) AppContext() 9223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) : io_thread_("io_thread"), 9323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) controller_thread_("controller_thread") {} 9423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ~AppContext() {} 9523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 9623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) void Init() { 9723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Initialize Mojo before starting any threads. 9803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) embedder::Init(scoped_ptr<mojo::embedder::PlatformSupport>( 9903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) new mojo::embedder::SimplePlatformSupport())); 10023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 10123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Create and start our I/O thread. 10223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Thread::Options io_thread_options(base::MessageLoop::TYPE_IO, 0); 10323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) CHECK(io_thread_.StartWithOptions(io_thread_options)); 10423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) io_runner_ = io_thread_.message_loop_proxy().get(); 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CHECK(io_runner_.get()); 10623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 10723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Create and start our controller thread. 10823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Thread::Options controller_thread_options; 10923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) controller_thread_options.message_loop_type = 11023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::MessageLoop::TYPE_CUSTOM; 11123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) controller_thread_options.message_pump_factory = 11223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Bind(&common::MessagePumpMojo::Create); 11323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) CHECK(controller_thread_.StartWithOptions(controller_thread_options)); 11423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) controller_runner_ = controller_thread_.message_loop_proxy().get(); 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CHECK(controller_runner_.get()); 11623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 11723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 1180de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) void Shutdown() { 1190de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) controller_runner_->PostTask( 1200de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) FROM_HERE, 1210de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) base::Bind(&DestroyController, base::Passed(&controller_))); 1220de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) } 1230de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 12423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::SingleThreadTaskRunner* io_runner() const { 12523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return io_runner_.get(); 12623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 12723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 12823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::SingleThreadTaskRunner* controller_runner() const { 12923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return controller_runner_.get(); 13023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 13123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 13223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) AppChildControllerImpl* controller() const { 13323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return controller_.get(); 13423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 13523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 13623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) void set_controller(scoped_ptr<AppChildControllerImpl> controller) { 13723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) controller_ = controller.Pass(); 13823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 13923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 14023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) private: 141effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Accessed only on the controller thread. 142effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // IMPORTANT: This must be BEFORE |controller_thread_|, so that the controller 143effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // thread gets joined (and thus |controller_| reset) before |controller_| is 144effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // destroyed. 145effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch scoped_ptr<AppChildControllerImpl> controller_; 146effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 14723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Thread io_thread_; 14823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> io_runner_; 14923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 15023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Thread controller_thread_; 15123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> controller_runner_; 15223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 15323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(AppContext); 15423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}; 15523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 15623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// AppChildControllerImpl ------------------------------------------------------ 15723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 1580de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)class AppChildControllerImpl : public InterfaceImpl<AppChildController> { 15923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) public: 16023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) virtual ~AppChildControllerImpl() { 16123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 1620de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 1630de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // TODO(vtl): Pass in the result from |MainMain()|. 164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) client()->AppCompleted(MOJO_RESULT_UNIMPLEMENTED); 16523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 16623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 16723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // To be executed on the controller thread. Creates the |AppChildController|, 16823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // etc. 16923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) static void Init( 17023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) AppContext* app_context, 17123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) embedder::ScopedPlatformHandle platform_channel, 172effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const Blocker::Unblocker& unblocker) { 17323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK(app_context); 17423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK(platform_channel.is_valid()); 17523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 17623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK(!app_context->controller()); 177effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1780de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) scoped_ptr<AppChildControllerImpl> impl( 1790de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) new AppChildControllerImpl(app_context, unblocker)); 180effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1810de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) ScopedMessagePipeHandle host_message_pipe(embedder::CreateChannel( 1820de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) platform_channel.Pass(), 1830de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) app_context->io_runner(), 1840de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) base::Bind(&AppChildControllerImpl::DidCreateChannel, 1850de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) base::Unretained(impl.get())), 1860de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) base::MessageLoopProxy::current())); 187effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1880de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) BindToPipe(impl.get(), host_message_pipe.Pass()); 18923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 1900de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) app_context->set_controller(impl.Pass()); 1910de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) } 1920de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 1930de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) virtual void OnConnectionError() OVERRIDE { 1940de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // TODO(darin): How should we handle a connection error here? 1950de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) } 1960de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 1970de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // |AppChildController| methods: 19823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) virtual void StartApp(const String& app_path, 19923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ScopedMessagePipeHandle service) OVERRIDE { 200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DVLOG(2) << "AppChildControllerImpl::StartApp(" << app_path << ", ...)"; 201effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK(thread_checker_.CalledOnValidThread()); 20223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 203effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch unblocker_.Unblock(base::Bind(&AppChildControllerImpl::StartAppOnMainThread, 204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::FilePath::FromUTF8Unsafe(app_path), 205effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Passed(&service))); 20623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 20723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 20823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) private: 209effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch AppChildControllerImpl(AppContext* app_context, 210effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const Blocker::Unblocker& unblocker) 21123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) : app_context_(app_context), 212effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch unblocker_(unblocker), 21323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) channel_info_(NULL) { 21423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 21523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 21623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Callback for |embedder::CreateChannel()|. 217effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch void DidCreateChannel(embedder::ChannelInfo* channel_info) { 21823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DVLOG(2) << "AppChildControllerImpl::DidCreateChannel()"; 21923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 22023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) channel_info_ = channel_info; 22123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 22223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 223effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch static void StartAppOnMainThread(const base::FilePath& app_path, 224effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ScopedMessagePipeHandle service) { 225effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // TODO(vtl): This is copied from in_process_dynamic_service_runner.cc. 226effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DVLOG(2) << "Loading/running Mojo app from " << app_path.value() 227effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch << " out of process"; 228effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 229effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch do { 230effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::NativeLibraryLoadError load_error; 231effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::ScopedNativeLibrary app_library( 232effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::LoadNativeLibrary(app_path, &load_error)); 233effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!app_library.is_valid()) { 234effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch LOG(ERROR) << "Failed to load library (error: " << load_error.ToString() 235effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch << ")"; 236effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch break; 237effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 238effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 239effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch typedef MojoResult (*MojoMainFunction)(MojoHandle); 240effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch MojoMainFunction main_function = reinterpret_cast<MojoMainFunction>( 241effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch app_library.GetFunctionPointer("MojoMain")); 242effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!main_function) { 243effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch LOG(ERROR) << "Entrypoint MojoMain not found"; 244effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch break; 245effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 246effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 247effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // TODO(vtl): Report the result back to our parent process. 248effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // |MojoMain()| takes ownership of the service handle. 249effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch MojoResult result = main_function(service.release().value()); 250effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (result < MOJO_RESULT_OK) 251effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch LOG(ERROR) << "MojoMain returned an error: " << result; 252effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } while (false); 253effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 254effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 25523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::ThreadChecker thread_checker_; 25623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) AppContext* const app_context_; 257effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch Blocker::Unblocker unblocker_; 25823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 25923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) embedder::ChannelInfo* channel_info_; 26023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 26123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(AppChildControllerImpl); 26223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}; 26323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 26423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} // namespace 26523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 26623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// AppChildProcess ------------------------------------------------------------- 26723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)AppChildProcess::AppChildProcess() { 269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)AppChildProcess::~AppChildProcess() { 272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AppChildProcess::Main() { 27523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DVLOG(2) << "AppChildProcess::Main()"; 27623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 27723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) AppContext app_context; 27823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) app_context.Init(); 27923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 280effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch Blocker blocker; 281effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch app_context.controller_runner()->PostTask( 282effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch FROM_HERE, 283effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Bind(&AppChildControllerImpl::Init, base::Unretained(&app_context), 284effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Passed(platform_channel()), blocker.GetUnblocker())); 285effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // This will block, then run whatever the controller wants. 286effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch blocker.Block(); 287effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 2880de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) app_context.Shutdown(); 289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace shell 292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace mojo 293