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_
12 #include "mojo/public/interfaces/service_provider/service_provider.mojom.h"
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
{
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();
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> {
56 static ServiceConnection
<ServiceImpl
, void>* New(void* context
) {
57 return new ServiceConnection
<ServiceImpl
, void>();
61 class ServiceConnectorBase
{
63 class Owner
: public ServiceProvider
{
66 Owner(ScopedMessagePipeHandle service_provider_handle
);
68 virtual void AddServiceConnector(
69 internal::ServiceConnectorBase
* service_connector
) = 0;
70 virtual void RemoveServiceConnector(
71 internal::ServiceConnectorBase
* service_connector
) = 0;
74 void set_service_connector_owner(ServiceConnectorBase
* service_connector
,
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_
; }
92 template <class ServiceImpl
, typename Context
=void>
93 class ServiceConnector
: public internal::ServiceConnectorBase
{
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
) {
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
) {
125 connections_
.erase(it
);
126 if (connections_
.empty())
127 owner_
->RemoveServiceConnector(this);
133 Context
* context() const { return context_
; }
136 typedef std::vector
<ServiceImpl
*> ConnectionList
;
137 ConnectionList connections_
;
141 } // namespace internal
144 #endif // MOJO_PUBLIC_CPP_APPLICATION_LIB_SERVICE_CONNECTOR_H_