| Index: content/common/service_manager/service_manager_connection_impl.cc
|
| diff --git a/content/common/service_manager/service_manager_connection_impl.cc b/content/common/service_manager/service_manager_connection_impl.cc
|
| index 25065a4a16e45769e291eec03139204b68d9fc1e..9e81238aa0a4a53a53cbf5928388dcc0a9d1c9ec 100644
|
| --- a/content/common/service_manager/service_manager_connection_impl.cc
|
| +++ b/content/common/service_manager/service_manager_connection_impl.cc
|
| @@ -19,9 +19,9 @@
|
| #include "content/common/child.mojom.h"
|
| #include "content/common/service_manager/embedded_service_runner.h"
|
| #include "content/public/common/connection_filter.h"
|
| -#include "content/public/common/service_names.mojom.h"
|
| #include "mojo/public/cpp/bindings/binding_set.h"
|
| #include "mojo/public/cpp/system/message_pipe.h"
|
| +#include "services/service_manager/public/cpp/interface_registry.h"
|
| #include "services/service_manager/public/cpp/service.h"
|
| #include "services/service_manager/public/cpp/service_context.h"
|
| #include "services/service_manager/public/interfaces/constants.mojom.h"
|
| @@ -112,6 +112,15 @@
|
| filter_id));
|
| }
|
|
|
| + // Safe to call any time before Start() is called.
|
| + void SetDefaultBinderForBrowserConnection(
|
| + const service_manager::InterfaceRegistry::Binder& binder) {
|
| + DCHECK(!started_);
|
| + default_browser_binder_ = base::Bind(
|
| + &IOThreadContext::CallBinderOnTaskRunner,
|
| + base::ThreadTaskRunnerHandle::Get(), binder);
|
| + }
|
| +
|
| void AddEmbeddedService(const std::string& name, const ServiceInfo& info) {
|
| io_task_runner_->PostTask(
|
| FROM_HERE, base::Bind(&ServiceManagerConnectionImpl::IOThreadContext::
|
| @@ -221,6 +230,11 @@
|
| // by ClearConnectionFiltersOnIOThread() above, so this id might not exist.
|
| if (it != connection_filters_.end())
|
| connection_filters_.erase(it);
|
| + }
|
| +
|
| + void OnBrowserConnectionLost() {
|
| + DCHECK(io_thread_checker_.CalledOnValidThread());
|
| + has_browser_connection_ = false;
|
| }
|
|
|
| void AddEmbeddedServiceRequestHandlerOnIoThread(const std::string& name,
|
| @@ -262,22 +276,18 @@
|
| const std::string& interface_name,
|
| mojo::ScopedMessagePipeHandle interface_pipe) override {
|
| DCHECK(io_thread_checker_.CalledOnValidThread());
|
| - if (source_info.identity.name() == service_manager::mojom::kServiceName &&
|
| +
|
| + std::string remote_service = source_info.identity.name();
|
| + // Only expose the ServiceFactory interface to the Service Manager.
|
| + if (remote_service == service_manager::mojom::kServiceName &&
|
| interface_name == service_manager::mojom::ServiceFactory::Name_) {
|
| factory_bindings_.AddBinding(
|
| this, mojo::MakeRequest<service_manager::mojom::ServiceFactory>(
|
| std::move(interface_pipe)));
|
| - } else if (source_info.identity.name() == mojom::kBrowserServiceName &&
|
| - interface_name == mojom::Child::Name_) {
|
| - DCHECK(!child_binding_.is_bound());
|
| - child_binding_.Bind(
|
| - mojo::MakeRequest<mojom::Child>(std::move(interface_pipe)));
|
| -
|
| - InitializeCallback handler =
|
| - base::ResetAndReturn(&browser_info_available_callback_);
|
| - callback_task_runner_->PostTask(FROM_HERE,
|
| - base::Bind(handler, source_info));
|
| - } else {
|
| + return;
|
| + }
|
| +
|
| + {
|
| base::AutoLock lock(lock_);
|
| for (auto& entry : connection_filters_) {
|
| entry.second->OnBindInterface(source_info, interface_name,
|
| @@ -288,10 +298,32 @@
|
| return;
|
| }
|
| }
|
| +
|
| + if (remote_service == "content_browser") {
|
| + if (interface_name == mojom::Child::Name_ && !has_browser_connection_) {
|
| + has_browser_connection_ = true;
|
| + InitializeCallback handler =
|
| + base::ResetAndReturn(&browser_info_available_callback_);
|
| + callback_task_runner_->PostTask(FROM_HERE,
|
| + base::Bind(handler, source_info));
|
| +
|
| + child_binding_.Bind(std::move(interface_pipe));
|
| + child_binding_.set_connection_error_handler(
|
| + base::Bind(&IOThreadContext::OnBrowserConnectionLost, this));
|
| + } else {
|
| + default_browser_binder_.Run(interface_name, std::move(interface_pipe));
|
| + }
|
| + }
|
| + }
|
| +
|
| + bool OnServiceManagerConnectionLost() override {
|
| + ClearConnectionFiltersOnIOThread();
|
| + callback_task_runner_->PostTask(FROM_HERE, stop_callback_);
|
| + return true;
|
| }
|
|
|
| /////////////////////////////////////////////////////////////////////////////
|
| - // service_manager::mojom::ServiceFactory:
|
| + // service_manager::mojom::ServiceFactory implementation
|
|
|
| void CreateService(service_manager::mojom::ServiceRequest request,
|
| const std::string& name) override {
|
| @@ -300,6 +332,15 @@
|
| DCHECK(it != request_handlers_.end())
|
| << "Can't create service " << name << ". No handler found.";
|
| it->second.Run(std::move(request));
|
| + }
|
| +
|
| + static void CallBinderOnTaskRunner(
|
| + scoped_refptr<base::SequencedTaskRunner> task_runner,
|
| + const service_manager::InterfaceRegistry::Binder& binder,
|
| + const std::string& interface_name,
|
| + mojo::ScopedMessagePipeHandle request_handle) {
|
| + task_runner->PostTask(FROM_HERE, base::Bind(binder, interface_name,
|
| + base::Passed(&request_handle)));
|
| }
|
|
|
| base::ThreadChecker io_thread_checker_;
|
| @@ -323,7 +364,18 @@
|
| // Callback to run if the service is stopped by the service manager.
|
| base::Closure stop_callback_;
|
|
|
| + // Called once a connection has been received from the browser process & the
|
| + // default binder (below) has been set up.
|
| + bool has_browser_connection_ = false;
|
| +
|
| service_manager::ServiceInfo local_info_;
|
| +
|
| + // Default binder callback used for the browser connection's
|
| + // InterfaceRegistry.
|
| + //
|
| + // TODO(rockot): Remove this once all interfaces exposed to the browser are
|
| + // exposed via a ConnectionFilter.
|
| + service_manager::InterfaceRegistry::Binder default_browser_binder_;
|
|
|
| std::unique_ptr<service_manager::ServiceContext> service_context_;
|
| mojo::BindingSet<service_manager::mojom::ServiceFactory> factory_bindings_;
|
| @@ -439,6 +491,18 @@
|
| connection_lost_handler_ = closure;
|
| }
|
|
|
| +void ServiceManagerConnectionImpl::SetupInterfaceRequestProxies(
|
| + service_manager::InterfaceRegistry* registry,
|
| + service_manager::InterfaceProvider* provider) {
|
| + // It's safe to bind |registry| as a raw pointer because the caller must
|
| + // guarantee that it outlives |this|, and |this| is bound as a weak ptr here.
|
| + context_->SetDefaultBinderForBrowserConnection(
|
| + base::Bind(&ServiceManagerConnectionImpl::GetInterface,
|
| + weak_factory_.GetWeakPtr(), registry));
|
| +
|
| + // TODO(beng): remove provider parameter.
|
| +}
|
| +
|
| int ServiceManagerConnectionImpl::AddConnectionFilter(
|
| std::unique_ptr<ConnectionFilter> filter) {
|
| return context_->AddConnectionFilter(std::move(filter));
|
|
|