OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 #include "mojo/public/cpp/bindings/binding.h" | 5 #include "mojo/public/cpp/bindings/binding.h" |
6 #include "mojo/public/cpp/bindings/error_handler.h" | 6 #include "mojo/public/cpp/bindings/error_handler.h" |
7 #include "mojo/public/cpp/bindings/strong_binding.h" | 7 #include "mojo/public/cpp/bindings/strong_binding.h" |
8 #include "mojo/public/cpp/environment/environment.h" | 8 #include "mojo/public/cpp/environment/environment.h" |
9 #include "mojo/public/cpp/utility/run_loop.h" | 9 #include "mojo/public/cpp/utility/run_loop.h" |
10 #include "mojo/public/interfaces/bindings/tests/math_calculator.mojom.h" | 10 #include "mojo/public/interfaces/bindings/tests/math_calculator.mojom.h" |
11 #include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h" | 11 #include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h" |
12 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
13 | 13 |
14 namespace mojo { | 14 namespace mojo { |
15 namespace test { | 15 namespace test { |
16 namespace { | 16 namespace { |
17 | 17 |
18 class ErrorObserver : public ErrorHandler { | 18 class ErrorObserver : public ErrorHandler { |
19 public: | 19 public: |
20 ErrorObserver() : encountered_error_(false) {} | 20 ErrorObserver() : encountered_error_(false) {} |
21 | 21 |
22 bool encountered_error() const { return encountered_error_; } | 22 bool encountered_error() const { return encountered_error_; } |
23 | 23 |
24 void OnConnectionError() override { encountered_error_ = true; } | 24 void OnConnectionError() override { encountered_error_ = true; } |
25 | 25 |
26 private: | 26 private: |
27 bool encountered_error_; | 27 bool encountered_error_; |
28 }; | 28 }; |
29 | 29 |
| 30 template <typename Method, typename Class> |
| 31 class RunnableImpl { |
| 32 public: |
| 33 RunnableImpl(Method method, Class instance) |
| 34 : method_(method), instance_(instance) {} |
| 35 template <typename... Args> |
| 36 void Run(Args... args) const { |
| 37 (instance_->*method_)(args...); |
| 38 } |
| 39 |
| 40 private: |
| 41 Method method_; |
| 42 Class instance_; |
| 43 }; |
| 44 |
| 45 template <typename Method, typename Class> |
| 46 RunnableImpl<Method, Class> MakeRunnable(Method method, Class object) { |
| 47 return RunnableImpl<Method, Class>(method, object); |
| 48 } |
| 49 |
| 50 typedef mojo::Callback<void(double)> CalcCallback; |
| 51 |
30 class MathCalculatorImpl : public InterfaceImpl<math::Calculator> { | 52 class MathCalculatorImpl : public InterfaceImpl<math::Calculator> { |
31 public: | 53 public: |
32 ~MathCalculatorImpl() override {} | 54 ~MathCalculatorImpl() override {} |
33 | 55 |
34 MathCalculatorImpl() : total_(0.0) {} | 56 MathCalculatorImpl() : total_(0.0) {} |
35 | 57 |
36 void Clear() override { client()->Output(total_); } | 58 void Clear(const CalcCallback& callback) override { |
37 | 59 total_ = 0.0; |
38 void Add(double value) override { | 60 callback.Run(total_); |
39 total_ += value; | |
40 client()->Output(total_); | |
41 } | 61 } |
42 | 62 |
43 void Multiply(double value) override { | 63 void Add(double value, const CalcCallback& callback) override { |
| 64 total_ += value; |
| 65 callback.Run(total_); |
| 66 } |
| 67 |
| 68 void Multiply(double value, const CalcCallback& callback) override { |
44 total_ *= value; | 69 total_ *= value; |
45 client()->Output(total_); | 70 callback.Run(total_); |
46 } | 71 } |
47 | 72 |
48 private: | 73 private: |
49 double total_; | 74 double total_; |
50 }; | 75 }; |
51 | 76 |
52 class MathCalculatorUIImpl : public math::CalculatorUI { | 77 class MathCalculatorUI { |
53 public: | 78 public: |
54 explicit MathCalculatorUIImpl(math::CalculatorPtr calculator) | 79 explicit MathCalculatorUI(math::CalculatorPtr calculator) |
55 : calculator_(calculator.Pass()), output_(0.0) { | 80 : calculator_(calculator.Pass()), |
56 calculator_.set_client(this); | 81 output_(0.0), |
57 } | 82 callback_(MakeRunnable(&MathCalculatorUI::Output, this)) {} |
58 | 83 |
59 bool WaitForIncomingMethodCall() { | 84 bool WaitForIncomingMethodCall() { |
60 return calculator_.WaitForIncomingMethodCall(); | 85 return calculator_.WaitForIncomingMethodCall(); |
61 } | 86 } |
62 | 87 |
63 bool encountered_error() const { return calculator_.encountered_error(); } | 88 bool encountered_error() const { return calculator_.encountered_error(); } |
64 | 89 |
65 void Add(double value) { calculator_->Add(value); } | 90 void Add(double value) { calculator_->Add(value, callback_); } |
66 | 91 |
67 void Subtract(double value) { calculator_->Add(-value); } | 92 void Subtract(double value) { calculator_->Add(-value, callback_); } |
68 | 93 |
69 void Multiply(double value) { calculator_->Multiply(value); } | 94 void Multiply(double value) { calculator_->Multiply(value, callback_); } |
70 | 95 |
71 void Divide(double value) { calculator_->Multiply(1.0 / value); } | 96 void Divide(double value) { calculator_->Multiply(1.0 / value, callback_); } |
72 | 97 |
73 double GetOutput() const { return output_; } | 98 double GetOutput() const { return output_; } |
74 | 99 |
75 private: | 100 private: |
76 // math::CalculatorUI implementation: | 101 void Output(double output) { output_ = output; } |
77 void Output(double value) override { output_ = value; } | |
78 | 102 |
79 math::CalculatorPtr calculator_; | 103 math::CalculatorPtr calculator_; |
80 double output_; | 104 double output_; |
| 105 Callback<void(double)> callback_; |
81 }; | 106 }; |
82 | 107 |
83 class SelfDestructingMathCalculatorUIImpl : public math::CalculatorUI { | 108 class SelfDestructingMathCalculatorUI { |
84 public: | 109 public: |
85 explicit SelfDestructingMathCalculatorUIImpl(math::CalculatorPtr calculator) | 110 explicit SelfDestructingMathCalculatorUI(math::CalculatorPtr calculator) |
86 : calculator_(calculator.Pass()), nesting_level_(0) { | 111 : calculator_(calculator.Pass()), nesting_level_(0) { |
87 ++num_instances_; | 112 ++num_instances_; |
88 calculator_.set_client(this); | |
89 } | 113 } |
90 | 114 |
91 void BeginTest(bool nested) { | 115 void BeginTest(bool nested) { |
92 nesting_level_ = nested ? 2 : 1; | 116 nesting_level_ = nested ? 2 : 1; |
93 calculator_->Add(1.0); | 117 calculator_->Add( |
| 118 1.0, MakeRunnable(&SelfDestructingMathCalculatorUI::Output, this)); |
94 } | 119 } |
95 | 120 |
96 static int num_instances() { return num_instances_; } | 121 static int num_instances() { return num_instances_; } |
97 | 122 |
98 private: | 123 void Output(double value) { |
99 ~SelfDestructingMathCalculatorUIImpl() override { --num_instances_; } | |
100 | |
101 void Output(double value) override { | |
102 if (--nesting_level_ > 0) { | 124 if (--nesting_level_ > 0) { |
103 // Add some more and wait for re-entrant call to Output! | 125 // Add some more and wait for re-entrant call to Output! |
104 calculator_->Add(1.0); | 126 calculator_->Add( |
| 127 1.0, MakeRunnable(&SelfDestructingMathCalculatorUI::Output, this)); |
105 RunLoop::current()->RunUntilIdle(); | 128 RunLoop::current()->RunUntilIdle(); |
106 } else { | 129 } else { |
107 delete this; | 130 delete this; |
108 } | 131 } |
109 } | 132 } |
110 | 133 |
| 134 private: |
| 135 ~SelfDestructingMathCalculatorUI() { --num_instances_; } |
| 136 |
111 math::CalculatorPtr calculator_; | 137 math::CalculatorPtr calculator_; |
112 int nesting_level_; | 138 int nesting_level_; |
113 static int num_instances_; | 139 static int num_instances_; |
114 }; | 140 }; |
115 | 141 |
116 // static | 142 // static |
117 int SelfDestructingMathCalculatorUIImpl::num_instances_ = 0; | 143 int SelfDestructingMathCalculatorUI::num_instances_ = 0; |
118 | 144 |
119 class ReentrantServiceImpl : public InterfaceImpl<sample::Service> { | 145 class ReentrantServiceImpl : public InterfaceImpl<sample::Service> { |
120 public: | 146 public: |
121 ~ReentrantServiceImpl() override {} | 147 ~ReentrantServiceImpl() override {} |
122 | 148 |
123 ReentrantServiceImpl() : call_depth_(0), max_call_depth_(0) {} | 149 ReentrantServiceImpl() : call_depth_(0), max_call_depth_(0) {} |
124 | 150 |
125 int max_call_depth() { return max_call_depth_; } | 151 int max_call_depth() { return max_call_depth_; } |
126 | 152 |
127 void Frobinate(sample::FooPtr foo, | 153 void Frobinate(sample::FooPtr foo, |
(...skipping 22 matching lines...) Expand all Loading... |
150 private: | 176 private: |
151 Environment env_; | 177 Environment env_; |
152 RunLoop loop_; | 178 RunLoop loop_; |
153 }; | 179 }; |
154 | 180 |
155 TEST_F(InterfacePtrTest, EndToEnd) { | 181 TEST_F(InterfacePtrTest, EndToEnd) { |
156 math::CalculatorPtr calc; | 182 math::CalculatorPtr calc; |
157 BindToProxy(new MathCalculatorImpl(), &calc); | 183 BindToProxy(new MathCalculatorImpl(), &calc); |
158 | 184 |
159 // Suppose this is instantiated in a process that has pipe1_. | 185 // Suppose this is instantiated in a process that has pipe1_. |
160 MathCalculatorUIImpl calculator_ui(calc.Pass()); | 186 MathCalculatorUI calculator_ui(calc.Pass()); |
161 | 187 |
162 calculator_ui.Add(2.0); | 188 calculator_ui.Add(2.0); |
163 calculator_ui.Multiply(5.0); | 189 calculator_ui.Multiply(5.0); |
164 | 190 |
165 PumpMessages(); | 191 PumpMessages(); |
166 | 192 |
167 EXPECT_EQ(10.0, calculator_ui.GetOutput()); | 193 EXPECT_EQ(10.0, calculator_ui.GetOutput()); |
168 } | 194 } |
169 | 195 |
170 TEST_F(InterfacePtrTest, EndToEnd_Synchronous) { | 196 TEST_F(InterfacePtrTest, EndToEnd_Synchronous) { |
171 math::CalculatorPtr calc; | 197 math::CalculatorPtr calc; |
172 MathCalculatorImpl* impl = BindToProxy(new MathCalculatorImpl(), &calc); | 198 MathCalculatorImpl* impl = BindToProxy(new MathCalculatorImpl(), &calc); |
173 | 199 |
174 // Suppose this is instantiated in a process that has pipe1_. | 200 // Suppose this is instantiated in a process that has pipe1_. |
175 MathCalculatorUIImpl calculator_ui(calc.Pass()); | 201 MathCalculatorUI calculator_ui(calc.Pass()); |
176 | 202 |
177 EXPECT_EQ(0.0, calculator_ui.GetOutput()); | 203 EXPECT_EQ(0.0, calculator_ui.GetOutput()); |
178 | 204 |
179 calculator_ui.Add(2.0); | 205 calculator_ui.Add(2.0); |
180 EXPECT_EQ(0.0, calculator_ui.GetOutput()); | 206 EXPECT_EQ(0.0, calculator_ui.GetOutput()); |
181 impl->WaitForIncomingMethodCall(); | 207 impl->WaitForIncomingMethodCall(); |
182 calculator_ui.WaitForIncomingMethodCall(); | 208 calculator_ui.WaitForIncomingMethodCall(); |
183 EXPECT_EQ(2.0, calculator_ui.GetOutput()); | 209 EXPECT_EQ(2.0, calculator_ui.GetOutput()); |
184 | 210 |
185 calculator_ui.Multiply(5.0); | 211 calculator_ui.Multiply(5.0); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 EXPECT_FALSE(a.internal_state()->router_for_testing()); | 249 EXPECT_FALSE(a.internal_state()->router_for_testing()); |
224 | 250 |
225 // Test that handle was closed. | 251 // Test that handle was closed. |
226 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, CloseRaw(handle)); | 252 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, CloseRaw(handle)); |
227 } | 253 } |
228 | 254 |
229 TEST_F(InterfacePtrTest, EncounteredError) { | 255 TEST_F(InterfacePtrTest, EncounteredError) { |
230 math::CalculatorPtr proxy; | 256 math::CalculatorPtr proxy; |
231 MathCalculatorImpl* server = BindToProxy(new MathCalculatorImpl(), &proxy); | 257 MathCalculatorImpl* server = BindToProxy(new MathCalculatorImpl(), &proxy); |
232 | 258 |
233 MathCalculatorUIImpl calculator_ui(proxy.Pass()); | 259 MathCalculatorUI calculator_ui(proxy.Pass()); |
234 | 260 |
235 calculator_ui.Add(2.0); | 261 calculator_ui.Add(2.0); |
236 PumpMessages(); | 262 PumpMessages(); |
237 EXPECT_EQ(2.0, calculator_ui.GetOutput()); | 263 EXPECT_EQ(2.0, calculator_ui.GetOutput()); |
238 EXPECT_FALSE(calculator_ui.encountered_error()); | 264 EXPECT_FALSE(calculator_ui.encountered_error()); |
239 | 265 |
240 calculator_ui.Multiply(5.0); | 266 calculator_ui.Multiply(5.0); |
241 EXPECT_FALSE(calculator_ui.encountered_error()); | 267 EXPECT_FALSE(calculator_ui.encountered_error()); |
242 | 268 |
243 // Close the server. | 269 // Close the server. |
244 server->internal_router()->CloseMessagePipe(); | 270 server->internal_router()->CloseMessagePipe(); |
245 | 271 |
246 // The state change isn't picked up locally yet. | 272 // The state change isn't picked up locally yet. |
247 EXPECT_FALSE(calculator_ui.encountered_error()); | 273 EXPECT_FALSE(calculator_ui.encountered_error()); |
248 | 274 |
249 PumpMessages(); | 275 PumpMessages(); |
250 | 276 |
251 // OK, now we see the error. | 277 // OK, now we see the error. |
252 EXPECT_TRUE(calculator_ui.encountered_error()); | 278 EXPECT_TRUE(calculator_ui.encountered_error()); |
253 } | 279 } |
254 | 280 |
255 TEST_F(InterfacePtrTest, EncounteredErrorCallback) { | 281 TEST_F(InterfacePtrTest, EncounteredErrorCallback) { |
256 math::CalculatorPtr proxy; | 282 math::CalculatorPtr proxy; |
257 MathCalculatorImpl* server = BindToProxy(new MathCalculatorImpl(), &proxy); | 283 MathCalculatorImpl* server = BindToProxy(new MathCalculatorImpl(), &proxy); |
258 | 284 |
259 ErrorObserver error_observer; | 285 ErrorObserver error_observer; |
260 proxy.set_error_handler(&error_observer); | 286 proxy.set_error_handler(&error_observer); |
261 | 287 |
262 MathCalculatorUIImpl calculator_ui(proxy.Pass()); | 288 MathCalculatorUI calculator_ui(proxy.Pass()); |
263 | 289 |
264 calculator_ui.Add(2.0); | 290 calculator_ui.Add(2.0); |
265 PumpMessages(); | 291 PumpMessages(); |
266 EXPECT_EQ(2.0, calculator_ui.GetOutput()); | 292 EXPECT_EQ(2.0, calculator_ui.GetOutput()); |
267 EXPECT_FALSE(calculator_ui.encountered_error()); | 293 EXPECT_FALSE(calculator_ui.encountered_error()); |
268 | 294 |
269 calculator_ui.Multiply(5.0); | 295 calculator_ui.Multiply(5.0); |
270 EXPECT_FALSE(calculator_ui.encountered_error()); | 296 EXPECT_FALSE(calculator_ui.encountered_error()); |
271 | 297 |
272 // Close the server. | 298 // Close the server. |
(...skipping 17 matching lines...) Expand all Loading... |
290 // does not have an explicit Client attribute. | 316 // does not have an explicit Client attribute. |
291 sample::PortPtr port; | 317 sample::PortPtr port; |
292 MessagePipe pipe; | 318 MessagePipe pipe; |
293 port.Bind(pipe.handle0.Pass()); | 319 port.Bind(pipe.handle0.Pass()); |
294 } | 320 } |
295 | 321 |
296 TEST_F(InterfacePtrTest, DestroyInterfacePtrOnClientMethod) { | 322 TEST_F(InterfacePtrTest, DestroyInterfacePtrOnClientMethod) { |
297 math::CalculatorPtr proxy; | 323 math::CalculatorPtr proxy; |
298 BindToProxy(new MathCalculatorImpl(), &proxy); | 324 BindToProxy(new MathCalculatorImpl(), &proxy); |
299 | 325 |
300 EXPECT_EQ(0, SelfDestructingMathCalculatorUIImpl::num_instances()); | 326 EXPECT_EQ(0, SelfDestructingMathCalculatorUI::num_instances()); |
301 | 327 |
302 SelfDestructingMathCalculatorUIImpl* impl = | 328 SelfDestructingMathCalculatorUI* impl = |
303 new SelfDestructingMathCalculatorUIImpl(proxy.Pass()); | 329 new SelfDestructingMathCalculatorUI(proxy.Pass()); |
304 impl->BeginTest(false); | 330 impl->BeginTest(false); |
305 | 331 |
306 PumpMessages(); | 332 PumpMessages(); |
307 | 333 |
308 EXPECT_EQ(0, SelfDestructingMathCalculatorUIImpl::num_instances()); | 334 EXPECT_EQ(0, SelfDestructingMathCalculatorUI::num_instances()); |
309 } | 335 } |
310 | 336 |
311 TEST_F(InterfacePtrTest, NestedDestroyInterfacePtrOnClientMethod) { | 337 TEST_F(InterfacePtrTest, NestedDestroyInterfacePtrOnClientMethod) { |
312 math::CalculatorPtr proxy; | 338 math::CalculatorPtr proxy; |
313 BindToProxy(new MathCalculatorImpl(), &proxy); | 339 BindToProxy(new MathCalculatorImpl(), &proxy); |
314 | 340 |
315 EXPECT_EQ(0, SelfDestructingMathCalculatorUIImpl::num_instances()); | 341 EXPECT_EQ(0, SelfDestructingMathCalculatorUI::num_instances()); |
316 | 342 |
317 SelfDestructingMathCalculatorUIImpl* impl = | 343 SelfDestructingMathCalculatorUI* impl = |
318 new SelfDestructingMathCalculatorUIImpl(proxy.Pass()); | 344 new SelfDestructingMathCalculatorUI(proxy.Pass()); |
319 impl->BeginTest(true); | 345 impl->BeginTest(true); |
320 | 346 |
321 PumpMessages(); | 347 PumpMessages(); |
322 | 348 |
323 EXPECT_EQ(0, SelfDestructingMathCalculatorUIImpl::num_instances()); | 349 EXPECT_EQ(0, SelfDestructingMathCalculatorUI::num_instances()); |
324 } | 350 } |
325 | 351 |
326 TEST_F(InterfacePtrTest, ReentrantWaitForIncomingMethodCall) { | 352 TEST_F(InterfacePtrTest, ReentrantWaitForIncomingMethodCall) { |
327 sample::ServicePtr proxy; | 353 sample::ServicePtr proxy; |
328 ReentrantServiceImpl* impl = BindToProxy(new ReentrantServiceImpl(), &proxy); | 354 ReentrantServiceImpl* impl = BindToProxy(new ReentrantServiceImpl(), &proxy); |
329 | 355 |
330 proxy->Frobinate(nullptr, sample::Service::BAZ_OPTIONS_REGULAR, nullptr); | 356 proxy->Frobinate(nullptr, sample::Service::BAZ_OPTIONS_REGULAR, nullptr); |
331 proxy->Frobinate(nullptr, sample::Service::BAZ_OPTIONS_REGULAR, nullptr); | 357 proxy->Frobinate(nullptr, sample::Service::BAZ_OPTIONS_REGULAR, nullptr); |
332 | 358 |
333 PumpMessages(); | 359 PumpMessages(); |
334 | 360 |
335 EXPECT_EQ(2, impl->max_call_depth()); | 361 EXPECT_EQ(2, impl->max_call_depth()); |
336 } | 362 } |
337 | 363 |
338 class StrongMathCalculatorImpl : public math::Calculator, public ErrorHandler { | 364 class StrongMathCalculatorImpl : public math::Calculator, public ErrorHandler { |
339 public: | 365 public: |
340 StrongMathCalculatorImpl(ScopedMessagePipeHandle handle, | 366 StrongMathCalculatorImpl(ScopedMessagePipeHandle handle, |
341 bool* error_received, | 367 bool* error_received, |
342 bool* destroyed) | 368 bool* destroyed) |
343 : error_received_(error_received), | 369 : error_received_(error_received), |
344 destroyed_(destroyed), | 370 destroyed_(destroyed), |
345 binding_(this, handle.Pass()) { | 371 binding_(this, handle.Pass()) { |
346 binding_.set_error_handler(this); | 372 binding_.set_error_handler(this); |
347 } | 373 } |
348 ~StrongMathCalculatorImpl() override { *destroyed_ = true; } | 374 ~StrongMathCalculatorImpl() override { *destroyed_ = true; } |
349 | 375 |
350 // math::Calculator implementation. | 376 // math::Calculator implementation. |
351 void Clear() override { binding_.client()->Output(total_); } | 377 void Clear(const CalcCallback& callback) override { callback.Run(total_); } |
352 | 378 |
353 void Add(double value) override { | 379 void Add(double value, const CalcCallback& callback) override { |
354 total_ += value; | 380 total_ += value; |
355 binding_.client()->Output(total_); | 381 callback.Run(total_); |
356 } | 382 } |
357 | 383 |
358 void Multiply(double value) override { | 384 void Multiply(double value, const CalcCallback& callback) override { |
359 total_ *= value; | 385 total_ *= value; |
360 binding_.client()->Output(total_); | 386 callback.Run(total_); |
361 } | 387 } |
362 | 388 |
363 // ErrorHandler implementation. | 389 // ErrorHandler implementation. |
364 void OnConnectionError() override { *error_received_ = true; } | 390 void OnConnectionError() override { *error_received_ = true; } |
365 | 391 |
366 private: | 392 private: |
367 double total_ = 0.0; | 393 double total_ = 0.0; |
368 bool* error_received_; | 394 bool* error_received_; |
369 bool* destroyed_; | 395 bool* destroyed_; |
370 | 396 |
371 StrongBinding<math::Calculator> binding_; | 397 StrongBinding<math::Calculator> binding_; |
372 }; | 398 }; |
373 | 399 |
374 TEST(StrongConnectorTest, Math) { | 400 TEST(StrongConnectorTest, Math) { |
375 Environment env; | 401 Environment env; |
376 RunLoop loop; | 402 RunLoop loop; |
377 | 403 |
378 bool error_received = false; | 404 bool error_received = false; |
379 bool destroyed = false; | 405 bool destroyed = false; |
380 MessagePipe pipe; | 406 MessagePipe pipe; |
381 new StrongMathCalculatorImpl(pipe.handle0.Pass(), &error_received, | 407 new StrongMathCalculatorImpl(pipe.handle0.Pass(), &error_received, |
382 &destroyed); | 408 &destroyed); |
383 | 409 |
384 math::CalculatorPtr calc; | 410 math::CalculatorPtr calc; |
385 calc.Bind(pipe.handle1.Pass()); | 411 calc.Bind(pipe.handle1.Pass()); |
386 | 412 |
387 { | 413 { |
388 // Suppose this is instantiated in a process that has the other end of the | 414 // Suppose this is instantiated in a process that has the other end of the |
389 // message pipe. | 415 // message pipe. |
390 MathCalculatorUIImpl calculator_ui(calc.Pass()); | 416 MathCalculatorUI calculator_ui(calc.Pass()); |
391 | 417 |
392 calculator_ui.Add(2.0); | 418 calculator_ui.Add(2.0); |
393 calculator_ui.Multiply(5.0); | 419 calculator_ui.Multiply(5.0); |
394 | 420 |
395 loop.RunUntilIdle(); | 421 loop.RunUntilIdle(); |
396 | 422 |
397 EXPECT_EQ(10.0, calculator_ui.GetOutput()); | 423 EXPECT_EQ(10.0, calculator_ui.GetOutput()); |
398 EXPECT_FALSE(error_received); | 424 EXPECT_FALSE(error_received); |
399 EXPECT_FALSE(destroyed); | 425 EXPECT_FALSE(destroyed); |
400 } | 426 } |
(...skipping 11 matching lines...) Expand all Loading... |
412 WeakMathCalculatorImpl(ScopedMessagePipeHandle handle, | 438 WeakMathCalculatorImpl(ScopedMessagePipeHandle handle, |
413 bool* error_received, | 439 bool* error_received, |
414 bool* destroyed) | 440 bool* destroyed) |
415 : error_received_(error_received), | 441 : error_received_(error_received), |
416 destroyed_(destroyed), | 442 destroyed_(destroyed), |
417 binding_(this, handle.Pass()) { | 443 binding_(this, handle.Pass()) { |
418 binding_.set_error_handler(this); | 444 binding_.set_error_handler(this); |
419 } | 445 } |
420 ~WeakMathCalculatorImpl() override { *destroyed_ = true; } | 446 ~WeakMathCalculatorImpl() override { *destroyed_ = true; } |
421 | 447 |
422 void Clear() override { binding_.client()->Output(total_); } | 448 void Clear(const CalcCallback& callback) override { callback.Run(total_); } |
423 | 449 |
424 void Add(double value) override { | 450 void Add(double value, const CalcCallback& callback) override { |
425 total_ += value; | 451 total_ += value; |
426 binding_.client()->Output(total_); | 452 callback.Run(total_); |
427 } | 453 } |
428 | 454 |
429 void Multiply(double value) override { | 455 void Multiply(double value, const CalcCallback& callback) override { |
430 total_ *= value; | 456 total_ *= value; |
431 binding_.client()->Output(total_); | 457 callback.Run(total_); |
432 } | 458 } |
433 | 459 |
434 // ErrorHandler implementation. | 460 // ErrorHandler implementation. |
435 void OnConnectionError() override { *error_received_ = true; } | 461 void OnConnectionError() override { *error_received_ = true; } |
436 | 462 |
437 private: | 463 private: |
438 double total_ = 0.0; | 464 double total_ = 0.0; |
439 bool* error_received_; | 465 bool* error_received_; |
440 bool* destroyed_; | 466 bool* destroyed_; |
441 | 467 |
442 Binding<math::Calculator> binding_; | 468 Binding<math::Calculator> binding_; |
443 }; | 469 }; |
444 | 470 |
445 TEST(WeakConnectorTest, Math) { | 471 TEST(WeakConnectorTest, Math) { |
446 Environment env; | 472 Environment env; |
447 RunLoop loop; | 473 RunLoop loop; |
448 | 474 |
449 bool error_received = false; | 475 bool error_received = false; |
450 bool destroyed = false; | 476 bool destroyed = false; |
451 MessagePipe pipe; | 477 MessagePipe pipe; |
452 WeakMathCalculatorImpl impl(pipe.handle0.Pass(), &error_received, &destroyed); | 478 WeakMathCalculatorImpl impl(pipe.handle0.Pass(), &error_received, &destroyed); |
453 | 479 |
454 math::CalculatorPtr calc; | 480 math::CalculatorPtr calc; |
455 calc.Bind(pipe.handle1.Pass()); | 481 calc.Bind(pipe.handle1.Pass()); |
456 | 482 |
457 { | 483 { |
458 // Suppose this is instantiated in a process that has the other end of the | 484 // Suppose this is instantiated in a process that has the other end of the |
459 // message pipe. | 485 // message pipe. |
460 MathCalculatorUIImpl calculator_ui(calc.Pass()); | 486 MathCalculatorUI calculator_ui(calc.Pass()); |
461 | 487 |
462 calculator_ui.Add(2.0); | 488 calculator_ui.Add(2.0); |
463 calculator_ui.Multiply(5.0); | 489 calculator_ui.Multiply(5.0); |
464 | 490 |
465 loop.RunUntilIdle(); | 491 loop.RunUntilIdle(); |
466 | 492 |
467 EXPECT_EQ(10.0, calculator_ui.GetOutput()); | 493 EXPECT_EQ(10.0, calculator_ui.GetOutput()); |
468 EXPECT_FALSE(error_received); | 494 EXPECT_FALSE(error_received); |
469 EXPECT_FALSE(destroyed); | 495 EXPECT_FALSE(destroyed); |
470 // Destroying calculator_ui should close the pipe and generate an error on | 496 // Destroying calculator_ui should close the pipe and generate an error on |
471 // the other | 497 // the other |
472 // end which will destroy the instance since it is strongly bound. | 498 // end which will destroy the instance since it is strongly bound. |
473 } | 499 } |
474 | 500 |
475 loop.RunUntilIdle(); | 501 loop.RunUntilIdle(); |
476 EXPECT_TRUE(error_received); | 502 EXPECT_TRUE(error_received); |
477 EXPECT_FALSE(destroyed); | 503 EXPECT_FALSE(destroyed); |
478 } | 504 } |
479 | 505 |
480 } // namespace | 506 } // namespace |
481 } // namespace test | 507 } // namespace test |
482 } // namespace mojo | 508 } // namespace mojo |
OLD | NEW |