| // Copyright 2016 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // !!! DEPRECATED !!! |
| // New usages should reference sdk/lib/sys/cpp/... |
| |
| #ifndef SRC_LIB_COMPONENT_CPP_SERVICE_PROVIDER_IMPL_H_ |
| #define SRC_LIB_COMPONENT_CPP_SERVICE_PROVIDER_IMPL_H_ |
| |
| #include <fuchsia/sys/cpp/fidl.h> |
| #include <lib/fidl/cpp/binding_set.h> |
| #include <lib/fit/function.h> |
| #include <lib/zx/channel.h> |
| |
| #include <string> |
| #include <unordered_map> |
| #include <utility> |
| |
| namespace component { |
| |
| // An implementation of |ServiceProvider|, which can be customized appropriately |
| // (to select what services it provides). |
| class ServiceProviderImpl : public fuchsia::sys::ServiceProvider { |
| public: |
| // |ServiceConnector| is the generic, type-unsafe interface for objects used |
| // by |ServiceProviderImpl| to connect generic "interface requests" (i.e., |
| // just channels) specified by service name to service implementations. |
| using ServiceConnector = fit::function<void(zx::channel)>; |
| |
| // |DefaultServiceConnector| is the default last resort service connector |
| // which is called when the service provider does not recognize a particular |
| // service name. This may be used to implement service provider delegation |
| // or more complex name-based service resolution strategies. |
| using DefaultServiceConnector = fit::function<void(std::string, zx::channel)>; |
| |
| // Constructs this service provider implementation in an unbound state. |
| ServiceProviderImpl(); |
| |
| // Constructs this service provider implementation, binding it to the given |
| // interface request. Note: If |request| is not valid ("pending"), then the |
| // object will be put into an unbound state. |
| explicit ServiceProviderImpl(fidl::InterfaceRequest<ServiceProvider> request); |
| |
| ~ServiceProviderImpl() override; |
| |
| // Disallow copy and assign. |
| ServiceProviderImpl(const ServiceProviderImpl&) = delete; |
| ServiceProviderImpl& operator=(const ServiceProviderImpl&) = delete; |
| |
| // Binds this service provider implementation to the given interface request. |
| // Multiple bindings may be added. They are automatically removed when closed |
| // remotely. |
| void AddBinding(fidl::InterfaceRequest<ServiceProvider> request); |
| |
| // Disconnect this service provider implementation and put it in a state where |
| // it can be rebound to a new request (i.e., restores this object to an |
| // unbound state). This may be called even if this object is already unbound. |
| void Close(); |
| |
| // Adds a supported service with the given |service_name|, using the given |
| // |service_connector|. |
| void AddServiceForName(ServiceConnector connector, const std::string& service_name); |
| |
| // Adds a supported service with the given |service_name|, using the given |
| // |interface_request_handler|, which should remain valid for the lifetime of |
| // this object. |
| // |
| // A typical usage may be: |
| // |
| // AddService(foobar_bindings_.GetHandler(this)); |
| template <typename Interface> |
| void AddService(fidl::InterfaceRequestHandler<Interface> handler, |
| const std::string& service_name = Interface::Name_) { |
| AddServiceForName( |
| [handler = std::move(handler)](zx::channel channel) { |
| handler(fidl::InterfaceRequest<Interface>(std::move(channel))); |
| }, |
| service_name); |
| } |
| |
| // Removes support for the service with the given |service_name|. |
| void RemoveServiceForName(const std::string& service_name); |
| |
| // Like |RemoveServiceForName()| (above), but designed so that it can be used |
| // like |RemoveService<Interface>()| or even |
| // |RemoveService<Interface>(service_name)| (to parallel |
| // |AddService<Interface>()|). |
| template <typename Interface> |
| void RemoveService(const std::string& service_name = Interface::Name_) { |
| RemoveServiceForName(service_name); |
| } |
| |
| // Sets the default service connector which is called when the service |
| // provider does not recognize a particular service name. This may be used to |
| // implement service provider delegation or more complex name-based service |
| // resolution strategies. |
| // |
| // Calling this function replaces any value set previously by |
| // |SetDefaultServiceConnector| or |SetDefaultServiceProvider|. |
| void SetDefaultServiceConnector(DefaultServiceConnector connector); |
| |
| // Like |SetDefaultServiceConnector| but delegates requests to another |
| // service provider. |
| // |
| // Calling this function replaces any value set previously by |
| // |SetDefaultServiceConnector| or |SetDefaultServiceProvider|. |
| void SetDefaultServiceProvider(fuchsia::sys::ServiceProviderPtr provider); |
| |
| private: |
| // Overridden from |ServiceProvider|: |
| void ConnectToService(std::string service_name, zx::channel client_handle) override; |
| |
| fidl::BindingSet<fuchsia::sys::ServiceProvider> bindings_; |
| |
| std::unordered_map<std::string, ServiceConnector> name_to_service_connector_; |
| DefaultServiceConnector default_service_connector_; |
| }; |
| |
| } // namespace component |
| |
| #endif // SRC_LIB_COMPONENT_CPP_SERVICE_PROVIDER_IMPL_H_ |