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 <utility> | 9 #include <utility> |
9 | 10 |
10 #include "base/bind.h" | 11 #include "base/bind.h" |
11 #include "base/callback.h" | 12 #include "base/callback.h" |
12 #include "base/macros.h" | 13 #include "base/macros.h" |
13 #include "mojo/public/cpp/bindings/binding.h" | 14 #include "mojo/public/cpp/bindings/binding.h" |
| 15 #include "mojo/public/cpp/bindings/connection_error_callback.h" |
14 #include "mojo/public/cpp/bindings/interface_ptr.h" | 16 #include "mojo/public/cpp/bindings/interface_ptr.h" |
15 #include "mojo/public/cpp/bindings/interface_request.h" | 17 #include "mojo/public/cpp/bindings/interface_request.h" |
16 #include "mojo/public/cpp/bindings/message.h" | 18 #include "mojo/public/cpp/bindings/message.h" |
17 | 19 |
18 namespace mojo { | 20 namespace mojo { |
19 | 21 |
20 template <typename BindingType> | 22 template <typename BindingType> |
21 struct BindingSetTraits; | 23 struct BindingSetTraits; |
22 | 24 |
23 template <typename Interface> | 25 template <typename Interface> |
(...skipping 27 matching lines...) Expand all Loading... |
51 | 53 |
52 // Constructs a new BindingSet operating in |dispatch_mode|. If |WITH_CONTEXT| | 54 // Constructs a new BindingSet operating in |dispatch_mode|. If |WITH_CONTEXT| |
53 // is used, AddBinding() supports a |context| argument, and dispatch_context() | 55 // is used, AddBinding() supports a |context| argument, and dispatch_context() |
54 // may be called during message or error dispatch to identify which specific | 56 // may be called during message or error dispatch to identify which specific |
55 // binding received the message or error. | 57 // binding received the message or error. |
56 explicit BindingSet(BindingSetDispatchMode dispatch_mode) | 58 explicit BindingSet(BindingSetDispatchMode dispatch_mode) |
57 : dispatch_mode_(dispatch_mode) {} | 59 : dispatch_mode_(dispatch_mode) {} |
58 | 60 |
59 void set_connection_error_handler(const base::Closure& error_handler) { | 61 void set_connection_error_handler(const base::Closure& error_handler) { |
60 error_handler_ = error_handler; | 62 error_handler_ = error_handler; |
| 63 error_with_reason_handler_.Reset(); |
| 64 } |
| 65 |
| 66 void set_connection_error_with_reason_handler( |
| 67 const ConnectionErrorWithReasonCallback& error_handler) { |
| 68 error_with_reason_handler_ = error_handler; |
| 69 error_handler_.Reset(); |
61 } | 70 } |
62 | 71 |
63 // Sets a callback to be invoked immediately before dispatching any message or | 72 // Sets a callback to be invoked immediately before dispatching any message or |
64 // error received by any of the bindings in the set. This may only be used | 73 // error received by any of the bindings in the set. This may only be used |
65 // if the set was constructed with |BindingSetDispatchMode::WITH_CONTEXT|. | 74 // if the set was constructed with |BindingSetDispatchMode::WITH_CONTEXT|. |
66 // |handler| is passed the context associated with the binding which received | 75 // |handler| is passed the context associated with the binding which received |
67 // the message or event about to be dispatched. | 76 // the message or event about to be dispatched. |
68 void set_pre_dispatch_handler(const PreDispatchCallback& handler) { | 77 void set_pre_dispatch_handler(const PreDispatchCallback& handler) { |
69 DCHECK(SupportsContext()); | 78 DCHECK(SupportsContext()); |
70 pre_dispatch_handler_ = handler; | 79 pre_dispatch_handler_ = handler; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 RequestType request, | 151 RequestType request, |
143 BindingSet* binding_set, | 152 BindingSet* binding_set, |
144 BindingId binding_id, | 153 BindingId binding_id, |
145 void* context) | 154 void* context) |
146 : binding_(impl, std::move(request)), | 155 : binding_(impl, std::move(request)), |
147 binding_set_(binding_set), | 156 binding_set_(binding_set), |
148 binding_id_(binding_id), | 157 binding_id_(binding_id), |
149 context_(context) { | 158 context_(context) { |
150 if (binding_set->SupportsContext()) | 159 if (binding_set->SupportsContext()) |
151 binding_.AddFilter(base::MakeUnique<DispatchFilter>(this)); | 160 binding_.AddFilter(base::MakeUnique<DispatchFilter>(this)); |
152 binding_.set_connection_error_handler(base::Bind( | 161 binding_.set_connection_error_with_reason_handler( |
153 &Entry::OnConnectionError, base::Unretained(this))); | 162 base::Bind(&Entry::OnConnectionError, base::Unretained(this))); |
154 } | 163 } |
155 | 164 |
156 void FlushForTesting() { binding_.FlushForTesting(); } | 165 void FlushForTesting() { binding_.FlushForTesting(); } |
157 | 166 |
158 private: | 167 private: |
159 class DispatchFilter : public MessageReceiver { | 168 class DispatchFilter : public MessageReceiver { |
160 public: | 169 public: |
161 explicit DispatchFilter(Entry* entry) : entry_(entry) {} | 170 explicit DispatchFilter(Entry* entry) : entry_(entry) {} |
162 ~DispatchFilter() override {} | 171 ~DispatchFilter() override {} |
163 | 172 |
164 private: | 173 private: |
165 // MessageReceiver: | 174 // MessageReceiver: |
166 bool Accept(Message* message) override { | 175 bool Accept(Message* message) override { |
167 entry_->WillDispatch(); | 176 entry_->WillDispatch(); |
168 return true; | 177 return true; |
169 } | 178 } |
170 | 179 |
171 Entry* entry_; | 180 Entry* entry_; |
172 | 181 |
173 DISALLOW_COPY_AND_ASSIGN(DispatchFilter); | 182 DISALLOW_COPY_AND_ASSIGN(DispatchFilter); |
174 }; | 183 }; |
175 | 184 |
176 void WillDispatch() { | 185 void WillDispatch() { |
177 DCHECK(binding_set_->SupportsContext()); | 186 DCHECK(binding_set_->SupportsContext()); |
178 binding_set_->SetDispatchContext(context_); | 187 binding_set_->SetDispatchContext(context_); |
179 } | 188 } |
180 | 189 |
181 void OnConnectionError() { | 190 void OnConnectionError(uint32_t custom_reason, |
| 191 const std::string& description) { |
182 if (binding_set_->SupportsContext()) | 192 if (binding_set_->SupportsContext()) |
183 WillDispatch(); | 193 WillDispatch(); |
184 binding_set_->OnConnectionError(binding_id_); | 194 binding_set_->OnConnectionError(binding_id_, custom_reason, description); |
185 } | 195 } |
186 | 196 |
187 BindingType binding_; | 197 BindingType binding_; |
188 BindingSet* const binding_set_; | 198 BindingSet* const binding_set_; |
189 const BindingId binding_id_; | 199 const BindingId binding_id_; |
190 void* const context_; | 200 void* const context_; |
191 | 201 |
192 DISALLOW_COPY_AND_ASSIGN(Entry); | 202 DISALLOW_COPY_AND_ASSIGN(Entry); |
193 }; | 203 }; |
194 | 204 |
195 void SetDispatchContext(void* context) { | 205 void SetDispatchContext(void* context) { |
196 DCHECK(SupportsContext()); | 206 DCHECK(SupportsContext()); |
197 dispatch_context_ = context; | 207 dispatch_context_ = context; |
198 if (!pre_dispatch_handler_.is_null()) | 208 if (!pre_dispatch_handler_.is_null()) |
199 pre_dispatch_handler_.Run(context); | 209 pre_dispatch_handler_.Run(context); |
200 } | 210 } |
201 | 211 |
202 bool SupportsContext() const { | 212 bool SupportsContext() const { |
203 return dispatch_mode_ == BindingSetDispatchMode::WITH_CONTEXT; | 213 return dispatch_mode_ == BindingSetDispatchMode::WITH_CONTEXT; |
204 } | 214 } |
205 | 215 |
206 void OnConnectionError(BindingId id) { | 216 void OnConnectionError(BindingId id, |
| 217 uint32_t custom_reason, |
| 218 const std::string& description) { |
207 auto it = bindings_.find(id); | 219 auto it = bindings_.find(id); |
208 DCHECK(it != bindings_.end()); | 220 DCHECK(it != bindings_.end()); |
209 bindings_.erase(it); | 221 bindings_.erase(it); |
210 | 222 |
211 if (!error_handler_.is_null()) | 223 if (!error_handler_.is_null()) |
212 error_handler_.Run(); | 224 error_handler_.Run(); |
| 225 else if (!error_with_reason_handler_.is_null()) |
| 226 error_with_reason_handler_.Run(custom_reason, description); |
213 } | 227 } |
214 | 228 |
215 BindingSetDispatchMode dispatch_mode_; | 229 BindingSetDispatchMode dispatch_mode_; |
216 base::Closure error_handler_; | 230 base::Closure error_handler_; |
| 231 ConnectionErrorWithReasonCallback error_with_reason_handler_; |
217 PreDispatchCallback pre_dispatch_handler_; | 232 PreDispatchCallback pre_dispatch_handler_; |
218 BindingId next_binding_id_ = 0; | 233 BindingId next_binding_id_ = 0; |
219 std::map<BindingId, std::unique_ptr<Entry>> bindings_; | 234 std::map<BindingId, std::unique_ptr<Entry>> bindings_; |
220 void* dispatch_context_ = nullptr; | 235 void* dispatch_context_ = nullptr; |
221 | 236 |
222 DISALLOW_COPY_AND_ASSIGN(BindingSet); | 237 DISALLOW_COPY_AND_ASSIGN(BindingSet); |
223 }; | 238 }; |
224 | 239 |
225 } // namespace mojo | 240 } // namespace mojo |
226 | 241 |
227 #endif // MOJO_PUBLIC_CPP_BINDINGS_BINDING_SET_H_ | 242 #endif // MOJO_PUBLIC_CPP_BINDINGS_BINDING_SET_H_ |
OLD | NEW |