| Index: mojo/public/cpp/application/service_provider_impl.h
|
| diff --git a/mojo/public/cpp/application/service_provider_impl.h b/mojo/public/cpp/application/service_provider_impl.h
|
| index 1afa14b21aea02c7dec3f27df062189c8103ba6b..b8859244ddf3337ec30f4fb53f32dcf6b876d6a8 100644
|
| --- a/mojo/public/cpp/application/service_provider_impl.h
|
| +++ b/mojo/public/cpp/application/service_provider_impl.h
|
| @@ -5,27 +5,57 @@
|
| #ifndef MOJO_PUBLIC_APPLICATION_SERVICE_PROVIDER_IMPL_H_
|
| #define MOJO_PUBLIC_APPLICATION_SERVICE_PROVIDER_IMPL_H_
|
|
|
| +#include <functional>
|
| #include <string>
|
|
|
| +#include "mojo/public/cpp/application/application_connection.h"
|
| +#include "mojo/public/cpp/application/connection_context.h"
|
| #include "mojo/public/cpp/application/lib/interface_factory_connector.h"
|
| #include "mojo/public/cpp/application/lib/service_connector_registry.h"
|
| +#include "mojo/public/cpp/application/service_connector.h"
|
| #include "mojo/public/cpp/bindings/binding.h"
|
| #include "mojo/public/interfaces/application/service_provider.mojom.h"
|
|
|
| namespace mojo {
|
|
|
| -// Implements a registry that can be used to expose services to another app.
|
| +// An implementation of |ServiceProvider|, which can be customized appropriately
|
| +// (to select what services it provides).
|
| class ServiceProviderImpl : public ServiceProvider {
|
| public:
|
| + // A |InterfaceRequestHandler<Interface>| is simply a function that handles an
|
| + // interface request for |Interface|. If it determines (e.g., based on the
|
| + // given |ConnectionContext|) that the request should be "accepted", then it
|
| + // should "connect" ("take ownership of") request. Otherwise, it can simply
|
| + // drop |interface_request| (as implied by the interface).
|
| + template <typename Interface>
|
| + using InterfaceRequestHandler =
|
| + std::function<void(const ConnectionContext& connection_context,
|
| + InterfaceRequest<Interface> interface_request)>;
|
| +
|
| + // Constructs this service provider implementation in an unbound state.
|
| ServiceProviderImpl();
|
| - explicit ServiceProviderImpl(InterfaceRequest<ServiceProvider> request);
|
| +
|
| + // Constructs this service provider implementation, binding it to the given
|
| + // interface request.
|
| + // TODO(vtl): This should take a |ConnectionContext|, to provide
|
| + // |InterfaceRequestHandler<I>|s.
|
| + explicit ServiceProviderImpl(
|
| + InterfaceRequest<ServiceProvider> service_provider_request);
|
| +
|
| ~ServiceProviderImpl() override;
|
|
|
| - void Bind(InterfaceRequest<ServiceProvider> request);
|
| - // Disconnect this service provider and put it in a state where it can be
|
| - // rebound to a new request.
|
| + // Binds this service provider implementation to the given interface request.
|
| + // This may only be called if this object is unbound.
|
| + // TODO(vtl): This should take a |ConnectionContext|, to provide
|
| + // |InterfaceRequestHandler<I>|s.
|
| + void Bind(InterfaceRequest<ServiceProvider> service_provider_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();
|
|
|
| + // TODO(vtl): Remove this.
|
| template <typename Interface>
|
| void AddService(InterfaceFactory<Interface>* factory,
|
| const std::string& interface_name = Interface::Name_) {
|
| @@ -35,18 +65,70 @@ class ServiceProviderImpl : public ServiceProvider {
|
| interface_name);
|
| }
|
|
|
| - // ServiceProviderImpl uses the fallback_service_provider_ whenever someone
|
| - // asks a service that doesn't exist in the service_connector_registry_.
|
| + // Adds a supported service with the given |name|, using the given
|
| + // |interface_request_handler| (see above for information about
|
| + // |InterfaceRequestHandler<Interface>|). |interface_request_handler| should
|
| + // remain valid for the lifetime of this object.
|
| //
|
| - // Note: ServiceProviderImpl does not take ownership of |fallback|. The caller
|
| - // must ensure that |fallback| outlives the ServiceProviderImpl.
|
| + // A typical usage may be:
|
| //
|
| - void set_fallback_service_provider(ServiceProvider* fallback) {
|
| - fallback_service_provider_ = fallback;
|
| + // service_provider_impl_->AddServiceNew<Foobar>(
|
| + // [](const ConnectionContext& connection_context,
|
| + // InterfaceRequest<FooBar> foobar_request) {
|
| + // // |FoobarImpl| owns itself.
|
| + // new FoobarImpl(std::move(foobar_request));
|
| + // });
|
| + // TODO(vtl): Remove the AddService() above and rename this to AddService().
|
| + template <typename Interface>
|
| + void AddServiceNew(
|
| + InterfaceRequestHandler<Interface> interface_request_handler,
|
| + const std::string& name = Interface::Name_) {
|
| + service_connector_registry_.SetServiceConnectorForName(
|
| + std::unique_ptr<ServiceConnector>(new ServiceConnectorImpl<Interface>(
|
| + std::move(interface_request_handler))),
|
| + name);
|
| + }
|
| +
|
| + // This uses the provided |fallback_service_provider| for connection requests
|
| + // for services that are not known (haven't been added). (Set it to null to
|
| + // not have any fallback.) A fallback must outlive this object (or until it is
|
| + // "cleared" or replaced by a different fallback.
|
| + void set_fallback_service_provider(
|
| + ServiceProvider* fallback_service_provider) {
|
| + fallback_service_provider_ = fallback_service_provider;
|
| }
|
|
|
| private:
|
| - // Overridden from ServiceProvider:
|
| + // Objects of this class are used to adapt a generic (untyped) connection
|
| + // request (i.e., |ServiceConnector::ConnectToService()|) to the type-safe
|
| + // |InterfaceRequestHandler<Interface>|.
|
| + template <typename Interface>
|
| + class ServiceConnectorImpl : public ServiceConnector {
|
| + public:
|
| + explicit ServiceConnectorImpl(
|
| + InterfaceRequestHandler<Interface> interface_request_handler)
|
| + : interface_request_handler_(std::move(interface_request_handler)) {}
|
| + ~ServiceConnectorImpl() override {}
|
| +
|
| + void ConnectToService(ApplicationConnection* application_connection,
|
| + const std::string& interface_name,
|
| + ScopedMessagePipeHandle client_handle) override {
|
| + // TODO(vtl): This should be given a |const ConnectionContext&|, instead
|
| + // of an |ApplicationConnection*| -- which may be null!
|
| + interface_request_handler_(
|
| + application_connection
|
| + ? application_connection->GetConnectionContext()
|
| + : ConnectionContext(),
|
| + InterfaceRequest<Interface>(client_handle.Pass()));
|
| + }
|
| +
|
| + private:
|
| + const InterfaceRequestHandler<Interface> interface_request_handler_;
|
| +
|
| + MOJO_DISALLOW_COPY_AND_ASSIGN(ServiceConnectorImpl);
|
| + };
|
| +
|
| + // Overridden from |ServiceProvider|:
|
| void ConnectToService(const String& service_name,
|
| ScopedMessagePipeHandle client_handle) override;
|
|
|
|
|