• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 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 
5 #include "mojo/shell/context.h"
6 
7 #include "build/build_config.h"
8 #include "base/command_line.h"
9 #include "base/lazy_instance.h"
10 #include "base/memory/scoped_vector.h"
11 #include "mojo/embedder/embedder.h"
12 #include "mojo/gles2/gles2_support_impl.h"
13 #include "mojo/public/cpp/application/application.h"
14 #include "mojo/service_manager/background_service_loader.h"
15 #include "mojo/service_manager/service_loader.h"
16 #include "mojo/service_manager/service_manager.h"
17 #include "mojo/services/native_viewport/native_viewport_service.h"
18 #include "mojo/shell/dynamic_service_loader.h"
19 #include "mojo/shell/in_process_dynamic_service_runner.h"
20 #include "mojo/shell/out_of_process_dynamic_service_runner.h"
21 #include "mojo/shell/switches.h"
22 #include "mojo/spy/spy.h"
23 
24 #if defined(OS_LINUX)
25 #include "mojo/shell/dbus_service_loader_linux.h"
26 #endif  // defined(OS_LINUX)
27 
28 #if defined(USE_AURA)
29 #include "mojo/shell/view_manager_loader.h"
30 #endif
31 
32 namespace mojo {
33 namespace shell {
34 namespace {
35 
36 // These mojo: URLs are loaded directly from the local filesystem. They
37 // correspond to shared libraries bundled alongside the mojo_shell.
38 const char* kLocalMojoURLs[] = {
39   "mojo:mojo_network_service",
40 };
41 
42 // Used to ensure we only init once.
43 class Setup {
44  public:
Setup()45   Setup() {
46     embedder::Init();
47     gles2::GLES2SupportImpl::Init();
48   }
49 
~Setup()50   ~Setup() {
51   }
52 
53  private:
54   DISALLOW_COPY_AND_ASSIGN(Setup);
55 };
56 
57 static base::LazyInstance<Setup>::Leaky setup = LAZY_INSTANCE_INITIALIZER;
58 
59 }  // namespace
60 
61 class Context::NativeViewportServiceLoader : public ServiceLoader {
62  public:
NativeViewportServiceLoader(Context * context)63   explicit NativeViewportServiceLoader(Context* context) : context_(context) {}
~NativeViewportServiceLoader()64   virtual ~NativeViewportServiceLoader() {}
65 
66  private:
LoadService(ServiceManager * manager,const GURL & url,ScopedMessagePipeHandle service_handle)67   virtual void LoadService(ServiceManager* manager,
68                            const GURL& url,
69                            ScopedMessagePipeHandle service_handle) OVERRIDE {
70     app_.reset(::CreateNativeViewportService(context_, service_handle.Pass()));
71   }
72 
OnServiceError(ServiceManager * manager,const GURL & url)73   virtual void OnServiceError(ServiceManager* manager,
74                               const GURL& url) OVERRIDE {
75   }
76 
77   Context* context_;
78   scoped_ptr<Application> app_;
79   DISALLOW_COPY_AND_ASSIGN(NativeViewportServiceLoader);
80 };
81 
Context()82 Context::Context()
83     : task_runners_(base::MessageLoop::current()->message_loop_proxy()) {
84   setup.Get();
85 
86   for (size_t i = 0; i < arraysize(kLocalMojoURLs); ++i)
87     mojo_url_resolver_.AddLocalFileMapping(GURL(kLocalMojoURLs[i]));
88 
89   base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
90   scoped_ptr<DynamicServiceRunnerFactory> runner_factory;
91   if (cmdline->HasSwitch(switches::kEnableMultiprocess))
92     runner_factory.reset(new OutOfProcessDynamicServiceRunnerFactory());
93   else
94     runner_factory.reset(new InProcessDynamicServiceRunnerFactory());
95 
96   service_manager_.set_default_loader(
97       scoped_ptr<ServiceLoader>(
98           new DynamicServiceLoader(this, runner_factory.Pass())));
99   // The native viewport service synchronously waits for certain messages. If we
100   // don't run it on its own thread we can easily deadlock. Long term native
101   // viewport should run its own process so that this isn't an issue.
102   service_manager_.SetLoaderForURL(
103       scoped_ptr<ServiceLoader>(
104           new BackgroundServiceLoader(
105               scoped_ptr<ServiceLoader>(new NativeViewportServiceLoader(this)),
106               "native_viewport",
107               base::MessageLoop::TYPE_UI)),
108       GURL("mojo:mojo_native_viewport_service"));
109 #if defined(USE_AURA)
110   // TODO(sky): need a better way to find this. It shouldn't be linked in.
111   service_manager_.SetLoaderForURL(
112       scoped_ptr<ServiceLoader>(new ViewManagerLoader()),
113       GURL("mojo:mojo_view_manager"));
114 #endif
115 
116 #if defined(OS_LINUX)
117   service_manager_.SetLoaderForScheme(
118       scoped_ptr<ServiceLoader>(new DBusServiceLoader(this)),
119       "dbus");
120 #endif  // defined(OS_LINUX)
121 
122   if (cmdline->HasSwitch(switches::kSpy)) {
123     spy_.reset(new mojo::Spy(&service_manager_,
124                              cmdline->GetSwitchValueASCII(switches::kSpy)));
125   }
126 }
127 
~Context()128 Context::~Context() {
129   // mojo_view_manager uses native_viewport. Destroy mojo_view_manager first so
130   // that there aren't shutdown ordering issues. Once native viewport service is
131   // moved into its own process this can likely be nuked.
132 #if defined(USE_AURA)
133   service_manager_.SetLoaderForURL(
134       scoped_ptr<ServiceLoader>(),
135       GURL("mojo:mojo_view_manager"));
136 #endif
137   service_manager_.set_default_loader(scoped_ptr<ServiceLoader>());
138 }
139 
140 }  // namespace shell
141 }  // namespace mojo
142