Chromium Code Reviews| 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_; |
|
yzshen1
2016/08/02 17:38:37
nit: please init this value. (here and other class
Ken Rockot(use gerrit already)
2016/08/02 18:21:24
Done (in all 3 places)
| |
| 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_; |
| 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_; | |
| 994 int32_t response_value_; | |
| 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 |