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 #include <stddef.h> | 5 #include <stddef.h> |
6 #include <stdint.h> | 6 #include <stdint.h> |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/callback.h" | 11 #include "base/callback.h" |
| 12 #include "base/callback_helpers.h" |
12 #include "base/message_loop/message_loop.h" | 13 #include "base/message_loop/message_loop.h" |
13 #include "base/run_loop.h" | 14 #include "base/run_loop.h" |
14 #include "base/single_thread_task_runner.h" | 15 #include "base/single_thread_task_runner.h" |
15 #include "base/threading/thread.h" | 16 #include "base/threading/thread.h" |
16 #include "base/threading/thread_task_runner_handle.h" | 17 #include "base/threading/thread_task_runner_handle.h" |
17 #include "mojo/public/cpp/bindings/associated_binding.h" | 18 #include "mojo/public/cpp/bindings/associated_binding.h" |
18 #include "mojo/public/cpp/bindings/associated_group.h" | 19 #include "mojo/public/cpp/bindings/associated_group.h" |
19 #include "mojo/public/cpp/bindings/associated_interface_ptr.h" | 20 #include "mojo/public/cpp/bindings/associated_interface_ptr.h" |
20 #include "mojo/public/cpp/bindings/associated_interface_ptr_info.h" | 21 #include "mojo/public/cpp/bindings/associated_interface_ptr_info.h" |
21 #include "mojo/public/cpp/bindings/associated_interface_request.h" | 22 #include "mojo/public/cpp/bindings/associated_interface_request.h" |
22 #include "mojo/public/cpp/bindings/binding.h" | 23 #include "mojo/public/cpp/bindings/binding.h" |
23 #include "mojo/public/cpp/bindings/lib/multiplex_router.h" | 24 #include "mojo/public/cpp/bindings/lib/multiplex_router.h" |
| 25 #include "mojo/public/interfaces/bindings/tests/ping_service.mojom.h" |
24 #include "mojo/public/interfaces/bindings/tests/test_associated_interfaces.mojom
.h" | 26 #include "mojo/public/interfaces/bindings/tests/test_associated_interfaces.mojom
.h" |
25 #include "testing/gtest/include/gtest/gtest.h" | 27 #include "testing/gtest/include/gtest/gtest.h" |
26 | 28 |
27 namespace mojo { | 29 namespace mojo { |
28 namespace test { | 30 namespace test { |
29 namespace { | 31 namespace { |
30 | 32 |
31 using mojo::internal::MultiplexRouter; | 33 using mojo::internal::MultiplexRouter; |
32 | 34 |
33 class IntegerSenderImpl : public IntegerSender { | 35 class IntegerSenderImpl : public IntegerSender { |
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 // There are no associated interfaces running on the pipe yet. It is okay to | 584 // There are no associated interfaces running on the pipe yet. It is okay to |
583 // wait. | 585 // wait. |
584 EXPECT_TRUE(connection.binding()->WaitForIncomingMethodCall()); | 586 EXPECT_TRUE(connection.binding()->WaitForIncomingMethodCall()); |
585 | 587 |
586 // The previous wait has dispatched the GetSender request message, therefore | 588 // The previous wait has dispatched the GetSender request message, therefore |
587 // an associated interface has been set up on the pipe. It is not allowed to | 589 // an associated interface has been set up on the pipe. It is not allowed to |
588 // wait or pause. | 590 // wait or pause. |
589 EXPECT_TRUE(connection.binding()->HasAssociatedInterfaces()); | 591 EXPECT_TRUE(connection.binding()->HasAssociatedInterfaces()); |
590 } | 592 } |
591 | 593 |
| 594 class PingServiceImpl : public PingService { |
| 595 public: |
| 596 explicit PingServiceImpl(PingServiceAssociatedRequest request) |
| 597 : binding_(this, std::move(request)) {} |
| 598 ~PingServiceImpl() override {} |
| 599 |
| 600 AssociatedBinding<PingService>& binding() { return binding_; } |
| 601 |
| 602 void set_ping_handler(const base::Closure& handler) { |
| 603 ping_handler_ = handler; |
| 604 } |
| 605 |
| 606 // PingService: |
| 607 void Ping(const PingCallback& callback) override { |
| 608 if (!ping_handler_.is_null()) |
| 609 ping_handler_.Run(); |
| 610 callback.Run(); |
| 611 } |
| 612 |
| 613 private: |
| 614 AssociatedBinding<PingService> binding_; |
| 615 base::Closure ping_handler_; |
| 616 }; |
| 617 |
| 618 class PingProviderImpl : public AssociatedPingProvider { |
| 619 public: |
| 620 explicit PingProviderImpl(AssociatedPingProviderRequest request) |
| 621 : binding_(this, std::move(request)) {} |
| 622 ~PingProviderImpl() override {} |
| 623 |
| 624 // AssociatedPingProvider: |
| 625 void GetPing(PingServiceAssociatedRequest request) override { |
| 626 ping_services_.emplace_back(new PingServiceImpl(std::move(request))); |
| 627 |
| 628 if (expected_bindings_count_ > 0 && |
| 629 ping_services_.size() == expected_bindings_count_ && |
| 630 !quit_waiting_.is_null()) { |
| 631 expected_bindings_count_ = 0; |
| 632 base::ResetAndReturn(&quit_waiting_).Run(); |
| 633 } |
| 634 } |
| 635 |
| 636 std::vector<std::unique_ptr<PingServiceImpl>>& ping_services() { |
| 637 return ping_services_; |
| 638 } |
| 639 |
| 640 void WaitForBindings(size_t count) { |
| 641 DCHECK(quit_waiting_.is_null()); |
| 642 |
| 643 expected_bindings_count_ = count; |
| 644 base::RunLoop loop; |
| 645 quit_waiting_ = loop.QuitClosure(); |
| 646 loop.Run(); |
| 647 } |
| 648 |
| 649 private: |
| 650 Binding<AssociatedPingProvider> binding_; |
| 651 std::vector<std::unique_ptr<PingServiceImpl>> ping_services_; |
| 652 size_t expected_bindings_count_ = 0; |
| 653 base::Closure quit_waiting_; |
| 654 }; |
| 655 |
| 656 class CallbackFilter : public MessageReceiver { |
| 657 public: |
| 658 explicit CallbackFilter(const base::Closure& callback) |
| 659 : callback_(callback) {} |
| 660 ~CallbackFilter() override {} |
| 661 |
| 662 static std::unique_ptr<CallbackFilter> Wrap(const base::Closure& callback) { |
| 663 return base::MakeUnique<CallbackFilter>(callback); |
| 664 } |
| 665 |
| 666 // MessageReceiver: |
| 667 bool Accept(Message* message) override { |
| 668 callback_.Run(); |
| 669 return true; |
| 670 } |
| 671 |
| 672 private: |
| 673 const base::Closure callback_; |
| 674 }; |
| 675 |
| 676 // Verifies that filters work as expected on associated bindings, i.e. that |
| 677 // they're notified in order, before dispatch; and that each associated |
| 678 // binding in a group operates with its own set of filters. |
| 679 TEST_F(AssociatedInterfaceTest, BindingWithFilters) { |
| 680 AssociatedPingProviderPtr provider; |
| 681 PingProviderImpl provider_impl(GetProxy(&provider)); |
| 682 |
| 683 PingServiceAssociatedPtr ping_a, ping_b; |
| 684 provider->GetPing(GetProxy(&ping_a, provider.associated_group())); |
| 685 provider->GetPing(GetProxy(&ping_b, provider.associated_group())); |
| 686 provider_impl.WaitForBindings(2); |
| 687 |
| 688 ASSERT_EQ(2u, provider_impl.ping_services().size()); |
| 689 PingServiceImpl& ping_a_impl = *provider_impl.ping_services()[0]; |
| 690 PingServiceImpl& ping_b_impl = *provider_impl.ping_services()[1]; |
| 691 |
| 692 int a_status, b_status; |
| 693 auto handler_helper = [] (int* a_status, int* b_status, int expected_a_status, |
| 694 int new_a_status, int expected_b_status, |
| 695 int new_b_status) { |
| 696 EXPECT_EQ(expected_a_status, *a_status); |
| 697 EXPECT_EQ(expected_b_status, *b_status); |
| 698 *a_status = new_a_status; |
| 699 *b_status = new_b_status; |
| 700 }; |
| 701 auto create_handler = [&] (int expected_a_status, int new_a_status, |
| 702 int expected_b_status, int new_b_status) { |
| 703 return base::Bind(handler_helper, &a_status, &b_status, expected_a_status, |
| 704 new_a_status, expected_b_status, new_b_status); |
| 705 }; |
| 706 |
| 707 ping_a_impl.binding().AddFilter( |
| 708 CallbackFilter::Wrap(create_handler(0, 1, 0, 0))); |
| 709 ping_a_impl.binding().AddFilter( |
| 710 CallbackFilter::Wrap(create_handler(1, 2, 0, 0))); |
| 711 ping_a_impl.set_ping_handler(create_handler(2, 3, 0, 0)); |
| 712 |
| 713 ping_b_impl.binding().AddFilter( |
| 714 CallbackFilter::Wrap(create_handler(3, 3, 0, 1))); |
| 715 ping_b_impl.binding().AddFilter( |
| 716 CallbackFilter::Wrap(create_handler(3, 3, 1, 2))); |
| 717 ping_b_impl.set_ping_handler(create_handler(3, 3, 2, 3)); |
| 718 |
| 719 for (int i = 0; i < 10; ++i) { |
| 720 a_status = 0; |
| 721 b_status = 0; |
| 722 |
| 723 { |
| 724 base::RunLoop loop; |
| 725 ping_a->Ping(loop.QuitClosure()); |
| 726 loop.Run(); |
| 727 } |
| 728 |
| 729 EXPECT_EQ(3, a_status); |
| 730 EXPECT_EQ(0, b_status); |
| 731 |
| 732 { |
| 733 base::RunLoop loop; |
| 734 ping_b->Ping(loop.QuitClosure()); |
| 735 loop.Run(); |
| 736 } |
| 737 |
| 738 EXPECT_EQ(3, a_status); |
| 739 EXPECT_EQ(3, b_status); |
| 740 } |
| 741 } |
| 742 |
592 } // namespace | 743 } // namespace |
593 } // namespace test | 744 } // namespace test |
594 } // namespace mojo | 745 } // namespace mojo |
OLD | NEW |