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)); |