blob: 869d21ca14dec45e59b2b711021b1e7c4629aa78 [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"
Wez831ae412017-08-30 00:29:3621#include "base/memory/shared_memory.h"
rockot8d890f62016-07-14 16:37:1422#include "base/message_loop/message_loop.h"
[email protected]64860882014-08-04 23:44:1723#include "base/path_service.h"
24#include "base/pickle.h"
rockotcbca72f2015-03-03 16:31:0425#include "base/run_loop.h"
skyostile687bdff2015-05-12 11:29:2126#include "base/single_thread_task_runner.h"
rockot7c6bf952016-07-14 00:34:1127#include "base/strings/stringprintf.h"
rockot9abe09b2016-08-02 20:57:3428#include "base/synchronization/waitable_event.h"
sammc57ed9f982016-03-10 06:28:3529#include "base/test/test_io_thread.h"
morrita0bd20bd2015-02-25 20:11:2730#include "base/test/test_timeouts.h"
[email protected]64860882014-08-04 23:44:1731#include "base/threading/thread.h"
gabf08ccc02016-05-11 18:51:1132#include "base/threading/thread_task_runner_handle.h"
avi246998d82015-12-22 02:39:0433#include "build/build_config.h"
[email protected]64860882014-08-04 23:44:1734#include "ipc/ipc_message.h"
Wez831ae412017-08-30 00:29:3635#include "ipc/ipc_message_utils.h"
amistryd4aa70d2016-06-23 07:52:3736#include "ipc/ipc_mojo_handle_attachment.h"
37#include "ipc/ipc_mojo_message_helper.h"
38#include "ipc/ipc_mojo_param_traits.h"
rockot9abe09b2016-08-02 20:57:3439#include "ipc/ipc_sync_channel.h"
40#include "ipc/ipc_sync_message.h"
rockot7c6bf952016-07-14 00:34:1141#include "ipc/ipc_test.mojom.h"
[email protected]64860882014-08-04 23:44:1742#include "ipc/ipc_test_base.h"
43#include "ipc/ipc_test_channel_listener.h"
rockota9d566a2017-03-17 19:36:1544#include "mojo/public/cpp/system/wait.h"
sammc57ed9f982016-03-10 06:28:3545#include "testing/gtest/include/gtest/gtest.h"
[email protected]64860882014-08-04 23:44:1746
47#if defined(OS_POSIX)
48#include "base/file_descriptor_posix.h"
morrita1aa788c2015-01-31 05:45:4249#include "ipc/ipc_platform_file_attachment_posix.h"
[email protected]64860882014-08-04 23:44:1750#endif
51
52namespace {
53
rockot7c6bf952016-07-14 00:34:1154void SendString(IPC::Sender* sender, const std::string& str) {
55 IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
56 message->WriteString(str);
57 ASSERT_TRUE(sender->Send(message));
58}
59
rockot9abe09b2016-08-02 20:57:3460void SendValue(IPC::Sender* sender, int32_t value) {
61 IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
62 message->WriteInt(value);
63 ASSERT_TRUE(sender->Send(message));
64}
65
[email protected]64860882014-08-04 23:44:1766class ListenerThatExpectsOK : public IPC::Listener {
67 public:
Wez831ae412017-08-30 00:29:3668 ListenerThatExpectsOK(base::Closure quit_closure)
69 : received_ok_(false), quit_closure_(quit_closure) {}
[email protected]64860882014-08-04 23:44:1770
dchengfe61fca2014-10-22 02:29:5271 ~ListenerThatExpectsOK() override {}
[email protected]64860882014-08-04 23:44:1772
dchengfe61fca2014-10-22 02:29:5273 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:2574 base::PickleIterator iter(message);
[email protected]64860882014-08-04 23:44:1775 std::string should_be_ok;
76 EXPECT_TRUE(iter.ReadString(&should_be_ok));
77 EXPECT_EQ(should_be_ok, "OK");
[email protected]e5c27752014-08-08 21:45:1378 received_ok_ = true;
Wez831ae412017-08-30 00:29:3679 quit_closure_.Run();
[email protected]64860882014-08-04 23:44:1780 return true;
81 }
82
dchengfe61fca2014-10-22 02:29:5283 void OnChannelError() override {
[email protected]e5c27752014-08-08 21:45:1384 // The connection should be healthy while the listener is waiting
85 // message. An error can occur after that because the peer
86 // process dies.
87 DCHECK(received_ok_);
[email protected]64860882014-08-04 23:44:1788 }
89
rockot7c6bf952016-07-14 00:34:1190 static void SendOK(IPC::Sender* sender) { SendString(sender, "OK"); }
[email protected]e5c27752014-08-08 21:45:1391
92 private:
93 bool received_ok_;
Wez831ae412017-08-30 00:29:3694 base::Closure quit_closure_;
95};
96
97class TestListenerBase : public IPC::Listener {
98 public:
99 TestListenerBase(base::Closure quit_closure) : quit_closure_(quit_closure) {}
100
101 ~TestListenerBase() override {}
102
103 void OnChannelError() override { quit_closure_.Run(); }
104
105 void set_sender(IPC::Sender* sender) { sender_ = sender; }
106 IPC::Sender* sender() const { return sender_; }
107 base::Closure quit_closure() const { return quit_closure_; }
108
109 private:
110 IPC::Sender* sender_ = nullptr;
111 base::Closure quit_closure_;
[email protected]64860882014-08-04 23:44:17112};
113
sammc4bcc4ed62016-10-27 10:13:59114using IPCChannelMojoTest = IPCChannelMojoTestBase;
rockotcbca72f2015-03-03 16:31:04115
[email protected]64860882014-08-04 23:44:17116class TestChannelListenerWithExtraExpectations
117 : public IPC::TestChannelListener {
118 public:
sammc57ed9f982016-03-10 06:28:35119 TestChannelListenerWithExtraExpectations() : is_connected_called_(false) {}
[email protected]64860882014-08-04 23:44:17120
tfarina10a5c062015-09-04 18:47:57121 void OnChannelConnected(int32_t peer_pid) override {
[email protected]64860882014-08-04 23:44:17122 IPC::TestChannelListener::OnChannelConnected(peer_pid);
123 EXPECT_TRUE(base::kNullProcessId != peer_pid);
124 is_connected_called_ = true;
125 }
126
127 bool is_connected_called() const { return is_connected_called_; }
128
129 private:
130 bool is_connected_called_;
131};
132
amistry0027a0952016-05-03 00:52:47133TEST_F(IPCChannelMojoTest, ConnectedFromClient) {
sammc4bcc4ed62016-10-27 10:13:59134 Init("IPCChannelMojoTestClient");
[email protected]64860882014-08-04 23:44:17135
136 // Set up IPC channel and start client.
137 TestChannelListenerWithExtraExpectations listener;
morrita373af03b2014-09-09 19:35:24138 CreateChannel(&listener);
[email protected]64860882014-08-04 23:44:17139 listener.Init(sender());
140 ASSERT_TRUE(ConnectChannel());
[email protected]64860882014-08-04 23:44:17141
sammc57ed9f982016-03-10 06:28:35142 IPC::TestChannelListener::SendOneMessage(sender(), "hello from parent");
[email protected]64860882014-08-04 23:44:17143
fdoray8e32586852016-06-22 19:56:16144 base::RunLoop().Run();
[email protected]64860882014-08-04 23:44:17145
sammc57ed9f982016-03-10 06:28:35146 channel()->Close();
[email protected]64860882014-08-04 23:44:17147
148 EXPECT_TRUE(WaitForClientShutdown());
149 EXPECT_TRUE(listener.is_connected_called());
150 EXPECT_TRUE(listener.HasSentAll());
151
152 DestroyChannel();
153}
154
155// A long running process that connects to us
sammc4bcc4ed62016-10-27 10:13:59156DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestClient) {
[email protected]64860882014-08-04 23:44:17157 TestChannelListenerWithExtraExpectations listener;
sammc57ed9f982016-03-10 06:28:35158 Connect(&listener);
159 listener.Init(channel());
[email protected]64860882014-08-04 23:44:17160
sammc57ed9f982016-03-10 06:28:35161 IPC::TestChannelListener::SendOneMessage(channel(), "hello from child");
fdoray8e32586852016-06-22 19:56:16162 base::RunLoop().Run();
[email protected]64860882014-08-04 23:44:17163 EXPECT_TRUE(listener.is_connected_called());
164 EXPECT_TRUE(listener.HasSentAll());
165
sammc57ed9f982016-03-10 06:28:35166 Close();
[email protected]64860882014-08-04 23:44:17167}
168
Wez831ae412017-08-30 00:29:36169class ListenerExpectingErrors : public TestListenerBase {
morrita0a24cfc92014-09-16 03:20:48170 public:
Wez831ae412017-08-30 00:29:36171 ListenerExpectingErrors(base::Closure quit_closure)
172 : TestListenerBase(quit_closure), has_error_(false) {}
morrita0a24cfc92014-09-16 03:20:48173
dchengfe61fca2014-10-22 02:29:52174 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita0a24cfc92014-09-16 03:20:48175
dchengfe61fca2014-10-22 02:29:52176 void OnChannelError() override {
morrita0a24cfc92014-09-16 03:20:48177 has_error_ = true;
Wez831ae412017-08-30 00:29:36178 TestListenerBase::OnChannelError();
morrita0a24cfc92014-09-16 03:20:48179 }
180
181 bool has_error() const { return has_error_; }
182
183 private:
184 bool has_error_;
185};
186
morrita0a24cfc92014-09-16 03:20:48187class ListenerThatQuits : public IPC::Listener {
188 public:
Wez831ae412017-08-30 00:29:36189 ListenerThatQuits(base::Closure quit_closure) : quit_closure_(quit_closure) {}
morrita0a24cfc92014-09-16 03:20:48190
sammc57ed9f982016-03-10 06:28:35191 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita0a24cfc92014-09-16 03:20:48192
Wez831ae412017-08-30 00:29:36193 void OnChannelConnected(int32_t peer_pid) override { quit_closure_.Run(); }
194
195 private:
196 base::Closure quit_closure_;
morrita0a24cfc92014-09-16 03:20:48197};
198
199// A long running process that connects to us.
sammc4bcc4ed62016-10-27 10:13:59200DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoErraticTestClient) {
Wez831ae412017-08-30 00:29:36201 base::RunLoop run_loop;
202 ListenerThatQuits listener(run_loop.QuitClosure());
sammc57ed9f982016-03-10 06:28:35203 Connect(&listener);
morrita0a24cfc92014-09-16 03:20:48204
Wez831ae412017-08-30 00:29:36205 run_loop.Run();
morrita0a24cfc92014-09-16 03:20:48206
sammc57ed9f982016-03-10 06:28:35207 Close();
morrita0a24cfc92014-09-16 03:20:48208}
209
rockot8c23d462016-07-25 17:33:04210TEST_F(IPCChannelMojoTest, SendFailWithPendingMessages) {
sammc4bcc4ed62016-10-27 10:13:59211 Init("IPCChannelMojoErraticTestClient");
morrita0a24cfc92014-09-16 03:20:48212
213 // Set up IPC channel and start client.
Wez831ae412017-08-30 00:29:36214 base::RunLoop run_loop;
215 ListenerExpectingErrors listener(run_loop.QuitClosure());
morrita0a24cfc92014-09-16 03:20:48216 CreateChannel(&listener);
217 ASSERT_TRUE(ConnectChannel());
218
jamesra03ae492014-10-03 04:26:48219 // This matches a value in mojo/edk/system/constants.h
morritabe6c4cc2014-09-24 23:38:44220 const int kMaxMessageNumBytes = 4 * 1024 * 1024;
221 std::string overly_large_data(kMaxMessageNumBytes, '*');
morrita0a24cfc92014-09-16 03:20:48222 // This messages are queued as pending.
morritabe6c4cc2014-09-24 23:38:44223 for (size_t i = 0; i < 10; ++i) {
sammc57ed9f982016-03-10 06:28:35224 IPC::TestChannelListener::SendOneMessage(sender(),
225 overly_large_data.c_str());
morrita0a24cfc92014-09-16 03:20:48226 }
227
Wez831ae412017-08-30 00:29:36228 run_loop.Run();
morrita0a24cfc92014-09-16 03:20:48229
sammc57ed9f982016-03-10 06:28:35230 channel()->Close();
morrita0a24cfc92014-09-16 03:20:48231
232 EXPECT_TRUE(WaitForClientShutdown());
233 EXPECT_TRUE(listener.has_error());
234
235 DestroyChannel();
236}
237
morrita81b17e02015-02-06 00:58:30238struct TestingMessagePipe {
239 TestingMessagePipe() {
240 EXPECT_EQ(MOJO_RESULT_OK, mojo::CreateMessagePipe(nullptr, &self, &peer));
241 }
242
243 mojo::ScopedMessagePipeHandle self;
244 mojo::ScopedMessagePipeHandle peer;
245};
246
247class HandleSendingHelper {
248 public:
249 static std::string GetSendingFileContent() { return "Hello"; }
250
251 static void WritePipe(IPC::Message* message, TestingMessagePipe* pipe) {
252 std::string content = HandleSendingHelper::GetSendingFileContent();
253 EXPECT_EQ(MOJO_RESULT_OK,
254 mojo::WriteMessageRaw(pipe->self.get(), &content[0],
255 static_cast<uint32_t>(content.size()),
256 nullptr, 0, 0));
dchenge48600452015-12-28 02:24:50257 EXPECT_TRUE(IPC::MojoMessageHelper::WriteMessagePipeTo(
258 message, std::move(pipe->peer)));
morrita81b17e02015-02-06 00:58:30259 }
260
261 static void WritePipeThenSend(IPC::Sender* sender, TestingMessagePipe* pipe) {
262 IPC::Message* message =
263 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
264 WritePipe(message, pipe);
265 ASSERT_TRUE(sender->Send(message));
266 }
267
268 static void ReadReceivedPipe(const IPC::Message& message,
brettwbd4d7112015-06-03 04:29:25269 base::PickleIterator* iter) {
morrita81b17e02015-02-06 00:58:30270 mojo::ScopedMessagePipeHandle pipe;
271 EXPECT_TRUE(
272 IPC::MojoMessageHelper::ReadMessagePipeFrom(&message, iter, &pipe));
Ken Rockotfada7d282017-06-12 21:25:13273 std::vector<uint8_t> content;
morrita81b17e02015-02-06 00:58:30274
sammc57ed9f982016-03-10 06:28:35275 ASSERT_EQ(MOJO_RESULT_OK,
rockota9d566a2017-03-17 19:36:15276 mojo::Wait(pipe.get(), MOJO_HANDLE_SIGNAL_READABLE));
morrita81b17e02015-02-06 00:58:30277 EXPECT_EQ(MOJO_RESULT_OK,
Ken Rockotfada7d282017-06-12 21:25:13278 mojo::ReadMessageRaw(pipe.get(), &content, nullptr, 0));
279 EXPECT_EQ(std::string(content.begin(), content.end()),
280 GetSendingFileContent());
morrita81b17e02015-02-06 00:58:30281 }
282
283#if defined(OS_POSIX)
amistry20e2b1d62016-06-23 06:12:35284 static base::FilePath GetSendingFilePath(const base::FilePath& dir_path) {
285 return dir_path.Append("ListenerThatExpectsFile.txt");
morrita81b17e02015-02-06 00:58:30286 }
287
288 static void WriteFile(IPC::Message* message, base::File& file) {
289 std::string content = GetSendingFileContent();
290 file.WriteAtCurrentPos(content.data(), content.size());
291 file.Flush();
292 message->WriteAttachment(new IPC::internal::PlatformFileAttachment(
293 base::ScopedFD(file.TakePlatformFile())));
294 }
295
296 static void WriteFileThenSend(IPC::Sender* sender, base::File& file) {
297 IPC::Message* message =
298 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
299 WriteFile(message, file);
300 ASSERT_TRUE(sender->Send(message));
301 }
302
303 static void WriteFileAndPipeThenSend(IPC::Sender* sender,
304 base::File& file,
305 TestingMessagePipe* pipe) {
306 IPC::Message* message =
307 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
308 WriteFile(message, file);
309 WritePipe(message, pipe);
310 ASSERT_TRUE(sender->Send(message));
311 }
312
313 static void ReadReceivedFile(const IPC::Message& message,
brettwbd4d7112015-06-03 04:29:25314 base::PickleIterator* iter) {
rockot502c94f2016-02-03 20:20:16315 scoped_refptr<base::Pickle::Attachment> attachment;
morrita81b17e02015-02-06 00:58:30316 EXPECT_TRUE(message.ReadAttachment(iter, &attachment));
sammc6ed3efb2016-11-23 03:17:35317 EXPECT_EQ(
318 IPC::MessageAttachment::Type::PLATFORM_FILE,
319 static_cast<IPC::MessageAttachment*>(attachment.get())->GetType());
320 base::File file(
321 static_cast<IPC::internal::PlatformFileAttachment*>(attachment.get())
322 ->TakePlatformFile());
morrita81b17e02015-02-06 00:58:30323 std::string content(GetSendingFileContent().size(), ' ');
324 file.Read(0, &content[0], content.size());
325 EXPECT_EQ(content, GetSendingFileContent());
326 }
327#endif
328};
329
Wez831ae412017-08-30 00:29:36330class ListenerThatExpectsMessagePipe : public TestListenerBase {
morrita81b17e02015-02-06 00:58:30331 public:
Wez831ae412017-08-30 00:29:36332 ListenerThatExpectsMessagePipe(base::Closure quit_closure)
333 : TestListenerBase(quit_closure) {}
morrita81b17e02015-02-06 00:58:30334
335 ~ListenerThatExpectsMessagePipe() override {}
336
337 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25338 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:30339 HandleSendingHelper::ReadReceivedPipe(message, &iter);
Wez831ae412017-08-30 00:29:36340 ListenerThatExpectsOK::SendOK(sender());
morrita81b17e02015-02-06 00:58:30341 return true;
342 }
morrita81b17e02015-02-06 00:58:30343};
344
amistry0027a0952016-05-03 00:52:47345TEST_F(IPCChannelMojoTest, SendMessagePipe) {
sammc4bcc4ed62016-10-27 10:13:59346 Init("IPCChannelMojoTestSendMessagePipeClient");
morrita81b17e02015-02-06 00:58:30347
Wez831ae412017-08-30 00:29:36348 base::RunLoop run_loop;
349 ListenerThatExpectsOK listener(run_loop.QuitClosure());
morrita81b17e02015-02-06 00:58:30350 CreateChannel(&listener);
351 ASSERT_TRUE(ConnectChannel());
morrita81b17e02015-02-06 00:58:30352
353 TestingMessagePipe pipe;
354 HandleSendingHelper::WritePipeThenSend(channel(), &pipe);
355
Wez831ae412017-08-30 00:29:36356 run_loop.Run();
sammc57ed9f982016-03-10 06:28:35357 channel()->Close();
morrita81b17e02015-02-06 00:58:30358
359 EXPECT_TRUE(WaitForClientShutdown());
360 DestroyChannel();
361}
362
sammc4bcc4ed62016-10-27 10:13:59363DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendMessagePipeClient) {
Wez831ae412017-08-30 00:29:36364 base::RunLoop run_loop;
365 ListenerThatExpectsMessagePipe listener(run_loop.QuitClosure());
sammc57ed9f982016-03-10 06:28:35366 Connect(&listener);
367 listener.set_sender(channel());
morrita81b17e02015-02-06 00:58:30368
Wez831ae412017-08-30 00:29:36369 run_loop.Run();
morrita81b17e02015-02-06 00:58:30370
sammc57ed9f982016-03-10 06:28:35371 Close();
morrita81b17e02015-02-06 00:58:30372}
373
morrita438a2ee2015-04-03 05:28:21374void ReadOK(mojo::MessagePipeHandle pipe) {
Ken Rockotfada7d282017-06-12 21:25:13375 std::vector<uint8_t> should_be_ok;
rockota9d566a2017-03-17 19:36:15376 CHECK_EQ(MOJO_RESULT_OK, mojo::Wait(pipe, MOJO_HANDLE_SIGNAL_READABLE));
morrita438a2ee2015-04-03 05:28:21377 CHECK_EQ(MOJO_RESULT_OK,
Ken Rockotfada7d282017-06-12 21:25:13378 mojo::ReadMessageRaw(pipe, &should_be_ok, nullptr, 0));
379 EXPECT_EQ("OK", std::string(should_be_ok.begin(), should_be_ok.end()));
morrita438a2ee2015-04-03 05:28:21380}
381
382void WriteOK(mojo::MessagePipeHandle pipe) {
383 std::string ok("OK");
384 CHECK_EQ(MOJO_RESULT_OK,
385 mojo::WriteMessageRaw(pipe, &ok[0], static_cast<uint32_t>(ok.size()),
386 nullptr, 0, 0));
387}
388
Wez831ae412017-08-30 00:29:36389class ListenerThatExpectsMessagePipeUsingParamTrait : public TestListenerBase {
morrita438a2ee2015-04-03 05:28:21390 public:
Wez831ae412017-08-30 00:29:36391 explicit ListenerThatExpectsMessagePipeUsingParamTrait(
392 base::Closure quit_closure,
393 bool receiving_valid)
394 : TestListenerBase(quit_closure), receiving_valid_(receiving_valid) {}
morrita438a2ee2015-04-03 05:28:21395
396 ~ListenerThatExpectsMessagePipeUsingParamTrait() override {}
397
398 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25399 base::PickleIterator iter(message);
morrita438a2ee2015-04-03 05:28:21400 mojo::MessagePipeHandle handle;
401 EXPECT_TRUE(IPC::ParamTraits<mojo::MessagePipeHandle>::Read(&message, &iter,
402 &handle));
403 EXPECT_EQ(handle.is_valid(), receiving_valid_);
404 if (receiving_valid_) {
405 ReadOK(handle);
406 MojoClose(handle.value());
407 }
408
Wez831ae412017-08-30 00:29:36409 ListenerThatExpectsOK::SendOK(sender());
morrita438a2ee2015-04-03 05:28:21410 return true;
411 }
412
morrita438a2ee2015-04-03 05:28:21413 private:
morrita438a2ee2015-04-03 05:28:21414 bool receiving_valid_;
415};
416
sammc4bcc4ed62016-10-27 10:13:59417class ParamTraitMessagePipeClient : public IpcChannelMojoTestClient {
sammc57ed9f982016-03-10 06:28:35418 public:
419 void RunTest(bool receiving_valid_handle) {
Wez831ae412017-08-30 00:29:36420 base::RunLoop run_loop;
sammc57ed9f982016-03-10 06:28:35421 ListenerThatExpectsMessagePipeUsingParamTrait listener(
Wez831ae412017-08-30 00:29:36422 run_loop.QuitClosure(), receiving_valid_handle);
sammc57ed9f982016-03-10 06:28:35423 Connect(&listener);
424 listener.set_sender(channel());
morrita438a2ee2015-04-03 05:28:21425
Wez831ae412017-08-30 00:29:36426 run_loop.Run();
morrita438a2ee2015-04-03 05:28:21427
sammc57ed9f982016-03-10 06:28:35428 Close();
429 }
430};
morrita438a2ee2015-04-03 05:28:21431
amistry0027a0952016-05-03 00:52:47432TEST_F(IPCChannelMojoTest, ParamTraitValidMessagePipe) {
sammc4bcc4ed62016-10-27 10:13:59433 Init("ParamTraitValidMessagePipeClient");
morrita438a2ee2015-04-03 05:28:21434
Wez831ae412017-08-30 00:29:36435 base::RunLoop run_loop;
436 ListenerThatExpectsOK listener(run_loop.QuitClosure());
morrita438a2ee2015-04-03 05:28:21437 CreateChannel(&listener);
438 ASSERT_TRUE(ConnectChannel());
morrita438a2ee2015-04-03 05:28:21439
440 TestingMessagePipe pipe;
441
danakj03de39b22016-04-23 04:21:09442 std::unique_ptr<IPC::Message> message(new IPC::Message());
morrita438a2ee2015-04-03 05:28:21443 IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
444 pipe.peer.release());
445 WriteOK(pipe.self.get());
446
sammc57ed9f982016-03-10 06:28:35447 channel()->Send(message.release());
Wez831ae412017-08-30 00:29:36448 run_loop.Run();
sammc57ed9f982016-03-10 06:28:35449 channel()->Close();
morrita438a2ee2015-04-03 05:28:21450
451 EXPECT_TRUE(WaitForClientShutdown());
452 DestroyChannel();
453}
454
sammc4bcc4ed62016-10-27 10:13:59455DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
456 ParamTraitValidMessagePipeClient,
457 ParamTraitMessagePipeClient) {
sammc57ed9f982016-03-10 06:28:35458 RunTest(true);
morrita438a2ee2015-04-03 05:28:21459}
460
amistry0027a0952016-05-03 00:52:47461TEST_F(IPCChannelMojoTest, ParamTraitInvalidMessagePipe) {
sammc4bcc4ed62016-10-27 10:13:59462 Init("ParamTraitInvalidMessagePipeClient");
morrita438a2ee2015-04-03 05:28:21463
Wez831ae412017-08-30 00:29:36464 base::RunLoop run_loop;
465 ListenerThatExpectsOK listener(run_loop.QuitClosure());
morrita438a2ee2015-04-03 05:28:21466 CreateChannel(&listener);
467 ASSERT_TRUE(ConnectChannel());
morrita438a2ee2015-04-03 05:28:21468
469 mojo::MessagePipeHandle invalid_handle;
danakj03de39b22016-04-23 04:21:09470 std::unique_ptr<IPC::Message> message(new IPC::Message());
morrita438a2ee2015-04-03 05:28:21471 IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
472 invalid_handle);
473
sammc57ed9f982016-03-10 06:28:35474 channel()->Send(message.release());
Wez831ae412017-08-30 00:29:36475 run_loop.Run();
sammc57ed9f982016-03-10 06:28:35476 channel()->Close();
morrita438a2ee2015-04-03 05:28:21477
478 EXPECT_TRUE(WaitForClientShutdown());
479 DestroyChannel();
480}
481
sammc4bcc4ed62016-10-27 10:13:59482DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
483 ParamTraitInvalidMessagePipeClient,
484 ParamTraitMessagePipeClient) {
sammc57ed9f982016-03-10 06:28:35485 RunTest(false);
morrita438a2ee2015-04-03 05:28:21486}
487
amistry0027a0952016-05-03 00:52:47488TEST_F(IPCChannelMojoTest, SendFailAfterClose) {
sammc4bcc4ed62016-10-27 10:13:59489 Init("IPCChannelMojoTestSendOkClient");
morrita17137e62015-06-23 22:29:36490
Wez831ae412017-08-30 00:29:36491 base::RunLoop run_loop;
492 ListenerThatExpectsOK listener(run_loop.QuitClosure());
morrita17137e62015-06-23 22:29:36493 CreateChannel(&listener);
494 ASSERT_TRUE(ConnectChannel());
morrita17137e62015-06-23 22:29:36495
Wez831ae412017-08-30 00:29:36496 run_loop.Run();
sammc57ed9f982016-03-10 06:28:35497 channel()->Close();
498 ASSERT_FALSE(channel()->Send(new IPC::Message()));
morrita17137e62015-06-23 22:29:36499
500 EXPECT_TRUE(WaitForClientShutdown());
501 DestroyChannel();
502}
503
Wez831ae412017-08-30 00:29:36504class ListenerSendingOneOk : public TestListenerBase {
morrita17137e62015-06-23 22:29:36505 public:
Wez831ae412017-08-30 00:29:36506 ListenerSendingOneOk(base::Closure quit_closure)
507 : TestListenerBase(quit_closure) {}
morrita17137e62015-06-23 22:29:36508
sammc57ed9f982016-03-10 06:28:35509 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita17137e62015-06-23 22:29:36510
tfarina10a5c062015-09-04 18:47:57511 void OnChannelConnected(int32_t peer_pid) override {
Wez831ae412017-08-30 00:29:36512 ListenerThatExpectsOK::SendOK(sender());
513 quit_closure().Run();
morrita17137e62015-06-23 22:29:36514 }
morrita17137e62015-06-23 22:29:36515};
516
sammc4bcc4ed62016-10-27 10:13:59517DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendOkClient) {
Wez831ae412017-08-30 00:29:36518 base::RunLoop run_loop;
519 ListenerSendingOneOk listener(run_loop.QuitClosure());
sammc57ed9f982016-03-10 06:28:35520 Connect(&listener);
521 listener.set_sender(channel());
morrita17137e62015-06-23 22:29:36522
Wez831ae412017-08-30 00:29:36523 run_loop.Run();
morrita17137e62015-06-23 22:29:36524
sammc57ed9f982016-03-10 06:28:35525 Close();
morrita17137e62015-06-23 22:29:36526}
527
rockot7c6bf952016-07-14 00:34:11528class ListenerWithSimpleAssociatedInterface
529 : public IPC::Listener,
530 public IPC::mojom::SimpleTestDriver {
531 public:
532 static const int kNumMessages;
533
534 ListenerWithSimpleAssociatedInterface() : binding_(this) {}
535
536 ~ListenerWithSimpleAssociatedInterface() override {}
537
538 bool OnMessageReceived(const IPC::Message& message) override {
539 base::PickleIterator iter(message);
rockot9abe09b2016-08-02 20:57:34540 int32_t should_be_expected;
541 EXPECT_TRUE(iter.ReadInt(&should_be_expected));
542 EXPECT_EQ(should_be_expected, next_expected_value_);
rockot7c6bf952016-07-14 00:34:11543 num_messages_received_++;
544 return true;
545 }
546
547 void OnChannelError() override {
548 DCHECK(received_quit_);
549 }
550
551 void RegisterInterfaceFactory(IPC::Channel* channel) {
552 channel->GetAssociatedInterfaceSupport()->AddAssociatedInterface(
553 base::Bind(&ListenerWithSimpleAssociatedInterface::BindRequest,
554 base::Unretained(this)));
555 }
556
557 private:
558 // IPC::mojom::SimpleTestDriver:
rockot9abe09b2016-08-02 20:57:34559 void ExpectValue(int32_t value) override {
560 next_expected_value_ = value;
561 }
562
tzikdd76ce712017-06-08 05:27:04563 void GetExpectedValue(GetExpectedValueCallback callback) override {
rockot9abe09b2016-08-02 20:57:34564 NOTREACHED();
565 }
566
tzikdd76ce712017-06-08 05:27:04567 void RequestValue(RequestValueCallback callback) override { NOTREACHED(); }
rockot7c6bf952016-07-14 00:34:11568
tzikdd76ce712017-06-08 05:27:04569 void RequestQuit(RequestQuitCallback callback) override {
rockot7c6bf952016-07-14 00:34:11570 EXPECT_EQ(kNumMessages, num_messages_received_);
571 received_quit_ = true;
tzikdd76ce712017-06-08 05:27:04572 std::move(callback).Run();
Gabriel Charette53a9ef812017-07-26 12:36:23573 base::RunLoop::QuitCurrentWhenIdleDeprecated();
rockot7c6bf952016-07-14 00:34:11574 }
575
576 void BindRequest(IPC::mojom::SimpleTestDriverAssociatedRequest request) {
577 DCHECK(!binding_.is_bound());
578 binding_.Bind(std::move(request));
579 }
580
rockot9abe09b2016-08-02 20:57:34581 int32_t next_expected_value_ = 0;
rockot7c6bf952016-07-14 00:34:11582 int num_messages_received_ = 0;
583 bool received_quit_ = false;
584
585 mojo::AssociatedBinding<IPC::mojom::SimpleTestDriver> binding_;
586};
587
588const int ListenerWithSimpleAssociatedInterface::kNumMessages = 1000;
589
590class ListenerSendingAssociatedMessages : public IPC::Listener {
591 public:
592 ListenerSendingAssociatedMessages() {}
593
594 bool OnMessageReceived(const IPC::Message& message) override { return true; }
595
596 void OnChannelConnected(int32_t peer_pid) override {
597 DCHECK(channel_);
598 channel_->GetAssociatedInterfaceSupport()->GetRemoteAssociatedInterface(
599 &driver_);
600
601 // Send a bunch of interleaved messages, alternating between the associated
602 // interface and a legacy IPC::Message.
603 for (int i = 0; i < ListenerWithSimpleAssociatedInterface::kNumMessages;
604 ++i) {
rockot9abe09b2016-08-02 20:57:34605 driver_->ExpectValue(i);
606 SendValue(channel_, i);
rockot7c6bf952016-07-14 00:34:11607 }
608 driver_->RequestQuit(base::Bind(&OnQuitAck));
609 }
610
611 void set_channel(IPC::Channel* channel) { channel_ = channel; }
612
613 private:
Gabriel Charette53a9ef812017-07-26 12:36:23614 static void OnQuitAck() { base::RunLoop::QuitCurrentWhenIdleDeprecated(); }
rockot7c6bf952016-07-14 00:34:11615
616 IPC::Channel* channel_ = nullptr;
617 IPC::mojom::SimpleTestDriverAssociatedPtr driver_;
618};
619
620TEST_F(IPCChannelMojoTest, SimpleAssociatedInterface) {
sammc4bcc4ed62016-10-27 10:13:59621 Init("SimpleAssociatedInterfaceClient");
rockot7c6bf952016-07-14 00:34:11622
623 ListenerWithSimpleAssociatedInterface listener;
624 CreateChannel(&listener);
625 ASSERT_TRUE(ConnectChannel());
626
627 listener.RegisterInterfaceFactory(channel());
628
629 base::RunLoop().Run();
630 channel()->Close();
631
632 EXPECT_TRUE(WaitForClientShutdown());
633 DestroyChannel();
634}
635
sammc4bcc4ed62016-10-27 10:13:59636DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(SimpleAssociatedInterfaceClient) {
rockot7c6bf952016-07-14 00:34:11637 ListenerSendingAssociatedMessages listener;
638 Connect(&listener);
639 listener.set_channel(channel());
640
641 base::RunLoop().Run();
642
643 Close();
644}
645
rockot8d890f62016-07-14 16:37:14646class ChannelProxyRunner {
647 public:
rockota34707ca2016-07-20 04:28:32648 ChannelProxyRunner(mojo::ScopedMessagePipeHandle handle,
649 bool for_server)
650 : for_server_(for_server),
651 handle_(std::move(handle)),
rockot9abe09b2016-08-02 20:57:34652 io_thread_("ChannelProxyRunner IO thread"),
653 never_signaled_(base::WaitableEvent::ResetPolicy::MANUAL,
654 base::WaitableEvent::InitialState::NOT_SIGNALED) {
rockot8d890f62016-07-14 16:37:14655 }
656
657 void CreateProxy(IPC::Listener* listener) {
658 io_thread_.StartWithOptions(
659 base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
Hajime Hoshiff15e972017-11-09 06:37:09660 proxy_ = IPC::SyncChannel::Create(listener, io_thread_.task_runner(),
661 base::ThreadTaskRunnerHandle::Get(),
662 &never_signaled_);
rockot8d890f62016-07-14 16:37:14663 }
rockota34707ca2016-07-20 04:28:32664
rockot10188752016-09-08 18:24:56665 void RunProxy() {
rockota34707ca2016-07-20 04:28:32666 std::unique_ptr<IPC::ChannelFactory> factory;
667 if (for_server_) {
668 factory = IPC::ChannelMojo::CreateServerFactory(
669 std::move(handle_), io_thread_.task_runner());
670 } else {
671 factory = IPC::ChannelMojo::CreateClientFactory(
672 std::move(handle_), io_thread_.task_runner());
673 }
rockot10188752016-09-08 18:24:56674 proxy_->Init(std::move(factory), true);
rockota34707ca2016-07-20 04:28:32675 }
rockot8d890f62016-07-14 16:37:14676
677 IPC::ChannelProxy* proxy() { return proxy_.get(); }
678
679 private:
rockota34707ca2016-07-20 04:28:32680 const bool for_server_;
rockot8d890f62016-07-14 16:37:14681
rockota34707ca2016-07-20 04:28:32682 mojo::ScopedMessagePipeHandle handle_;
rockot8d890f62016-07-14 16:37:14683 base::Thread io_thread_;
rockot9abe09b2016-08-02 20:57:34684 base::WaitableEvent never_signaled_;
rockotb62e2e32017-03-24 18:36:44685 std::unique_ptr<IPC::ChannelProxy> proxy_;
rockot8d890f62016-07-14 16:37:14686
687 DISALLOW_COPY_AND_ASSIGN(ChannelProxyRunner);
688};
689
690class IPCChannelProxyMojoTest : public IPCChannelMojoTestBase {
691 public:
sammc4bcc4ed62016-10-27 10:13:59692 void Init(const std::string& client_name) {
693 IPCChannelMojoTestBase::Init(client_name);
rockota34707ca2016-07-20 04:28:32694 runner_.reset(new ChannelProxyRunner(TakeHandle(), true));
rockot8d890f62016-07-14 16:37:14695 }
696 void CreateProxy(IPC::Listener* listener) { runner_->CreateProxy(listener); }
rockot10188752016-09-08 18:24:56697 void RunProxy() {
698 runner_->RunProxy();
rockot401fb2c2016-09-06 18:35:57699 }
rockot0e4de5f2016-07-22 21:18:07700 void DestroyProxy() {
701 runner_.reset();
702 base::RunLoop().RunUntilIdle();
703 }
rockot8d890f62016-07-14 16:37:14704
705 IPC::ChannelProxy* proxy() { return runner_->proxy(); }
706
707 private:
rockot8d890f62016-07-14 16:37:14708 std::unique_ptr<ChannelProxyRunner> runner_;
709};
710
711class ListenerWithSimpleProxyAssociatedInterface
712 : public IPC::Listener,
713 public IPC::mojom::SimpleTestDriver {
714 public:
715 static const int kNumMessages;
716
717 ListenerWithSimpleProxyAssociatedInterface() : binding_(this) {}
718
719 ~ListenerWithSimpleProxyAssociatedInterface() override {}
720
721 bool OnMessageReceived(const IPC::Message& message) override {
722 base::PickleIterator iter(message);
rockot9abe09b2016-08-02 20:57:34723 int32_t should_be_expected;
724 EXPECT_TRUE(iter.ReadInt(&should_be_expected));
725 EXPECT_EQ(should_be_expected, next_expected_value_);
rockot8d890f62016-07-14 16:37:14726 num_messages_received_++;
727 return true;
728 }
729
730 void OnChannelError() override {
731 DCHECK(received_quit_);
732 }
733
rockotf62002a2016-09-15 00:08:59734 void OnAssociatedInterfaceRequest(
735 const std::string& interface_name,
736 mojo::ScopedInterfaceEndpointHandle handle) override {
737 DCHECK_EQ(interface_name, IPC::mojom::SimpleTestDriver::Name_);
Ken Rockot96d1b7b52017-05-13 00:29:21738 binding_.Bind(
739 IPC::mojom::SimpleTestDriverAssociatedRequest(std::move(handle)));
rockot8d890f62016-07-14 16:37:14740 }
741
742 bool received_all_messages() const {
743 return num_messages_received_ == kNumMessages && received_quit_;
744 }
745
746 private:
747 // IPC::mojom::SimpleTestDriver:
rockot9abe09b2016-08-02 20:57:34748 void ExpectValue(int32_t value) override {
749 next_expected_value_ = value;
750 }
751
tzikdd76ce712017-06-08 05:27:04752 void GetExpectedValue(GetExpectedValueCallback callback) override {
753 std::move(callback).Run(next_expected_value_);
rockot9abe09b2016-08-02 20:57:34754 }
755
tzikdd76ce712017-06-08 05:27:04756 void RequestValue(RequestValueCallback callback) override { NOTREACHED(); }
rockot8d890f62016-07-14 16:37:14757
tzikdd76ce712017-06-08 05:27:04758 void RequestQuit(RequestQuitCallback callback) override {
rockot8d890f62016-07-14 16:37:14759 received_quit_ = true;
tzikdd76ce712017-06-08 05:27:04760 std::move(callback).Run();
rockot0e4de5f2016-07-22 21:18:07761 binding_.Close();
Gabriel Charette53a9ef812017-07-26 12:36:23762 base::RunLoop::QuitCurrentWhenIdleDeprecated();
rockot8d890f62016-07-14 16:37:14763 }
764
765 void BindRequest(IPC::mojom::SimpleTestDriverAssociatedRequest request) {
766 DCHECK(!binding_.is_bound());
767 binding_.Bind(std::move(request));
768 }
769
rockot9abe09b2016-08-02 20:57:34770 int32_t next_expected_value_ = 0;
rockot8d890f62016-07-14 16:37:14771 int num_messages_received_ = 0;
772 bool received_quit_ = false;
773
774 mojo::AssociatedBinding<IPC::mojom::SimpleTestDriver> binding_;
775};
776
777const int ListenerWithSimpleProxyAssociatedInterface::kNumMessages = 1000;
778
779TEST_F(IPCChannelProxyMojoTest, ProxyThreadAssociatedInterface) {
sammc4bcc4ed62016-10-27 10:13:59780 Init("ProxyThreadAssociatedInterfaceClient");
rockot8d890f62016-07-14 16:37:14781
782 ListenerWithSimpleProxyAssociatedInterface listener;
783 CreateProxy(&listener);
rockot8d890f62016-07-14 16:37:14784 RunProxy();
785
786 base::RunLoop().Run();
787
788 EXPECT_TRUE(WaitForClientShutdown());
789 EXPECT_TRUE(listener.received_all_messages());
790
rockot0e4de5f2016-07-22 21:18:07791 DestroyProxy();
rockot8d890f62016-07-14 16:37:14792}
793
794class ChannelProxyClient {
795 public:
796 void Init(mojo::ScopedMessagePipeHandle handle) {
rockota34707ca2016-07-20 04:28:32797 runner_.reset(new ChannelProxyRunner(std::move(handle), false));
rockot8d890f62016-07-14 16:37:14798 }
rockot9abe09b2016-08-02 20:57:34799
rockot8d890f62016-07-14 16:37:14800 void CreateProxy(IPC::Listener* listener) { runner_->CreateProxy(listener); }
rockot9abe09b2016-08-02 20:57:34801
rockot10188752016-09-08 18:24:56802 void RunProxy() { runner_->RunProxy(); }
rockot9abe09b2016-08-02 20:57:34803
rockot0e4de5f2016-07-22 21:18:07804 void DestroyProxy() {
805 runner_.reset();
806 base::RunLoop().RunUntilIdle();
807 }
rockot8d890f62016-07-14 16:37:14808
rockot9abe09b2016-08-02 20:57:34809 void RequestQuitAndWaitForAck(IPC::mojom::SimpleTestDriver* driver) {
810 base::RunLoop loop;
811 driver->RequestQuit(loop.QuitClosure());
812 loop.Run();
813 }
814
rockot8d890f62016-07-14 16:37:14815 IPC::ChannelProxy* proxy() { return runner_->proxy(); }
816
817 private:
818 base::MessageLoop message_loop_;
819 std::unique_ptr<ChannelProxyRunner> runner_;
820};
821
rockot0e4de5f2016-07-22 21:18:07822class DummyListener : public IPC::Listener {
rockot8d890f62016-07-14 16:37:14823 public:
rockot8d890f62016-07-14 16:37:14824 // IPC::Listener
825 bool OnMessageReceived(const IPC::Message& message) override { return true; }
rockot8d890f62016-07-14 16:37:14826};
827
sammc4bcc4ed62016-10-27 10:13:59828DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
829 ProxyThreadAssociatedInterfaceClient,
830 ChannelProxyClient) {
rockot0e4de5f2016-07-22 21:18:07831 DummyListener listener;
rockot8d890f62016-07-14 16:37:14832 CreateProxy(&listener);
833 RunProxy();
rockot8d890f62016-07-14 16:37:14834
835 // Send a bunch of interleaved messages, alternating between the associated
836 // interface and a legacy IPC::Message.
837 IPC::mojom::SimpleTestDriverAssociatedPtr driver;
838 proxy()->GetRemoteAssociatedInterface(&driver);
839 for (int i = 0; i < ListenerWithSimpleProxyAssociatedInterface::kNumMessages;
840 ++i) {
rockot9abe09b2016-08-02 20:57:34841 driver->ExpectValue(i);
842 SendValue(proxy(), i);
rockot8d890f62016-07-14 16:37:14843 }
844 driver->RequestQuit(base::MessageLoop::QuitWhenIdleClosure());
845 base::RunLoop().Run();
rockot0e4de5f2016-07-22 21:18:07846
847 DestroyProxy();
rockot8d890f62016-07-14 16:37:14848}
849
rockot401fb2c2016-09-06 18:35:57850class ListenerWithIndirectProxyAssociatedInterface
851 : public IPC::Listener,
852 public IPC::mojom::IndirectTestDriver,
853 public IPC::mojom::PingReceiver {
854 public:
855 ListenerWithIndirectProxyAssociatedInterface()
856 : driver_binding_(this), ping_receiver_binding_(this) {}
857 ~ListenerWithIndirectProxyAssociatedInterface() override {}
858
rockot70bbb59492017-01-25 00:56:51859 // IPC::Listener:
rockot401fb2c2016-09-06 18:35:57860 bool OnMessageReceived(const IPC::Message& message) override { return true; }
861
rockot70bbb59492017-01-25 00:56:51862 void OnAssociatedInterfaceRequest(
863 const std::string& interface_name,
864 mojo::ScopedInterfaceEndpointHandle handle) override {
865 DCHECK(!driver_binding_.is_bound());
866 DCHECK_EQ(interface_name, IPC::mojom::IndirectTestDriver::Name_);
Ken Rockot96d1b7b52017-05-13 00:29:21867 driver_binding_.Bind(
868 IPC::mojom::IndirectTestDriverAssociatedRequest(std::move(handle)));
rockot401fb2c2016-09-06 18:35:57869 }
870
871 void set_ping_handler(const base::Closure& handler) {
872 ping_handler_ = handler;
873 }
874
875 private:
876 // IPC::mojom::IndirectTestDriver:
877 void GetPingReceiver(
878 IPC::mojom::PingReceiverAssociatedRequest request) override {
879 ping_receiver_binding_.Bind(std::move(request));
880 }
881
882 // IPC::mojom::PingReceiver:
tzikdd76ce712017-06-08 05:27:04883 void Ping(PingCallback callback) override {
884 std::move(callback).Run();
rockot401fb2c2016-09-06 18:35:57885 ping_handler_.Run();
886 }
887
rockot401fb2c2016-09-06 18:35:57888 mojo::AssociatedBinding<IPC::mojom::IndirectTestDriver> driver_binding_;
889 mojo::AssociatedBinding<IPC::mojom::PingReceiver> ping_receiver_binding_;
890
891 base::Closure ping_handler_;
892};
893
894TEST_F(IPCChannelProxyMojoTest, ProxyThreadAssociatedInterfaceIndirect) {
895 // Tests that we can pipeline interface requests and subsequent messages
896 // targeting proxy thread bindings, and the channel will still dispatch
897 // messages appropriately.
898
sammc4bcc4ed62016-10-27 10:13:59899 Init("ProxyThreadAssociatedInterfaceIndirectClient");
rockot401fb2c2016-09-06 18:35:57900
901 ListenerWithIndirectProxyAssociatedInterface listener;
902 CreateProxy(&listener);
rockot401fb2c2016-09-06 18:35:57903 RunProxy();
904
905 base::RunLoop loop;
906 listener.set_ping_handler(loop.QuitClosure());
907 loop.Run();
908
909 EXPECT_TRUE(WaitForClientShutdown());
910
911 DestroyProxy();
912}
913
sammc4bcc4ed62016-10-27 10:13:59914DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
rockot401fb2c2016-09-06 18:35:57915 ProxyThreadAssociatedInterfaceIndirectClient,
916 ChannelProxyClient) {
917 DummyListener listener;
918 CreateProxy(&listener);
919 RunProxy();
920
921 // Use an interface requested via another interface. On the remote end both
922 // interfaces are bound on the proxy thread. This ensures that the Ping
923 // message we send will still be dispatched properly even though the remote
924 // endpoint may not have been bound yet by the time the message is initially
925 // processed on the IO thread.
926 IPC::mojom::IndirectTestDriverAssociatedPtr driver;
927 IPC::mojom::PingReceiverAssociatedPtr ping_receiver;
928 proxy()->GetRemoteAssociatedInterface(&driver);
yzshen1aa8e56c2017-02-16 23:15:45929 driver->GetPingReceiver(mojo::MakeRequest(&ping_receiver));
rockot401fb2c2016-09-06 18:35:57930
931 base::RunLoop loop;
932 ping_receiver->Ping(loop.QuitClosure());
933 loop.Run();
934
935 DestroyProxy();
936}
937
rockot9abe09b2016-08-02 20:57:34938class ListenerWithSyncAssociatedInterface
939 : public IPC::Listener,
940 public IPC::mojom::SimpleTestDriver {
941 public:
942 ListenerWithSyncAssociatedInterface() : binding_(this) {}
943 ~ListenerWithSyncAssociatedInterface() override {}
944
945 void set_sync_sender(IPC::Sender* sync_sender) { sync_sender_ = sync_sender; }
946
rockot9abe09b2016-08-02 20:57:34947 void RunUntilQuitRequested() {
948 base::RunLoop loop;
949 quit_closure_ = loop.QuitClosure();
950 loop.Run();
951 }
952
953 void CloseBinding() { binding_.Close(); }
954
955 void set_response_value(int32_t response) {
956 response_value_ = response;
957 }
958
959 private:
960 // IPC::mojom::SimpleTestDriver:
961 void ExpectValue(int32_t value) override {
962 next_expected_value_ = value;
963 }
964
tzikdd76ce712017-06-08 05:27:04965 void GetExpectedValue(GetExpectedValueCallback callback) override {
966 std::move(callback).Run(next_expected_value_);
rockot9abe09b2016-08-02 20:57:34967 }
968
tzikdd76ce712017-06-08 05:27:04969 void RequestValue(RequestValueCallback callback) override {
970 std::move(callback).Run(response_value_);
rockot9abe09b2016-08-02 20:57:34971 }
972
tzikdd76ce712017-06-08 05:27:04973 void RequestQuit(RequestQuitCallback callback) override {
rockot9abe09b2016-08-02 20:57:34974 quit_closure_.Run();
tzikdd76ce712017-06-08 05:27:04975 std::move(callback).Run();
rockot9abe09b2016-08-02 20:57:34976 }
977
978 // IPC::Listener:
979 bool OnMessageReceived(const IPC::Message& message) override {
980 EXPECT_EQ(0u, message.type());
981 EXPECT_TRUE(message.is_sync());
982 EXPECT_TRUE(message.should_unblock());
983 std::unique_ptr<IPC::Message> reply(
984 IPC::SyncMessage::GenerateReply(&message));
985 reply->WriteInt(response_value_);
986 DCHECK(sync_sender_);
987 EXPECT_TRUE(sync_sender_->Send(reply.release()));
988 return true;
989 }
990
rockot70bbb59492017-01-25 00:56:51991 void OnAssociatedInterfaceRequest(
992 const std::string& interface_name,
993 mojo::ScopedInterfaceEndpointHandle handle) override {
994 DCHECK(!binding_.is_bound());
995 DCHECK_EQ(interface_name, IPC::mojom::SimpleTestDriver::Name_);
Ken Rockot96d1b7b52017-05-13 00:29:21996 binding_.Bind(
997 IPC::mojom::SimpleTestDriverAssociatedRequest(std::move(handle)));
rockot70bbb59492017-01-25 00:56:51998 }
999
rockot9abe09b2016-08-02 20:57:341000 void BindRequest(IPC::mojom::SimpleTestDriverAssociatedRequest request) {
1001 DCHECK(!binding_.is_bound());
1002 binding_.Bind(std::move(request));
1003 }
1004
1005 IPC::Sender* sync_sender_ = nullptr;
1006 int32_t next_expected_value_ = 0;
1007 int32_t response_value_ = 0;
1008 base::Closure quit_closure_;
1009
1010 mojo::AssociatedBinding<IPC::mojom::SimpleTestDriver> binding_;
1011};
1012
1013class SyncReplyReader : public IPC::MessageReplyDeserializer {
1014 public:
1015 explicit SyncReplyReader(int32_t* storage) : storage_(storage) {}
1016 ~SyncReplyReader() override {}
1017
1018 private:
1019 // IPC::MessageReplyDeserializer:
1020 bool SerializeOutputParameters(const IPC::Message& message,
1021 base::PickleIterator iter) override {
1022 if (!iter.ReadInt(storage_))
1023 return false;
1024 return true;
1025 }
1026
1027 int32_t* storage_;
1028
1029 DISALLOW_COPY_AND_ASSIGN(SyncReplyReader);
1030};
1031
1032TEST_F(IPCChannelProxyMojoTest, SyncAssociatedInterface) {
sammc4bcc4ed62016-10-27 10:13:591033 Init("SyncAssociatedInterface");
rockot9abe09b2016-08-02 20:57:341034
1035 ListenerWithSyncAssociatedInterface listener;
1036 CreateProxy(&listener);
1037 listener.set_sync_sender(proxy());
rockot9abe09b2016-08-02 20:57:341038 RunProxy();
1039
1040 // Run the client's simple sanity check to completion.
1041 listener.RunUntilQuitRequested();
1042
1043 // Verify that we can send a sync IPC and service an incoming sync request
1044 // while waiting on it
1045 listener.set_response_value(42);
1046 IPC::mojom::SimpleTestClientAssociatedPtr client;
1047 proxy()->GetRemoteAssociatedInterface(&client);
1048 int32_t received_value;
1049 EXPECT_TRUE(client->RequestValue(&received_value));
1050 EXPECT_EQ(42, received_value);
1051
1052 // Do it again. This time the client will send a classical sync IPC to us
1053 // while we wait.
1054 received_value = 0;
1055 EXPECT_TRUE(client->RequestValue(&received_value));
1056 EXPECT_EQ(42, received_value);
1057
1058 // Now make a classical sync IPC request to the client. It will send a
1059 // sync associated interface message to us while we wait.
1060 received_value = 0;
1061 std::unique_ptr<IPC::SyncMessage> request(
1062 new IPC::SyncMessage(0, 0, IPC::Message::PRIORITY_NORMAL,
1063 new SyncReplyReader(&received_value)));
1064 EXPECT_TRUE(proxy()->Send(request.release()));
1065 EXPECT_EQ(42, received_value);
1066
1067 listener.CloseBinding();
1068 EXPECT_TRUE(WaitForClientShutdown());
1069
1070 DestroyProxy();
1071}
1072
1073class SimpleTestClientImpl : public IPC::mojom::SimpleTestClient,
1074 public IPC::Listener {
1075 public:
1076 SimpleTestClientImpl() : binding_(this) {}
1077
1078 void set_driver(IPC::mojom::SimpleTestDriver* driver) { driver_ = driver; }
1079 void set_sync_sender(IPC::Sender* sync_sender) { sync_sender_ = sync_sender; }
1080
rockot9abe09b2016-08-02 20:57:341081 void WaitForValueRequest() {
1082 run_loop_.reset(new base::RunLoop);
1083 run_loop_->Run();
1084 }
1085
1086 void UseSyncSenderForRequest(bool use_sync_sender) {
1087 use_sync_sender_ = use_sync_sender;
1088 }
1089
1090 private:
1091 // IPC::mojom::SimpleTestClient:
tzikdd76ce712017-06-08 05:27:041092 void RequestValue(RequestValueCallback callback) override {
rockot9abe09b2016-08-02 20:57:341093 int32_t response = 0;
1094 if (use_sync_sender_) {
1095 std::unique_ptr<IPC::SyncMessage> reply(new IPC::SyncMessage(
1096 0, 0, IPC::Message::PRIORITY_NORMAL, new SyncReplyReader(&response)));
1097 EXPECT_TRUE(sync_sender_->Send(reply.release()));
1098 } else {
1099 DCHECK(driver_);
1100 EXPECT_TRUE(driver_->RequestValue(&response));
1101 }
1102
tzikdd76ce712017-06-08 05:27:041103 std::move(callback).Run(response);
rockot9abe09b2016-08-02 20:57:341104
1105 DCHECK(run_loop_);
1106 run_loop_->Quit();
1107 }
1108
1109 // IPC::Listener:
1110 bool OnMessageReceived(const IPC::Message& message) override {
1111 int32_t response;
1112 DCHECK(driver_);
1113 EXPECT_TRUE(driver_->RequestValue(&response));
1114 std::unique_ptr<IPC::Message> reply(
1115 IPC::SyncMessage::GenerateReply(&message));
1116 reply->WriteInt(response);
1117 EXPECT_TRUE(sync_sender_->Send(reply.release()));
1118
1119 DCHECK(run_loop_);
1120 run_loop_->Quit();
1121 return true;
1122 }
1123
rockot70bbb59492017-01-25 00:56:511124 void OnAssociatedInterfaceRequest(
1125 const std::string& interface_name,
1126 mojo::ScopedInterfaceEndpointHandle handle) override {
1127 DCHECK(!binding_.is_bound());
1128 DCHECK_EQ(interface_name, IPC::mojom::SimpleTestClient::Name_);
1129
Ken Rockot96d1b7b52017-05-13 00:29:211130 binding_.Bind(
1131 IPC::mojom::SimpleTestClientAssociatedRequest(std::move(handle)));
rockot70bbb59492017-01-25 00:56:511132 }
1133
rockot9abe09b2016-08-02 20:57:341134 bool use_sync_sender_ = false;
1135 mojo::AssociatedBinding<IPC::mojom::SimpleTestClient> binding_;
1136 IPC::Sender* sync_sender_ = nullptr;
1137 IPC::mojom::SimpleTestDriver* driver_ = nullptr;
1138 std::unique_ptr<base::RunLoop> run_loop_;
1139
1140 DISALLOW_COPY_AND_ASSIGN(SimpleTestClientImpl);
1141};
1142
sammc4bcc4ed62016-10-27 10:13:591143DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(SyncAssociatedInterface,
1144 ChannelProxyClient) {
rockot9abe09b2016-08-02 20:57:341145 SimpleTestClientImpl client_impl;
1146 CreateProxy(&client_impl);
1147 client_impl.set_sync_sender(proxy());
rockot9abe09b2016-08-02 20:57:341148 RunProxy();
1149
1150 IPC::mojom::SimpleTestDriverAssociatedPtr driver;
1151 proxy()->GetRemoteAssociatedInterface(&driver);
1152 client_impl.set_driver(driver.get());
1153
1154 // Simple sync message sanity check.
1155 driver->ExpectValue(42);
1156 int32_t expected_value = 0;
1157 EXPECT_TRUE(driver->GetExpectedValue(&expected_value));
1158 EXPECT_EQ(42, expected_value);
1159 RequestQuitAndWaitForAck(driver.get());
1160
1161 // Wait for the test driver to perform a sync call test with our own sync
1162 // associated interface message nested inside.
1163 client_impl.UseSyncSenderForRequest(false);
1164 client_impl.WaitForValueRequest();
1165
1166 // Wait for the test driver to perform a sync call test with our own classical
1167 // sync IPC nested inside.
1168 client_impl.UseSyncSenderForRequest(true);
1169 client_impl.WaitForValueRequest();
1170
1171 // Wait for the test driver to perform a classical sync IPC request, with our
1172 // own sync associated interface message nested inside.
1173 client_impl.UseSyncSenderForRequest(false);
1174 client_impl.WaitForValueRequest();
1175
1176 DestroyProxy();
1177}
1178
rockot10188752016-09-08 18:24:561179TEST_F(IPCChannelProxyMojoTest, Pause) {
1180 // Ensures that pausing a channel elicits the expected behavior when sending
1181 // messages, unpausing, sending more messages, and then manually flushing.
1182 // Specifically a sequence like:
rockot401fb2c2016-09-06 18:35:571183 //
1184 // Connect()
1185 // Send(A)
rockot10188752016-09-08 18:24:561186 // Pause()
rockot401fb2c2016-09-06 18:35:571187 // Send(B)
rockot401fb2c2016-09-06 18:35:571188 // Send(C)
rockot10188752016-09-08 18:24:561189 // Unpause(false)
1190 // Send(D)
1191 // Send(E)
rockot401fb2c2016-09-06 18:35:571192 // Flush()
1193 //
rockot10188752016-09-08 18:24:561194 // must result in the other end receiving messages A, D, E, B, D; in that
rockot401fb2c2016-09-06 18:35:571195 // order.
1196 //
1197 // This behavior is required by some consumers of IPC::Channel, and it is not
1198 // sufficient to leave this up to the consumer to implement since associated
1199 // interface requests and messages also need to be queued according to the
1200 // same policy.
sammc4bcc4ed62016-10-27 10:13:591201 Init("CreatePausedClient");
rockot401fb2c2016-09-06 18:35:571202
1203 DummyListener listener;
1204 CreateProxy(&listener);
rockot10188752016-09-08 18:24:561205 RunProxy();
1206
1207 // This message must be sent immediately since the channel is unpaused.
1208 SendValue(proxy(), 1);
1209
1210 proxy()->Pause();
rockot401fb2c2016-09-06 18:35:571211
1212 // These messages must be queued internally since the channel is paused.
rockot401fb2c2016-09-06 18:35:571213 SendValue(proxy(), 2);
rockot10188752016-09-08 18:24:561214 SendValue(proxy(), 3);
rockot401fb2c2016-09-06 18:35:571215
1216 proxy()->Unpause(false /* flush */);
1217
1218 // These messages must be sent immediately since the channel is unpaused.
rockot401fb2c2016-09-06 18:35:571219 SendValue(proxy(), 4);
rockot10188752016-09-08 18:24:561220 SendValue(proxy(), 5);
rockot401fb2c2016-09-06 18:35:571221
1222 // Now we flush the previously queued messages.
1223 proxy()->Flush();
1224
1225 EXPECT_TRUE(WaitForClientShutdown());
1226 DestroyProxy();
1227}
1228
1229class ExpectValueSequenceListener : public IPC::Listener {
1230 public:
Brett Wilsona62d9c02017-09-20 20:53:201231 explicit ExpectValueSequenceListener(base::queue<int32_t>* expected_values)
rockot401fb2c2016-09-06 18:35:571232 : expected_values_(expected_values) {}
1233 ~ExpectValueSequenceListener() override {}
1234
1235 // IPC::Listener:
1236 bool OnMessageReceived(const IPC::Message& message) override {
1237 DCHECK(!expected_values_->empty());
1238 base::PickleIterator iter(message);
1239 int32_t should_be_expected;
1240 EXPECT_TRUE(iter.ReadInt(&should_be_expected));
1241 EXPECT_EQ(expected_values_->front(), should_be_expected);
1242 expected_values_->pop();
1243 if (expected_values_->empty())
Gabriel Charette53a9ef812017-07-26 12:36:231244 base::RunLoop::QuitCurrentWhenIdleDeprecated();
rockot401fb2c2016-09-06 18:35:571245 return true;
1246 }
1247
1248 private:
Brett Wilsona62d9c02017-09-20 20:53:201249 base::queue<int32_t>* expected_values_;
rockot401fb2c2016-09-06 18:35:571250
1251 DISALLOW_COPY_AND_ASSIGN(ExpectValueSequenceListener);
1252};
1253
sammc4bcc4ed62016-10-27 10:13:591254DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(CreatePausedClient,
1255 ChannelProxyClient) {
Brett Wilsona62d9c02017-09-20 20:53:201256 base::queue<int32_t> expected_values;
rockot401fb2c2016-09-06 18:35:571257 ExpectValueSequenceListener listener(&expected_values);
1258 CreateProxy(&listener);
rockot401fb2c2016-09-06 18:35:571259 expected_values.push(1);
rockot10188752016-09-08 18:24:561260 expected_values.push(4);
1261 expected_values.push(5);
rockot401fb2c2016-09-06 18:35:571262 expected_values.push(2);
rockot10188752016-09-08 18:24:561263 expected_values.push(3);
rockot401fb2c2016-09-06 18:35:571264 RunProxy();
1265 base::RunLoop().Run();
1266 EXPECT_TRUE(expected_values.empty());
1267 DestroyProxy();
1268}
1269
sammc5c8a6c62017-02-04 01:33:381270TEST_F(IPCChannelProxyMojoTest, AssociatedRequestClose) {
1271 Init("DropAssociatedRequest");
1272
1273 DummyListener listener;
1274 CreateProxy(&listener);
1275 RunProxy();
1276
1277 IPC::mojom::AssociatedInterfaceVendorAssociatedPtr vendor;
1278 proxy()->GetRemoteAssociatedInterface(&vendor);
1279 IPC::mojom::SimpleTestDriverAssociatedPtr tester;
yzshen1aa8e56c2017-02-16 23:15:451280 vendor->GetTestInterface(mojo::MakeRequest(&tester));
sammc5c8a6c62017-02-04 01:33:381281 base::RunLoop run_loop;
1282 tester.set_connection_error_handler(run_loop.QuitClosure());
1283 run_loop.Run();
1284
1285 proxy()->GetRemoteAssociatedInterface(&tester);
1286 EXPECT_TRUE(WaitForClientShutdown());
1287 DestroyProxy();
1288}
1289
1290class AssociatedInterfaceDroppingListener : public IPC::Listener {
1291 public:
1292 AssociatedInterfaceDroppingListener(const base::Closure& callback)
1293 : callback_(callback) {}
1294 bool OnMessageReceived(const IPC::Message& message) override { return false; }
1295
1296 void OnAssociatedInterfaceRequest(
1297 const std::string& interface_name,
1298 mojo::ScopedInterfaceEndpointHandle handle) override {
1299 if (interface_name == IPC::mojom::SimpleTestDriver::Name_)
1300 base::ResetAndReturn(&callback_).Run();
1301 }
1302
1303 private:
1304 base::Closure callback_;
1305};
1306
1307DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(DropAssociatedRequest,
1308 ChannelProxyClient) {
1309 base::RunLoop run_loop;
1310 AssociatedInterfaceDroppingListener listener(run_loop.QuitClosure());
1311 CreateProxy(&listener);
1312 RunProxy();
1313 run_loop.Run();
1314 DestroyProxy();
1315}
1316
Wez831ae412017-08-30 00:29:361317#if !defined(OS_MACOSX)
1318// TODO(wez): On Mac we need to set up a MachPortBroker before we can transfer
1319// Mach ports (which underpin Sharedmemory on Mac) across IPC.
1320
1321class ListenerThatExpectsSharedMemory : public TestListenerBase {
1322 public:
1323 ListenerThatExpectsSharedMemory(base::Closure quit_closure)
1324 : TestListenerBase(quit_closure) {}
1325
1326 bool OnMessageReceived(const IPC::Message& message) override {
1327 base::PickleIterator iter(message);
1328
1329 base::SharedMemoryHandle shared_memory;
1330 EXPECT_TRUE(IPC::ReadParam(&message, &iter, &shared_memory));
1331 EXPECT_TRUE(shared_memory.IsValid());
1332 shared_memory.Close();
1333
1334 ListenerThatExpectsOK::SendOK(sender());
1335 return true;
1336 }
1337};
1338
1339TEST_F(IPCChannelMojoTest, SendSharedMemory) {
1340 Init("IPCChannelMojoTestSendSharedMemoryClient");
1341
1342 // Create some shared-memory to share.
1343 base::SharedMemoryCreateOptions options;
1344 options.size = 1004;
1345
1346 base::SharedMemory shmem;
1347 ASSERT_TRUE(shmem.Create(options));
1348
1349 // Create a success listener, and launch the child process.
1350 base::RunLoop run_loop;
1351 ListenerThatExpectsOK listener(run_loop.QuitClosure());
1352 CreateChannel(&listener);
1353 ASSERT_TRUE(ConnectChannel());
1354
1355 // Send the child process an IPC with |shmem| attached, to verify
1356 // that is is correctly wrapped, transferred and unwrapped.
1357 IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
1358 IPC::WriteParam(message, shmem.handle());
1359 ASSERT_TRUE(channel()->Send(message));
1360
1361 run_loop.Run();
1362
1363 channel()->Close();
1364
1365 EXPECT_TRUE(WaitForClientShutdown());
1366 DestroyChannel();
1367}
1368
1369DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendSharedMemoryClient) {
1370 base::RunLoop run_loop;
1371 ListenerThatExpectsSharedMemory listener(run_loop.QuitClosure());
1372 Connect(&listener);
1373 listener.set_sender(channel());
1374
1375 run_loop.Run();
1376
1377 Close();
1378}
1379
1380#endif // !defined(OS_MACOSX)
1381
[email protected]64860882014-08-04 23:44:171382#if defined(OS_POSIX)
rockot8d890f62016-07-14 16:37:141383
Wez831ae412017-08-30 00:29:361384class ListenerThatExpectsFile : public TestListenerBase {
[email protected]64860882014-08-04 23:44:171385 public:
Wez831ae412017-08-30 00:29:361386 ListenerThatExpectsFile(base::Closure quit_closure)
1387 : TestListenerBase(quit_closure) {}
[email protected]64860882014-08-04 23:44:171388
dchengfe61fca2014-10-22 02:29:521389 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:251390 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:301391 HandleSendingHelper::ReadReceivedFile(message, &iter);
Wez831ae412017-08-30 00:29:361392 ListenerThatExpectsOK::SendOK(sender());
[email protected]64860882014-08-04 23:44:171393 return true;
1394 }
[email protected]64860882014-08-04 23:44:171395};
1396
Wez831ae412017-08-30 00:29:361397TEST_F(IPCChannelMojoTest, SendPlatformFile) {
1398 Init("IPCChannelMojoTestSendPlatformFileClient");
[email protected]64860882014-08-04 23:44:171399
Wez831ae412017-08-30 00:29:361400 base::RunLoop run_loop;
1401 ListenerThatExpectsOK listener(run_loop.QuitClosure());
morrita373af03b2014-09-09 19:35:241402 CreateChannel(&listener);
[email protected]64860882014-08-04 23:44:171403 ASSERT_TRUE(ConnectChannel());
[email protected]64860882014-08-04 23:44:171404
amistry20e2b1d62016-06-23 06:12:351405 base::ScopedTempDir temp_dir;
1406 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
vabr16e5f602016-09-15 18:14:001407 base::File file(HandleSendingHelper::GetSendingFilePath(temp_dir.GetPath()),
[email protected]64860882014-08-04 23:44:171408 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
morrita81b17e02015-02-06 00:58:301409 base::File::FLAG_READ);
1410 HandleSendingHelper::WriteFileThenSend(channel(), file);
Wez831ae412017-08-30 00:29:361411 run_loop.Run();
[email protected]64860882014-08-04 23:44:171412
sammc57ed9f982016-03-10 06:28:351413 channel()->Close();
[email protected]64860882014-08-04 23:44:171414
1415 EXPECT_TRUE(WaitForClientShutdown());
1416 DestroyChannel();
1417}
1418
Wez831ae412017-08-30 00:29:361419DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendPlatformFileClient) {
1420 base::RunLoop run_loop;
1421 ListenerThatExpectsFile listener(run_loop.QuitClosure());
sammc57ed9f982016-03-10 06:28:351422 Connect(&listener);
1423 listener.set_sender(channel());
[email protected]64860882014-08-04 23:44:171424
Wez831ae412017-08-30 00:29:361425 run_loop.Run();
[email protected]64860882014-08-04 23:44:171426
sammc57ed9f982016-03-10 06:28:351427 Close();
[email protected]64860882014-08-04 23:44:171428}
morrita81b17e02015-02-06 00:58:301429
Wez831ae412017-08-30 00:29:361430class ListenerThatExpectsFileAndMessagePipe : public TestListenerBase {
morrita81b17e02015-02-06 00:58:301431 public:
Wez831ae412017-08-30 00:29:361432 ListenerThatExpectsFileAndMessagePipe(base::Closure quit_closure)
1433 : TestListenerBase(quit_closure) {}
morrita81b17e02015-02-06 00:58:301434
Wez831ae412017-08-30 00:29:361435 ~ListenerThatExpectsFileAndMessagePipe() override {}
morrita81b17e02015-02-06 00:58:301436
1437 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:251438 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:301439 HandleSendingHelper::ReadReceivedFile(message, &iter);
1440 HandleSendingHelper::ReadReceivedPipe(message, &iter);
Wez831ae412017-08-30 00:29:361441 ListenerThatExpectsOK::SendOK(sender());
morrita81b17e02015-02-06 00:58:301442 return true;
1443 }
morrita81b17e02015-02-06 00:58:301444};
1445
Wez831ae412017-08-30 00:29:361446TEST_F(IPCChannelMojoTest, SendPlatformFileAndMessagePipe) {
1447 Init("IPCChannelMojoTestSendPlatformFileAndMessagePipeClient");
morrita81b17e02015-02-06 00:58:301448
Wez831ae412017-08-30 00:29:361449 base::RunLoop run_loop;
1450 ListenerThatExpectsOK listener(run_loop.QuitClosure());
morrita81b17e02015-02-06 00:58:301451 CreateChannel(&listener);
1452 ASSERT_TRUE(ConnectChannel());
morrita81b17e02015-02-06 00:58:301453
amistry20e2b1d62016-06-23 06:12:351454 base::ScopedTempDir temp_dir;
1455 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
vabr16e5f602016-09-15 18:14:001456 base::File file(HandleSendingHelper::GetSendingFilePath(temp_dir.GetPath()),
morrita81b17e02015-02-06 00:58:301457 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
1458 base::File::FLAG_READ);
1459 TestingMessagePipe pipe;
1460 HandleSendingHelper::WriteFileAndPipeThenSend(channel(), file, &pipe);
1461
Wez831ae412017-08-30 00:29:361462 run_loop.Run();
sammc57ed9f982016-03-10 06:28:351463 channel()->Close();
morrita81b17e02015-02-06 00:58:301464
1465 EXPECT_TRUE(WaitForClientShutdown());
1466 DestroyChannel();
1467}
1468
sammc57ed9f982016-03-10 06:28:351469DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
Wez831ae412017-08-30 00:29:361470 IPCChannelMojoTestSendPlatformFileAndMessagePipeClient) {
1471 base::RunLoop run_loop;
1472 ListenerThatExpectsFileAndMessagePipe listener(run_loop.QuitClosure());
sammc57ed9f982016-03-10 06:28:351473 Connect(&listener);
1474 listener.set_sender(channel());
morrita81b17e02015-02-06 00:58:301475
Wez831ae412017-08-30 00:29:361476 run_loop.Run();
morrita81b17e02015-02-06 00:58:301477
sammc57ed9f982016-03-10 06:28:351478 Close();
morrita81b17e02015-02-06 00:58:301479}
1480
rockot7c6bf952016-07-14 00:34:111481#endif // defined(OS_POSIX)
[email protected]64860882014-08-04 23:44:171482
morrita0bd20bd2015-02-25 20:11:271483#if defined(OS_LINUX)
1484
1485const base::ProcessId kMagicChildId = 54321;
1486
Wez831ae412017-08-30 00:29:361487class ListenerThatVerifiesPeerPid : public TestListenerBase {
morrita0bd20bd2015-02-25 20:11:271488 public:
Wez831ae412017-08-30 00:29:361489 ListenerThatVerifiesPeerPid(base::Closure quit_closure)
1490 : TestListenerBase(quit_closure) {}
1491
tfarina10a5c062015-09-04 18:47:571492 void OnChannelConnected(int32_t peer_pid) override {
morrita0bd20bd2015-02-25 20:11:271493 EXPECT_EQ(peer_pid, kMagicChildId);
Wez831ae412017-08-30 00:29:361494 quit_closure().Run();
morrita0bd20bd2015-02-25 20:11:271495 }
1496
1497 bool OnMessageReceived(const IPC::Message& message) override {
1498 NOTREACHED();
1499 return true;
1500 }
1501};
1502
sammc57ed9f982016-03-10 06:28:351503TEST_F(IPCChannelMojoTest, VerifyGlobalPid) {
sammc4bcc4ed62016-10-27 10:13:591504 Init("IPCChannelMojoTestVerifyGlobalPidClient");
morrita0bd20bd2015-02-25 20:11:271505
Wez831ae412017-08-30 00:29:361506 base::RunLoop run_loop;
1507 ListenerThatVerifiesPeerPid listener(run_loop.QuitClosure());
morrita0bd20bd2015-02-25 20:11:271508 CreateChannel(&listener);
1509 ASSERT_TRUE(ConnectChannel());
morrita0bd20bd2015-02-25 20:11:271510
Wez831ae412017-08-30 00:29:361511 run_loop.Run();
rockotcbca72f2015-03-03 16:31:041512 channel()->Close();
morrita0bd20bd2015-02-25 20:11:271513
1514 EXPECT_TRUE(WaitForClientShutdown());
1515 DestroyChannel();
1516}
1517
sammc4bcc4ed62016-10-27 10:13:591518DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestVerifyGlobalPidClient) {
morrita0bd20bd2015-02-25 20:11:271519 IPC::Channel::SetGlobalPid(kMagicChildId);
Wez831ae412017-08-30 00:29:361520
1521 base::RunLoop run_loop;
1522 ListenerThatQuits listener(run_loop.QuitClosure());
sammc57ed9f982016-03-10 06:28:351523 Connect(&listener);
morrita0bd20bd2015-02-25 20:11:271524
Wez831ae412017-08-30 00:29:361525 run_loop.Run();
morrita0bd20bd2015-02-25 20:11:271526
sammc57ed9f982016-03-10 06:28:351527 Close();
morrita0bd20bd2015-02-25 20:11:271528}
1529
sammc57ed9f982016-03-10 06:28:351530#endif // OS_LINUX
morrita0bd20bd2015-02-25 20:11:271531
[email protected]64860882014-08-04 23:44:171532} // namespace