| 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 #include <memory> |   10 #include <memory> | 
|   10 #include <utility> |   11 #include <utility> | 
|   11  |   12  | 
|   12 #include "base/base_paths.h" |   13 #include "base/base_paths.h" | 
|   13 #include "base/files/file.h" |   14 #include "base/files/file.h" | 
|   14 #include "base/files/scoped_temp_dir.h" |   15 #include "base/files/scoped_temp_dir.h" | 
|   15 #include "base/location.h" |   16 #include "base/location.h" | 
|   16 #include "base/path_service.h" |   17 #include "base/path_service.h" | 
|   17 #include "base/pickle.h" |   18 #include "base/pickle.h" | 
|   18 #include "base/run_loop.h" |   19 #include "base/run_loop.h" | 
|   19 #include "base/single_thread_task_runner.h" |   20 #include "base/single_thread_task_runner.h" | 
 |   21 #include "base/strings/stringprintf.h" | 
|   20 #include "base/test/test_io_thread.h" |   22 #include "base/test/test_io_thread.h" | 
|   21 #include "base/test/test_timeouts.h" |   23 #include "base/test/test_timeouts.h" | 
|   22 #include "base/threading/thread.h" |   24 #include "base/threading/thread.h" | 
|   23 #include "base/threading/thread_task_runner_handle.h" |   25 #include "base/threading/thread_task_runner_handle.h" | 
|   24 #include "build/build_config.h" |   26 #include "build/build_config.h" | 
|   25 #include "ipc/ipc_message.h" |   27 #include "ipc/ipc_message.h" | 
|   26 #include "ipc/ipc_mojo_handle_attachment.h" |   28 #include "ipc/ipc_mojo_handle_attachment.h" | 
|   27 #include "ipc/ipc_mojo_message_helper.h" |   29 #include "ipc/ipc_mojo_message_helper.h" | 
|   28 #include "ipc/ipc_mojo_param_traits.h" |   30 #include "ipc/ipc_mojo_param_traits.h" | 
 |   31 #include "ipc/ipc_test.mojom.h" | 
