Chromium Code Reviews| Index: services/service_manager/public/cpp/service_context.cc |
| diff --git a/services/service_manager/public/cpp/service_context.cc b/services/service_manager/public/cpp/service_context.cc |
| index 4e81468a0855d1b5929e52516db213443ce7d270..c0adcbd6f3e06e13b556be843be0328ed029e962 100644 |
| --- a/services/service_manager/public/cpp/service_context.cc |
| +++ b/services/service_manager/public/cpp/service_context.cc |
| @@ -7,6 +7,7 @@ |
| #include <utility> |
| #include "base/bind.h" |
| +#include "base/lazy_instance.h" |
| #include "base/logging.h" |
| #include "mojo/public/cpp/bindings/interface_request.h" |
| #include "services/service_manager/public/cpp/connector.h" |
| @@ -14,9 +15,57 @@ |
| namespace service_manager { |
| +namespace { |
| + |
| +using ServiceNameToBinderRegistryMap = std::map<std::string, BinderRegistry>; |
| + |
| +base::LazyInstance<std::unique_ptr<ServiceNameToBinderRegistryMap>>::Leaky |
|
blundell
2017/05/16 15:00:14
As an aside, I don't see that the LazyInstance nee
|
| + g_overridden_binder_registries = LAZY_INSTANCE_INITIALIZER; |
| + |
| +// Returns the overridden binder registry which intercepts interface bind |
| +// requests to all |service_name| service instances, returns nullptr if no such |
| +// one. |
| +BinderRegistry* GetGlobalBinderRegistryForService( |
| + const std::string& service_name) { |
| + const auto& registries = g_overridden_binder_registries.Get(); |
| + if (registries) { |
| + auto it = registries->find(service_name); |
| + if (it != registries->end()) |
| + return &it->second; |
| + } |
| + |
| + return nullptr; |
| +} |
| + |
| +} // namespace |
| + |
| //////////////////////////////////////////////////////////////////////////////// |
| // ServiceContext, public: |
| +// static |
| +void ServiceContext::SetGlobalBinderForTesting( |
| + const std::string& service_name, |
| + const std::string& interface_name, |
| + const BinderRegistry::Binder& binder, |
| + const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) { |
| + if (!g_overridden_binder_registries.Get()) { |
| + g_overridden_binder_registries.Get() = |
| + base::MakeUnique<ServiceNameToBinderRegistryMap>(); |
| + } |
| + |
| + (*g_overridden_binder_registries.Get())[service_name].AddInterface( |
| + interface_name, binder, task_runner); |
| +} |
| + |
| +// static |
| +void ServiceContext::ClearGlobalBindersForTesting( |
| + const std::string& service_name) { |
| + if (!g_overridden_binder_registries.Get()) |
| + return; |
| + |
| + g_overridden_binder_registries.Get()->erase(service_name); |
| +} |
| + |
| ServiceContext::ServiceContext( |
| std::unique_ptr<service_manager::Service> service, |
| mojom::ServiceRequest request, |
| @@ -83,6 +132,14 @@ void ServiceContext::OnBindInterface( |
| // Acknowledge the request regardless of whether it's accepted. |
| callback.Run(); |
| + BinderRegistry* global_registry = |
| + GetGlobalBinderRegistryForService(identity_.name()); |
| + if (global_registry && global_registry->CanBindInterface(interface_name)) { |
| + // Just use the binder overridden globally. |
| + global_registry->BindInterface(source_info, interface_name, |
| + std::move(interface_pipe)); |
| + return; |
| + } |
| service_->OnBindInterface(source_info, interface_name, |
| std::move(interface_pipe)); |
| } |