Temporarily re-enabling SizeAfterPrefChange test with traces.
[chromium-blink-merge.git] / mojo / public / cpp / application / lib / service_connector.h
blob914b2a924e85614cb08c9eacf93f269c889a1b14
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef MOJO_PUBLIC_CPP_APPLICATION_LIB_SERVICE_CONNECTOR_H_
6 #define MOJO_PUBLIC_CPP_APPLICATION_LIB_SERVICE_CONNECTOR_H_
8 #include <assert.h>
10 #include <vector>
12 #include "mojo/public/interfaces/service_provider/service_provider.mojom.h"
14 namespace mojo {
15 namespace internal {
17 template <class ServiceImpl, typename Context>
18 class ServiceConnector;
20 // Specialization of ServiceConnection.
21 // ServiceImpl: Subclass of InterfaceImpl<...>.
22 // Context: Type of shared context.
23 template <class ServiceImpl, typename Context>
24 class ServiceConnection : public ServiceImpl {
25 public:
26 ServiceConnection() : ServiceImpl() {}
27 ServiceConnection(Context* context) : ServiceImpl(context) {}
29 virtual void OnConnectionError() MOJO_OVERRIDE {
30 service_connector_->RemoveConnection(static_cast<ServiceImpl*>(this));
31 ServiceImpl::OnConnectionError();
34 private:
35 friend class ServiceConnector<ServiceImpl, Context>;
37 // Called shortly after this class is instantiated.
38 void set_service_connector(
39 ServiceConnector<ServiceImpl, Context>* connector) {
40 service_connector_ = connector;
43 ServiceConnector<ServiceImpl, Context>* service_connector_;
46 template <typename ServiceImpl, typename Context>
47 struct ServiceConstructor {
48 static ServiceConnection<ServiceImpl, Context>* New(Context* context) {
49 return new ServiceConnection<ServiceImpl, Context>(context);
53 template <typename ServiceImpl>
54 struct ServiceConstructor<ServiceImpl, void> {
55 public:
56 static ServiceConnection<ServiceImpl, void>* New(void* context) {
57 return new ServiceConnection<ServiceImpl, void>();
61 class ServiceConnectorBase {
62 public:
63 class Owner : public ServiceProvider {
64 public:
65 Owner();
66 Owner(ScopedMessagePipeHandle service_provider_handle);
67 virtual ~Owner();
68 virtual void AddServiceConnector(
69 internal::ServiceConnectorBase* service_connector) = 0;
70 virtual void RemoveServiceConnector(
71 internal::ServiceConnectorBase* service_connector) = 0;
73 protected:
74 void set_service_connector_owner(ServiceConnectorBase* service_connector,
75 Owner* owner) {
76 service_connector->owner_ = owner;
78 ServiceProviderPtr service_provider_;
80 ServiceConnectorBase(const std::string& name) : name_(name), owner_(NULL) {}
81 virtual ~ServiceConnectorBase();
82 virtual void ConnectToService(const std::string& url,
83 const std::string& name,
84 ScopedMessagePipeHandle client_handle) = 0;
85 std::string name() const { return name_; }
87 protected:
88 std::string name_;
89 Owner* owner_;
92 template <class ServiceImpl, typename Context=void>
93 class ServiceConnector : public internal::ServiceConnectorBase {
94 public:
95 ServiceConnector(const std::string& name, Context* context = NULL)
96 : ServiceConnectorBase(name), context_(context) {}
98 virtual ~ServiceConnector() {
99 ConnectionList doomed;
100 doomed.swap(connections_);
101 for (typename ConnectionList::iterator it = doomed.begin();
102 it != doomed.end(); ++it) {
103 delete *it;
105 assert(connections_.empty()); // No one should have added more!
108 virtual void ConnectToService(const std::string& url,
109 const std::string& name,
110 ScopedMessagePipeHandle handle) MOJO_OVERRIDE {
111 ServiceConnection<ServiceImpl, Context>* impl =
112 ServiceConstructor<ServiceImpl, Context>::New(context_);
113 impl->set_service_connector(this);
114 BindToPipe(impl, handle.Pass());
116 connections_.push_back(impl);
119 void RemoveConnection(ServiceImpl* impl) {
120 // Called from ~ServiceImpl, in response to a connection error.
121 for (typename ConnectionList::iterator it = connections_.begin();
122 it != connections_.end(); ++it) {
123 if (*it == impl) {
124 delete impl;
125 connections_.erase(it);
126 if (connections_.empty())
127 owner_->RemoveServiceConnector(this);
128 return;
133 Context* context() const { return context_; }
135 private:
136 typedef std::vector<ServiceImpl*> ConnectionList;
137 ConnectionList connections_;
138 Context* context_;
141 } // namespace internal
142 } // namespace mojo
144 #endif // MOJO_PUBLIC_CPP_APPLICATION_LIB_SERVICE_CONNECTOR_H_