|   29 #include "ipc/ipc_test_base.h" |   32 #include "ipc/ipc_test_base.h" | 
|   30 #include "ipc/ipc_test_channel_listener.h" |   33 #include "ipc/ipc_test_channel_listener.h" | 
|   31 #include "mojo/edk/test/mojo_test_base.h" |   34 #include "mojo/edk/test/mojo_test_base.h" | 
|   32 #include "mojo/edk/test/multiprocess_test_helper.h" |   35 #include "mojo/edk/test/multiprocess_test_helper.h" | 
|   33 #include "testing/gtest/include/gtest/gtest.h" |   36 #include "testing/gtest/include/gtest/gtest.h" | 
|   34  |   37  | 
|   35 #if defined(OS_POSIX) |   38 #if defined(OS_POSIX) | 
|   36 #include "base/file_descriptor_posix.h" |   39 #include "base/file_descriptor_posix.h" | 
|   37 #include "ipc/ipc_platform_file_attachment_posix.h" |   40 #include "ipc/ipc_platform_file_attachment_posix.h" | 
|   38 #endif |   41 #endif | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
|   53     test.Main();                                                          \ |   56     test.Main();                                                          \ | 
|   54     return (::testing::Test::HasFatalFailure() ||                         \ |   57     return (::testing::Test::HasFatalFailure() ||                         \ | 
|   55             ::testing::Test::HasNonfatalFailure())                        \ |   58             ::testing::Test::HasNonfatalFailure())                        \ | 
|   56                ? 1                                                        \ |   59                ? 1                                                        \ | 
|   57                : 0;                                                       \ |   60                : 0;                                                       \ | 
|   58   }                                                                       \ |   61   }                                                                       \ | 
|   59   void client_name##_MainFixture::Main() |   62   void client_name##_MainFixture::Main() | 
|   60  |   63  | 
|   61 namespace { |   64 namespace { | 
|   62  |   65  | 
 |   66 void SendString(IPC::Sender* sender, const std::string& str) { | 
 |   67   IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL); | 
 |   68   message->WriteString(str); | 
 |   69   ASSERT_TRUE(sender->Send(message)); | 
 |   70 } | 
 |   71  | 
|   63 class ListenerThatExpectsOK : public IPC::Listener { |   72 class ListenerThatExpectsOK : public IPC::Listener { | 
|   64  public: |   73  public: | 
|   65   ListenerThatExpectsOK() : received_ok_(false) {} |   74   ListenerThatExpectsOK() : received_ok_(false) {} | 
|   66  |   75  | 
|   67   ~ListenerThatExpectsOK() override {} |   76   ~ListenerThatExpectsOK() override {} | 
|   68  |   77  | 
|   69   bool OnMessageReceived(const IPC::Message& message) override { |   78   bool OnMessageReceived(const IPC::Message& message) override { | 
|   70     base::PickleIterator iter(message); |   79     base::PickleIterator iter(message); | 
|   71     std::string should_be_ok; |   80     std::string should_be_ok; | 
|   72     EXPECT_TRUE(iter.ReadString(&should_be_ok)); |   81     EXPECT_TRUE(iter.ReadString(&should_be_ok)); | 
|   73     EXPECT_EQ(should_be_ok, "OK"); |   82     EXPECT_EQ(should_be_ok, "OK"); | 
|   74     received_ok_ = true; |   83     received_ok_ = true; | 
|   75     base::MessageLoop::current()->QuitWhenIdle(); |   84     base::MessageLoop::current()->QuitWhenIdle(); | 
|   76     return true; |   85     return true; | 
|   77   } |   86   } | 
|   78  |   87  | 
|   79   void OnChannelError() override { |   88   void OnChannelError() override { | 
|   80     // The connection should be healthy while the listener is waiting |   89     // The connection should be healthy while the listener is waiting | 
|   81     // message.  An error can occur after that because the peer |   90     // message.  An error can occur after that because the peer | 
|   82     // process dies. |   91     // process dies. | 
|   83     DCHECK(received_ok_); |   92     DCHECK(received_ok_); | 
|   84   } |   93   } | 
|   85  |   94  | 
|   86   static void SendOK(IPC::Sender* sender) { |   95   static void SendOK(IPC::Sender* sender) { SendString(sender, "OK"); } | 
|   87     IPC::Message* message = |  | 
|   88         new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL); |  | 
|   89     message->WriteString(std::string("OK")); |  | 
|   90     ASSERT_TRUE(sender->Send(message)); |  | 
|   91   } |  | 
|   92  |   96  | 
|   93  private: |   97  private: | 
|   94   bool received_ok_; |   98   bool received_ok_; | 
|   95 }; |   99 }; | 
|   96  |  100  | 
|   97 class ChannelClient { |  101 class ChannelClient { | 
|   98  public: |  102  public: | 
|   99   void Init(mojo::ScopedMessagePipeHandle handle) { |  103   void Init(mojo::ScopedMessagePipeHandle handle) { | 
|  100     handle_ = std::move(handle); |  104     handle_ = std::move(handle); | 
|  101   } |  105   } | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
|  117   IPC::ChannelMojo* channel() const { return channel_.get(); } |  121   IPC::ChannelMojo* channel() const { return channel_.get(); } | 
|  118  |  122  | 
|  119  private: |  123  private: | 
|  120   base::MessageLoopForIO main_message_loop_; |  124   base::MessageLoopForIO main_message_loop_; | 
|  121   mojo::ScopedMessagePipeHandle handle_; |  125   mojo::ScopedMessagePipeHandle handle_; | 
|  122   std::unique_ptr<IPC::ChannelMojo> channel_; |  126   std::unique_ptr<IPC::ChannelMojo> channel_; | 
|  123 }; |  127 }; | 
|  124  |  128  | 
|  125 class IPCChannelMojoTest : public testing::Test { |  129 class IPCChannelMojoTest : public testing::Test { | 
|  126  public: |  130  public: | 
|  127   IPCChannelMojoTest() : io_thread_(base::TestIOThread::Mode::kAutoStart) {} |  131   IPCChannelMojoTest() {} | 
|  128  |  132  | 
|  129   void TearDown() override { base::RunLoop().RunUntilIdle(); } |  133   void TearDown() override { base::RunLoop().RunUntilIdle(); } | 
|  130  |  134  | 
|  131   void InitWithMojo(const std::string& test_client_name) { |  135   void InitWithMojo(const std::string& test_client_name) { | 
|  132     handle_ = helper_.StartChild(test_client_name); |  136     handle_ = helper_.StartChild(test_client_name); | 
|  133   } |  137   } | 
|  134  |  138  | 
|  135   void CreateChannel(IPC::Listener* listener) { |  139   void CreateChannel(IPC::Listener* listener) { | 
|  136     channel_ = IPC::ChannelMojo::Create(std::move(handle_), |  140     channel_ = IPC::ChannelMojo::Create(std::move(handle_), | 
|  137                                         IPC::Channel::MODE_SERVER, listener); |  141                                         IPC::Channel::MODE_SERVER, listener); | 
|  138   } |  142   } | 
|  139  |  143  | 
|  140   bool ConnectChannel() { return channel_->Connect(); } |  144   bool ConnectChannel() { return channel_->Connect(); } | 
|  141  |  145  | 
|  142   void DestroyChannel() { channel_.reset(); } |  146   void DestroyChannel() { channel_.reset(); } | 
|  143  |  147  | 
|  144   bool WaitForClientShutdown() { return helper_.WaitForChildTestShutdown(); } |  148   bool WaitForClientShutdown() { return helper_.WaitForChildTestShutdown(); } | 
|  145  |  149  | 
|  146   IPC::Sender* sender() { return channel(); } |  150   IPC::Sender* sender() { return channel(); } | 
|  147   IPC::Channel* channel() { return channel_.get(); } |  151   IPC::Channel* channel() { return channel_.get(); } | 
|  148  |  152  | 
|  149  private: |  153  private: | 
|  150   base::MessageLoop message_loop_; |  154   base::MessageLoop message_loop_; | 
|  151   base::TestIOThread io_thread_; |  | 
|  152   mojo::edk::test::MultiprocessTestHelper helper_; |  155   mojo::edk::test::MultiprocessTestHelper helper_; | 
|  153   mojo::ScopedMessagePipeHandle handle_; |  156   mojo::ScopedMessagePipeHandle handle_; | 
|  154   std::unique_ptr<IPC::Channel> channel_; |  157   std::unique_ptr<IPC::Channel> channel_; | 
|  155 }; |  158 }; | 
|  156  |  159  | 
|  157 class TestChannelListenerWithExtraExpectations |  160 class TestChannelListenerWithExtraExpectations | 
|  158     : public IPC::TestChannelListener { |  161     : public IPC::TestChannelListener { | 
|  159  public: |  162  public: | 
|  160   TestChannelListenerWithExtraExpectations() : is_connected_called_(false) {} |  163   TestChannelListenerWithExtraExpectations() : is_connected_called_(false) {} | 
|  161  |  164  | 
| (...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  575                                     ChannelClient) { |  578                                     ChannelClient) { | 
|  576   ListenerSendingOneOk listener; |  579   ListenerSendingOneOk listener; | 
|  577   Connect(&listener); |  580   Connect(&listener); | 
|  578   listener.set_sender(channel()); |  581   listener.set_sender(channel()); | 
|  579  |  582  | 
|  580   base::RunLoop().Run(); |  583   base::RunLoop().Run(); | 
|  581  |  584  | 
|  582   Close(); |  585   Close(); | 
|  583 } |  586 } | 
|  584  |  587  | 
 |  588 class ListenerWithSimpleAssociatedInterface | 
 |  589     : public IPC::Listener, | 
 |  590       public IPC::mojom::SimpleTestDriver { | 
 |  591  public: | 
 |  592   static const int kNumMessages; | 
 |  593  | 
 |  594   ListenerWithSimpleAssociatedInterface() : binding_(this) {} | 
 |  595  | 
 |  596   ~ListenerWithSimpleAssociatedInterface() override {} | 
 |  597  | 
 |  598   bool OnMessageReceived(const IPC::Message& message) override { | 
 |  599     base::PickleIterator iter(message); | 
 |  600     std::string should_be_expected; | 
 |  601     EXPECT_TRUE(iter.ReadString(&should_be_expected)); | 
 |  602     EXPECT_EQ(should_be_expected, next_expected_string_); | 
 |  603     num_messages_received_++; | 
 |  604     return true; | 
 |  605   } | 
 |  606  | 
 |  607   void OnChannelError() override { | 
 |  608     DCHECK(received_quit_); | 
 |  609   } | 
 |  610  | 
 |  611   void RegisterInterfaceFactory(IPC::Channel* channel) { | 
 |  612     channel->GetAssociatedInterfaceSupport()->AddAssociatedInterface( | 
 |  613         base::Bind(&ListenerWithSimpleAssociatedInterface::BindRequest, | 
 |  614                    base::Unretained(this))); | 
 |  615   } | 
 |  616  | 
 |  617  private: | 
 |  618   // IPC::mojom::SimpleTestDriver: | 
 |  619   void ExpectString(const mojo::String& str) override { | 
 |  620     next_expected_string_ = str; | 
 |  621   } | 
 |  622  | 
 |  623   void RequestQuit(const RequestQuitCallback& callback) override { | 
 |  624     EXPECT_EQ(kNumMessages, num_messages_received_); | 
 |  625     received_quit_ = true; | 
 |  626     callback.Run(); | 
 |  627     base::MessageLoop::current()->QuitWhenIdle(); | 
 |  628   } | 
 |  629  | 
 |  630   void BindRequest(IPC::mojom::SimpleTestDriverAssociatedRequest request) { | 
 |  631     DCHECK(!binding_.is_bound()); | 
 |  632     binding_.Bind(std::move(request)); | 
 |  633   } | 
 |  634  | 
 |  635   std::string next_expected_string_; | 
 |  636   int num_messages_received_ = 0; | 
 |  637   bool received_quit_ = false; | 
 |  638  | 
 |  639   mojo::AssociatedBinding<IPC::mojom::SimpleTestDriver> binding_; | 
 |  640 }; | 
 |  641  | 
 |  642 const int ListenerWithSimpleAssociatedInterface::kNumMessages = 1000; | 
 |  643  | 
 |  644 class ListenerSendingAssociatedMessages : public IPC::Listener { | 
 |  645  public: | 
 |  646   ListenerSendingAssociatedMessages() {} | 
 |  647  | 
 |  648   bool OnMessageReceived(const IPC::Message& message) override { return true; } | 
 |  649  | 
 |  650   void OnChannelConnected(int32_t peer_pid) override { | 
 |  651     DCHECK(channel_); | 
 |  652     channel_->GetAssociatedInterfaceSupport()->GetRemoteAssociatedInterface( | 
 |  653         &driver_); | 
 |  654  | 
 |  655     // Send a bunch of interleaved messages, alternating between the associated | 
 |  656     // interface and a legacy IPC::Message. | 
 |  657     for (int i = 0; i < ListenerWithSimpleAssociatedInterface::kNumMessages; | 
 |  658          ++i) { | 
 |  659       std::string str = base::StringPrintf("Hello! %d", i); | 
 |  660       driver_->ExpectString(str); | 
 |  661       SendString(channel_, str); | 
 |  662     } | 
 |  663     driver_->RequestQuit(base::Bind(&OnQuitAck)); | 
 |  664   } | 
 |  665  | 
 |  666   void set_channel(IPC::Channel* channel) { channel_ = channel; } | 
 |  667  | 
 |  668  private: | 
 |  669   static void OnQuitAck() { base::MessageLoop::current()->QuitWhenIdle(); } | 
 |  670  | 
 |  671   IPC::Channel* channel_ = nullptr; | 
 |  672   IPC::mojom::SimpleTestDriverAssociatedPtr driver_; | 
 |  673 }; | 
 |  674  | 
 |  675 TEST_F(IPCChannelMojoTest, SimpleAssociatedInterface) { | 
 |  676   InitWithMojo("SimpleAssociatedInterfaceClient"); | 
 |  677  | 
 |  678   ListenerWithSimpleAssociatedInterface listener; | 
 |  679   CreateChannel(&listener); | 
 |  680   ASSERT_TRUE(ConnectChannel()); | 
 |  681  | 
 |  682   listener.RegisterInterfaceFactory(channel()); | 
 |  683  | 
 |  684   base::RunLoop().Run(); | 
 |  685   channel()->Close(); | 
 |  686  | 
 |  687   EXPECT_TRUE(WaitForClientShutdown()); | 
 |  688   DestroyChannel(); | 
 |  689 } | 
 |  690  | 
 |  691 DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(SimpleAssociatedInterfaceClient, | 
 |  692                                     ChannelClient) { | 
 |  693   ListenerSendingAssociatedMessages listener; | 
 |  694   Connect(&listener); | 
 |  695   listener.set_channel(channel()); | 
 |  696  | 
 |  697   base::RunLoop().Run(); | 
 |  698  | 
 |  699   Close(); | 
 |  700 } | 
 |  701  | 
|  585 #if defined(OS_POSIX) |  702 #if defined(OS_POSIX) | 
|  586 class ListenerThatExpectsFile : public IPC::Listener { |  703 class ListenerThatExpectsFile : public IPC::Listener { | 
|  587  public: |  704  public: | 
|  588   ListenerThatExpectsFile() : sender_(NULL) {} |  705   ListenerThatExpectsFile() : sender_(NULL) {} | 
|  589  |  706  | 
|  590   ~ListenerThatExpectsFile() override {} |  707   ~ListenerThatExpectsFile() override {} | 
|  591  |  708  | 
|  592   bool OnMessageReceived(const IPC::Message& message) override { |  709   bool OnMessageReceived(const IPC::Message& message) override { | 
|  593     base::PickleIterator iter(message); |  710     base::PickleIterator iter(message); | 
|  594     HandleSendingHelper::ReadReceivedFile(message, &iter); |  711     HandleSendingHelper::ReadReceivedFile(message, &iter); | 
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  689     ChannelClient) { |  806     ChannelClient) { | 
|  690   ListenerThatExpectsFileAndPipe listener; |  807   ListenerThatExpectsFileAndPipe listener; | 
|  691   Connect(&listener); |  808   Connect(&listener); | 
|  692   listener.set_sender(channel()); |  809   listener.set_sender(channel()); | 
|  693  |  810  | 
|  694   base::RunLoop().Run(); |  811   base::RunLoop().Run(); | 
|  695  |  812  | 
|  696   Close(); |  813   Close(); | 
|  697 } |  814 } | 
|  698  |  815  | 
|  699 #endif |  816 #endif  // defined(OS_POSIX) | 
|  700  |  817  | 
|  701 #if defined(OS_LINUX) |  818 #if defined(OS_LINUX) | 
|  702  |  819  | 
|  703 const base::ProcessId kMagicChildId = 54321; |  820 const base::ProcessId kMagicChildId = 54321; | 
|  704  |  821  | 
|  705 class ListenerThatVerifiesPeerPid : public IPC::Listener { |  822 class ListenerThatVerifiesPeerPid : public IPC::Listener { | 
|  706  public: |  823  public: | 
|  707   void OnChannelConnected(int32_t peer_pid) override { |  824   void OnChannelConnected(int32_t peer_pid) override { | 
|  708     EXPECT_EQ(peer_pid, kMagicChildId); |  825     EXPECT_EQ(peer_pid, kMagicChildId); | 
|  709     base::MessageLoop::current()->QuitWhenIdle(); |  826     base::MessageLoop::current()->QuitWhenIdle(); | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
|  736   Connect(&listener); |  853   Connect(&listener); | 
|  737  |  854  | 
|  738   base::MessageLoop::current()->Run(); |  855   base::MessageLoop::current()->Run(); | 
|  739  |  856  | 
|  740   Close(); |  857   Close(); | 
|  741 } |  858 } | 
|  742  |  859  | 
|  743 #endif  // OS_LINUX |  860 #endif  // OS_LINUX | 
|  744  |  861  | 
|  745 }  // namespace |  862 }  // namespace | 
| OLD | NEW |