Chromium Code Reviews| 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 |