diff options
author | davemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-25 21:57:02 +0000 |
---|---|---|
committer | davemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-25 21:57:02 +0000 |
commit | 8fc44a9f0c97c5f2e61fc8125a4822a057c67446 (patch) | |
tree | 0e3745a55a87d85cc5463b4a157aadccd0713c45 /mojo/public/cpp/application | |
parent | cf0c55a04cc3cb7e996d823eaf574e70d305a303 (diff) | |
download | chromium_src-8fc44a9f0c97c5f2e61fc8125a4822a057c67446.zip chromium_src-8fc44a9f0c97c5f2e61fc8125a4822a057c67446.tar.gz chromium_src-8fc44a9f0c97c5f2e61fc8125a4822a057c67446.tar.bz2 |
Split ServiceProvider into 3
BUG=
R=darin@chromium.org, qsr@chromium.org
Review URL: https://codereview.chromium.org/347333002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@279830 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'mojo/public/cpp/application')
16 files changed, 467 insertions, 241 deletions
diff --git a/mojo/public/cpp/application/application.h b/mojo/public/cpp/application/application.h deleted file mode 100644 index da7a0ed..0000000 --- a/mojo/public/cpp/application/application.h +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MOJO_PUBLIC_APPLICATION_APPLICATION_H_ -#define MOJO_PUBLIC_APPLICATION_APPLICATION_H_ -#include <vector> - -#include "mojo/public/cpp/application/connect.h" -#include "mojo/public/cpp/application/lib/service_connector.h" -#include "mojo/public/cpp/system/core.h" -#include "mojo/public/interfaces/service_provider/service_provider.mojom.h" - -#if defined(WIN32) -#if !defined(CDECL) -#define CDECL __cdecl -#endif -#define APPLICATION_EXPORT __declspec(dllexport) -#else -#define CDECL -#define APPLICATION_EXPORT __attribute__((visibility("default"))) -#endif - -// DSOs can either implement MojoMain directly or include -// mojo_main_{standalone|chromium}.cc in their project and implement -// Application::Create(); -// TODO(davemoore): Establish this as part of our SDK for third party mojo -// application writers. -extern "C" APPLICATION_EXPORT MojoResult CDECL MojoMain( - MojoHandle service_provider_handle); - -namespace mojo { - -// Utility class for creating ServiceProviders that vend service instances. -// To use define a class that implements your specific server api, e.g. FooImpl -// to implement a service named Foo. -// That class must subclass an InterfaceImpl specialization. -// -// If there is context that is to be shared amongst all instances, define a -// constructor with that class as its only argument, otherwise define an empty -// constructor. -// -// class FooImpl : public InterfaceImpl<Foo> { -// public: -// FooImpl() {} -// }; -// -// or -// -// class BarImpl : public InterfaceImpl<Bar> { -// public: -// // context will remain valid for the lifetime of BarImpl. -// BarImpl(BarContext* context) : context_(context) {} -// private: -// BarContext* context; -// }; -// -// Create an Application instance that collects any service implementations. -// -// Application app(service_provider_handle); -// app.AddService<FooImpl>(); -// -// BarContext context; -// app.AddService<BarImpl>(&context); -// -// -class Application { - public: - Application(); - explicit Application(ScopedMessagePipeHandle service_provider_handle); - explicit Application(MojoHandle service_provider_handle); - virtual ~Application(); - - // Override this method to control what urls are allowed to connect to a - // service. - virtual bool AllowIncomingConnection(const mojo::String& service_name, - const mojo::String& requestor_url); - - template <typename Impl, typename Context> - void AddService(Context* context) { - service_registry_.AddServiceConnector( - new internal::ServiceConnector<Impl, Context>(Impl::Name_, context)); - } - - template <typename Impl> - void AddService() { - service_registry_.AddServiceConnector( - new internal::ServiceConnector<Impl, void>(Impl::Name_, NULL)); - } - - template <typename Interface> - void ConnectTo(const std::string& url, InterfacePtr<Interface>* ptr) { - mojo::ConnectToService(service_provider(), url, ptr); - } - - ServiceProvider* service_provider() { - return service_registry_.remote_service_provider(); - } - - void BindServiceProvider(ScopedMessagePipeHandle service_provider_handle); - - protected: - // Override this to do any necessary initialization. There's no need to call - // Application's implementation. - // The service_provider will be bound to its pipe before this is called. - virtual void Initialize(); - - private: - friend MojoResult (::MojoMain)(MojoHandle); - - // Implement this method to create the specific subclass of Application. - static Application* Create(); - - internal::ServiceRegistry service_registry_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(Application); -}; - -} // namespace mojo - -#endif // MOJO_PUBLIC_APPLICATION_APPLICATION_H_ diff --git a/mojo/public/cpp/application/application_connection.h b/mojo/public/cpp/application/application_connection.h new file mode 100644 index 0000000..2044af1 --- /dev/null +++ b/mojo/public/cpp/application/application_connection.h @@ -0,0 +1,106 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MOJO_PUBLIC_APPLICATION_APPLICATION_CONNECTION_H_ +#define MOJO_PUBLIC_APPLICATION_APPLICATION_CONNECTION_H_ + +#include <string> + +#include "mojo/public/cpp/application/lib/service_connector.h" + +namespace mojo { + +// An instance of this class is passed to +// ApplicationDelegate's ConfigureIncomingConnection() method each time a +// connection is made to this app, and to ApplicationDelegate's +// ConfigureOutgoingConnection() method when the app connects to +// another. +// +// To use define a class that implements your specific service api, e.g. FooImpl +// to implement a service named Foo. +// That class must subclass an InterfaceImpl specialization. +// +// If there is context that is to be shared amongst all instances, define a +// constructor with that class as its only argument, otherwise define an empty +// constructor. +// +// class FooImpl : public InterfaceImpl<Foo> { +// public: +// explicit FooImpl(ApplicationConnnection* connection) {} +// }; +// +// or +// +// class BarImpl : public InterfaceImpl<Bar> { +// public: +// // contexts will remain valid for the lifetime of BarImpl. +// BarImpl(ApplicationConnnection* connection, BarContext* service_context) +// : connection_(connection), servicecontext_(context) {} +// +// Create an ApplicationDelegate instance and pass it to the constructor +// of an ApplicationImpl. The delegate will be called when new connections are +// made to other applications. +// +// connection->AddService<FooImpl>(); +// +// BarContext context; +// connection->AddService<BarImpl>(&context); +class ApplicationConnection { + public: + virtual ~ApplicationConnection(); + + // Impl’s constructor will receive two arguments: + // Impl::Impl(Application::Context* app_context, + // ServiceContext* svc_context) + template <typename Impl, typename ServiceContext> + void AddService(ServiceContext* context) { + AddServiceConnector( + new internal::ServiceConnector<Impl, ServiceContext>(Impl::Name_, + context)); + } + + // Impl’s constructor will receive one argument: + // Impl::Impl(Application::Context* app_context) + template <typename Impl> + void AddService() { + AddServiceConnector( + new internal::ServiceConnector<Impl, void>(Impl::Name_, NULL)); + } + + // Connect to the service implementing |Interface|. + template <typename Interface> + void ConnectToService(InterfacePtr<Interface>* ptr) { + MessagePipe pipe; + ptr->Bind(pipe.handle0.Pass()); + GetServiceProvider()->ConnectToService(Interface::Name_, + pipe.handle1.Pass()); + } + + // The url identifying the application on the other end of this connection. + virtual const std::string& GetRemoteApplicationURL() = 0; + + // Establishes a new connection to an application. + // TODO(davemoore): Would it be better to expose the ApplicationImpl? + virtual ApplicationConnection* ConnectToApplication( + const std::string& url) = 0; + + // Connect to application identified by |application_url| and connect to + // the service implementation of the interface identified by |Interface|. + template <typename Interface> + void ConnectToService(const std::string& application_url, + InterfacePtr<Interface>* ptr) { + ConnectToApplication(application_url)->ConnectToService(ptr); + } + + // Raw ServiceProvider interface to remote application. + virtual ServiceProvider* GetServiceProvider() = 0; + +private: + virtual void AddServiceConnector( + internal::ServiceConnectorBase* service_connector) = 0; +}; + +} // namespace mojo + +#endif // MOJO_PUBLIC_APPLICATION_APPLICATION_CONNECTION_H_ diff --git a/mojo/public/cpp/application/application_delegate.h b/mojo/public/cpp/application/application_delegate.h new file mode 100644 index 0000000..cb67308 --- /dev/null +++ b/mojo/public/cpp/application/application_delegate.h @@ -0,0 +1,44 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MOJO_PUBLIC_APPLICATION_APPLICATION_DELEGATE_H_ +#define MOJO_PUBLIC_APPLICATION_APPLICATION_DELEGATE_H_ + +#include <string> + +#include "mojo/public/cpp/system/macros.h" + +namespace mojo { + +class ApplicationConnection; +class ApplicationImpl; + +class ApplicationDelegate { + public: + ApplicationDelegate(); + virtual ~ApplicationDelegate(); + + // Implement this method to create the specific subclass of + // ApplicationDelegate. Ownership is taken by the caller. It will be deleted. + static ApplicationDelegate* Create(); + + virtual void Initialize(ApplicationImpl* app); + + // Override this method to configure what services a connection supports when + // being connected to from an app. + // return false to reject the connection entirely. + virtual bool ConfigureIncomingConnection(ApplicationConnection* connection); + + // Override this method to configure what services a connection supports when + // connecting to another app. + // return false to reject the connection entirely. + virtual bool ConfigureOutgoingConnection(ApplicationConnection* connection); + + private: + MOJO_DISALLOW_COPY_AND_ASSIGN(ApplicationDelegate); +}; + +} // namespace mojo + +#endif // MOJO_PUBLIC_APPLICATION_APPLICATION_DELEGATE_H_ diff --git a/mojo/public/cpp/application/application_impl.h b/mojo/public/cpp/application/application_impl.h new file mode 100644 index 0000000..8f7a842 --- /dev/null +++ b/mojo/public/cpp/application/application_impl.h @@ -0,0 +1,111 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MOJO_PUBLIC_APPLICATION_APPLICATION_IMPL_H_ +#define MOJO_PUBLIC_APPLICATION_APPLICATION_IMPL_H_ +#include <vector> + +#include "mojo/public/cpp/application/application_connection.h" +#include "mojo/public/cpp/application/lib/service_connector.h" +#include "mojo/public/cpp/application/lib/service_registry.h" +#include "mojo/public/cpp/system/core.h" +#include "mojo/public/interfaces/service_provider/service_provider.mojom.h" + +#if defined(WIN32) +#if !defined(CDECL) +#define CDECL __cdecl +#endif +#define APPLICATION_EXPORT __declspec(dllexport) +#else +#define CDECL +#define APPLICATION_EXPORT __attribute__((visibility("default"))) +#endif + +// DSOs can either implement MojoMain directly or include +// mojo_main_{standalone|chromium}.cc in their project and implement +// ApplicationImpl::Create(); +// TODO(davemoore): Establish this as part of our SDK for third party mojo +// application writers. +extern "C" APPLICATION_EXPORT MojoResult CDECL MojoMain( + MojoHandle service_provider_handle); + +namespace mojo { + +class ApplicationDelegate; + +// Utility class for communicating with the Shell, and providing Services +// to clients. +// +// To use define a class that implements your specific server api, e.g. FooImpl +// to implement a service named Foo. +// That class must subclass an InterfaceImpl specialization. +// +// If there is context that is to be shared amongst all instances, define a +// constructor with that class as its only argument, otherwise define an empty +// constructor. +// +// class FooImpl : public InterfaceImpl<Foo> { +// public: +// FooImpl(ApplicationContext* app_context) {} +// }; +// +// or +// +// class BarImpl : public InterfaceImpl<Bar> { +// public: +// // contexts will remain valid for the lifetime of BarImpl. +// BarImpl(ApplicationContext* app_context, BarContext* service_context) +// : app_context_(app_context), servicecontext_(context) {} +// +// Create an ApplicationDele instance that collects any service implementations. +// +// ApplicationImpl app(service_provider_handle); +// app.AddService<FooImpl>(); +// +// BarContext context; +// app.AddService<BarImpl>(&context); +// +// +class ApplicationImpl : public InterfaceImpl<Application> { + public: + explicit ApplicationImpl(ApplicationDelegate* delegate); + ApplicationImpl(ApplicationDelegate* delegate, + ScopedMessagePipeHandle shell_handle); + ApplicationImpl(ApplicationDelegate* delegate, + MojoHandle shell_handle); + virtual ~ApplicationImpl(); + + // Establishes a new connection to an application. Caller does not own. + ApplicationConnection* ConnectToApplication(const String& application_url); + + // Connect to application identified by |application_url| and connect to + // an the service implementation of the interface identified by |Interface|. + template <typename Interface> + void ConnectToService(const std::string& application_url, + InterfacePtr<Interface>* ptr) { + ConnectToApplication(application_url)->ConnectToService(ptr); + } + + private: + friend MojoResult (::MojoMain)(MojoHandle); + + void BindShell(ScopedMessagePipeHandle shell_handle); + void BindShell(MojoHandle shell_handle); + + // Application implementation. + virtual void AcceptConnection(const String& requestor_url, + ServiceProviderPtr provider) MOJO_OVERRIDE; + + typedef std::vector<internal::ServiceRegistry*> ServiceRegistryList; + ServiceRegistryList incoming_service_registries_; + ServiceRegistryList outgoing_service_registries_; + ApplicationDelegate* delegate_; + ShellPtr shell_; + + MOJO_DISALLOW_COPY_AND_ASSIGN(ApplicationImpl); +}; + +} // namespace mojo + +#endif // MOJO_PUBLIC_APPLICATION_APPLICATION_IMPL_H_ diff --git a/mojo/public/cpp/application/connect.h b/mojo/public/cpp/application/connect.h index e4ba641..7160316 100644 --- a/mojo/public/cpp/application/connect.h +++ b/mojo/public/cpp/application/connect.h @@ -11,12 +11,10 @@ namespace mojo { template <typename Interface> inline void ConnectToService(ServiceProvider* service_provider, - const std::string& url, InterfacePtr<Interface>* ptr) { MessagePipe pipe; ptr->Bind(pipe.handle0.Pass()); - service_provider->ConnectToService( - url, Interface::Name_, pipe.handle1.Pass(), std::string()); + service_provider->ConnectToService(Interface::Name_, pipe.handle1.Pass()); } } // namespace mojo diff --git a/mojo/public/cpp/application/lib/application.cc b/mojo/public/cpp/application/lib/application.cc deleted file mode 100644 index 78f5a8b..0000000 --- a/mojo/public/cpp/application/lib/application.cc +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "mojo/public/cpp/application/application.h" - -namespace mojo { - -Application::Application() : service_registry_(this) {} - -Application::Application(ScopedMessagePipeHandle service_provider_handle) - : service_registry_(this, service_provider_handle.Pass()) {} - -Application::Application(MojoHandle service_provider_handle) - : service_registry_( - this, - mojo::MakeScopedHandle( - MessagePipeHandle(service_provider_handle)).Pass()) {} - -Application::~Application() {} - -bool Application::AllowIncomingConnection(const mojo::String& service_name, - const mojo::String& requestor_url) { - return true; -} - -void Application::BindServiceProvider( - ScopedMessagePipeHandle service_provider_handle) { - service_registry_.BindRemoteServiceProvider(service_provider_handle.Pass()); -} - -void Application::Initialize() {} - -} // namespace mojo diff --git a/mojo/public/cpp/application/lib/application_connection.cc b/mojo/public/cpp/application/lib/application_connection.cc new file mode 100644 index 0000000..4978a35 --- /dev/null +++ b/mojo/public/cpp/application/lib/application_connection.cc @@ -0,0 +1,12 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "mojo/public/cpp/application/application_connection.h" + +namespace mojo { + +ApplicationConnection::~ApplicationConnection() {} + +} // namespace mojo + diff --git a/mojo/public/cpp/application/lib/application_delegate.cc b/mojo/public/cpp/application/lib/application_delegate.cc new file mode 100644 index 0000000..715daa0 --- /dev/null +++ b/mojo/public/cpp/application/lib/application_delegate.cc @@ -0,0 +1,24 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "mojo/public/cpp/application/application_delegate.h" + +namespace mojo { + +ApplicationDelegate::ApplicationDelegate() {} +ApplicationDelegate::~ApplicationDelegate() {} + +void ApplicationDelegate::Initialize(ApplicationImpl* app) {} + +bool ApplicationDelegate::ConfigureIncomingConnection( + ApplicationConnection* connection) { + return true; +} + +bool ApplicationDelegate::ConfigureOutgoingConnection( + ApplicationConnection* connection) { + return true; +} + +} // namespace mojo diff --git a/mojo/public/cpp/application/lib/application_impl.cc b/mojo/public/cpp/application/lib/application_impl.cc new file mode 100644 index 0000000..f5831aa --- /dev/null +++ b/mojo/public/cpp/application/lib/application_impl.cc @@ -0,0 +1,74 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "mojo/public/cpp/application/application_impl.h" + +#include "mojo/public/cpp/application/application_delegate.h" +#include "mojo/public/cpp/application/lib/service_registry.h" +#include "mojo/public/cpp/bindings/interface_ptr.h" + +namespace mojo { + +ApplicationImpl::ApplicationImpl(ApplicationDelegate* delegate) + : delegate_(delegate) {} + +ApplicationImpl::ApplicationImpl(ApplicationDelegate* delegate, + ScopedMessagePipeHandle shell_handle) + : delegate_(delegate) { + BindShell(shell_handle.Pass()); +} + +ApplicationImpl::ApplicationImpl(ApplicationDelegate* delegate, + MojoHandle shell_handle) + : delegate_(delegate) { + BindShell(shell_handle); +} + +ApplicationImpl::~ApplicationImpl() { + for (ServiceRegistryList::iterator i(incoming_service_registries_.begin()); + i != incoming_service_registries_.end(); ++i) + delete *i; + for (ServiceRegistryList::iterator i(outgoing_service_registries_.begin()); + i != outgoing_service_registries_.end(); ++i) + delete *i; +} + +ApplicationConnection* ApplicationImpl::ConnectToApplication( + const String& application_url) { + ServiceProviderPtr out_service_provider; + shell_->ConnectToApplication(application_url, Get(&out_service_provider)); + internal::ServiceRegistry* registry = new internal::ServiceRegistry( + this, + application_url, + out_service_provider.Pass()); + if (!delegate_->ConfigureOutgoingConnection(registry)) { + delete registry; + return NULL; + } + outgoing_service_registries_.push_back(registry); + return registry; +} + +void ApplicationImpl::BindShell(ScopedMessagePipeHandle shell_handle) { + shell_.Bind(shell_handle.Pass()); + shell_.set_client(this); + delegate_->Initialize(this); +} + +void ApplicationImpl::BindShell(MojoHandle shell_handle) { + BindShell(mojo::MakeScopedHandle(mojo::MessagePipeHandle(shell_handle))); +} + +void ApplicationImpl::AcceptConnection(const String& requestor_url, + ServiceProviderPtr service_provider) { + internal::ServiceRegistry* registry = new internal::ServiceRegistry( + this, requestor_url, service_provider.Pass()); + if (!delegate_->ConfigureIncomingConnection(registry)) { + delete registry; + return; + } + incoming_service_registries_.push_back(registry); +} + +} // namespace mojo diff --git a/mojo/public/cpp/application/lib/mojo_main_chromium.cc b/mojo/public/cpp/application/lib/mojo_main_chromium.cc index cda7cd0..6eb0c63 100644 --- a/mojo/public/cpp/application/lib/mojo_main_chromium.cc +++ b/mojo/public/cpp/application/lib/mojo_main_chromium.cc @@ -5,18 +5,18 @@ #include "base/at_exit.h" #include "base/command_line.h" #include "base/message_loop/message_loop.h" -#include "mojo/public/cpp/application/application.h" +#include "mojo/public/cpp/application/application_delegate.h" +#include "mojo/public/cpp/application/application_impl.h" extern "C" APPLICATION_EXPORT MojoResult CDECL MojoMain( - MojoHandle service_provider_handle) { + MojoHandle shell_handle) { base::CommandLine::Init(0, NULL); base::AtExitManager at_exit; base::MessageLoop loop; - - scoped_ptr<mojo::Application> app(mojo::Application::Create()); - app->BindServiceProvider( - mojo::MakeScopedHandle(mojo::MessagePipeHandle(service_provider_handle))); - app->Initialize(); + scoped_ptr<mojo::ApplicationDelegate> delegate( + mojo::ApplicationDelegate::Create()); + mojo::ApplicationImpl app(delegate.get()); + app.BindShell(shell_handle); loop.Run(); return MOJO_RESULT_OK; diff --git a/mojo/public/cpp/application/lib/mojo_main_standalone.cc b/mojo/public/cpp/application/lib/mojo_main_standalone.cc index 05825aa..0ba078b 100644 --- a/mojo/public/cpp/application/lib/mojo_main_standalone.cc +++ b/mojo/public/cpp/application/lib/mojo_main_standalone.cc @@ -2,21 +2,22 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "mojo/public/cpp/application/application.h" +#include "mojo/public/cpp/application/application_delegate.h" +#include "mojo/public/cpp/application/application_impl.h" #include "mojo/public/cpp/environment/environment.h" #include "mojo/public/cpp/utility/run_loop.h" extern "C" APPLICATION_EXPORT MojoResult CDECL MojoMain( - MojoHandle service_provider_handle) { + MojoHandle shell_handle) { mojo::Environment env; mojo::RunLoop loop; - - mojo::Application* app = mojo::Application::Create(); - app->BindServiceProvider( - mojo::MakeScopedHandle(mojo::MessagePipeHandle(service_provider_handle))); - app->Initialize(); - loop.Run(); - delete app; + mojo::ApplicationDelegate* delegate = mojo::ApplicationDelegate::Create(); + { + mojo::ApplicationImpl app(delegate); + app.BindShell(shell_handle); + loop.Run(); + } + delete delegate; return MOJO_RESULT_OK; } diff --git a/mojo/public/cpp/application/lib/service_connector.cc b/mojo/public/cpp/application/lib/service_connector.cc index 5cc4421..1a52b62 100644 --- a/mojo/public/cpp/application/lib/service_connector.cc +++ b/mojo/public/cpp/application/lib/service_connector.cc @@ -9,7 +9,7 @@ namespace internal { ServiceConnectorBase::ServiceConnectorBase(const std::string& name) : name_(name), - registry_(NULL) { + application_connection_(NULL) { } ServiceConnectorBase::~ServiceConnectorBase() {} diff --git a/mojo/public/cpp/application/lib/service_connector.h b/mojo/public/cpp/application/lib/service_connector.h index 30786ad..d2de48b 100644 --- a/mojo/public/cpp/application/lib/service_connector.h +++ b/mojo/public/cpp/application/lib/service_connector.h @@ -9,10 +9,11 @@ #include <vector> -#include "mojo/public/cpp/application/lib/service_registry.h" #include "mojo/public/interfaces/service_provider/service_provider.mojom.h" namespace mojo { +class ApplicationConnection; + namespace internal { template <class ServiceImpl, typename Context> @@ -24,8 +25,10 @@ class ServiceConnector; template <class ServiceImpl, typename Context> class ServiceConnection : public ServiceImpl { public: - ServiceConnection() : ServiceImpl() {} - ServiceConnection(Context* context) : ServiceImpl(context) {} + explicit ServiceConnection(ApplicationConnection* connection) + : ServiceImpl(connection) {} + ServiceConnection(ApplicationConnection* connection, + Context* context) : ServiceImpl(connection, context) {} virtual void OnConnectionError() MOJO_OVERRIDE { service_connector_->RemoveConnection(static_cast<ServiceImpl*>(this)); @@ -48,16 +51,21 @@ private: template <typename ServiceImpl, typename Context> struct ServiceConstructor { - static ServiceConnection<ServiceImpl, Context>* New(Context* context) { - return new ServiceConnection<ServiceImpl, Context>(context); + static ServiceConnection<ServiceImpl, Context>* New( + ApplicationConnection* connection, + Context* context) { + return new ServiceConnection<ServiceImpl, Context>( + connection, context); } }; template <typename ServiceImpl> struct ServiceConstructor<ServiceImpl, void> { public: - static ServiceConnection<ServiceImpl, void>* New(void* context) { - return new ServiceConnection<ServiceImpl, void>(); + static ServiceConnection<ServiceImpl, void>* New( + ApplicationConnection* connection, + void* context) { + return new ServiceConnection<ServiceImpl, void>(connection); } }; @@ -65,15 +73,15 @@ class ServiceConnectorBase { public: ServiceConnectorBase(const std::string& name); virtual ~ServiceConnectorBase(); - virtual void ConnectToService(const std::string& url, - const std::string& name, + virtual void ConnectToService(const std::string& name, ScopedMessagePipeHandle client_handle) = 0; std::string name() const { return name_; } - void set_registry(ServiceRegistry* registry) { registry_ = registry; } + void set_application_connection(ApplicationConnection* connection) { + application_connection_ = connection; } protected: std::string name_; - ServiceRegistry* registry_; + ApplicationConnection* application_connection_; MOJO_DISALLOW_COPY_AND_ASSIGN(ServiceConnectorBase); }; @@ -94,11 +102,11 @@ class ServiceConnector : public internal::ServiceConnectorBase { assert(connections_.empty()); // No one should have added more! } - virtual void ConnectToService(const std::string& url, - const std::string& name, + virtual void ConnectToService(const std::string& name, ScopedMessagePipeHandle handle) MOJO_OVERRIDE { ServiceConnection<ServiceImpl, Context>* impl = - ServiceConstructor<ServiceImpl, Context>::New(context_); + ServiceConstructor<ServiceImpl, Context>::New(application_connection_, + context_); impl->set_service_connector(this); BindToPipe(impl, handle.Pass()); diff --git a/mojo/public/cpp/application/lib/service_registry.cc b/mojo/public/cpp/application/lib/service_registry.cc index 44b51ef..1bb061b 100644 --- a/mojo/public/cpp/application/lib/service_registry.cc +++ b/mojo/public/cpp/application/lib/service_registry.cc @@ -4,24 +4,24 @@ #include "mojo/public/cpp/application/lib/service_registry.h" -#include "mojo/public/cpp/application/application.h" +#include "mojo/public/cpp/application/application_connection.h" +#include "mojo/public/cpp/application/application_impl.h" #include "mojo/public/cpp/application/lib/service_connector.h" namespace mojo { namespace internal { -ServiceRegistry::ServiceRegistry(Application* application) - : application_(application) { -} - -ServiceRegistry::ServiceRegistry( - Application* application, - ScopedMessagePipeHandle service_provider_handle) - : application_(application) { - remote_service_provider_.Bind(service_provider_handle.Pass()); +ServiceRegistry::ServiceRegistry(ApplicationImpl* application_impl, + const std::string& url, + ServiceProviderPtr service_provider) + : application_impl_(application_impl), + url_(url), + remote_service_provider_(service_provider.Pass()) { remote_service_provider_.set_client(this); } +ServiceRegistry::ServiceRegistry() : application_impl_(NULL) {} + ServiceRegistry::~ServiceRegistry() { for (NameToServiceConnectorMap::iterator i = name_to_service_connector_.begin(); @@ -35,7 +35,7 @@ void ServiceRegistry::AddServiceConnector( ServiceConnectorBase* service_connector) { RemoveServiceConnectorInternal(service_connector); name_to_service_connector_[service_connector->name()] = service_connector; - service_connector->set_registry(this); + service_connector->set_application_connection(this); } void ServiceRegistry::RemoveServiceConnector( @@ -56,30 +56,30 @@ bool ServiceRegistry::RemoveServiceConnectorInternal( return true; } -void ServiceRegistry::BindRemoteServiceProvider( - ScopedMessagePipeHandle service_provider_handle) { - remote_service_provider_.Bind(service_provider_handle.Pass()); - remote_service_provider_.set_client(this); +const std::string& ServiceRegistry::GetRemoteApplicationURL() { + return url_; } -void ServiceRegistry::ConnectToService(const mojo::String& service_url, - const mojo::String& service_name, - ScopedMessagePipeHandle client_handle, - const mojo::String& requestor_url) { +ServiceProvider* ServiceRegistry::GetServiceProvider() { + return remote_service_provider_.get(); +} + +ApplicationConnection* ServiceRegistry::ConnectToApplication( + const std::string& url) { + return application_impl_->ConnectToApplication(url); +} + +void ServiceRegistry::ConnectToService(const mojo::String& service_name, + ScopedMessagePipeHandle client_handle) { if (name_to_service_connector_.find(service_name) == - name_to_service_connector_.end() || - !application_->AllowIncomingConnection(service_name, requestor_url)) { + name_to_service_connector_.end()) { client_handle.reset(); return; } - internal::ServiceConnectorBase* service_connector = name_to_service_connector_[service_name]; - assert(service_connector); - // requestor_url is ignored because the service_connector stores the url - // of the requestor safely. - return service_connector->ConnectToService( - service_url, service_name, client_handle.Pass()); + return service_connector->ConnectToService(service_name, + client_handle.Pass()); } } // namespace internal diff --git a/mojo/public/cpp/application/lib/service_registry.h b/mojo/public/cpp/application/lib/service_registry.h index a2f23cd..8f77259 100644 --- a/mojo/public/cpp/application/lib/service_registry.h +++ b/mojo/public/cpp/application/lib/service_registry.h @@ -5,43 +5,47 @@ #ifndef MOJO_PUBLIC_CPP_APPLICATION_LIB_SERVICE_REGISTRY_H_ #define MOJO_PUBLIC_CPP_APPLICATION_LIB_SERVICE_REGISTRY_H_ -#include <map> -#include <string> - +#include "mojo/public/cpp/application/application_connection.h" #include "mojo/public/interfaces/service_provider/service_provider.mojom.h" namespace mojo { -class Application; +class ApplicationImpl; namespace internal { class ServiceConnectorBase; -class ServiceRegistry : public ServiceProvider { +// A ServiceRegistry represents each half of a connection between two +// applications, allowing customization of which services are published to the +// other. +class ServiceRegistry : public ServiceProvider, public ApplicationConnection { public: - ServiceRegistry(Application* application); - ServiceRegistry(Application* application, - ScopedMessagePipeHandle service_provider_handle); + ServiceRegistry(); + ServiceRegistry(ApplicationImpl* application_impl, + const std::string& url, + ServiceProviderPtr service_provider); virtual ~ServiceRegistry(); - void AddServiceConnector(ServiceConnectorBase* service_connector); - void RemoveServiceConnector(ServiceConnectorBase* service_connector); - - ServiceProvider* remote_service_provider() { - return remote_service_provider_.get(); - } + // ApplicationConnection overrides. + virtual void AddServiceConnector(ServiceConnectorBase* service_connector) + MOJO_OVERRIDE; + virtual const std::string& GetRemoteApplicationURL() MOJO_OVERRIDE; + virtual ApplicationConnection* ConnectToApplication( + const std::string& url) MOJO_OVERRIDE; + virtual ServiceProvider* GetServiceProvider() MOJO_OVERRIDE; - void BindRemoteServiceProvider( - ScopedMessagePipeHandle service_provider_handle); + virtual void RemoveServiceConnector(ServiceConnectorBase* service_connector); + private: // ServiceProvider method. - virtual void ConnectToService(const mojo::String& service_url, - const mojo::String& service_name, - ScopedMessagePipeHandle client_handle, - const mojo::String& requestor_url) + virtual void ConnectToService(const mojo::String& service_name, + ScopedMessagePipeHandle client_handle) MOJO_OVERRIDE; + ApplicationImpl* application_impl_; + const std::string url_; + private: bool RemoveServiceConnectorInternal( ServiceConnectorBase* service_connector); diff --git a/mojo/public/cpp/application/tests/service_registry_unittest.cc b/mojo/public/cpp/application/tests/service_registry_unittest.cc index 586dff8..9749ae4 100644 --- a/mojo/public/cpp/application/tests/service_registry_unittest.cc +++ b/mojo/public/cpp/application/tests/service_registry_unittest.cc @@ -17,7 +17,6 @@ class TestConnector : public ServiceConnectorBase { : ServiceConnectorBase(name), delete_count_(delete_count) {} virtual ~TestConnector() { (*delete_count_)++; } virtual void ConnectToService( - const std::string& url, const std::string& name, ScopedMessagePipeHandle client_handle) MOJO_OVERRIDE {} private: @@ -29,14 +28,14 @@ TEST(ServiceRegistryTest, Ownership) { // Destruction. { - ServiceRegistry registry(NULL); + ServiceRegistry registry; registry.AddServiceConnector(new TestConnector("TC1", &delete_count)); } EXPECT_EQ(1, delete_count); // Removal. { - ServiceRegistry registry(NULL); + ServiceRegistry registry; ServiceConnectorBase* c = new TestConnector("TC1", &delete_count); registry.AddServiceConnector(c); registry.RemoveServiceConnector(c); @@ -45,7 +44,7 @@ TEST(ServiceRegistryTest, Ownership) { // Multiple. { - ServiceRegistry registry(NULL); + ServiceRegistry registry; registry.AddServiceConnector(new TestConnector("TC1", &delete_count)); registry.AddServiceConnector(new TestConnector("TC2", &delete_count)); } @@ -53,7 +52,7 @@ TEST(ServiceRegistryTest, Ownership) { // Re-addition. { - ServiceRegistry registry(NULL); + ServiceRegistry registry; registry.AddServiceConnector(new TestConnector("TC1", &delete_count)); registry.AddServiceConnector(new TestConnector("TC1", &delete_count)); EXPECT_EQ(5, delete_count); |