summaryrefslogtreecommitdiffstats
path: root/mojo/public
diff options
context:
space:
mode:
authordavemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-12 16:26:11 +0000
committerdavemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-12 16:26:11 +0000
commit128daf6bc3b24d366cf8f252ebe20f70818ea1b7 (patch)
tree8f6c4f5cf42904532664f7786857400be61251b7 /mojo/public
parentcd4186fcba54ce17d0c16467fdb8835286aa466f (diff)
downloadchromium_src-128daf6bc3b24d366cf8f252ebe20f70818ea1b7.zip
chromium_src-128daf6bc3b24d366cf8f252ebe20f70818ea1b7.tar.gz
chromium_src-128daf6bc3b24d366cf8f252ebe20f70818ea1b7.tar.bz2
Create Application class
BUG= R=darin@chromium.org Review URL: https://codereview.chromium.org/135513008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@250731 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'mojo/public')
-rw-r--r--mojo/public/shell/application.h46
-rw-r--r--mojo/public/shell/lib/application.cc57
-rw-r--r--mojo/public/shell/lib/service.cc10
-rw-r--r--mojo/public/shell/lib/shell.mojom2
-rw-r--r--mojo/public/shell/service.h93
5 files changed, 162 insertions, 46 deletions
diff --git a/mojo/public/shell/application.h b/mojo/public/shell/application.h
new file mode 100644
index 0000000..57bd2fd
--- /dev/null
+++ b/mojo/public/shell/application.h
@@ -0,0 +1,46 @@
+// 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_SHELL_APPLICATION_H_
+#define MOJO_PUBLIC_SHELL_APPLICATION_H_
+
+#include <vector>
+
+#include "mojo/public/bindings/remote_ptr.h"
+#include "mojo/public/shell/service.h"
+#include "mojo/public/system/core_cpp.h"
+#include "mojom/shell.h"
+
+namespace mojo {
+
+class Application : public internal::ServiceFactoryBase::Owner,
+ public ShellClient {
+ public:
+ explicit Application(ScopedShellHandle shell_handle);
+ explicit Application(MojoHandle shell_handle);
+ virtual ~Application();
+
+ // internal::ServiceFactoryBase::Owner methods.
+ virtual Shell* GetShell() MOJO_OVERRIDE;
+ // Takes ownership of |service_factory|.
+ virtual void AddServiceFactory(internal::ServiceFactoryBase* service_factory)
+ MOJO_OVERRIDE;
+ virtual void RemoveServiceFactory(
+ internal::ServiceFactoryBase* service_factory) MOJO_OVERRIDE;
+
+ protected:
+ // ShellClient methods.
+ virtual void AcceptConnection(const mojo::String& url,
+ ScopedMessagePipeHandle client_handle)
+ MOJO_OVERRIDE;
+
+ private:
+ typedef std::vector<internal::ServiceFactoryBase*> ServiceFactoryList;
+ ServiceFactoryList service_factories_;
+ RemotePtr<Shell> shell_;
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_SHELL_APPLICATION_H_
diff --git a/mojo/public/shell/lib/application.cc b/mojo/public/shell/lib/application.cc
new file mode 100644
index 0000000..dde3227
--- /dev/null
+++ b/mojo/public/shell/lib/application.cc
@@ -0,0 +1,57 @@
+// 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/shell/application.h"
+
+namespace mojo {
+
+Application::Application(ScopedShellHandle shell_handle)
+ : shell_(shell_handle.Pass(), this) {
+}
+
+Application::Application(MojoHandle shell_handle)
+ : shell_(mojo::MakeScopedHandle(ShellHandle(shell_handle)).Pass()) {}
+
+Application::~Application() {
+ for (ServiceFactoryList::iterator it = service_factories_.begin();
+ it != service_factories_.end(); ++it) {
+ delete *it;
+ }
+}
+
+Shell* Application::GetShell() {
+ return shell_.get();
+}
+
+void Application::AddServiceFactory(
+ internal::ServiceFactoryBase* service_factory) {
+ service_factories_.push_back(service_factory);
+ set_service_factory_owner(service_factory, this);
+}
+
+void Application::RemoveServiceFactory(
+ internal::ServiceFactoryBase* service_factory) {
+ for (ServiceFactoryList::iterator it = service_factories_.begin();
+ it != service_factories_.end(); ++it) {
+ if (*it == service_factory) {
+ service_factories_.erase(it);
+ delete service_factory;
+ break;
+ }
+ }
+ if (service_factories_.empty())
+ shell_.reset();
+}
+
+void Application::AcceptConnection(const mojo::String& url,
+ ScopedMessagePipeHandle client_handle) {
+ // TODO(davemoore): This method must be overridden by an Application subclass
+ // to dispatch to the right ServiceFactory. We need to figure out an approach
+ // to registration to make this better.
+ assert(1 == service_factories_.size());
+ return service_factories_.front()->AcceptConnection(url.To<std::string>(),
+ client_handle.Pass());
+}
+
+} // namespace mojo
diff --git a/mojo/public/shell/lib/service.cc b/mojo/public/shell/lib/service.cc
index e4ca1a1..8ae0d05 100644
--- a/mojo/public/shell/lib/service.cc
+++ b/mojo/public/shell/lib/service.cc
@@ -5,15 +5,9 @@
#include "mojo/public/shell/service.h"
namespace mojo {
-
-ServiceFactoryBase::ServiceFactoryBase(ScopedShellHandle shell_handle)
- : shell_(shell_handle.Pass(), this) {
-}
+namespace internal {
ServiceFactoryBase::~ServiceFactoryBase() {}
-void ServiceFactoryBase::DisconnectFromShell() {
- shell_.reset();
-}
-
+} // namespace internal
} // namespace mojo
diff --git a/mojo/public/shell/lib/shell.mojom b/mojo/public/shell/lib/shell.mojom
index 65fc790..69827da5 100644
--- a/mojo/public/shell/lib/shell.mojom
+++ b/mojo/public/shell/lib/shell.mojom
@@ -13,7 +13,7 @@ interface Shell {
[Peer=Shell]
interface ShellClient {
- void AcceptConnection(handle<message_pipe> client_handle);
+ void AcceptConnection(string url, handle<message_pipe> client_handle);
};
}
diff --git a/mojo/public/shell/service.h b/mojo/public/shell/service.h
index 26bac9b..1a68353 100644
--- a/mojo/public/shell/service.h
+++ b/mojo/public/shell/service.h
@@ -18,7 +18,6 @@
// and the Initialize() method.
// class FooImpl : public Foo {
// public:
-// typedef MyContext SharedContext;
// FooImpl();
// void Initialize(ServiceFactory<FooImpl>* service_factory,
// ScopedMessagePipeHandle client_handle
@@ -27,10 +26,8 @@
// RemotePtr<FooPeer> client_;
// };
//
-// To instantiate such a service:
-// ServiceFactory<FooImpl> service_factory(shell_handle.Pass());
//
-// To simplify further Foo can use the Service<> template.
+// To simplify further FooImpl can use the Service<> template.
// class FooImpl : public Service<Foo, FooImpl> {
// public:
// FooImpl();
@@ -38,47 +35,73 @@
// <Foo implementation>
// };
//
-// Optionally the clases can be specializeed with a shared context
+// Instances of FooImpl will be created by a specialized ServiceFactory
+//
+// ServiceFactory<FooImpl>
+//
+// Optionally the classes can be specializeed with a shared context
// class ServiceFactory<FooImpl, MyContext>
// and
// class FooImpl : public Service<Foo, FooImpl, MyContext>
//
-// ServiceFactory<FooImpl> service_factory(shell_handle.Pass(), my_context)
+// foo_factory = new ServiceFactory<FooImpl, MyContext>(my_context);
// instances of FooImpl can call context() and retrieve the value of my_context.
//
+// Lastly create an Application instance that collects all the ServiceFactories.
+//
+// Application app(shell_handle);
+// app.AddServiceFactory(new ServiceFactory<FooImpl>);
+//
+//
// Specialization of ServiceFactory.
// ServiceImpl: Implementation of Service interface.
// Context: Optional type of shared context.v
+//
+//
namespace mojo {
-class ServiceFactoryBase : public ShellClient {
+namespace internal {
+class ServiceFactoryBase {
public:
+ class Owner {
+ public:
+ virtual Shell* GetShell() = 0;
+ virtual void AddServiceFactory(
+ internal::ServiceFactoryBase* service_factory) = 0;
+ virtual void RemoveServiceFactory(
+ internal::ServiceFactoryBase* service_factory) = 0;
+
+ protected:
+ void set_service_factory_owner(ServiceFactoryBase* service_factory,
+ Owner* owner) {
+ service_factory->owner_ = owner;
+ }
+ };
+ ServiceFactoryBase() : owner_(NULL) {}
virtual ~ServiceFactoryBase();
+ Shell* GetShell() { return owner_->GetShell(); }
+ virtual void AcceptConnection(const std::string& url,
+ ScopedMessagePipeHandle client_handle) = 0;
protected:
- ServiceFactoryBase(ScopedShellHandle shell_handle);
- Shell* shell() { return shell_.get(); }
- // Destroys connection to Shell.
- void DisconnectFromShell();
-
- private:
- RemotePtr<Shell> shell_;
+ Owner* owner_;
};
+} // namespace internal
template <class ServiceImpl, typename Context=void>
-class ServiceFactory : public ServiceFactoryBase {
+class ServiceFactory : public internal::ServiceFactoryBase {
public:
- ServiceFactory(ScopedShellHandle shell_handle, Context* context = NULL)
- : ServiceFactoryBase(shell_handle.Pass()),
- context_(context) {
- }
+ ServiceFactory(Context* context = NULL) : context_(context) {}
virtual ~ServiceFactory() {
- while (!services_.empty())
- delete services_.front();
+ for (typename ServiceList::iterator it = services_.begin();
+ it != services_.end(); ++it) {
+ delete *it;
+ }
}
- virtual void AcceptConnection(ScopedMessagePipeHandle client_handle)
+ virtual void AcceptConnection(const std::string& url,
+ ScopedMessagePipeHandle client_handle)
MOJO_OVERRIDE {
ServiceImpl* service = new ServiceImpl();
service->Initialize(this, client_handle.Pass());
@@ -90,16 +113,15 @@ class ServiceFactory : public ServiceFactoryBase {
it != services_.end(); ++it) {
if (*it == service) {
services_.erase(it);
+ delete service;
if (services_.empty())
- DisconnectFromShell();
+ owner_->RemoveServiceFactory(this);
return;
}
}
}
- Context* context() const {
- return context_;
- }
+ Context* context() const { return context_; }
private:
typedef std::vector<ServiceImpl*> ServiceList;
@@ -114,13 +136,10 @@ class ServiceFactory : public ServiceFactoryBase {
template <class ServiceInterface, class ServiceImpl, typename Context=void>
class Service : public ServiceInterface {
public:
- virtual ~Service() {
- service_factory_->RemoveService(static_cast<ServiceImpl*>(this));
- }
+ virtual ~Service() {}
protected:
- friend class ServiceFactory<ServiceImpl, Context>;
- Service() : reaper_(this) {}
+ Service() : reaper_(this), service_factory_(NULL) {}
void Initialize(ServiceFactory<ServiceImpl, Context>* service_factory,
ScopedMessagePipeHandle client_handle) {
@@ -129,13 +148,11 @@ class Service : public ServiceInterface {
MakeScopedHandle(
InterfaceHandle<typename ServiceInterface::_Peer>(
client_handle.release().value())).Pass(),
- this, &reaper_);
- }
-
- Context* context() const {
- return service_factory_->context();
+ this,
+ &reaper_);
}
+ Context* context() const { return service_factory_->context(); }
typename ServiceInterface::_Peer* client() { return client_.get(); }
private:
@@ -146,11 +163,13 @@ class Service : public ServiceInterface {
Reaper(Service<ServiceInterface, ServiceImpl, Context>* service)
: service_(service) {}
virtual void OnError() {
- delete service_;
+ service_->service_factory_->RemoveService(
+ static_cast<ServiceImpl*>(service_));
}
private:
Service<ServiceInterface, ServiceImpl, Context>* service_;
};
+ friend class ServiceFactory<ServiceImpl, Context>;
Reaper reaper_;
ServiceFactory<ServiceImpl, Context>* service_factory_;
RemotePtr<typename ServiceInterface::_Peer> client_;