| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_BINDING_SET_H_ | 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_BINDING_SET_H_ |
| 6 #define MOJO_PUBLIC_CPP_BINDINGS_BINDING_SET_H_ | 6 #define MOJO_PUBLIC_CPP_BINDINGS_BINDING_SET_H_ |
| 7 | 7 |
| 8 #include <string> | 8 #include <string> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/callback.h" | 12 #include "base/callback.h" |
| 13 #include "base/macros.h" | 13 #include "base/macros.h" |
| 14 #include "base/memory/ptr_util.h" | 14 #include "base/memory/ptr_util.h" |
| 15 #include "mojo/public/cpp/bindings/binding.h" | 15 #include "mojo/public/cpp/bindings/binding.h" |
| 16 #include "mojo/public/cpp/bindings/connection_error_callback.h" | 16 #include "mojo/public/cpp/bindings/connection_error_callback.h" |
| 17 #include "mojo/public/cpp/bindings/interface_ptr.h" | 17 #include "mojo/public/cpp/bindings/interface_ptr.h" |
| 18 #include "mojo/public/cpp/bindings/interface_request.h" | 18 #include "mojo/public/cpp/bindings/interface_request.h" |
| 19 #include "mojo/public/cpp/bindings/message.h" | 19 #include "mojo/public/cpp/bindings/message.h" |
| 20 | 20 |
| 21 namespace mojo { | 21 namespace mojo { |
| 22 | 22 |
| 23 template <typename BindingType> | 23 template <typename BindingType> |
| 24 struct BindingSetTraits; | 24 struct BindingSetTraits; |
| 25 | 25 |
| 26 template <typename Interface> | 26 template <typename Interface, typename ImplRefTraits> |
| 27 struct BindingSetTraits<Binding<Interface>> { | 27 struct BindingSetTraits<Binding<Interface, ImplRefTraits>> { |
| 28 using ProxyType = InterfacePtr<Interface>; | 28 using ProxyType = InterfacePtr<Interface>; |
| 29 using RequestType = InterfaceRequest<Interface>; | 29 using RequestType = InterfaceRequest<Interface>; |
| 30 using BindingType = Binding<Interface, ImplRefTraits>; |
| 31 using ImplPointerType = typename BindingType::ImplPointerType; |
| 30 | 32 |
| 31 static RequestType MakeRequest(ProxyType* proxy) { | 33 static RequestType MakeRequest(ProxyType* proxy) { |
| 32 return mojo::MakeRequest(proxy); | 34 return mojo::MakeRequest(proxy); |
| 33 } | 35 } |
| 34 }; | 36 }; |
| 35 | 37 |
| 36 using BindingId = size_t; | 38 using BindingId = size_t; |
| 37 | 39 |
| 38 template <typename ContextType> | 40 template <typename ContextType> |
| 39 struct BindingSetContextTraits { | 41 struct BindingSetContextTraits { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 60 // the extent of any message dispatch targeting that specific binding. | 62 // the extent of any message dispatch targeting that specific binding. |
| 61 template <typename Interface, typename BindingType, typename ContextType> | 63 template <typename Interface, typename BindingType, typename ContextType> |
| 62 class BindingSetBase { | 64 class BindingSetBase { |
| 63 public: | 65 public: |
| 64 using ContextTraits = BindingSetContextTraits<ContextType>; | 66 using ContextTraits = BindingSetContextTraits<ContextType>; |
| 65 using Context = typename ContextTraits::Type; | 67 using Context = typename ContextTraits::Type; |
| 66 using PreDispatchCallback = base::Callback<void(const Context&)>; | 68 using PreDispatchCallback = base::Callback<void(const Context&)>; |
| 67 using Traits = BindingSetTraits<BindingType>; | 69 using Traits = BindingSetTraits<BindingType>; |
| 68 using ProxyType = typename Traits::ProxyType; | 70 using ProxyType = typename Traits::ProxyType; |
| 69 using RequestType = typename Traits::RequestType; | 71 using RequestType = typename Traits::RequestType; |
| 72 using ImplPointerType = typename Traits::ImplPointerType; |
| 70 | 73 |
| 71 BindingSetBase() {} | 74 BindingSetBase() {} |
| 72 | 75 |
| 73 void set_connection_error_handler(const base::Closure& error_handler) { | 76 void set_connection_error_handler(const base::Closure& error_handler) { |
| 74 error_handler_ = error_handler; | 77 error_handler_ = error_handler; |
| 75 error_with_reason_handler_.Reset(); | 78 error_with_reason_handler_.Reset(); |
| 76 } | 79 } |
| 77 | 80 |
| 78 void set_connection_error_with_reason_handler( | 81 void set_connection_error_with_reason_handler( |
| 79 const ConnectionErrorWithReasonCallback& error_handler) { | 82 const ConnectionErrorWithReasonCallback& error_handler) { |
| 80 error_with_reason_handler_ = error_handler; | 83 error_with_reason_handler_ = error_handler; |
| 81 error_handler_.Reset(); | 84 error_handler_.Reset(); |
| 82 } | 85 } |
| 83 | 86 |
| 84 // Sets a callback to be invoked immediately before dispatching any message or | 87 // Sets a callback to be invoked immediately before dispatching any message or |
| 85 // error received by any of the bindings in the set. This may only be used | 88 // error received by any of the bindings in the set. This may only be used |
| 86 // with a non-void |ContextType|. | 89 // with a non-void |ContextType|. |
| 87 void set_pre_dispatch_handler(const PreDispatchCallback& handler) { | 90 void set_pre_dispatch_handler(const PreDispatchCallback& handler) { |
| 88 static_assert(ContextTraits::SupportsContext(), | 91 static_assert(ContextTraits::SupportsContext(), |
| 89 "Pre-dispatch handler usage requires non-void context type."); | 92 "Pre-dispatch handler usage requires non-void context type."); |
| 90 pre_dispatch_handler_ = handler; | 93 pre_dispatch_handler_ = handler; |
| 91 } | 94 } |
| 92 | 95 |
| 93 // Adds a new binding to the set which binds |request| to |impl| with no | 96 // Adds a new binding to the set which binds |request| to |impl| with no |
| 94 // additional context. | 97 // additional context. |
| 95 BindingId AddBinding(Interface* impl, RequestType request) { | 98 BindingId AddBinding(ImplPointerType impl, RequestType request) { |
| 96 static_assert(!ContextTraits::SupportsContext(), | 99 static_assert(!ContextTraits::SupportsContext(), |
| 97 "Context value required for non-void context type."); | 100 "Context value required for non-void context type."); |
| 98 return AddBindingImpl(impl, std::move(request), false); | 101 return AddBindingImpl(std::move(impl), std::move(request), false); |
| 99 } | 102 } |
| 100 | 103 |
| 101 // Adds a new binding associated with |context|. | 104 // Adds a new binding associated with |context|. |
| 102 BindingId AddBinding(Interface* impl, RequestType request, Context context) { | 105 BindingId AddBinding(ImplPointerType impl, |
| 106 RequestType request, |
| 107 Context context) { |
| 103 static_assert(ContextTraits::SupportsContext(), | 108 static_assert(ContextTraits::SupportsContext(), |
| 104 "Context value unsupported for void context type."); | 109 "Context value unsupported for void context type."); |
| 105 return AddBindingImpl(impl, std::move(request), std::move(context)); | 110 return AddBindingImpl(std::move(impl), std::move(request), |
| 111 std::move(context)); |
| 106 } | 112 } |
| 107 | 113 |
| 108 // Removes a binding from the set. Note that this is safe to call even if the | 114 // Removes a binding from the set. Note that this is safe to call even if the |
| 109 // binding corresponding to |id| has already been removed. | 115 // binding corresponding to |id| has already been removed. |
| 110 // | 116 // |
| 111 // Returns |true| if the binding was removed and |false| if it didn't exist. | 117 // Returns |true| if the binding was removed and |false| if it didn't exist. |
| 112 bool RemoveBinding(BindingId id) { | 118 bool RemoveBinding(BindingId id) { |
| 113 auto it = bindings_.find(id); | 119 auto it = bindings_.find(id); |
| 114 if (it == bindings_.end()) | 120 if (it == bindings_.end()) |
| 115 return false; | 121 return false; |
| 116 bindings_.erase(it); | 122 bindings_.erase(it); |
| 117 return true; | 123 return true; |
| 118 } | 124 } |
| 119 | 125 |
| 120 // Returns a proxy bound to one end of a pipe whose other end is bound to | 126 // Returns a proxy bound to one end of a pipe whose other end is bound to |
| 121 // |this|. If |id_storage| is not null, |*id_storage| will be set to the ID | 127 // |this|. If |id_storage| is not null, |*id_storage| will be set to the ID |
| 122 // of the added binding. | 128 // of the added binding. |
| 123 ProxyType CreateInterfacePtrAndBind(Interface* impl, | 129 ProxyType CreateInterfacePtrAndBind(ImplPointerType impl, |
| 124 BindingId* id_storage = nullptr) { | 130 BindingId* id_storage = nullptr) { |
| 125 ProxyType proxy; | 131 ProxyType proxy; |
| 126 BindingId id = AddBinding(impl, Traits::MakeRequest(&proxy)); | 132 BindingId id = AddBinding(std::move(impl), Traits::MakeRequest(&proxy)); |
| 127 if (id_storage) | 133 if (id_storage) |
| 128 *id_storage = id; | 134 *id_storage = id; |
| 129 return proxy; | 135 return proxy; |
| 130 } | 136 } |
| 131 | 137 |
| 132 void CloseAllBindings() { bindings_.clear(); } | 138 void CloseAllBindings() { bindings_.clear(); } |
| 133 | 139 |
| 134 bool empty() const { return bindings_.empty(); } | 140 bool empty() const { return bindings_.empty(); } |
| 135 | 141 |
| 136 // Implementations may call this when processing a dispatched message or | 142 // Implementations may call this when processing a dispatched message or |
| (...skipping 10 matching lines...) Expand all Loading... |
| 147 void FlushForTesting() { | 153 void FlushForTesting() { |
| 148 for (auto& binding : bindings_) | 154 for (auto& binding : bindings_) |
| 149 binding.second->FlushForTesting(); | 155 binding.second->FlushForTesting(); |
| 150 } | 156 } |
| 151 | 157 |
| 152 private: | 158 private: |
| 153 friend class Entry; | 159 friend class Entry; |
| 154 | 160 |
| 155 class Entry { | 161 class Entry { |
| 156 public: | 162 public: |
| 157 Entry(Interface* impl, | 163 Entry(ImplPointerType impl, |
| 158 RequestType request, | 164 RequestType request, |
| 159 BindingSetBase* binding_set, | 165 BindingSetBase* binding_set, |
| 160 BindingId binding_id, | 166 BindingId binding_id, |
| 161 Context context) | 167 Context context) |
| 162 : binding_(impl, std::move(request)), | 168 : binding_(std::move(impl), std::move(request)), |
| 163 binding_set_(binding_set), | 169 binding_set_(binding_set), |
| 164 binding_id_(binding_id), | 170 binding_id_(binding_id), |
| 165 context_(std::move(context)) { | 171 context_(std::move(context)) { |
| 166 if (ContextTraits::SupportsContext()) | 172 if (ContextTraits::SupportsContext()) |
| 167 binding_.AddFilter(base::MakeUnique<DispatchFilter>(this)); | 173 binding_.AddFilter(base::MakeUnique<DispatchFilter>(this)); |
| 168 binding_.set_connection_error_with_reason_handler( | 174 binding_.set_connection_error_with_reason_handler( |
| 169 base::Bind(&Entry::OnConnectionError, base::Unretained(this))); | 175 base::Bind(&Entry::OnConnectionError, base::Unretained(this))); |
| 170 } | 176 } |
| 171 | 177 |
| 172 void FlushForTesting() { binding_.FlushForTesting(); } | 178 void FlushForTesting() { binding_.FlushForTesting(); } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 DISALLOW_COPY_AND_ASSIGN(Entry); | 215 DISALLOW_COPY_AND_ASSIGN(Entry); |
| 210 }; | 216 }; |
| 211 | 217 |
| 212 void SetDispatchContext(const Context* context) { | 218 void SetDispatchContext(const Context* context) { |
| 213 DCHECK(ContextTraits::SupportsContext()); | 219 DCHECK(ContextTraits::SupportsContext()); |
| 214 dispatch_context_ = context; | 220 dispatch_context_ = context; |
| 215 if (!pre_dispatch_handler_.is_null()) | 221 if (!pre_dispatch_handler_.is_null()) |
| 216 pre_dispatch_handler_.Run(*context); | 222 pre_dispatch_handler_.Run(*context); |
| 217 } | 223 } |
| 218 | 224 |
| 219 BindingId AddBindingImpl(Interface* impl, | 225 BindingId AddBindingImpl(ImplPointerType impl, |
| 220 RequestType request, | 226 RequestType request, |
| 221 Context context) { | 227 Context context) { |
| 222 BindingId id = next_binding_id_++; | 228 BindingId id = next_binding_id_++; |
| 223 DCHECK_GE(next_binding_id_, 0u); | 229 DCHECK_GE(next_binding_id_, 0u); |
| 224 auto entry = base::MakeUnique<Entry>( | 230 auto entry = base::MakeUnique<Entry>(std::move(impl), std::move(request), |
| 225 impl, std::move(request), this, id, std::move(context)); | 231 this, id, std::move(context)); |
| 226 bindings_.insert(std::make_pair(id, std::move(entry))); | 232 bindings_.insert(std::make_pair(id, std::move(entry))); |
| 227 return id; | 233 return id; |
| 228 } | 234 } |
| 229 | 235 |
| 230 void OnConnectionError(BindingId id, | 236 void OnConnectionError(BindingId id, |
| 231 uint32_t custom_reason, | 237 uint32_t custom_reason, |
| 232 const std::string& description) { | 238 const std::string& description) { |
| 233 auto it = bindings_.find(id); | 239 auto it = bindings_.find(id); |
| 234 DCHECK(it != bindings_.end()); | 240 DCHECK(it != bindings_.end()); |
| 235 | 241 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 252 | 258 |
| 253 DISALLOW_COPY_AND_ASSIGN(BindingSetBase); | 259 DISALLOW_COPY_AND_ASSIGN(BindingSetBase); |
| 254 }; | 260 }; |
| 255 | 261 |
| 256 template <typename Interface, typename ContextType = void> | 262 template <typename Interface, typename ContextType = void> |
| 257 using BindingSet = BindingSetBase<Interface, Binding<Interface>, ContextType>; | 263 using BindingSet = BindingSetBase<Interface, Binding<Interface>, ContextType>; |
| 258 | 264 |
| 259 } // namespace mojo | 265 } // namespace mojo |
| 260 | 266 |
| 261 #endif // MOJO_PUBLIC_CPP_BINDINGS_BINDING_SET_H_ | 267 #endif // MOJO_PUBLIC_CPP_BINDINGS_BINDING_SET_H_ |
| OLD | NEW |