blob: a4abb3218ef09d6bbcc1e54e42fb1f829c4f205a [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"
[email protected]64860882014-08-04 23:44:1716#include "base/files/file.h"
amistry20e2b1d62016-06-23 06:12:3517#include "base/files/scoped_temp_dir.h"
skyostile687bdff2015-05-12 11:29:2118#include "base/location.h"
rockot8d890f62016-07-14 16:37:1419#include "base/macros.h"
20#include "base/message_loop/message_loop.h"
[email protected]64860882014-08-04 23:44:1721#include "base/path_service.h"
22#include "base/pickle.h"
rockotcbca72f2015-03-03 16:31:0423#include "base/run_loop.h"
skyostile687bdff2015-05-12 11:29:2124#include "base/single_thread_task_runner.h"
rockot7c6bf952016-07-14 00:34:1125#include "base/strings/stringprintf.h"
rockot9abe09b2016-08-02 20:57:3426#include "base/synchronization/waitable_event.h"
sammc57ed9f982016-03-10 06:28:3527#include "base/test/test_io_thread.h"
morrita0bd20bd2015-02-25 20:11:2728#include "base/test/test_timeouts.h"
[email protected]64860882014-08-04 23:44:1729#include "base/threading/thread.h"
gabf08ccc02016-05-11 18:51:1130#include "base/threading/thread_task_runner_handle.h"
avi246998d82015-12-22 02:39:0431#include "build/build_config.h"
[email protected]64860882014-08-04 23:44:1732#include "ipc/ipc_message.h"
amistryd4aa70d2016-06-23 07:52:3733#include "ipc/ipc_mojo_handle_attachment.h"
34#include "ipc/ipc_mojo_message_helper.h"
35#include "ipc/ipc_mojo_param_traits.h"
rockot9abe09b2016-08-02 20:57:3436#include "ipc/ipc_sync_channel.h"
37#include "ipc/ipc_sync_message.h"
rockot7c6bf952016-07-14 00:34:1138#include "ipc/ipc_test.mojom.h"
[email protected]64860882014-08-04 23:44:1739#include "ipc/ipc_test_base.h"
40#include "ipc/ipc_test_channel_listener.h"
rockota9d566a2017-03-17 19:36:1541#include "mojo/public/cpp/system/wait.h"
sammc57ed9f982016-03-10 06:28:3542#include "testing/gtest/include/gtest/gtest.h"
[email protected]64860882014-08-04 23:44:1743
44#if defined(OS_POSIX)
45#include "base/file_descriptor_posix.h"
morrita1aa788c2015-01-31 05:45:4246#include "ipc/ipc_platform_file_attachment_posix.h"
[email protected]64860882014-08-04 23:44:1747#endif
48
49namespace {
50
rockot7c6bf952016-07-14 00:34:1151void SendString(IPC::Sender* sender, const std::string& str) {
52 IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
53 message->WriteString(str);
54 ASSERT_TRUE(sender->Send(message));
55}
56
rockot9abe09b2016-08-02 20:57:3457void SendValue(IPC::Sender* sender, int32_t value) {
58 IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
59 message->WriteInt(value);
60 ASSERT_TRUE(sender->Send(message));
61}
62
[email protected]64860882014-08-04 23:44:1763class ListenerThatExpectsOK : public IPC::Listener {
64 public:
sammc57ed9f982016-03-10 06:28:3565 ListenerThatExpectsOK() : received_ok_(false) {}
[email protected]64860882014-08-04 23:44:1766
dchengfe61fca2014-10-22 02:29:5267 ~ListenerThatExpectsOK() override {}
[email protected]64860882014-08-04 23:44:1768
dchengfe61fca2014-10-22 02:29:5269 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:2570 base::PickleIterator iter(message);
[email protected]64860882014-08-04 23:44:1771 std::string should_be_ok;
72 EXPECT_TRUE(iter.ReadString(&should_be_ok));
73 EXPECT_EQ(should_be_ok, "OK");
[email protected]e5c27752014-08-08 21:45:1374 received_ok_ = true;
ki.stfua21ed8c2015-10-12 17:26:0075 base::MessageLoop::current()->QuitWhenIdle();
[email protected]64860882014-08-04 23:44:1776 return true;
77 }
78
dchengfe61fca2014-10-22 02:29:5279 void OnChannelError() override {
[email protected]e5c27752014-08-08 21:45:1380 // The connection should be healthy while the listener is waiting
81 // message. An error can occur after that because the peer
82 // process dies.
83 DCHECK(received_ok_);
[email protected]64860882014-08-04 23:44:1784 }
85
rockot7c6bf952016-07-14 00:34:1186 static void SendOK(IPC::Sender* sender) { SendString(sender, "OK"); }
[email protected]e5c27752014-08-08 21:45:1387
88 private:
89 bool received_ok_;
[email protected]64860882014-08-04 23:44:1790};
91
sammc4bcc4ed62016-10-27 10:13:5992using IPCChannelMojoTest = IPCChannelMojoTestBase;
rockotcbca72f2015-03-03 16:31:0493
[email protected]64860882014-08-04 23:44:1794class TestChannelListenerWithExtraExpectations
95 : public IPC::TestChannelListener {
96 public:
sammc57ed9f982016-03-10 06:28:3597 TestChannelListenerWithExtraExpectations() : is_connected_called_(false) {}
[email protected]64860882014-08-04 23:44:1798
tfarina10a5c062015-09-04 18:47:5799 void OnChannelConnected(int32_t peer_pid) override {
[email protected]64860882014-08-04 23:44:17100 IPC::TestChannelListener::OnChannelConnected(peer_pid);
101 EXPECT_TRUE(base::kNullProcessId != peer_pid);
102 is_connected_called_ = true;
103 }
104
105 bool is_connected_called() const { return is_connected_called_; }
106
107 private:
108 bool is_connected_called_;
109};
110
amistry0027a0952016-05-03 00:52:47111TEST_F(IPCChannelMojoTest, ConnectedFromClient) {
sammc4bcc4ed62016-10-27 10:13:59112 Init("IPCChannelMojoTestClient");
[email protected]64860882014-08-04 23:44:17113
114 // Set up IPC channel and start client.
115 TestChannelListenerWithExtraExpectations listener;
morrita373af03b2014-09-09 19:35:24116 CreateChannel(&listener);
[email protected]64860882014-08-04 23:44:17117 listener.Init(sender());
118 ASSERT_TRUE(ConnectChannel());
[email protected]64860882014-08-04 23:44:17119
sammc57ed9f982016-03-10 06:28:35120 IPC::TestChannelListener::SendOneMessage(sender(), "hello from parent");
[email protected]64860882014-08-04 23:44:17121
fdoray8e32586852016-06-22 19:56:16122 base::RunLoop().Run();
[email protected]64860882014-08-04 23:44:17123
sammc57ed9f982016-03-10 06:28:35124 channel()->Close();
[email protected]64860882014-08-04 23:44:17125
126 EXPECT_TRUE(WaitForClientShutdown());
127 EXPECT_TRUE(listener.is_connected_called());
128 EXPECT_TRUE(listener.HasSentAll());
129
130 DestroyChannel();
131}
132
133// A long running process that connects to us
sammc4bcc4ed62016-10-27 10:13:59134DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestClient) {
[email protected]64860882014-08-04 23:44:17135 TestChannelListenerWithExtraExpectations listener;
sammc57ed9f982016-03-10 06:28:35136 Connect(&listener);
137 listener.Init(channel());
[email protected]64860882014-08-04 23:44:17138
sammc57ed9f982016-03-10 06:28:35139 IPC::TestChannelListener::SendOneMessage(channel(), "hello from child");
fdoray8e32586852016-06-22 19:56:16140 base::RunLoop().Run();
[email protected]64860882014-08-04 23:44:17141 EXPECT_TRUE(listener.is_connected_called());
142 EXPECT_TRUE(listener.HasSentAll());
143
sammc57ed9f982016-03-10 06:28:35144 Close();
[email protected]64860882014-08-04 23:44:17145}
146
morrita0a24cfc92014-09-16 03:20:48147class ListenerExpectingErrors : public IPC::Listener {
148 public:
sammc57ed9f982016-03-10 06:28:35149 ListenerExpectingErrors() : has_error_(false) {}
morrita0a24cfc92014-09-16 03:20:48150
dchengfe61fca2014-10-22 02:29:52151 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita0a24cfc92014-09-16 03:20:48152
dchengfe61fca2014-10-22 02:29:52153 void OnChannelError() override {
morrita0a24cfc92014-09-16 03:20:48154 has_error_ = true;
ki.stfua21ed8c2015-10-12 17:26:00155 base::MessageLoop::current()->QuitWhenIdle();
morrita0a24cfc92014-09-16 03:20:48156 }
157
158 bool has_error() const { return has_error_; }
159
160 private:
161 bool has_error_;
162};
163
morrita0a24cfc92014-09-16 03:20:48164class ListenerThatQuits : public IPC::Listener {
165 public:
sammc57ed9f982016-03-10 06:28:35166 ListenerThatQuits() {}
morrita0a24cfc92014-09-16 03:20:48167
sammc57ed9f982016-03-10 06:28:35168 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita0a24cfc92014-09-16 03:20:48169
tfarina10a5c062015-09-04 18:47:57170 void OnChannelConnected(int32_t peer_pid) override {
ki.stfua21ed8c2015-10-12 17:26:00171 base::MessageLoop::current()->QuitWhenIdle();
morrita0a24cfc92014-09-16 03:20:48172 }
173};
174
175// A long running process that connects to us.
sammc4bcc4ed62016-10-27 10:13:59176DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoErraticTestClient) {
morrita0a24cfc92014-09-16 03:20:48177 ListenerThatQuits listener;
sammc57ed9f982016-03-10 06:28:35178 Connect(&listener);
morrita0a24cfc92014-09-16 03:20:48179
fdoray8e32586852016-06-22 19:56:16180 base::RunLoop().Run();
morrita0a24cfc92014-09-16 03:20:48181
sammc57ed9f982016-03-10 06:28:35182 Close();
morrita0a24cfc92014-09-16 03:20:48183}
184
rockot8c23d462016-07-25 17:33:04185TEST_F(IPCChannelMojoTest, SendFailWithPendingMessages) {
sammc4bcc4ed62016-10-27 10:13:59186 Init("IPCChannelMojoErraticTestClient");
morrita0a24cfc92014-09-16 03:20:48187
188 // Set up IPC channel and start client.
189 ListenerExpectingErrors listener;
190 CreateChannel(&listener);
191 ASSERT_TRUE(ConnectChannel());
192
jamesra03ae492014-10-03 04:26:48193 // This matches a value in mojo/edk/system/constants.h
morritabe6c4cc2014-09-24 23:38:44194 const int kMaxMessageNumBytes = 4 * 1024 * 1024;
195 std::string overly_large_data(kMaxMessageNumBytes, '*');
morrita0a24cfc92014-09-16 03:20:48196 // This messages are queued as pending.
morritabe6c4cc2014-09-24 23:38:44197 for (size_t i = 0; i < 10; ++i) {
sammc57ed9f982016-03-10 06:28:35198 IPC::TestChannelListener::SendOneMessage(sender(),
199 overly_large_data.c_str());
morrita0a24cfc92014-09-16 03:20:48200 }
201
fdoray8e32586852016-06-22 19:56:16202 base::RunLoop().Run();
morrita0a24cfc92014-09-16 03:20:48203
sammc57ed9f982016-03-10 06:28:35204 channel()->Close();
morrita0a24cfc92014-09-16 03:20:48205
206 EXPECT_TRUE(WaitForClientShutdown());
207 EXPECT_TRUE(listener.has_error());
208
209 DestroyChannel();
210}
211
morrita81b17e02015-02-06 00:58:30212struct TestingMessagePipe {
213 TestingMessagePipe() {
214 EXPECT_EQ(MOJO_RESULT_OK, mojo::CreateMessagePipe(nullptr, &self, &peer));
215 }
216
217 mojo::ScopedMessagePipeHandle self;
218 mojo::ScopedMessagePipeHandle peer;
219};
220
221class HandleSendingHelper {
222 public:
223 static std::string GetSendingFileContent() { return "Hello"; }
224
225 static void WritePipe(IPC::Message* message, TestingMessagePipe* pipe) {
226 std::string content = HandleSendingHelper::GetSendingFileContent();
227 EXPECT_EQ(MOJO_RESULT_OK,
228 mojo::WriteMessageRaw(pipe->self.get(), &content[0],
229 static_cast<uint32_t>(content.size()),
230 nullptr, 0, 0));
dchenge48600452015-12-28 02:24:50231 EXPECT_TRUE(IPC::MojoMessageHelper::WriteMessagePipeTo(
232 message, std::move(pipe->peer)));
morrita81b17e02015-02-06 00:58:30233 }
234
235 static void WritePipeThenSend(IPC::Sender* sender, TestingMessagePipe* pipe) {
236 IPC::Message* message =
237 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
238 WritePipe(message, pipe);
239 ASSERT_TRUE(sender->Send(message));
240 }
241
242 static void ReadReceivedPipe(const IPC::Message& message,
brettwbd4d7112015-06-03 04:29:25243 base::PickleIterator* iter) {
morrita81b17e02015-02-06 00:58:30244 mojo::ScopedMessagePipeHandle pipe;
245 EXPECT_TRUE(
246 IPC::MojoMessageHelper::ReadMessagePipeFrom(&message, iter, &pipe));
247 std::string content(GetSendingFileContent().size(), ' ');
248
249 uint32_t num_bytes = static_cast<uint32_t>(content.size());
sammc57ed9f982016-03-10 06:28:35250 ASSERT_EQ(MOJO_RESULT_OK,
rockota9d566a2017-03-17 19:36:15251 mojo::Wait(pipe.get(), MOJO_HANDLE_SIGNAL_READABLE));
morrita81b17e02015-02-06 00:58:30252 EXPECT_EQ(MOJO_RESULT_OK,
253 mojo::ReadMessageRaw(pipe.get(), &content[0], &num_bytes, nullptr,
254 nullptr, 0));
255 EXPECT_EQ(content, GetSendingFileContent());
256 }
257
258#if defined(OS_POSIX)
amistry20e2b1d62016-06-23 06:12:35259 static base::FilePath GetSendingFilePath(const base::FilePath& dir_path) {
260 return dir_path.Append("ListenerThatExpectsFile.txt");
morrita81b17e02015-02-06 00:58:30261 }
262
263 static void WriteFile(IPC::Message* message, base::File& file) {
264 std::string content = GetSendingFileContent();
265 file.WriteAtCurrentPos(content.data(), content.size());
266 file.Flush();
267 message->WriteAttachment(new IPC::internal::PlatformFileAttachment(
268 base::ScopedFD(file.TakePlatformFile())));
269 }
270
271 static void WriteFileThenSend(IPC::Sender* sender, base::File& file) {
272 IPC::Message* message =
273 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
274 WriteFile(message, file);
275 ASSERT_TRUE(sender->Send(message));
276 }
277
278 static void WriteFileAndPipeThenSend(IPC::Sender* sender,
279 base::File& file,
280 TestingMessagePipe* pipe) {
281 IPC::Message* message =
282 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
283 WriteFile(message, file);
284 WritePipe(message, pipe);
285 ASSERT_TRUE(sender->Send(message));
286 }
287
288 static void ReadReceivedFile(const IPC::Message& message,
brettwbd4d7112015-06-03 04:29:25289 base::PickleIterator* iter) {
morrita81b17e02015-02-06 00:58:30290 base::ScopedFD fd;
rockot502c94f2016-02-03 20:20:16291 scoped_refptr<base::Pickle::Attachment> attachment;
morrita81b17e02015-02-06 00:58:30292 EXPECT_TRUE(message.ReadAttachment(iter, &attachment));
sammc6ed3efb2016-11-23 03:17:35293 EXPECT_EQ(
294 IPC::MessageAttachment::Type::PLATFORM_FILE,
295 static_cast<IPC::MessageAttachment*>(attachment.get())->GetType());
296 base::File file(
297 static_cast<IPC::internal::PlatformFileAttachment*>(attachment.get())
298 ->TakePlatformFile());
morrita81b17e02015-02-06 00:58:30299 std::string content(GetSendingFileContent().size(), ' ');
300 file.Read(0, &content[0], content.size());
301 EXPECT_EQ(content, GetSendingFileContent());
302 }
303#endif
304};
305
306class ListenerThatExpectsMessagePipe : public IPC::Listener {
307 public:
308 ListenerThatExpectsMessagePipe() : sender_(NULL) {}
309
310 ~ListenerThatExpectsMessagePipe() override {}
311
312 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25313 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:30314 HandleSendingHelper::ReadReceivedPipe(message, &iter);
morrita81b17e02015-02-06 00:58:30315 ListenerThatExpectsOK::SendOK(sender_);
316 return true;
317 }
318
amistry6c70caea2016-06-09 03:08:29319 void OnChannelError() override {
320 base::MessageLoop::current()->QuitWhenIdle();
321 }
morrita81b17e02015-02-06 00:58:30322
323 void set_sender(IPC::Sender* sender) { sender_ = sender; }
324
325 private:
326 IPC::Sender* sender_;
327};
328
amistry0027a0952016-05-03 00:52:47329TEST_F(IPCChannelMojoTest, SendMessagePipe) {
sammc4bcc4ed62016-10-27 10:13:59330 Init("IPCChannelMojoTestSendMessagePipeClient");
morrita81b17e02015-02-06 00:58:30331
332 ListenerThatExpectsOK listener;
333 CreateChannel(&listener);
334 ASSERT_TRUE(ConnectChannel());
morrita81b17e02015-02-06 00:58:30335
336 TestingMessagePipe pipe;
337 HandleSendingHelper::WritePipeThenSend(channel(), &pipe);
338
fdoray8e32586852016-06-22 19:56:16339 base::RunLoop().Run();
sammc57ed9f982016-03-10 06:28:35340 channel()->Close();
morrita81b17e02015-02-06 00:58:30341
342 EXPECT_TRUE(WaitForClientShutdown());
343 DestroyChannel();
344}
345
sammc4bcc4ed62016-10-27 10:13:59346DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendMessagePipeClient) {
morrita81b17e02015-02-06 00:58:30347 ListenerThatExpectsMessagePipe listener;
sammc57ed9f982016-03-10 06:28:35348 Connect(&listener);
349 listener.set_sender(channel());
morrita81b17e02015-02-06 00:58:30350
fdoray8e32586852016-06-22 19:56:16351 base::RunLoop().Run();
morrita81b17e02015-02-06 00:58:30352
sammc57ed9f982016-03-10 06:28:35353 Close();
morrita81b17e02015-02-06 00:58:30354}
355
morrita438a2ee2015-04-03 05:28:21356void ReadOK(mojo::MessagePipeHandle pipe) {
357 std::string should_be_ok("xx");
358 uint32_t num_bytes = static_cast<uint32_t>(should_be_ok.size());
rockota9d566a2017-03-17 19:36:15359 CHECK_EQ(MOJO_RESULT_OK, mojo::Wait(pipe, MOJO_HANDLE_SIGNAL_READABLE));
morrita438a2ee2015-04-03 05:28:21360 CHECK_EQ(MOJO_RESULT_OK,
361 mojo::ReadMessageRaw(pipe, &should_be_ok[0], &num_bytes, nullptr,
362 nullptr, 0));
363 EXPECT_EQ(should_be_ok, std::string("OK"));
364}
365
366void WriteOK(mojo::MessagePipeHandle pipe) {
367 std::string ok("OK");
368 CHECK_EQ(MOJO_RESULT_OK,
369 mojo::WriteMessageRaw(pipe, &ok[0], static_cast<uint32_t>(ok.size()),
370 nullptr, 0, 0));
371}
372
373class ListenerThatExpectsMessagePipeUsingParamTrait : public IPC::Listener {
374 public:
375 explicit ListenerThatExpectsMessagePipeUsingParamTrait(bool receiving_valid)
376 : sender_(NULL), receiving_valid_(receiving_valid) {}
377
378 ~ListenerThatExpectsMessagePipeUsingParamTrait() override {}
379
380 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25381 base::PickleIterator iter(message);
morrita438a2ee2015-04-03 05:28:21382 mojo::MessagePipeHandle handle;
383 EXPECT_TRUE(IPC::ParamTraits<mojo::MessagePipeHandle>::Read(&message, &iter,
384 &handle));
385 EXPECT_EQ(handle.is_valid(), receiving_valid_);
386 if (receiving_valid_) {
387 ReadOK(handle);
388 MojoClose(handle.value());
389 }
390
morrita438a2ee2015-04-03 05:28:21391 ListenerThatExpectsOK::SendOK(sender_);
392 return true;
393 }
394
amistry6c70caea2016-06-09 03:08:29395 void OnChannelError() override {
396 base::MessageLoop::current()->QuitWhenIdle();
397 }
398
morrita438a2ee2015-04-03 05:28:21399 void set_sender(IPC::Sender* sender) { sender_ = sender; }
400
401 private:
402 IPC::Sender* sender_;
403 bool receiving_valid_;
404};
405
sammc4bcc4ed62016-10-27 10:13:59406class ParamTraitMessagePipeClient : public IpcChannelMojoTestClient {
sammc57ed9f982016-03-10 06:28:35407 public:
408 void RunTest(bool receiving_valid_handle) {
409 ListenerThatExpectsMessagePipeUsingParamTrait listener(
410 receiving_valid_handle);
411 Connect(&listener);
412 listener.set_sender(channel());
morrita438a2ee2015-04-03 05:28:21413
fdoray8e32586852016-06-22 19:56:16414 base::RunLoop().Run();
morrita438a2ee2015-04-03 05:28:21415
sammc57ed9f982016-03-10 06:28:35416 Close();
417 }
418};
morrita438a2ee2015-04-03 05:28:21419
amistry0027a0952016-05-03 00:52:47420TEST_F(IPCChannelMojoTest, ParamTraitValidMessagePipe) {
sammc4bcc4ed62016-10-27 10:13:59421 Init("ParamTraitValidMessagePipeClient");
morrita438a2ee2015-04-03 05:28:21422
423 ListenerThatExpectsOK listener;
424 CreateChannel(&listener);
425 ASSERT_TRUE(ConnectChannel());
morrita438a2ee2015-04-03 05:28:21426
427 TestingMessagePipe pipe;
428
danakj03de39b22016-04-23 04:21:09429 std::unique_ptr<IPC::Message> message(new IPC::Message());
morrita438a2ee2015-04-03 05:28:21430 IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
431 pipe.peer.release());
432 WriteOK(pipe.self.get());
433
sammc57ed9f982016-03-10 06:28:35434 channel()->Send(message.release());
fdoray8e32586852016-06-22 19:56:16435 base::RunLoop().Run();
sammc57ed9f982016-03-10 06:28:35436 channel()->Close();
morrita438a2ee2015-04-03 05:28:21437
438 EXPECT_TRUE(WaitForClientShutdown());
439 DestroyChannel();
440}
441
sammc4bcc4ed62016-10-27 10:13:59442DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
443 ParamTraitValidMessagePipeClient,
444 ParamTraitMessagePipeClient) {
sammc57ed9f982016-03-10 06:28:35445 RunTest(true);
morrita438a2ee2015-04-03 05:28:21446}
447
amistry0027a0952016-05-03 00:52:47448TEST_F(IPCChannelMojoTest, ParamTraitInvalidMessagePipe) {
sammc4bcc4ed62016-10-27 10:13:59449 Init("ParamTraitInvalidMessagePipeClient");
morrita438a2ee2015-04-03 05:28:21450
451 ListenerThatExpectsOK listener;
452 CreateChannel(&listener);
453 ASSERT_TRUE(ConnectChannel());
morrita438a2ee2015-04-03 05:28:21454
455 mojo::MessagePipeHandle invalid_handle;
danakj03de39b22016-04-23 04:21:09456 std::unique_ptr<IPC::Message> message(new IPC::Message());
morrita438a2ee2015-04-03 05:28:21457 IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
458 invalid_handle);
459
sammc57ed9f982016-03-10 06:28:35460 channel()->Send(message.release());
fdoray8e32586852016-06-22 19:56:16461 base::RunLoop().Run();
sammc57ed9f982016-03-10 06:28:35462 channel()->Close();
morrita438a2ee2015-04-03 05:28:21463
464 EXPECT_TRUE(WaitForClientShutdown());
465 DestroyChannel();
466}
467
sammc4bcc4ed62016-10-27 10:13:59468DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
469 ParamTraitInvalidMessagePipeClient,
470 ParamTraitMessagePipeClient) {
sammc57ed9f982016-03-10 06:28:35471 RunTest(false);
morrita438a2ee2015-04-03 05:28:21472}
473
amistry0027a0952016-05-03 00:52:47474TEST_F(IPCChannelMojoTest, SendFailAfterClose) {
sammc4bcc4ed62016-10-27 10:13:59475 Init("IPCChannelMojoTestSendOkClient");
morrita17137e62015-06-23 22:29:36476
477 ListenerThatExpectsOK listener;
478 CreateChannel(&listener);
479 ASSERT_TRUE(ConnectChannel());
morrita17137e62015-06-23 22:29:36480
fdoray8e32586852016-06-22 19:56:16481 base::RunLoop().Run();
sammc57ed9f982016-03-10 06:28:35482 channel()->Close();
483 ASSERT_FALSE(channel()->Send(new IPC::Message()));
morrita17137e62015-06-23 22:29:36484
485 EXPECT_TRUE(WaitForClientShutdown());
486 DestroyChannel();
487}
488
489class ListenerSendingOneOk : public IPC::Listener {
490 public:
sammc57ed9f982016-03-10 06:28:35491 ListenerSendingOneOk() {}
morrita17137e62015-06-23 22:29:36492
sammc57ed9f982016-03-10 06:28:35493 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita17137e62015-06-23 22:29:36494
tfarina10a5c062015-09-04 18:47:57495 void OnChannelConnected(int32_t peer_pid) override {
morrita17137e62015-06-23 22:29:36496 ListenerThatExpectsOK::SendOK(sender_);
ki.stfua21ed8c2015-10-12 17:26:00497 base::MessageLoop::current()->QuitWhenIdle();
morrita17137e62015-06-23 22:29:36498 }
499
500 void set_sender(IPC::Sender* sender) { sender_ = sender; }
501
502 private:
503 IPC::Sender* sender_;
504};
505
sammc4bcc4ed62016-10-27 10:13:59506DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendOkClient) {
morrita17137e62015-06-23 22:29:36507 ListenerSendingOneOk listener;
sammc57ed9f982016-03-10 06:28:35508 Connect(&listener);
509 listener.set_sender(channel());
morrita17137e62015-06-23 22:29:36510
fdoray8e32586852016-06-22 19:56:16511 base::RunLoop().Run();
morrita17137e62015-06-23 22:29:36512
sammc57ed9f982016-03-10 06:28:35513 Close();
morrita17137e62015-06-23 22:29:36514}
515
rockot7c6bf952016-07-14 00:34:11516class ListenerWithSimpleAssociatedInterface
517 : public IPC::Listener,
518 public IPC::mojom::SimpleTestDriver {
519 public:
520 static const int kNumMessages;
521
522 ListenerWithSimpleAssociatedInterface() : binding_(this) {}
523
524 ~ListenerWithSimpleAssociatedInterface() override {}
525
526 bool OnMessageReceived(const IPC::Message& message) override {
527 base::PickleIterator iter(message);
rockot9abe09b2016-08-02 20:57:34528 int32_t should_be_expected;
529 EXPECT_TRUE(iter.ReadInt(&should_be_expected));
530 EXPECT_EQ(should_be_expected, next_expected_value_);
rockot7c6bf952016-07-14 00:34:11531 num_messages_received_++;
532 return true;
533 }
534
535 void OnChannelError() override {
536 DCHECK(received_quit_);
537 }
538
539 void RegisterInterfaceFactory(IPC::Channel* channel) {
540 channel->GetAssociatedInterfaceSupport()->AddAssociatedInterface(
541 base::Bind(&ListenerWithSimpleAssociatedInterface::BindRequest,
542 base::Unretained(this)));
543 }
544
545 private:
546 // IPC::mojom::SimpleTestDriver:
rockot9abe09b2016-08-02 20:57:34547 void ExpectValue(int32_t value) override {
548 next_expected_value_ = value;
549 }
550
551 void GetExpectedValue(const GetExpectedValueCallback& callback) override {
552 NOTREACHED();
553 }
554
555 void RequestValue(const RequestValueCallback& callback) override {
556 NOTREACHED();
rockot7c6bf952016-07-14 00:34:11557 }
558
559 void RequestQuit(const RequestQuitCallback& callback) override {
560 EXPECT_EQ(kNumMessages, num_messages_received_);
561 received_quit_ = true;
562 callback.Run();
563 base::MessageLoop::current()->QuitWhenIdle();
564 }
565
566 void BindRequest(IPC::mojom::SimpleTestDriverAssociatedRequest request) {
567 DCHECK(!binding_.is_bound());
568 binding_.Bind(std::move(request));
569 }
570
rockot9abe09b2016-08-02 20:57:34571 int32_t next_expected_value_ = 0;
rockot7c6bf952016-07-14 00:34:11572 int num_messages_received_ = 0;
573 bool received_quit_ = false;
574
575 mojo::AssociatedBinding<IPC::mojom::SimpleTestDriver> binding_;
576};
577
578const int ListenerWithSimpleAssociatedInterface::kNumMessages = 1000;
579
580class ListenerSendingAssociatedMessages : public IPC::Listener {
581 public:
582 ListenerSendingAssociatedMessages() {}
583
584 bool OnMessageReceived(const IPC::Message& message) override { return true; }
585
586 void OnChannelConnected(int32_t peer_pid) override {
587 DCHECK(channel_);
588 channel_->GetAssociatedInterfaceSupport()->GetRemoteAssociatedInterface(
589 &driver_);
590
591 // Send a bunch of interleaved messages, alternating between the associated
592 // interface and a legacy IPC::Message.
593 for (int i = 0; i < ListenerWithSimpleAssociatedInterface::kNumMessages;
594 ++i) {
rockot9abe09b2016-08-02 20:57:34595 driver_->ExpectValue(i);
596 SendValue(channel_, i);
rockot7c6bf952016-07-14 00:34:11597 }
598 driver_->RequestQuit(base::Bind(&OnQuitAck));
599 }
600
601 void set_channel(IPC::Channel* channel) { channel_ = channel; }
602
603 private:
604 static void OnQuitAck() { base::MessageLoop::current()->QuitWhenIdle(); }
605
606 IPC::Channel* channel_ = nullptr;
607 IPC::mojom::SimpleTestDriverAssociatedPtr driver_;
608};
609
610TEST_F(IPCChannelMojoTest, SimpleAssociatedInterface) {
sammc4bcc4ed62016-10-27 10:13:59611 Init("SimpleAssociatedInterfaceClient");
rockot7c6bf952016-07-14 00:34:11612
613 ListenerWithSimpleAssociatedInterface listener;
614 CreateChannel(&listener);
615 ASSERT_TRUE(ConnectChannel());
616
617 listener.RegisterInterfaceFactory(channel());
618
619 base::RunLoop().Run();
620 channel()->Close();
621
622 EXPECT_TRUE(WaitForClientShutdown());
623 DestroyChannel();
624}
625
sammc4bcc4ed62016-10-27 10:13:59626DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(SimpleAssociatedInterfaceClient) {
rockot7c6bf952016-07-14 00:34:11627 ListenerSendingAssociatedMessages listener;
628 Connect(&listener);
629 listener.set_channel(channel());
630
631 base::RunLoop().Run();
632
633 Close();
634}
635
rockot8d890f62016-07-14 16:37:14636class ChannelProxyRunner {
637 public:
rockota34707ca2016-07-20 04:28:32638 ChannelProxyRunner(mojo::ScopedMessagePipeHandle handle,
639 bool for_server)
640 : for_server_(for_server),
641 handle_(std::move(handle)),
rockot9abe09b2016-08-02 20:57:34642 io_thread_("ChannelProxyRunner IO thread"),
643 never_signaled_(base::WaitableEvent::ResetPolicy::MANUAL,
644 base::WaitableEvent::InitialState::NOT_SIGNALED) {
rockot8d890f62016-07-14 16:37:14645 }
646
647 void CreateProxy(IPC::Listener* listener) {
648 io_thread_.StartWithOptions(
649 base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
rockot9abe09b2016-08-02 20:57:34650 proxy_ = IPC::SyncChannel::Create(
651 listener, io_thread_.task_runner(), &never_signaled_);
rockot8d890f62016-07-14 16:37:14652 }
rockota34707ca2016-07-20 04:28:32653
rockot10188752016-09-08 18:24:56654 void RunProxy() {
rockota34707ca2016-07-20 04:28:32655 std::unique_ptr<IPC::ChannelFactory> factory;
656 if (for_server_) {
657 factory = IPC::ChannelMojo::CreateServerFactory(
658 std::move(handle_), io_thread_.task_runner());
659 } else {
660 factory = IPC::ChannelMojo::CreateClientFactory(
661 std::move(handle_), io_thread_.task_runner());
662 }
rockot10188752016-09-08 18:24:56663 proxy_->Init(std::move(factory), true);
rockota34707ca2016-07-20 04:28:32664 }
rockot8d890f62016-07-14 16:37:14665
666 IPC::ChannelProxy* proxy() { return proxy_.get(); }
667
668 private:
rockota34707ca2016-07-20 04:28:32669 const bool for_server_;
rockot8d890f62016-07-14 16:37:14670
rockota34707ca2016-07-20 04:28:32671 mojo::ScopedMessagePipeHandle handle_;
rockot8d890f62016-07-14 16:37:14672 base::Thread io_thread_;
rockot9abe09b2016-08-02 20:57:34673 base::WaitableEvent never_signaled_;
rockotb62e2e32017-03-24 18:36:44674 std::unique_ptr<IPC::ChannelProxy> proxy_;
rockot8d890f62016-07-14 16:37:14675
676 DISALLOW_COPY_AND_ASSIGN(ChannelProxyRunner);
677};
678
679class IPCChannelProxyMojoTest : public IPCChannelMojoTestBase {
680 public:
sammc4bcc4ed62016-10-27 10:13:59681 void Init(const std::string& client_name) {
682 IPCChannelMojoTestBase::Init(client_name);
rockota34707ca2016-07-20 04:28:32683 runner_.reset(new ChannelProxyRunner(TakeHandle(), true));
rockot8d890f62016-07-14 16:37:14684 }
685 void CreateProxy(IPC::Listener* listener) { runner_->CreateProxy(listener); }
rockot10188752016-09-08 18:24:56686 void RunProxy() {
687 runner_->RunProxy();
rockot401fb2c2016-09-06 18:35:57688 }
rockot0e4de5f2016-07-22 21:18:07689 void DestroyProxy() {
690 runner_.reset();
691 base::RunLoop().RunUntilIdle();
692 }
rockot8d890f62016-07-14 16:37:14693
694 IPC::ChannelProxy* proxy() { return runner_->proxy(); }
695
696 private:
rockot8d890f62016-07-14 16:37:14697 std::unique_ptr<ChannelProxyRunner> runner_;
698};
699
700class ListenerWithSimpleProxyAssociatedInterface
701 : public IPC::Listener,
702 public IPC::mojom::SimpleTestDriver {
703 public:
704 static const int kNumMessages;
705
706 ListenerWithSimpleProxyAssociatedInterface() : binding_(this) {}
707
708 ~ListenerWithSimpleProxyAssociatedInterface() override {}
709
710 bool OnMessageReceived(const IPC::Message& message) override {
711 base::PickleIterator iter(message);
rockot9abe09b2016-08-02 20:57:34712 int32_t should_be_expected;
713 EXPECT_TRUE(iter.ReadInt(&should_be_expected));
714 EXPECT_EQ(should_be_expected, next_expected_value_);
rockot8d890f62016-07-14 16:37:14715 num_messages_received_++;
716 return true;
717 }
718
719 void OnChannelError() override {
720 DCHECK(received_quit_);
721 }
722
rockotf62002a2016-09-15 00:08:59723 void OnAssociatedInterfaceRequest(
724 const std::string& interface_name,
725 mojo::ScopedInterfaceEndpointHandle handle) override {
726 DCHECK_EQ(interface_name, IPC::mojom::SimpleTestDriver::Name_);
727 IPC::mojom::SimpleTestDriverAssociatedRequest request;
728 request.Bind(std::move(handle));
729 binding_.Bind(std::move(request));
rockot8d890f62016-07-14 16:37:14730 }
731
732 bool received_all_messages() const {
733 return num_messages_received_ == kNumMessages && received_quit_;
734 }
735
736 private:
737 // IPC::mojom::SimpleTestDriver:
rockot9abe09b2016-08-02 20:57:34738 void ExpectValue(int32_t value) override {
739 next_expected_value_ = value;
740 }
741
742 void GetExpectedValue(const GetExpectedValueCallback& callback) override {
743 callback.Run(next_expected_value_);
744 }
745
746 void RequestValue(const RequestValueCallback& callback) override {
747 NOTREACHED();
rockot8d890f62016-07-14 16:37:14748 }
749
750 void RequestQuit(const RequestQuitCallback& callback) override {
751 received_quit_ = true;
752 callback.Run();
rockot0e4de5f2016-07-22 21:18:07753 binding_.Close();
rockot8d890f62016-07-14 16:37:14754 base::MessageLoop::current()->QuitWhenIdle();
755 }
756
757 void BindRequest(IPC::mojom::SimpleTestDriverAssociatedRequest request) {
758 DCHECK(!binding_.is_bound());
759 binding_.Bind(std::move(request));
760 }
761
rockot9abe09b2016-08-02 20:57:34762 int32_t next_expected_value_ = 0;
rockot8d890f62016-07-14 16:37:14763 int num_messages_received_ = 0;
764 bool received_quit_ = false;
765
766 mojo::AssociatedBinding<IPC::mojom::SimpleTestDriver> binding_;
767};
768
769const int ListenerWithSimpleProxyAssociatedInterface::kNumMessages = 1000;
770
771TEST_F(IPCChannelProxyMojoTest, ProxyThreadAssociatedInterface) {
sammc4bcc4ed62016-10-27 10:13:59772 Init("ProxyThreadAssociatedInterfaceClient");
rockot8d890f62016-07-14 16:37:14773
774 ListenerWithSimpleProxyAssociatedInterface listener;
775 CreateProxy(&listener);
rockot8d890f62016-07-14 16:37:14776 RunProxy();
777
778 base::RunLoop().Run();
779
780 EXPECT_TRUE(WaitForClientShutdown());
781 EXPECT_TRUE(listener.received_all_messages());
782
rockot0e4de5f2016-07-22 21:18:07783 DestroyProxy();
rockot8d890f62016-07-14 16:37:14784}
785
786class ChannelProxyClient {
787 public:
788 void Init(mojo::ScopedMessagePipeHandle handle) {
rockota34707ca2016-07-20 04:28:32789 runner_.reset(new ChannelProxyRunner(std::move(handle), false));
rockot8d890f62016-07-14 16:37:14790 }
rockot9abe09b2016-08-02 20:57:34791
rockot8d890f62016-07-14 16:37:14792 void CreateProxy(IPC::Listener* listener) { runner_->CreateProxy(listener); }
rockot9abe09b2016-08-02 20:57:34793
rockot10188752016-09-08 18:24:56794 void RunProxy() { runner_->RunProxy(); }
rockot9abe09b2016-08-02 20:57:34795
rockot0e4de5f2016-07-22 21:18:07796 void DestroyProxy() {
797 runner_.reset();
798 base::RunLoop().RunUntilIdle();
799 }
rockot8d890f62016-07-14 16:37:14800
rockot9abe09b2016-08-02 20:57:34801 void RequestQuitAndWaitForAck(IPC::mojom::SimpleTestDriver* driver) {
802 base::RunLoop loop;
803 driver->RequestQuit(loop.QuitClosure());
804 loop.Run();
805 }
806
rockot8d890f62016-07-14 16:37:14807 IPC::ChannelProxy* proxy() { return runner_->proxy(); }
808
809 private:
810 base::MessageLoop message_loop_;
811 std::unique_ptr<ChannelProxyRunner> runner_;
812};
813
rockot0e4de5f2016-07-22 21:18:07814class DummyListener : public IPC::Listener {
rockot8d890f62016-07-14 16:37:14815 public:
rockot8d890f62016-07-14 16:37:14816 // IPC::Listener
817 bool OnMessageReceived(const IPC::Message& message) override { return true; }
rockot8d890f62016-07-14 16:37:14818};
819
sammc4bcc4ed62016-10-27 10:13:59820DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
821 ProxyThreadAssociatedInterfaceClient,
822 ChannelProxyClient) {
rockot0e4de5f2016-07-22 21:18:07823 DummyListener listener;
rockot8d890f62016-07-14 16:37:14824 CreateProxy(&listener);
825 RunProxy();
rockot8d890f62016-07-14 16:37:14826
827 // Send a bunch of interleaved messages, alternating between the associated
828 // interface and a legacy IPC::Message.
829 IPC::mojom::SimpleTestDriverAssociatedPtr driver;
830 proxy()->GetRemoteAssociatedInterface(&driver);
831 for (int i = 0; i < ListenerWithSimpleProxyAssociatedInterface::kNumMessages;
832 ++i) {
rockot9abe09b2016-08-02 20:57:34833 driver->ExpectValue(i);
834 SendValue(proxy(), i);
rockot8d890f62016-07-14 16:37:14835 }
836 driver->RequestQuit(base::MessageLoop::QuitWhenIdleClosure());
837 base::RunLoop().Run();
rockot0e4de5f2016-07-22 21:18:07838
839 DestroyProxy();
rockot8d890f62016-07-14 16:37:14840}
841
rockot401fb2c2016-09-06 18:35:57842class ListenerWithIndirectProxyAssociatedInterface
843 : public IPC::Listener,
844 public IPC::mojom::IndirectTestDriver,
845 public IPC::mojom::PingReceiver {
846 public:
847 ListenerWithIndirectProxyAssociatedInterface()
848 : driver_binding_(this), ping_receiver_binding_(this) {}
849 ~ListenerWithIndirectProxyAssociatedInterface() override {}
850
rockot70bbb59492017-01-25 00:56:51851 // IPC::Listener:
rockot401fb2c2016-09-06 18:35:57852 bool OnMessageReceived(const IPC::Message& message) override { return true; }
853
rockot70bbb59492017-01-25 00:56:51854 void OnAssociatedInterfaceRequest(
855 const std::string& interface_name,
856 mojo::ScopedInterfaceEndpointHandle handle) override {
857 DCHECK(!driver_binding_.is_bound());
858 DCHECK_EQ(interface_name, IPC::mojom::IndirectTestDriver::Name_);
859 IPC::mojom::IndirectTestDriverAssociatedRequest request;
860 request.Bind(std::move(handle));
861 driver_binding_.Bind(std::move(request));
rockot401fb2c2016-09-06 18:35:57862 }
863
864 void set_ping_handler(const base::Closure& handler) {
865 ping_handler_ = handler;
866 }
867
868 private:
869 // IPC::mojom::IndirectTestDriver:
870 void GetPingReceiver(
871 IPC::mojom::PingReceiverAssociatedRequest request) override {
872 ping_receiver_binding_.Bind(std::move(request));
873 }
874
875 // IPC::mojom::PingReceiver:
876 void Ping(const PingCallback& callback) override {
877 callback.Run();
878 ping_handler_.Run();
879 }
880
rockot401fb2c2016-09-06 18:35:57881 mojo::AssociatedBinding<IPC::mojom::IndirectTestDriver> driver_binding_;
882 mojo::AssociatedBinding<IPC::mojom::PingReceiver> ping_receiver_binding_;
883
884 base::Closure ping_handler_;
885};
886
887TEST_F(IPCChannelProxyMojoTest, ProxyThreadAssociatedInterfaceIndirect) {
888 // Tests that we can pipeline interface requests and subsequent messages
889 // targeting proxy thread bindings, and the channel will still dispatch
890 // messages appropriately.
891
sammc4bcc4ed62016-10-27 10:13:59892 Init("ProxyThreadAssociatedInterfaceIndirectClient");
rockot401fb2c2016-09-06 18:35:57893
894 ListenerWithIndirectProxyAssociatedInterface listener;
895 CreateProxy(&listener);
rockot401fb2c2016-09-06 18:35:57896 RunProxy();
897
898 base::RunLoop loop;
899 listener.set_ping_handler(loop.QuitClosure());
900 loop.Run();
901
902 EXPECT_TRUE(WaitForClientShutdown());
903
904 DestroyProxy();
905}
906
sammc4bcc4ed62016-10-27 10:13:59907DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
rockot401fb2c2016-09-06 18:35:57908 ProxyThreadAssociatedInterfaceIndirectClient,
909 ChannelProxyClient) {
910 DummyListener listener;
911 CreateProxy(&listener);
912 RunProxy();
913
914 // Use an interface requested via another interface. On the remote end both
915 // interfaces are bound on the proxy thread. This ensures that the Ping
916 // message we send will still be dispatched properly even though the remote
917 // endpoint may not have been bound yet by the time the message is initially
918 // processed on the IO thread.
919 IPC::mojom::IndirectTestDriverAssociatedPtr driver;
920 IPC::mojom::PingReceiverAssociatedPtr ping_receiver;
921 proxy()->GetRemoteAssociatedInterface(&driver);
yzshen1aa8e56c2017-02-16 23:15:45922 driver->GetPingReceiver(mojo::MakeRequest(&ping_receiver));
rockot401fb2c2016-09-06 18:35:57923
924 base::RunLoop loop;
925 ping_receiver->Ping(loop.QuitClosure());
926 loop.Run();
927
928 DestroyProxy();
929}
930
rockot9abe09b2016-08-02 20:57:34931class ListenerWithSyncAssociatedInterface
932 : public IPC::Listener,
933 public IPC::mojom::SimpleTestDriver {
934 public:
935 ListenerWithSyncAssociatedInterface() : binding_(this) {}
936 ~ListenerWithSyncAssociatedInterface() override {}
937
938 void set_sync_sender(IPC::Sender* sync_sender) { sync_sender_ = sync_sender; }
939
rockot9abe09b2016-08-02 20:57:34940 void RunUntilQuitRequested() {
941 base::RunLoop loop;
942 quit_closure_ = loop.QuitClosure();
943 loop.Run();
944 }
945
946 void CloseBinding() { binding_.Close(); }
947
948 void set_response_value(int32_t response) {
949 response_value_ = response;
950 }
951
952 private:
953 // IPC::mojom::SimpleTestDriver:
954 void ExpectValue(int32_t value) override {
955 next_expected_value_ = value;
956 }
957
958 void GetExpectedValue(const GetExpectedValueCallback& callback) override {
959 callback.Run(next_expected_value_);
960 }
961
962 void RequestValue(const RequestValueCallback& callback) override {
963 callback.Run(response_value_);
964 }
965
966 void RequestQuit(const RequestQuitCallback& callback) override {
967 quit_closure_.Run();
968 callback.Run();
969 }
970
971 // IPC::Listener:
972 bool OnMessageReceived(const IPC::Message& message) override {
973 EXPECT_EQ(0u, message.type());
974 EXPECT_TRUE(message.is_sync());
975 EXPECT_TRUE(message.should_unblock());
976 std::unique_ptr<IPC::Message> reply(
977 IPC::SyncMessage::GenerateReply(&message));
978 reply->WriteInt(response_value_);
979 DCHECK(sync_sender_);
980 EXPECT_TRUE(sync_sender_->Send(reply.release()));
981 return true;
982 }
983
rockot70bbb59492017-01-25 00:56:51984 void OnAssociatedInterfaceRequest(
985 const std::string& interface_name,
986 mojo::ScopedInterfaceEndpointHandle handle) override {
987 DCHECK(!binding_.is_bound());
988 DCHECK_EQ(interface_name, IPC::mojom::SimpleTestDriver::Name_);
989
990 IPC::mojom::SimpleTestDriverAssociatedRequest request;
991 request.Bind(std::move(handle));
992 binding_.Bind(std::move(request));
993 }
994
rockot9abe09b2016-08-02 20:57:34995 void BindRequest(IPC::mojom::SimpleTestDriverAssociatedRequest request) {
996 DCHECK(!binding_.is_bound());
997 binding_.Bind(std::move(request));
998 }
999
1000 IPC::Sender* sync_sender_ = nullptr;
1001 int32_t next_expected_value_ = 0;
1002 int32_t response_value_ = 0;
1003 base::Closure quit_closure_;
1004
1005 mojo::AssociatedBinding<IPC::mojom::SimpleTestDriver> binding_;
1006};
1007
1008class SyncReplyReader : public IPC::MessageReplyDeserializer {
1009 public:
1010 explicit SyncReplyReader(int32_t* storage) : storage_(storage) {}
1011 ~SyncReplyReader() override {}
1012
1013 private:
1014 // IPC::MessageReplyDeserializer:
1015 bool SerializeOutputParameters(const IPC::Message& message,
1016 base::PickleIterator iter) override {
1017 if (!iter.ReadInt(storage_))
1018 return false;
1019 return true;
1020 }
1021
1022 int32_t* storage_;
1023
1024 DISALLOW_COPY_AND_ASSIGN(SyncReplyReader);
1025};
1026
1027TEST_F(IPCChannelProxyMojoTest, SyncAssociatedInterface) {
sammc4bcc4ed62016-10-27 10:13:591028 Init("SyncAssociatedInterface");
rockot9abe09b2016-08-02 20:57:341029
1030 ListenerWithSyncAssociatedInterface listener;
1031 CreateProxy(&listener);
1032 listener.set_sync_sender(proxy());
rockot9abe09b2016-08-02 20:57:341033 RunProxy();
1034
1035 // Run the client's simple sanity check to completion.
1036 listener.RunUntilQuitRequested();
1037
1038 // Verify that we can send a sync IPC and service an incoming sync request
1039 // while waiting on it
1040 listener.set_response_value(42);
1041 IPC::mojom::SimpleTestClientAssociatedPtr client;
1042 proxy()->GetRemoteAssociatedInterface(&client);
1043 int32_t received_value;
1044 EXPECT_TRUE(client->RequestValue(&received_value));
1045 EXPECT_EQ(42, received_value);
1046
1047 // Do it again. This time the client will send a classical sync IPC to us
1048 // while we wait.
1049 received_value = 0;
1050 EXPECT_TRUE(client->RequestValue(&received_value));
1051 EXPECT_EQ(42, received_value);
1052
1053 // Now make a classical sync IPC request to the client. It will send a
1054 // sync associated interface message to us while we wait.
1055 received_value = 0;
1056 std::unique_ptr<IPC::SyncMessage> request(
1057 new IPC::SyncMessage(0, 0, IPC::Message::PRIORITY_NORMAL,
1058 new SyncReplyReader(&received_value)));
1059 EXPECT_TRUE(proxy()->Send(request.release()));
1060 EXPECT_EQ(42, received_value);
1061
1062 listener.CloseBinding();
1063 EXPECT_TRUE(WaitForClientShutdown());
1064
1065 DestroyProxy();
1066}
1067
1068class SimpleTestClientImpl : public IPC::mojom::SimpleTestClient,
1069 public IPC::Listener {
1070 public:
1071 SimpleTestClientImpl() : binding_(this) {}
1072
1073 void set_driver(IPC::mojom::SimpleTestDriver* driver) { driver_ = driver; }
1074 void set_sync_sender(IPC::Sender* sync_sender) { sync_sender_ = sync_sender; }
1075
rockot9abe09b2016-08-02 20:57:341076 void WaitForValueRequest() {
1077 run_loop_.reset(new base::RunLoop);
1078 run_loop_->Run();
1079 }
1080
1081 void UseSyncSenderForRequest(bool use_sync_sender) {
1082 use_sync_sender_ = use_sync_sender;
1083 }
1084
1085 private:
1086 // IPC::mojom::SimpleTestClient:
1087 void RequestValue(const RequestValueCallback& callback) override {
1088 int32_t response = 0;
1089 if (use_sync_sender_) {
1090 std::unique_ptr<IPC::SyncMessage> reply(new IPC::SyncMessage(
1091 0, 0, IPC::Message::PRIORITY_NORMAL, new SyncReplyReader(&response)));
1092 EXPECT_TRUE(sync_sender_->Send(reply.release()));
1093 } else {
1094 DCHECK(driver_);
1095 EXPECT_TRUE(driver_->RequestValue(&response));
1096 }
1097
1098 callback.Run(response);
1099
1100 DCHECK(run_loop_);
1101 run_loop_->Quit();
1102 }
1103
1104 // IPC::Listener:
1105 bool OnMessageReceived(const IPC::Message& message) override {
1106 int32_t response;
1107 DCHECK(driver_);
1108 EXPECT_TRUE(driver_->RequestValue(&response));
1109 std::unique_ptr<IPC::Message> reply(
1110 IPC::SyncMessage::GenerateReply(&message));
1111 reply->WriteInt(response);
1112 EXPECT_TRUE(sync_sender_->Send(reply.release()));
1113
1114 DCHECK(run_loop_);
1115 run_loop_->Quit();
1116 return true;
1117 }
1118
rockot70bbb59492017-01-25 00:56:511119 void OnAssociatedInterfaceRequest(
1120 const std::string& interface_name,
1121 mojo::ScopedInterfaceEndpointHandle handle) override {
1122 DCHECK(!binding_.is_bound());
1123 DCHECK_EQ(interface_name, IPC::mojom::SimpleTestClient::Name_);
1124
1125 IPC::mojom::SimpleTestClientAssociatedRequest request;
1126 request.Bind(std::move(handle));
1127 binding_.Bind(std::move(request));
1128 }
1129
rockot9abe09b2016-08-02 20:57:341130 bool use_sync_sender_ = false;
1131 mojo::AssociatedBinding<IPC::mojom::SimpleTestClient> binding_;
1132 IPC::Sender* sync_sender_ = nullptr;
1133 IPC::mojom::SimpleTestDriver* driver_ = nullptr;
1134 std::unique_ptr<base::RunLoop> run_loop_;
1135
1136 DISALLOW_COPY_AND_ASSIGN(SimpleTestClientImpl);
1137};
1138
sammc4bcc4ed62016-10-27 10:13:591139DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(SyncAssociatedInterface,
1140 ChannelProxyClient) {
rockot9abe09b2016-08-02 20:57:341141 SimpleTestClientImpl client_impl;
1142 CreateProxy(&client_impl);
1143 client_impl.set_sync_sender(proxy());
rockot9abe09b2016-08-02 20:57:341144 RunProxy();
1145
1146 IPC::mojom::SimpleTestDriverAssociatedPtr driver;
1147 proxy()->GetRemoteAssociatedInterface(&driver);
1148 client_impl.set_driver(driver.get());
1149
1150 // Simple sync message sanity check.
1151 driver->ExpectValue(42);
1152 int32_t expected_value = 0;
1153 EXPECT_TRUE(driver->GetExpectedValue(&expected_value));
1154 EXPECT_EQ(42, expected_value);
1155 RequestQuitAndWaitForAck(driver.get());
1156
1157 // Wait for the test driver to perform a sync call test with our own sync
1158 // associated interface message nested inside.
1159 client_impl.UseSyncSenderForRequest(false);
1160 client_impl.WaitForValueRequest();
1161
1162 // Wait for the test driver to perform a sync call test with our own classical
1163 // sync IPC nested inside.
1164 client_impl.UseSyncSenderForRequest(true);
1165 client_impl.WaitForValueRequest();
1166
1167 // Wait for the test driver to perform a classical sync IPC request, with our
1168 // own sync associated interface message nested inside.
1169 client_impl.UseSyncSenderForRequest(false);
1170 client_impl.WaitForValueRequest();
1171
1172 DestroyProxy();
1173}
1174
rockot10188752016-09-08 18:24:561175TEST_F(IPCChannelProxyMojoTest, Pause) {
1176 // Ensures that pausing a channel elicits the expected behavior when sending
1177 // messages, unpausing, sending more messages, and then manually flushing.
1178 // Specifically a sequence like:
rockot401fb2c2016-09-06 18:35:571179 //
1180 // Connect()
1181 // Send(A)
rockot10188752016-09-08 18:24:561182 // Pause()
rockot401fb2c2016-09-06 18:35:571183 // Send(B)
rockot401fb2c2016-09-06 18:35:571184 // Send(C)
rockot10188752016-09-08 18:24:561185 // Unpause(false)
1186 // Send(D)
1187 // Send(E)
rockot401fb2c2016-09-06 18:35:571188 // Flush()
1189 //
rockot10188752016-09-08 18:24:561190 // must result in the other end receiving messages A, D, E, B, D; in that
rockot401fb2c2016-09-06 18:35:571191 // order.
1192 //
1193 // This behavior is required by some consumers of IPC::Channel, and it is not
1194 // sufficient to leave this up to the consumer to implement since associated
1195 // interface requests and messages also need to be queued according to the
1196 // same policy.
sammc4bcc4ed62016-10-27 10:13:591197 Init("CreatePausedClient");
rockot401fb2c2016-09-06 18:35:571198
1199 DummyListener listener;
1200 CreateProxy(&listener);
rockot10188752016-09-08 18:24:561201 RunProxy();
1202
1203 // This message must be sent immediately since the channel is unpaused.
1204 SendValue(proxy(), 1);
1205
1206 proxy()->Pause();
rockot401fb2c2016-09-06 18:35:571207
1208 // These messages must be queued internally since the channel is paused.
rockot401fb2c2016-09-06 18:35:571209 SendValue(proxy(), 2);
rockot10188752016-09-08 18:24:561210 SendValue(proxy(), 3);
rockot401fb2c2016-09-06 18:35:571211
1212 proxy()->Unpause(false /* flush */);
1213
1214 // These messages must be sent immediately since the channel is unpaused.
rockot401fb2c2016-09-06 18:35:571215 SendValue(proxy(), 4);
rockot10188752016-09-08 18:24:561216 SendValue(proxy(), 5);
rockot401fb2c2016-09-06 18:35:571217
1218 // Now we flush the previously queued messages.
1219 proxy()->Flush();
1220
1221 EXPECT_TRUE(WaitForClientShutdown());
1222 DestroyProxy();
1223}
1224
1225class ExpectValueSequenceListener : public IPC::Listener {
1226 public:
1227 explicit ExpectValueSequenceListener(std::queue<int32_t>* expected_values)
1228 : expected_values_(expected_values) {}
1229 ~ExpectValueSequenceListener() override {}
1230
1231 // IPC::Listener:
1232 bool OnMessageReceived(const IPC::Message& message) override {
1233 DCHECK(!expected_values_->empty());
1234 base::PickleIterator iter(message);
1235 int32_t should_be_expected;
1236 EXPECT_TRUE(iter.ReadInt(&should_be_expected));
1237 EXPECT_EQ(expected_values_->front(), should_be_expected);
1238 expected_values_->pop();
1239 if (expected_values_->empty())
1240 base::MessageLoop::current()->QuitWhenIdle();
1241 return true;
1242 }
1243
1244 private:
1245 std::queue<int32_t>* expected_values_;
1246
1247 DISALLOW_COPY_AND_ASSIGN(ExpectValueSequenceListener);
1248};
1249
sammc4bcc4ed62016-10-27 10:13:591250DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(CreatePausedClient,
1251 ChannelProxyClient) {
rockot401fb2c2016-09-06 18:35:571252 std::queue<int32_t> expected_values;
1253 ExpectValueSequenceListener listener(&expected_values);
1254 CreateProxy(&listener);
rockot401fb2c2016-09-06 18:35:571255 expected_values.push(1);
rockot10188752016-09-08 18:24:561256 expected_values.push(4);
1257 expected_values.push(5);
rockot401fb2c2016-09-06 18:35:571258 expected_values.push(2);
rockot10188752016-09-08 18:24:561259 expected_values.push(3);
rockot401fb2c2016-09-06 18:35:571260 RunProxy();
1261 base::RunLoop().Run();
1262 EXPECT_TRUE(expected_values.empty());
1263 DestroyProxy();
1264}
1265
sammc5c8a6c62017-02-04 01:33:381266TEST_F(IPCChannelProxyMojoTest, AssociatedRequestClose) {
1267 Init("DropAssociatedRequest");
1268
1269 DummyListener listener;
1270 CreateProxy(&listener);
1271 RunProxy();
1272
1273 IPC::mojom::AssociatedInterfaceVendorAssociatedPtr vendor;
1274 proxy()->GetRemoteAssociatedInterface(&vendor);
1275 IPC::mojom::SimpleTestDriverAssociatedPtr tester;
yzshen1aa8e56c2017-02-16 23:15:451276 vendor->GetTestInterface(mojo::MakeRequest(&tester));
sammc5c8a6c62017-02-04 01:33:381277 base::RunLoop run_loop;
1278 tester.set_connection_error_handler(run_loop.QuitClosure());
1279 run_loop.Run();
1280
1281 proxy()->GetRemoteAssociatedInterface(&tester);
1282 EXPECT_TRUE(WaitForClientShutdown());
1283 DestroyProxy();
1284}
1285
1286class AssociatedInterfaceDroppingListener : public IPC::Listener {
1287 public:
1288 AssociatedInterfaceDroppingListener(const base::Closure& callback)
1289 : callback_(callback) {}
1290 bool OnMessageReceived(const IPC::Message& message) override { return false; }
1291
1292 void OnAssociatedInterfaceRequest(
1293 const std::string& interface_name,
1294 mojo::ScopedInterfaceEndpointHandle handle) override {
1295 if (interface_name == IPC::mojom::SimpleTestDriver::Name_)
1296 base::ResetAndReturn(&callback_).Run();
1297 }
1298
1299 private:
1300 base::Closure callback_;
1301};
1302
1303DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(DropAssociatedRequest,
1304 ChannelProxyClient) {
1305 base::RunLoop run_loop;
1306 AssociatedInterfaceDroppingListener listener(run_loop.QuitClosure());
1307 CreateProxy(&listener);
1308 RunProxy();
1309 run_loop.Run();
1310 DestroyProxy();
1311}
1312
[email protected]64860882014-08-04 23:44:171313#if defined(OS_POSIX)
rockot8d890f62016-07-14 16:37:141314
[email protected]64860882014-08-04 23:44:171315class ListenerThatExpectsFile : public IPC::Listener {
1316 public:
sammc57ed9f982016-03-10 06:28:351317 ListenerThatExpectsFile() : sender_(NULL) {}
[email protected]64860882014-08-04 23:44:171318
dchengfe61fca2014-10-22 02:29:521319 ~ListenerThatExpectsFile() override {}
[email protected]64860882014-08-04 23:44:171320
dchengfe61fca2014-10-22 02:29:521321 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:251322 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:301323 HandleSendingHelper::ReadReceivedFile(message, &iter);
[email protected]64860882014-08-04 23:44:171324 ListenerThatExpectsOK::SendOK(sender_);
1325 return true;
1326 }
1327
amistry6c70caea2016-06-09 03:08:291328 void OnChannelError() override {
1329 base::MessageLoop::current()->QuitWhenIdle();
1330 }
[email protected]64860882014-08-04 23:44:171331
[email protected]64860882014-08-04 23:44:171332 void set_sender(IPC::Sender* sender) { sender_ = sender; }
1333
1334 private:
1335 IPC::Sender* sender_;
1336};
1337
amistry0027a0952016-05-03 00:52:471338TEST_F(IPCChannelMojoTest, SendPlatformHandle) {
sammc4bcc4ed62016-10-27 10:13:591339 Init("IPCChannelMojoTestSendPlatformHandleClient");
[email protected]64860882014-08-04 23:44:171340
1341 ListenerThatExpectsOK listener;
morrita373af03b2014-09-09 19:35:241342 CreateChannel(&listener);
[email protected]64860882014-08-04 23:44:171343 ASSERT_TRUE(ConnectChannel());
[email protected]64860882014-08-04 23:44:171344
amistry20e2b1d62016-06-23 06:12:351345 base::ScopedTempDir temp_dir;
1346 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
vabr16e5f602016-09-15 18:14:001347 base::File file(HandleSendingHelper::GetSendingFilePath(temp_dir.GetPath()),
[email protected]64860882014-08-04 23:44:171348 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
morrita81b17e02015-02-06 00:58:301349 base::File::FLAG_READ);
1350 HandleSendingHelper::WriteFileThenSend(channel(), file);
fdoray8e32586852016-06-22 19:56:161351 base::RunLoop().Run();
[email protected]64860882014-08-04 23:44:171352
sammc57ed9f982016-03-10 06:28:351353 channel()->Close();
[email protected]64860882014-08-04 23:44:171354
1355 EXPECT_TRUE(WaitForClientShutdown());
1356 DestroyChannel();
1357}
1358
sammc4bcc4ed62016-10-27 10:13:591359DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
1360 IPCChannelMojoTestSendPlatformHandleClient) {
[email protected]64860882014-08-04 23:44:171361 ListenerThatExpectsFile listener;
sammc57ed9f982016-03-10 06:28:351362 Connect(&listener);
1363 listener.set_sender(channel());
[email protected]64860882014-08-04 23:44:171364
fdoray8e32586852016-06-22 19:56:161365 base::RunLoop().Run();
[email protected]64860882014-08-04 23:44:171366
sammc57ed9f982016-03-10 06:28:351367 Close();
[email protected]64860882014-08-04 23:44:171368}
morrita81b17e02015-02-06 00:58:301369
1370class ListenerThatExpectsFileAndPipe : public IPC::Listener {
1371 public:
1372 ListenerThatExpectsFileAndPipe() : sender_(NULL) {}
1373
1374 ~ListenerThatExpectsFileAndPipe() override {}
1375
1376 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:251377 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:301378 HandleSendingHelper::ReadReceivedFile(message, &iter);
1379 HandleSendingHelper::ReadReceivedPipe(message, &iter);
morrita81b17e02015-02-06 00:58:301380 ListenerThatExpectsOK::SendOK(sender_);
1381 return true;
1382 }
1383
amistry6c70caea2016-06-09 03:08:291384 void OnChannelError() override {
1385 base::MessageLoop::current()->QuitWhenIdle();
1386 }
morrita81b17e02015-02-06 00:58:301387
1388 void set_sender(IPC::Sender* sender) { sender_ = sender; }
1389
1390 private:
1391 IPC::Sender* sender_;
1392};
1393
amistry0027a0952016-05-03 00:52:471394TEST_F(IPCChannelMojoTest, SendPlatformHandleAndPipe) {
sammc4bcc4ed62016-10-27 10:13:591395 Init("IPCChannelMojoTestSendPlatformHandleAndPipeClient");
morrita81b17e02015-02-06 00:58:301396
1397 ListenerThatExpectsOK listener;
1398 CreateChannel(&listener);
1399 ASSERT_TRUE(ConnectChannel());
morrita81b17e02015-02-06 00:58:301400
amistry20e2b1d62016-06-23 06:12:351401 base::ScopedTempDir temp_dir;
1402 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
vabr16e5f602016-09-15 18:14:001403 base::File file(HandleSendingHelper::GetSendingFilePath(temp_dir.GetPath()),
morrita81b17e02015-02-06 00:58:301404 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
1405 base::File::FLAG_READ);
1406 TestingMessagePipe pipe;
1407 HandleSendingHelper::WriteFileAndPipeThenSend(channel(), file, &pipe);
1408
fdoray8e32586852016-06-22 19:56:161409 base::RunLoop().Run();
sammc57ed9f982016-03-10 06:28:351410 channel()->Close();
morrita81b17e02015-02-06 00:58:301411
1412 EXPECT_TRUE(WaitForClientShutdown());
1413 DestroyChannel();
1414}
1415
sammc57ed9f982016-03-10 06:28:351416DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
sammc4bcc4ed62016-10-27 10:13:591417 IPCChannelMojoTestSendPlatformHandleAndPipeClient) {
morrita81b17e02015-02-06 00:58:301418 ListenerThatExpectsFileAndPipe listener;
sammc57ed9f982016-03-10 06:28:351419 Connect(&listener);
1420 listener.set_sender(channel());
morrita81b17e02015-02-06 00:58:301421
fdoray8e32586852016-06-22 19:56:161422 base::RunLoop().Run();
morrita81b17e02015-02-06 00:58:301423
sammc57ed9f982016-03-10 06:28:351424 Close();
morrita81b17e02015-02-06 00:58:301425}
1426
rockot7c6bf952016-07-14 00:34:111427#endif // defined(OS_POSIX)
[email protected]64860882014-08-04 23:44:171428
morrita0bd20bd2015-02-25 20:11:271429#if defined(OS_LINUX)
1430
1431const base::ProcessId kMagicChildId = 54321;
1432
1433class ListenerThatVerifiesPeerPid : public IPC::Listener {
1434 public:
tfarina10a5c062015-09-04 18:47:571435 void OnChannelConnected(int32_t peer_pid) override {
morrita0bd20bd2015-02-25 20:11:271436 EXPECT_EQ(peer_pid, kMagicChildId);
ki.stfua21ed8c2015-10-12 17:26:001437 base::MessageLoop::current()->QuitWhenIdle();
morrita0bd20bd2015-02-25 20:11:271438 }
1439
1440 bool OnMessageReceived(const IPC::Message& message) override {
1441 NOTREACHED();
1442 return true;
1443 }
1444};
1445
sammc57ed9f982016-03-10 06:28:351446TEST_F(IPCChannelMojoTest, VerifyGlobalPid) {
sammc4bcc4ed62016-10-27 10:13:591447 Init("IPCChannelMojoTestVerifyGlobalPidClient");
morrita0bd20bd2015-02-25 20:11:271448
1449 ListenerThatVerifiesPeerPid listener;
1450 CreateChannel(&listener);
1451 ASSERT_TRUE(ConnectChannel());
morrita0bd20bd2015-02-25 20:11:271452
fdoray6ef45cf2016-08-25 15:36:371453 base::RunLoop().Run();
rockotcbca72f2015-03-03 16:31:041454 channel()->Close();
morrita0bd20bd2015-02-25 20:11:271455
1456 EXPECT_TRUE(WaitForClientShutdown());
1457 DestroyChannel();
1458}
1459
sammc4bcc4ed62016-10-27 10:13:591460DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestVerifyGlobalPidClient) {
morrita0bd20bd2015-02-25 20:11:271461 IPC::Channel::SetGlobalPid(kMagicChildId);
1462 ListenerThatQuits listener;
sammc57ed9f982016-03-10 06:28:351463 Connect(&listener);
morrita0bd20bd2015-02-25 20:11:271464
fdoray6ef45cf2016-08-25 15:36:371465 base::RunLoop().Run();
morrita0bd20bd2015-02-25 20:11:271466
sammc57ed9f982016-03-10 06:28:351467 Close();
morrita0bd20bd2015-02-25 20:11:271468}
1469
sammc57ed9f982016-03-10 06:28:351470#endif // OS_LINUX
morrita0bd20bd2015-02-25 20:11:271471
[email protected]64860882014-08-04 23:44:171472} // namespace