blob: d5be36802e2e6373de04790a9cc52c9203bc891b [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"
sammc5c8a6c62017-02-04 01:33:3815#include "base/callback_helpers.h"
Brett Wilsona62d9c02017-09-20 20:53:2016#include "base/containers/queue.h"
[email protected]64860882014-08-04 23:44:1717#include "base/files/file.h"
amistry20e2b1d62016-06-23 06:12:3518#include "base/files/scoped_temp_dir.h"
skyostile687bdff2015-05-12 11:29:2119#include "base/location.h"
rockot8d890f62016-07-14 16:37:1420#include "base/macros.h"
Alexandr Ilind497eee2018-04-19 22:50:5421#include "base/memory/platform_shared_memory_region.h"
Wez831ae412017-08-30 00:29:3622#include "base/memory/shared_memory.h"
Alexandr Ilind497eee2018-04-19 22:50:5423#include "base/memory/shared_memory_mapping.h"
rockot8d890f62016-07-14 16:37:1424#include "base/message_loop/message_loop.h"
[email protected]64860882014-08-04 23:44:1725#include "base/path_service.h"
26#include "base/pickle.h"
rockotcbca72f2015-03-03 16:31:0427#include "base/run_loop.h"
skyostile687bdff2015-05-12 11:29:2128#include "base/single_thread_task_runner.h"
rockot7c6bf952016-07-14 00:34:1129#include "base/strings/stringprintf.h"
rockot9abe09b2016-08-02 20:57:3430#include "base/synchronization/waitable_event.h"
sammc57ed9f982016-03-10 06:28:3531#include "base/test/test_io_thread.h"
Alexandr Ilind497eee2018-04-19 22:50:5432#include "base/test/test_shared_memory_util.h"
morrita0bd20bd2015-02-25 20:11:2733#include "base/test/test_timeouts.h"
[email protected]64860882014-08-04 23:44:1734#include "base/threading/thread.h"
gabf08ccc02016-05-11 18:51:1135#include "base/threading/thread_task_runner_handle.h"
avi246998d82015-12-22 02:39:0436#include "build/build_config.h"
[email protected]64860882014-08-04 23:44:1737#include "ipc/ipc_message.h"
Wez831ae412017-08-30 00:29:3638#include "ipc/ipc_message_utils.h"
amistryd4aa70d2016-06-23 07:52:3739#include "ipc/ipc_mojo_handle_attachment.h"
40#include "ipc/ipc_mojo_message_helper.h"
41#include "ipc/ipc_mojo_param_traits.h"
rockot9abe09b2016-08-02 20:57:3442#include "ipc/ipc_sync_channel.h"
43#include "ipc/ipc_sync_message.h"
rockot7c6bf952016-07-14 00:34:1144#include "ipc/ipc_test.mojom.h"
[email protected]64860882014-08-04 23:44:1745#include "ipc/ipc_test_base.h"
46#include "ipc/ipc_test_channel_listener.h"
rockota9d566a2017-03-17 19:36:1547#include "mojo/public/cpp/system/wait.h"
sammc57ed9f982016-03-10 06:28:3548#include "testing/gtest/include/gtest/gtest.h"
[email protected]64860882014-08-04 23:44:1749
50#if defined(OS_POSIX)
51#include "base/file_descriptor_posix.h"
morrita1aa788c2015-01-31 05:45:4252#include "ipc/ipc_platform_file_attachment_posix.h"
[email protected]64860882014-08-04 23:44:1753#endif
54
55namespace {
56
rockot7c6bf952016-07-14 00:34:1157void SendString(IPC::Sender* sender, const std::string& str) {
58 IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
59 message->WriteString(str);
60 ASSERT_TRUE(sender->Send(message));
61}
62
rockot9abe09b2016-08-02 20:57:3463void SendValue(IPC::Sender* sender, int32_t value) {
64 IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
65 message->WriteInt(value);
66 ASSERT_TRUE(sender->Send(message));
67}
68
[email protected]64860882014-08-04 23:44:1769class ListenerThatExpectsOK : public IPC::Listener {
70 public:
Wez831ae412017-08-30 00:29:3671 ListenerThatExpectsOK(base::Closure quit_closure)
72 : received_ok_(false), quit_closure_(quit_closure) {}
[email protected]64860882014-08-04 23:44:1773
Chris Watkins2d879af2017-11-30 02:11:5974 ~ListenerThatExpectsOK() override = default;
[email protected]64860882014-08-04 23:44:1775
dchengfe61fca2014-10-22 02:29:5276 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:2577 base::PickleIterator iter(message);
[email protected]64860882014-08-04 23:44:1778 std::string should_be_ok;
79 EXPECT_TRUE(iter.ReadString(&should_be_ok));
80 EXPECT_EQ(should_be_ok, "OK");
[email protected]e5c27752014-08-08 21:45:1381 received_ok_ = true;
Wez831ae412017-08-30 00:29:3682 quit_closure_.Run();
[email protected]64860882014-08-04 23:44:1783 return true;
84 }
85
dchengfe61fca2014-10-22 02:29:5286 void OnChannelError() override {
[email protected]e5c27752014-08-08 21:45:1387 // The connection should be healthy while the listener is waiting
88 // message. An error can occur after that because the peer
89 // process dies.
Wezd95d48042018-02-26 20:50:4790 CHECK(received_ok_);
[email protected]64860882014-08-04 23:44:1791 }
92
rockot7c6bf952016-07-14 00:34:1193 static void SendOK(IPC::Sender* sender) { SendString(sender, "OK"); }
[email protected]e5c27752014-08-08 21:45:1394
95 private:
96 bool received_ok_;
Wez831ae412017-08-30 00:29:3697 base::Closure quit_closure_;
98};
99
100class TestListenerBase : public IPC::Listener {
101 public:
102 TestListenerBase(base::Closure quit_closure) : quit_closure_(quit_closure) {}
103
Chris Watkins2d879af2017-11-30 02:11:59104 ~TestListenerBase() override = default;
Wez831ae412017-08-30 00:29:36105
106 void OnChannelError() override { quit_closure_.Run(); }
107
108 void set_sender(IPC::Sender* sender) { sender_ = sender; }
109 IPC::Sender* sender() const { return sender_; }
110 base::Closure quit_closure() const { return quit_closure_; }
111
112 private:
113 IPC::Sender* sender_ = nullptr;
114 base::Closure quit_closure_;
[email protected]64860882014-08-04 23:44:17115};
116
sammc4bcc4ed62016-10-27 10:13:59117using IPCChannelMojoTest = IPCChannelMojoTestBase;
rockotcbca72f2015-03-03 16:31:04118
[email protected]64860882014-08-04 23:44:17119class TestChannelListenerWithExtraExpectations
120 : public IPC::TestChannelListener {
121 public:
sammc57ed9f982016-03-10 06:28:35122 TestChannelListenerWithExtraExpectations() : is_connected_called_(false) {}
[email protected]64860882014-08-04 23:44:17123
tfarina10a5c062015-09-04 18:47:57124 void OnChannelConnected(int32_t peer_pid) override {
[email protected]64860882014-08-04 23:44:17125 IPC::TestChannelListener::OnChannelConnected(peer_pid);
126 EXPECT_TRUE(base::kNullProcessId != peer_pid);
127 is_connected_called_ = true;
128 }
129
130 bool is_connected_called() const { return is_connected_called_; }
131
132 private:
133 bool is_connected_called_;
134};
135
amistry0027a0952016-05-03 00:52:47136TEST_F(IPCChannelMojoTest, ConnectedFromClient) {
sammc4bcc4ed62016-10-27 10:13:59137 Init("IPCChannelMojoTestClient");
[email protected]64860882014-08-04 23:44:17138
139 // Set up IPC channel and start client.
140 TestChannelListenerWithExtraExpectations listener;
morrita373af03b2014-09-09 19:35:24141 CreateChannel(&listener);
[email protected]64860882014-08-04 23:44:17142 listener.Init(sender());
143 ASSERT_TRUE(ConnectChannel());
[email protected]64860882014-08-04 23:44:17144
sammc57ed9f982016-03-10 06:28:35145 IPC::TestChannelListener::SendOneMessage(sender(), "hello from parent");
[email protected]64860882014-08-04 23:44:17146
fdoray8e32586852016-06-22 19:56:16147 base::RunLoop().Run();
[email protected]64860882014-08-04 23:44:17148
sammc57ed9f982016-03-10 06:28:35149 channel()->Close();
[email protected]64860882014-08-04 23:44:17150
151 EXPECT_TRUE(WaitForClientShutdown());
152 EXPECT_TRUE(listener.is_connected_called());
153 EXPECT_TRUE(listener.HasSentAll());
154
155 DestroyChannel();
156}
157
158// A long running process that connects to us
sammc4bcc4ed62016-10-27 10:13:59159DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestClient) {
[email protected]64860882014-08-04 23:44:17160 TestChannelListenerWithExtraExpectations listener;
sammc57ed9f982016-03-10 06:28:35161 Connect(&listener);
162 listener.Init(channel());
[email protected]64860882014-08-04 23:44:17163
sammc57ed9f982016-03-10 06:28:35164 IPC::TestChannelListener::SendOneMessage(channel(), "hello from child");
fdoray8e32586852016-06-22 19:56:16165 base::RunLoop().Run();
[email protected]64860882014-08-04 23:44:17166 EXPECT_TRUE(listener.is_connected_called());
167 EXPECT_TRUE(listener.HasSentAll());
168
sammc57ed9f982016-03-10 06:28:35169 Close();
[email protected]64860882014-08-04 23:44:17170}
171
Wez831ae412017-08-30 00:29:36172class ListenerExpectingErrors : public TestListenerBase {
morrita0a24cfc92014-09-16 03:20:48173 public:
Wez831ae412017-08-30 00:29:36174 ListenerExpectingErrors(base::Closure quit_closure)
175 : TestListenerBase(quit_closure), has_error_(false) {}
morrita0a24cfc92014-09-16 03:20:48176
dchengfe61fca2014-10-22 02:29:52177 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita0a24cfc92014-09-16 03:20:48178
dchengfe61fca2014-10-22 02:29:52179 void OnChannelError() override {
morrita0a24cfc92014-09-16 03:20:48180 has_error_ = true;
Wez831ae412017-08-30 00:29:36181 TestListenerBase::OnChannelError();
morrita0a24cfc92014-09-16 03:20:48182 }
183
184 bool has_error() const { return has_error_; }
185
186 private:
187 bool has_error_;
188};
189
morrita0a24cfc92014-09-16 03:20:48190class ListenerThatQuits : public IPC::Listener {
191 public:
Wez831ae412017-08-30 00:29:36192 ListenerThatQuits(base::Closure quit_closure) : quit_closure_(quit_closure) {}
morrita0a24cfc92014-09-16 03:20:48193
sammc57ed9f982016-03-10 06:28:35194 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita0a24cfc92014-09-16 03:20:48195
Wez831ae412017-08-30 00:29:36196 void OnChannelConnected(int32_t peer_pid) override { quit_closure_.Run(); }
197
198 private:
199 base::Closure quit_closure_;
morrita0a24cfc92014-09-16 03:20:48200};
201
202// A long running process that connects to us.
sammc4bcc4ed62016-10-27 10:13:59203DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoErraticTestClient) {
Wez831ae412017-08-30 00:29:36204 base::RunLoop run_loop;
205 ListenerThatQuits listener(run_loop.QuitClosure());
sammc57ed9f982016-03-10 06:28:35206 Connect(&listener);
morrita0a24cfc92014-09-16 03:20:48207
Wez831ae412017-08-30 00:29:36208 run_loop.Run();
morrita0a24cfc92014-09-16 03:20:48209
sammc57ed9f982016-03-10 06:28:35210 Close();
morrita0a24cfc92014-09-16 03:20:48211}
212
rockot8c23d462016-07-25 17:33:04213TEST_F(IPCChannelMojoTest, SendFailWithPendingMessages) {
sammc4bcc4ed62016-10-27 10:13:59214 Init("IPCChannelMojoErraticTestClient");
morrita0a24cfc92014-09-16 03:20:48215
216 // Set up IPC channel and start client.
Wez831ae412017-08-30 00:29:36217 base::RunLoop run_loop;
218 ListenerExpectingErrors listener(run_loop.QuitClosure());
morrita0a24cfc92014-09-16 03:20:48219 CreateChannel(&listener);
220 ASSERT_TRUE(ConnectChannel());
221
jamesra03ae492014-10-03 04:26:48222 // This matches a value in mojo/edk/system/constants.h
morritabe6c4cc2014-09-24 23:38:44223 const int kMaxMessageNumBytes = 4 * 1024 * 1024;
224 std::string overly_large_data(kMaxMessageNumBytes, '*');
morrita0a24cfc92014-09-16 03:20:48225 // This messages are queued as pending.
morritabe6c4cc2014-09-24 23:38:44226 for (size_t i = 0; i < 10; ++i) {
sammc57ed9f982016-03-10 06:28:35227 IPC::TestChannelListener::SendOneMessage(sender(),
228 overly_large_data.c_str());
morrita0a24cfc92014-09-16 03:20:48229 }
230
Wez831ae412017-08-30 00:29:36231 run_loop.Run();
morrita0a24cfc92014-09-16 03:20:48232
sammc57ed9f982016-03-10 06:28:35233 channel()->Close();
morrita0a24cfc92014-09-16 03:20:48234
235 EXPECT_TRUE(WaitForClientShutdown());
236 EXPECT_TRUE(listener.has_error());
237
238 DestroyChannel();
239}
240
morrita81b17e02015-02-06 00:58:30241struct TestingMessagePipe {
242 TestingMessagePipe() {
243 EXPECT_EQ(MOJO_RESULT_OK, mojo::CreateMessagePipe(nullptr, &self, &peer));
244 }
245
246 mojo::ScopedMessagePipeHandle self;
247 mojo::ScopedMessagePipeHandle peer;
248};
249
250class HandleSendingHelper {
251 public:
252 static std::string GetSendingFileContent() { return "Hello"; }
253
254 static void WritePipe(IPC::Message* message, TestingMessagePipe* pipe) {
255 std::string content = HandleSendingHelper::GetSendingFileContent();
256 EXPECT_EQ(MOJO_RESULT_OK,
257 mojo::WriteMessageRaw(pipe->self.get(), &content[0],
258 static_cast<uint32_t>(content.size()),
259 nullptr, 0, 0));
dchenge48600452015-12-28 02:24:50260 EXPECT_TRUE(IPC::MojoMessageHelper::WriteMessagePipeTo(
261 message, std::move(pipe->peer)));
morrita81b17e02015-02-06 00:58:30262 }
263
264 static void WritePipeThenSend(IPC::Sender* sender, TestingMessagePipe* pipe) {
265 IPC::Message* message =
266 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
267 WritePipe(message, pipe);
268 ASSERT_TRUE(sender->Send(message));
269 }
270
271 static void ReadReceivedPipe(const IPC::Message& message,
brettwbd4d7112015-06-03 04:29:25272 base::PickleIterator* iter) {
morrita81b17e02015-02-06 00:58:30273 mojo::ScopedMessagePipeHandle pipe;
274 EXPECT_TRUE(
275 IPC::MojoMessageHelper::ReadMessagePipeFrom(&message, iter, &pipe));
Ken Rockotfada7d282017-06-12 21:25:13276 std::vector<uint8_t> content;
morrita81b17e02015-02-06 00:58:30277
sammc57ed9f982016-03-10 06:28:35278 ASSERT_EQ(MOJO_RESULT_OK,
rockota9d566a2017-03-17 19:36:15279 mojo::Wait(pipe.get(), MOJO_HANDLE_SIGNAL_READABLE));
morrita81b17e02015-02-06 00:58:30280 EXPECT_EQ(MOJO_RESULT_OK,
Ken Rockotfada7d282017-06-12 21:25:13281 mojo::ReadMessageRaw(pipe.get(), &content, nullptr, 0));
282 EXPECT_EQ(std::string(content.begin(), content.end()),
283 GetSendingFileContent());
morrita81b17e02015-02-06 00:58:30284 }
285
286#if defined(OS_POSIX)
amistry20e2b1d62016-06-23 06:12:35287 static base::FilePath GetSendingFilePath(const base::FilePath& dir_path) {
288 return dir_path.Append("ListenerThatExpectsFile.txt");
morrita81b17e02015-02-06 00:58:30289 }
290
291 static void WriteFile(IPC::Message* message, base::File& file) {
292 std::string content = GetSendingFileContent();
293 file.WriteAtCurrentPos(content.data(), content.size());
294 file.Flush();
295 message->WriteAttachment(new IPC::internal::PlatformFileAttachment(
296 base::ScopedFD(file.TakePlatformFile())));
297 }
298
299 static void WriteFileThenSend(IPC::Sender* sender, base::File& file) {
300 IPC::Message* message =
301 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
302 WriteFile(message, file);
303 ASSERT_TRUE(sender->Send(message));
304 }
305
306 static void WriteFileAndPipeThenSend(IPC::Sender* sender,
307 base::File& file,
308 TestingMessagePipe* pipe) {
309 IPC::Message* message =
310 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
311 WriteFile(message, file);
312 WritePipe(message, pipe);
313 ASSERT_TRUE(sender->Send(message));
314 }
315
316 static void ReadReceivedFile(const IPC::Message& message,
brettwbd4d7112015-06-03 04:29:25317 base::PickleIterator* iter) {
rockot502c94f2016-02-03 20:20:16318 scoped_refptr<base::Pickle::Attachment> attachment;
morrita81b17e02015-02-06 00:58:30319 EXPECT_TRUE(message.ReadAttachment(iter, &attachment));
sammc6ed3efb2016-11-23 03:17:35320 EXPECT_EQ(
321 IPC::MessageAttachment::Type::PLATFORM_FILE,
322 static_cast<IPC::MessageAttachment*>(attachment.get())->GetType());
323 base::File file(
324 static_cast<IPC::internal::PlatformFileAttachment*>(attachment.get())
325 ->TakePlatformFile());
morrita81b17e02015-02-06 00:58:30326 std::string content(GetSendingFileContent().size(), ' ');
327 file.Read(0, &content[0], content.size());
328 EXPECT_EQ(content, GetSendingFileContent());
329 }
330#endif
331};
332
Wez831ae412017-08-30 00:29:36333class ListenerThatExpectsMessagePipe : public TestListenerBase {
morrita81b17e02015-02-06 00:58:30334 public:
Wez831ae412017-08-30 00:29:36335 ListenerThatExpectsMessagePipe(base::Closure quit_closure)
336 : TestListenerBase(quit_closure) {}
morrita81b17e02015-02-06 00:58:30337
Chris Watkins2d879af2017-11-30 02:11:59338 ~ListenerThatExpectsMessagePipe() override = default;
morrita81b17e02015-02-06 00:58:30339
340 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25341 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:30342 HandleSendingHelper::ReadReceivedPipe(message, &iter);
Wez831ae412017-08-30 00:29:36343 ListenerThatExpectsOK::SendOK(sender());
morrita81b17e02015-02-06 00:58:30344 return true;
345 }
morrita81b17e02015-02-06 00:58:30346};
347
amistry0027a0952016-05-03 00:52:47348TEST_F(IPCChannelMojoTest, SendMessagePipe) {
sammc4bcc4ed62016-10-27 10:13:59349 Init("IPCChannelMojoTestSendMessagePipeClient");
morrita81b17e02015-02-06 00:58:30350
Wez831ae412017-08-30 00:29:36351 base::RunLoop run_loop;
352 ListenerThatExpectsOK listener(run_loop.QuitClosure());
morrita81b17e02015-02-06 00:58:30353 CreateChannel(&listener);
354 ASSERT_TRUE(ConnectChannel());
morrita81b17e02015-02-06 00:58:30355
356 TestingMessagePipe pipe;
357 HandleSendingHelper::WritePipeThenSend(channel(), &pipe);
358
Wez831ae412017-08-30 00:29:36359 run_loop.Run();
sammc57ed9f982016-03-10 06:28:35360 channel()->Close();
morrita81b17e02015-02-06 00:58:30361
362 EXPECT_TRUE(WaitForClientShutdown());
363 DestroyChannel();
364}
365
sammc4bcc4ed62016-10-27 10:13:59366DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendMessagePipeClient) {
Wez831ae412017-08-30 00:29:36367 base::RunLoop run_loop;
368 ListenerThatExpectsMessagePipe listener(run_loop.QuitClosure());
sammc57ed9f982016-03-10 06:28:35369 Connect(&listener);
370 listener.set_sender(channel());
morrita81b17e02015-02-06 00:58:30371
Wez831ae412017-08-30 00:29:36372 run_loop.Run();
morrita81b17e02015-02-06 00:58:30373
sammc57ed9f982016-03-10 06:28:35374 Close();
morrita81b17e02015-02-06 00:58:30375}
376
morrita438a2ee2015-04-03 05:28:21377void ReadOK(mojo::MessagePipeHandle pipe) {
Ken Rockotfada7d282017-06-12 21:25:13378 std::vector<uint8_t> should_be_ok;
rockota9d566a2017-03-17 19:36:15379 CHECK_EQ(MOJO_RESULT_OK, mojo::Wait(pipe, MOJO_HANDLE_SIGNAL_READABLE));
morrita438a2ee2015-04-03 05:28:21380 CHECK_EQ(MOJO_RESULT_OK,
Ken Rockotfada7d282017-06-12 21:25:13381 mojo::ReadMessageRaw(pipe, &should_be_ok, nullptr, 0));
382 EXPECT_EQ("OK", std::string(should_be_ok.begin(), should_be_ok.end()));
morrita438a2ee2015-04-03 05:28:21383}
384
385void WriteOK(mojo::MessagePipeHandle pipe) {
386 std::string ok("OK");
387 CHECK_EQ(MOJO_RESULT_OK,
388 mojo::WriteMessageRaw(pipe, &ok[0], static_cast<uint32_t>(ok.size()),
389 nullptr, 0, 0));
390}
391
Wez831ae412017-08-30 00:29:36392class ListenerThatExpectsMessagePipeUsingParamTrait : public TestListenerBase {
morrita438a2ee2015-04-03 05:28:21393 public:
Wez831ae412017-08-30 00:29:36394 explicit ListenerThatExpectsMessagePipeUsingParamTrait(
395 base::Closure quit_closure,
396 bool receiving_valid)
397 : TestListenerBase(quit_closure), receiving_valid_(receiving_valid) {}
morrita438a2ee2015-04-03 05:28:21398
Chris Watkins2d879af2017-11-30 02:11:59399 ~ListenerThatExpectsMessagePipeUsingParamTrait() override = default;
morrita438a2ee2015-04-03 05:28:21400
401 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25402 base::PickleIterator iter(message);
morrita438a2ee2015-04-03 05:28:21403 mojo::MessagePipeHandle handle;
404 EXPECT_TRUE(IPC::ParamTraits<mojo::MessagePipeHandle>::Read(&message, &iter,
405 &handle));
406 EXPECT_EQ(handle.is_valid(), receiving_valid_);
407 if (receiving_valid_) {
408 ReadOK(handle);
409 MojoClose(handle.value());
410 }
411
Wez831ae412017-08-30 00:29:36412 ListenerThatExpectsOK::SendOK(sender());
morrita438a2ee2015-04-03 05:28:21413 return true;
414 }
415
morrita438a2ee2015-04-03 05:28:21416 private:
morrita438a2ee2015-04-03 05:28:21417 bool receiving_valid_;
418};
419
sammc4bcc4ed62016-10-27 10:13:59420class ParamTraitMessagePipeClient : public IpcChannelMojoTestClient {
sammc57ed9f982016-03-10 06:28:35421 public:
422 void RunTest(bool receiving_valid_handle) {
Wez831ae412017-08-30 00:29:36423 base::RunLoop run_loop;
sammc57ed9f982016-03-10 06:28:35424 ListenerThatExpectsMessagePipeUsingParamTrait listener(
Wez831ae412017-08-30 00:29:36425 run_loop.QuitClosure(), receiving_valid_handle);
sammc57ed9f982016-03-10 06:28:35426 Connect(&listener);
427 listener.set_sender(channel());
morrita438a2ee2015-04-03 05:28:21428
Wez831ae412017-08-30 00:29:36429 run_loop.Run();
morrita438a2ee2015-04-03 05:28:21430
sammc57ed9f982016-03-10 06:28:35431 Close();
432 }
433};
morrita438a2ee2015-04-03 05:28:21434
amistry0027a0952016-05-03 00:52:47435TEST_F(IPCChannelMojoTest, ParamTraitValidMessagePipe) {
sammc4bcc4ed62016-10-27 10:13:59436 Init("ParamTraitValidMessagePipeClient");
morrita438a2ee2015-04-03 05:28:21437
Wez831ae412017-08-30 00:29:36438 base::RunLoop run_loop;
439 ListenerThatExpectsOK listener(run_loop.QuitClosure());
morrita438a2ee2015-04-03 05:28:21440 CreateChannel(&listener);
441 ASSERT_TRUE(ConnectChannel());
morrita438a2ee2015-04-03 05:28:21442
443 TestingMessagePipe pipe;
444
danakj03de39b22016-04-23 04:21:09445 std::unique_ptr<IPC::Message> message(new IPC::Message());
morrita438a2ee2015-04-03 05:28:21446 IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
447 pipe.peer.release());
448 WriteOK(pipe.self.get());
449
sammc57ed9f982016-03-10 06:28:35450 channel()->Send(message.release());
Wez831ae412017-08-30 00:29:36451 run_loop.Run();
sammc57ed9f982016-03-10 06:28:35452 channel()->Close();
morrita438a2ee2015-04-03 05:28:21453
454 EXPECT_TRUE(WaitForClientShutdown());
455 DestroyChannel();
456}
457
sammc4bcc4ed62016-10-27 10:13:59458DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
459 ParamTraitValidMessagePipeClient,
460 ParamTraitMessagePipeClient) {
sammc57ed9f982016-03-10 06:28:35461 RunTest(true);
morrita438a2ee2015-04-03 05:28:21462}
463
amistry0027a0952016-05-03 00:52:47464TEST_F(IPCChannelMojoTest, ParamTraitInvalidMessagePipe) {
sammc4bcc4ed62016-10-27 10:13:59465 Init("ParamTraitInvalidMessagePipeClient");
morrita438a2ee2015-04-03 05:28:21466
Wez831ae412017-08-30 00:29:36467 base::RunLoop run_loop;
468 ListenerThatExpectsOK listener(run_loop.QuitClosure());
morrita438a2ee2015-04-03 05:28:21469 CreateChannel(&listener);
470 ASSERT_TRUE(ConnectChannel());
morrita438a2ee2015-04-03 05:28:21471
472 mojo::MessagePipeHandle invalid_handle;
danakj03de39b22016-04-23 04:21:09473 std::unique_ptr<IPC::Message> message(new IPC::Message());
morrita438a2ee2015-04-03 05:28:21474 IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
475 invalid_handle);
476
sammc57ed9f982016-03-10 06:28:35477 channel()->Send(message.release());
Wez831ae412017-08-30 00:29:36478 run_loop.Run();
sammc57ed9f982016-03-10 06:28:35479 channel()->Close();
morrita438a2ee2015-04-03 05:28:21480
481 EXPECT_TRUE(WaitForClientShutdown());
482 DestroyChannel();
483}
484
sammc4bcc4ed62016-10-27 10:13:59485DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
486 ParamTraitInvalidMessagePipeClient,
487 ParamTraitMessagePipeClient) {
sammc57ed9f982016-03-10 06:28:35488 RunTest(false);
morrita438a2ee2015-04-03 05:28:21489}
490
amistry0027a0952016-05-03 00:52:47491TEST_F(IPCChannelMojoTest, SendFailAfterClose) {
sammc4bcc4ed62016-10-27 10:13:59492 Init("IPCChannelMojoTestSendOkClient");
morrita17137e62015-06-23 22:29:36493
Wez831ae412017-08-30 00:29:36494 base::RunLoop run_loop;
495 ListenerThatExpectsOK listener(run_loop.QuitClosure());
morrita17137e62015-06-23 22:29:36496 CreateChannel(&listener);
497 ASSERT_TRUE(ConnectChannel());
morrita17137e62015-06-23 22:29:36498
Wez831ae412017-08-30 00:29:36499 run_loop.Run();
sammc57ed9f982016-03-10 06:28:35500 channel()->Close();
501 ASSERT_FALSE(channel()->Send(new IPC::Message()));
morrita17137e62015-06-23 22:29:36502
503 EXPECT_TRUE(WaitForClientShutdown());
504 DestroyChannel();
505}
506
Wez831ae412017-08-30 00:29:36507class ListenerSendingOneOk : public TestListenerBase {
morrita17137e62015-06-23 22:29:36508 public:
Wez831ae412017-08-30 00:29:36509 ListenerSendingOneOk(base::Closure quit_closure)
510 : TestListenerBase(quit_closure) {}
morrita17137e62015-06-23 22:29:36511
sammc57ed9f982016-03-10 06:28:35512 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita17137e62015-06-23 22:29:36513
tfarina10a5c062015-09-04 18:47:57514 void OnChannelConnected(int32_t peer_pid) override {
Wez831ae412017-08-30 00:29:36515 ListenerThatExpectsOK::SendOK(sender());
516 quit_closure().Run();
morrita17137e62015-06-23 22:29:36517 }
morrita17137e62015-06-23 22:29:36518};
519
sammc4bcc4ed62016-10-27 10:13:59520DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendOkClient) {
Wez831ae412017-08-30 00:29:36521 base::RunLoop run_loop;
522 ListenerSendingOneOk listener(run_loop.QuitClosure());
sammc57ed9f982016-03-10 06:28:35523 Connect(&listener);
524 listener.set_sender(channel());
morrita17137e62015-06-23 22:29:36525
Wez831ae412017-08-30 00:29:36526 run_loop.Run();
morrita17137e62015-06-23 22:29:36527
sammc57ed9f982016-03-10 06:28:35528 Close();
morrita17137e62015-06-23 22:29:36529}
530
rockot7c6bf952016-07-14 00:34:11531class ListenerWithSimpleAssociatedInterface
532 : public IPC::Listener,
533 public IPC::mojom::SimpleTestDriver {
534 public:
535 static const int kNumMessages;
536
537 ListenerWithSimpleAssociatedInterface() : binding_(this) {}
538
Chris Watkins2d879af2017-11-30 02:11:59539 ~ListenerWithSimpleAssociatedInterface() override = default;
rockot7c6bf952016-07-14 00:34:11540
541 bool OnMessageReceived(const IPC::Message& message) override {
542 base::PickleIterator iter(message);
rockot9abe09b2016-08-02 20:57:34543 int32_t should_be_expected;
544 EXPECT_TRUE(iter.ReadInt(&should_be_expected));
545 EXPECT_EQ(should_be_expected, next_expected_value_);
rockot7c6bf952016-07-14 00:34:11546 num_messages_received_++;
547 return true;
548 }
549
Wezd95d48042018-02-26 20:50:47550 void OnChannelError() override { CHECK(received_quit_); }
rockot7c6bf952016-07-14 00:34:11551
552 void RegisterInterfaceFactory(IPC::Channel* channel) {
553 channel->GetAssociatedInterfaceSupport()->AddAssociatedInterface(
554 base::Bind(&ListenerWithSimpleAssociatedInterface::BindRequest,
555 base::Unretained(this)));
556 }
557
558 private:
559 // IPC::mojom::SimpleTestDriver:
rockot9abe09b2016-08-02 20:57:34560 void ExpectValue(int32_t value) override {
561 next_expected_value_ = value;
562 }
563
tzikdd76ce712017-06-08 05:27:04564 void GetExpectedValue(GetExpectedValueCallback callback) override {
rockot9abe09b2016-08-02 20:57:34565 NOTREACHED();
566 }
567
tzikdd76ce712017-06-08 05:27:04568 void RequestValue(RequestValueCallback callback) override { NOTREACHED(); }
rockot7c6bf952016-07-14 00:34:11569
tzikdd76ce712017-06-08 05:27:04570 void RequestQuit(RequestQuitCallback callback) override {
rockot7c6bf952016-07-14 00:34:11571 EXPECT_EQ(kNumMessages, num_messages_received_);
572 received_quit_ = true;
tzikdd76ce712017-06-08 05:27:04573 std::move(callback).Run();
Gabriel Charette53a9ef812017-07-26 12:36:23574 base::RunLoop::QuitCurrentWhenIdleDeprecated();
rockot7c6bf952016-07-14 00:34:11575 }
576
577 void BindRequest(IPC::mojom::SimpleTestDriverAssociatedRequest request) {
578 DCHECK(!binding_.is_bound());
579 binding_.Bind(std::move(request));
580 }
581
rockot9abe09b2016-08-02 20:57:34582 int32_t next_expected_value_ = 0;
rockot7c6bf952016-07-14 00:34:11583 int num_messages_received_ = 0;
584 bool received_quit_ = false;
585
586 mojo::AssociatedBinding<IPC::mojom::SimpleTestDriver> binding_;
587};
588
589const int ListenerWithSimpleAssociatedInterface::kNumMessages = 1000;
590
591class ListenerSendingAssociatedMessages : public IPC::Listener {
592 public:
Chris Watkins2d879af2017-11-30 02:11:59593 ListenerSendingAssociatedMessages() = default;
rockot7c6bf952016-07-14 00:34:11594
595 bool OnMessageReceived(const IPC::Message& message) override { return true; }
596
597 void OnChannelConnected(int32_t peer_pid) override {
598 DCHECK(channel_);
599 channel_->GetAssociatedInterfaceSupport()->GetRemoteAssociatedInterface(
600 &driver_);
601
602 // Send a bunch of interleaved messages, alternating between the associated
603 // interface and a legacy IPC::Message.
604 for (int i = 0; i < ListenerWithSimpleAssociatedInterface::kNumMessages;
605 ++i) {
rockot9abe09b2016-08-02 20:57:34606 driver_->ExpectValue(i);
607 SendValue(channel_, i);
rockot7c6bf952016-07-14 00:34:11608 }
609 driver_->RequestQuit(base::Bind(&OnQuitAck));
610 }
611
612 void set_channel(IPC::Channel* channel) { channel_ = channel; }
613
614 private:
Gabriel Charette53a9ef812017-07-26 12:36:23615 static void OnQuitAck() { base::RunLoop::QuitCurrentWhenIdleDeprecated(); }
rockot7c6bf952016-07-14 00:34:11616
617 IPC::Channel* channel_ = nullptr;
618 IPC::mojom::SimpleTestDriverAssociatedPtr driver_;
619};
620
621TEST_F(IPCChannelMojoTest, SimpleAssociatedInterface) {
sammc4bcc4ed62016-10-27 10:13:59622 Init("SimpleAssociatedInterfaceClient");
rockot7c6bf952016-07-14 00:34:11623
624 ListenerWithSimpleAssociatedInterface listener;
625 CreateChannel(&listener);
626 ASSERT_TRUE(ConnectChannel());
627
628 listener.RegisterInterfaceFactory(channel());
629
630 base::RunLoop().Run();
631 channel()->Close();
632
633 EXPECT_TRUE(WaitForClientShutdown());
634 DestroyChannel();
635}
636
sammc4bcc4ed62016-10-27 10:13:59637DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(SimpleAssociatedInterfaceClient) {
rockot7c6bf952016-07-14 00:34:11638 ListenerSendingAssociatedMessages listener;
639 Connect(&listener);
640 listener.set_channel(channel());
641
642 base::RunLoop().Run();
643
644 Close();
645}
646
rockot8d890f62016-07-14 16:37:14647class ChannelProxyRunner {
648 public:
rockota34707ca2016-07-20 04:28:32649 ChannelProxyRunner(mojo::ScopedMessagePipeHandle handle,
650 bool for_server)
651 : for_server_(for_server),
652 handle_(std::move(handle)),
rockot9abe09b2016-08-02 20:57:34653 io_thread_("ChannelProxyRunner IO thread"),
654 never_signaled_(base::WaitableEvent::ResetPolicy::MANUAL,
655 base::WaitableEvent::InitialState::NOT_SIGNALED) {
rockot8d890f62016-07-14 16:37:14656 }
657
658 void CreateProxy(IPC::Listener* listener) {
659 io_thread_.StartWithOptions(
660 base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
Hajime Hoshiff15e972017-11-09 06:37:09661 proxy_ = IPC::SyncChannel::Create(listener, io_thread_.task_runner(),
662 base::ThreadTaskRunnerHandle::Get(),
663 &never_signaled_);
rockot8d890f62016-07-14 16:37:14664 }
rockota34707ca2016-07-20 04:28:32665
rockot10188752016-09-08 18:24:56666 void RunProxy() {
rockota34707ca2016-07-20 04:28:32667 std::unique_ptr<IPC::ChannelFactory> factory;
668 if (for_server_) {
669 factory = IPC::ChannelMojo::CreateServerFactory(
Hajime Hoshia98f1102017-11-20 06:34:35670 std::move(handle_), io_thread_.task_runner(),
671 base::ThreadTaskRunnerHandle::Get());
rockota34707ca2016-07-20 04:28:32672 } else {
673 factory = IPC::ChannelMojo::CreateClientFactory(
Hajime Hoshia98f1102017-11-20 06:34:35674 std::move(handle_), io_thread_.task_runner(),
675 base::ThreadTaskRunnerHandle::Get());
rockota34707ca2016-07-20 04:28:32676 }
rockot10188752016-09-08 18:24:56677 proxy_->Init(std::move(factory), true);
rockota34707ca2016-07-20 04:28:32678 }
rockot8d890f62016-07-14 16:37:14679
680 IPC::ChannelProxy* proxy() { return proxy_.get(); }
681
682 private:
rockota34707ca2016-07-20 04:28:32683 const bool for_server_;
rockot8d890f62016-07-14 16:37:14684
rockota34707ca2016-07-20 04:28:32685 mojo::ScopedMessagePipeHandle handle_;
rockot8d890f62016-07-14 16:37:14686 base::Thread io_thread_;
rockot9abe09b2016-08-02 20:57:34687 base::WaitableEvent never_signaled_;
rockotb62e2e32017-03-24 18:36:44688 std::unique_ptr<IPC::ChannelProxy> proxy_;
rockot8d890f62016-07-14 16:37:14689
690 DISALLOW_COPY_AND_ASSIGN(ChannelProxyRunner);
691};
692
693class IPCChannelProxyMojoTest : public IPCChannelMojoTestBase {
694 public:
sammc4bcc4ed62016-10-27 10:13:59695 void Init(const std::string& client_name) {
696 IPCChannelMojoTestBase::Init(client_name);
rockota34707ca2016-07-20 04:28:32697 runner_.reset(new ChannelProxyRunner(TakeHandle(), true));
rockot8d890f62016-07-14 16:37:14698 }
699 void CreateProxy(IPC::Listener* listener) { runner_->CreateProxy(listener); }
rockot10188752016-09-08 18:24:56700 void RunProxy() {
701 runner_->RunProxy();
rockot401fb2c2016-09-06 18:35:57702 }
rockot0e4de5f2016-07-22 21:18:07703 void DestroyProxy() {
704 runner_.reset();
705 base::RunLoop().RunUntilIdle();
706 }
rockot8d890f62016-07-14 16:37:14707
708 IPC::ChannelProxy* proxy() { return runner_->proxy(); }
709
710 private:
rockot8d890f62016-07-14 16:37:14711 std::unique_ptr<ChannelProxyRunner> runner_;
712};
713
714class ListenerWithSimpleProxyAssociatedInterface
715 : public IPC::Listener,
716 public IPC::mojom::SimpleTestDriver {
717 public:
718 static const int kNumMessages;
719
720 ListenerWithSimpleProxyAssociatedInterface() : binding_(this) {}
721
Chris Watkins2d879af2017-11-30 02:11:59722 ~ListenerWithSimpleProxyAssociatedInterface() override = default;
rockot8d890f62016-07-14 16:37:14723
724 bool OnMessageReceived(const IPC::Message& message) override {
725 base::PickleIterator iter(message);
rockot9abe09b2016-08-02 20:57:34726 int32_t should_be_expected;
727 EXPECT_TRUE(iter.ReadInt(&should_be_expected));
728 EXPECT_EQ(should_be_expected, next_expected_value_);
rockot8d890f62016-07-14 16:37:14729 num_messages_received_++;
730 return true;
731 }
732
Wezd95d48042018-02-26 20:50:47733 void OnChannelError() override { CHECK(received_quit_); }
rockot8d890f62016-07-14 16:37:14734
rockotf62002a2016-09-15 00:08:59735 void OnAssociatedInterfaceRequest(
736 const std::string& interface_name,
737 mojo::ScopedInterfaceEndpointHandle handle) override {
738 DCHECK_EQ(interface_name, IPC::mojom::SimpleTestDriver::Name_);
Ken Rockot96d1b7b52017-05-13 00:29:21739 binding_.Bind(
740 IPC::mojom::SimpleTestDriverAssociatedRequest(std::move(handle)));
rockot8d890f62016-07-14 16:37:14741 }
742
743 bool received_all_messages() const {
744 return num_messages_received_ == kNumMessages && received_quit_;
745 }
746
747 private:
748 // IPC::mojom::SimpleTestDriver:
rockot9abe09b2016-08-02 20:57:34749 void ExpectValue(int32_t value) override {
750 next_expected_value_ = value;
751 }
752
tzikdd76ce712017-06-08 05:27:04753 void GetExpectedValue(GetExpectedValueCallback callback) override {
754 std::move(callback).Run(next_expected_value_);
rockot9abe09b2016-08-02 20:57:34755 }
756
tzikdd76ce712017-06-08 05:27:04757 void RequestValue(RequestValueCallback callback) override { NOTREACHED(); }
rockot8d890f62016-07-14 16:37:14758
tzikdd76ce712017-06-08 05:27:04759 void RequestQuit(RequestQuitCallback callback) override {
rockot8d890f62016-07-14 16:37:14760 received_quit_ = true;
tzikdd76ce712017-06-08 05:27:04761 std::move(callback).Run();
rockot0e4de5f2016-07-22 21:18:07762 binding_.Close();
Gabriel Charette53a9ef812017-07-26 12:36:23763 base::RunLoop::QuitCurrentWhenIdleDeprecated();
rockot8d890f62016-07-14 16:37:14764 }
765
766 void BindRequest(IPC::mojom::SimpleTestDriverAssociatedRequest request) {
767 DCHECK(!binding_.is_bound());
768 binding_.Bind(std::move(request));
769 }
770
rockot9abe09b2016-08-02 20:57:34771 int32_t next_expected_value_ = 0;
rockot8d890f62016-07-14 16:37:14772 int num_messages_received_ = 0;
773 bool received_quit_ = false;
774
775 mojo::AssociatedBinding<IPC::mojom::SimpleTestDriver> binding_;
776};
777
778const int ListenerWithSimpleProxyAssociatedInterface::kNumMessages = 1000;
779
780TEST_F(IPCChannelProxyMojoTest, ProxyThreadAssociatedInterface) {
sammc4bcc4ed62016-10-27 10:13:59781 Init("ProxyThreadAssociatedInterfaceClient");
rockot8d890f62016-07-14 16:37:14782
783 ListenerWithSimpleProxyAssociatedInterface listener;
784 CreateProxy(&listener);
rockot8d890f62016-07-14 16:37:14785 RunProxy();
786
787 base::RunLoop().Run();
788
789 EXPECT_TRUE(WaitForClientShutdown());
790 EXPECT_TRUE(listener.received_all_messages());
791
rockot0e4de5f2016-07-22 21:18:07792 DestroyProxy();
rockot8d890f62016-07-14 16:37:14793}
794
795class ChannelProxyClient {
796 public:
797 void Init(mojo::ScopedMessagePipeHandle handle) {
rockota34707ca2016-07-20 04:28:32798 runner_.reset(new ChannelProxyRunner(std::move(handle), false));
rockot8d890f62016-07-14 16:37:14799 }
rockot9abe09b2016-08-02 20:57:34800
rockot8d890f62016-07-14 16:37:14801 void CreateProxy(IPC::Listener* listener) { runner_->CreateProxy(listener); }
rockot9abe09b2016-08-02 20:57:34802
rockot10188752016-09-08 18:24:56803 void RunProxy() { runner_->RunProxy(); }
rockot9abe09b2016-08-02 20:57:34804
rockot0e4de5f2016-07-22 21:18:07805 void DestroyProxy() {
806 runner_.reset();
807 base::RunLoop().RunUntilIdle();
808 }
rockot8d890f62016-07-14 16:37:14809
rockot9abe09b2016-08-02 20:57:34810 void RequestQuitAndWaitForAck(IPC::mojom::SimpleTestDriver* driver) {
811 base::RunLoop loop;
812 driver->RequestQuit(loop.QuitClosure());
813 loop.Run();
814 }
815
rockot8d890f62016-07-14 16:37:14816 IPC::ChannelProxy* proxy() { return runner_->proxy(); }
817
818 private:
819 base::MessageLoop message_loop_;
820 std::unique_ptr<ChannelProxyRunner> runner_;
821};
822
rockot0e4de5f2016-07-22 21:18:07823class DummyListener : public IPC::Listener {
rockot8d890f62016-07-14 16:37:14824 public:
rockot8d890f62016-07-14 16:37:14825 // IPC::Listener
826 bool OnMessageReceived(const IPC::Message& message) override { return true; }
rockot8d890f62016-07-14 16:37:14827};
828
sammc4bcc4ed62016-10-27 10:13:59829DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
830 ProxyThreadAssociatedInterfaceClient,
831 ChannelProxyClient) {
rockot0e4de5f2016-07-22 21:18:07832 DummyListener listener;
rockot8d890f62016-07-14 16:37:14833 CreateProxy(&listener);
834 RunProxy();
rockot8d890f62016-07-14 16:37:14835
836 // Send a bunch of interleaved messages, alternating between the associated
837 // interface and a legacy IPC::Message.
838 IPC::mojom::SimpleTestDriverAssociatedPtr driver;
839 proxy()->GetRemoteAssociatedInterface(&driver);
840 for (int i = 0; i < ListenerWithSimpleProxyAssociatedInterface::kNumMessages;
841 ++i) {
rockot9abe09b2016-08-02 20:57:34842 driver->ExpectValue(i);
843 SendValue(proxy(), i);
rockot8d890f62016-07-14 16:37:14844 }
845 driver->RequestQuit(base::MessageLoop::QuitWhenIdleClosure());
846 base::RunLoop().Run();
rockot0e4de5f2016-07-22 21:18:07847
848 DestroyProxy();
rockot8d890f62016-07-14 16:37:14849}
850
rockot401fb2c2016-09-06 18:35:57851class ListenerWithIndirectProxyAssociatedInterface
852 : public IPC::Listener,
853 public IPC::mojom::IndirectTestDriver,
854 public IPC::mojom::PingReceiver {
855 public:
856 ListenerWithIndirectProxyAssociatedInterface()
857 : driver_binding_(this), ping_receiver_binding_(this) {}
Chris Watkins2d879af2017-11-30 02:11:59858 ~ListenerWithIndirectProxyAssociatedInterface() override = default;
rockot401fb2c2016-09-06 18:35:57859
rockot70bbb59492017-01-25 00:56:51860 // IPC::Listener:
rockot401fb2c2016-09-06 18:35:57861 bool OnMessageReceived(const IPC::Message& message) override { return true; }
862
rockot70bbb59492017-01-25 00:56:51863 void OnAssociatedInterfaceRequest(
864 const std::string& interface_name,
865 mojo::ScopedInterfaceEndpointHandle handle) override {
866 DCHECK(!driver_binding_.is_bound());
867 DCHECK_EQ(interface_name, IPC::mojom::IndirectTestDriver::Name_);
Ken Rockot96d1b7b52017-05-13 00:29:21868 driver_binding_.Bind(
869 IPC::mojom::IndirectTestDriverAssociatedRequest(std::move(handle)));
rockot401fb2c2016-09-06 18:35:57870 }
871
872 void set_ping_handler(const base::Closure& handler) {
873 ping_handler_ = handler;
874 }
875
876 private:
877 // IPC::mojom::IndirectTestDriver:
878 void GetPingReceiver(
879 IPC::mojom::PingReceiverAssociatedRequest request) override {
880 ping_receiver_binding_.Bind(std::move(request));
881 }
882
883 // IPC::mojom::PingReceiver:
tzikdd76ce712017-06-08 05:27:04884 void Ping(PingCallback callback) override {
885 std::move(callback).Run();
rockot401fb2c2016-09-06 18:35:57886 ping_handler_.Run();
887 }
888
rockot401fb2c2016-09-06 18:35:57889 mojo::AssociatedBinding<IPC::mojom::IndirectTestDriver> driver_binding_;
890 mojo::AssociatedBinding<IPC::mojom::PingReceiver> ping_receiver_binding_;
891
892 base::Closure ping_handler_;
893};
894
895TEST_F(IPCChannelProxyMojoTest, ProxyThreadAssociatedInterfaceIndirect) {
896 // Tests that we can pipeline interface requests and subsequent messages
897 // targeting proxy thread bindings, and the channel will still dispatch
898 // messages appropriately.
899
sammc4bcc4ed62016-10-27 10:13:59900 Init("ProxyThreadAssociatedInterfaceIndirectClient");
rockot401fb2c2016-09-06 18:35:57901
902 ListenerWithIndirectProxyAssociatedInterface listener;
903 CreateProxy(&listener);
rockot401fb2c2016-09-06 18:35:57904 RunProxy();
905
906 base::RunLoop loop;
907 listener.set_ping_handler(loop.QuitClosure());
908 loop.Run();
909
910 EXPECT_TRUE(WaitForClientShutdown());
911
912 DestroyProxy();
913}
914
sammc4bcc4ed62016-10-27 10:13:59915DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
rockot401fb2c2016-09-06 18:35:57916 ProxyThreadAssociatedInterfaceIndirectClient,
917 ChannelProxyClient) {
918 DummyListener listener;
919 CreateProxy(&listener);
920 RunProxy();
921
922 // Use an interface requested via another interface. On the remote end both
923 // interfaces are bound on the proxy thread. This ensures that the Ping
924 // message we send will still be dispatched properly even though the remote
925 // endpoint may not have been bound yet by the time the message is initially
926 // processed on the IO thread.
927 IPC::mojom::IndirectTestDriverAssociatedPtr driver;
928 IPC::mojom::PingReceiverAssociatedPtr ping_receiver;
929 proxy()->GetRemoteAssociatedInterface(&driver);
yzshen1aa8e56c2017-02-16 23:15:45930 driver->GetPingReceiver(mojo::MakeRequest(&ping_receiver));
rockot401fb2c2016-09-06 18:35:57931
932 base::RunLoop loop;
933 ping_receiver->Ping(loop.QuitClosure());
934 loop.Run();
935
936 DestroyProxy();
937}
938
rockot9abe09b2016-08-02 20:57:34939class ListenerWithSyncAssociatedInterface
940 : public IPC::Listener,
941 public IPC::mojom::SimpleTestDriver {
942 public:
943 ListenerWithSyncAssociatedInterface() : binding_(this) {}
Chris Watkins2d879af2017-11-30 02:11:59944 ~ListenerWithSyncAssociatedInterface() override = default;
rockot9abe09b2016-08-02 20:57:34945
946 void set_sync_sender(IPC::Sender* sync_sender) { sync_sender_ = sync_sender; }
947
rockot9abe09b2016-08-02 20:57:34948 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
tzikdd76ce712017-06-08 05:27:04966 void GetExpectedValue(GetExpectedValueCallback callback) override {
967 std::move(callback).Run(next_expected_value_);
rockot9abe09b2016-08-02 20:57:34968 }
969
tzikdd76ce712017-06-08 05:27:04970 void RequestValue(RequestValueCallback callback) override {
971 std::move(callback).Run(response_value_);
rockot9abe09b2016-08-02 20:57:34972 }
973
tzikdd76ce712017-06-08 05:27:04974 void RequestQuit(RequestQuitCallback callback) override {
rockot9abe09b2016-08-02 20:57:34975 quit_closure_.Run();
tzikdd76ce712017-06-08 05:27:04976 std::move(callback).Run();
rockot9abe09b2016-08-02 20:57:34977 }
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
rockot70bbb59492017-01-25 00:56:51992 void OnAssociatedInterfaceRequest(
993 const std::string& interface_name,
994 mojo::ScopedInterfaceEndpointHandle handle) override {
995 DCHECK(!binding_.is_bound());
996 DCHECK_EQ(interface_name, IPC::mojom::SimpleTestDriver::Name_);
Ken Rockot96d1b7b52017-05-13 00:29:21997 binding_.Bind(
998 IPC::mojom::SimpleTestDriverAssociatedRequest(std::move(handle)));
rockot70bbb59492017-01-25 00:56:51999 }
1000
rockot9abe09b2016-08-02 20:57:341001 void BindRequest(IPC::mojom::SimpleTestDriverAssociatedRequest request) {
1002 DCHECK(!binding_.is_bound());
1003 binding_.Bind(std::move(request));
1004 }
1005
1006 IPC::Sender* sync_sender_ = nullptr;
1007 int32_t next_expected_value_ = 0;
1008 int32_t response_value_ = 0;
1009 base::Closure quit_closure_;
1010
1011 mojo::AssociatedBinding<IPC::mojom::SimpleTestDriver> binding_;
1012};
1013
1014class SyncReplyReader : public IPC::MessageReplyDeserializer {
1015 public:
1016 explicit SyncReplyReader(int32_t* storage) : storage_(storage) {}
Chris Watkins2d879af2017-11-30 02:11:591017 ~SyncReplyReader() override = default;
rockot9abe09b2016-08-02 20:57:341018
1019 private:
1020 // IPC::MessageReplyDeserializer:
1021 bool SerializeOutputParameters(const IPC::Message& message,
1022 base::PickleIterator iter) override {
1023 if (!iter.ReadInt(storage_))
1024 return false;
1025 return true;
1026 }
1027
1028 int32_t* storage_;
1029
1030 DISALLOW_COPY_AND_ASSIGN(SyncReplyReader);
1031};
1032
1033TEST_F(IPCChannelProxyMojoTest, SyncAssociatedInterface) {
sammc4bcc4ed62016-10-27 10:13:591034 Init("SyncAssociatedInterface");
rockot9abe09b2016-08-02 20:57:341035
1036 ListenerWithSyncAssociatedInterface listener;
1037 CreateProxy(&listener);
1038 listener.set_sync_sender(proxy());
rockot9abe09b2016-08-02 20:57:341039 RunProxy();
1040
1041 // Run the client's simple sanity check to completion.
1042 listener.RunUntilQuitRequested();
1043
1044 // Verify that we can send a sync IPC and service an incoming sync request
1045 // while waiting on it
1046 listener.set_response_value(42);
1047 IPC::mojom::SimpleTestClientAssociatedPtr client;
1048 proxy()->GetRemoteAssociatedInterface(&client);
1049 int32_t received_value;
1050 EXPECT_TRUE(client->RequestValue(&received_value));
1051 EXPECT_EQ(42, received_value);
1052
1053 // Do it again. This time the client will send a classical sync IPC to us
1054 // while we wait.
1055 received_value = 0;
1056 EXPECT_TRUE(client->RequestValue(&received_value));
1057 EXPECT_EQ(42, received_value);
1058
1059 // Now make a classical sync IPC request to the client. It will send a
1060 // sync associated interface message to us while we wait.
1061 received_value = 0;
1062 std::unique_ptr<IPC::SyncMessage> request(
1063 new IPC::SyncMessage(0, 0, IPC::Message::PRIORITY_NORMAL,
1064 new SyncReplyReader(&received_value)));
1065 EXPECT_TRUE(proxy()->Send(request.release()));
1066 EXPECT_EQ(42, received_value);
1067
1068 listener.CloseBinding();
1069 EXPECT_TRUE(WaitForClientShutdown());
1070
1071 DestroyProxy();
1072}
1073
1074class SimpleTestClientImpl : public IPC::mojom::SimpleTestClient,
1075 public IPC::Listener {
1076 public:
1077 SimpleTestClientImpl() : binding_(this) {}
1078
1079 void set_driver(IPC::mojom::SimpleTestDriver* driver) { driver_ = driver; }
1080 void set_sync_sender(IPC::Sender* sync_sender) { sync_sender_ = sync_sender; }
1081
rockot9abe09b2016-08-02 20:57:341082 void WaitForValueRequest() {
1083 run_loop_.reset(new base::RunLoop);
1084 run_loop_->Run();
1085 }
1086
1087 void UseSyncSenderForRequest(bool use_sync_sender) {
1088 use_sync_sender_ = use_sync_sender;
1089 }
1090
1091 private:
1092 // IPC::mojom::SimpleTestClient:
tzikdd76ce712017-06-08 05:27:041093 void RequestValue(RequestValueCallback callback) override {
rockot9abe09b2016-08-02 20:57:341094 int32_t response = 0;
1095 if (use_sync_sender_) {
1096 std::unique_ptr<IPC::SyncMessage> reply(new IPC::SyncMessage(
1097 0, 0, IPC::Message::PRIORITY_NORMAL, new SyncReplyReader(&response)));
1098 EXPECT_TRUE(sync_sender_->Send(reply.release()));
1099 } else {
1100 DCHECK(driver_);
1101 EXPECT_TRUE(driver_->RequestValue(&response));
1102 }
1103
tzikdd76ce712017-06-08 05:27:041104 std::move(callback).Run(response);
rockot9abe09b2016-08-02 20:57:341105
1106 DCHECK(run_loop_);
1107 run_loop_->Quit();
1108 }
1109
1110 // IPC::Listener:
1111 bool OnMessageReceived(const IPC::Message& message) override {
1112 int32_t response;
1113 DCHECK(driver_);
1114 EXPECT_TRUE(driver_->RequestValue(&response));
1115 std::unique_ptr<IPC::Message> reply(
1116 IPC::SyncMessage::GenerateReply(&message));
1117 reply->WriteInt(response);
1118 EXPECT_TRUE(sync_sender_->Send(reply.release()));
1119
1120 DCHECK(run_loop_);
1121 run_loop_->Quit();
1122 return true;
1123 }
1124
rockot70bbb59492017-01-25 00:56:511125 void OnAssociatedInterfaceRequest(
1126 const std::string& interface_name,
1127 mojo::ScopedInterfaceEndpointHandle handle) override {
1128 DCHECK(!binding_.is_bound());
1129 DCHECK_EQ(interface_name, IPC::mojom::SimpleTestClient::Name_);
1130
Ken Rockot96d1b7b52017-05-13 00:29:211131 binding_.Bind(
1132 IPC::mojom::SimpleTestClientAssociatedRequest(std::move(handle)));
rockot70bbb59492017-01-25 00:56:511133 }
1134
rockot9abe09b2016-08-02 20:57:341135 bool use_sync_sender_ = false;
1136 mojo::AssociatedBinding<IPC::mojom::SimpleTestClient> binding_;
1137 IPC::Sender* sync_sender_ = nullptr;
1138 IPC::mojom::SimpleTestDriver* driver_ = nullptr;
1139 std::unique_ptr<base::RunLoop> run_loop_;
1140
1141 DISALLOW_COPY_AND_ASSIGN(SimpleTestClientImpl);
1142};
1143
sammc4bcc4ed62016-10-27 10:13:591144DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(SyncAssociatedInterface,
1145 ChannelProxyClient) {
rockot9abe09b2016-08-02 20:57:341146 SimpleTestClientImpl client_impl;
1147 CreateProxy(&client_impl);
1148 client_impl.set_sync_sender(proxy());
rockot9abe09b2016-08-02 20:57:341149 RunProxy();
1150
1151 IPC::mojom::SimpleTestDriverAssociatedPtr driver;
1152 proxy()->GetRemoteAssociatedInterface(&driver);
1153 client_impl.set_driver(driver.get());
1154
1155 // Simple sync message sanity check.
1156 driver->ExpectValue(42);
1157 int32_t expected_value = 0;
1158 EXPECT_TRUE(driver->GetExpectedValue(&expected_value));
1159 EXPECT_EQ(42, expected_value);
1160 RequestQuitAndWaitForAck(driver.get());
1161
1162 // Wait for the test driver to perform a sync call test with our own sync
1163 // associated interface message nested inside.
1164 client_impl.UseSyncSenderForRequest(false);
1165 client_impl.WaitForValueRequest();
1166
1167 // Wait for the test driver to perform a sync call test with our own classical
1168 // sync IPC nested inside.
1169 client_impl.UseSyncSenderForRequest(true);
1170 client_impl.WaitForValueRequest();
1171
1172 // Wait for the test driver to perform a classical sync IPC request, with our
1173 // own sync associated interface message nested inside.
1174 client_impl.UseSyncSenderForRequest(false);
1175 client_impl.WaitForValueRequest();
1176
1177 DestroyProxy();
1178}
1179
rockot10188752016-09-08 18:24:561180TEST_F(IPCChannelProxyMojoTest, Pause) {
1181 // Ensures that pausing a channel elicits the expected behavior when sending
1182 // messages, unpausing, sending more messages, and then manually flushing.
1183 // Specifically a sequence like:
rockot401fb2c2016-09-06 18:35:571184 //
1185 // Connect()
1186 // Send(A)
rockot10188752016-09-08 18:24:561187 // Pause()
rockot401fb2c2016-09-06 18:35:571188 // Send(B)
rockot401fb2c2016-09-06 18:35:571189 // Send(C)
rockot10188752016-09-08 18:24:561190 // Unpause(false)
1191 // Send(D)
1192 // Send(E)
rockot401fb2c2016-09-06 18:35:571193 // Flush()
1194 //
rockot10188752016-09-08 18:24:561195 // must result in the other end receiving messages A, D, E, B, D; in that
rockot401fb2c2016-09-06 18:35:571196 // order.
1197 //
1198 // This behavior is required by some consumers of IPC::Channel, and it is not
1199 // sufficient to leave this up to the consumer to implement since associated
1200 // interface requests and messages also need to be queued according to the
1201 // same policy.
sammc4bcc4ed62016-10-27 10:13:591202 Init("CreatePausedClient");
rockot401fb2c2016-09-06 18:35:571203
1204 DummyListener listener;
1205 CreateProxy(&listener);
rockot10188752016-09-08 18:24:561206 RunProxy();
1207
1208 // This message must be sent immediately since the channel is unpaused.
1209 SendValue(proxy(), 1);
1210
1211 proxy()->Pause();
rockot401fb2c2016-09-06 18:35:571212
1213 // These messages must be queued internally since the channel is paused.
rockot401fb2c2016-09-06 18:35:571214 SendValue(proxy(), 2);
rockot10188752016-09-08 18:24:561215 SendValue(proxy(), 3);
rockot401fb2c2016-09-06 18:35:571216
1217 proxy()->Unpause(false /* flush */);
1218
1219 // These messages must be sent immediately since the channel is unpaused.
rockot401fb2c2016-09-06 18:35:571220 SendValue(proxy(), 4);
rockot10188752016-09-08 18:24:561221 SendValue(proxy(), 5);
rockot401fb2c2016-09-06 18:35:571222
1223 // Now we flush the previously queued messages.
1224 proxy()->Flush();
1225
1226 EXPECT_TRUE(WaitForClientShutdown());
1227 DestroyProxy();
1228}
1229
1230class ExpectValueSequenceListener : public IPC::Listener {
1231 public:
Brett Wilsona62d9c02017-09-20 20:53:201232 explicit ExpectValueSequenceListener(base::queue<int32_t>* expected_values)
rockot401fb2c2016-09-06 18:35:571233 : expected_values_(expected_values) {}
Chris Watkins2d879af2017-11-30 02:11:591234 ~ExpectValueSequenceListener() override = default;
rockot401fb2c2016-09-06 18:35:571235
1236 // IPC::Listener:
1237 bool OnMessageReceived(const IPC::Message& message) override {
1238 DCHECK(!expected_values_->empty());
1239 base::PickleIterator iter(message);
1240 int32_t should_be_expected;
1241 EXPECT_TRUE(iter.ReadInt(&should_be_expected));
1242 EXPECT_EQ(expected_values_->front(), should_be_expected);
1243 expected_values_->pop();
1244 if (expected_values_->empty())
Gabriel Charette53a9ef812017-07-26 12:36:231245 base::RunLoop::QuitCurrentWhenIdleDeprecated();
rockot401fb2c2016-09-06 18:35:571246 return true;
1247 }
1248
1249 private:
Brett Wilsona62d9c02017-09-20 20:53:201250 base::queue<int32_t>* expected_values_;
rockot401fb2c2016-09-06 18:35:571251
1252 DISALLOW_COPY_AND_ASSIGN(ExpectValueSequenceListener);
1253};
1254
sammc4bcc4ed62016-10-27 10:13:591255DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(CreatePausedClient,
1256 ChannelProxyClient) {
Brett Wilsona62d9c02017-09-20 20:53:201257 base::queue<int32_t> expected_values;
rockot401fb2c2016-09-06 18:35:571258 ExpectValueSequenceListener listener(&expected_values);
1259 CreateProxy(&listener);
rockot401fb2c2016-09-06 18:35:571260 expected_values.push(1);
rockot10188752016-09-08 18:24:561261 expected_values.push(4);
1262 expected_values.push(5);
rockot401fb2c2016-09-06 18:35:571263 expected_values.push(2);
rockot10188752016-09-08 18:24:561264 expected_values.push(3);
rockot401fb2c2016-09-06 18:35:571265 RunProxy();
1266 base::RunLoop().Run();
1267 EXPECT_TRUE(expected_values.empty());
1268 DestroyProxy();
1269}
1270
sammc5c8a6c62017-02-04 01:33:381271TEST_F(IPCChannelProxyMojoTest, AssociatedRequestClose) {
1272 Init("DropAssociatedRequest");
1273
1274 DummyListener listener;
1275 CreateProxy(&listener);
1276 RunProxy();
1277
1278 IPC::mojom::AssociatedInterfaceVendorAssociatedPtr vendor;
1279 proxy()->GetRemoteAssociatedInterface(&vendor);
1280 IPC::mojom::SimpleTestDriverAssociatedPtr tester;
yzshen1aa8e56c2017-02-16 23:15:451281 vendor->GetTestInterface(mojo::MakeRequest(&tester));
sammc5c8a6c62017-02-04 01:33:381282 base::RunLoop run_loop;
1283 tester.set_connection_error_handler(run_loop.QuitClosure());
1284 run_loop.Run();
1285
1286 proxy()->GetRemoteAssociatedInterface(&tester);
1287 EXPECT_TRUE(WaitForClientShutdown());
1288 DestroyProxy();
1289}
1290
1291class AssociatedInterfaceDroppingListener : public IPC::Listener {
1292 public:
1293 AssociatedInterfaceDroppingListener(const base::Closure& callback)
1294 : callback_(callback) {}
1295 bool OnMessageReceived(const IPC::Message& message) override { return false; }
1296
1297 void OnAssociatedInterfaceRequest(
1298 const std::string& interface_name,
1299 mojo::ScopedInterfaceEndpointHandle handle) override {
1300 if (interface_name == IPC::mojom::SimpleTestDriver::Name_)
1301 base::ResetAndReturn(&callback_).Run();
1302 }
1303
1304 private:
1305 base::Closure callback_;
1306};
1307
1308DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(DropAssociatedRequest,
1309 ChannelProxyClient) {
1310 base::RunLoop run_loop;
1311 AssociatedInterfaceDroppingListener listener(run_loop.QuitClosure());
1312 CreateProxy(&listener);
1313 RunProxy();
1314 run_loop.Run();
1315 DestroyProxy();
1316}
1317
Wez831ae412017-08-30 00:29:361318#if !defined(OS_MACOSX)
1319// TODO(wez): On Mac we need to set up a MachPortBroker before we can transfer
1320// Mach ports (which underpin Sharedmemory on Mac) across IPC.
1321
1322class ListenerThatExpectsSharedMemory : public TestListenerBase {
1323 public:
1324 ListenerThatExpectsSharedMemory(base::Closure quit_closure)
1325 : TestListenerBase(quit_closure) {}
1326
1327 bool OnMessageReceived(const IPC::Message& message) override {
1328 base::PickleIterator iter(message);
1329
1330 base::SharedMemoryHandle shared_memory;
1331 EXPECT_TRUE(IPC::ReadParam(&message, &iter, &shared_memory));
1332 EXPECT_TRUE(shared_memory.IsValid());
1333 shared_memory.Close();
1334
1335 ListenerThatExpectsOK::SendOK(sender());
1336 return true;
1337 }
1338};
1339
1340TEST_F(IPCChannelMojoTest, SendSharedMemory) {
1341 Init("IPCChannelMojoTestSendSharedMemoryClient");
1342
1343 // Create some shared-memory to share.
1344 base::SharedMemoryCreateOptions options;
1345 options.size = 1004;
1346
1347 base::SharedMemory shmem;
1348 ASSERT_TRUE(shmem.Create(options));
1349
1350 // Create a success listener, and launch the child process.
1351 base::RunLoop run_loop;
1352 ListenerThatExpectsOK listener(run_loop.QuitClosure());
1353 CreateChannel(&listener);
1354 ASSERT_TRUE(ConnectChannel());
1355
1356 // Send the child process an IPC with |shmem| attached, to verify
1357 // that is is correctly wrapped, transferred and unwrapped.
1358 IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
1359 IPC::WriteParam(message, shmem.handle());
1360 ASSERT_TRUE(channel()->Send(message));
1361
1362 run_loop.Run();
1363
1364 channel()->Close();
1365
1366 EXPECT_TRUE(WaitForClientShutdown());
1367 DestroyChannel();
1368}
1369
1370DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendSharedMemoryClient) {
1371 base::RunLoop run_loop;
1372 ListenerThatExpectsSharedMemory listener(run_loop.QuitClosure());
1373 Connect(&listener);
1374 listener.set_sender(channel());
1375
1376 run_loop.Run();
1377
1378 Close();
1379}
1380
Alexandr Ilind497eee2018-04-19 22:50:541381template <class SharedMemoryRegionType>
1382class IPCChannelMojoSharedMemoryRegionTypedTest : public IPCChannelMojoTest {};
1383
1384struct WritableRegionTraits {
1385 using RegionType = base::WritableSharedMemoryRegion;
1386 static const char kClientName[];
1387};
1388const char WritableRegionTraits::kClientName[] =
1389 "IPCChannelMojoTestSendWritableSharedMemoryRegionClient";
1390struct UnsafeRegionTraits {
1391 using RegionType = base::UnsafeSharedMemoryRegion;
1392 static const char kClientName[];
1393};
1394const char UnsafeRegionTraits::kClientName[] =
1395 "IPCChannelMojoTestSendUnsafeSharedMemoryRegionClient";
1396struct ReadOnlyRegionTraits {
1397 using RegionType = base::ReadOnlySharedMemoryRegion;
1398 static const char kClientName[];
1399};
1400const char ReadOnlyRegionTraits::kClientName[] =
1401 "IPCChannelMojoTestSendReadOnlySharedMemoryRegionClient";
1402
1403typedef ::testing::
1404 Types<WritableRegionTraits, UnsafeRegionTraits, ReadOnlyRegionTraits>
1405 AllSharedMemoryRegionTraits;
1406TYPED_TEST_CASE(IPCChannelMojoSharedMemoryRegionTypedTest,
1407 AllSharedMemoryRegionTraits);
1408
1409template <class SharedMemoryRegionType>
1410class ListenerThatExpectsSharedMemoryRegion : public TestListenerBase {
1411 public:
1412 ListenerThatExpectsSharedMemoryRegion(base::Closure quit_closure)
1413 : TestListenerBase(std::move(quit_closure)) {}
1414
1415 bool OnMessageReceived(const IPC::Message& message) override {
1416 base::PickleIterator iter(message);
1417
1418 SharedMemoryRegionType region;
1419 EXPECT_TRUE(IPC::ReadParam(&message, &iter, &region));
1420 EXPECT_TRUE(region.IsValid());
1421
1422 // Verify the shared memory region has expected content.
1423 typename SharedMemoryRegionType::MappingType mapping = region.Map();
1424 std::string content = HandleSendingHelper::GetSendingFileContent();
1425 EXPECT_EQ(0, memcmp(mapping.memory(), content.data(), content.size()));
1426
1427 ListenerThatExpectsOK::SendOK(sender());
1428 return true;
1429 }
1430};
1431
1432TYPED_TEST(IPCChannelMojoSharedMemoryRegionTypedTest, Send) {
1433 this->Init(TypeParam::kClientName);
1434
1435 const size_t size = 1004;
1436 typename TypeParam::RegionType region;
1437 base::WritableSharedMemoryMapping mapping;
1438 std::tie(region, mapping) =
1439 base::CreateMappedRegion<typename TypeParam::RegionType>(size);
1440
1441 std::string content = HandleSendingHelper::GetSendingFileContent();
1442 memcpy(mapping.memory(), content.data(), content.size());
1443
1444 // Create a success listener, and launch the child process.
1445 base::RunLoop run_loop;
1446 ListenerThatExpectsOK listener(run_loop.QuitClosure());
1447 this->CreateChannel(&listener);
1448 ASSERT_TRUE(this->ConnectChannel());
1449
1450 // Send the child process an IPC with |shmem| attached, to verify
1451 // that is is correctly wrapped, transferred and unwrapped.
1452 IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
1453 IPC::WriteParam(message, region);
1454 ASSERT_TRUE(this->channel()->Send(message));
1455
1456 run_loop.Run();
1457
1458 this->channel()->Close();
1459
1460 EXPECT_TRUE(this->WaitForClientShutdown());
1461 EXPECT_FALSE(region.IsValid());
1462 this->DestroyChannel();
1463}
1464
1465DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
1466 IPCChannelMojoTestSendWritableSharedMemoryRegionClient) {
1467 base::RunLoop run_loop;
1468 ListenerThatExpectsSharedMemoryRegion<base::WritableSharedMemoryRegion>
1469 listener(run_loop.QuitClosure());
1470 Connect(&listener);
1471 listener.set_sender(channel());
1472
1473 run_loop.Run();
1474
1475 Close();
1476}
1477DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
1478 IPCChannelMojoTestSendUnsafeSharedMemoryRegionClient) {
1479 base::RunLoop run_loop;
1480 ListenerThatExpectsSharedMemoryRegion<base::UnsafeSharedMemoryRegion>
1481 listener(run_loop.QuitClosure());
1482 Connect(&listener);
1483 listener.set_sender(channel());
1484
1485 run_loop.Run();
1486
1487 Close();
1488}
1489DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
1490 IPCChannelMojoTestSendReadOnlySharedMemoryRegionClient) {
1491 base::RunLoop run_loop;
1492 ListenerThatExpectsSharedMemoryRegion<base::ReadOnlySharedMemoryRegion>
1493 listener(run_loop.QuitClosure());
1494 Connect(&listener);
1495 listener.set_sender(channel());
1496
1497 run_loop.Run();
1498
1499 Close();
1500}
Wez831ae412017-08-30 00:29:361501#endif // !defined(OS_MACOSX)
1502
[email protected]64860882014-08-04 23:44:171503#if defined(OS_POSIX)
rockot8d890f62016-07-14 16:37:141504
Wez831ae412017-08-30 00:29:361505class ListenerThatExpectsFile : public TestListenerBase {
[email protected]64860882014-08-04 23:44:171506 public:
Wez831ae412017-08-30 00:29:361507 ListenerThatExpectsFile(base::Closure quit_closure)
1508 : TestListenerBase(quit_closure) {}
[email protected]64860882014-08-04 23:44:171509
dchengfe61fca2014-10-22 02:29:521510 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:251511 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:301512 HandleSendingHelper::ReadReceivedFile(message, &iter);
Wez831ae412017-08-30 00:29:361513 ListenerThatExpectsOK::SendOK(sender());
[email protected]64860882014-08-04 23:44:171514 return true;
1515 }
[email protected]64860882014-08-04 23:44:171516};
1517
Wez831ae412017-08-30 00:29:361518TEST_F(IPCChannelMojoTest, SendPlatformFile) {
1519 Init("IPCChannelMojoTestSendPlatformFileClient");
[email protected]64860882014-08-04 23:44:171520
Wez831ae412017-08-30 00:29:361521 base::RunLoop run_loop;
1522 ListenerThatExpectsOK listener(run_loop.QuitClosure());
morrita373af03b2014-09-09 19:35:241523 CreateChannel(&listener);
[email protected]64860882014-08-04 23:44:171524 ASSERT_TRUE(ConnectChannel());
[email protected]64860882014-08-04 23:44:171525
amistry20e2b1d62016-06-23 06:12:351526 base::ScopedTempDir temp_dir;
1527 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
vabr16e5f602016-09-15 18:14:001528 base::File file(HandleSendingHelper::GetSendingFilePath(temp_dir.GetPath()),
[email protected]64860882014-08-04 23:44:171529 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
morrita81b17e02015-02-06 00:58:301530 base::File::FLAG_READ);
1531 HandleSendingHelper::WriteFileThenSend(channel(), file);
Wez831ae412017-08-30 00:29:361532 run_loop.Run();
[email protected]64860882014-08-04 23:44:171533
sammc57ed9f982016-03-10 06:28:351534 channel()->Close();
[email protected]64860882014-08-04 23:44:171535
1536 EXPECT_TRUE(WaitForClientShutdown());
1537 DestroyChannel();
1538}
1539
Wez831ae412017-08-30 00:29:361540DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendPlatformFileClient) {
1541 base::RunLoop run_loop;
1542 ListenerThatExpectsFile listener(run_loop.QuitClosure());
sammc57ed9f982016-03-10 06:28:351543 Connect(&listener);
1544 listener.set_sender(channel());
[email protected]64860882014-08-04 23:44:171545
Wez831ae412017-08-30 00:29:361546 run_loop.Run();
[email protected]64860882014-08-04 23:44:171547
sammc57ed9f982016-03-10 06:28:351548 Close();
[email protected]64860882014-08-04 23:44:171549}
morrita81b17e02015-02-06 00:58:301550
Wez831ae412017-08-30 00:29:361551class ListenerThatExpectsFileAndMessagePipe : public TestListenerBase {
morrita81b17e02015-02-06 00:58:301552 public:
Wez831ae412017-08-30 00:29:361553 ListenerThatExpectsFileAndMessagePipe(base::Closure quit_closure)
1554 : TestListenerBase(quit_closure) {}
morrita81b17e02015-02-06 00:58:301555
Chris Watkins2d879af2017-11-30 02:11:591556 ~ListenerThatExpectsFileAndMessagePipe() override = default;
morrita81b17e02015-02-06 00:58:301557
1558 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:251559 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:301560 HandleSendingHelper::ReadReceivedFile(message, &iter);
1561 HandleSendingHelper::ReadReceivedPipe(message, &iter);
Wez831ae412017-08-30 00:29:361562 ListenerThatExpectsOK::SendOK(sender());
morrita81b17e02015-02-06 00:58:301563 return true;
1564 }
morrita81b17e02015-02-06 00:58:301565};
1566
Wez831ae412017-08-30 00:29:361567TEST_F(IPCChannelMojoTest, SendPlatformFileAndMessagePipe) {
1568 Init("IPCChannelMojoTestSendPlatformFileAndMessagePipeClient");
morrita81b17e02015-02-06 00:58:301569
Wez831ae412017-08-30 00:29:361570 base::RunLoop run_loop;
1571 ListenerThatExpectsOK listener(run_loop.QuitClosure());
morrita81b17e02015-02-06 00:58:301572 CreateChannel(&listener);
1573 ASSERT_TRUE(ConnectChannel());
morrita81b17e02015-02-06 00:58:301574
amistry20e2b1d62016-06-23 06:12:351575 base::ScopedTempDir temp_dir;
1576 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
vabr16e5f602016-09-15 18:14:001577 base::File file(HandleSendingHelper::GetSendingFilePath(temp_dir.GetPath()),
morrita81b17e02015-02-06 00:58:301578 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
1579 base::File::FLAG_READ);
1580 TestingMessagePipe pipe;
1581 HandleSendingHelper::WriteFileAndPipeThenSend(channel(), file, &pipe);
1582
Wez831ae412017-08-30 00:29:361583 run_loop.Run();
sammc57ed9f982016-03-10 06:28:351584 channel()->Close();
morrita81b17e02015-02-06 00:58:301585
1586 EXPECT_TRUE(WaitForClientShutdown());
1587 DestroyChannel();
1588}
1589
sammc57ed9f982016-03-10 06:28:351590DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
Wez831ae412017-08-30 00:29:361591 IPCChannelMojoTestSendPlatformFileAndMessagePipeClient) {
1592 base::RunLoop run_loop;
1593 ListenerThatExpectsFileAndMessagePipe listener(run_loop.QuitClosure());
sammc57ed9f982016-03-10 06:28:351594 Connect(&listener);
1595 listener.set_sender(channel());
morrita81b17e02015-02-06 00:58:301596
Wez831ae412017-08-30 00:29:361597 run_loop.Run();
morrita81b17e02015-02-06 00:58:301598
sammc57ed9f982016-03-10 06:28:351599 Close();
morrita81b17e02015-02-06 00:58:301600}
1601
rockot7c6bf952016-07-14 00:34:111602#endif // defined(OS_POSIX)
[email protected]64860882014-08-04 23:44:171603
morrita0bd20bd2015-02-25 20:11:271604#if defined(OS_LINUX)
1605
1606const base::ProcessId kMagicChildId = 54321;
1607
Wez831ae412017-08-30 00:29:361608class ListenerThatVerifiesPeerPid : public TestListenerBase {
morrita0bd20bd2015-02-25 20:11:271609 public:
Wez831ae412017-08-30 00:29:361610 ListenerThatVerifiesPeerPid(base::Closure quit_closure)
1611 : TestListenerBase(quit_closure) {}
1612
tfarina10a5c062015-09-04 18:47:571613 void OnChannelConnected(int32_t peer_pid) override {
morrita0bd20bd2015-02-25 20:11:271614 EXPECT_EQ(peer_pid, kMagicChildId);
Wez831ae412017-08-30 00:29:361615 quit_closure().Run();
morrita0bd20bd2015-02-25 20:11:271616 }
1617
1618 bool OnMessageReceived(const IPC::Message& message) override {
1619 NOTREACHED();
1620 return true;
1621 }
1622};
1623
sammc57ed9f982016-03-10 06:28:351624TEST_F(IPCChannelMojoTest, VerifyGlobalPid) {
sammc4bcc4ed62016-10-27 10:13:591625 Init("IPCChannelMojoTestVerifyGlobalPidClient");
morrita0bd20bd2015-02-25 20:11:271626
Wez831ae412017-08-30 00:29:361627 base::RunLoop run_loop;
1628 ListenerThatVerifiesPeerPid listener(run_loop.QuitClosure());
morrita0bd20bd2015-02-25 20:11:271629 CreateChannel(&listener);
1630 ASSERT_TRUE(ConnectChannel());
morrita0bd20bd2015-02-25 20:11:271631
Wez831ae412017-08-30 00:29:361632 run_loop.Run();
rockotcbca72f2015-03-03 16:31:041633 channel()->Close();
morrita0bd20bd2015-02-25 20:11:271634
1635 EXPECT_TRUE(WaitForClientShutdown());
1636 DestroyChannel();
1637}
1638
sammc4bcc4ed62016-10-27 10:13:591639DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestVerifyGlobalPidClient) {
morrita0bd20bd2015-02-25 20:11:271640 IPC::Channel::SetGlobalPid(kMagicChildId);
Wez831ae412017-08-30 00:29:361641
1642 base::RunLoop run_loop;
1643 ListenerThatQuits listener(run_loop.QuitClosure());
sammc57ed9f982016-03-10 06:28:351644 Connect(&listener);
morrita0bd20bd2015-02-25 20:11:271645
Wez831ae412017-08-30 00:29:361646 run_loop.Run();
morrita0bd20bd2015-02-25 20:11:271647
sammc57ed9f982016-03-10 06:28:351648 Close();
morrita0bd20bd2015-02-25 20:11:271649}
1650
sammc57ed9f982016-03-10 06:28:351651#endif // OS_LINUX
morrita0bd20bd2015-02-25 20:11:271652
[email protected]64860882014-08-04 23:44:171653} // namespace