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. 4 5 #ifndef MOJO_PUBLIC_CPP_APPLICATION_LIB_SERVICE_CONNECTOR_H_ 6 #define MOJO_PUBLIC_CPP_APPLICATION_LIB_SERVICE_CONNECTOR_H_ 7 8 #include <assert.h> 9 10 #include <vector> 11 12 #include "mojo/public/cpp/application/lib/service_registry.h" 13 #include "mojo/public/interfaces/service_provider/service_provider.mojom.h" 14 15 namespace mojo { 16 namespace internal { 17 18 template <class ServiceImpl, typename Context> 19 class ServiceConnector; 20 21 // Specialization of ServiceConnection. 22 // ServiceImpl: Subclass of InterfaceImpl<...>. 23 // Context: Type of shared context. 24 template <class ServiceImpl, typename Context> 25 class ServiceConnection : public ServiceImpl { 26 public: 27 ServiceConnection() : ServiceImpl() {} 28 ServiceConnection(Context* context) : ServiceImpl(context) {} 29 30 virtual void OnConnectionError() MOJO_OVERRIDE { 31 service_connector_->RemoveConnection(static_cast<ServiceImpl*>(this)); 32 ServiceImpl::OnConnectionError(); 33 } 34 35 private: 36 friend class ServiceConnector<ServiceImpl, Context>; 37 38 // Called shortly after this class is instantiated. 39 void set_service_connector( 40 ServiceConnector<ServiceImpl, Context>* connector) { 41 service_connector_ = connector; 42 } 43 44 ServiceConnector<ServiceImpl, Context>* service_connector_; 45 46 MOJO_DISALLOW_COPY_AND_ASSIGN(ServiceConnection); 47 }; 48 49 template <typename ServiceImpl, typename Context> 50 struct ServiceConstructor { 51 static ServiceConnection<ServiceImpl, Context>* New(Context* context) { 52 return new ServiceConnection<ServiceImpl, Context>(context); 53 } 54 }; 55 56 template <typename ServiceImpl> 57 struct ServiceConstructor<ServiceImpl, void> { 58 public: 59 static ServiceConnection<ServiceImpl, void>* New(void* context) { 60 return new ServiceConnection<ServiceImpl, void>(); 61 } 62 }; 63 64 class ServiceConnectorBase { 65 public: 66 ServiceConnectorBase(const std::string& name); 67 virtual ~ServiceConnectorBase(); 68 virtual void ConnectToService(const std::string& url, 69 const std::string& name, 70 ScopedMessagePipeHandle client_handle) = 0; 71 std::string name() const { return name_; } 72 void set_registry(ServiceRegistry* registry) { registry_ = registry; } 73 74 protected: 75 std::string name_; 76 ServiceRegistry* registry_; 77 78 MOJO_DISALLOW_COPY_AND_ASSIGN(ServiceConnectorBase); 79 }; 80 81 template <class ServiceImpl, typename Context=void> 82 class ServiceConnector : public internal::ServiceConnectorBase { 83 public: 84 ServiceConnector(const std::string& name, Context* context = NULL) 85 : ServiceConnectorBase(name), context_(context) {} 86 87 virtual ~ServiceConnector() { 88 ConnectionList doomed; 89 doomed.swap(connections_); 90 for (typename ConnectionList::iterator it = doomed.begin(); 91 it != doomed.end(); ++it) { 92 delete *it; 93 } 94 assert(connections_.empty()); // No one should have added more! 95 } 96 97 virtual void ConnectToService(const std::string& url, 98 const std::string& name, 99 ScopedMessagePipeHandle handle) MOJO_OVERRIDE { 100 ServiceConnection<ServiceImpl, Context>* impl = 101 ServiceConstructor<ServiceImpl, Context>::New(context_); 102 impl->set_service_connector(this); 103 BindToPipe(impl, handle.Pass()); 104 105 connections_.push_back(impl); 106 } 107 108 void RemoveConnection(ServiceImpl* impl) { 109 // Called from ~ServiceImpl, in response to a connection error. 110 for (typename ConnectionList::iterator it = connections_.begin(); 111 it != connections_.end(); ++it) { 112 if (*it == impl) { 113 delete impl; 114 connections_.erase(it); 115 return; 116 } 117 } 118 } 119 120 Context* context() const { return context_; } 121 122 private: 123 typedef std::vector<ServiceImpl*> ConnectionList; 124 ConnectionList connections_; 125 Context* context_; 126 127 MOJO_DISALLOW_COPY_AND_ASSIGN(ServiceConnector); 128 }; 129 130 } // namespace internal 131 } // namespace mojo 132 133 #endif // MOJO_PUBLIC_CPP_APPLICATION_LIB_SERVICE_CONNECTOR_H_ 134