| 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/mojo/ipc_channel_mojo.h" | 5 #include "ipc/mojo/ipc_channel_mojo.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/base_paths.h" | 11 #include "base/base_paths.h" |
| 12 #include "base/command_line.h" |
| 12 #include "base/files/file.h" | 13 #include "base/files/file.h" |
| 13 #include "base/location.h" | 14 #include "base/location.h" |
| 14 #include "base/path_service.h" | 15 #include "base/path_service.h" |
| 15 #include "base/pickle.h" | 16 #include "base/pickle.h" |
| 16 #include "base/run_loop.h" | 17 #include "base/run_loop.h" |
| 17 #include "base/single_thread_task_runner.h" | 18 #include "base/single_thread_task_runner.h" |
| 18 #include "base/test/test_timeouts.h" | 19 #include "base/test/test_timeouts.h" |
| 19 #include "base/thread_task_runner_handle.h" | 20 #include "base/thread_task_runner_handle.h" |
| 20 #include "base/threading/thread.h" | 21 #include "base/threading/thread.h" |
| 21 #include "build/build_config.h" | 22 #include "build/build_config.h" |
| 22 #include "ipc/ipc_message.h" | 23 #include "ipc/ipc_message.h" |
| 23 #include "ipc/ipc_test_base.h" | 24 #include "ipc/ipc_test_base.h" |
| 24 #include "ipc/ipc_test_channel_listener.h" | 25 #include "ipc/ipc_test_channel_listener.h" |
| 25 #include "ipc/mojo/ipc_mojo_handle_attachment.h" | 26 #include "ipc/mojo/ipc_mojo_handle_attachment.h" |
| 26 #include "ipc/mojo/ipc_mojo_message_helper.h" | 27 #include "ipc/mojo/ipc_mojo_message_helper.h" |
| 27 #include "ipc/mojo/ipc_mojo_param_traits.h" | 28 #include "ipc/mojo/ipc_mojo_param_traits.h" |
| 28 #include "ipc/mojo/scoped_ipc_support.h" | 29 #include "ipc/mojo/scoped_ipc_support.h" |
| 30 #include "mojo/edk/embedder/embedder.h" |
| 31 #include "mojo/edk/embedder/embedder_internal.h" |
| 32 #include "mojo/edk/embedder/platform_channel_pair.h" |
| 29 | 33 |
| 30 #if defined(OS_POSIX) | 34 #if defined(OS_POSIX) |
| 31 #include "base/file_descriptor_posix.h" | 35 #include "base/file_descriptor_posix.h" |
| 32 #include "ipc/ipc_platform_file_attachment_posix.h" | 36 #include "ipc/ipc_platform_file_attachment_posix.h" |
| 33 #endif | 37 #endif |
| 34 | 38 |
| 35 namespace { | 39 namespace { |
| 36 | 40 |
| 37 class ListenerThatExpectsOK : public IPC::Listener { | 41 class ListenerThatExpectsOK : public IPC::Listener { |
| 38 public: | 42 public: |
| (...skipping 26 matching lines...) Expand all Loading... |
| 65 ASSERT_TRUE(sender->Send(message)); | 69 ASSERT_TRUE(sender->Send(message)); |
| 66 } | 70 } |
| 67 | 71 |
| 68 private: | 72 private: |
| 69 bool received_ok_; | 73 bool received_ok_; |
| 70 }; | 74 }; |
| 71 | 75 |
| 72 class ChannelClient { | 76 class ChannelClient { |
| 73 public: | 77 public: |
| 74 explicit ChannelClient(IPC::Listener* listener, const char* name) { | 78 explicit ChannelClient(IPC::Listener* listener, const char* name) { |
| 75 channel_ = IPC::ChannelMojo::Create(main_message_loop_.task_runner(), | 79 channel_ = IPC::ChannelMojo::Create( |
| 76 IPCTestBase::GetChannelName(name), | 80 mojo::edk::internal::g_io_thread_task_runner, |
| 77 IPC::Channel::MODE_CLIENT, listener); | 81 IPCTestBase::GetChannelName(name), |
| 82 IPC::Channel::MODE_CLIENT, listener); |
| 78 } | 83 } |
| 79 | 84 |
| 80 void Connect() { | 85 void Connect() { |
| 81 CHECK(channel_->Connect()); | 86 CHECK(channel_->Connect()); |
| 82 } | 87 } |
| 83 | 88 |
| 84 void Close() { | 89 void Close() { |
| 85 channel_->Close(); | 90 channel_->Close(); |
| 86 | 91 |
| 87 base::RunLoop run_loop; | 92 base::RunLoop run_loop; |
| 88 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | 93 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
| 89 run_loop.QuitClosure()); | 94 run_loop.QuitClosure()); |
| 90 run_loop.Run(); | 95 run_loop.Run(); |
| 91 } | 96 } |
| 92 | 97 |
| 93 IPC::ChannelMojo* channel() const { return channel_.get(); } | 98 IPC::ChannelMojo* channel() const { return channel_.get(); } |
| 94 | 99 |
| 95 private: | 100 private: |
| 96 base::MessageLoopForIO main_message_loop_; | 101 base::MessageLoopForIO main_message_loop_; |
| 97 scoped_ptr<IPC::ChannelMojo> channel_; | 102 scoped_ptr<IPC::ChannelMojo> channel_; |
| 98 }; | 103 }; |
| 99 | 104 |
| 100 class IPCChannelMojoTestBase : public IPCTestBase { | 105 class IPCChannelMojoTestBase : public IPCTestBase { |
| 101 public: | 106 public: |
| 102 void InitWithMojo(const std::string& test_client_name) { | 107 void InitWithMojo(const std::string& test_client_name) { |
| 103 Init(test_client_name); | 108 Init(test_client_name); |
| 104 } | 109 } |
| 105 | 110 |
| 106 void TearDown() override { | 111 // IPCTestBase: |
| 107 // Make sure Mojo IPC support is properly shutdown on the I/O loop before | 112 scoped_refptr<base::TaskRunner> io_task_runner() override { |
| 108 // TearDown continues. | 113 return make_scoped_refptr(mojo::edk::internal::g_io_thread_task_runner); |
| 109 base::RunLoop run_loop; | 114 } |
| 110 task_runner()->PostTask(FROM_HERE, run_loop.QuitClosure()); | |
| 111 run_loop.Run(); | |
| 112 | 115 |
| 113 IPCTestBase::TearDown(); | 116 void AboutToSpawnChild(base::LaunchOptions* options) override { |
| 117 #if defined(OS_POSIX) |
| 118 base::FileHandleMappingVector* handles = |
| 119 const_cast<base::FileHandleMappingVector*>(options->fds_to_remap); |
| 120 #else |
| 121 base::HandlesToInheritVector* handles = |
| 122 const_cast<base::HandlesToInheritVector*>(options->handles_to_inherit); |
| 123 #endif |
| 124 broker_handle_ = broker_platform_channel_pair_. |
| 125 PrepareToPassClientHandleToChildProcessAsString(handles); |
| 114 } | 126 } |
| 127 |
| 128 bool DidStartClient() override { |
| 129 broker_platform_channel_pair_.ChildProcessLaunched(); |
| 130 ChildProcessLaunched(client_process().Handle(), |
| 131 broker_platform_channel_pair_.PassServerHandle()); |
| 132 return IPCTestBase::DidStartClient(); |
| 133 } |
| 134 |
| 135 // MultiProcessTest: |
| 136 base::CommandLine MakeCmdLine(const std::string& procname) override { |
| 137 base::CommandLine command_line = MultiProcessTest::MakeCmdLine(procname); |
| 138 command_line.AppendSwitchASCII("broker-handle", broker_handle_); |
| 139 return command_line; |
| 140 } |
| 141 |
| 142 private: |
| 143 // Used by the broker. |
| 144 mojo::edk::PlatformChannelPair broker_platform_channel_pair_; |
| 145 std::string broker_handle_; |
| 115 }; | 146 }; |
| 116 | 147 |
| 117 class IPCChannelMojoTest : public IPCChannelMojoTestBase { | 148 class IPCChannelMojoTest : public IPCChannelMojoTestBase { |
| 118 protected: | 149 protected: |
| 119 scoped_ptr<IPC::ChannelFactory> CreateChannelFactory( | 150 scoped_ptr<IPC::ChannelFactory> CreateChannelFactory( |
| 120 const IPC::ChannelHandle& handle, | 151 const IPC::ChannelHandle& handle, |
| 121 base::SequencedTaskRunner* runner) override { | 152 base::TaskRunner* runner) override { |
| 122 return IPC::ChannelMojo::CreateServerFactory(task_runner(), handle); | 153 return IPC::ChannelMojo::CreateServerFactory(io_task_runner(), handle); |
| 123 } | 154 } |
| 124 | 155 |
| 125 bool DidStartClient() override { | 156 bool DidStartClient() override { |
| 126 bool ok = IPCTestBase::DidStartClient(); | 157 bool ok = IPCChannelMojoTestBase::DidStartClient(); |
| 127 DCHECK(ok); | 158 DCHECK(ok); |
| 128 return ok; | 159 return ok; |
| 129 } | 160 } |
| 130 }; | 161 }; |
| 131 | 162 |
| 132 | 163 |
| 133 class TestChannelListenerWithExtraExpectations | 164 class TestChannelListenerWithExtraExpectations |
| 134 : public IPC::TestChannelListener { | 165 : public IPC::TestChannelListener { |
| 135 public: | 166 public: |
| 136 TestChannelListenerWithExtraExpectations() | 167 TestChannelListenerWithExtraExpectations() |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 219 | 250 |
| 220 private: | 251 private: |
| 221 bool has_error_; | 252 bool has_error_; |
| 222 }; | 253 }; |
| 223 | 254 |
| 224 | 255 |
| 225 class IPCChannelMojoErrorTest : public IPCChannelMojoTestBase { | 256 class IPCChannelMojoErrorTest : public IPCChannelMojoTestBase { |
| 226 protected: | 257 protected: |
| 227 scoped_ptr<IPC::ChannelFactory> CreateChannelFactory( | 258 scoped_ptr<IPC::ChannelFactory> CreateChannelFactory( |
| 228 const IPC::ChannelHandle& handle, | 259 const IPC::ChannelHandle& handle, |
| 229 base::SequencedTaskRunner* runner) override { | 260 base::TaskRunner* runner) override { |
| 230 return IPC::ChannelMojo::CreateServerFactory(task_runner(), handle); | 261 return IPC::ChannelMojo::CreateServerFactory(io_task_runner(), handle); |
| 231 } | 262 } |
| 232 | 263 |
| 233 bool DidStartClient() override { | 264 bool DidStartClient() override { |
| 234 bool ok = IPCTestBase::DidStartClient(); | 265 bool ok = IPCChannelMojoTestBase::DidStartClient(); |
| 235 DCHECK(ok); | 266 DCHECK(ok); |
| 236 return ok; | 267 return ok; |
| 237 } | 268 } |
| 238 }; | 269 }; |
| 239 | 270 |
| 240 class ListenerThatQuits : public IPC::Listener { | 271 class ListenerThatQuits : public IPC::Listener { |
| 241 public: | 272 public: |
| 242 ListenerThatQuits() { | 273 ListenerThatQuits() { |
| 243 } | 274 } |
| 244 | 275 |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 base::MessageLoop::current()->Run(); | 474 base::MessageLoop::current()->Run(); |
| 444 | 475 |
| 445 client.Close(); | 476 client.Close(); |
| 446 | 477 |
| 447 return 0; | 478 return 0; |
| 448 } | 479 } |
| 449 | 480 |
| 450 void ReadOK(mojo::MessagePipeHandle pipe) { | 481 void ReadOK(mojo::MessagePipeHandle pipe) { |
| 451 std::string should_be_ok("xx"); | 482 std::string should_be_ok("xx"); |
| 452 uint32_t num_bytes = static_cast<uint32_t>(should_be_ok.size()); | 483 uint32_t num_bytes = static_cast<uint32_t>(should_be_ok.size()); |
| 484 EXPECT_EQ(MOJO_RESULT_OK, mojo::Wait(pipe, MOJO_HANDLE_SIGNAL_READABLE, |
| 485 MOJO_DEADLINE_INDEFINITE, nullptr)); |
| 453 CHECK_EQ(MOJO_RESULT_OK, | 486 CHECK_EQ(MOJO_RESULT_OK, |
| 454 mojo::ReadMessageRaw(pipe, &should_be_ok[0], &num_bytes, nullptr, | 487 mojo::ReadMessageRaw(pipe, &should_be_ok[0], &num_bytes, nullptr, |
| 455 nullptr, 0)); | 488 nullptr, 0)); |
| 456 EXPECT_EQ(should_be_ok, std::string("OK")); | 489 EXPECT_EQ(should_be_ok, std::string("OK")); |
| 457 } | 490 } |
| 458 | 491 |
| 459 void WriteOK(mojo::MessagePipeHandle pipe) { | 492 void WriteOK(mojo::MessagePipeHandle pipe) { |
| 460 std::string ok("OK"); | 493 std::string ok("OK"); |
| 461 CHECK_EQ(MOJO_RESULT_OK, | 494 CHECK_EQ(MOJO_RESULT_OK, |
| 462 mojo::WriteMessageRaw(pipe, &ok[0], static_cast<uint32_t>(ok.size()), | 495 mojo::WriteMessageRaw(pipe, &ok[0], static_cast<uint32_t>(ok.size()), |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 620 client.Close(); | 653 client.Close(); |
| 621 | 654 |
| 622 return 0; | 655 return 0; |
| 623 } | 656 } |
| 624 | 657 |
| 625 #if defined(OS_WIN) | 658 #if defined(OS_WIN) |
| 626 class IPCChannelMojoDeadHandleTest : public IPCChannelMojoTestBase { | 659 class IPCChannelMojoDeadHandleTest : public IPCChannelMojoTestBase { |
| 627 protected: | 660 protected: |
| 628 scoped_ptr<IPC::ChannelFactory> CreateChannelFactory( | 661 scoped_ptr<IPC::ChannelFactory> CreateChannelFactory( |
| 629 const IPC::ChannelHandle& handle, | 662 const IPC::ChannelHandle& handle, |
| 630 base::SequencedTaskRunner* runner) override { | 663 base::TaskRunner* runner) override { |
| 631 return IPC::ChannelMojo::CreateServerFactory(task_runner(), handle); | 664 return IPC::ChannelMojo::CreateServerFactory(io_task_runner(), handle); |
| 632 } | 665 } |
| 633 | 666 |
| 634 bool DidStartClient() override { | 667 bool DidStartClient() override { |
| 635 IPCTestBase::DidStartClient(); | 668 IPCChannelMojoTestBase::DidStartClient(); |
| 636 // const base::ProcessHandle client = client_process().Handle(); | 669 // const base::ProcessHandle client = client_process().Handle(); |
| 637 // Forces GetFileHandleForProcess() fail. It happens occasionally | 670 // Forces GetFileHandleForProcess() fail. It happens occasionally |
| 638 // in production, so we should exercise it somehow. | 671 // in production, so we should exercise it somehow. |
| 639 // TODO(morrita): figure out how to safely test this. See crbug.com/464109. | 672 // TODO(morrita): figure out how to safely test this. See crbug.com/464109. |
| 640 // ::CloseHandle(client); | 673 // ::CloseHandle(client); |
| 641 return true; | 674 return true; |
| 642 } | 675 } |
| 643 }; | 676 }; |
| 644 | 677 |
| 645 TEST_F(IPCChannelMojoDeadHandleTest, InvalidClientHandle) { | 678 TEST_F(IPCChannelMojoDeadHandleTest, InvalidClientHandle) { |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 853 base::MessageLoop::current()->Run(); | 886 base::MessageLoop::current()->Run(); |
| 854 | 887 |
| 855 client.Close(); | 888 client.Close(); |
| 856 | 889 |
| 857 return 0; | 890 return 0; |
| 858 } | 891 } |
| 859 | 892 |
| 860 #endif // OS_LINUX | 893 #endif // OS_LINUX |
| 861 | 894 |
| 862 } // namespace | 895 } // namespace |
| OLD | NEW |