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/service_manager/service_manager_connection_impl.h" | 5 #include "content/common/service_manager/service_manager_connection_impl.h" |
6 | 6 |
7 #include <queue> | 7 #include <queue> |
8 #include <utility> | 8 #include <utility> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/callback_helpers.h" | 12 #include "base/callback_helpers.h" |
13 #include "base/lazy_instance.h" | 13 #include "base/lazy_instance.h" |
14 #include "base/macros.h" | 14 #include "base/macros.h" |
15 #include "base/memory/ptr_util.h" | 15 #include "base/memory/ptr_util.h" |
16 #include "base/message_loop/message_loop.h" | 16 #include "base/message_loop/message_loop.h" |
17 #include "base/threading/thread_checker.h" | 17 #include "base/threading/thread_checker.h" |
18 #include "base/threading/thread_task_runner_handle.h" | 18 #include "base/threading/thread_task_runner_handle.h" |
19 #include "content/common/child.mojom.h" | 19 #include "content/common/child.mojom.h" |
20 #include "content/common/service_manager/embedded_service_runner.h" | 20 #include "content/common/service_manager/embedded_service_runner.h" |
21 #include "content/public/common/connection_filter.h" | 21 #include "content/public/common/connection_filter.h" |
22 #include "content/public/common/service_names.mojom.h" | |
22 #include "mojo/public/cpp/bindings/binding_set.h" | 23 #include "mojo/public/cpp/bindings/binding_set.h" |
23 #include "mojo/public/cpp/system/message_pipe.h" | 24 #include "mojo/public/cpp/system/message_pipe.h" |
24 #include "services/service_manager/public/cpp/interface_registry.h" | |
25 #include "services/service_manager/public/cpp/service.h" | 25 #include "services/service_manager/public/cpp/service.h" |
26 #include "services/service_manager/public/cpp/service_context.h" | 26 #include "services/service_manager/public/cpp/service_context.h" |
27 #include "services/service_manager/public/interfaces/constants.mojom.h" | 27 #include "services/service_manager/public/interfaces/constants.mojom.h" |
28 #include "services/service_manager/public/interfaces/service_factory.mojom.h" | 28 #include "services/service_manager/public/interfaces/service_factory.mojom.h" |
29 #include "services/service_manager/runner/common/client_util.h" | 29 #include "services/service_manager/runner/common/client_util.h" |
30 | 30 |
31 namespace content { | 31 namespace content { |
32 namespace { | 32 namespace { |
33 | 33 |
34 base::LazyInstance<std::unique_ptr<ServiceManagerConnection>>::Leaky | 34 base::LazyInstance<std::unique_ptr<ServiceManagerConnection>>::Leaky |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
105 return id; | 105 return id; |
106 } | 106 } |
107 | 107 |
108 void RemoveConnectionFilter(int filter_id) { | 108 void RemoveConnectionFilter(int filter_id) { |
109 io_task_runner_->PostTask( | 109 io_task_runner_->PostTask( |
110 FROM_HERE, | 110 FROM_HERE, |
111 base::Bind(&IOThreadContext::RemoveConnectionFilterOnIOThread, this, | 111 base::Bind(&IOThreadContext::RemoveConnectionFilterOnIOThread, this, |
112 filter_id)); | 112 filter_id)); |
113 } | 113 } |
114 | 114 |
115 // Safe to call any time before Start() is called. | |
116 void SetDefaultBinderForBrowserConnection( | |
117 const service_manager::InterfaceRegistry::Binder& binder) { | |
118 DCHECK(!started_); | |
119 default_browser_binder_ = base::Bind( | |
120 &IOThreadContext::CallBinderOnTaskRunner, | |
121 base::ThreadTaskRunnerHandle::Get(), binder); | |
122 } | |
123 | |
124 void AddEmbeddedService(const std::string& name, const ServiceInfo& info) { | 115 void AddEmbeddedService(const std::string& name, const ServiceInfo& info) { |
125 io_task_runner_->PostTask( | 116 io_task_runner_->PostTask( |
126 FROM_HERE, base::Bind(&ServiceManagerConnectionImpl::IOThreadContext:: | 117 FROM_HERE, base::Bind(&ServiceManagerConnectionImpl::IOThreadContext:: |
127 AddEmbeddedServiceRequestHandlerOnIoThread, | 118 AddEmbeddedServiceRequestHandlerOnIoThread, |
128 this, name, info)); | 119 this, name, info)); |
129 } | 120 } |
130 | 121 |
131 void AddServiceRequestHandler(const std::string& name, | 122 void AddServiceRequestHandler(const std::string& name, |
132 const ServiceRequestHandler& handler) { | 123 const ServiceRequestHandler& handler) { |
133 io_task_runner_->PostTask( | 124 io_task_runner_->PostTask( |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
225 | 216 |
226 void RemoveConnectionFilterOnIOThread(int filter_id) { | 217 void RemoveConnectionFilterOnIOThread(int filter_id) { |
227 base::AutoLock lock(lock_); | 218 base::AutoLock lock(lock_); |
228 auto it = connection_filters_.find(filter_id); | 219 auto it = connection_filters_.find(filter_id); |
229 // During shutdown the connection filters might have been cleared already | 220 // During shutdown the connection filters might have been cleared already |
230 // by ClearConnectionFiltersOnIOThread() above, so this id might not exist. | 221 // by ClearConnectionFiltersOnIOThread() above, so this id might not exist. |
231 if (it != connection_filters_.end()) | 222 if (it != connection_filters_.end()) |
232 connection_filters_.erase(it); | 223 connection_filters_.erase(it); |
233 } | 224 } |
234 | 225 |
235 void OnBrowserConnectionLost() { | |
236 DCHECK(io_thread_checker_.CalledOnValidThread()); | |
237 has_browser_connection_ = false; | |
238 } | |
239 | |
240 void AddEmbeddedServiceRequestHandlerOnIoThread(const std::string& name, | 226 void AddEmbeddedServiceRequestHandlerOnIoThread(const std::string& name, |
241 const ServiceInfo& info) { | 227 const ServiceInfo& info) { |
242 DCHECK(io_thread_checker_.CalledOnValidThread()); | 228 DCHECK(io_thread_checker_.CalledOnValidThread()); |
243 std::unique_ptr<EmbeddedServiceRunner> service( | 229 std::unique_ptr<EmbeddedServiceRunner> service( |
244 new EmbeddedServiceRunner(name, info)); | 230 new EmbeddedServiceRunner(name, info)); |
245 AddServiceRequestHandlerOnIoThread( | 231 AddServiceRequestHandlerOnIoThread( |
246 name, base::Bind(&EmbeddedServiceRunner::BindServiceRequest, | 232 name, base::Bind(&EmbeddedServiceRunner::BindServiceRequest, |
247 base::Unretained(service.get()))); | 233 base::Unretained(service.get()))); |
248 auto result = | 234 auto result = |
249 embedded_services_.insert(std::make_pair(name, std::move(service))); | 235 embedded_services_.insert(std::make_pair(name, std::move(service))); |
(...skipping 19 matching lines...) Expand all Loading... | |
269 InitializeCallback handler = | 255 InitializeCallback handler = |
270 base::ResetAndReturn(&local_info_available_callback_); | 256 base::ResetAndReturn(&local_info_available_callback_); |
271 callback_task_runner_->PostTask(FROM_HERE, | 257 callback_task_runner_->PostTask(FROM_HERE, |
272 base::Bind(handler, local_info_)); | 258 base::Bind(handler, local_info_)); |
273 } | 259 } |
274 | 260 |
275 void OnBindInterface(const service_manager::ServiceInfo& source_info, | 261 void OnBindInterface(const service_manager::ServiceInfo& source_info, |
276 const std::string& interface_name, | 262 const std::string& interface_name, |
277 mojo::ScopedMessagePipeHandle interface_pipe) override { | 263 mojo::ScopedMessagePipeHandle interface_pipe) override { |
278 DCHECK(io_thread_checker_.CalledOnValidThread()); | 264 DCHECK(io_thread_checker_.CalledOnValidThread()); |
265 last_source_info_ = source_info; | |
279 | 266 |
280 std::string remote_service = source_info.identity.name(); | 267 if (source_info.identity.name() == service_manager::mojom::kServiceName && |
281 // Only expose the ServiceFactory interface to the Service Manager. | |
282 if (remote_service == service_manager::mojom::kServiceName && | |
283 interface_name == service_manager::mojom::ServiceFactory::Name_) { | 268 interface_name == service_manager::mojom::ServiceFactory::Name_) { |
284 factory_bindings_.AddBinding( | 269 factory_bindings_.AddBinding( |
285 this, mojo::MakeRequest<service_manager::mojom::ServiceFactory>( | 270 this, mojo::MakeRequest<service_manager::mojom::ServiceFactory>( |
286 std::move(interface_pipe))); | 271 std::move(interface_pipe))); |
287 return; | 272 } else if (source_info.identity.name() == mojom::kBrowserServiceName && |
288 } | 273 interface_name == mojom::Child::Name_) { |
274 DCHECK(!child_binding_.is_bound()); | |
275 child_binding_.Bind( | |
276 mojo::MakeRequest<mojom::Child>(std::move(interface_pipe))); | |
289 | 277 |
290 { | 278 InitializeCallback handler = |
279 base::ResetAndReturn(&browser_info_available_callback_); | |
280 // TODO(beng): change |source_identity| parameter to |source_info|. | |
281 callback_task_runner_->PostTask(FROM_HERE, | |
282 base::Bind(handler, last_source_info_)); | |
283 } else { | |
291 base::AutoLock lock(lock_); | 284 base::AutoLock lock(lock_); |
292 for (auto& entry : connection_filters_) { | 285 for (auto& entry : connection_filters_) { |
293 entry.second->OnBindInterface(source_info, interface_name, | 286 entry.second->OnBindInterface(source_info, interface_name, |
294 &interface_pipe, | 287 &interface_pipe, |
295 service_context_->connector()); | 288 service_context_->connector()); |
296 // A filter may have bound the interface, claiming the pipe. | 289 // A filter may have bound the interface, claiming the pipe. |
297 if (!interface_pipe.is_valid()) | 290 if (!interface_pipe.is_valid()) |
298 return; | 291 return; |
299 } | 292 } |
300 } | 293 } |
301 | |
302 if (remote_service == "content_browser") { | |
303 if (interface_name == mojom::Child::Name_ && !has_browser_connection_) { | |
304 has_browser_connection_ = true; | |
305 InitializeCallback handler = | |
306 base::ResetAndReturn(&browser_info_available_callback_); | |
307 callback_task_runner_->PostTask(FROM_HERE, | |
308 base::Bind(handler, source_info)); | |
309 | |
310 child_binding_.Bind(std::move(interface_pipe)); | |
311 child_binding_.set_connection_error_handler( | |
312 base::Bind(&IOThreadContext::OnBrowserConnectionLost, this)); | |
313 } else { | |
314 default_browser_binder_.Run(interface_name, std::move(interface_pipe)); | |
315 } | |
316 } | |
317 } | 294 } |
318 | 295 |
319 bool OnServiceManagerConnectionLost() override { | |
320 ClearConnectionFiltersOnIOThread(); | |
321 callback_task_runner_->PostTask(FROM_HERE, stop_callback_); | |
322 return true; | |
323 } | |
324 | |
325 ///////////////////////////////////////////////////////////////////////////// | 296 ///////////////////////////////////////////////////////////////////////////// |
326 // service_manager::mojom::ServiceFactory implementation | 297 // service_manager::mojom::ServiceFactory: |
327 | 298 |
328 void CreateService(service_manager::mojom::ServiceRequest request, | 299 void CreateService(service_manager::mojom::ServiceRequest request, |
329 const std::string& name) override { | 300 const std::string& name) override { |
330 DCHECK(io_thread_checker_.CalledOnValidThread()); | 301 DCHECK(io_thread_checker_.CalledOnValidThread()); |
331 auto it = request_handlers_.find(name); | 302 auto it = request_handlers_.find(name); |
332 DCHECK(it != request_handlers_.end()) | 303 DCHECK(it != request_handlers_.end()) |
333 << "Can't create service " << name << ". No handler found."; | 304 << "Can't create service " << name << ". No handler found."; |
334 it->second.Run(std::move(request)); | 305 it->second.Run(std::move(request)); |
335 } | 306 } |
336 | 307 |
337 static void CallBinderOnTaskRunner( | |
338 scoped_refptr<base::SequencedTaskRunner> task_runner, | |
339 const service_manager::InterfaceRegistry::Binder& binder, | |
340 const std::string& interface_name, | |
341 mojo::ScopedMessagePipeHandle request_handle) { | |
342 task_runner->PostTask(FROM_HERE, base::Bind(binder, interface_name, | |
343 base::Passed(&request_handle))); | |
344 } | |
345 | |
346 base::ThreadChecker io_thread_checker_; | 308 base::ThreadChecker io_thread_checker_; |
347 bool started_ = false; | 309 bool started_ = false; |
348 | 310 |
349 // Temporary state established on construction and consumed on the IO thread | 311 // Temporary state established on construction and consumed on the IO thread |
350 // once the connection is started. | 312 // once the connection is started. |
351 service_manager::mojom::ServiceRequest pending_service_request_; | 313 service_manager::mojom::ServiceRequest pending_service_request_; |
352 scoped_refptr<base::SequencedTaskRunner> io_task_runner_; | 314 scoped_refptr<base::SequencedTaskRunner> io_task_runner_; |
353 std::unique_ptr<service_manager::Connector> io_thread_connector_; | 315 std::unique_ptr<service_manager::Connector> io_thread_connector_; |
354 service_manager::mojom::ConnectorRequest pending_connector_request_; | 316 service_manager::mojom::ConnectorRequest pending_connector_request_; |
355 | 317 |
356 // TaskRunner on which to run our owner's callbacks, i.e. the ones passed to | 318 // TaskRunner on which to run our owner's callbacks, i.e. the ones passed to |
357 // Start(). | 319 // Start(). |
358 scoped_refptr<base::SequencedTaskRunner> callback_task_runner_; | 320 scoped_refptr<base::SequencedTaskRunner> callback_task_runner_; |
359 | 321 |
360 // Callback to run once Service::OnStart is invoked. | 322 // Callback to run once Service::OnStart is invoked. |
361 InitializeCallback local_info_available_callback_; | 323 InitializeCallback local_info_available_callback_; |
362 InitializeCallback browser_info_available_callback_; | 324 InitializeCallback browser_info_available_callback_; |
363 | 325 |
364 // Callback to run if the service is stopped by the service manager. | 326 // Callback to run if the service is stopped by the service manager. |
365 base::Closure stop_callback_; | 327 base::Closure stop_callback_; |
366 | 328 |
367 // Called once a connection has been received from the browser process & the | |
368 // default binder (below) has been set up. | |
369 bool has_browser_connection_ = false; | |
370 | |
371 service_manager::ServiceInfo local_info_; | 329 service_manager::ServiceInfo local_info_; |
372 | 330 service_manager::ServiceInfo last_source_info_; |
Ken Rockot(use gerrit already)
2017/04/24 22:36:31
This member variable doesn't seem to be necessary?
| |
373 // Default binder callback used for the browser connection's | |
374 // InterfaceRegistry. | |
375 // | |
376 // TODO(rockot): Remove this once all interfaces exposed to the browser are | |
377 // exposed via a ConnectionFilter. | |
378 service_manager::InterfaceRegistry::Binder default_browser_binder_; | |
379 | 331 |
380 std::unique_ptr<service_manager::ServiceContext> service_context_; | 332 std::unique_ptr<service_manager::ServiceContext> service_context_; |
381 mojo::BindingSet<service_manager::mojom::ServiceFactory> factory_bindings_; | 333 mojo::BindingSet<service_manager::mojom::ServiceFactory> factory_bindings_; |
382 int next_filter_id_ = kInvalidConnectionFilterId; | 334 int next_filter_id_ = kInvalidConnectionFilterId; |
383 | 335 |
384 // Not owned. | 336 // Not owned. |
385 MessageLoopObserver* message_loop_observer_ = nullptr; | 337 MessageLoopObserver* message_loop_observer_ = nullptr; |
386 | 338 |
387 // Guards |connection_filters_|. | 339 // Guards |connection_filters_|. |
388 base::Lock lock_; | 340 base::Lock lock_; |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
484 const service_manager::ServiceInfo& | 436 const service_manager::ServiceInfo& |
485 ServiceManagerConnectionImpl::GetBrowserInfo() const { | 437 ServiceManagerConnectionImpl::GetBrowserInfo() const { |
486 return browser_info_; | 438 return browser_info_; |
487 } | 439 } |
488 | 440 |
489 void ServiceManagerConnectionImpl::SetConnectionLostClosure( | 441 void ServiceManagerConnectionImpl::SetConnectionLostClosure( |
490 const base::Closure& closure) { | 442 const base::Closure& closure) { |
491 connection_lost_handler_ = closure; | 443 connection_lost_handler_ = closure; |
492 } | 444 } |
493 | 445 |
494 void ServiceManagerConnectionImpl::SetupInterfaceRequestProxies( | |
495 service_manager::InterfaceRegistry* registry, | |
496 service_manager::InterfaceProvider* provider) { | |
497 // It's safe to bind |registry| as a raw pointer because the caller must | |
498 // guarantee that it outlives |this|, and |this| is bound as a weak ptr here. | |
499 context_->SetDefaultBinderForBrowserConnection( | |
500 base::Bind(&ServiceManagerConnectionImpl::GetInterface, | |
501 weak_factory_.GetWeakPtr(), registry)); | |
502 | |
503 // TODO(beng): remove provider parameter. | |
504 } | |
505 | |
506 int ServiceManagerConnectionImpl::AddConnectionFilter( | 446 int ServiceManagerConnectionImpl::AddConnectionFilter( |
507 std::unique_ptr<ConnectionFilter> filter) { | 447 std::unique_ptr<ConnectionFilter> filter) { |
508 return context_->AddConnectionFilter(std::move(filter)); | 448 return context_->AddConnectionFilter(std::move(filter)); |
509 } | 449 } |
510 | 450 |
511 void ServiceManagerConnectionImpl::RemoveConnectionFilter(int filter_id) { | 451 void ServiceManagerConnectionImpl::RemoveConnectionFilter(int filter_id) { |
512 context_->RemoveConnectionFilter(filter_id); | 452 context_->RemoveConnectionFilter(filter_id); |
513 } | 453 } |
514 | 454 |
515 void ServiceManagerConnectionImpl::AddEmbeddedService(const std::string& name, | 455 void ServiceManagerConnectionImpl::AddEmbeddedService(const std::string& name, |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
554 } | 494 } |
555 | 495 |
556 void ServiceManagerConnectionImpl::GetInterface( | 496 void ServiceManagerConnectionImpl::GetInterface( |
557 service_manager::mojom::InterfaceProvider* provider, | 497 service_manager::mojom::InterfaceProvider* provider, |
558 const std::string& interface_name, | 498 const std::string& interface_name, |
559 mojo::ScopedMessagePipeHandle request_handle) { | 499 mojo::ScopedMessagePipeHandle request_handle) { |
560 provider->GetInterface(interface_name, std::move(request_handle)); | 500 provider->GetInterface(interface_name, std::move(request_handle)); |
561 } | 501 } |
562 | 502 |
563 } // namespace content | 503 } // namespace content |
OLD | NEW |