OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 // Note: This file tests both binding.h (mojo::Binding) and strong_binding.h | 5 // Note: This file tests both binding.h (mojo::Binding) and strong_binding.h |
6 // (mojo::StrongBinding). | 6 // (mojo::StrongBinding). |
7 | 7 |
8 #include "mojo/public/cpp/bindings/binding.h" | 8 #include "mojo/public/cpp/bindings/binding.h" |
9 | 9 |
10 #include <stdint.h> | 10 #include <stdint.h> |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 const FrobinateCallback& callback) override { | 51 const FrobinateCallback& callback) override { |
52 callback.Run(1); | 52 callback.Run(1); |
53 } | 53 } |
54 void GetPort(InterfaceRequest<sample::Port> port) override {} | 54 void GetPort(InterfaceRequest<sample::Port> port) override {} |
55 | 55 |
56 bool* const was_deleted_; | 56 bool* const was_deleted_; |
57 | 57 |
58 DISALLOW_COPY_AND_ASSIGN(ServiceImpl); | 58 DISALLOW_COPY_AND_ASSIGN(ServiceImpl); |
59 }; | 59 }; |
60 | 60 |
| 61 template <typename... Args> |
| 62 void DoSetFlagAndRunClosure(bool* flag, |
| 63 const base::Closure& closure, |
| 64 Args... args) { |
| 65 *flag = true; |
| 66 closure.Run(); |
| 67 } |
| 68 |
| 69 template <typename... Args> |
| 70 base::Callback<void(Args...)> SetFlagAndRunClosure( |
| 71 bool* flag, |
| 72 const base::Closure& callback = base::Closure()) { |
| 73 return base::Bind(&DoSetFlagAndRunClosure<Args...>, flag, callback); |
| 74 } |
| 75 |
61 // BindingTest ----------------------------------------------------------------- | 76 // BindingTest ----------------------------------------------------------------- |
62 | 77 |
63 using BindingTest = BindingTestBase; | 78 using BindingTest = BindingTestBase; |
64 | 79 |
65 TEST_F(BindingTest, Close) { | 80 TEST_F(BindingTest, Close) { |
66 bool called = false; | 81 bool called = false; |
67 sample::ServicePtr ptr; | 82 sample::ServicePtr ptr; |
68 auto request = GetProxy(&ptr); | 83 auto request = GetProxy(&ptr); |
69 base::RunLoop run_loop; | 84 base::RunLoop run_loop; |
70 ptr.set_connection_error_handler([&called, &run_loop]() { | 85 ptr.set_connection_error_handler( |
71 called = true; | 86 SetFlagAndRunClosure(&called, run_loop.QuitClosure())); |
72 run_loop.Quit(); | |
73 }); | |
74 ServiceImpl impl; | 87 ServiceImpl impl; |
75 Binding<sample::Service> binding(&impl, std::move(request)); | 88 Binding<sample::Service> binding(&impl, std::move(request)); |
76 | 89 |
77 binding.Close(); | 90 binding.Close(); |
78 EXPECT_FALSE(called); | 91 EXPECT_FALSE(called); |
79 run_loop.Run(); | 92 run_loop.Run(); |
80 EXPECT_TRUE(called); | 93 EXPECT_TRUE(called); |
81 } | 94 } |
82 | 95 |
83 // Tests that destroying a mojo::Binding closes the bound message pipe handle. | 96 // Tests that destroying a mojo::Binding closes the bound message pipe handle. |
84 TEST_F(BindingTest, DestroyClosesMessagePipe) { | 97 TEST_F(BindingTest, DestroyClosesMessagePipe) { |
85 bool encountered_error = false; | 98 bool encountered_error = false; |
86 ServiceImpl impl; | 99 ServiceImpl impl; |
87 sample::ServicePtr ptr; | 100 sample::ServicePtr ptr; |
88 auto request = GetProxy(&ptr); | 101 auto request = GetProxy(&ptr); |
89 base::RunLoop run_loop; | 102 base::RunLoop run_loop; |
90 ptr.set_connection_error_handler( | 103 ptr.set_connection_error_handler( |
91 [&encountered_error, &run_loop]() { | 104 SetFlagAndRunClosure(&encountered_error, run_loop.QuitClosure())); |
92 encountered_error = true; | |
93 run_loop.Quit(); | |
94 }); | |
95 bool called = false; | 105 bool called = false; |
96 base::RunLoop run_loop2; | 106 base::RunLoop run_loop2; |
97 auto called_cb = [&called, &run_loop2](int32_t result) { | |
98 called = true; | |
99 run_loop2.Quit(); | |
100 }; | |
101 { | 107 { |
102 Binding<sample::Service> binding(&impl, std::move(request)); | 108 Binding<sample::Service> binding(&impl, std::move(request)); |
103 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, | 109 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, |
104 called_cb); | 110 SetFlagAndRunClosure<int32_t>(&called, |
| 111 run_loop2.QuitClosure())); |
105 run_loop2.Run(); | 112 run_loop2.Run(); |
106 EXPECT_TRUE(called); | 113 EXPECT_TRUE(called); |
107 EXPECT_FALSE(encountered_error); | 114 EXPECT_FALSE(encountered_error); |
108 } | 115 } |
109 // Now that the Binding is out of scope we should detect an error on the other | 116 // Now that the Binding is out of scope we should detect an error on the other |
110 // end of the pipe. | 117 // end of the pipe. |
111 run_loop.Run(); | 118 run_loop.Run(); |
112 EXPECT_TRUE(encountered_error); | 119 EXPECT_TRUE(encountered_error); |
113 | 120 |
114 // And calls should fail. | 121 // And calls should fail. |
115 called = false; | 122 called = false; |
116 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, | 123 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, |
117 called_cb); | 124 SetFlagAndRunClosure<int32_t>(&called, |
| 125 run_loop2.QuitClosure())); |
118 loop().RunUntilIdle(); | 126 loop().RunUntilIdle(); |
119 EXPECT_FALSE(called); | 127 EXPECT_FALSE(called); |
120 } | 128 } |
121 | 129 |
122 // Tests that the binding's connection error handler gets called when the other | 130 // Tests that the binding's connection error handler gets called when the other |
123 // end is closed. | 131 // end is closed. |
124 TEST_F(BindingTest, ConnectionError) { | 132 TEST_F(BindingTest, ConnectionError) { |
125 bool called = false; | 133 bool called = false; |
126 { | 134 { |
127 ServiceImpl impl; | 135 ServiceImpl impl; |
128 sample::ServicePtr ptr; | 136 sample::ServicePtr ptr; |
129 Binding<sample::Service> binding(&impl, GetProxy(&ptr)); | 137 Binding<sample::Service> binding(&impl, GetProxy(&ptr)); |
130 base::RunLoop run_loop; | 138 base::RunLoop run_loop; |
131 binding.set_connection_error_handler([&called, &run_loop]() { | 139 binding.set_connection_error_handler( |
132 called = true; | 140 SetFlagAndRunClosure(&called, run_loop.QuitClosure())); |
133 run_loop.Quit(); | |
134 }); | |
135 ptr.reset(); | 141 ptr.reset(); |
136 EXPECT_FALSE(called); | 142 EXPECT_FALSE(called); |
137 run_loop.Run(); | 143 run_loop.Run(); |
138 EXPECT_TRUE(called); | 144 EXPECT_TRUE(called); |
139 // We want to make sure that it isn't called again during destruction. | 145 // We want to make sure that it isn't called again during destruction. |
140 called = false; | 146 called = false; |
141 } | 147 } |
142 EXPECT_FALSE(called); | 148 EXPECT_FALSE(called); |
143 } | 149 } |
144 | 150 |
145 // Tests that calling Close doesn't result in the connection error handler being | 151 // Tests that calling Close doesn't result in the connection error handler being |
146 // called. | 152 // called. |
147 TEST_F(BindingTest, CloseDoesntCallConnectionErrorHandler) { | 153 TEST_F(BindingTest, CloseDoesntCallConnectionErrorHandler) { |
148 ServiceImpl impl; | 154 ServiceImpl impl; |
149 sample::ServicePtr ptr; | 155 sample::ServicePtr ptr; |
150 Binding<sample::Service> binding(&impl, GetProxy(&ptr)); | 156 Binding<sample::Service> binding(&impl, GetProxy(&ptr)); |
151 bool called = false; | 157 bool called = false; |
152 binding.set_connection_error_handler([&called]() { called = true; }); | 158 binding.set_connection_error_handler(SetFlagAndRunClosure(&called)); |
153 binding.Close(); | 159 binding.Close(); |
154 loop().RunUntilIdle(); | 160 loop().RunUntilIdle(); |
155 EXPECT_FALSE(called); | 161 EXPECT_FALSE(called); |
156 | 162 |
157 // We can also close the other end, and the error handler still won't be | 163 // We can also close the other end, and the error handler still won't be |
158 // called. | 164 // called. |
159 ptr.reset(); | 165 ptr.reset(); |
160 loop().RunUntilIdle(); | 166 loop().RunUntilIdle(); |
161 EXPECT_FALSE(called); | 167 EXPECT_FALSE(called); |
162 } | 168 } |
163 | 169 |
164 class ServiceImplWithBinding : public ServiceImpl { | 170 class ServiceImplWithBinding : public ServiceImpl { |
165 public: | 171 public: |
166 ServiceImplWithBinding(bool* was_deleted, | 172 ServiceImplWithBinding(bool* was_deleted, |
167 const base::Closure& closure, | 173 const base::Closure& closure, |
168 InterfaceRequest<sample::Service> request) | 174 InterfaceRequest<sample::Service> request) |
169 : ServiceImpl(was_deleted), | 175 : ServiceImpl(was_deleted), |
170 binding_(this, std::move(request)), | 176 binding_(this, std::move(request)), |
171 closure_(closure) { | 177 closure_(closure) { |
172 binding_.set_connection_error_handler([this]() { delete this; }); | 178 binding_.set_connection_error_handler( |
| 179 base::Bind(&ServiceImplWithBinding::OnConnectionError, |
| 180 base::Unretained(this))); |
173 } | 181 } |
174 | 182 |
175 private: | 183 private: |
176 ~ServiceImplWithBinding() override{ | 184 ~ServiceImplWithBinding() override{ |
177 closure_.Run(); | 185 closure_.Run(); |
178 } | 186 } |
179 | 187 |
| 188 void OnConnectionError() { delete this; } |
| 189 |
180 Binding<sample::Service> binding_; | 190 Binding<sample::Service> binding_; |
181 base::Closure closure_; | 191 base::Closure closure_; |
182 | 192 |
183 DISALLOW_COPY_AND_ASSIGN(ServiceImplWithBinding); | 193 DISALLOW_COPY_AND_ASSIGN(ServiceImplWithBinding); |
184 }; | 194 }; |
185 | 195 |
186 // Tests that the binding may be deleted in the connection error handler. | 196 // Tests that the binding may be deleted in the connection error handler. |
187 TEST_F(BindingTest, SelfDeleteOnConnectionError) { | 197 TEST_F(BindingTest, SelfDeleteOnConnectionError) { |
188 bool was_deleted = false; | 198 bool was_deleted = false; |
189 sample::ServicePtr ptr; | 199 sample::ServicePtr ptr; |
190 // This should delete itself on connection error. | 200 // This should delete itself on connection error. |
191 base::RunLoop run_loop; | 201 base::RunLoop run_loop; |
192 new ServiceImplWithBinding(&was_deleted, run_loop.QuitClosure(), | 202 new ServiceImplWithBinding(&was_deleted, run_loop.QuitClosure(), |
193 GetProxy(&ptr)); | 203 GetProxy(&ptr)); |
194 ptr.reset(); | 204 ptr.reset(); |
195 EXPECT_FALSE(was_deleted); | 205 EXPECT_FALSE(was_deleted); |
196 run_loop.Run(); | 206 run_loop.Run(); |
197 EXPECT_TRUE(was_deleted); | 207 EXPECT_TRUE(was_deleted); |
198 } | 208 } |
199 | 209 |
200 // Tests that explicitly calling Unbind followed by rebinding works. | 210 // Tests that explicitly calling Unbind followed by rebinding works. |
201 TEST_F(BindingTest, Unbind) { | 211 TEST_F(BindingTest, Unbind) { |
202 ServiceImpl impl; | 212 ServiceImpl impl; |
203 sample::ServicePtr ptr; | 213 sample::ServicePtr ptr; |
204 Binding<sample::Service> binding(&impl, GetProxy(&ptr)); | 214 Binding<sample::Service> binding(&impl, GetProxy(&ptr)); |
205 | 215 |
206 bool called = false; | 216 bool called = false; |
207 base::RunLoop run_loop; | 217 base::RunLoop run_loop; |
208 auto called_cb = [&called, &run_loop](int32_t result) { | |
209 called = true; | |
210 run_loop.Quit(); | |
211 }; | |
212 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, | 218 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, |
213 called_cb); | 219 SetFlagAndRunClosure<int32_t>(&called, |
| 220 run_loop.QuitClosure())); |
214 run_loop.Run(); | 221 run_loop.Run(); |
215 EXPECT_TRUE(called); | 222 EXPECT_TRUE(called); |
216 | 223 |
217 called = false; | 224 called = false; |
218 auto request = binding.Unbind(); | 225 auto request = binding.Unbind(); |
219 EXPECT_FALSE(binding.is_bound()); | 226 EXPECT_FALSE(binding.is_bound()); |
220 // All calls should fail when not bound... | 227 // All calls should fail when not bound... |
221 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, | 228 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, |
222 called_cb); | 229 SetFlagAndRunClosure<int32_t>(&called, |
| 230 run_loop.QuitClosure())); |
223 loop().RunUntilIdle(); | 231 loop().RunUntilIdle(); |
224 EXPECT_FALSE(called); | 232 EXPECT_FALSE(called); |
225 | 233 |
226 called = false; | 234 called = false; |
227 binding.Bind(std::move(request)); | 235 binding.Bind(std::move(request)); |
228 EXPECT_TRUE(binding.is_bound()); | 236 EXPECT_TRUE(binding.is_bound()); |
229 // ...and should succeed again when the rebound. | 237 // ...and should succeed again when the rebound. |
230 base::RunLoop run_loop2; | 238 base::RunLoop run_loop2; |
231 auto called_cb2 = [&called, &run_loop2](int32_t result) { | |
232 called = true; | |
233 run_loop2.Quit(); | |
234 }; | |
235 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, | 239 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, |
236 called_cb2); | 240 SetFlagAndRunClosure<int32_t>(&called, |
| 241 run_loop2.QuitClosure())); |
237 run_loop2.Run(); | 242 run_loop2.Run(); |
238 EXPECT_TRUE(called); | 243 EXPECT_TRUE(called); |
239 } | 244 } |
240 | 245 |
241 class IntegerAccessorImpl : public sample::IntegerAccessor { | 246 class IntegerAccessorImpl : public sample::IntegerAccessor { |
242 public: | 247 public: |
243 IntegerAccessorImpl() {} | 248 IntegerAccessorImpl() {} |
244 ~IntegerAccessorImpl() override {} | 249 ~IntegerAccessorImpl() override {} |
245 | 250 |
246 private: | 251 private: |
247 // sample::IntegerAccessor implementation. | 252 // sample::IntegerAccessor implementation. |
248 void GetInteger(const GetIntegerCallback& callback) override { | 253 void GetInteger(const GetIntegerCallback& callback) override { |
249 callback.Run(1, sample::Enum::VALUE); | 254 callback.Run(1, sample::Enum::VALUE); |
250 } | 255 } |
251 void SetInteger(int64_t data, sample::Enum type) override {} | 256 void SetInteger(int64_t data, sample::Enum type) override {} |
252 | 257 |
253 DISALLOW_COPY_AND_ASSIGN(IntegerAccessorImpl); | 258 DISALLOW_COPY_AND_ASSIGN(IntegerAccessorImpl); |
254 }; | 259 }; |
255 | 260 |
256 TEST_F(BindingTest, SetInterfacePtrVersion) { | 261 TEST_F(BindingTest, SetInterfacePtrVersion) { |
257 IntegerAccessorImpl impl; | 262 IntegerAccessorImpl impl; |
258 sample::IntegerAccessorPtr ptr; | 263 sample::IntegerAccessorPtr ptr; |
259 Binding<sample::IntegerAccessor> binding(&impl, &ptr); | 264 Binding<sample::IntegerAccessor> binding(&impl, &ptr); |
260 EXPECT_EQ(3u, ptr.version()); | 265 EXPECT_EQ(3u, ptr.version()); |
261 } | 266 } |
262 | 267 |
263 TEST_F(BindingTest, PauseResume) { | 268 TEST_F(BindingTest, PauseResume) { |
264 bool called = false; | 269 bool called = false; |
265 base::RunLoop run_loop; | 270 base::RunLoop run_loop; |
266 auto called_cb = [&called, &run_loop](int32_t result) { | |
267 called = true; | |
268 run_loop.Quit(); | |
269 }; | |
270 sample::ServicePtr ptr; | 271 sample::ServicePtr ptr; |
271 auto request = GetProxy(&ptr); | 272 auto request = GetProxy(&ptr); |
272 ServiceImpl impl; | 273 ServiceImpl impl; |
273 Binding<sample::Service> binding(&impl, std::move(request)); | 274 Binding<sample::Service> binding(&impl, std::move(request)); |
274 binding.PauseIncomingMethodCallProcessing(); | 275 binding.PauseIncomingMethodCallProcessing(); |
275 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, | 276 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, |
276 called_cb); | 277 SetFlagAndRunClosure<int32_t>(&called, |
| 278 run_loop.QuitClosure())); |
277 EXPECT_FALSE(called); | 279 EXPECT_FALSE(called); |
278 loop().RunUntilIdle(); | 280 loop().RunUntilIdle(); |
279 // Frobinate() should not be called as the binding is paused. | 281 // Frobinate() should not be called as the binding is paused. |
280 EXPECT_FALSE(called); | 282 EXPECT_FALSE(called); |
281 | 283 |
282 // Resume the binding, which should trigger processing. | 284 // Resume the binding, which should trigger processing. |
283 binding.ResumeIncomingMethodCallProcessing(); | 285 binding.ResumeIncomingMethodCallProcessing(); |
284 run_loop.Run(); | 286 run_loop.Run(); |
285 EXPECT_TRUE(called); | 287 EXPECT_TRUE(called); |
286 } | 288 } |
287 | 289 |
288 // Verifies the connection error handler is not run while a binding is paused. | 290 // Verifies the connection error handler is not run while a binding is paused. |
289 TEST_F(BindingTest, ErrorHandleNotRunWhilePaused) { | 291 TEST_F(BindingTest, ErrorHandleNotRunWhilePaused) { |
290 bool called = false; | 292 bool called = false; |
291 base::RunLoop run_loop; | 293 base::RunLoop run_loop; |
292 sample::ServicePtr ptr; | 294 sample::ServicePtr ptr; |
293 auto request = GetProxy(&ptr); | 295 auto request = GetProxy(&ptr); |
294 ServiceImpl impl; | 296 ServiceImpl impl; |
295 Binding<sample::Service> binding(&impl, std::move(request)); | 297 Binding<sample::Service> binding(&impl, std::move(request)); |
296 binding.set_connection_error_handler([&called, &run_loop]() { | 298 binding.set_connection_error_handler( |
297 called = true; | 299 SetFlagAndRunClosure(&called, run_loop.QuitClosure())); |
298 run_loop.Quit(); | |
299 }); | |
300 binding.PauseIncomingMethodCallProcessing(); | 300 binding.PauseIncomingMethodCallProcessing(); |
301 | 301 |
302 ptr.reset(); | 302 ptr.reset(); |
303 loop().RunUntilIdle(); | 303 loop().RunUntilIdle(); |
304 // The connection error handle should not be called as the binding is paused. | 304 // The connection error handle should not be called as the binding is paused. |
305 EXPECT_FALSE(called); | 305 EXPECT_FALSE(called); |
306 | 306 |
307 // Resume the binding, which should trigger the error handler. | 307 // Resume the binding, which should trigger the error handler. |
308 binding.ResumeIncomingMethodCallProcessing(); | 308 binding.ResumeIncomingMethodCallProcessing(); |
309 run_loop.Run(); | 309 run_loop.Run(); |
310 EXPECT_TRUE(called); | 310 EXPECT_TRUE(called); |
311 } | 311 } |
312 | 312 |
313 // StrongBindingTest ----------------------------------------------------------- | 313 // StrongBindingTest ----------------------------------------------------------- |
314 | 314 |
315 using StrongBindingTest = BindingTestBase; | 315 using StrongBindingTest = BindingTestBase; |
316 | 316 |
317 // Tests that destroying a mojo::StrongBinding closes the bound message pipe | 317 // Tests that destroying a mojo::StrongBinding closes the bound message pipe |
318 // handle but does *not* destroy the implementation object. | 318 // handle but does *not* destroy the implementation object. |
319 TEST_F(StrongBindingTest, DestroyClosesMessagePipe) { | 319 TEST_F(StrongBindingTest, DestroyClosesMessagePipe) { |
320 base::RunLoop run_loop; | 320 base::RunLoop run_loop; |
321 bool encountered_error = false; | 321 bool encountered_error = false; |
322 bool was_deleted = false; | 322 bool was_deleted = false; |
323 ServiceImpl impl(&was_deleted); | 323 ServiceImpl impl(&was_deleted); |
324 sample::ServicePtr ptr; | 324 sample::ServicePtr ptr; |
325 auto request = GetProxy(&ptr); | 325 auto request = GetProxy(&ptr); |
326 ptr.set_connection_error_handler( | 326 ptr.set_connection_error_handler( |
327 [&encountered_error, &run_loop]() { | 327 SetFlagAndRunClosure(&encountered_error, run_loop.QuitClosure())); |
328 encountered_error = true; | |
329 run_loop.Quit(); | |
330 }); | |
331 bool called = false; | 328 bool called = false; |
332 base::RunLoop run_loop2; | 329 base::RunLoop run_loop2; |
333 auto called_cb = [&called, &run_loop2](int32_t result) { | |
334 called = true; | |
335 run_loop2.Quit(); | |
336 }; | |
337 { | 330 { |
338 StrongBinding<sample::Service> binding(&impl, std::move(request)); | 331 StrongBinding<sample::Service> binding(&impl, std::move(request)); |
339 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, | 332 ptr->Frobinate(nullptr, sample::Service::BazOptions::REGULAR, nullptr, |
340 called_cb); | 333 SetFlagAndRunClosure<int32_t>(&called, |
| 334 run_loop2.QuitClosure())); |
341 run_loop2.Run(); | 335 run_loop2.Run(); |
342 EXPECT_TRUE(called); | 336 EXPECT_TRUE(called); |
343 EXPECT_FALSE(encountered_error); | 337 EXPECT_FALSE(encountered_error); |
344 } | 338 } |
345 // Now that the StrongBinding is out of scope we should detect an error on the | 339 // Now that the StrongBinding is out of scope we should detect an error on the |
346 // other end of the pipe. | 340 // other end of the pipe. |
347 run_loop.Run(); | 341 run_loop.Run(); |
348 EXPECT_TRUE(encountered_error); | 342 EXPECT_TRUE(encountered_error); |
349 // But destroying the StrongBinding doesn't destroy the object. | 343 // But destroying the StrongBinding doesn't destroy the object. |
350 ASSERT_FALSE(was_deleted); | 344 ASSERT_FALSE(was_deleted); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 // Tests that even when the implementation object owns the StrongBinding, that | 380 // Tests that even when the implementation object owns the StrongBinding, that |
387 // the implementation can still be deleted (which should result in the message | 381 // the implementation can still be deleted (which should result in the message |
388 // pipe being closed). Also checks that the connection error handler doesn't get | 382 // pipe being closed). Also checks that the connection error handler doesn't get |
389 // called. | 383 // called. |
390 TEST_F(StrongBindingTest, ExplicitDeleteImpl) { | 384 TEST_F(StrongBindingTest, ExplicitDeleteImpl) { |
391 bool ptr_error_handler_called = false; | 385 bool ptr_error_handler_called = false; |
392 sample::ServicePtr ptr; | 386 sample::ServicePtr ptr; |
393 auto request = GetProxy(&ptr); | 387 auto request = GetProxy(&ptr); |
394 base::RunLoop run_loop; | 388 base::RunLoop run_loop; |
395 ptr.set_connection_error_handler( | 389 ptr.set_connection_error_handler( |
396 [&ptr_error_handler_called, &run_loop]() { | 390 SetFlagAndRunClosure(&ptr_error_handler_called, run_loop.QuitClosure())); |
397 ptr_error_handler_called = true; | |
398 run_loop.Quit(); | |
399 }); | |
400 bool was_deleted = false; | 391 bool was_deleted = false; |
401 ServiceImplWithStrongBinding* impl = | 392 ServiceImplWithStrongBinding* impl = |
402 new ServiceImplWithStrongBinding(&was_deleted, std::move(request)); | 393 new ServiceImplWithStrongBinding(&was_deleted, std::move(request)); |
403 bool binding_error_handler_called = false; | 394 bool binding_error_handler_called = false; |
404 impl->binding().set_connection_error_handler( | 395 impl->binding().set_connection_error_handler( |
405 [&binding_error_handler_called]() { | 396 SetFlagAndRunClosure(&binding_error_handler_called)); |
406 binding_error_handler_called = true; | |
407 }); | |
408 | 397 |
409 loop().RunUntilIdle(); | 398 loop().RunUntilIdle(); |
410 EXPECT_FALSE(ptr_error_handler_called); | 399 EXPECT_FALSE(ptr_error_handler_called); |
411 EXPECT_FALSE(was_deleted); | 400 EXPECT_FALSE(was_deleted); |
412 | 401 |
413 delete impl; | 402 delete impl; |
414 EXPECT_FALSE(ptr_error_handler_called); | 403 EXPECT_FALSE(ptr_error_handler_called); |
415 EXPECT_TRUE(was_deleted); | 404 EXPECT_TRUE(was_deleted); |
416 was_deleted = false; // It shouldn't be double-deleted! | 405 was_deleted = false; // It shouldn't be double-deleted! |
417 run_loop.Run(); | 406 run_loop.Run(); |
418 EXPECT_TRUE(ptr_error_handler_called); | 407 EXPECT_TRUE(ptr_error_handler_called); |
419 EXPECT_FALSE(was_deleted); | 408 EXPECT_FALSE(was_deleted); |
420 | 409 |
421 EXPECT_FALSE(binding_error_handler_called); | 410 EXPECT_FALSE(binding_error_handler_called); |
422 } | 411 } |
423 | 412 |
424 } // namespace | 413 } // namespace |
425 } // mojo | 414 } // mojo |
OLD | NEW |