OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "content/common/mojo/mojo_shell_connection_impl.h" | 5 #include "content/common/mojo/mojo_shell_connection_impl.h" |
6 | 6 |
7 #include <queue> | |
8 #include <utility> | |
9 #include <vector> | |
10 | |
11 #include "base/bind.h" | 7 #include "base/bind.h" |
12 #include "base/callback_helpers.h" | |
13 #include "base/lazy_instance.h" | 8 #include "base/lazy_instance.h" |
14 #include "base/macros.h" | |
15 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
16 #include "base/threading/thread_checker.h" | 10 #include "base/threading/thread_local.h" |
17 #include "content/common/mojo/embedded_application_runner.h" | 11 #include "content/common/mojo/embedded_application_runner.h" |
18 #include "content/public/common/connection_filter.h" | |
19 #include "mojo/public/cpp/bindings/binding_set.h" | |
20 #include "mojo/public/cpp/system/message_pipe.h" | |
21 #include "services/shell/public/cpp/service.h" | 12 #include "services/shell/public/cpp/service.h" |
22 #include "services/shell/public/cpp/shell_connection.h" | 13 #include "services/shell/public/cpp/shell_connection.h" |
23 #include "services/shell/public/interfaces/service_factory.mojom.h" | |
24 #include "services/shell/runner/common/client_util.h" | 14 #include "services/shell/runner/common/client_util.h" |
25 | 15 |
26 namespace content { | 16 namespace content { |
27 namespace { | 17 namespace { |
28 | 18 |
29 base::LazyInstance<std::unique_ptr<MojoShellConnection>>::Leaky | 19 using MojoShellConnectionPtr = |
30 g_connection_for_process = LAZY_INSTANCE_INITIALIZER; | 20 base::ThreadLocalPointer<MojoShellConnection>; |
| 21 |
| 22 // Env is thread local so that aura may be used on multiple threads. |
| 23 base::LazyInstance<MojoShellConnectionPtr>::Leaky lazy_tls_ptr = |
| 24 LAZY_INSTANCE_INITIALIZER; |
31 | 25 |
32 MojoShellConnection::Factory* mojo_shell_connection_factory = nullptr; | 26 MojoShellConnection::Factory* mojo_shell_connection_factory = nullptr; |
33 | 27 |
34 } // namespace | 28 } // namespace |
35 | 29 |
36 // A ref-counted object which owns the IO thread state of a | |
37 // MojoShellConnectionImpl. This includes Service and ServiceFactory | |
38 // bindings. | |
39 class MojoShellConnectionImpl::IOThreadContext | |
40 : public base::RefCountedThreadSafe<IOThreadContext>, | |
41 public shell::Service, | |
42 public shell::InterfaceFactory<shell::mojom::ServiceFactory>, | |
43 public shell::mojom::ServiceFactory { | |
44 public: | |
45 using InitializeCallback = base::Callback<void(const shell::Identity&)>; | |
46 using ServiceFactoryCallback = | |
47 base::Callback<void(shell::mojom::ServiceRequest, const mojo::String&)>; | |
48 | |
49 IOThreadContext(shell::mojom::ServiceRequest service_request, | |
50 scoped_refptr<base::SequencedTaskRunner> io_task_runner, | |
51 std::unique_ptr<shell::Connector> io_thread_connector, | |
52 shell::mojom::ConnectorRequest connector_request) | |
53 : pending_service_request_(std::move(service_request)), | |
54 io_task_runner_(io_task_runner), | |
55 io_thread_connector_(std::move(io_thread_connector)), | |
56 pending_connector_request_(std::move(connector_request)) { | |
57 // This will be reattached by any of the IO thread functions on first call. | |
58 io_thread_checker_.DetachFromThread(); | |
59 } | |
60 | |
61 // Safe to call from any thread. | |
62 void Start(const InitializeCallback& initialize_callback, | |
63 const ServiceFactoryCallback& create_service) { | |
64 DCHECK(!started_); | |
65 | |
66 started_ = true; | |
67 initialize_handler_ = base::Bind( | |
68 &IOThreadContext::CallInitializeOnTaskRunner, | |
69 base::ThreadTaskRunnerHandle::Get(), initialize_callback); | |
70 | |
71 create_service_callback_ = base::Bind( | |
72 &IOThreadContext::CallServiceFactoryOnTaskRunner, | |
73 base::ThreadTaskRunnerHandle::Get(), create_service); | |
74 | |
75 io_task_runner_->PostTask( | |
76 FROM_HERE, base::Bind(&IOThreadContext::StartOnIOThread, this)); | |
77 } | |
78 | |
79 // Safe to call from whichever thread called Start() (or may have called | |
80 // Start()). Must be called before IO thread shutdown. | |
81 void ShutDown() { | |
82 if (!started_) | |
83 return; | |
84 | |
85 bool posted = io_task_runner_->PostTask( | |
86 FROM_HERE, base::Bind(&IOThreadContext::ShutDownOnIOThread, this)); | |
87 DCHECK(posted); | |
88 } | |
89 | |
90 // Safe to call any time before Start() is called. | |
91 void AddConnectionFilter(std::unique_ptr<ConnectionFilter> filter) { | |
92 DCHECK(!started_); | |
93 connection_filters_.emplace_back(std::move(filter)); | |
94 } | |
95 | |
96 // Safe to call any time before Start() is called. | |
97 void SetDefaultBinderForBrowserConnection( | |
98 const shell::InterfaceRegistry::Binder& binder) { | |
99 DCHECK(!started_); | |
100 default_browser_binder_ = base::Bind( | |
101 &IOThreadContext::CallBinderOnTaskRunner, | |
102 base::ThreadTaskRunnerHandle::Get(), binder); | |
103 } | |
104 | |
105 // Safe to call any time after Start() is called. | |
106 void GetRemoteInterface(const mojo::String& interface_name, | |
107 mojo::ScopedMessagePipeHandle request_handle) { | |
108 DCHECK(started_); | |
109 io_task_runner_->PostTask( | |
110 FROM_HERE, | |
111 base::Bind(&IOThreadContext::GetRemoteInterfaceOnIOThread, this, | |
112 interface_name, base::Passed(&request_handle))); | |
113 } | |
114 | |
115 private: | |
116 friend class base::RefCountedThreadSafe<IOThreadContext>; | |
117 | |
118 ~IOThreadContext() override {} | |
119 | |
120 void StartOnIOThread() { | |
121 // Should bind |io_thread_checker_| to the context's thread. | |
122 DCHECK(io_thread_checker_.CalledOnValidThread()); | |
123 shell_connection_.reset(new shell::ShellConnection( | |
124 this, std::move(pending_service_request_), | |
125 std::move(io_thread_connector_), | |
126 std::move(pending_connector_request_))); | |
127 } | |
128 | |
129 void ShutDownOnIOThread() { | |
130 DCHECK(io_thread_checker_.CalledOnValidThread()); | |
131 shell_connection_.reset(); | |
132 factory_bindings_.CloseAllBindings(); | |
133 } | |
134 | |
135 void GetRemoteInterfaceOnIOThread( | |
136 const mojo::String& interface_name, | |
137 mojo::ScopedMessagePipeHandle request_handle) { | |
138 DCHECK(io_thread_checker_.CalledOnValidThread()); | |
139 if (browser_connection_) { | |
140 browser_connection_->GetRemoteInterfaces()->GetInterface( | |
141 interface_name, std::move(request_handle)); | |
142 } else { | |
143 pending_remote_interface_requests_.emplace(interface_name, | |
144 std::move(request_handle)); | |
145 } | |
146 } | |
147 | |
148 void OnBrowserConnectionLost() { | |
149 DCHECK(io_thread_checker_.CalledOnValidThread()); | |
150 browser_connection_ = nullptr; | |
151 } | |
152 | |
153 ///////////////////////////////////////////////////////////////////////////// | |
154 // shell::Service implementation | |
155 | |
156 void OnStart(shell::Connector* connector, | |
157 const shell::Identity& identity, | |
158 uint32_t id) override { | |
159 DCHECK(io_thread_checker_.CalledOnValidThread()); | |
160 DCHECK(!initialize_handler_.is_null()); | |
161 base::ResetAndReturn(&initialize_handler_).Run(identity); | |
162 } | |
163 | |
164 bool OnConnect(shell::Connection* connection) override { | |
165 DCHECK(io_thread_checker_.CalledOnValidThread()); | |
166 std::string remote_app = connection->GetRemoteIdentity().name(); | |
167 if (remote_app == "mojo:shell") { | |
168 // Only expose the SCF interface to the shell. | |
169 connection->AddInterface<shell::mojom::ServiceFactory>(this); | |
170 return true; | |
171 } | |
172 | |
173 bool accept = false; | |
174 for (auto& filter : connection_filters_) { | |
175 accept = accept || | |
176 filter->OnConnect(connection, shell_connection_->connector()); | |
177 } | |
178 | |
179 // Capture the browser connection if possible. | |
180 if (remote_app == "exe:content_browser" && !browser_connection_) { | |
181 browser_connection_ = connection; | |
182 connection->GetInterfaceRegistry()->set_default_binder( | |
183 default_browser_binder_); | |
184 connection->SetConnectionLostClosure( | |
185 base::Bind(&IOThreadContext::OnBrowserConnectionLost, this)); | |
186 shell::InterfaceProvider* remote_interfaces = | |
187 connection->GetRemoteInterfaces(); | |
188 | |
189 // Flush any pending outgoing interface requests. | |
190 while (!pending_remote_interface_requests_.empty()) { | |
191 auto& request = pending_remote_interface_requests_.front(); | |
192 remote_interfaces->GetInterface( | |
193 request.first, std::move(request.second)); | |
194 pending_remote_interface_requests_.pop(); | |
195 } | |
196 return true; | |
197 } | |
198 | |
199 // If no filters were interested, reject the connection. | |
200 return accept; | |
201 } | |
202 | |
203 ///////////////////////////////////////////////////////////////////////////// | |
204 // shell::InterfaceFactory<shell::mojom::ServiceFactory> implementation | |
205 | |
206 void Create(shell::Connection* connection, | |
207 shell::mojom::ServiceFactoryRequest request) override { | |
208 DCHECK(io_thread_checker_.CalledOnValidThread()); | |
209 factory_bindings_.AddBinding(this, std::move(request)); | |
210 } | |
211 | |
212 ///////////////////////////////////////////////////////////////////////////// | |
213 // shell::mojom::ServiceFactory implementation | |
214 | |
215 void CreateService(shell::mojom::ServiceRequest request, | |
216 const mojo::String& name) override { | |
217 DCHECK(io_thread_checker_.CalledOnValidThread()); | |
218 create_service_callback_.Run(std::move(request), name); | |
219 } | |
220 | |
221 static void CallInitializeOnTaskRunner( | |
222 scoped_refptr<base::SequencedTaskRunner> task_runner, | |
223 const InitializeCallback& callback, | |
224 const shell::Identity& identity) { | |
225 task_runner->PostTask(FROM_HERE, base::Bind(callback, identity)); | |
226 } | |
227 | |
228 static void CallServiceFactoryOnTaskRunner( | |
229 scoped_refptr<base::SequencedTaskRunner> task_runner, | |
230 const ServiceFactoryCallback& callback, | |
231 shell::mojom::ServiceRequest request, | |
232 const mojo::String& name) { | |
233 task_runner->PostTask( | |
234 FROM_HERE, base::Bind(callback, base::Passed(&request), name)); | |
235 } | |
236 | |
237 static void CallBinderOnTaskRunner( | |
238 scoped_refptr<base::SequencedTaskRunner> task_runner, | |
239 const shell::InterfaceRegistry::Binder& binder, | |
240 const mojo::String& interface_name, | |
241 mojo::ScopedMessagePipeHandle request_handle) { | |
242 task_runner->PostTask(FROM_HERE, base::Bind(binder, interface_name, | |
243 base::Passed(&request_handle))); | |
244 } | |
245 | |
246 base::ThreadChecker io_thread_checker_; | |
247 bool started_ = false; | |
248 | |
249 // Temporary state established on construction and consumed on the IO thread | |
250 // once the connection is started. | |
251 shell::mojom::ServiceRequest pending_service_request_; | |
252 scoped_refptr<base::SequencedTaskRunner> io_task_runner_; | |
253 std::unique_ptr<shell::Connector> io_thread_connector_; | |
254 shell::mojom::ConnectorRequest pending_connector_request_; | |
255 | |
256 // Callback to run once Service::OnStart is invoked. | |
257 InitializeCallback initialize_handler_; | |
258 | |
259 // Callback to run when a new Service request is received. | |
260 ServiceFactoryCallback create_service_callback_; | |
261 | |
262 // The incoming Connection from the browser process. This is captured the | |
263 // first time the browser connects to this Service and persists until shutdown | |
264 // or a connection error is detected. This connection is used to fulfill | |
265 // remote interface requests from legacy code which does not use | |
266 // shell::Connector. | |
267 // | |
268 // TODO(rockot): Remove this once all child-to-browser interface connections | |
269 // are made via a Connector rather than directly through an InterfaceProvider | |
270 // and all interfaces exposed to the browser are exposed via a | |
271 // ConnectionFilter. | |
272 shell::Connection* browser_connection_ = nullptr; | |
273 | |
274 // A queue of remote interface requests destined for the browser, which will | |
275 // remain pending until an incoming connection is accepted from the browser. | |
276 // | |
277 // TODO(rockot): Remove this once all child-to-browser interface connections | |
278 // are made via a Connector rather than directly through an InterfaceProvider. | |
279 std::queue<std::pair<mojo::String, mojo::ScopedMessagePipeHandle>> | |
280 pending_remote_interface_requests_; | |
281 | |
282 // Default binder callback used for the browser connection's | |
283 // InterfaceRegistry. | |
284 // | |
285 // TODO(rockot): Remove this once all interfaces exposed to the browser are | |
286 // exposed via a ConnectionFilter. | |
287 shell::InterfaceRegistry::Binder default_browser_binder_; | |
288 | |
289 std::unique_ptr<shell::ShellConnection> shell_connection_; | |
290 mojo::BindingSet<shell::mojom::ServiceFactory> factory_bindings_; | |
291 std::vector<std::unique_ptr<ConnectionFilter>> connection_filters_; | |
292 | |
293 DISALLOW_COPY_AND_ASSIGN(IOThreadContext); | |
294 }; | |
295 | |
296 //////////////////////////////////////////////////////////////////////////////// | 30 //////////////////////////////////////////////////////////////////////////////// |
297 // MojoShellConnection, public: | 31 // MojoShellConnection, public: |
298 | 32 |
299 // static | 33 // static |
300 void MojoShellConnection::SetForProcess( | 34 void MojoShellConnection::SetForProcess( |
301 std::unique_ptr<MojoShellConnection> connection) { | 35 std::unique_ptr<MojoShellConnection> connection) { |
302 DCHECK(!g_connection_for_process.Get()); | 36 DCHECK(!lazy_tls_ptr.Pointer()->Get()); |
303 g_connection_for_process.Get() = std::move(connection); | 37 lazy_tls_ptr.Pointer()->Set(connection.release()); |
304 } | 38 } |
305 | 39 |
306 // static | 40 // static |
307 MojoShellConnection* MojoShellConnection::GetForProcess() { | 41 MojoShellConnection* MojoShellConnection::GetForProcess() { |
308 return g_connection_for_process.Get().get(); | 42 return lazy_tls_ptr.Pointer()->Get(); |
309 } | 43 } |
310 | 44 |
311 // static | 45 // static |
312 void MojoShellConnection::DestroyForProcess() { | 46 void MojoShellConnection::DestroyForProcess() { |
313 // This joins the shell controller thread. | 47 // This joins the shell controller thread. |
314 g_connection_for_process.Get().reset(); | 48 delete GetForProcess(); |
| 49 lazy_tls_ptr.Pointer()->Set(nullptr); |
315 } | 50 } |
316 | 51 |
317 // static | 52 // static |
318 void MojoShellConnection::SetFactoryForTest(Factory* factory) { | 53 void MojoShellConnection::SetFactoryForTest(Factory* factory) { |
319 DCHECK(!g_connection_for_process.Get()); | 54 DCHECK(!lazy_tls_ptr.Pointer()->Get()); |
320 mojo_shell_connection_factory = factory; | 55 mojo_shell_connection_factory = factory; |
321 } | 56 } |
322 | 57 |
323 // static | 58 // static |
324 std::unique_ptr<MojoShellConnection> MojoShellConnection::Create( | 59 std::unique_ptr<MojoShellConnection> MojoShellConnection::Create( |
325 shell::mojom::ServiceRequest request, | 60 shell::mojom::ServiceRequest request) { |
326 scoped_refptr<base::SequencedTaskRunner> io_task_runner) { | |
327 if (mojo_shell_connection_factory) | 61 if (mojo_shell_connection_factory) |
328 return mojo_shell_connection_factory->Run(); | 62 return mojo_shell_connection_factory->Run(); |
329 return base::MakeUnique<MojoShellConnectionImpl>( | 63 return base::WrapUnique(new MojoShellConnectionImpl(std::move(request))); |
330 std::move(request), io_task_runner); | |
331 } | 64 } |
332 | 65 |
333 MojoShellConnection::~MojoShellConnection() {} | 66 MojoShellConnection::~MojoShellConnection() {} |
334 | 67 |
335 //////////////////////////////////////////////////////////////////////////////// | 68 //////////////////////////////////////////////////////////////////////////////// |
336 // MojoShellConnectionImpl, public: | 69 // MojoShellConnectionImpl, public: |
337 | 70 |
338 MojoShellConnectionImpl::MojoShellConnectionImpl( | 71 MojoShellConnectionImpl::MojoShellConnectionImpl( |
339 shell::mojom::ServiceRequest request, | 72 shell::mojom::ServiceRequest request) |
340 scoped_refptr<base::SequencedTaskRunner> io_task_runner) | 73 : shell_connection_(new shell::ShellConnection(this, std::move(request))) {} |
341 : weak_factory_(this) { | |
342 shell::mojom::ConnectorRequest connector_request; | |
343 connector_ = shell::Connector::Create(&connector_request); | |
344 | 74 |
345 std::unique_ptr<shell::Connector> io_thread_connector = connector_->Clone(); | 75 MojoShellConnectionImpl::~MojoShellConnectionImpl() {} |
346 context_ = new IOThreadContext( | 76 |
347 std::move(request), io_task_runner, std::move(io_thread_connector), | 77 //////////////////////////////////////////////////////////////////////////////// |
348 std::move(connector_request)); | 78 // MojoShellConnectionImpl, shell::Service implementation: |
| 79 |
| 80 void MojoShellConnectionImpl::OnStart(shell::Connector* connector, |
| 81 const shell::Identity& identity, |
| 82 uint32_t id) { |
| 83 for (auto& client : embedded_services_) |
| 84 client->OnStart(connector, identity, id); |
349 } | 85 } |
350 | 86 |
351 MojoShellConnectionImpl::~MojoShellConnectionImpl() { | 87 bool MojoShellConnectionImpl::OnConnect(shell::Connection* connection) { |
352 context_->ShutDown(); | 88 std::string remote_app = connection->GetRemoteIdentity().name(); |
| 89 if (remote_app == "mojo:shell") { |
| 90 // Only expose the SCF interface to the shell. |
| 91 connection->AddInterface<shell::mojom::ServiceFactory>(this); |
| 92 return true; |
| 93 } |
| 94 |
| 95 bool accept = false; |
| 96 for (auto& client : embedded_services_) |
| 97 accept |= client->OnConnect(connection); |
| 98 |
| 99 // Reject all other connections to this application. |
| 100 return accept; |
| 101 } |
| 102 |
| 103 shell::InterfaceRegistry* |
| 104 MojoShellConnectionImpl::GetInterfaceRegistryForConnection() { |
| 105 // TODO(beng): This is really horrible since obviously subject to issues |
| 106 // of ordering, but is no more horrible than this API is in general. |
| 107 shell::InterfaceRegistry* registry = nullptr; |
| 108 for (auto& client : embedded_services_) { |
| 109 registry = client->GetInterfaceRegistryForConnection(); |
| 110 if (registry) |
| 111 return registry; |
| 112 } |
| 113 return nullptr; |
| 114 } |
| 115 |
| 116 shell::InterfaceProvider* |
| 117 MojoShellConnectionImpl::GetInterfaceProviderForConnection() { |
| 118 // TODO(beng): This is really horrible since obviously subject to issues |
| 119 // of ordering, but is no more horrible than this API is in general. |
| 120 shell::InterfaceProvider* provider = nullptr; |
| 121 for (auto& client : embedded_services_) { |
| 122 provider = client->GetInterfaceProviderForConnection(); |
| 123 if (provider) |
| 124 return provider; |
| 125 } |
| 126 return nullptr; |
| 127 } |
| 128 |
| 129 //////////////////////////////////////////////////////////////////////////////// |
| 130 // MojoShellConnectionImpl, |
| 131 // shell::InterfaceFactory<shell::mojom::ServiceFactory> implementation: |
| 132 |
| 133 void MojoShellConnectionImpl::Create( |
| 134 shell::Connection* connection, |
| 135 shell::mojom::ServiceFactoryRequest request) { |
| 136 factory_bindings_.AddBinding(this, std::move(request)); |
| 137 } |
| 138 |
| 139 //////////////////////////////////////////////////////////////////////////////// |
| 140 // MojoShellConnectionImpl, shell::mojom::ServiceFactory implementation: |
| 141 |
| 142 void MojoShellConnectionImpl::CreateService( |
| 143 shell::mojom::ServiceRequest request, |
| 144 const mojo::String& name) { |
| 145 auto it = request_handlers_.find(name); |
| 146 if (it != request_handlers_.end()) |
| 147 it->second.Run(std::move(request)); |
353 } | 148 } |
354 | 149 |
355 //////////////////////////////////////////////////////////////////////////////// | 150 //////////////////////////////////////////////////////////////////////////////// |
356 // MojoShellConnectionImpl, MojoShellConnection implementation: | 151 // MojoShellConnectionImpl, MojoShellConnection implementation: |
357 | 152 |
358 void MojoShellConnectionImpl::Start() { | 153 shell::ShellConnection* MojoShellConnectionImpl::GetShellConnection() { |
359 context_->Start( | 154 return shell_connection_.get(); |
360 base::Bind(&MojoShellConnectionImpl::OnContextInitialized, | |
361 weak_factory_.GetWeakPtr()), | |
362 base::Bind(&MojoShellConnectionImpl::CreateService, | |
363 weak_factory_.GetWeakPtr())); | |
364 } | |
365 | |
366 void MojoShellConnectionImpl::SetInitializeHandler( | |
367 const base::Closure& handler) { | |
368 DCHECK(initialize_handler_.is_null()); | |
369 initialize_handler_ = handler; | |
370 } | 155 } |
371 | 156 |
372 shell::Connector* MojoShellConnectionImpl::GetConnector() { | 157 shell::Connector* MojoShellConnectionImpl::GetConnector() { |
373 return connector_.get(); | 158 DCHECK(shell_connection_); |
| 159 return shell_connection_->connector(); |
374 } | 160 } |
375 | 161 |
376 const shell::Identity& MojoShellConnectionImpl::GetIdentity() const { | 162 const shell::Identity& MojoShellConnectionImpl::GetIdentity() const { |
377 return identity_; | 163 DCHECK(shell_connection_); |
| 164 return shell_connection_->identity(); |
378 } | 165 } |
379 | 166 |
380 void MojoShellConnectionImpl::SetConnectionLostClosure( | 167 void MojoShellConnectionImpl::SetConnectionLostClosure( |
381 const base::Closure& closure) { | 168 const base::Closure& closure) { |
382 connection_lost_handler_ = closure; | 169 shell_connection_->SetConnectionLostClosure(closure); |
383 } | 170 } |
384 | 171 |
385 void MojoShellConnectionImpl::SetupInterfaceRequestProxies( | 172 void MojoShellConnectionImpl::MergeService( |
386 shell::InterfaceRegistry* registry, | 173 std::unique_ptr<shell::Service> service) { |
387 shell::InterfaceProvider* provider) { | 174 embedded_services_.push_back(service.get()); |
388 // It's safe to bind |registry| as a raw pointer because the caller must | 175 owned_services_.push_back(std::move(service)); |
389 // guarantee that it outlives |this|, and |this| is bound as a weak ptr here. | |
390 context_->SetDefaultBinderForBrowserConnection( | |
391 base::Bind(&MojoShellConnectionImpl::GetInterface, | |
392 weak_factory_.GetWeakPtr(), registry)); | |
393 | |
394 // Forward all remote interface requests on |provider| to our IO-thread | |
395 // context. This will ensure they're forwarded to the provider on the | |
396 // incoming browser connection. | |
397 provider->Forward(base::Bind(&IOThreadContext::GetRemoteInterface, context_)); | |
398 } | 176 } |
399 | 177 |
400 void MojoShellConnectionImpl::AddConnectionFilter( | 178 void MojoShellConnectionImpl::MergeService( |
401 std::unique_ptr<ConnectionFilter> filter) { | 179 shell::Service* service) { |
402 context_->AddConnectionFilter(std::move(filter)); | 180 embedded_services_.push_back(service); |
403 } | 181 } |
404 | 182 |
405 void MojoShellConnectionImpl::AddEmbeddedService( | 183 void MojoShellConnectionImpl::AddEmbeddedService( |
406 const std::string& name, | 184 const std::string& name, |
407 const MojoApplicationInfo& info) { | 185 const MojoApplicationInfo& info) { |
408 std::unique_ptr<EmbeddedApplicationRunner> app( | 186 std::unique_ptr<EmbeddedApplicationRunner> app( |
409 new EmbeddedApplicationRunner(name, info)); | 187 new EmbeddedApplicationRunner(name, info)); |
410 AddServiceRequestHandler( | 188 AddServiceRequestHandler( |
411 name, base::Bind(&EmbeddedApplicationRunner::BindServiceRequest, | 189 name, base::Bind(&EmbeddedApplicationRunner::BindServiceRequest, |
412 base::Unretained(app.get()))); | 190 base::Unretained(app.get()))); |
413 auto result = embedded_apps_.insert(std::make_pair(name, std::move(app))); | 191 auto result = embedded_apps_.insert(std::make_pair(name, std::move(app))); |
414 DCHECK(result.second); | 192 DCHECK(result.second); |
415 } | 193 } |
416 | 194 |
417 void MojoShellConnectionImpl::AddServiceRequestHandler( | 195 void MojoShellConnectionImpl::AddServiceRequestHandler( |
418 const std::string& name, | 196 const std::string& name, |
419 const ServiceRequestHandler& handler) { | 197 const ServiceRequestHandler& handler) { |
420 auto result = request_handlers_.insert(std::make_pair(name, handler)); | 198 auto result = request_handlers_.insert(std::make_pair(name, handler)); |
421 DCHECK(result.second); | 199 DCHECK(result.second); |
422 } | 200 } |
423 | 201 |
424 void MojoShellConnectionImpl::CreateService( | |
425 shell::mojom::ServiceRequest request, | |
426 const mojo::String& name) { | |
427 auto it = request_handlers_.find(name); | |
428 if (it != request_handlers_.end()) | |
429 it->second.Run(std::move(request)); | |
430 } | |
431 | |
432 void MojoShellConnectionImpl::OnContextInitialized( | |
433 const shell::Identity& identity) { | |
434 identity_ = identity; | |
435 if (!initialize_handler_.is_null()) | |
436 base::ResetAndReturn(&initialize_handler_).Run(); | |
437 } | |
438 | |
439 void MojoShellConnectionImpl::OnConnectionLost() { | |
440 if (!connection_lost_handler_.is_null()) | |
441 connection_lost_handler_.Run(); | |
442 } | |
443 | |
444 void MojoShellConnectionImpl::GetInterface( | |
445 shell::mojom::InterfaceProvider* provider, | |
446 const mojo::String& interface_name, | |
447 mojo::ScopedMessagePipeHandle request_handle) { | |
448 provider->GetInterface(interface_name, std::move(request_handle)); | |
449 } | |
450 | |
451 } // namespace content | 202 } // namespace content |
OLD | NEW |