blob: 5c23ea3823c6b407c7fbf32d16354913dc42e314 [file] [log] [blame]
[email protected]64860882014-08-04 23:44:171// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
amistryd4aa70d2016-06-23 07:52:375#include "ipc/ipc_channel_mojo.h"
[email protected]64860882014-08-04 23:44:176
avi246998d82015-12-22 02:39:047#include <stddef.h>
tfarina10a5c062015-09-04 18:47:578#include <stdint.h>
rockot7c6bf952016-07-14 00:34:119
danakj03de39b22016-04-23 04:21:0910#include <memory>
dchenge48600452015-12-28 02:24:5011#include <utility>
tfarina10a5c062015-09-04 18:47:5712
[email protected]64860882014-08-04 23:44:1713#include "base/base_paths.h"
rockot8d890f62016-07-14 16:37:1414#include "base/bind.h"
[email protected]64860882014-08-04 23:44:1715#include "base/files/file.h"
amistry20e2b1d62016-06-23 06:12:3516#include "base/files/scoped_temp_dir.h"
skyostile687bdff2015-05-12 11:29:2117#include "base/location.h"
rockot8d890f62016-07-14 16:37:1418#include "base/macros.h"
19#include "base/message_loop/message_loop.h"
[email protected]64860882014-08-04 23:44:1720#include "base/path_service.h"
21#include "base/pickle.h"
rockotcbca72f2015-03-03 16:31:0422#include "base/run_loop.h"
skyostile687bdff2015-05-12 11:29:2123#include "base/single_thread_task_runner.h"
rockot7c6bf952016-07-14 00:34:1124#include "base/strings/stringprintf.h"
rockot9abe09b2016-08-02 20:57:3425#include "base/synchronization/waitable_event.h"
sammc57ed9f982016-03-10 06:28:3526#include "base/test/test_io_thread.h"
morrita0bd20bd2015-02-25 20:11:2727#include "base/test/test_timeouts.h"
[email protected]64860882014-08-04 23:44:1728#include "base/threading/thread.h"
gabf08ccc02016-05-11 18:51:1129#include "base/threading/thread_task_runner_handle.h"
avi246998d82015-12-22 02:39:0430#include "build/build_config.h"
[email protected]64860882014-08-04 23:44:1731#include "ipc/ipc_message.h"
amistryd4aa70d2016-06-23 07:52:3732#include "ipc/ipc_mojo_handle_attachment.h"
33#include "ipc/ipc_mojo_message_helper.h"
34#include "ipc/ipc_mojo_param_traits.h"
rockot9abe09b2016-08-02 20:57:3435#include "ipc/ipc_sync_channel.h"
36#include "ipc/ipc_sync_message.h"
rockot7c6bf952016-07-14 00:34:1137#include "ipc/ipc_test.mojom.h"
[email protected]64860882014-08-04 23:44:1738#include "ipc/ipc_test_base.h"
39#include "ipc/ipc_test_channel_listener.h"
sammc57ed9f982016-03-10 06:28:3540#include "testing/gtest/include/gtest/gtest.h"
[email protected]64860882014-08-04 23:44:1741
42#if defined(OS_POSIX)
43#include "base/file_descriptor_posix.h"
morrita1aa788c2015-01-31 05:45:4244#include "ipc/ipc_platform_file_attachment_posix.h"
[email protected]64860882014-08-04 23:44:1745#endif
46
47namespace {
48
rockot7c6bf952016-07-14 00:34:1149void SendString(IPC::Sender* sender, const std::string& str) {
50 IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
51 message->WriteString(str);
52 ASSERT_TRUE(sender->Send(message));
53}
54
rockot9abe09b2016-08-02 20:57:3455void SendValue(IPC::Sender* sender, int32_t value) {
56 IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
57 message->WriteInt(value);
58 ASSERT_TRUE(sender->Send(message));
59}
60
[email protected]64860882014-08-04 23:44:1761class ListenerThatExpectsOK : public IPC::Listener {
62 public:
sammc57ed9f982016-03-10 06:28:3563 ListenerThatExpectsOK() : received_ok_(false) {}
[email protected]64860882014-08-04 23:44:1764
dchengfe61fca2014-10-22 02:29:5265 ~ListenerThatExpectsOK() override {}
[email protected]64860882014-08-04 23:44:1766
dchengfe61fca2014-10-22 02:29:5267 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:2568 base::PickleIterator iter(message);
[email protected]64860882014-08-04 23:44:1769 std::string should_be_ok;
70 EXPECT_TRUE(iter.ReadString(&should_be_ok));
71 EXPECT_EQ(should_be_ok, "OK");
[email protected]e5c27752014-08-08 21:45:1372 received_ok_ = true;
ki.stfua21ed8c2015-10-12 17:26:0073 base::MessageLoop::current()->QuitWhenIdle();
[email protected]64860882014-08-04 23:44:1774 return true;
75 }
76
dchengfe61fca2014-10-22 02:29:5277 void OnChannelError() override {
[email protected]e5c27752014-08-08 21:45:1378 // The connection should be healthy while the listener is waiting
79 // message. An error can occur after that because the peer
80 // process dies.
81 DCHECK(received_ok_);
[email protected]64860882014-08-04 23:44:1782 }
83
rockot7c6bf952016-07-14 00:34:1184 static void SendOK(IPC::Sender* sender) { SendString(sender, "OK"); }
[email protected]e5c27752014-08-08 21:45:1385
86 private:
87 bool received_ok_;
[email protected]64860882014-08-04 23:44:1788};
89
sammc4bcc4ed62016-10-27 10:13:5990using IPCChannelMojoTest = IPCChannelMojoTestBase;
rockotcbca72f2015-03-03 16:31:0491
[email protected]64860882014-08-04 23:44:1792class TestChannelListenerWithExtraExpectations
93 : public IPC::TestChannelListener {
94 public:
sammc57ed9f982016-03-10 06:28:3595 TestChannelListenerWithExtraExpectations() : is_connected_called_(false) {}
[email protected]64860882014-08-04 23:44:1796
tfarina10a5c062015-09-04 18:47:5797 void OnChannelConnected(int32_t peer_pid) override {
[email protected]64860882014-08-04 23:44:1798 IPC::TestChannelListener::OnChannelConnected(peer_pid);
99 EXPECT_TRUE(base::kNullProcessId != peer_pid);
100 is_connected_called_ = true;
101 }
102
103 bool is_connected_called() const { return is_connected_called_; }
104
105 private:
106 bool is_connected_called_;
107};
108
amistry0027a0952016-05-03 00:52:47109TEST_F(IPCChannelMojoTest, ConnectedFromClient) {
sammc4bcc4ed62016-10-27 10:13:59110 Init("IPCChannelMojoTestClient");
[email protected]64860882014-08-04 23:44:17111
112 // Set up IPC channel and start client.
113 TestChannelListenerWithExtraExpectations listener;
morrita373af03b2014-09-09 19:35:24114 CreateChannel(&listener);
[email protected]64860882014-08-04 23:44:17115 listener.Init(sender());
116 ASSERT_TRUE(ConnectChannel());
[email protected]64860882014-08-04 23:44:17117
sammc57ed9f982016-03-10 06:28:35118 IPC::TestChannelListener::SendOneMessage(sender(), "hello from parent");
[email protected]64860882014-08-04 23:44:17119
fdoray8e32586852016-06-22 19:56:16120 base::RunLoop().Run();
[email protected]64860882014-08-04 23:44:17121
sammc57ed9f982016-03-10 06:28:35122 channel()->Close();
[email protected]64860882014-08-04 23:44:17123
124 EXPECT_TRUE(WaitForClientShutdown());
125 EXPECT_TRUE(listener.is_connected_called());
126 EXPECT_TRUE(listener.HasSentAll());
127
128 DestroyChannel();
129}
130
131// A long running process that connects to us
sammc4bcc4ed62016-10-27 10:13:59132DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestClient) {
[email protected]64860882014-08-04 23:44:17133 TestChannelListenerWithExtraExpectations listener;
sammc57ed9f982016-03-10 06:28:35134 Connect(&listener);
135 listener.Init(channel());
[email protected]64860882014-08-04 23:44:17136
sammc57ed9f982016-03-10 06:28:35137 IPC::TestChannelListener::SendOneMessage(channel(), "hello from child");
fdoray8e32586852016-06-22 19:56:16138 base::RunLoop().Run();
[email protected]64860882014-08-04 23:44:17139 EXPECT_TRUE(listener.is_connected_called());
140 EXPECT_TRUE(listener.HasSentAll());
141
sammc57ed9f982016-03-10 06:28:35142 Close();
[email protected]64860882014-08-04 23:44:17143}
144
morrita0a24cfc92014-09-16 03:20:48145class ListenerExpectingErrors : public IPC::Listener {
146 public:
sammc57ed9f982016-03-10 06:28:35147 ListenerExpectingErrors() : has_error_(false) {}
morrita0a24cfc92014-09-16 03:20:48148
dchengfe61fca2014-10-22 02:29:52149 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita0a24cfc92014-09-16 03:20:48150
dchengfe61fca2014-10-22 02:29:52151 void OnChannelError() override {
morrita0a24cfc92014-09-16 03:20:48152 has_error_ = true;
ki.stfua21ed8c2015-10-12 17:26:00153 base::MessageLoop::current()->QuitWhenIdle();
morrita0a24cfc92014-09-16 03:20:48154 }
155
156 bool has_error() const { return has_error_; }
157
158 private:
159 bool has_error_;
160};
161
morrita0a24cfc92014-09-16 03:20:48162class ListenerThatQuits : public IPC::Listener {
163 public:
sammc57ed9f982016-03-10 06:28:35164 ListenerThatQuits() {}
morrita0a24cfc92014-09-16 03:20:48165
sammc57ed9f982016-03-10 06:28:35166 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita0a24cfc92014-09-16 03:20:48167
tfarina10a5c062015-09-04 18:47:57168 void OnChannelConnected(int32_t peer_pid) override {
ki.stfua21ed8c2015-10-12 17:26:00169 base::MessageLoop::current()->QuitWhenIdle();
morrita0a24cfc92014-09-16 03:20:48170 }
171};
172
173// A long running process that connects to us.
sammc4bcc4ed62016-10-27 10:13:59174DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoErraticTestClient) {
morrita0a24cfc92014-09-16 03:20:48175 ListenerThatQuits listener;
sammc57ed9f982016-03-10 06:28:35176 Connect(&listener);
morrita0a24cfc92014-09-16 03:20:48177
fdoray8e32586852016-06-22 19:56:16178 base::RunLoop().Run();
morrita0a24cfc92014-09-16 03:20:48179
sammc57ed9f982016-03-10 06:28:35180 Close();
morrita0a24cfc92014-09-16 03:20:48181}
182
rockot8c23d462016-07-25 17:33:04183TEST_F(IPCChannelMojoTest, SendFailWithPendingMessages) {
sammc4bcc4ed62016-10-27 10:13:59184 Init("IPCChannelMojoErraticTestClient");
morrita0a24cfc92014-09-16 03:20:48185
186 // Set up IPC channel and start client.
187 ListenerExpectingErrors listener;
188 CreateChannel(&listener);
189 ASSERT_TRUE(ConnectChannel());
190
jamesra03ae492014-10-03 04:26:48191 // This matches a value in mojo/edk/system/constants.h
morritabe6c4cc2014-09-24 23:38:44192 const int kMaxMessageNumBytes = 4 * 1024 * 1024;
193 std::string overly_large_data(kMaxMessageNumBytes, '*');
morrita0a24cfc92014-09-16 03:20:48194 // This messages are queued as pending.
morritabe6c4cc2014-09-24 23:38:44195 for (size_t i = 0; i < 10; ++i) {
sammc57ed9f982016-03-10 06:28:35196 IPC::TestChannelListener::SendOneMessage(sender(),
197 overly_large_data.c_str());
morrita0a24cfc92014-09-16 03:20:48198 }
199
fdoray8e32586852016-06-22 19:56:16200 base::RunLoop().Run();
morrita0a24cfc92014-09-16 03:20:48201
sammc57ed9f982016-03-10 06:28:35202 channel()->Close();
morrita0a24cfc92014-09-16 03:20:48203
204 EXPECT_TRUE(WaitForClientShutdown());
205 EXPECT_TRUE(listener.has_error());
206
207 DestroyChannel();
208}
209
morrita81b17e02015-02-06 00:58:30210struct TestingMessagePipe {
211 TestingMessagePipe() {
212 EXPECT_EQ(MOJO_RESULT_OK, mojo::CreateMessagePipe(nullptr, &self, &peer));
213 }
214
215 mojo::ScopedMessagePipeHandle self;
216 mojo::ScopedMessagePipeHandle peer;
217};
218
219class HandleSendingHelper {
220 public:
221 static std::string GetSendingFileContent() { return "Hello"; }
222
223 static void WritePipe(IPC::Message* message, TestingMessagePipe* pipe) {
224 std::string content = HandleSendingHelper::GetSendingFileContent();
225 EXPECT_EQ(MOJO_RESULT_OK,
226 mojo::WriteMessageRaw(pipe->self.get(), &content[0],
227 static_cast<uint32_t>(content.size()),
228 nullptr, 0, 0));
dchenge48600452015-12-28 02:24:50229 EXPECT_TRUE(IPC::MojoMessageHelper::WriteMessagePipeTo(
230 message, std::move(pipe->peer)));
morrita81b17e02015-02-06 00:58:30231 }
232
233 static void WritePipeThenSend(IPC::Sender* sender, TestingMessagePipe* pipe) {
234 IPC::Message* message =
235 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
236 WritePipe(message, pipe);
237 ASSERT_TRUE(sender->Send(message));
238 }
239
240 static void ReadReceivedPipe(const IPC::Message& message,
brettwbd4d7112015-06-03 04:29:25241 base::PickleIterator* iter) {
morrita81b17e02015-02-06 00:58:30242 mojo::ScopedMessagePipeHandle pipe;
243 EXPECT_TRUE(
244 IPC::MojoMessageHelper::ReadMessagePipeFrom(&message, iter, &pipe));
245 std::string content(GetSendingFileContent().size(), ' ');
246
247 uint32_t num_bytes = static_cast<uint32_t>(content.size());
sammc57ed9f982016-03-10 06:28:35248 ASSERT_EQ(MOJO_RESULT_OK,
249 mojo::Wait(pipe.get(), MOJO_HANDLE_SIGNAL_READABLE,
250 MOJO_DEADLINE_INDEFINITE, nullptr));
morrita81b17e02015-02-06 00:58:30251 EXPECT_EQ(MOJO_RESULT_OK,
252 mojo::ReadMessageRaw(pipe.get(), &content[0], &num_bytes, nullptr,
253 nullptr, 0));
254 EXPECT_EQ(content, GetSendingFileContent());
255 }
256
257#if defined(OS_POSIX)
amistry20e2b1d62016-06-23 06:12:35258 static base::FilePath GetSendingFilePath(const base::FilePath& dir_path) {
259 return dir_path.Append("ListenerThatExpectsFile.txt");
morrita81b17e02015-02-06 00:58:30260 }
261
262 static void WriteFile(IPC::Message* message, base::File& file) {
263 std::string content = GetSendingFileContent();
264 file.WriteAtCurrentPos(content.data(), content.size());
265 file.Flush();
266 message->WriteAttachment(new IPC::internal::PlatformFileAttachment(
267 base::ScopedFD(file.TakePlatformFile())));
268 }
269
270 static void WriteFileThenSend(IPC::Sender* sender, base::File& file) {
271 IPC::Message* message =
272 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
273 WriteFile(message, file);
274 ASSERT_TRUE(sender->Send(message));
275 }
276
277 static void WriteFileAndPipeThenSend(IPC::Sender* sender,
278 base::File& file,
279 TestingMessagePipe* pipe) {
280 IPC::Message* message =
281 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
282 WriteFile(message, file);
283 WritePipe(message, pipe);
284 ASSERT_TRUE(sender->Send(message));
285 }
286
287 static void ReadReceivedFile(const IPC::Message& message,
brettwbd4d7112015-06-03 04:29:25288 base::PickleIterator* iter) {
morrita81b17e02015-02-06 00:58:30289 base::ScopedFD fd;
rockot502c94f2016-02-03 20:20:16290 scoped_refptr<base::Pickle::Attachment> attachment;
morrita81b17e02015-02-06 00:58:30291 EXPECT_TRUE(message.ReadAttachment(iter, &attachment));
sammc6ed3efb2016-11-23 03:17:35292 EXPECT_EQ(
293 IPC::MessageAttachment::Type::PLATFORM_FILE,
294 static_cast<IPC::MessageAttachment*>(attachment.get())->GetType());
295 base::File file(
296 static_cast<IPC::internal::PlatformFileAttachment*>(attachment.get())
297 ->TakePlatformFile());
morrita81b17e02015-02-06 00:58:30298 std::string content(GetSendingFileContent().size(), ' ');
299 file.Read(0, &content[0], content.size());
300 EXPECT_EQ(content, GetSendingFileContent());
301 }
302#endif
303};
304
305class ListenerThatExpectsMessagePipe : public IPC::Listener {
306 public:
307 ListenerThatExpectsMessagePipe() : sender_(NULL) {}
308
309 ~ListenerThatExpectsMessagePipe() override {}
310
311 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25312 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:30313 HandleSendingHelper::ReadReceivedPipe(message, &iter);
morrita81b17e02015-02-06 00:58:30314 ListenerThatExpectsOK::SendOK(sender_);
315 return true;
316 }
317
amistry6c70caea2016-06-09 03:08:29318 void OnChannelError() override {
319 base::MessageLoop::current()->QuitWhenIdle();
320 }
morrita81b17e02015-02-06 00:58:30321
322 void set_sender(IPC::Sender* sender) { sender_ = sender; }
323
324 private:
325 IPC::Sender* sender_;
326};
327
amistry0027a0952016-05-03 00:52:47328TEST_F(IPCChannelMojoTest, SendMessagePipe) {
sammc4bcc4ed62016-10-27 10:13:59329 Init("IPCChannelMojoTestSendMessagePipeClient");
morrita81b17e02015-02-06 00:58:30330
331 ListenerThatExpectsOK listener;
332 CreateChannel(&listener);
333 ASSERT_TRUE(ConnectChannel());
morrita81b17e02015-02-06 00:58:30334
335 TestingMessagePipe pipe;
336 HandleSendingHelper::WritePipeThenSend(channel(), &pipe);
337
fdoray8e32586852016-06-22 19:56:16338 base::RunLoop().Run();
sammc57ed9f982016-03-10 06:28:35339 channel()->Close();
morrita81b17e02015-02-06 00:58:30340
341 EXPECT_TRUE(WaitForClientShutdown());
342 DestroyChannel();
343}
344
sammc4bcc4ed62016-10-27 10:13:59345DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendMessagePipeClient) {
morrita81b17e02015-02-06 00:58:30346 ListenerThatExpectsMessagePipe listener;
sammc57ed9f982016-03-10 06:28:35347 Connect(&listener);
348 listener.set_sender(channel());
morrita81b17e02015-02-06 00:58:30349
fdoray8e32586852016-06-22 19:56:16350 base::RunLoop().Run();
morrita81b17e02015-02-06 00:58:30351
sammc57ed9f982016-03-10 06:28:35352 Close();
morrita81b17e02015-02-06 00:58:30353}
354
morrita438a2ee2015-04-03 05:28:21355void ReadOK(mojo::MessagePipeHandle pipe) {
356 std::string should_be_ok("xx");
357 uint32_t num_bytes = static_cast<uint32_t>(should_be_ok.size());
sammc57ed9f982016-03-10 06:28:35358 CHECK_EQ(MOJO_RESULT_OK, mojo::Wait(pipe, MOJO_HANDLE_SIGNAL_READABLE,
359 MOJO_DEADLINE_INDEFINITE, nullptr));
morrita438a2ee2015-04-03 05:28:21360 CHECK_EQ(MOJO_RESULT_OK,
361 mojo::ReadMessageRaw(pipe, &should_be_ok[0], &num_bytes, nullptr,
362 nullptr, 0));
363 EXPECT_EQ(should_be_ok, std::string("OK"));
364}
365
366void WriteOK(mojo::MessagePipeHandle pipe) {
367 std::string ok("OK");
368 CHECK_EQ(MOJO_RESULT_OK,
369 mojo::WriteMessageRaw(pipe, &ok[0], static_cast<uint32_t>(ok.size()),
370 nullptr, 0, 0));
371}
372
373class ListenerThatExpectsMessagePipeUsingParamTrait : public IPC::Listener {
374 public:
375 explicit ListenerThatExpectsMessagePipeUsingParamTrait(bool receiving_valid)
376 : sender_(NULL), receiving_valid_(receiving_valid) {}
377
378 ~ListenerThatExpectsMessagePipeUsingParamTrait() override {}
379
380 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25381 base::PickleIterator iter(message);
morrita438a2ee2015-04-03 05:28:21382 mojo::MessagePipeHandle handle;
383 EXPECT_TRUE(IPC::ParamTraits<mojo::MessagePipeHandle>::Read(&message, &iter,
384 &handle));
385 EXPECT_EQ(handle.is_valid(), receiving_valid_);
386 if (receiving_valid_) {
387 ReadOK(handle);
388 MojoClose(handle.value());
389 }
390
morrita438a2ee2015-04-03 05:28:21391 ListenerThatExpectsOK::SendOK(sender_);
392 return true;
393 }
394
amistry6c70caea2016-06-09 03:08:29395 void OnChannelError() override {
396 base::MessageLoop::current()->QuitWhenIdle();
397 }
398
morrita438a2ee2015-04-03 05:28:21399 void set_sender(IPC::Sender* sender) { sender_ = sender; }
400
401 private:
402 IPC::Sender* sender_;
403 bool receiving_valid_;
404};
405
sammc4bcc4ed62016-10-27 10:13:59406class ParamTraitMessagePipeClient : public IpcChannelMojoTestClient {
sammc57ed9f982016-03-10 06:28:35407 public:
408 void RunTest(bool receiving_valid_handle) {
409 ListenerThatExpectsMessagePipeUsingParamTrait listener(
410 receiving_valid_handle);
411 Connect(&listener);
412 listener.set_sender(channel());
morrita438a2ee2015-04-03 05:28:21413
fdoray8e32586852016-06-22 19:56:16414 base::RunLoop().Run();
morrita438a2ee2015-04-03 05:28:21415
sammc57ed9f982016-03-10 06:28:35416 Close();
417 }
418};
morrita438a2ee2015-04-03 05:28:21419
amistry0027a0952016-05-03 00:52:47420TEST_F(IPCChannelMojoTest, ParamTraitValidMessagePipe) {
sammc4bcc4ed62016-10-27 10:13:59421 Init("ParamTraitValidMessagePipeClient");
morrita438a2ee2015-04-03 05:28:21422
423 ListenerThatExpectsOK listener;
424 CreateChannel(&listener);
425 ASSERT_TRUE(ConnectChannel());
morrita438a2ee2015-04-03 05:28:21426
427 TestingMessagePipe pipe;
428
danakj03de39b22016-04-23 04:21:09429 std::unique_ptr<IPC::Message> message(new IPC::Message());
morrita438a2ee2015-04-03 05:28:21430 IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
431 pipe.peer.release());
432 WriteOK(pipe.self.get());
433
sammc57ed9f982016-03-10 06:28:35434 channel()->Send(message.release());
fdoray8e32586852016-06-22 19:56:16435 base::RunLoop().Run();
sammc57ed9f982016-03-10 06:28:35436 channel()->Close();
morrita438a2ee2015-04-03 05:28:21437
438 EXPECT_TRUE(WaitForClientShutdown());
439 DestroyChannel();
440}
441
sammc4bcc4ed62016-10-27 10:13:59442DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
443 ParamTraitValidMessagePipeClient,
444 ParamTraitMessagePipeClient) {
sammc57ed9f982016-03-10 06:28:35445 RunTest(true);
morrita438a2ee2015-04-03 05:28:21446}
447
amistry0027a0952016-05-03 00:52:47448TEST_F(IPCChannelMojoTest, ParamTraitInvalidMessagePipe) {
sammc4bcc4ed62016-10-27 10:13:59449 Init("ParamTraitInvalidMessagePipeClient");
morrita438a2ee2015-04-03 05:28:21450
451 ListenerThatExpectsOK listener;
452 CreateChannel(&listener);
453 ASSERT_TRUE(ConnectChannel());
morrita438a2ee2015-04-03 05:28:21454
455 mojo::MessagePipeHandle invalid_handle;
danakj03de39b22016-04-23 04:21:09456 std::unique_ptr<IPC::Message> message(new IPC::Message());
morrita438a2ee2015-04-03 05:28:21457 IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
458 invalid_handle);
459
sammc57ed9f982016-03-10 06:28:35460 channel()->Send(message.release());
fdoray8e32586852016-06-22 19:56:16461 base::RunLoop().Run();
sammc57ed9f982016-03-10 06:28:35462 channel()->Close();
morrita438a2ee2015-04-03 05:28:21463
464 EXPECT_TRUE(WaitForClientShutdown());
465 DestroyChannel();
466}
467
sammc4bcc4ed62016-10-27 10:13:59468DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
469 ParamTraitInvalidMessagePipeClient,
470 ParamTraitMessagePipeClient) {
sammc57ed9f982016-03-10 06:28:35471 RunTest(false);
morrita438a2ee2015-04-03 05:28:21472}
473
amistry0027a0952016-05-03 00:52:47474TEST_F(IPCChannelMojoTest, SendFailAfterClose) {
sammc4bcc4ed62016-10-27 10:13:59475 Init("IPCChannelMojoTestSendOkClient");
morrita17137e62015-06-23 22:29:36476
477 ListenerThatExpectsOK listener;
478 CreateChannel(&listener);
479 ASSERT_TRUE(ConnectChannel());
morrita17137e62015-06-23 22:29:36480
fdoray8e32586852016-06-22 19:56:16481 base::RunLoop().Run();
sammc57ed9f982016-03-10 06:28:35482 channel()->Close();
483 ASSERT_FALSE(channel()->Send(new IPC::Message()));
morrita17137e62015-06-23 22:29:36484
485 EXPECT_TRUE(WaitForClientShutdown());
486 DestroyChannel();
487}
488
489class ListenerSendingOneOk : public IPC::Listener {
490 public:
sammc57ed9f982016-03-10 06:28:35491 ListenerSendingOneOk() {}
morrita17137e62015-06-23 22:29:36492
sammc57ed9f982016-03-10 06:28:35493 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita17137e62015-06-23 22:29:36494
tfarina10a5c062015-09-04 18:47:57495 void OnChannelConnected(int32_t peer_pid) override {
morrita17137e62015-06-23 22:29:36496 ListenerThatExpectsOK::SendOK(sender_);
ki.stfua21ed8c2015-10-12 17:26:00497 base::MessageLoop::current()->QuitWhenIdle();
morrita17137e62015-06-23 22:29:36498 }
499
500 void set_sender(IPC::Sender* sender) { sender_ = sender; }
501
502 private:
503 IPC::Sender* sender_;
504};
505
sammc4bcc4ed62016-10-27 10:13:59506DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendOkClient) {
morrita17137e62015-06-23 22:29:36507 ListenerSendingOneOk listener;
sammc57ed9f982016-03-10 06:28:35508 Connect(&listener);
509 listener.set_sender(channel());
morrita17137e62015-06-23 22:29:36510
fdoray8e32586852016-06-22 19:56:16511 base::RunLoop().Run();
morrita17137e62015-06-23 22:29:36512
sammc57ed9f982016-03-10 06:28:35513 Close();
morrita17137e62015-06-23 22:29:36514}
515
rockot7c6bf952016-07-14 00:34:11516class ListenerWithSimpleAssociatedInterface
517 : public IPC::Listener,
518 public IPC::mojom::SimpleTestDriver {
519 public:
520 static const int kNumMessages;
521
522 ListenerWithSimpleAssociatedInterface() : binding_(this) {}
523
524 ~ListenerWithSimpleAssociatedInterface() override {}
525
526 bool OnMessageReceived(const IPC::Message& message) override {
527 base::PickleIterator iter(message);
rockot9abe09b2016-08-02 20:57:34528 int32_t should_be_expected;
529 EXPECT_TRUE(iter.ReadInt(&should_be_expected));
530 EXPECT_EQ(should_be_expected, next_expected_value_);
rockot7c6bf952016-07-14 00:34:11531 num_messages_received_++;
532 return true;
533 }
534
535 void OnChannelError() override {
536 DCHECK(received_quit_);
537 }
538
539 void RegisterInterfaceFactory(IPC::Channel* channel) {
540 channel->GetAssociatedInterfaceSupport()->AddAssociatedInterface(
541 base::Bind(&ListenerWithSimpleAssociatedInterface::BindRequest,
542 base::Unretained(this)));
543 }
544
545 private:
546 // IPC::mojom::SimpleTestDriver:
rockot9abe09b2016-08-02 20:57:34547 void ExpectValue(int32_t value) override {
548 next_expected_value_ = value;
549 }
550
551 void GetExpectedValue(const GetExpectedValueCallback& callback) override {
552 NOTREACHED();
553 }
554
555 void RequestValue(const RequestValueCallback& callback) override {
556 NOTREACHED();
rockot7c6bf952016-07-14 00:34:11557 }
558
559 void RequestQuit(const RequestQuitCallback& callback) override {
560 EXPECT_EQ(kNumMessages, num_messages_received_);
561 received_quit_ = true;
562 callback.Run();
563 base::MessageLoop::current()->QuitWhenIdle();
564 }
565
566 void BindRequest(IPC::mojom::SimpleTestDriverAssociatedRequest request) {
567 DCHECK(!binding_.is_bound());
568 binding_.Bind(std::move(request));
569 }
570
rockot9abe09b2016-08-02 20:57:34571 int32_t next_expected_value_ = 0;
rockot7c6bf952016-07-14 00:34:11572 int num_messages_received_ = 0;
573 bool received_quit_ = false;
574
575 mojo::AssociatedBinding<IPC::mojom::SimpleTestDriver> binding_;
576};
577
578const int ListenerWithSimpleAssociatedInterface::kNumMessages = 1000;
579
580class ListenerSendingAssociatedMessages : public IPC::Listener {
581 public:
582 ListenerSendingAssociatedMessages() {}
583
584 bool OnMessageReceived(const IPC::Message& message) override { return true; }
585
586 void OnChannelConnected(int32_t peer_pid) override {
587 DCHECK(channel_);
588 channel_->GetAssociatedInterfaceSupport()->GetRemoteAssociatedInterface(
589 &driver_);
590
591 // Send a bunch of interleaved messages, alternating between the associated
592 // interface and a legacy IPC::Message.
593 for (int i = 0; i < ListenerWithSimpleAssociatedInterface::kNumMessages;
594 ++i) {
rockot9abe09b2016-08-02 20:57:34595 driver_->ExpectValue(i);
596 SendValue(channel_, i);
rockot7c6bf952016-07-14 00:34:11597 }
598 driver_->RequestQuit(base::Bind(&OnQuitAck));
599 }
600
601 void set_channel(IPC::Channel* channel) { channel_ = channel; }
602
603 private:
604 static void OnQuitAck() { base::MessageLoop::current()->QuitWhenIdle(); }
605
606 IPC::Channel* channel_ = nullptr;
607 IPC::mojom::SimpleTestDriverAssociatedPtr driver_;
608};
609
610TEST_F(IPCChannelMojoTest, SimpleAssociatedInterface) {
sammc4bcc4ed62016-10-27 10:13:59611 Init("SimpleAssociatedInterfaceClient");
rockot7c6bf952016-07-14 00:34:11612
613 ListenerWithSimpleAssociatedInterface listener;
614 CreateChannel(&listener);
615 ASSERT_TRUE(ConnectChannel());
616
617 listener.RegisterInterfaceFactory(channel());
618
619 base::RunLoop().Run();
620 channel()->Close();
621
622 EXPECT_TRUE(WaitForClientShutdown());
623 DestroyChannel();
624}
625
sammc4bcc4ed62016-10-27 10:13:59626DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(SimpleAssociatedInterfaceClient) {
rockot7c6bf952016-07-14 00:34:11627 ListenerSendingAssociatedMessages listener;
628 Connect(&listener);
629 listener.set_channel(channel());
630
631 base::RunLoop().Run();
632
633 Close();
634}
635
rockot8d890f62016-07-14 16:37:14636class ChannelProxyRunner {
637 public:
rockota34707ca2016-07-20 04:28:32638 ChannelProxyRunner(mojo::ScopedMessagePipeHandle handle,
639 bool for_server)
640 : for_server_(for_server),
641 handle_(std::move(handle)),
rockot9abe09b2016-08-02 20:57:34642 io_thread_("ChannelProxyRunner IO thread"),
643 never_signaled_(base::WaitableEvent::ResetPolicy::MANUAL,
644 base::WaitableEvent::InitialState::NOT_SIGNALED) {
rockot8d890f62016-07-14 16:37:14645 }
646
647 void CreateProxy(IPC::Listener* listener) {
648 io_thread_.StartWithOptions(
649 base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
rockot9abe09b2016-08-02 20:57:34650 proxy_ = IPC::SyncChannel::Create(
651 listener, io_thread_.task_runner(), &never_signaled_);
rockot8d890f62016-07-14 16:37:14652 }
rockota34707ca2016-07-20 04:28:32653
rockot10188752016-09-08 18:24:56654 void RunProxy() {
rockota34707ca2016-07-20 04:28:32655 std::unique_ptr<IPC::ChannelFactory> factory;
656 if (for_server_) {
657 factory = IPC::ChannelMojo::CreateServerFactory(
658 std::move(handle_), io_thread_.task_runner());
659 } else {
660 factory = IPC::ChannelMojo::CreateClientFactory(
661 std::move(handle_), io_thread_.task_runner());
662 }
rockot10188752016-09-08 18:24:56663 proxy_->Init(std::move(factory), true);
rockota34707ca2016-07-20 04:28:32664 }
rockot8d890f62016-07-14 16:37:14665
666 IPC::ChannelProxy* proxy() { return proxy_.get(); }
667
668 private:
rockota34707ca2016-07-20 04:28:32669 const bool for_server_;
rockot8d890f62016-07-14 16:37:14670
rockota34707ca2016-07-20 04:28:32671 mojo::ScopedMessagePipeHandle handle_;
rockot8d890f62016-07-14 16:37:14672 base::Thread io_thread_;
673 std::unique_ptr<IPC::ChannelProxy> proxy_;
rockot9abe09b2016-08-02 20:57:34674 base::WaitableEvent never_signaled_;
rockot8d890f62016-07-14 16:37:14675
676 DISALLOW_COPY_AND_ASSIGN(ChannelProxyRunner);
677};
678
679class IPCChannelProxyMojoTest : public IPCChannelMojoTestBase {
680 public:
sammc4bcc4ed62016-10-27 10:13:59681 void Init(const std::string& client_name) {
682 IPCChannelMojoTestBase::Init(client_name);
rockota34707ca2016-07-20 04:28:32683 runner_.reset(new ChannelProxyRunner(TakeHandle(), true));
rockot8d890f62016-07-14 16:37:14684 }
685 void CreateProxy(IPC::Listener* listener) { runner_->CreateProxy(listener); }
rockot10188752016-09-08 18:24:56686 void RunProxy() {
687 runner_->RunProxy();
rockot401fb2c2016-09-06 18:35:57688 }
rockot0e4de5f2016-07-22 21:18:07689 void DestroyProxy() {
690 runner_.reset();
691 base::RunLoop().RunUntilIdle();
692 }
rockot8d890f62016-07-14 16:37:14693
694 IPC::ChannelProxy* proxy() { return runner_->proxy(); }
695
696 private:
rockot8d890f62016-07-14 16:37:14697 std::unique_ptr<ChannelProxyRunner> runner_;
698};
699
700class ListenerWithSimpleProxyAssociatedInterface
701 : public IPC::Listener,
702 public IPC::mojom::SimpleTestDriver {
703 public:
704 static const int kNumMessages;
705
706 ListenerWithSimpleProxyAssociatedInterface() : binding_(this) {}
707
708 ~ListenerWithSimpleProxyAssociatedInterface() override {}
709
710 bool OnMessageReceived(const IPC::Message& message) override {
711 base::PickleIterator iter(message);
rockot9abe09b2016-08-02 20:57:34712 int32_t should_be_expected;
713 EXPECT_TRUE(iter.ReadInt(&should_be_expected));
714 EXPECT_EQ(should_be_expected, next_expected_value_);
rockot8d890f62016-07-14 16:37:14715 num_messages_received_++;
716 return true;
717 }
718
719 void OnChannelError() override {
720 DCHECK(received_quit_);
721 }
722
rockotf62002a2016-09-15 00:08:59723 void OnAssociatedInterfaceRequest(
724 const std::string& interface_name,
725 mojo::ScopedInterfaceEndpointHandle handle) override {
726 DCHECK_EQ(interface_name, IPC::mojom::SimpleTestDriver::Name_);
727 IPC::mojom::SimpleTestDriverAssociatedRequest request;
728 request.Bind(std::move(handle));
729 binding_.Bind(std::move(request));
rockot8d890f62016-07-14 16:37:14730 }
731
732 bool received_all_messages() const {
733 return num_messages_received_ == kNumMessages && received_quit_;
734 }
735
736 private:
737 // IPC::mojom::SimpleTestDriver:
rockot9abe09b2016-08-02 20:57:34738 void ExpectValue(int32_t value) override {
739 next_expected_value_ = value;
740 }
741
742 void GetExpectedValue(const GetExpectedValueCallback& callback) override {
743 callback.Run(next_expected_value_);
744 }
745
746 void RequestValue(const RequestValueCallback& callback) override {
747 NOTREACHED();
rockot8d890f62016-07-14 16:37:14748 }
749
750 void RequestQuit(const RequestQuitCallback& callback) override {
751 received_quit_ = true;
752 callback.Run();
rockot0e4de5f2016-07-22 21:18:07753 binding_.Close();
rockot8d890f62016-07-14 16:37:14754 base::MessageLoop::current()->QuitWhenIdle();
755 }
756
757 void BindRequest(IPC::mojom::SimpleTestDriverAssociatedRequest request) {
758 DCHECK(!binding_.is_bound());
759 binding_.Bind(std::move(request));
760 }
761
rockot9abe09b2016-08-02 20:57:34762 int32_t next_expected_value_ = 0;
rockot8d890f62016-07-14 16:37:14763 int num_messages_received_ = 0;
764 bool received_quit_ = false;
765
766 mojo::AssociatedBinding<IPC::mojom::SimpleTestDriver> binding_;
767};
768
769const int ListenerWithSimpleProxyAssociatedInterface::kNumMessages = 1000;
770
771TEST_F(IPCChannelProxyMojoTest, ProxyThreadAssociatedInterface) {
sammc4bcc4ed62016-10-27 10:13:59772 Init("ProxyThreadAssociatedInterfaceClient");
rockot8d890f62016-07-14 16:37:14773
774 ListenerWithSimpleProxyAssociatedInterface listener;
775 CreateProxy(&listener);
rockot8d890f62016-07-14 16:37:14776 RunProxy();
777
778 base::RunLoop().Run();
779
780 EXPECT_TRUE(WaitForClientShutdown());
781 EXPECT_TRUE(listener.received_all_messages());
782
rockot0e4de5f2016-07-22 21:18:07783 DestroyProxy();
rockot8d890f62016-07-14 16:37:14784}
785
786class ChannelProxyClient {
787 public:
788 void Init(mojo::ScopedMessagePipeHandle handle) {
rockota34707ca2016-07-20 04:28:32789 runner_.reset(new ChannelProxyRunner(std::move(handle), false));
rockot8d890f62016-07-14 16:37:14790 }
rockot9abe09b2016-08-02 20:57:34791
rockot8d890f62016-07-14 16:37:14792 void CreateProxy(IPC::Listener* listener) { runner_->CreateProxy(listener); }
rockot9abe09b2016-08-02 20:57:34793
rockot10188752016-09-08 18:24:56794 void RunProxy() { runner_->RunProxy(); }
rockot9abe09b2016-08-02 20:57:34795
rockot0e4de5f2016-07-22 21:18:07796 void DestroyProxy() {
797 runner_.reset();
798 base::RunLoop().RunUntilIdle();
799 }
rockot8d890f62016-07-14 16:37:14800
rockot9abe09b2016-08-02 20:57:34801 void RequestQuitAndWaitForAck(IPC::mojom::SimpleTestDriver* driver) {
802 base::RunLoop loop;
803 driver->RequestQuit(loop.QuitClosure());
804 loop.Run();
805 }
806
rockot8d890f62016-07-14 16:37:14807 IPC::ChannelProxy* proxy() { return runner_->proxy(); }
808
809 private:
810 base::MessageLoop message_loop_;
811 std::unique_ptr<ChannelProxyRunner> runner_;
812};
813
rockot0e4de5f2016-07-22 21:18:07814class DummyListener : public IPC::Listener {
rockot8d890f62016-07-14 16:37:14815 public:
rockot8d890f62016-07-14 16:37:14816 // IPC::Listener
817 bool OnMessageReceived(const IPC::Message& message) override { return true; }
rockot8d890f62016-07-14 16:37:14818};
819
sammc4bcc4ed62016-10-27 10:13:59820DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
821 ProxyThreadAssociatedInterfaceClient,
822 ChannelProxyClient) {
rockot0e4de5f2016-07-22 21:18:07823 DummyListener listener;
rockot8d890f62016-07-14 16:37:14824 CreateProxy(&listener);
825 RunProxy();
rockot8d890f62016-07-14 16:37:14826
827 // Send a bunch of interleaved messages, alternating between the associated
828 // interface and a legacy IPC::Message.
829 IPC::mojom::SimpleTestDriverAssociatedPtr driver;
830 proxy()->GetRemoteAssociatedInterface(&driver);
831 for (int i = 0; i < ListenerWithSimpleProxyAssociatedInterface::kNumMessages;
832 ++i) {
rockot9abe09b2016-08-02 20:57:34833 driver->ExpectValue(i);
834 SendValue(proxy(), i);
rockot8d890f62016-07-14 16:37:14835 }
836 driver->RequestQuit(base::MessageLoop::QuitWhenIdleClosure());
837 base::RunLoop().Run();
rockot0e4de5f2016-07-22 21:18:07838
839 DestroyProxy();
rockot8d890f62016-07-14 16:37:14840}
841
rockot401fb2c2016-09-06 18:35:57842class ListenerWithIndirectProxyAssociatedInterface
843 : public IPC::Listener,
844 public IPC::mojom::IndirectTestDriver,
845 public IPC::mojom::PingReceiver {
846 public:
847 ListenerWithIndirectProxyAssociatedInterface()
848 : driver_binding_(this), ping_receiver_binding_(this) {}
849 ~ListenerWithIndirectProxyAssociatedInterface() override {}
850
851 bool OnMessageReceived(const IPC::Message& message) override { return true; }
852
853 void RegisterInterfaceFactory(IPC::ChannelProxy* proxy) {
854 proxy->AddAssociatedInterface(
855 base::Bind(&ListenerWithIndirectProxyAssociatedInterface::BindRequest,
856 base::Unretained(this)));
857 }
858
859 void set_ping_handler(const base::Closure& handler) {
860 ping_handler_ = handler;
861 }
862
863 private:
864 // IPC::mojom::IndirectTestDriver:
865 void GetPingReceiver(
866 IPC::mojom::PingReceiverAssociatedRequest request) override {
867 ping_receiver_binding_.Bind(std::move(request));
868 }
869
870 // IPC::mojom::PingReceiver:
871 void Ping(const PingCallback& callback) override {
872 callback.Run();
873 ping_handler_.Run();
874 }
875
876 void BindRequest(IPC::mojom::IndirectTestDriverAssociatedRequest request) {
877 DCHECK(!driver_binding_.is_bound());
878 driver_binding_.Bind(std::move(request));
879 }
880
881 mojo::AssociatedBinding<IPC::mojom::IndirectTestDriver> driver_binding_;
882 mojo::AssociatedBinding<IPC::mojom::PingReceiver> ping_receiver_binding_;
883
884 base::Closure ping_handler_;
885};
886
887TEST_F(IPCChannelProxyMojoTest, ProxyThreadAssociatedInterfaceIndirect) {
888 // Tests that we can pipeline interface requests and subsequent messages
889 // targeting proxy thread bindings, and the channel will still dispatch
890 // messages appropriately.
891
sammc4bcc4ed62016-10-27 10:13:59892 Init("ProxyThreadAssociatedInterfaceIndirectClient");
rockot401fb2c2016-09-06 18:35:57893
894 ListenerWithIndirectProxyAssociatedInterface listener;
895 CreateProxy(&listener);
896 listener.RegisterInterfaceFactory(proxy());
897 RunProxy();
898
899 base::RunLoop loop;
900 listener.set_ping_handler(loop.QuitClosure());
901 loop.Run();
902
903 EXPECT_TRUE(WaitForClientShutdown());
904
905 DestroyProxy();
906}
907
sammc4bcc4ed62016-10-27 10:13:59908DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
rockot401fb2c2016-09-06 18:35:57909 ProxyThreadAssociatedInterfaceIndirectClient,
910 ChannelProxyClient) {
911 DummyListener listener;
912 CreateProxy(&listener);
913 RunProxy();
914
915 // Use an interface requested via another interface. On the remote end both
916 // interfaces are bound on the proxy thread. This ensures that the Ping
917 // message we send will still be dispatched properly even though the remote
918 // endpoint may not have been bound yet by the time the message is initially
919 // processed on the IO thread.
920 IPC::mojom::IndirectTestDriverAssociatedPtr driver;
921 IPC::mojom::PingReceiverAssociatedPtr ping_receiver;
922 proxy()->GetRemoteAssociatedInterface(&driver);
923 driver->GetPingReceiver(
924 mojo::GetProxy(&ping_receiver, driver.associated_group()));
925
926 base::RunLoop loop;
927 ping_receiver->Ping(loop.QuitClosure());
928 loop.Run();
929
930 DestroyProxy();
931}
932
rockot9abe09b2016-08-02 20:57:34933class ListenerWithSyncAssociatedInterface
934 : public IPC::Listener,
935 public IPC::mojom::SimpleTestDriver {
936 public:
937 ListenerWithSyncAssociatedInterface() : binding_(this) {}
938 ~ListenerWithSyncAssociatedInterface() override {}
939
940 void set_sync_sender(IPC::Sender* sync_sender) { sync_sender_ = sync_sender; }
941
942 void RegisterInterfaceFactory(IPC::ChannelProxy* proxy) {
943 proxy->AddAssociatedInterface(
944 base::Bind(&ListenerWithSyncAssociatedInterface::BindRequest,
945 base::Unretained(this)));
946 }
947
948 void RunUntilQuitRequested() {
949 base::RunLoop loop;
950 quit_closure_ = loop.QuitClosure();
951 loop.Run();
952 }
953
954 void CloseBinding() { binding_.Close(); }
955
956 void set_response_value(int32_t response) {
957 response_value_ = response;
958 }
959
960 private:
961 // IPC::mojom::SimpleTestDriver:
962 void ExpectValue(int32_t value) override {
963 next_expected_value_ = value;
964 }
965
966 void GetExpectedValue(const GetExpectedValueCallback& callback) override {
967 callback.Run(next_expected_value_);
968 }
969
970 void RequestValue(const RequestValueCallback& callback) override {
971 callback.Run(response_value_);
972 }
973
974 void RequestQuit(const RequestQuitCallback& callback) override {
975 quit_closure_.Run();
976 callback.Run();
977 }
978
979 // IPC::Listener:
980 bool OnMessageReceived(const IPC::Message& message) override {
981 EXPECT_EQ(0u, message.type());
982 EXPECT_TRUE(message.is_sync());
983 EXPECT_TRUE(message.should_unblock());
984 std::unique_ptr<IPC::Message> reply(
985 IPC::SyncMessage::GenerateReply(&message));
986 reply->WriteInt(response_value_);
987 DCHECK(sync_sender_);
988 EXPECT_TRUE(sync_sender_->Send(reply.release()));
989 return true;
990 }
991
992 void BindRequest(IPC::mojom::SimpleTestDriverAssociatedRequest request) {
993 DCHECK(!binding_.is_bound());
994 binding_.Bind(std::move(request));
995 }
996
997 IPC::Sender* sync_sender_ = nullptr;
998 int32_t next_expected_value_ = 0;
999 int32_t response_value_ = 0;
1000 base::Closure quit_closure_;
1001
1002 mojo::AssociatedBinding<IPC::mojom::SimpleTestDriver> binding_;
1003};
1004
1005class SyncReplyReader : public IPC::MessageReplyDeserializer {
1006 public:
1007 explicit SyncReplyReader(int32_t* storage) : storage_(storage) {}
1008 ~SyncReplyReader() override {}
1009
1010 private:
1011 // IPC::MessageReplyDeserializer:
1012 bool SerializeOutputParameters(const IPC::Message& message,
1013 base::PickleIterator iter) override {
1014 if (!iter.ReadInt(storage_))
1015 return false;
1016 return true;
1017 }
1018
1019 int32_t* storage_;
1020
1021 DISALLOW_COPY_AND_ASSIGN(SyncReplyReader);
1022};
1023
1024TEST_F(IPCChannelProxyMojoTest, SyncAssociatedInterface) {
sammc4bcc4ed62016-10-27 10:13:591025 Init("SyncAssociatedInterface");
rockot9abe09b2016-08-02 20:57:341026
1027 ListenerWithSyncAssociatedInterface listener;
1028 CreateProxy(&listener);
1029 listener.set_sync_sender(proxy());
1030 listener.RegisterInterfaceFactory(proxy());
1031 RunProxy();
1032
1033 // Run the client's simple sanity check to completion.
1034 listener.RunUntilQuitRequested();
1035
1036 // Verify that we can send a sync IPC and service an incoming sync request
1037 // while waiting on it
1038 listener.set_response_value(42);
1039 IPC::mojom::SimpleTestClientAssociatedPtr client;
1040 proxy()->GetRemoteAssociatedInterface(&client);
1041 int32_t received_value;
1042 EXPECT_TRUE(client->RequestValue(&received_value));
1043 EXPECT_EQ(42, received_value);
1044
1045 // Do it again. This time the client will send a classical sync IPC to us
1046 // while we wait.
1047 received_value = 0;
1048 EXPECT_TRUE(client->RequestValue(&received_value));
1049 EXPECT_EQ(42, received_value);
1050
1051 // Now make a classical sync IPC request to the client. It will send a
1052 // sync associated interface message to us while we wait.
1053 received_value = 0;
1054 std::unique_ptr<IPC::SyncMessage> request(
1055 new IPC::SyncMessage(0, 0, IPC::Message::PRIORITY_NORMAL,
1056 new SyncReplyReader(&received_value)));
1057 EXPECT_TRUE(proxy()->Send(request.release()));
1058 EXPECT_EQ(42, received_value);
1059
1060 listener.CloseBinding();
1061 EXPECT_TRUE(WaitForClientShutdown());
1062
1063 DestroyProxy();
1064}
1065
1066class SimpleTestClientImpl : public IPC::mojom::SimpleTestClient,
1067 public IPC::Listener {
1068 public:
1069 SimpleTestClientImpl() : binding_(this) {}
1070
1071 void set_driver(IPC::mojom::SimpleTestDriver* driver) { driver_ = driver; }
1072 void set_sync_sender(IPC::Sender* sync_sender) { sync_sender_ = sync_sender; }
1073
1074 void BindRequest(IPC::mojom::SimpleTestClientAssociatedRequest request) {
1075 DCHECK(!binding_.is_bound());
1076 binding_.Bind(std::move(request));
1077 }
1078
1079 void WaitForValueRequest() {
1080 run_loop_.reset(new base::RunLoop);
1081 run_loop_->Run();
1082 }
1083
1084 void UseSyncSenderForRequest(bool use_sync_sender) {
1085 use_sync_sender_ = use_sync_sender;
1086 }
1087
1088 private:
1089 // IPC::mojom::SimpleTestClient:
1090 void RequestValue(const RequestValueCallback& callback) override {
1091 int32_t response = 0;
1092 if (use_sync_sender_) {
1093 std::unique_ptr<IPC::SyncMessage> reply(new IPC::SyncMessage(
1094 0, 0, IPC::Message::PRIORITY_NORMAL, new SyncReplyReader(&response)));
1095 EXPECT_TRUE(sync_sender_->Send(reply.release()));
1096 } else {
1097 DCHECK(driver_);
1098 EXPECT_TRUE(driver_->RequestValue(&response));
1099 }
1100
1101 callback.Run(response);
1102
1103 DCHECK(run_loop_);
1104 run_loop_->Quit();
1105 }
1106
1107 // IPC::Listener:
1108 bool OnMessageReceived(const IPC::Message& message) override {
1109 int32_t response;
1110 DCHECK(driver_);
1111 EXPECT_TRUE(driver_->RequestValue(&response));
1112 std::unique_ptr<IPC::Message> reply(
1113 IPC::SyncMessage::GenerateReply(&message));
1114 reply->WriteInt(response);
1115 EXPECT_TRUE(sync_sender_->Send(reply.release()));
1116
1117 DCHECK(run_loop_);
1118 run_loop_->Quit();
1119 return true;
1120 }
1121
1122 bool use_sync_sender_ = false;
1123 mojo::AssociatedBinding<IPC::mojom::SimpleTestClient> binding_;
1124 IPC::Sender* sync_sender_ = nullptr;
1125 IPC::mojom::SimpleTestDriver* driver_ = nullptr;
1126 std::unique_ptr<base::RunLoop> run_loop_;
1127
1128 DISALLOW_COPY_AND_ASSIGN(SimpleTestClientImpl);
1129};
1130
sammc4bcc4ed62016-10-27 10:13:591131DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(SyncAssociatedInterface,
1132 ChannelProxyClient) {
rockot9abe09b2016-08-02 20:57:341133 SimpleTestClientImpl client_impl;
1134 CreateProxy(&client_impl);
1135 client_impl.set_sync_sender(proxy());
1136 proxy()->AddAssociatedInterface(base::Bind(&SimpleTestClientImpl::BindRequest,
1137 base::Unretained(&client_impl)));
1138 RunProxy();
1139
1140 IPC::mojom::SimpleTestDriverAssociatedPtr driver;
1141 proxy()->GetRemoteAssociatedInterface(&driver);
1142 client_impl.set_driver(driver.get());
1143
1144 // Simple sync message sanity check.
1145 driver->ExpectValue(42);
1146 int32_t expected_value = 0;
1147 EXPECT_TRUE(driver->GetExpectedValue(&expected_value));
1148 EXPECT_EQ(42, expected_value);
1149 RequestQuitAndWaitForAck(driver.get());
1150
1151 // Wait for the test driver to perform a sync call test with our own sync
1152 // associated interface message nested inside.
1153 client_impl.UseSyncSenderForRequest(false);
1154 client_impl.WaitForValueRequest();
1155
1156 // Wait for the test driver to perform a sync call test with our own classical
1157 // sync IPC nested inside.
1158 client_impl.UseSyncSenderForRequest(true);
1159 client_impl.WaitForValueRequest();
1160
1161 // Wait for the test driver to perform a classical sync IPC request, with our
1162 // own sync associated interface message nested inside.
1163 client_impl.UseSyncSenderForRequest(false);
1164 client_impl.WaitForValueRequest();
1165
1166 DestroyProxy();
1167}
1168
rockot10188752016-09-08 18:24:561169TEST_F(IPCChannelProxyMojoTest, Pause) {
1170 // Ensures that pausing a channel elicits the expected behavior when sending
1171 // messages, unpausing, sending more messages, and then manually flushing.
1172 // Specifically a sequence like:
rockot401fb2c2016-09-06 18:35:571173 //
1174 // Connect()
1175 // Send(A)
rockot10188752016-09-08 18:24:561176 // Pause()
rockot401fb2c2016-09-06 18:35:571177 // Send(B)
rockot401fb2c2016-09-06 18:35:571178 // Send(C)
rockot10188752016-09-08 18:24:561179 // Unpause(false)
1180 // Send(D)
1181 // Send(E)
rockot401fb2c2016-09-06 18:35:571182 // Flush()
1183 //
rockot10188752016-09-08 18:24:561184 // must result in the other end receiving messages A, D, E, B, D; in that
rockot401fb2c2016-09-06 18:35:571185 // order.
1186 //
1187 // This behavior is required by some consumers of IPC::Channel, and it is not
1188 // sufficient to leave this up to the consumer to implement since associated
1189 // interface requests and messages also need to be queued according to the
1190 // same policy.
sammc4bcc4ed62016-10-27 10:13:591191 Init("CreatePausedClient");
rockot401fb2c2016-09-06 18:35:571192
1193 DummyListener listener;
1194 CreateProxy(&listener);
rockot10188752016-09-08 18:24:561195 RunProxy();
1196
1197 // This message must be sent immediately since the channel is unpaused.
1198 SendValue(proxy(), 1);
1199
1200 proxy()->Pause();
rockot401fb2c2016-09-06 18:35:571201
1202 // These messages must be queued internally since the channel is paused.
rockot401fb2c2016-09-06 18:35:571203 SendValue(proxy(), 2);
rockot10188752016-09-08 18:24:561204 SendValue(proxy(), 3);
rockot401fb2c2016-09-06 18:35:571205
1206 proxy()->Unpause(false /* flush */);
1207
1208 // These messages must be sent immediately since the channel is unpaused.
rockot401fb2c2016-09-06 18:35:571209 SendValue(proxy(), 4);
rockot10188752016-09-08 18:24:561210 SendValue(proxy(), 5);
rockot401fb2c2016-09-06 18:35:571211
1212 // Now we flush the previously queued messages.
1213 proxy()->Flush();
1214
1215 EXPECT_TRUE(WaitForClientShutdown());
1216 DestroyProxy();
1217}
1218
1219class ExpectValueSequenceListener : public IPC::Listener {
1220 public:
1221 explicit ExpectValueSequenceListener(std::queue<int32_t>* expected_values)
1222 : expected_values_(expected_values) {}
1223 ~ExpectValueSequenceListener() override {}
1224
1225 // IPC::Listener:
1226 bool OnMessageReceived(const IPC::Message& message) override {
1227 DCHECK(!expected_values_->empty());
1228 base::PickleIterator iter(message);
1229 int32_t should_be_expected;
1230 EXPECT_TRUE(iter.ReadInt(&should_be_expected));
1231 EXPECT_EQ(expected_values_->front(), should_be_expected);
1232 expected_values_->pop();
1233 if (expected_values_->empty())
1234 base::MessageLoop::current()->QuitWhenIdle();
1235 return true;
1236 }
1237
1238 private:
1239 std::queue<int32_t>* expected_values_;
1240
1241 DISALLOW_COPY_AND_ASSIGN(ExpectValueSequenceListener);
1242};
1243
sammc4bcc4ed62016-10-27 10:13:591244DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(CreatePausedClient,
1245 ChannelProxyClient) {
rockot401fb2c2016-09-06 18:35:571246 std::queue<int32_t> expected_values;
1247 ExpectValueSequenceListener listener(&expected_values);
1248 CreateProxy(&listener);
rockot401fb2c2016-09-06 18:35:571249 expected_values.push(1);
rockot10188752016-09-08 18:24:561250 expected_values.push(4);
1251 expected_values.push(5);
rockot401fb2c2016-09-06 18:35:571252 expected_values.push(2);
rockot10188752016-09-08 18:24:561253 expected_values.push(3);
rockot401fb2c2016-09-06 18:35:571254 RunProxy();
1255 base::RunLoop().Run();
1256 EXPECT_TRUE(expected_values.empty());
1257 DestroyProxy();
1258}
1259
[email protected]64860882014-08-04 23:44:171260#if defined(OS_POSIX)
rockot8d890f62016-07-14 16:37:141261
[email protected]64860882014-08-04 23:44:171262class ListenerThatExpectsFile : public IPC::Listener {
1263 public:
sammc57ed9f982016-03-10 06:28:351264 ListenerThatExpectsFile() : sender_(NULL) {}
[email protected]64860882014-08-04 23:44:171265
dchengfe61fca2014-10-22 02:29:521266 ~ListenerThatExpectsFile() override {}
[email protected]64860882014-08-04 23:44:171267
dchengfe61fca2014-10-22 02:29:521268 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:251269 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:301270 HandleSendingHelper::ReadReceivedFile(message, &iter);
[email protected]64860882014-08-04 23:44:171271 ListenerThatExpectsOK::SendOK(sender_);
1272 return true;
1273 }
1274
amistry6c70caea2016-06-09 03:08:291275 void OnChannelError() override {
1276 base::MessageLoop::current()->QuitWhenIdle();
1277 }
[email protected]64860882014-08-04 23:44:171278
[email protected]64860882014-08-04 23:44:171279 void set_sender(IPC::Sender* sender) { sender_ = sender; }
1280
1281 private:
1282 IPC::Sender* sender_;
1283};
1284
amistry0027a0952016-05-03 00:52:471285TEST_F(IPCChannelMojoTest, SendPlatformHandle) {
sammc4bcc4ed62016-10-27 10:13:591286 Init("IPCChannelMojoTestSendPlatformHandleClient");
[email protected]64860882014-08-04 23:44:171287
1288 ListenerThatExpectsOK listener;
morrita373af03b2014-09-09 19:35:241289 CreateChannel(&listener);
[email protected]64860882014-08-04 23:44:171290 ASSERT_TRUE(ConnectChannel());
[email protected]64860882014-08-04 23:44:171291
amistry20e2b1d62016-06-23 06:12:351292 base::ScopedTempDir temp_dir;
1293 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
vabr16e5f602016-09-15 18:14:001294 base::File file(HandleSendingHelper::GetSendingFilePath(temp_dir.GetPath()),
[email protected]64860882014-08-04 23:44:171295 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
morrita81b17e02015-02-06 00:58:301296 base::File::FLAG_READ);
1297 HandleSendingHelper::WriteFileThenSend(channel(), file);
fdoray8e32586852016-06-22 19:56:161298 base::RunLoop().Run();
[email protected]64860882014-08-04 23:44:171299
sammc57ed9f982016-03-10 06:28:351300 channel()->Close();
[email protected]64860882014-08-04 23:44:171301
1302 EXPECT_TRUE(WaitForClientShutdown());
1303 DestroyChannel();
1304}
1305
sammc4bcc4ed62016-10-27 10:13:591306DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
1307 IPCChannelMojoTestSendPlatformHandleClient) {
[email protected]64860882014-08-04 23:44:171308 ListenerThatExpectsFile listener;
sammc57ed9f982016-03-10 06:28:351309 Connect(&listener);
1310 listener.set_sender(channel());
[email protected]64860882014-08-04 23:44:171311
fdoray8e32586852016-06-22 19:56:161312 base::RunLoop().Run();
[email protected]64860882014-08-04 23:44:171313
sammc57ed9f982016-03-10 06:28:351314 Close();
[email protected]64860882014-08-04 23:44:171315}
morrita81b17e02015-02-06 00:58:301316
1317class ListenerThatExpectsFileAndPipe : public IPC::Listener {
1318 public:
1319 ListenerThatExpectsFileAndPipe() : sender_(NULL) {}
1320
1321 ~ListenerThatExpectsFileAndPipe() override {}
1322
1323 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:251324 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:301325 HandleSendingHelper::ReadReceivedFile(message, &iter);
1326 HandleSendingHelper::ReadReceivedPipe(message, &iter);
morrita81b17e02015-02-06 00:58:301327 ListenerThatExpectsOK::SendOK(sender_);
1328 return true;
1329 }
1330
amistry6c70caea2016-06-09 03:08:291331 void OnChannelError() override {
1332 base::MessageLoop::current()->QuitWhenIdle();
1333 }
morrita81b17e02015-02-06 00:58:301334
1335 void set_sender(IPC::Sender* sender) { sender_ = sender; }
1336
1337 private:
1338 IPC::Sender* sender_;
1339};
1340
amistry0027a0952016-05-03 00:52:471341TEST_F(IPCChannelMojoTest, SendPlatformHandleAndPipe) {
sammc4bcc4ed62016-10-27 10:13:591342 Init("IPCChannelMojoTestSendPlatformHandleAndPipeClient");
morrita81b17e02015-02-06 00:58:301343
1344 ListenerThatExpectsOK listener;
1345 CreateChannel(&listener);
1346 ASSERT_TRUE(ConnectChannel());
morrita81b17e02015-02-06 00:58:301347
amistry20e2b1d62016-06-23 06:12:351348 base::ScopedTempDir temp_dir;
1349 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
vabr16e5f602016-09-15 18:14:001350 base::File file(HandleSendingHelper::GetSendingFilePath(temp_dir.GetPath()),
morrita81b17e02015-02-06 00:58:301351 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
1352 base::File::FLAG_READ);
1353 TestingMessagePipe pipe;
1354 HandleSendingHelper::WriteFileAndPipeThenSend(channel(), file, &pipe);
1355
fdoray8e32586852016-06-22 19:56:161356 base::RunLoop().Run();
sammc57ed9f982016-03-10 06:28:351357 channel()->Close();
morrita81b17e02015-02-06 00:58:301358
1359 EXPECT_TRUE(WaitForClientShutdown());
1360 DestroyChannel();
1361}
1362
sammc57ed9f982016-03-10 06:28:351363DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
sammc4bcc4ed62016-10-27 10:13:591364 IPCChannelMojoTestSendPlatformHandleAndPipeClient) {
morrita81b17e02015-02-06 00:58:301365 ListenerThatExpectsFileAndPipe listener;
sammc57ed9f982016-03-10 06:28:351366 Connect(&listener);
1367 listener.set_sender(channel());
morrita81b17e02015-02-06 00:58:301368
fdoray8e32586852016-06-22 19:56:161369 base::RunLoop().Run();
morrita81b17e02015-02-06 00:58:301370
sammc57ed9f982016-03-10 06:28:351371 Close();
morrita81b17e02015-02-06 00:58:301372}
1373
rockot7c6bf952016-07-14 00:34:111374#endif // defined(OS_POSIX)
[email protected]64860882014-08-04 23:44:171375
morrita0bd20bd2015-02-25 20:11:271376#if defined(OS_LINUX)
1377
1378const base::ProcessId kMagicChildId = 54321;
1379
1380class ListenerThatVerifiesPeerPid : public IPC::Listener {
1381 public:
tfarina10a5c062015-09-04 18:47:571382 void OnChannelConnected(int32_t peer_pid) override {
morrita0bd20bd2015-02-25 20:11:271383 EXPECT_EQ(peer_pid, kMagicChildId);
ki.stfua21ed8c2015-10-12 17:26:001384 base::MessageLoop::current()->QuitWhenIdle();
morrita0bd20bd2015-02-25 20:11:271385 }
1386
1387 bool OnMessageReceived(const IPC::Message& message) override {
1388 NOTREACHED();
1389 return true;
1390 }
1391};
1392
sammc57ed9f982016-03-10 06:28:351393TEST_F(IPCChannelMojoTest, VerifyGlobalPid) {
sammc4bcc4ed62016-10-27 10:13:591394 Init("IPCChannelMojoTestVerifyGlobalPidClient");
morrita0bd20bd2015-02-25 20:11:271395
1396 ListenerThatVerifiesPeerPid listener;
1397 CreateChannel(&listener);
1398 ASSERT_TRUE(ConnectChannel());
morrita0bd20bd2015-02-25 20:11:271399
fdoray6ef45cf2016-08-25 15:36:371400 base::RunLoop().Run();
rockotcbca72f2015-03-03 16:31:041401 channel()->Close();
morrita0bd20bd2015-02-25 20:11:271402
1403 EXPECT_TRUE(WaitForClientShutdown());
1404 DestroyChannel();
1405}
1406
sammc4bcc4ed62016-10-27 10:13:591407DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestVerifyGlobalPidClient) {
morrita0bd20bd2015-02-25 20:11:271408 IPC::Channel::SetGlobalPid(kMagicChildId);
1409 ListenerThatQuits listener;
sammc57ed9f982016-03-10 06:28:351410 Connect(&listener);
morrita0bd20bd2015-02-25 20:11:271411
fdoray6ef45cf2016-08-25 15:36:371412 base::RunLoop().Run();
morrita0bd20bd2015-02-25 20:11:271413
sammc57ed9f982016-03-10 06:28:351414 Close();
morrita0bd20bd2015-02-25 20:11:271415}
1416
sammc57ed9f982016-03-10 06:28:351417#endif // OS_LINUX
morrita0bd20bd2015-02-25 20:11:271418
[email protected]64860882014-08-04 23:44:171419} // namespace