| 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..20ee92a8d235dad84ad72b4bb3a64fdee3862f58 100644
|
| --- a/services/service_manager/public/cpp/service_context.cc
|
| +++ b/services/service_manager/public/cpp/service_context.cc
|
| @@ -7,16 +7,69 @@
|
| #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/binder_registry.h"
|
| #include "services/service_manager/public/cpp/connector.h"
|
| #include "services/service_manager/public/cpp/service.h"
|
|
|
| namespace service_manager {
|
|
|
| +namespace {
|
| +
|
| +using IdentityToBinderRegistryMap = std::map<Identity, BinderRegistry>;
|
| +
|
| +base::LazyInstance<std::unique_ptr<IdentityToBinderRegistryMap>>::Leaky
|
| + g_overridden_binder_registries = LAZY_INSTANCE_INITIALIZER;
|
| +
|
| +// Returns the overridden binder registry which can intercept interface bind
|
| +// requests to the |service|, returns nullptr if no such one.
|
| +BinderRegistry* GetGlobalBinderRegistryForService(const Identity& service) {
|
| + const auto& registries = g_overridden_binder_registries.Get();
|
| + if (registries) {
|
| + // Find the registry matching the exact service identity.
|
| + auto it = registries->find(service);
|
| + if (it != registries->end())
|
| + return &it->second;
|
| + // Find the general registry matching the service name.
|
| + it = registries->find(Identity(service.name()));
|
| + if (it != registries->end())
|
| + return &it->second;
|
| + }
|
| +
|
| + return nullptr;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| ////////////////////////////////////////////////////////////////////////////////
|
| // ServiceContext, public:
|
|
|
| +// static
|
| +void ServiceContext::TestApi::SetGlobalBinder(
|
| + const Identity& service,
|
| + const std::string& interface_name,
|
| + const base::Callback<void(mojo::ScopedMessagePipeHandle)>& binder,
|
| + const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
|
| + if (!g_overridden_binder_registries.Get()) {
|
| + g_overridden_binder_registries.Get() =
|
| + base::MakeUnique<IdentityToBinderRegistryMap>();
|
| + }
|
| +
|
| + (*g_overridden_binder_registries.Get())[service].AddInterface(
|
| + interface_name, binder, task_runner);
|
| +}
|
| +
|
| +// static
|
| +void ServiceContext::TestApi::ClearGlobalBinders(const Identity& service) {
|
| + if (!g_overridden_binder_registries.Get()) {
|
| + return;
|
| + }
|
| +
|
| + g_overridden_binder_registries.Get()->erase(service);
|
| +}
|
| +
|
| ServiceContext::ServiceContext(
|
| std::unique_ptr<service_manager::Service> service,
|
| mojom::ServiceRequest request,
|
| @@ -83,6 +136,14 @@ void ServiceContext::OnBindInterface(
|
| // Acknowledge the request regardless of whether it's accepted.
|
| callback.Run();
|
|
|
| + BinderRegistry* global_registry =
|
| + GetGlobalBinderRegistryForService(identity_);
|
| + 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));
|
| }
|
|
|