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 #include "ipc/ipc_channel_mojo.h" | 5 #include "ipc/ipc_channel_mojo.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <memory> | 10 #include <memory> |
11 #include <utility> | 11 #include <utility> |
12 | 12 |
13 #include "base/base_paths.h" | 13 #include "base/base_paths.h" |
14 #include "base/bind.h" | 14 #include "base/bind.h" |
15 #include "base/files/file.h" | 15 #include "base/files/file.h" |
16 #include "base/files/scoped_temp_dir.h" | 16 #include "base/files/scoped_temp_dir.h" |
17 #include "base/location.h" | 17 #include "base/location.h" |
18 #include "base/macros.h" | 18 #include "base/macros.h" |
19 #include "base/message_loop/message_loop.h" | 19 #include "base/message_loop/message_loop.h" |
20 #include "base/path_service.h" | 20 #include "base/path_service.h" |
21 #include "base/pickle.h" | 21 #include "base/pickle.h" |
22 #include "base/run_loop.h" | 22 #include "base/run_loop.h" |
23 #include "base/single_thread_task_runner.h" | 23 #include "base/single_thread_task_runner.h" |
24 #include "base/strings/stringprintf.h" | 24 #include "base/strings/stringprintf.h" |
25 #include "base/synchronization/waitable_event.h" | |
25 #include "base/test/test_io_thread.h" | 26 #include "base/test/test_io_thread.h" |
26 #include "base/test/test_timeouts.h" | 27 #include "base/test/test_timeouts.h" |
27 #include "base/threading/thread.h" | 28 #include "base/threading/thread.h" |
28 #include "base/threading/thread_task_runner_handle.h" | 29 #include "base/threading/thread_task_runner_handle.h" |
29 #include "build/build_config.h" | 30 #include "build/build_config.h" |
30 #include "ipc/ipc_message.h" | 31 #include "ipc/ipc_message.h" |
31 #include "ipc/ipc_mojo_handle_attachment.h" | 32 #include "ipc/ipc_mojo_handle_attachment.h" |
32 #include "ipc/ipc_mojo_message_helper.h" | 33 #include "ipc/ipc_mojo_message_helper.h" |
33 #include "ipc/ipc_mojo_param_traits.h" | 34 #include "ipc/ipc_mojo_param_traits.h" |
35 #include "ipc/ipc_sync_channel.h" | |
36 #include "ipc/ipc_sync_message.h" | |
34 #include "ipc/ipc_test.mojom.h" | 37 #include "ipc/ipc_test.mojom.h" |
35 #include "ipc/ipc_test_base.h" | 38 #include "ipc/ipc_test_base.h" |
36 #include "ipc/ipc_test_channel_listener.h" | 39 #include "ipc/ipc_test_channel_listener.h" |
37 #include "mojo/edk/test/mojo_test_base.h" | 40 #include "mojo/edk/test/mojo_test_base.h" |
38 #include "mojo/edk/test/multiprocess_test_helper.h" | 41 #include "mojo/edk/test/multiprocess_test_helper.h" |
39 #include "testing/gtest/include/gtest/gtest.h" | 42 #include "testing/gtest/include/gtest/gtest.h" |
40 | 43 |
41 #if defined(OS_POSIX) | 44 #if defined(OS_POSIX) |
42 #include "base/file_descriptor_posix.h" | 45 #include "base/file_descriptor_posix.h" |
43 #include "ipc/ipc_platform_file_attachment_posix.h" | 46 #include "ipc/ipc_platform_file_attachment_posix.h" |
(...skipping 21 matching lines...) Expand all Loading... | |
65 void client_name##_MainFixture::Main() | 68 void client_name##_MainFixture::Main() |
66 | 69 |
67 namespace { | 70 namespace { |
68 | 71 |
69 void SendString(IPC::Sender* sender, const std::string& str) { | 72 void SendString(IPC::Sender* sender, const std::string& str) { |
70 IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL); | 73 IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL); |
71 message->WriteString(str); | 74 message->WriteString(str); |
72 ASSERT_TRUE(sender->Send(message)); | 75 ASSERT_TRUE(sender->Send(message)); |
73 } | 76 } |
74 | 77 |
78 void SendValue(IPC::Sender* sender, int32_t value) { | |
79 IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL); | |
80 message->WriteInt(value); | |
81 ASSERT_TRUE(sender->Send(message)); | |
82 } | |
83 | |
75 class ListenerThatExpectsOK : public IPC::Listener { | 84 class ListenerThatExpectsOK : public IPC::Listener { |
76 public: | 85 public: |
77 ListenerThatExpectsOK() : received_ok_(false) {} | 86 ListenerThatExpectsOK() : received_ok_(false) {} |
78 | 87 |
79 ~ListenerThatExpectsOK() override {} | 88 ~ListenerThatExpectsOK() override {} |
80 | 89 |
81 bool OnMessageReceived(const IPC::Message& message) override { | 90 bool OnMessageReceived(const IPC::Message& message) override { |
82 base::PickleIterator iter(message); | 91 base::PickleIterator iter(message); |
83 std::string should_be_ok; | 92 std::string should_be_ok; |
84 EXPECT_TRUE(iter.ReadString(&should_be_ok)); | 93 EXPECT_TRUE(iter.ReadString(&should_be_ok)); |
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
598 public IPC::mojom::SimpleTestDriver { | 607 public IPC::mojom::SimpleTestDriver { |
599 public: | 608 public: |
600 static const int kNumMessages; | 609 static const int kNumMessages; |
601 | 610 |
602 ListenerWithSimpleAssociatedInterface() : binding_(this) {} | 611 ListenerWithSimpleAssociatedInterface() : binding_(this) {} |
603 | 612 |
604 ~ListenerWithSimpleAssociatedInterface() override {} | 613 ~ListenerWithSimpleAssociatedInterface() override {} |
605 | 614 |
606 bool OnMessageReceived(const IPC::Message& message) override { | 615 bool OnMessageReceived(const IPC::Message& message) override { |
607 base::PickleIterator iter(message); | 616 base::PickleIterator iter(message); |
608 std::string should_be_expected; | 617 int32_t should_be_expected; |
609 EXPECT_TRUE(iter.ReadString(&should_be_expected)); | 618 EXPECT_TRUE(iter.ReadInt(&should_be_expected)); |
610 EXPECT_EQ(should_be_expected, next_expected_string_); | 619 EXPECT_EQ(should_be_expected, next_expected_value_); |
611 num_messages_received_++; | 620 num_messages_received_++; |
612 return true; | 621 return true; |
613 } | 622 } |
614 | 623 |
615 void OnChannelError() override { | 624 void OnChannelError() override { |
616 DCHECK(received_quit_); | 625 DCHECK(received_quit_); |
617 } | 626 } |
618 | 627 |
619 void RegisterInterfaceFactory(IPC::Channel* channel) { | 628 void RegisterInterfaceFactory(IPC::Channel* channel) { |
620 channel->GetAssociatedInterfaceSupport()->AddAssociatedInterface( | 629 channel->GetAssociatedInterfaceSupport()->AddAssociatedInterface( |
621 base::Bind(&ListenerWithSimpleAssociatedInterface::BindRequest, | 630 base::Bind(&ListenerWithSimpleAssociatedInterface::BindRequest, |
622 base::Unretained(this))); | 631 base::Unretained(this))); |
623 } | 632 } |
624 | 633 |
625 private: | 634 private: |
626 // IPC::mojom::SimpleTestDriver: | 635 // IPC::mojom::SimpleTestDriver: |
627 void ExpectString(const mojo::String& str) override { | 636 void ExpectValue(int32_t value) override { |
628 next_expected_string_ = str; | 637 next_expected_value_ = value; |
638 } | |
639 | |
640 void GetExpectedValue(const GetExpectedValueCallback& callback) override { | |
641 NOTREACHED(); | |
642 } | |
643 | |
644 void RequestValue(const RequestValueCallback& callback) override { | |
645 NOTREACHED(); | |
629 } | 646 } |
630 | 647 |
631 void RequestQuit(const RequestQuitCallback& callback) override { | 648 void RequestQuit(const RequestQuitCallback& callback) override { |
632 EXPECT_EQ(kNumMessages, num_messages_received_); | 649 EXPECT_EQ(kNumMessages, num_messages_received_); |
633 received_quit_ = true; | 650 received_quit_ = true; |
634 callback.Run(); | 651 callback.Run(); |
635 base::MessageLoop::current()->QuitWhenIdle(); | 652 base::MessageLoop::current()->QuitWhenIdle(); |
636 } | 653 } |
637 | 654 |
638 void BindRequest(IPC::mojom::SimpleTestDriverAssociatedRequest request) { | 655 void BindRequest(IPC::mojom::SimpleTestDriverAssociatedRequest request) { |
639 DCHECK(!binding_.is_bound()); | 656 DCHECK(!binding_.is_bound()); |
640 binding_.Bind(std::move(request)); | 657 binding_.Bind(std::move(request)); |
641 } | 658 } |
642 | 659 |
643 std::string next_expected_string_; | 660 int32_t next_expected_value_ = 0; |
644 int num_messages_received_ = 0; | 661 int num_messages_received_ = 0; |
645 bool received_quit_ = false; | 662 bool received_quit_ = false; |
646 | 663 |
647 mojo::AssociatedBinding<IPC::mojom::SimpleTestDriver> binding_; | 664 mojo::AssociatedBinding<IPC::mojom::SimpleTestDriver> binding_; |
648 }; | 665 }; |
649 | 666 |
650 const int ListenerWithSimpleAssociatedInterface::kNumMessages = 1000; | 667 const int ListenerWithSimpleAssociatedInterface::kNumMessages = 1000; |
651 | 668 |
652 class ListenerSendingAssociatedMessages : public IPC::Listener { | 669 class ListenerSendingAssociatedMessages : public IPC::Listener { |
653 public: | 670 public: |
654 ListenerSendingAssociatedMessages() {} | 671 ListenerSendingAssociatedMessages() {} |
655 | 672 |
656 bool OnMessageReceived(const IPC::Message& message) override { return true; } | 673 bool OnMessageReceived(const IPC::Message& message) override { return true; } |
657 | 674 |
658 void OnChannelConnected(int32_t peer_pid) override { | 675 void OnChannelConnected(int32_t peer_pid) override { |
659 DCHECK(channel_); | 676 DCHECK(channel_); |
660 channel_->GetAssociatedInterfaceSupport()->GetRemoteAssociatedInterface( | 677 channel_->GetAssociatedInterfaceSupport()->GetRemoteAssociatedInterface( |
661 &driver_); | 678 &driver_); |
662 | 679 |
663 // Send a bunch of interleaved messages, alternating between the associated | 680 // Send a bunch of interleaved messages, alternating between the associated |
664 // interface and a legacy IPC::Message. | 681 // interface and a legacy IPC::Message. |
665 for (int i = 0; i < ListenerWithSimpleAssociatedInterface::kNumMessages; | 682 for (int i = 0; i < ListenerWithSimpleAssociatedInterface::kNumMessages; |
666 ++i) { | 683 ++i) { |
667 std::string str = base::StringPrintf("Hello! %d", i); | 684 driver_->ExpectValue(i); |
668 driver_->ExpectString(str); | 685 SendValue(channel_, i); |
669 SendString(channel_, str); | |
670 } | 686 } |
671 driver_->RequestQuit(base::Bind(&OnQuitAck)); | 687 driver_->RequestQuit(base::Bind(&OnQuitAck)); |
672 } | 688 } |
673 | 689 |
674 void set_channel(IPC::Channel* channel) { channel_ = channel; } | 690 void set_channel(IPC::Channel* channel) { channel_ = channel; } |
675 | 691 |
676 private: | 692 private: |
677 static void OnQuitAck() { base::MessageLoop::current()->QuitWhenIdle(); } | 693 static void OnQuitAck() { base::MessageLoop::current()->QuitWhenIdle(); } |
678 | 694 |
679 IPC::Channel* channel_ = nullptr; | 695 IPC::Channel* channel_ = nullptr; |
(...skipping 26 matching lines...) Expand all Loading... | |
706 | 722 |
707 Close(); | 723 Close(); |
708 } | 724 } |
709 | 725 |
710 class ChannelProxyRunner { | 726 class ChannelProxyRunner { |
711 public: | 727 public: |
712 ChannelProxyRunner(mojo::ScopedMessagePipeHandle handle, | 728 ChannelProxyRunner(mojo::ScopedMessagePipeHandle handle, |
713 bool for_server) | 729 bool for_server) |
714 : for_server_(for_server), | 730 : for_server_(for_server), |
715 handle_(std::move(handle)), | 731 handle_(std::move(handle)), |
716 io_thread_("ChannelProxyRunner IO thread") { | 732 io_thread_("ChannelProxyRunner IO thread"), |
733 never_signaled_(base::WaitableEvent::ResetPolicy::MANUAL, | |
734 base::WaitableEvent::InitialState::NOT_SIGNALED) { | |
717 } | 735 } |
718 | 736 |
719 void CreateProxy(IPC::Listener* listener) { | 737 void CreateProxy(IPC::Listener* listener) { |
720 io_thread_.StartWithOptions( | 738 io_thread_.StartWithOptions( |
721 base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); | 739 base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); |
722 proxy_.reset(new IPC::ChannelProxy(listener, io_thread_.task_runner())); | 740 proxy_ = IPC::SyncChannel::Create( |
741 listener, io_thread_.task_runner(), &never_signaled_); | |
723 } | 742 } |
724 | 743 |
725 void RunProxy() { | 744 void RunProxy() { |
726 std::unique_ptr<IPC::ChannelFactory> factory; | 745 std::unique_ptr<IPC::ChannelFactory> factory; |
727 if (for_server_) { | 746 if (for_server_) { |
728 factory = IPC::ChannelMojo::CreateServerFactory( | 747 factory = IPC::ChannelMojo::CreateServerFactory( |
729 std::move(handle_), io_thread_.task_runner()); | 748 std::move(handle_), io_thread_.task_runner()); |
730 } else { | 749 } else { |
731 factory = IPC::ChannelMojo::CreateClientFactory( | 750 factory = IPC::ChannelMojo::CreateClientFactory( |
732 std::move(handle_), io_thread_.task_runner()); | 751 std::move(handle_), io_thread_.task_runner()); |
733 } | 752 } |
734 proxy_->Init(std::move(factory), true); | 753 proxy_->Init(std::move(factory), true); |
735 } | 754 } |
736 | 755 |
737 IPC::ChannelProxy* proxy() { return proxy_.get(); } | 756 IPC::ChannelProxy* proxy() { return proxy_.get(); } |
738 | 757 |
739 private: | 758 private: |
740 const bool for_server_; | 759 const bool for_server_; |
741 | 760 |
742 mojo::ScopedMessagePipeHandle handle_; | 761 mojo::ScopedMessagePipeHandle handle_; |
743 base::Thread io_thread_; | 762 base::Thread io_thread_; |
744 std::unique_ptr<IPC::ChannelProxy> proxy_; | 763 std::unique_ptr<IPC::ChannelProxy> proxy_; |
764 base::WaitableEvent never_signaled_; | |
745 | 765 |
746 DISALLOW_COPY_AND_ASSIGN(ChannelProxyRunner); | 766 DISALLOW_COPY_AND_ASSIGN(ChannelProxyRunner); |
747 }; | 767 }; |
748 | 768 |
749 class IPCChannelProxyMojoTest : public IPCChannelMojoTestBase { | 769 class IPCChannelProxyMojoTest : public IPCChannelMojoTestBase { |
750 public: | 770 public: |
751 void InitWithMojo(const std::string& client_name) { | 771 void InitWithMojo(const std::string& client_name) { |
752 IPCChannelMojoTestBase::InitWithMojo(client_name); | 772 IPCChannelMojoTestBase::InitWithMojo(client_name); |
753 runner_.reset(new ChannelProxyRunner(TakeHandle(), true)); | 773 runner_.reset(new ChannelProxyRunner(TakeHandle(), true)); |
754 } | 774 } |
(...skipping 16 matching lines...) Expand all Loading... | |
771 public IPC::mojom::SimpleTestDriver { | 791 public IPC::mojom::SimpleTestDriver { |
772 public: | 792 public: |
773 static const int kNumMessages; | 793 static const int kNumMessages; |
774 | 794 |
775 ListenerWithSimpleProxyAssociatedInterface() : binding_(this) {} | 795 ListenerWithSimpleProxyAssociatedInterface() : binding_(this) {} |
776 | 796 |
777 ~ListenerWithSimpleProxyAssociatedInterface() override {} | 797 ~ListenerWithSimpleProxyAssociatedInterface() override {} |
778 | 798 |
779 bool OnMessageReceived(const IPC::Message& message) override { | 799 bool OnMessageReceived(const IPC::Message& message) override { |
780 base::PickleIterator iter(message); | 800 base::PickleIterator iter(message); |
781 std::string should_be_expected; | 801 int32_t should_be_expected; |
782 EXPECT_TRUE(iter.ReadString(&should_be_expected)); | 802 EXPECT_TRUE(iter.ReadInt(&should_be_expected)); |
783 EXPECT_EQ(should_be_expected, next_expected_string_); | 803 EXPECT_EQ(should_be_expected, next_expected_value_); |
784 num_messages_received_++; | 804 num_messages_received_++; |
785 return true; | 805 return true; |
786 } | 806 } |
787 | 807 |
788 void OnChannelError() override { | 808 void OnChannelError() override { |
789 DCHECK(received_quit_); | 809 DCHECK(received_quit_); |
790 } | 810 } |
791 | 811 |
792 void RegisterInterfaceFactory(IPC::ChannelProxy* proxy) { | 812 void RegisterInterfaceFactory(IPC::ChannelProxy* proxy) { |
793 proxy->AddAssociatedInterface( | 813 proxy->AddAssociatedInterface( |
794 base::Bind(&ListenerWithSimpleProxyAssociatedInterface::BindRequest, | 814 base::Bind(&ListenerWithSimpleProxyAssociatedInterface::BindRequest, |
795 base::Unretained(this))); | 815 base::Unretained(this))); |
796 } | 816 } |
797 | 817 |
798 bool received_all_messages() const { | 818 bool received_all_messages() const { |
799 return num_messages_received_ == kNumMessages && received_quit_; | 819 return num_messages_received_ == kNumMessages && received_quit_; |
800 } | 820 } |
801 | 821 |
802 private: | 822 private: |
803 // IPC::mojom::SimpleTestDriver: | 823 // IPC::mojom::SimpleTestDriver: |
804 void ExpectString(const mojo::String& str) override { | 824 void ExpectValue(int32_t value) override { |
805 next_expected_string_ = str; | 825 next_expected_value_ = value; |
826 } | |
827 | |
828 void GetExpectedValue(const GetExpectedValueCallback& callback) override { | |
829 callback.Run(next_expected_value_); | |
830 } | |
831 | |
832 void RequestValue(const RequestValueCallback& callback) override { | |
833 NOTREACHED(); | |
806 } | 834 } |
807 | 835 |
808 void RequestQuit(const RequestQuitCallback& callback) override { | 836 void RequestQuit(const RequestQuitCallback& callback) override { |
809 received_quit_ = true; | 837 received_quit_ = true; |
810 callback.Run(); | 838 callback.Run(); |
811 binding_.Close(); | 839 binding_.Close(); |
812 base::MessageLoop::current()->QuitWhenIdle(); | 840 base::MessageLoop::current()->QuitWhenIdle(); |
813 } | 841 } |
814 | 842 |
815 void BindRequest(IPC::mojom::SimpleTestDriverAssociatedRequest request) { | 843 void BindRequest(IPC::mojom::SimpleTestDriverAssociatedRequest request) { |
816 DCHECK(!binding_.is_bound()); | 844 DCHECK(!binding_.is_bound()); |
817 binding_.Bind(std::move(request)); | 845 binding_.Bind(std::move(request)); |
818 } | 846 } |
819 | 847 |
820 std::string next_expected_string_; | 848 int32_t next_expected_value_ = 0; |
821 int num_messages_received_ = 0; | 849 int num_messages_received_ = 0; |
822 bool received_quit_ = false; | 850 bool received_quit_ = false; |
823 | 851 |
824 mojo::AssociatedBinding<IPC::mojom::SimpleTestDriver> binding_; | 852 mojo::AssociatedBinding<IPC::mojom::SimpleTestDriver> binding_; |
825 }; | 853 }; |
826 | 854 |
827 const int ListenerWithSimpleProxyAssociatedInterface::kNumMessages = 1000; | 855 const int ListenerWithSimpleProxyAssociatedInterface::kNumMessages = 1000; |
828 | 856 |
829 TEST_F(IPCChannelProxyMojoTest, ProxyThreadAssociatedInterface) { | 857 TEST_F(IPCChannelProxyMojoTest, ProxyThreadAssociatedInterface) { |
830 InitWithMojo("ProxyThreadAssociatedInterfaceClient"); | 858 InitWithMojo("ProxyThreadAssociatedInterfaceClient"); |
831 | 859 |
832 ListenerWithSimpleProxyAssociatedInterface listener; | 860 ListenerWithSimpleProxyAssociatedInterface listener; |
833 CreateProxy(&listener); | 861 CreateProxy(&listener); |
834 listener.RegisterInterfaceFactory(proxy()); | 862 listener.RegisterInterfaceFactory(proxy()); |
835 RunProxy(); | 863 RunProxy(); |
836 | 864 |
837 base::RunLoop().Run(); | 865 base::RunLoop().Run(); |
838 | 866 |
839 EXPECT_TRUE(WaitForClientShutdown()); | 867 EXPECT_TRUE(WaitForClientShutdown()); |
840 EXPECT_TRUE(listener.received_all_messages()); | 868 EXPECT_TRUE(listener.received_all_messages()); |
841 | 869 |
842 DestroyProxy(); | 870 DestroyProxy(); |
843 } | 871 } |
844 | 872 |
845 class ChannelProxyClient { | 873 class ChannelProxyClient { |
846 public: | 874 public: |
847 void Init(mojo::ScopedMessagePipeHandle handle) { | 875 void Init(mojo::ScopedMessagePipeHandle handle) { |
848 runner_.reset(new ChannelProxyRunner(std::move(handle), false)); | 876 runner_.reset(new ChannelProxyRunner(std::move(handle), false)); |
849 } | 877 } |
878 | |
850 void CreateProxy(IPC::Listener* listener) { runner_->CreateProxy(listener); } | 879 void CreateProxy(IPC::Listener* listener) { runner_->CreateProxy(listener); } |
880 | |
851 void RunProxy() { runner_->RunProxy(); } | 881 void RunProxy() { runner_->RunProxy(); } |
882 | |
852 void DestroyProxy() { | 883 void DestroyProxy() { |
853 runner_.reset(); | 884 runner_.reset(); |
854 base::RunLoop().RunUntilIdle(); | 885 base::RunLoop().RunUntilIdle(); |
855 } | 886 } |
856 | 887 |
888 void RequestQuitAndWaitForAck(IPC::mojom::SimpleTestDriver* driver) { | |
889 base::RunLoop loop; | |
890 driver->RequestQuit(loop.QuitClosure()); | |
891 loop.Run(); | |
892 } | |
893 | |
857 IPC::ChannelProxy* proxy() { return runner_->proxy(); } | 894 IPC::ChannelProxy* proxy() { return runner_->proxy(); } |
858 | 895 |
859 private: | 896 private: |
860 base::MessageLoop message_loop_; | 897 base::MessageLoop message_loop_; |
861 std::unique_ptr<ChannelProxyRunner> runner_; | 898 std::unique_ptr<ChannelProxyRunner> runner_; |
862 }; | 899 }; |
863 | 900 |
864 class DummyListener : public IPC::Listener { | 901 class DummyListener : public IPC::Listener { |
865 public: | 902 public: |
866 // IPC::Listener | 903 // IPC::Listener |
867 bool OnMessageReceived(const IPC::Message& message) override { return true; } | 904 bool OnMessageReceived(const IPC::Message& message) override { return true; } |
868 }; | 905 }; |
869 | 906 |
870 DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(ProxyThreadAssociatedInterfaceClient, | 907 DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(ProxyThreadAssociatedInterfaceClient, |
871 ChannelProxyClient) { | 908 ChannelProxyClient) { |
872 DummyListener listener; | 909 DummyListener listener; |
873 CreateProxy(&listener); | 910 CreateProxy(&listener); |
874 RunProxy(); | 911 RunProxy(); |
875 | 912 |
876 // Send a bunch of interleaved messages, alternating between the associated | 913 // Send a bunch of interleaved messages, alternating between the associated |
877 // interface and a legacy IPC::Message. | 914 // interface and a legacy IPC::Message. |
878 IPC::mojom::SimpleTestDriverAssociatedPtr driver; | 915 IPC::mojom::SimpleTestDriverAssociatedPtr driver; |
879 proxy()->GetRemoteAssociatedInterface(&driver); | 916 proxy()->GetRemoteAssociatedInterface(&driver); |
880 for (int i = 0; i < ListenerWithSimpleProxyAssociatedInterface::kNumMessages; | 917 for (int i = 0; i < ListenerWithSimpleProxyAssociatedInterface::kNumMessages; |
881 ++i) { | 918 ++i) { |
882 std::string str = base::StringPrintf("Hello! %d", i); | 919 driver->ExpectValue(i); |
883 driver->ExpectString(str); | 920 SendValue(proxy(), i); |
884 SendString(proxy(), str); | |
885 } | 921 } |
886 driver->RequestQuit(base::MessageLoop::QuitWhenIdleClosure()); | 922 driver->RequestQuit(base::MessageLoop::QuitWhenIdleClosure()); |
887 base::RunLoop().Run(); | 923 base::RunLoop().Run(); |
888 | 924 |
889 DestroyProxy(); | 925 DestroyProxy(); |
890 } | 926 } |
891 | 927 |
928 class ListenerWithSyncAssociatedInterface | |
929 : public IPC::Listener, | |
930 public IPC::mojom::SimpleTestDriver { | |
931 public: | |
932 ListenerWithSyncAssociatedInterface() : binding_(this) {} | |
933 ~ListenerWithSyncAssociatedInterface() override {} | |
934 | |
935 void set_sync_sender(IPC::Sender* sync_sender) { sync_sender_ = sync_sender; } | |
936 | |
937 void RegisterInterfaceFactory(IPC::ChannelProxy* proxy) { | |
938 proxy->AddAssociatedInterface( | |
939 base::Bind(&ListenerWithSyncAssociatedInterface::BindRequest, | |
940 base::Unretained(this))); | |
941 } | |
942 | |
943 void RunUntilQuitRequested() { | |
944 base::RunLoop loop; | |
945 quit_closure_ = loop.QuitClosure(); | |
946 loop.Run(); | |
947 } | |
948 | |
949 void CloseBinding() { binding_.Close(); } | |
950 | |
951 void set_response_value(int32_t response) { | |
952 response_value_ = response; | |
953 } | |
954 | |
955 private: | |
956 // IPC::mojom::SimpleTestDriver: | |
957 void ExpectValue(int32_t value) override { | |
958 next_expected_value_ = value; | |
959 } | |
960 | |
961 void GetExpectedValue(const GetExpectedValueCallback& callback) override { | |
962 callback.Run(next_expected_value_); | |
963 } | |
964 | |
965 void RequestValue(const RequestValueCallback& callback) override { | |
966 callback.Run(response_value_); | |
967 } | |
968 | |
969 void RequestQuit(const RequestQuitCallback& callback) override { | |
970 quit_closure_.Run(); | |
971 callback.Run(); | |
972 } | |
973 | |
974 // IPC::Listener: | |
975 bool OnMessageReceived(const IPC::Message& message) override { | |
976 EXPECT_EQ(0u, message.type()); | |
977 EXPECT_TRUE(message.is_sync()); | |
978 EXPECT_TRUE(message.should_unblock()); | |
979 std::unique_ptr<IPC::Message> reply( | |
980 IPC::SyncMessage::GenerateReply(&message)); | |
981 reply->WriteInt(response_value_); | |
982 DCHECK(sync_sender_); | |
983 EXPECT_TRUE(sync_sender_->Send(reply.release())); | |
984 return true; | |
985 } | |
986 | |
987 void BindRequest(IPC::mojom::SimpleTestDriverAssociatedRequest request) { | |
988 DCHECK(!binding_.is_bound()); | |
989 binding_.Bind(std::move(request)); | |
990 } | |
991 | |
992 IPC::Sender* sync_sender_ = nullptr; | |
993 int32_t next_expected_value_ = 0; | |
994 int32_t response_value_; | |
yzshen1
2016/08/02 18:34:11
nit: please init this variable too.
Ken Rockot(use gerrit already)
2016/08/02 19:05:05
Done
| |
995 base::Closure quit_closure_; | |
996 | |
997 mojo::AssociatedBinding<IPC::mojom::SimpleTestDriver> binding_; | |
998 }; | |
999 | |
1000 class SyncReplyReader : public IPC::MessageReplyDeserializer { | |
1001 public: | |
1002 explicit SyncReplyReader(int32_t* storage) : storage_(storage) {} | |
1003 ~SyncReplyReader() override {} | |
1004 | |
1005 private: | |
1006 // IPC::MessageReplyDeserializer: | |
1007 bool SerializeOutputParameters(const IPC::Message& message, | |
1008 base::PickleIterator iter) override { | |
1009 if (!iter.ReadInt(storage_)) | |
1010 return false; | |
1011 return true; | |
1012 } | |
1013 | |
1014 int32_t* storage_; | |
1015 | |
1016 DISALLOW_COPY_AND_ASSIGN(SyncReplyReader); | |
1017 }; | |
1018 | |
1019 TEST_F(IPCChannelProxyMojoTest, SyncAssociatedInterface) { | |
1020 InitWithMojo("SyncAssociatedInterface"); | |
1021 | |
1022 ListenerWithSyncAssociatedInterface listener; | |
1023 CreateProxy(&listener); | |
1024 listener.set_sync_sender(proxy()); | |
1025 listener.RegisterInterfaceFactory(proxy()); | |
1026 RunProxy(); | |
1027 | |
1028 // Run the client's simple sanity check to completion. | |
1029 listener.RunUntilQuitRequested(); | |
1030 | |
1031 // Verify that we can send a sync IPC and service an incoming sync request | |
1032 // while waiting on it | |
1033 listener.set_response_value(42); | |
1034 IPC::mojom::SimpleTestClientAssociatedPtr client; | |
1035 proxy()->GetRemoteAssociatedInterface(&client); | |
1036 int32_t received_value; | |
1037 EXPECT_TRUE(client->RequestValue(&received_value)); | |
1038 EXPECT_EQ(42, received_value); | |
1039 | |
1040 // Do it again. This time the client will send a classical sync IPC to us | |
1041 // while we wait. | |
1042 received_value = 0; | |
1043 EXPECT_TRUE(client->RequestValue(&received_value)); | |
1044 EXPECT_EQ(42, received_value); | |
1045 | |
1046 // Now make a classical sync IPC request to the client. It will send a | |
1047 // sync associated interface message to us while we wait. | |
1048 received_value = 0; | |
1049 std::unique_ptr<IPC::SyncMessage> request( | |
1050 new IPC::SyncMessage(0, 0, IPC::Message::PRIORITY_NORMAL, | |
1051 new SyncReplyReader(&received_value))); | |
1052 EXPECT_TRUE(proxy()->Send(request.release())); | |
1053 EXPECT_EQ(42, received_value); | |
1054 | |
1055 listener.CloseBinding(); | |
1056 EXPECT_TRUE(WaitForClientShutdown()); | |
1057 | |
1058 DestroyProxy(); | |
1059 } | |
1060 | |
1061 class SimpleTestClientImpl : public IPC::mojom::SimpleTestClient, | |
1062 public IPC::Listener { | |
1063 public: | |
1064 SimpleTestClientImpl() : binding_(this) {} | |
1065 | |
1066 void set_driver(IPC::mojom::SimpleTestDriver* driver) { driver_ = driver; } | |
1067 void set_sync_sender(IPC::Sender* sync_sender) { sync_sender_ = sync_sender; } | |
1068 | |
1069 void BindRequest(IPC::mojom::SimpleTestClientAssociatedRequest request) { | |
1070 DCHECK(!binding_.is_bound()); | |
1071 binding_.Bind(std::move(request)); | |
1072 } | |
1073 | |
1074 void WaitForValueRequest() { | |
1075 run_loop_.reset(new base::RunLoop); | |
1076 run_loop_->Run(); | |
1077 } | |
1078 | |
1079 void UseSyncSenderForRequest(bool use_sync_sender) { | |
1080 use_sync_sender_ = use_sync_sender; | |
1081 } | |
1082 | |
1083 private: | |
1084 // IPC::mojom::SimpleTestClient: | |
1085 void RequestValue(const RequestValueCallback& callback) override { | |
1086 int32_t response = 0; | |
1087 if (use_sync_sender_) { | |
1088 std::unique_ptr<IPC::SyncMessage> reply(new IPC::SyncMessage( | |
1089 0, 0, IPC::Message::PRIORITY_NORMAL, new SyncReplyReader(&response))); | |
1090 EXPECT_TRUE(sync_sender_->Send(reply.release())); | |
1091 } else { | |
1092 DCHECK(driver_); | |
1093 EXPECT_TRUE(driver_->RequestValue(&response)); | |
1094 } | |
1095 | |
1096 callback.Run(response); | |
1097 | |
1098 DCHECK(run_loop_); | |
1099 run_loop_->Quit(); | |
1100 } | |
1101 | |
1102 // IPC::Listener: | |
1103 bool OnMessageReceived(const IPC::Message& message) override { | |
1104 int32_t response; | |
1105 DCHECK(driver_); | |
1106 EXPECT_TRUE(driver_->RequestValue(&response)); | |
1107 std::unique_ptr<IPC::Message> reply( | |
1108 IPC::SyncMessage::GenerateReply(&message)); | |
1109 reply->WriteInt(response); | |
1110 EXPECT_TRUE(sync_sender_->Send(reply.release())); | |
1111 | |
1112 DCHECK(run_loop_); | |
1113 run_loop_->Quit(); | |
1114 return true; | |
1115 } | |
1116 | |
1117 bool use_sync_sender_ = false; | |
1118 mojo::AssociatedBinding<IPC::mojom::SimpleTestClient> binding_; | |
1119 IPC::Sender* sync_sender_ = nullptr; | |
1120 IPC::mojom::SimpleTestDriver* driver_ = nullptr; | |
1121 std::unique_ptr<base::RunLoop> run_loop_; | |
1122 | |
1123 DISALLOW_COPY_AND_ASSIGN(SimpleTestClientImpl); | |
1124 }; | |
1125 | |
1126 DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(SyncAssociatedInterface, | |
1127 ChannelProxyClient) { | |
1128 SimpleTestClientImpl client_impl; | |
1129 CreateProxy(&client_impl); | |
1130 client_impl.set_sync_sender(proxy()); | |
1131 proxy()->AddAssociatedInterface(base::Bind(&SimpleTestClientImpl::BindRequest, | |
1132 base::Unretained(&client_impl))); | |
1133 RunProxy(); | |
1134 | |
1135 IPC::mojom::SimpleTestDriverAssociatedPtr driver; | |
1136 proxy()->GetRemoteAssociatedInterface(&driver); | |
1137 client_impl.set_driver(driver.get()); | |
1138 | |
1139 // Simple sync message sanity check. | |
1140 driver->ExpectValue(42); | |
1141 int32_t expected_value = 0; | |
1142 EXPECT_TRUE(driver->GetExpectedValue(&expected_value)); | |
1143 EXPECT_EQ(42, expected_value); | |
1144 RequestQuitAndWaitForAck(driver.get()); | |
1145 | |
1146 // Wait for the test driver to perform a sync call test with our own sync | |
1147 // associated interface message nested inside. | |
1148 client_impl.UseSyncSenderForRequest(false); | |
1149 client_impl.WaitForValueRequest(); | |
1150 | |
1151 // Wait for the test driver to perform a sync call test with our own classical | |
1152 // sync IPC nested inside. | |
1153 client_impl.UseSyncSenderForRequest(true); | |
1154 client_impl.WaitForValueRequest(); | |
1155 | |
1156 // Wait for the test driver to perform a classical sync IPC request, with our | |
1157 // own sync associated interface message nested inside. | |
1158 client_impl.UseSyncSenderForRequest(false); | |
1159 client_impl.WaitForValueRequest(); | |
1160 | |
1161 DestroyProxy(); | |
1162 } | |
1163 | |
892 #if defined(OS_POSIX) | 1164 #if defined(OS_POSIX) |
893 | 1165 |
894 class ListenerThatExpectsFile : public IPC::Listener { | 1166 class ListenerThatExpectsFile : public IPC::Listener { |
895 public: | 1167 public: |
896 ListenerThatExpectsFile() : sender_(NULL) {} | 1168 ListenerThatExpectsFile() : sender_(NULL) {} |
897 | 1169 |
898 ~ListenerThatExpectsFile() override {} | 1170 ~ListenerThatExpectsFile() override {} |
899 | 1171 |
900 bool OnMessageReceived(const IPC::Message& message) override { | 1172 bool OnMessageReceived(const IPC::Message& message) override { |
901 base::PickleIterator iter(message); | 1173 base::PickleIterator iter(message); |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1044 Connect(&listener); | 1316 Connect(&listener); |
1045 | 1317 |
1046 base::MessageLoop::current()->Run(); | 1318 base::MessageLoop::current()->Run(); |
1047 | 1319 |
1048 Close(); | 1320 Close(); |
1049 } | 1321 } |
1050 | 1322 |
1051 #endif // OS_LINUX | 1323 #endif // OS_LINUX |
1052 | 1324 |
1053 } // namespace | 1325 } // namespace |
OLD | NEW |