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> |
11 #include <utility> | 11 #include <utility> |
12 | 12 |
13 #include "base/macros.h" | 13 #include "base/macros.h" |
| 14 #include "base/memory/weak_ptr.h" |
14 #include "base/message_loop/message_loop.h" | 15 #include "base/message_loop/message_loop.h" |
15 #include "base/run_loop.h" | 16 #include "base/run_loop.h" |
16 #include "mojo/public/cpp/bindings/strong_binding.h" | 17 #include "mojo/public/cpp/bindings/strong_binding.h" |
17 #include "mojo/public/interfaces/bindings/tests/ping_service.mojom.h" | 18 #include "mojo/public/interfaces/bindings/tests/ping_service.mojom.h" |
18 #include "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom.h" | 19 #include "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom.h" |
19 #include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h" | 20 #include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h" |
20 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
21 | 22 |
22 namespace mojo { | 23 namespace mojo { |
23 namespace { | 24 namespace { |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 EXPECT_FALSE(called); | 308 EXPECT_FALSE(called); |
308 | 309 |
309 // Resume the binding, which should trigger the error handler. | 310 // Resume the binding, which should trigger the error handler. |
310 binding.ResumeIncomingMethodCallProcessing(); | 311 binding.ResumeIncomingMethodCallProcessing(); |
311 run_loop.Run(); | 312 run_loop.Run(); |
312 EXPECT_TRUE(called); | 313 EXPECT_TRUE(called); |
313 } | 314 } |
314 | 315 |
315 class PingServiceImpl : public test::PingService { | 316 class PingServiceImpl : public test::PingService { |
316 public: | 317 public: |
317 explicit PingServiceImpl(test::PingServiceRequest request) | 318 PingServiceImpl() {} |
318 : binding_(this, std::move(request)) {} | |
319 ~PingServiceImpl() override {} | 319 ~PingServiceImpl() override {} |
320 | 320 |
321 // test::PingService: | 321 // test::PingService: |
322 void Ping(const PingCallback& callback) override { | 322 void Ping(const PingCallback& callback) override { |
323 if (!ping_handler_.is_null()) | 323 if (!ping_handler_.is_null()) |
324 ping_handler_.Run(); | 324 ping_handler_.Run(); |
325 callback.Run(); | 325 callback.Run(); |
326 } | 326 } |
327 | 327 |
328 mojo::Binding<test::PingService>& binding() { return binding_; } | |
329 | |
330 void set_ping_handler(const base::Closure& handler) { | 328 void set_ping_handler(const base::Closure& handler) { |
331 ping_handler_ = handler; | 329 ping_handler_ = handler; |
332 } | 330 } |
333 | 331 |
334 private: | 332 private: |
335 mojo::Binding<test::PingService> binding_; | |
336 base::Closure ping_handler_; | 333 base::Closure ping_handler_; |
337 | 334 |
338 DISALLOW_COPY_AND_ASSIGN(PingServiceImpl); | 335 DISALLOW_COPY_AND_ASSIGN(PingServiceImpl); |
339 }; | 336 }; |
340 | 337 |
341 class CallbackFilter : public MessageReceiver { | 338 class CallbackFilter : public MessageReceiver { |
342 public: | 339 public: |
343 explicit CallbackFilter(const base::Closure& callback) | 340 explicit CallbackFilter(const base::Closure& callback) |
344 : callback_(callback) {} | 341 : callback_(callback) {} |
345 ~CallbackFilter() override {} | 342 ~CallbackFilter() override {} |
346 | 343 |
347 static std::unique_ptr<CallbackFilter> Wrap(const base::Closure& callback) { | 344 static std::unique_ptr<CallbackFilter> Wrap(const base::Closure& callback) { |
348 return base::MakeUnique<CallbackFilter>(callback); | 345 return base::MakeUnique<CallbackFilter>(callback); |
349 } | 346 } |
350 | 347 |
351 // MessageReceiver: | 348 // MessageReceiver: |
352 bool Accept(Message* message) override { | 349 bool Accept(Message* message) override { |
353 callback_.Run(); | 350 callback_.Run(); |
354 return true; | 351 return true; |
355 } | 352 } |
356 | 353 |
357 private: | 354 private: |
358 const base::Closure callback_; | 355 const base::Closure callback_; |
359 }; | 356 }; |
360 | 357 |
361 // Verifies that message filters are notified in the order they were added and | 358 // Verifies that message filters are notified in the order they were added and |
362 // are always notified before a message is dispatched. | 359 // are always notified before a message is dispatched. |
363 TEST_F(BindingTest, MessageFilter) { | 360 TEST_F(BindingTest, MessageFilter) { |
364 test::PingServicePtr ptr; | 361 test::PingServicePtr ptr; |
365 PingServiceImpl impl(GetProxy(&ptr)); | 362 PingServiceImpl impl; |
| 363 mojo::Binding<test::PingService> binding(&impl, GetProxy(&ptr)); |
366 | 364 |
367 int status = 0; | 365 int status = 0; |
368 auto handler_helper = [] (int* status, int expected_status, int new_status) { | 366 auto handler_helper = [] (int* status, int expected_status, int new_status) { |
369 EXPECT_EQ(expected_status, *status); | 367 EXPECT_EQ(expected_status, *status); |
370 *status = new_status; | 368 *status = new_status; |
371 }; | 369 }; |
372 auto create_handler = [&] (int expected_status, int new_status) { | 370 auto create_handler = [&] (int expected_status, int new_status) { |
373 return base::Bind(handler_helper, &status, expected_status, new_status); | 371 return base::Bind(handler_helper, &status, expected_status, new_status); |
374 }; | 372 }; |
375 | 373 |
376 impl.binding().AddFilter(CallbackFilter::Wrap(create_handler(0, 1))); | 374 binding.AddFilter(CallbackFilter::Wrap(create_handler(0, 1))); |
377 impl.binding().AddFilter(CallbackFilter::Wrap(create_handler(1, 2))); | 375 binding.AddFilter(CallbackFilter::Wrap(create_handler(1, 2))); |
378 impl.set_ping_handler(create_handler(2, 3)); | 376 impl.set_ping_handler(create_handler(2, 3)); |
379 | 377 |
380 for (int i = 0; i < 10; ++i) { | 378 for (int i = 0; i < 10; ++i) { |
381 status = 0; | 379 status = 0; |
382 base::RunLoop loop; | 380 base::RunLoop loop; |
383 ptr->Ping(loop.QuitClosure()); | 381 ptr->Ping(loop.QuitClosure()); |
384 loop.Run(); | 382 loop.Run(); |
385 EXPECT_EQ(3, status); | 383 EXPECT_EQ(3, status); |
386 } | 384 } |
387 } | 385 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
438 EXPECT_EQ("hello", description); | 436 EXPECT_EQ("hello", description); |
439 quit_closure.Run(); | 437 quit_closure.Run(); |
440 }, | 438 }, |
441 run_loop.QuitClosure())); | 439 run_loop.QuitClosure())); |
442 | 440 |
443 ptr.ResetWithReason(1234u, "hello"); | 441 ptr.ResetWithReason(1234u, "hello"); |
444 | 442 |
445 run_loop.Run(); | 443 run_loop.Run(); |
446 } | 444 } |
447 | 445 |
| 446 template <typename T> |
| 447 struct WeakPtrImplRefTraits { |
| 448 using PointerType = base::WeakPtr<T>; |
| 449 |
| 450 static bool IsNull(const base::WeakPtr<T>& ptr) { return !ptr; } |
| 451 static T* GetRawPointer(base::WeakPtr<T>* ptr) { return ptr->get(); } |
| 452 }; |
| 453 |
| 454 template <typename T> |
| 455 using WeakBinding = Binding<T, WeakPtrImplRefTraits<T>>; |
| 456 |
| 457 TEST_F(BindingTest, CustomImplPointerType) { |
| 458 PingServiceImpl impl; |
| 459 base::WeakPtrFactory<test::PingService> weak_factory(&impl); |
| 460 |
| 461 test::PingServicePtr proxy; |
| 462 WeakBinding<test::PingService> binding(weak_factory.GetWeakPtr(), |
| 463 GetProxy(&proxy)); |
| 464 |
| 465 { |
| 466 // Ensure the binding is functioning. |
| 467 base::RunLoop run_loop; |
| 468 proxy->Ping(run_loop.QuitClosure()); |
| 469 run_loop.Run(); |
| 470 } |
| 471 |
| 472 { |
| 473 // Attempt to dispatch another message after the WeakPtr is invalidated. |
| 474 base::Closure assert_not_reached = base::Bind([] { NOTREACHED(); }); |
| 475 impl.set_ping_handler(assert_not_reached); |
| 476 proxy->Ping(assert_not_reached); |
| 477 |
| 478 // The binding will close its end of the pipe which will trigger a |
| 479 // connection error on |proxy|. |
| 480 base::RunLoop run_loop; |
| 481 proxy.set_connection_error_handler(run_loop.QuitClosure()); |
| 482 weak_factory.InvalidateWeakPtrs(); |
| 483 run_loop.Run(); |
| 484 } |
| 485 } |
| 486 |
448 // StrongBindingTest ----------------------------------------------------------- | 487 // StrongBindingTest ----------------------------------------------------------- |
449 | 488 |
450 using StrongBindingTest = BindingTestBase; | 489 using StrongBindingTest = BindingTestBase; |
451 | 490 |
452 // Tests that destroying a mojo::StrongBinding closes the bound message pipe | 491 // Tests that destroying a mojo::StrongBinding closes the bound message pipe |
453 // handle but does *not* destroy the implementation object. | 492 // handle but does *not* destroy the implementation object. |
454 TEST_F(StrongBindingTest, DestroyClosesMessagePipe) { | 493 TEST_F(StrongBindingTest, DestroyClosesMessagePipe) { |
455 base::RunLoop run_loop; | 494 base::RunLoop run_loop; |
456 bool encountered_error = false; | 495 bool encountered_error = false; |
457 bool was_deleted = false; | 496 bool was_deleted = false; |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 }, | 601 }, |
563 run_loop.QuitClosure())); | 602 run_loop.QuitClosure())); |
564 | 603 |
565 ptr.ResetWithReason(5678u, "hello"); | 604 ptr.ResetWithReason(5678u, "hello"); |
566 | 605 |
567 run_loop.Run(); | 606 run_loop.Run(); |
568 } | 607 } |
569 | 608 |
570 } // namespace | 609 } // namespace |
571 } // mojo | 610 } // mojo |
OLD | NEW |