| 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()); |
| 279 | 265 if (source_info.identity.name() == service_manager::mojom::kServiceName && |
| 280 std::string remote_service = source_info.identity.name(); | |
| 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_) { | 266 interface_name == service_manager::mojom::ServiceFactory::Name_) { |
| 284 factory_bindings_.AddBinding( | 267 factory_bindings_.AddBinding( |
| 285 this, mojo::MakeRequest<service_manager::mojom::ServiceFactory>( | 268 this, mojo::MakeRequest<service_manager::mojom::ServiceFactory>( |
| 286 std::move(interface_pipe))); | 269 std::move(interface_pipe))); |
| 287 return; | 270 } else if (source_info.identity.name() == mojom::kBrowserServiceName && |
| 288 } | 271 interface_name == mojom::Child::Name_) { |
| 272 DCHECK(!child_binding_.is_bound()); |
| 273 child_binding_.Bind( |
| 274 mojo::MakeRequest<mojom::Child>(std::move(interface_pipe))); |
| 289 | 275 |
| 290 { | 276 InitializeCallback handler = |
| 277 base::ResetAndReturn(&browser_info_available_callback_); |
| 278 callback_task_runner_->PostTask(FROM_HERE, |
| 279 base::Bind(handler, source_info)); |
| 280 } else { |
| 291 base::AutoLock lock(lock_); | 281 base::AutoLock lock(lock_); |
| 292 for (auto& entry : connection_filters_) { | 282 for (auto& entry : connection_filters_) { |
| 293 entry.second->OnBindInterface(source_info, interface_name, | 283 entry.second->OnBindInterface(source_info, interface_name, |
| 294 &interface_pipe, | 284 &interface_pipe, |
| 295 service_context_->connector()); | 285 service_context_->connector()); |
| 296 // A filter may have bound the interface, claiming the pipe. | 286 // A filter may have bound the interface, claiming the pipe. |
| 297 if (!interface_pipe.is_valid()) | 287 if (!interface_pipe.is_valid()) |
| 298 return; | 288 return; |
| 299 } | 289 } |
| 300 } | 290 } |
| 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 } | 291 } |
| 318 | 292 |
| 319 bool OnServiceManagerConnectionLost() override { | 293 bool OnServiceManagerConnectionLost() override { |
| 320 ClearConnectionFiltersOnIOThread(); | 294 ClearConnectionFiltersOnIOThread(); |
| 321 callback_task_runner_->PostTask(FROM_HERE, stop_callback_); | 295 callback_task_runner_->PostTask(FROM_HERE, stop_callback_); |
| 322 return true; | 296 return true; |
| 323 } | 297 } |
| 324 | 298 |
| 325 ///////////////////////////////////////////////////////////////////////////// | 299 ///////////////////////////////////////////////////////////////////////////// |
| 326 // service_manager::mojom::ServiceFactory implementation | 300 // service_manager::mojom::ServiceFactory: |
| 327 | 301 |
| 328 void CreateService(service_manager::mojom::ServiceRequest request, | 302 void CreateService(service_manager::mojom::ServiceRequest request, |
| 329 const std::string& name) override { | 303 const std::string& name) override { |
| 330 DCHECK(io_thread_checker_.CalledOnValidThread()); | 304 DCHECK(io_thread_checker_.CalledOnValidThread()); |
| 331 auto it = request_handlers_.find(name); | 305 auto it = request_handlers_.find(name); |
| 332 DCHECK(it != request_handlers_.end()) | 306 DCHECK(it != request_handlers_.end()) |
| 333 << "Can't create service " << name << ". No handler found."; | 307 << "Can't create service " << name << ". No handler found."; |
| 334 it->second.Run(std::move(request)); | 308 it->second.Run(std::move(request)); |
| 335 } | 309 } |
| 336 | 310 |
| 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_; | 311 base::ThreadChecker io_thread_checker_; |
| 347 bool started_ = false; | 312 bool started_ = false; |
| 348 | 313 |
| 349 // Temporary state established on construction and consumed on the IO thread | 314 // Temporary state established on construction and consumed on the IO thread |
| 350 // once the connection is started. | 315 // once the connection is started. |
| 351 service_manager::mojom::ServiceRequest pending_service_request_; | 316 service_manager::mojom::ServiceRequest pending_service_request_; |
| 352 scoped_refptr<base::SequencedTaskRunner> io_task_runner_; | 317 scoped_refptr<base::SequencedTaskRunner> io_task_runner_; |
| 353 std::unique_ptr<service_manager::Connector> io_thread_connector_; | 318 std::unique_ptr<service_manager::Connector> io_thread_connector_; |
| 354 service_manager::mojom::ConnectorRequest pending_connector_request_; | 319 service_manager::mojom::ConnectorRequest pending_connector_request_; |
| 355 | 320 |
| 356 // TaskRunner on which to run our owner's callbacks, i.e. the ones passed to | 321 // TaskRunner on which to run our owner's callbacks, i.e. the ones passed to |
| 357 // Start(). | 322 // Start(). |
| 358 scoped_refptr<base::SequencedTaskRunner> callback_task_runner_; | 323 scoped_refptr<base::SequencedTaskRunner> callback_task_runner_; |
| 359 | 324 |
| 360 // Callback to run once Service::OnStart is invoked. | 325 // Callback to run once Service::OnStart is invoked. |
| 361 InitializeCallback local_info_available_callback_; | 326 InitializeCallback local_info_available_callback_; |
| 362 InitializeCallback browser_info_available_callback_; | 327 InitializeCallback browser_info_available_callback_; |
| 363 | 328 |
| 364 // Callback to run if the service is stopped by the service manager. | 329 // Callback to run if the service is stopped by the service manager. |
| 365 base::Closure stop_callback_; | 330 base::Closure stop_callback_; |
| 366 | 331 |
| 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_; | 332 service_manager::ServiceInfo local_info_; |
| 372 | 333 |
| 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 | |
| 380 std::unique_ptr<service_manager::ServiceContext> service_context_; | 334 std::unique_ptr<service_manager::ServiceContext> service_context_; |
| 381 mojo::BindingSet<service_manager::mojom::ServiceFactory> factory_bindings_; | 335 mojo::BindingSet<service_manager::mojom::ServiceFactory> factory_bindings_; |
| 382 int next_filter_id_ = kInvalidConnectionFilterId; | 336 int next_filter_id_ = kInvalidConnectionFilterId; |
| 383 | 337 |
| 384 // Not owned. | 338 // Not owned. |
| 385 MessageLoopObserver* message_loop_observer_ = nullptr; | 339 MessageLoopObserver* message_loop_observer_ = nullptr; |
| 386 | 340 |
| 387 // Guards |connection_filters_|. | 341 // Guards |connection_filters_|. |
| 388 base::Lock lock_; | 342 base::Lock lock_; |
| 389 std::map<int, std::unique_ptr<ConnectionFilter>> connection_filters_; | 343 std::map<int, std::unique_ptr<ConnectionFilter>> connection_filters_; |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 484 const service_manager::ServiceInfo& | 438 const service_manager::ServiceInfo& |
| 485 ServiceManagerConnectionImpl::GetBrowserInfo() const { | 439 ServiceManagerConnectionImpl::GetBrowserInfo() const { |
| 486 return browser_info_; | 440 return browser_info_; |
| 487 } | 441 } |
| 488 | 442 |
| 489 void ServiceManagerConnectionImpl::SetConnectionLostClosure( | 443 void ServiceManagerConnectionImpl::SetConnectionLostClosure( |
| 490 const base::Closure& closure) { | 444 const base::Closure& closure) { |
| 491 connection_lost_handler_ = closure; | 445 connection_lost_handler_ = closure; |
| 492 } | 446 } |
| 493 | 447 |
| 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( | 448 int ServiceManagerConnectionImpl::AddConnectionFilter( |
| 507 std::unique_ptr<ConnectionFilter> filter) { | 449 std::unique_ptr<ConnectionFilter> filter) { |
| 508 return context_->AddConnectionFilter(std::move(filter)); | 450 return context_->AddConnectionFilter(std::move(filter)); |
| 509 } | 451 } |
| 510 | 452 |
| 511 void ServiceManagerConnectionImpl::RemoveConnectionFilter(int filter_id) { | 453 void ServiceManagerConnectionImpl::RemoveConnectionFilter(int filter_id) { |
| 512 context_->RemoveConnectionFilter(filter_id); | 454 context_->RemoveConnectionFilter(filter_id); |
| 513 } | 455 } |
| 514 | 456 |
| 515 void ServiceManagerConnectionImpl::AddEmbeddedService(const std::string& name, | 457 void ServiceManagerConnectionImpl::AddEmbeddedService(const std::string& name, |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 554 } | 496 } |
| 555 | 497 |
| 556 void ServiceManagerConnectionImpl::GetInterface( | 498 void ServiceManagerConnectionImpl::GetInterface( |
| 557 service_manager::mojom::InterfaceProvider* provider, | 499 service_manager::mojom::InterfaceProvider* provider, |
| 558 const std::string& interface_name, | 500 const std::string& interface_name, |
| 559 mojo::ScopedMessagePipeHandle request_handle) { | 501 mojo::ScopedMessagePipeHandle request_handle) { |
| 560 provider->GetInterface(interface_name, std::move(request_handle)); | 502 provider->GetInterface(interface_name, std::move(request_handle)); |
| 561 } | 503 } |
| 562 | 504 |
| 563 } // namespace content | 505 } // namespace content |
| OLD | NEW |