blob: 5493ac11ec829f951dadc05c5a1cd106b6156f0a [file] [log] [blame]
[email protected]64860882014-08-04 23:44:171// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
amistryd4aa70d2016-06-23 07:52:375#include "ipc/ipc_channel_mojo.h"
[email protected]64860882014-08-04 23:44:176
avi246998d82015-12-22 02:39:047#include <stddef.h>
tfarina10a5c062015-09-04 18:47:578#include <stdint.h>
rockot7c6bf952016-07-14 00:34:119
danakj03de39b22016-04-23 04:21:0910#include <memory>
dchenge48600452015-12-28 02:24:5011#include <utility>
tfarina10a5c062015-09-04 18:47:5712
[email protected]64860882014-08-04 23:44:1713#include "base/base_paths.h"
rockot8d890f62016-07-14 16:37:1414#include "base/bind.h"
[email protected]64860882014-08-04 23:44:1715#include "base/files/file.h"
amistry20e2b1d62016-06-23 06:12:3516#include "base/files/scoped_temp_dir.h"
skyostile687bdff2015-05-12 11:29:2117#include "base/location.h"
rockot8d890f62016-07-14 16:37:1418#include "base/macros.h"
19#include "base/message_loop/message_loop.h"
[email protected]64860882014-08-04 23:44:1720#include "base/path_service.h"
21#include "base/pickle.h"
rockotcbca72f2015-03-03 16:31:0422#include "base/run_loop.h"
skyostile687bdff2015-05-12 11:29:2123#include "base/single_thread_task_runner.h"
rockot7c6bf952016-07-14 00:34:1124#include "base/strings/stringprintf.h"
rockot9abe09b2016-08-02 20:57:3425#include "base/synchronization/waitable_event.h"
sammc57ed9f982016-03-10 06:28:3526#include "base/test/test_io_thread.h"
morrita0bd20bd2015-02-25 20:11:2727#include "base/test/test_timeouts.h"
[email protected]64860882014-08-04 23:44:1728#include "base/threading/thread.h"
gabf08ccc02016-05-11 18:51:1129#include "base/threading/thread_task_runner_handle.h"
avi246998d82015-12-22 02:39:0430#include "build/build_config.h"
[email protected]64860882014-08-04 23:44:1731#include "ipc/ipc_message.h"
amistryd4aa70d2016-06-23 07:52:3732#include "ipc/ipc_mojo_handle_attachment.h"
33#include "ipc/ipc_mojo_message_helper.h"
34#include "ipc/ipc_mojo_param_traits.h"
rockot9abe09b2016-08-02 20:57:3435#include "ipc/ipc_sync_channel.h"
36#include "ipc/ipc_sync_message.h"
rockot7c6bf952016-07-14 00:34:1137#include "ipc/ipc_test.mojom.h"
[email protected]64860882014-08-04 23:44:1738#include "ipc/ipc_test_base.h"
39#include "ipc/ipc_test_channel_listener.h"
sammc57ed9f982016-03-10 06:28:3540#include "mojo/edk/test/mojo_test_base.h"
41#include "mojo/edk/test/multiprocess_test_helper.h"
42#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
sammcb0a39f82016-08-10 06:29:5449#define DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(client_name, test_base) \
50 class client_name##_MainFixture : public test_base { \
51 public: \
52 void Main(); \
53 }; \
54 MULTIPROCESS_TEST_MAIN_WITH_SETUP( \
55 client_name##TestChildMain, \
56 ::mojo::edk::test::MultiprocessTestHelper::ChildSetup) { \
57 client_name##_MainFixture test; \
58 test.Init( \
59 std::move(mojo::edk::test::MultiprocessTestHelper::primordial_pipe)); \
60 test.Main(); \
61 return (::testing::Test::HasFatalFailure() || \
62 ::testing::Test::HasNonfatalFailure()) \
63 ? 1 \
64 : 0; \
65 } \
sammc57ed9f982016-03-10 06:28:3566 void client_name##_MainFixture::Main()
67
[email protected]64860882014-08-04 23:44:1768namespace {
69
rockot7c6bf952016-07-14 00:34:1170void SendString(IPC::Sender* sender, const std::string& str) {
71 IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
72 message->WriteString(str);
73 ASSERT_TRUE(sender->Send(message));
74}
75
rockot9abe09b2016-08-02 20:57:3476void SendValue(IPC::Sender* sender, int32_t value) {
77 IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
78 message->WriteInt(value);
79 ASSERT_TRUE(sender->Send(message));
80}
81
[email protected]64860882014-08-04 23:44:1782class ListenerThatExpectsOK : public IPC::Listener {
83 public:
sammc57ed9f982016-03-10 06:28:3584 ListenerThatExpectsOK() : received_ok_(false) {}
[email protected]64860882014-08-04 23:44:1785
dchengfe61fca2014-10-22 02:29:5286 ~ListenerThatExpectsOK() override {}
[email protected]64860882014-08-04 23:44:1787
dchengfe61fca2014-10-22 02:29:5288 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:2589 base::PickleIterator iter(message);
[email protected]64860882014-08-04 23:44:1790 std::string should_be_ok;
91 EXPECT_TRUE(iter.ReadString(&should_be_ok));
92 EXPECT_EQ(should_be_ok, "OK");
[email protected]e5c27752014-08-08 21:45:1393 received_ok_ = true;
ki.stfua21ed8c2015-10-12 17:26:0094 base::MessageLoop::current()->QuitWhenIdle();
[email protected]64860882014-08-04 23:44:1795 return true;
96 }
97
dchengfe61fca2014-10-22 02:29:5298 void OnChannelError() override {
[email protected]e5c27752014-08-08 21:45:1399 // The connection should be healthy while the listener is waiting
100 // message. An error can occur after that because the peer
101 // process dies.
102 DCHECK(received_ok_);
[email protected]64860882014-08-04 23:44:17103 }
104
rockot7c6bf952016-07-14 00:34:11105 static void SendOK(IPC::Sender* sender) { SendString(sender, "OK"); }
[email protected]e5c27752014-08-08 21:45:13106
107 private:
108 bool received_ok_;
[email protected]64860882014-08-04 23:44:17109};
110
[email protected]64860882014-08-04 23:44:17111class ChannelClient {
112 public:
sammc57ed9f982016-03-10 06:28:35113 void Init(mojo::ScopedMessagePipeHandle handle) {
114 handle_ = std::move(handle);
tsergeant896012862016-03-10 03:51:33115 }
rockot8d890f62016-07-14 16:37:14116
sammc57ed9f982016-03-10 06:28:35117 void Connect(IPC::Listener* listener) {
rockota34707ca2016-07-20 04:28:32118 channel_ = IPC::ChannelMojo::Create(
119 std::move(handle_), IPC::Channel::MODE_CLIENT, listener,
120 base::ThreadTaskRunnerHandle::Get());
[email protected]64860882014-08-04 23:44:17121 CHECK(channel_->Connect());
122 }
123
rockotcbca72f2015-03-03 16:31:04124 void Close() {
125 channel_->Close();
126
127 base::RunLoop run_loop;
skyostile687bdff2015-05-12 11:29:21128 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
129 run_loop.QuitClosure());
rockotcbca72f2015-03-03 16:31:04130 run_loop.Run();
131 }
132
[email protected]64860882014-08-04 23:44:17133 IPC::ChannelMojo* channel() const { return channel_.get(); }
134
135 private:
[email protected]64860882014-08-04 23:44:17136 base::MessageLoopForIO main_message_loop_;
sammc57ed9f982016-03-10 06:28:35137 mojo::ScopedMessagePipeHandle handle_;
danakj03de39b22016-04-23 04:21:09138 std::unique_ptr<IPC::ChannelMojo> channel_;
[email protected]64860882014-08-04 23:44:17139};
140
rockot8d890f62016-07-14 16:37:14141class IPCChannelMojoTestBase : public testing::Test {
rockotcbca72f2015-03-03 16:31:04142 public:
143 void InitWithMojo(const std::string& test_client_name) {
sammc57ed9f982016-03-10 06:28:35144 handle_ = helper_.StartChild(test_client_name);
rockotcbca72f2015-03-03 16:31:04145 }
146
rockot8d890f62016-07-14 16:37:14147 bool WaitForClientShutdown() { return helper_.WaitForChildTestShutdown(); }
148
149 protected:
150 mojo::ScopedMessagePipeHandle TakeHandle() { return std::move(handle_); }
151
152 private:
153 mojo::ScopedMessagePipeHandle handle_;
154 mojo::edk::test::MultiprocessTestHelper helper_;
155};
156
157class IPCChannelMojoTest : public IPCChannelMojoTestBase {
158 public:
159 void TearDown() override { base::RunLoop().RunUntilIdle(); }
160
sammc57ed9f982016-03-10 06:28:35161 void CreateChannel(IPC::Listener* listener) {
rockot8d890f62016-07-14 16:37:14162 channel_ = IPC::ChannelMojo::Create(
rockota34707ca2016-07-20 04:28:32163 TakeHandle(), IPC::Channel::MODE_SERVER, listener,
164 base::ThreadTaskRunnerHandle::Get());
rockotcbca72f2015-03-03 16:31:04165 }
sammc57ed9f982016-03-10 06:28:35166
167 bool ConnectChannel() { return channel_->Connect(); }
168
169 void DestroyChannel() { channel_.reset(); }
170
sammc57ed9f982016-03-10 06:28:35171 IPC::Sender* sender() { return channel(); }
172 IPC::Channel* channel() { return channel_.get(); }
173
174 private:
175 base::MessageLoop message_loop_;
danakj03de39b22016-04-23 04:21:09176 std::unique_ptr<IPC::Channel> channel_;
rockotcbca72f2015-03-03 16:31:04177};
178
[email protected]64860882014-08-04 23:44:17179class TestChannelListenerWithExtraExpectations
180 : public IPC::TestChannelListener {
181 public:
sammc57ed9f982016-03-10 06:28:35182 TestChannelListenerWithExtraExpectations() : is_connected_called_(false) {}
[email protected]64860882014-08-04 23:44:17183
tfarina10a5c062015-09-04 18:47:57184 void OnChannelConnected(int32_t peer_pid) override {
[email protected]64860882014-08-04 23:44:17185 IPC::TestChannelListener::OnChannelConnected(peer_pid);
186 EXPECT_TRUE(base::kNullProcessId != peer_pid);
187 is_connected_called_ = true;
188 }
189
190 bool is_connected_called() const { return is_connected_called_; }
191
192 private:
193 bool is_connected_called_;
194};
195
amistry0027a0952016-05-03 00:52:47196TEST_F(IPCChannelMojoTest, ConnectedFromClient) {
rockotcbca72f2015-03-03 16:31:04197 InitWithMojo("IPCChannelMojoTestClient");
[email protected]64860882014-08-04 23:44:17198
199 // Set up IPC channel and start client.
200 TestChannelListenerWithExtraExpectations listener;
morrita373af03b2014-09-09 19:35:24201 CreateChannel(&listener);
[email protected]64860882014-08-04 23:44:17202 listener.Init(sender());
203 ASSERT_TRUE(ConnectChannel());
[email protected]64860882014-08-04 23:44:17204
sammc57ed9f982016-03-10 06:28:35205 IPC::TestChannelListener::SendOneMessage(sender(), "hello from parent");
[email protected]64860882014-08-04 23:44:17206
fdoray8e32586852016-06-22 19:56:16207 base::RunLoop().Run();
[email protected]64860882014-08-04 23:44:17208
sammc57ed9f982016-03-10 06:28:35209 channel()->Close();
[email protected]64860882014-08-04 23:44:17210
211 EXPECT_TRUE(WaitForClientShutdown());
212 EXPECT_TRUE(listener.is_connected_called());
213 EXPECT_TRUE(listener.HasSentAll());
214
215 DestroyChannel();
216}
217
218// A long running process that connects to us
sammc57ed9f982016-03-10 06:28:35219DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestClient, ChannelClient) {
[email protected]64860882014-08-04 23:44:17220 TestChannelListenerWithExtraExpectations listener;
sammc57ed9f982016-03-10 06:28:35221 Connect(&listener);
222 listener.Init(channel());
[email protected]64860882014-08-04 23:44:17223
sammc57ed9f982016-03-10 06:28:35224 IPC::TestChannelListener::SendOneMessage(channel(), "hello from child");
fdoray8e32586852016-06-22 19:56:16225 base::RunLoop().Run();
[email protected]64860882014-08-04 23:44:17226 EXPECT_TRUE(listener.is_connected_called());
227 EXPECT_TRUE(listener.HasSentAll());
228
sammc57ed9f982016-03-10 06:28:35229 Close();
[email protected]64860882014-08-04 23:44:17230}
231
morrita0a24cfc92014-09-16 03:20:48232class ListenerExpectingErrors : public IPC::Listener {
233 public:
sammc57ed9f982016-03-10 06:28:35234 ListenerExpectingErrors() : has_error_(false) {}
morrita0a24cfc92014-09-16 03:20:48235
dchengfe61fca2014-10-22 02:29:52236 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita0a24cfc92014-09-16 03:20:48237
dchengfe61fca2014-10-22 02:29:52238 void OnChannelError() override {
morrita0a24cfc92014-09-16 03:20:48239 has_error_ = true;
ki.stfua21ed8c2015-10-12 17:26:00240 base::MessageLoop::current()->QuitWhenIdle();
morrita0a24cfc92014-09-16 03:20:48241 }
242
243 bool has_error() const { return has_error_; }
244
245 private:
246 bool has_error_;
247};
248
morrita0a24cfc92014-09-16 03:20:48249class ListenerThatQuits : public IPC::Listener {
250 public:
sammc57ed9f982016-03-10 06:28:35251 ListenerThatQuits() {}
morrita0a24cfc92014-09-16 03:20:48252
sammc57ed9f982016-03-10 06:28:35253 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita0a24cfc92014-09-16 03:20:48254
tfarina10a5c062015-09-04 18:47:57255 void OnChannelConnected(int32_t peer_pid) override {
ki.stfua21ed8c2015-10-12 17:26:00256 base::MessageLoop::current()->QuitWhenIdle();
morrita0a24cfc92014-09-16 03:20:48257 }
258};
259
260// A long running process that connects to us.
sammc57ed9f982016-03-10 06:28:35261DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoErraticTestClient,
262 ChannelClient) {
morrita0a24cfc92014-09-16 03:20:48263 ListenerThatQuits listener;
sammc57ed9f982016-03-10 06:28:35264 Connect(&listener);
morrita0a24cfc92014-09-16 03:20:48265
fdoray8e32586852016-06-22 19:56:16266 base::RunLoop().Run();
morrita0a24cfc92014-09-16 03:20:48267
sammc57ed9f982016-03-10 06:28:35268 Close();
morrita0a24cfc92014-09-16 03:20:48269}
270
rockot8c23d462016-07-25 17:33:04271TEST_F(IPCChannelMojoTest, SendFailWithPendingMessages) {
rockotcbca72f2015-03-03 16:31:04272 InitWithMojo("IPCChannelMojoErraticTestClient");
morrita0a24cfc92014-09-16 03:20:48273
274 // Set up IPC channel and start client.
275 ListenerExpectingErrors listener;
276 CreateChannel(&listener);
277 ASSERT_TRUE(ConnectChannel());
278
jamesra03ae492014-10-03 04:26:48279 // This matches a value in mojo/edk/system/constants.h
morritabe6c4cc2014-09-24 23:38:44280 const int kMaxMessageNumBytes = 4 * 1024 * 1024;
281 std::string overly_large_data(kMaxMessageNumBytes, '*');
morrita0a24cfc92014-09-16 03:20:48282 // This messages are queued as pending.
morritabe6c4cc2014-09-24 23:38:44283 for (size_t i = 0; i < 10; ++i) {
sammc57ed9f982016-03-10 06:28:35284 IPC::TestChannelListener::SendOneMessage(sender(),
285 overly_large_data.c_str());
morrita0a24cfc92014-09-16 03:20:48286 }
287
fdoray8e32586852016-06-22 19:56:16288 base::RunLoop().Run();
morrita0a24cfc92014-09-16 03:20:48289
sammc57ed9f982016-03-10 06:28:35290 channel()->Close();
morrita0a24cfc92014-09-16 03:20:48291
292 EXPECT_TRUE(WaitForClientShutdown());
293 EXPECT_TRUE(listener.has_error());
294
295 DestroyChannel();
296}
297
morrita81b17e02015-02-06 00:58:30298struct TestingMessagePipe {
299 TestingMessagePipe() {
300 EXPECT_EQ(MOJO_RESULT_OK, mojo::CreateMessagePipe(nullptr, &self, &peer));
301 }
302
303 mojo::ScopedMessagePipeHandle self;
304 mojo::ScopedMessagePipeHandle peer;
305};
306
307class HandleSendingHelper {
308 public:
309 static std::string GetSendingFileContent() { return "Hello"; }
310
311 static void WritePipe(IPC::Message* message, TestingMessagePipe* pipe) {
312 std::string content = HandleSendingHelper::GetSendingFileContent();
313 EXPECT_EQ(MOJO_RESULT_OK,
314 mojo::WriteMessageRaw(pipe->self.get(), &content[0],
315 static_cast<uint32_t>(content.size()),
316 nullptr, 0, 0));
dchenge48600452015-12-28 02:24:50317 EXPECT_TRUE(IPC::MojoMessageHelper::WriteMessagePipeTo(
318 message, std::move(pipe->peer)));
morrita81b17e02015-02-06 00:58:30319 }
320
321 static void WritePipeThenSend(IPC::Sender* sender, TestingMessagePipe* pipe) {
322 IPC::Message* message =
323 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
324 WritePipe(message, pipe);
325 ASSERT_TRUE(sender->Send(message));
326 }
327
328 static void ReadReceivedPipe(const IPC::Message& message,
brettwbd4d7112015-06-03 04:29:25329 base::PickleIterator* iter) {
morrita81b17e02015-02-06 00:58:30330 mojo::ScopedMessagePipeHandle pipe;
331 EXPECT_TRUE(
332 IPC::MojoMessageHelper::ReadMessagePipeFrom(&message, iter, &pipe));
333 std::string content(GetSendingFileContent().size(), ' ');
334
335 uint32_t num_bytes = static_cast<uint32_t>(content.size());
sammc57ed9f982016-03-10 06:28:35336 ASSERT_EQ(MOJO_RESULT_OK,
337 mojo::Wait(pipe.get(), MOJO_HANDLE_SIGNAL_READABLE,
338 MOJO_DEADLINE_INDEFINITE, nullptr));
morrita81b17e02015-02-06 00:58:30339 EXPECT_EQ(MOJO_RESULT_OK,
340 mojo::ReadMessageRaw(pipe.get(), &content[0], &num_bytes, nullptr,
341 nullptr, 0));
342 EXPECT_EQ(content, GetSendingFileContent());
343 }
344
345#if defined(OS_POSIX)
amistry20e2b1d62016-06-23 06:12:35346 static base::FilePath GetSendingFilePath(const base::FilePath& dir_path) {
347 return dir_path.Append("ListenerThatExpectsFile.txt");
morrita81b17e02015-02-06 00:58:30348 }
349
350 static void WriteFile(IPC::Message* message, base::File& file) {
351 std::string content = GetSendingFileContent();
352 file.WriteAtCurrentPos(content.data(), content.size());
353 file.Flush();
354 message->WriteAttachment(new IPC::internal::PlatformFileAttachment(
355 base::ScopedFD(file.TakePlatformFile())));
356 }
357
358 static void WriteFileThenSend(IPC::Sender* sender, base::File& file) {
359 IPC::Message* message =
360 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
361 WriteFile(message, file);
362 ASSERT_TRUE(sender->Send(message));
363 }
364
365 static void WriteFileAndPipeThenSend(IPC::Sender* sender,
366 base::File& file,
367 TestingMessagePipe* pipe) {
368 IPC::Message* message =
369 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
370 WriteFile(message, file);
371 WritePipe(message, pipe);
372 ASSERT_TRUE(sender->Send(message));
373 }
374
375 static void ReadReceivedFile(const IPC::Message& message,
brettwbd4d7112015-06-03 04:29:25376 base::PickleIterator* iter) {
morrita81b17e02015-02-06 00:58:30377 base::ScopedFD fd;
rockot502c94f2016-02-03 20:20:16378 scoped_refptr<base::Pickle::Attachment> attachment;
morrita81b17e02015-02-06 00:58:30379 EXPECT_TRUE(message.ReadAttachment(iter, &attachment));
amistry980a61b2016-06-09 02:51:20380 EXPECT_EQ(IPC::MessageAttachment::TYPE_PLATFORM_FILE,
381 static_cast<IPC::MessageAttachment*>(attachment.get())
382 ->GetType());
rockot502c94f2016-02-03 20:20:16383 base::File file(static_cast<IPC::MessageAttachment*>(attachment.get())
384 ->TakePlatformFile());
morrita81b17e02015-02-06 00:58:30385 std::string content(GetSendingFileContent().size(), ' ');
386 file.Read(0, &content[0], content.size());
387 EXPECT_EQ(content, GetSendingFileContent());
388 }
389#endif
390};
391
392class ListenerThatExpectsMessagePipe : public IPC::Listener {
393 public:
394 ListenerThatExpectsMessagePipe() : sender_(NULL) {}
395
396 ~ListenerThatExpectsMessagePipe() override {}
397
398 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25399 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:30400 HandleSendingHelper::ReadReceivedPipe(message, &iter);
morrita81b17e02015-02-06 00:58:30401 ListenerThatExpectsOK::SendOK(sender_);
402 return true;
403 }
404
amistry6c70caea2016-06-09 03:08:29405 void OnChannelError() override {
406 base::MessageLoop::current()->QuitWhenIdle();
407 }
morrita81b17e02015-02-06 00:58:30408
409 void set_sender(IPC::Sender* sender) { sender_ = sender; }
410
411 private:
412 IPC::Sender* sender_;
413};
414
amistry0027a0952016-05-03 00:52:47415TEST_F(IPCChannelMojoTest, SendMessagePipe) {
rockotcbca72f2015-03-03 16:31:04416 InitWithMojo("IPCChannelMojoTestSendMessagePipeClient");
morrita81b17e02015-02-06 00:58:30417
418 ListenerThatExpectsOK listener;
419 CreateChannel(&listener);
420 ASSERT_TRUE(ConnectChannel());
morrita81b17e02015-02-06 00:58:30421
422 TestingMessagePipe pipe;
423 HandleSendingHelper::WritePipeThenSend(channel(), &pipe);
424
fdoray8e32586852016-06-22 19:56:16425 base::RunLoop().Run();
sammc57ed9f982016-03-10 06:28:35426 channel()->Close();
morrita81b17e02015-02-06 00:58:30427
428 EXPECT_TRUE(WaitForClientShutdown());
429 DestroyChannel();
430}
431
sammc57ed9f982016-03-10 06:28:35432DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendMessagePipeClient,
433 ChannelClient) {
morrita81b17e02015-02-06 00:58:30434 ListenerThatExpectsMessagePipe listener;
sammc57ed9f982016-03-10 06:28:35435 Connect(&listener);
436 listener.set_sender(channel());
morrita81b17e02015-02-06 00:58:30437
fdoray8e32586852016-06-22 19:56:16438 base::RunLoop().Run();
morrita81b17e02015-02-06 00:58:30439
sammc57ed9f982016-03-10 06:28:35440 Close();
morrita81b17e02015-02-06 00:58:30441}
442
morrita438a2ee2015-04-03 05:28:21443void ReadOK(mojo::MessagePipeHandle pipe) {
444 std::string should_be_ok("xx");
445 uint32_t num_bytes = static_cast<uint32_t>(should_be_ok.size());
sammc57ed9f982016-03-10 06:28:35446 CHECK_EQ(MOJO_RESULT_OK, mojo::Wait(pipe, MOJO_HANDLE_SIGNAL_READABLE,
447 MOJO_DEADLINE_INDEFINITE, nullptr));
morrita438a2ee2015-04-03 05:28:21448 CHECK_EQ(MOJO_RESULT_OK,
449 mojo::ReadMessageRaw(pipe, &should_be_ok[0], &num_bytes, nullptr,
450 nullptr, 0));
451 EXPECT_EQ(should_be_ok, std::string("OK"));
452}
453
454void WriteOK(mojo::MessagePipeHandle pipe) {
455 std::string ok("OK");
456 CHECK_EQ(MOJO_RESULT_OK,
457 mojo::WriteMessageRaw(pipe, &ok[0], static_cast<uint32_t>(ok.size()),
458 nullptr, 0, 0));
459}
460
461class ListenerThatExpectsMessagePipeUsingParamTrait : public IPC::Listener {
462 public:
463 explicit ListenerThatExpectsMessagePipeUsingParamTrait(bool receiving_valid)
464 : sender_(NULL), receiving_valid_(receiving_valid) {}
465
466 ~ListenerThatExpectsMessagePipeUsingParamTrait() override {}
467
468 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25469 base::PickleIterator iter(message);
morrita438a2ee2015-04-03 05:28:21470 mojo::MessagePipeHandle handle;
471 EXPECT_TRUE(IPC::ParamTraits<mojo::MessagePipeHandle>::Read(&message, &iter,
472 &handle));
473 EXPECT_EQ(handle.is_valid(), receiving_valid_);
474 if (receiving_valid_) {
475 ReadOK(handle);
476 MojoClose(handle.value());
477 }
478
morrita438a2ee2015-04-03 05:28:21479 ListenerThatExpectsOK::SendOK(sender_);
480 return true;
481 }
482
amistry6c70caea2016-06-09 03:08:29483 void OnChannelError() override {
484 base::MessageLoop::current()->QuitWhenIdle();
485 }
486
morrita438a2ee2015-04-03 05:28:21487 void set_sender(IPC::Sender* sender) { sender_ = sender; }
488
489 private:
490 IPC::Sender* sender_;
491 bool receiving_valid_;
492};
493
sammc57ed9f982016-03-10 06:28:35494class ParamTraitMessagePipeClient : public ChannelClient {
495 public:
496 void RunTest(bool receiving_valid_handle) {
497 ListenerThatExpectsMessagePipeUsingParamTrait listener(
498 receiving_valid_handle);
499 Connect(&listener);
500 listener.set_sender(channel());
morrita438a2ee2015-04-03 05:28:21501
fdoray8e32586852016-06-22 19:56:16502 base::RunLoop().Run();
morrita438a2ee2015-04-03 05:28:21503
sammc57ed9f982016-03-10 06:28:35504 Close();
505 }
506};
morrita438a2ee2015-04-03 05:28:21507
amistry0027a0952016-05-03 00:52:47508TEST_F(IPCChannelMojoTest, ParamTraitValidMessagePipe) {
morrita438a2ee2015-04-03 05:28:21509 InitWithMojo("ParamTraitValidMessagePipeClient");
510
511 ListenerThatExpectsOK listener;
512 CreateChannel(&listener);
513 ASSERT_TRUE(ConnectChannel());
morrita438a2ee2015-04-03 05:28:21514
515 TestingMessagePipe pipe;
516
danakj03de39b22016-04-23 04:21:09517 std::unique_ptr<IPC::Message> message(new IPC::Message());
morrita438a2ee2015-04-03 05:28:21518 IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
519 pipe.peer.release());
520 WriteOK(pipe.self.get());
521
sammc57ed9f982016-03-10 06:28:35522 channel()->Send(message.release());
fdoray8e32586852016-06-22 19:56:16523 base::RunLoop().Run();
sammc57ed9f982016-03-10 06:28:35524 channel()->Close();
morrita438a2ee2015-04-03 05:28:21525
526 EXPECT_TRUE(WaitForClientShutdown());
527 DestroyChannel();
528}
529
sammc57ed9f982016-03-10 06:28:35530DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(ParamTraitValidMessagePipeClient,
531 ParamTraitMessagePipeClient) {
532 RunTest(true);
morrita438a2ee2015-04-03 05:28:21533}
534
amistry0027a0952016-05-03 00:52:47535TEST_F(IPCChannelMojoTest, ParamTraitInvalidMessagePipe) {
morrita438a2ee2015-04-03 05:28:21536 InitWithMojo("ParamTraitInvalidMessagePipeClient");
537
538 ListenerThatExpectsOK listener;
539 CreateChannel(&listener);
540 ASSERT_TRUE(ConnectChannel());
morrita438a2ee2015-04-03 05:28:21541
542 mojo::MessagePipeHandle invalid_handle;
danakj03de39b22016-04-23 04:21:09543 std::unique_ptr<IPC::Message> message(new IPC::Message());
morrita438a2ee2015-04-03 05:28:21544 IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
545 invalid_handle);
546
sammc57ed9f982016-03-10 06:28:35547 channel()->Send(message.release());
fdoray8e32586852016-06-22 19:56:16548 base::RunLoop().Run();
sammc57ed9f982016-03-10 06:28:35549 channel()->Close();
morrita438a2ee2015-04-03 05:28:21550
551 EXPECT_TRUE(WaitForClientShutdown());
552 DestroyChannel();
553}
554
sammc57ed9f982016-03-10 06:28:35555DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(ParamTraitInvalidMessagePipeClient,
556 ParamTraitMessagePipeClient) {
557 RunTest(false);
morrita438a2ee2015-04-03 05:28:21558}
559
amistry0027a0952016-05-03 00:52:47560TEST_F(IPCChannelMojoTest, SendFailAfterClose) {
morrita17137e62015-06-23 22:29:36561 InitWithMojo("IPCChannelMojoTestSendOkClient");
562
563 ListenerThatExpectsOK listener;
564 CreateChannel(&listener);
565 ASSERT_TRUE(ConnectChannel());
morrita17137e62015-06-23 22:29:36566
fdoray8e32586852016-06-22 19:56:16567 base::RunLoop().Run();
sammc57ed9f982016-03-10 06:28:35568 channel()->Close();
569 ASSERT_FALSE(channel()->Send(new IPC::Message()));
morrita17137e62015-06-23 22:29:36570
571 EXPECT_TRUE(WaitForClientShutdown());
572 DestroyChannel();
573}
574
575class ListenerSendingOneOk : public IPC::Listener {
576 public:
sammc57ed9f982016-03-10 06:28:35577 ListenerSendingOneOk() {}
morrita17137e62015-06-23 22:29:36578
sammc57ed9f982016-03-10 06:28:35579 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita17137e62015-06-23 22:29:36580
tfarina10a5c062015-09-04 18:47:57581 void OnChannelConnected(int32_t peer_pid) override {
morrita17137e62015-06-23 22:29:36582 ListenerThatExpectsOK::SendOK(sender_);
ki.stfua21ed8c2015-10-12 17:26:00583 base::MessageLoop::current()->QuitWhenIdle();
morrita17137e62015-06-23 22:29:36584 }
585
586 void set_sender(IPC::Sender* sender) { sender_ = sender; }
587
588 private:
589 IPC::Sender* sender_;
590};
591
sammc57ed9f982016-03-10 06:28:35592DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendOkClient,
593 ChannelClient) {
morrita17137e62015-06-23 22:29:36594 ListenerSendingOneOk listener;
sammc57ed9f982016-03-10 06:28:35595 Connect(&listener);
596 listener.set_sender(channel());
morrita17137e62015-06-23 22:29:36597
fdoray8e32586852016-06-22 19:56:16598 base::RunLoop().Run();
morrita17137e62015-06-23 22:29:36599
sammc57ed9f982016-03-10 06:28:35600 Close();
morrita17137e62015-06-23 22:29:36601}
602
rockot7c6bf952016-07-14 00:34:11603class ListenerWithSimpleAssociatedInterface
604 : public IPC::Listener,
605 public IPC::mojom::SimpleTestDriver {
606 public:
607 static const int kNumMessages;
608
609 ListenerWithSimpleAssociatedInterface() : binding_(this) {}
610
611 ~ListenerWithSimpleAssociatedInterface() override {}
612
613 bool OnMessageReceived(const IPC::Message& message) override {
614 base::PickleIterator iter(message);
rockot9abe09b2016-08-02 20:57:34615 int32_t should_be_expected;
616 EXPECT_TRUE(iter.ReadInt(&should_be_expected));
617 EXPECT_EQ(should_be_expected, next_expected_value_);
rockot7c6bf952016-07-14 00:34:11618 num_messages_received_++;
619 return true;
620 }
621
622 void OnChannelError() override {
623 DCHECK(received_quit_);
624 }
625
626 void RegisterInterfaceFactory(IPC::Channel* channel) {
627 channel->GetAssociatedInterfaceSupport()->AddAssociatedInterface(
628 base::Bind(&ListenerWithSimpleAssociatedInterface::BindRequest,
629 base::Unretained(this)));
630 }
631
632 private:
633 // IPC::mojom::SimpleTestDriver:
rockot9abe09b2016-08-02 20:57:34634 void ExpectValue(int32_t value) override {
635 next_expected_value_ = value;
636 }
637
638 void GetExpectedValue(const GetExpectedValueCallback& callback) override {
639 NOTREACHED();
640 }
641
642 void RequestValue(const RequestValueCallback& callback) override {
643 NOTREACHED();
rockot7c6bf952016-07-14 00:34:11644 }
645
646 void RequestQuit(const RequestQuitCallback& callback) override {
647 EXPECT_EQ(kNumMessages, num_messages_received_);
648 received_quit_ = true;
649 callback.Run();
650 base::MessageLoop::current()->QuitWhenIdle();
651 }
652
653 void BindRequest(IPC::mojom::SimpleTestDriverAssociatedRequest request) {
654 DCHECK(!binding_.is_bound());
655 binding_.Bind(std::move(request));
656 }
657
rockot9abe09b2016-08-02 20:57:34658 int32_t next_expected_value_ = 0;
rockot7c6bf952016-07-14 00:34:11659 int num_messages_received_ = 0;
660 bool received_quit_ = false;
661
662 mojo::AssociatedBinding<IPC::mojom::SimpleTestDriver> binding_;
663};
664
665const int ListenerWithSimpleAssociatedInterface::kNumMessages = 1000;
666
667class ListenerSendingAssociatedMessages : public IPC::Listener {
668 public:
669 ListenerSendingAssociatedMessages() {}
670
671 bool OnMessageReceived(const IPC::Message& message) override { return true; }
672
673 void OnChannelConnected(int32_t peer_pid) override {
674 DCHECK(channel_);
675 channel_->GetAssociatedInterfaceSupport()->GetRemoteAssociatedInterface(
676 &driver_);
677
678 // Send a bunch of interleaved messages, alternating between the associated
679 // interface and a legacy IPC::Message.
680 for (int i = 0; i < ListenerWithSimpleAssociatedInterface::kNumMessages;
681 ++i) {
rockot9abe09b2016-08-02 20:57:34682 driver_->ExpectValue(i);
683 SendValue(channel_, i);
rockot7c6bf952016-07-14 00:34:11684 }
685 driver_->RequestQuit(base::Bind(&OnQuitAck));
686 }
687
688 void set_channel(IPC::Channel* channel) { channel_ = channel; }
689
690 private:
691 static void OnQuitAck() { base::MessageLoop::current()->QuitWhenIdle(); }
692
693 IPC::Channel* channel_ = nullptr;
694 IPC::mojom::SimpleTestDriverAssociatedPtr driver_;
695};
696
697TEST_F(IPCChannelMojoTest, SimpleAssociatedInterface) {
698 InitWithMojo("SimpleAssociatedInterfaceClient");
699
700 ListenerWithSimpleAssociatedInterface listener;
701 CreateChannel(&listener);
702 ASSERT_TRUE(ConnectChannel());
703
704 listener.RegisterInterfaceFactory(channel());
705
706 base::RunLoop().Run();
707 channel()->Close();
708
709 EXPECT_TRUE(WaitForClientShutdown());
710 DestroyChannel();
711}
712
713DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(SimpleAssociatedInterfaceClient,
714 ChannelClient) {
715 ListenerSendingAssociatedMessages listener;
716 Connect(&listener);
717 listener.set_channel(channel());
718
719 base::RunLoop().Run();
720
721 Close();
722}
723
rockot8d890f62016-07-14 16:37:14724class ChannelProxyRunner {
725 public:
rockota34707ca2016-07-20 04:28:32726 ChannelProxyRunner(mojo::ScopedMessagePipeHandle handle,
727 bool for_server)
728 : for_server_(for_server),
729 handle_(std::move(handle)),
rockot9abe09b2016-08-02 20:57:34730 io_thread_("ChannelProxyRunner IO thread"),
731 never_signaled_(base::WaitableEvent::ResetPolicy::MANUAL,
732 base::WaitableEvent::InitialState::NOT_SIGNALED) {
rockot8d890f62016-07-14 16:37:14733 }
734
735 void CreateProxy(IPC::Listener* listener) {
736 io_thread_.StartWithOptions(
737 base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
rockot9abe09b2016-08-02 20:57:34738 proxy_ = IPC::SyncChannel::Create(
739 listener, io_thread_.task_runner(), &never_signaled_);
rockot8d890f62016-07-14 16:37:14740 }
rockota34707ca2016-07-20 04:28:32741
rockot10188752016-09-08 18:24:56742 void RunProxy() {
rockota34707ca2016-07-20 04:28:32743 std::unique_ptr<IPC::ChannelFactory> factory;
744 if (for_server_) {
745 factory = IPC::ChannelMojo::CreateServerFactory(
746 std::move(handle_), io_thread_.task_runner());
747 } else {
748 factory = IPC::ChannelMojo::CreateClientFactory(
749 std::move(handle_), io_thread_.task_runner());
750 }
rockot10188752016-09-08 18:24:56751 proxy_->Init(std::move(factory), true);
rockota34707ca2016-07-20 04:28:32752 }
rockot8d890f62016-07-14 16:37:14753
754 IPC::ChannelProxy* proxy() { return proxy_.get(); }
755
756 private:
rockota34707ca2016-07-20 04:28:32757 const bool for_server_;
rockot8d890f62016-07-14 16:37:14758
rockota34707ca2016-07-20 04:28:32759 mojo::ScopedMessagePipeHandle handle_;
rockot8d890f62016-07-14 16:37:14760 base::Thread io_thread_;
761 std::unique_ptr<IPC::ChannelProxy> proxy_;
rockot9abe09b2016-08-02 20:57:34762 base::WaitableEvent never_signaled_;
rockot8d890f62016-07-14 16:37:14763
764 DISALLOW_COPY_AND_ASSIGN(ChannelProxyRunner);
765};
766
767class IPCChannelProxyMojoTest : public IPCChannelMojoTestBase {
768 public:
769 void InitWithMojo(const std::string& client_name) {
770 IPCChannelMojoTestBase::InitWithMojo(client_name);
rockota34707ca2016-07-20 04:28:32771 runner_.reset(new ChannelProxyRunner(TakeHandle(), true));
rockot8d890f62016-07-14 16:37:14772 }
773 void CreateProxy(IPC::Listener* listener) { runner_->CreateProxy(listener); }
rockot10188752016-09-08 18:24:56774 void RunProxy() {
775 runner_->RunProxy();
rockot401fb2c2016-09-06 18:35:57776 }
rockot0e4de5f2016-07-22 21:18:07777 void DestroyProxy() {
778 runner_.reset();
779 base::RunLoop().RunUntilIdle();
780 }
rockot8d890f62016-07-14 16:37:14781
782 IPC::ChannelProxy* proxy() { return runner_->proxy(); }
783
784 private:
785 base::MessageLoop message_loop_;
786 std::unique_ptr<ChannelProxyRunner> runner_;
787};
788
789class ListenerWithSimpleProxyAssociatedInterface
790 : public IPC::Listener,
791 public IPC::mojom::SimpleTestDriver {
792 public:
793 static const int kNumMessages;
794
795 ListenerWithSimpleProxyAssociatedInterface() : binding_(this) {}
796
797 ~ListenerWithSimpleProxyAssociatedInterface() override {}
798
799 bool OnMessageReceived(const IPC::Message& message) override {
800 base::PickleIterator iter(message);
rockot9abe09b2016-08-02 20:57:34801 int32_t should_be_expected;
802 EXPECT_TRUE(iter.ReadInt(&should_be_expected));
803 EXPECT_EQ(should_be_expected, next_expected_value_);
rockot8d890f62016-07-14 16:37:14804 num_messages_received_++;
805 return true;
806 }
807
808 void OnChannelError() override {
809 DCHECK(received_quit_);
810 }
811
rockotf62002a2016-09-15 00:08:59812 void OnAssociatedInterfaceRequest(
813 const std::string& interface_name,
814 mojo::ScopedInterfaceEndpointHandle handle) override {
815 DCHECK_EQ(interface_name, IPC::mojom::SimpleTestDriver::Name_);
816 IPC::mojom::SimpleTestDriverAssociatedRequest request;
817 request.Bind(std::move(handle));
818 binding_.Bind(std::move(request));
rockot8d890f62016-07-14 16:37:14819 }
820
821 bool received_all_messages() const {
822 return num_messages_received_ == kNumMessages && received_quit_;
823 }
824
825 private:
826 // IPC::mojom::SimpleTestDriver:
rockot9abe09b2016-08-02 20:57:34827 void ExpectValue(int32_t value) override {
828 next_expected_value_ = value;
829 }
830
831 void GetExpectedValue(const GetExpectedValueCallback& callback) override {
832 callback.Run(next_expected_value_);
833 }
834
835 void RequestValue(const RequestValueCallback& callback) override {
836 NOTREACHED();
rockot8d890f62016-07-14 16:37:14837 }
838
839 void RequestQuit(const RequestQuitCallback& callback) override {
840 received_quit_ = true;
841 callback.Run();
rockot0e4de5f2016-07-22 21:18:07842 binding_.Close();
rockot8d890f62016-07-14 16:37:14843 base::MessageLoop::current()->QuitWhenIdle();
844 }
845
846 void BindRequest(IPC::mojom::SimpleTestDriverAssociatedRequest request) {
847 DCHECK(!binding_.is_bound());
848 binding_.Bind(std::move(request));
849 }
850
rockot9abe09b2016-08-02 20:57:34851 int32_t next_expected_value_ = 0;
rockot8d890f62016-07-14 16:37:14852 int num_messages_received_ = 0;
853 bool received_quit_ = false;
854
855 mojo::AssociatedBinding<IPC::mojom::SimpleTestDriver> binding_;
856};
857
858const int ListenerWithSimpleProxyAssociatedInterface::kNumMessages = 1000;
859
860TEST_F(IPCChannelProxyMojoTest, ProxyThreadAssociatedInterface) {
861 InitWithMojo("ProxyThreadAssociatedInterfaceClient");
862
863 ListenerWithSimpleProxyAssociatedInterface listener;
864 CreateProxy(&listener);
rockot8d890f62016-07-14 16:37:14865 RunProxy();
866
867 base::RunLoop().Run();
868
869 EXPECT_TRUE(WaitForClientShutdown());
870 EXPECT_TRUE(listener.received_all_messages());
871
rockot0e4de5f2016-07-22 21:18:07872 DestroyProxy();
rockot8d890f62016-07-14 16:37:14873}
874
875class ChannelProxyClient {
876 public:
877 void Init(mojo::ScopedMessagePipeHandle handle) {
rockota34707ca2016-07-20 04:28:32878 runner_.reset(new ChannelProxyRunner(std::move(handle), false));
rockot8d890f62016-07-14 16:37:14879 }
rockot9abe09b2016-08-02 20:57:34880
rockot8d890f62016-07-14 16:37:14881 void CreateProxy(IPC::Listener* listener) { runner_->CreateProxy(listener); }
rockot9abe09b2016-08-02 20:57:34882
rockot10188752016-09-08 18:24:56883 void RunProxy() { runner_->RunProxy(); }
rockot9abe09b2016-08-02 20:57:34884
rockot0e4de5f2016-07-22 21:18:07885 void DestroyProxy() {
886 runner_.reset();
887 base::RunLoop().RunUntilIdle();
888 }
rockot8d890f62016-07-14 16:37:14889
rockot9abe09b2016-08-02 20:57:34890 void RequestQuitAndWaitForAck(IPC::mojom::SimpleTestDriver* driver) {
891 base::RunLoop loop;
892 driver->RequestQuit(loop.QuitClosure());
893 loop.Run();
894 }
895
rockot8d890f62016-07-14 16:37:14896 IPC::ChannelProxy* proxy() { return runner_->proxy(); }
897
898 private:
899 base::MessageLoop message_loop_;
900 std::unique_ptr<ChannelProxyRunner> runner_;
901};
902
rockot0e4de5f2016-07-22 21:18:07903class DummyListener : public IPC::Listener {
rockot8d890f62016-07-14 16:37:14904 public:
rockot8d890f62016-07-14 16:37:14905 // IPC::Listener
906 bool OnMessageReceived(const IPC::Message& message) override { return true; }
rockot8d890f62016-07-14 16:37:14907};
908
909DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(ProxyThreadAssociatedInterfaceClient,
910 ChannelProxyClient) {
rockot0e4de5f2016-07-22 21:18:07911 DummyListener listener;
rockot8d890f62016-07-14 16:37:14912 CreateProxy(&listener);
913 RunProxy();
rockot8d890f62016-07-14 16:37:14914
915 // Send a bunch of interleaved messages, alternating between the associated
916 // interface and a legacy IPC::Message.
917 IPC::mojom::SimpleTestDriverAssociatedPtr driver;
918 proxy()->GetRemoteAssociatedInterface(&driver);
919 for (int i = 0; i < ListenerWithSimpleProxyAssociatedInterface::kNumMessages;
920 ++i) {
rockot9abe09b2016-08-02 20:57:34921 driver->ExpectValue(i);
922 SendValue(proxy(), i);
rockot8d890f62016-07-14 16:37:14923 }
924 driver->RequestQuit(base::MessageLoop::QuitWhenIdleClosure());
925 base::RunLoop().Run();
rockot0e4de5f2016-07-22 21:18:07926
927 DestroyProxy();
rockot8d890f62016-07-14 16:37:14928}
929
rockot401fb2c2016-09-06 18:35:57930class ListenerWithIndirectProxyAssociatedInterface
931 : public IPC::Listener,
932 public IPC::mojom::IndirectTestDriver,
933 public IPC::mojom::PingReceiver {
934 public:
935 ListenerWithIndirectProxyAssociatedInterface()
936 : driver_binding_(this), ping_receiver_binding_(this) {}
937 ~ListenerWithIndirectProxyAssociatedInterface() override {}
938
939 bool OnMessageReceived(const IPC::Message& message) override { return true; }
940
941 void RegisterInterfaceFactory(IPC::ChannelProxy* proxy) {
942 proxy->AddAssociatedInterface(
943 base::Bind(&ListenerWithIndirectProxyAssociatedInterface::BindRequest,
944 base::Unretained(this)));
945 }
946
947 void set_ping_handler(const base::Closure& handler) {
948 ping_handler_ = handler;
949 }
950
951 private:
952 // IPC::mojom::IndirectTestDriver:
953 void GetPingReceiver(
954 IPC::mojom::PingReceiverAssociatedRequest request) override {
955 ping_receiver_binding_.Bind(std::move(request));
956 }
957
958 // IPC::mojom::PingReceiver:
959 void Ping(const PingCallback& callback) override {
960 callback.Run();
961 ping_handler_.Run();
962 }
963
964 void BindRequest(IPC::mojom::IndirectTestDriverAssociatedRequest request) {
965 DCHECK(!driver_binding_.is_bound());
966 driver_binding_.Bind(std::move(request));
967 }
968
969 mojo::AssociatedBinding<IPC::mojom::IndirectTestDriver> driver_binding_;
970 mojo::AssociatedBinding<IPC::mojom::PingReceiver> ping_receiver_binding_;
971
972 base::Closure ping_handler_;
973};
974
975TEST_F(IPCChannelProxyMojoTest, ProxyThreadAssociatedInterfaceIndirect) {
976 // Tests that we can pipeline interface requests and subsequent messages
977 // targeting proxy thread bindings, and the channel will still dispatch
978 // messages appropriately.
979
980 InitWithMojo("ProxyThreadAssociatedInterfaceIndirectClient");
981
982 ListenerWithIndirectProxyAssociatedInterface listener;
983 CreateProxy(&listener);
984 listener.RegisterInterfaceFactory(proxy());
985 RunProxy();
986
987 base::RunLoop loop;
988 listener.set_ping_handler(loop.QuitClosure());
989 loop.Run();
990
991 EXPECT_TRUE(WaitForClientShutdown());
992
993 DestroyProxy();
994}
995
996DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
997 ProxyThreadAssociatedInterfaceIndirectClient,
998 ChannelProxyClient) {
999 DummyListener listener;
1000 CreateProxy(&listener);
1001 RunProxy();
1002
1003 // Use an interface requested via another interface. On the remote end both
1004 // interfaces are bound on the proxy thread. This ensures that the Ping
1005 // message we send will still be dispatched properly even though the remote
1006 // endpoint may not have been bound yet by the time the message is initially
1007 // processed on the IO thread.
1008 IPC::mojom::IndirectTestDriverAssociatedPtr driver;
1009 IPC::mojom::PingReceiverAssociatedPtr ping_receiver;
1010 proxy()->GetRemoteAssociatedInterface(&driver);
1011 driver->GetPingReceiver(
1012 mojo::GetProxy(&ping_receiver, driver.associated_group()));
1013
1014 base::RunLoop loop;
1015 ping_receiver->Ping(loop.QuitClosure());
1016 loop.Run();
1017
1018 DestroyProxy();
1019}
1020
rockot9abe09b2016-08-02 20:57:341021class ListenerWithSyncAssociatedInterface
1022 : public IPC::Listener,
1023 public IPC::mojom::SimpleTestDriver {
1024 public:
1025 ListenerWithSyncAssociatedInterface() : binding_(this) {}
1026 ~ListenerWithSyncAssociatedInterface() override {}
1027
1028 void set_sync_sender(IPC::Sender* sync_sender) { sync_sender_ = sync_sender; }
1029
1030 void RegisterInterfaceFactory(IPC::ChannelProxy* proxy) {
1031 proxy->AddAssociatedInterface(
1032 base::Bind(&ListenerWithSyncAssociatedInterface::BindRequest,
1033 base::Unretained(this)));
1034 }
1035
1036 void RunUntilQuitRequested() {
1037 base::RunLoop loop;
1038 quit_closure_ = loop.QuitClosure();
1039 loop.Run();
1040 }
1041
1042 void CloseBinding() { binding_.Close(); }
1043
1044 void set_response_value(int32_t response) {
1045 response_value_ = response;
1046 }
1047
1048 private:
1049 // IPC::mojom::SimpleTestDriver:
1050 void ExpectValue(int32_t value) override {
1051 next_expected_value_ = value;
1052 }
1053
1054 void GetExpectedValue(const GetExpectedValueCallback& callback) override {
1055 callback.Run(next_expected_value_);
1056 }
1057
1058 void RequestValue(const RequestValueCallback& callback) override {
1059 callback.Run(response_value_);
1060 }
1061
1062 void RequestQuit(const RequestQuitCallback& callback) override {
1063 quit_closure_.Run();
1064 callback.Run();
1065 }
1066
1067 // IPC::Listener:
1068 bool OnMessageReceived(const IPC::Message& message) override {
1069 EXPECT_EQ(0u, message.type());
1070 EXPECT_TRUE(message.is_sync());
1071 EXPECT_TRUE(message.should_unblock());
1072 std::unique_ptr<IPC::Message> reply(
1073 IPC::SyncMessage::GenerateReply(&message));
1074 reply->WriteInt(response_value_);
1075 DCHECK(sync_sender_);
1076 EXPECT_TRUE(sync_sender_->Send(reply.release()));
1077 return true;
1078 }
1079
1080 void BindRequest(IPC::mojom::SimpleTestDriverAssociatedRequest request) {
1081 DCHECK(!binding_.is_bound());
1082 binding_.Bind(std::move(request));
1083 }
1084
1085 IPC::Sender* sync_sender_ = nullptr;
1086 int32_t next_expected_value_ = 0;
1087 int32_t response_value_ = 0;
1088 base::Closure quit_closure_;
1089
1090 mojo::AssociatedBinding<IPC::mojom::SimpleTestDriver> binding_;
1091};
1092
1093class SyncReplyReader : public IPC::MessageReplyDeserializer {
1094 public:
1095 explicit SyncReplyReader(int32_t* storage) : storage_(storage) {}
1096 ~SyncReplyReader() override {}
1097
1098 private:
1099 // IPC::MessageReplyDeserializer:
1100 bool SerializeOutputParameters(const IPC::Message& message,
1101 base::PickleIterator iter) override {
1102 if (!iter.ReadInt(storage_))
1103 return false;
1104 return true;
1105 }
1106
1107 int32_t* storage_;
1108
1109 DISALLOW_COPY_AND_ASSIGN(SyncReplyReader);
1110};
1111
1112TEST_F(IPCChannelProxyMojoTest, SyncAssociatedInterface) {
1113 InitWithMojo("SyncAssociatedInterface");
1114
1115 ListenerWithSyncAssociatedInterface listener;
1116 CreateProxy(&listener);
1117 listener.set_sync_sender(proxy());
1118 listener.RegisterInterfaceFactory(proxy());
1119 RunProxy();
1120
1121 // Run the client's simple sanity check to completion.
1122 listener.RunUntilQuitRequested();
1123
1124 // Verify that we can send a sync IPC and service an incoming sync request
1125 // while waiting on it
1126 listener.set_response_value(42);
1127 IPC::mojom::SimpleTestClientAssociatedPtr client;
1128 proxy()->GetRemoteAssociatedInterface(&client);
1129 int32_t received_value;
1130 EXPECT_TRUE(client->RequestValue(&received_value));
1131 EXPECT_EQ(42, received_value);
1132
1133 // Do it again. This time the client will send a classical sync IPC to us
1134 // while we wait.
1135 received_value = 0;
1136 EXPECT_TRUE(client->RequestValue(&received_value));
1137 EXPECT_EQ(42, received_value);
1138
1139 // Now make a classical sync IPC request to the client. It will send a
1140 // sync associated interface message to us while we wait.
1141 received_value = 0;
1142 std::unique_ptr<IPC::SyncMessage> request(
1143 new IPC::SyncMessage(0, 0, IPC::Message::PRIORITY_NORMAL,
1144 new SyncReplyReader(&received_value)));
1145 EXPECT_TRUE(proxy()->Send(request.release()));
1146 EXPECT_EQ(42, received_value);
1147
1148 listener.CloseBinding();
1149 EXPECT_TRUE(WaitForClientShutdown());
1150
1151 DestroyProxy();
1152}
1153
1154class SimpleTestClientImpl : public IPC::mojom::SimpleTestClient,
1155 public IPC::Listener {
1156 public:
1157 SimpleTestClientImpl() : binding_(this) {}
1158
1159 void set_driver(IPC::mojom::SimpleTestDriver* driver) { driver_ = driver; }
1160 void set_sync_sender(IPC::Sender* sync_sender) { sync_sender_ = sync_sender; }
1161
1162 void BindRequest(IPC::mojom::SimpleTestClientAssociatedRequest request) {
1163 DCHECK(!binding_.is_bound());
1164 binding_.Bind(std::move(request));
1165 }
1166
1167 void WaitForValueRequest() {
1168 run_loop_.reset(new base::RunLoop);
1169 run_loop_->Run();
1170 }
1171
1172 void UseSyncSenderForRequest(bool use_sync_sender) {
1173 use_sync_sender_ = use_sync_sender;
1174 }
1175
1176 private:
1177 // IPC::mojom::SimpleTestClient:
1178 void RequestValue(const RequestValueCallback& callback) override {
1179 int32_t response = 0;
1180 if (use_sync_sender_) {
1181 std::unique_ptr<IPC::SyncMessage> reply(new IPC::SyncMessage(
1182 0, 0, IPC::Message::PRIORITY_NORMAL, new SyncReplyReader(&response)));
1183 EXPECT_TRUE(sync_sender_->Send(reply.release()));
1184 } else {
1185 DCHECK(driver_);
1186 EXPECT_TRUE(driver_->RequestValue(&response));
1187 }
1188
1189 callback.Run(response);
1190
1191 DCHECK(run_loop_);
1192 run_loop_->Quit();
1193 }
1194
1195 // IPC::Listener:
1196 bool OnMessageReceived(const IPC::Message& message) override {
1197 int32_t response;
1198 DCHECK(driver_);
1199 EXPECT_TRUE(driver_->RequestValue(&response));
1200 std::unique_ptr<IPC::Message> reply(
1201 IPC::SyncMessage::GenerateReply(&message));
1202 reply->WriteInt(response);
1203 EXPECT_TRUE(sync_sender_->Send(reply.release()));
1204
1205 DCHECK(run_loop_);
1206 run_loop_->Quit();
1207 return true;
1208 }
1209
1210 bool use_sync_sender_ = false;
1211 mojo::AssociatedBinding<IPC::mojom::SimpleTestClient> binding_;
1212 IPC::Sender* sync_sender_ = nullptr;
1213 IPC::mojom::SimpleTestDriver* driver_ = nullptr;
1214 std::unique_ptr<base::RunLoop> run_loop_;
1215
1216 DISALLOW_COPY_AND_ASSIGN(SimpleTestClientImpl);
1217};
1218
1219DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(SyncAssociatedInterface,
1220 ChannelProxyClient) {
1221 SimpleTestClientImpl client_impl;
1222 CreateProxy(&client_impl);
1223 client_impl.set_sync_sender(proxy());
1224 proxy()->AddAssociatedInterface(base::Bind(&SimpleTestClientImpl::BindRequest,
1225 base::Unretained(&client_impl)));
1226 RunProxy();
1227
1228 IPC::mojom::SimpleTestDriverAssociatedPtr driver;
1229 proxy()->GetRemoteAssociatedInterface(&driver);
1230 client_impl.set_driver(driver.get());
1231
1232 // Simple sync message sanity check.
1233 driver->ExpectValue(42);
1234 int32_t expected_value = 0;
1235 EXPECT_TRUE(driver->GetExpectedValue(&expected_value));
1236 EXPECT_EQ(42, expected_value);
1237 RequestQuitAndWaitForAck(driver.get());
1238
1239 // Wait for the test driver to perform a sync call test with our own sync
1240 // associated interface message nested inside.
1241 client_impl.UseSyncSenderForRequest(false);
1242 client_impl.WaitForValueRequest();
1243
1244 // Wait for the test driver to perform a sync call test with our own classical
1245 // sync IPC nested inside.
1246 client_impl.UseSyncSenderForRequest(true);
1247 client_impl.WaitForValueRequest();
1248
1249 // Wait for the test driver to perform a classical sync IPC request, with our
1250 // own sync associated interface message nested inside.
1251 client_impl.UseSyncSenderForRequest(false);
1252 client_impl.WaitForValueRequest();
1253
1254 DestroyProxy();
1255}
1256
rockot10188752016-09-08 18:24:561257TEST_F(IPCChannelProxyMojoTest, Pause) {
1258 // Ensures that pausing a channel elicits the expected behavior when sending
1259 // messages, unpausing, sending more messages, and then manually flushing.
1260 // Specifically a sequence like:
rockot401fb2c2016-09-06 18:35:571261 //
1262 // Connect()
1263 // Send(A)
rockot10188752016-09-08 18:24:561264 // Pause()
rockot401fb2c2016-09-06 18:35:571265 // Send(B)
rockot401fb2c2016-09-06 18:35:571266 // Send(C)
rockot10188752016-09-08 18:24:561267 // Unpause(false)
1268 // Send(D)
1269 // Send(E)
rockot401fb2c2016-09-06 18:35:571270 // Flush()
1271 //
rockot10188752016-09-08 18:24:561272 // must result in the other end receiving messages A, D, E, B, D; in that
rockot401fb2c2016-09-06 18:35:571273 // order.
1274 //
1275 // This behavior is required by some consumers of IPC::Channel, and it is not
1276 // sufficient to leave this up to the consumer to implement since associated
1277 // interface requests and messages also need to be queued according to the
1278 // same policy.
1279 InitWithMojo("CreatePausedClient");
1280
1281 DummyListener listener;
1282 CreateProxy(&listener);
rockot10188752016-09-08 18:24:561283 RunProxy();
1284
1285 // This message must be sent immediately since the channel is unpaused.
1286 SendValue(proxy(), 1);
1287
1288 proxy()->Pause();
rockot401fb2c2016-09-06 18:35:571289
1290 // These messages must be queued internally since the channel is paused.
rockot401fb2c2016-09-06 18:35:571291 SendValue(proxy(), 2);
rockot10188752016-09-08 18:24:561292 SendValue(proxy(), 3);
rockot401fb2c2016-09-06 18:35:571293
1294 proxy()->Unpause(false /* flush */);
1295
1296 // These messages must be sent immediately since the channel is unpaused.
rockot401fb2c2016-09-06 18:35:571297 SendValue(proxy(), 4);
rockot10188752016-09-08 18:24:561298 SendValue(proxy(), 5);
rockot401fb2c2016-09-06 18:35:571299
1300 // Now we flush the previously queued messages.
1301 proxy()->Flush();
1302
1303 EXPECT_TRUE(WaitForClientShutdown());
1304 DestroyProxy();
1305}
1306
1307class ExpectValueSequenceListener : public IPC::Listener {
1308 public:
1309 explicit ExpectValueSequenceListener(std::queue<int32_t>* expected_values)
1310 : expected_values_(expected_values) {}
1311 ~ExpectValueSequenceListener() override {}
1312
1313 // IPC::Listener:
1314 bool OnMessageReceived(const IPC::Message& message) override {
1315 DCHECK(!expected_values_->empty());
1316 base::PickleIterator iter(message);
1317 int32_t should_be_expected;
1318 EXPECT_TRUE(iter.ReadInt(&should_be_expected));
1319 EXPECT_EQ(expected_values_->front(), should_be_expected);
1320 expected_values_->pop();
1321 if (expected_values_->empty())
1322 base::MessageLoop::current()->QuitWhenIdle();
1323 return true;
1324 }
1325
1326 private:
1327 std::queue<int32_t>* expected_values_;
1328
1329 DISALLOW_COPY_AND_ASSIGN(ExpectValueSequenceListener);
1330};
1331
1332DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(CreatePausedClient, ChannelProxyClient) {
1333 std::queue<int32_t> expected_values;
1334 ExpectValueSequenceListener listener(&expected_values);
1335 CreateProxy(&listener);
rockot401fb2c2016-09-06 18:35:571336 expected_values.push(1);
rockot10188752016-09-08 18:24:561337 expected_values.push(4);
1338 expected_values.push(5);
rockot401fb2c2016-09-06 18:35:571339 expected_values.push(2);
rockot10188752016-09-08 18:24:561340 expected_values.push(3);
rockot401fb2c2016-09-06 18:35:571341 RunProxy();
1342 base::RunLoop().Run();
1343 EXPECT_TRUE(expected_values.empty());
1344 DestroyProxy();
1345}
1346
[email protected]64860882014-08-04 23:44:171347#if defined(OS_POSIX)
rockot8d890f62016-07-14 16:37:141348
[email protected]64860882014-08-04 23:44:171349class ListenerThatExpectsFile : public IPC::Listener {
1350 public:
sammc57ed9f982016-03-10 06:28:351351 ListenerThatExpectsFile() : sender_(NULL) {}
[email protected]64860882014-08-04 23:44:171352
dchengfe61fca2014-10-22 02:29:521353 ~ListenerThatExpectsFile() override {}
[email protected]64860882014-08-04 23:44:171354
dchengfe61fca2014-10-22 02:29:521355 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:251356 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:301357 HandleSendingHelper::ReadReceivedFile(message, &iter);
[email protected]64860882014-08-04 23:44:171358 ListenerThatExpectsOK::SendOK(sender_);
1359 return true;
1360 }
1361
amistry6c70caea2016-06-09 03:08:291362 void OnChannelError() override {
1363 base::MessageLoop::current()->QuitWhenIdle();
1364 }
[email protected]64860882014-08-04 23:44:171365
[email protected]64860882014-08-04 23:44:171366 void set_sender(IPC::Sender* sender) { sender_ = sender; }
1367
1368 private:
1369 IPC::Sender* sender_;
1370};
1371
amistry0027a0952016-05-03 00:52:471372TEST_F(IPCChannelMojoTest, SendPlatformHandle) {
rockotcbca72f2015-03-03 16:31:041373 InitWithMojo("IPCChannelMojoTestSendPlatformHandleClient");
[email protected]64860882014-08-04 23:44:171374
1375 ListenerThatExpectsOK listener;
morrita373af03b2014-09-09 19:35:241376 CreateChannel(&listener);
[email protected]64860882014-08-04 23:44:171377 ASSERT_TRUE(ConnectChannel());
[email protected]64860882014-08-04 23:44:171378
amistry20e2b1d62016-06-23 06:12:351379 base::ScopedTempDir temp_dir;
1380 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
vabr16e5f602016-09-15 18:14:001381 base::File file(HandleSendingHelper::GetSendingFilePath(temp_dir.GetPath()),
[email protected]64860882014-08-04 23:44:171382 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
morrita81b17e02015-02-06 00:58:301383 base::File::FLAG_READ);
1384 HandleSendingHelper::WriteFileThenSend(channel(), file);
fdoray8e32586852016-06-22 19:56:161385 base::RunLoop().Run();
[email protected]64860882014-08-04 23:44:171386
sammc57ed9f982016-03-10 06:28:351387 channel()->Close();
[email protected]64860882014-08-04 23:44:171388
1389 EXPECT_TRUE(WaitForClientShutdown());
1390 DestroyChannel();
1391}
1392
sammc57ed9f982016-03-10 06:28:351393DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendPlatformHandleClient,
1394 ChannelClient) {
[email protected]64860882014-08-04 23:44:171395 ListenerThatExpectsFile listener;
sammc57ed9f982016-03-10 06:28:351396 Connect(&listener);
1397 listener.set_sender(channel());
[email protected]64860882014-08-04 23:44:171398
fdoray8e32586852016-06-22 19:56:161399 base::RunLoop().Run();
[email protected]64860882014-08-04 23:44:171400
sammc57ed9f982016-03-10 06:28:351401 Close();
[email protected]64860882014-08-04 23:44:171402}
morrita81b17e02015-02-06 00:58:301403
1404class ListenerThatExpectsFileAndPipe : public IPC::Listener {
1405 public:
1406 ListenerThatExpectsFileAndPipe() : sender_(NULL) {}
1407
1408 ~ListenerThatExpectsFileAndPipe() override {}
1409
1410 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:251411 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:301412 HandleSendingHelper::ReadReceivedFile(message, &iter);
1413 HandleSendingHelper::ReadReceivedPipe(message, &iter);
morrita81b17e02015-02-06 00:58:301414 ListenerThatExpectsOK::SendOK(sender_);
1415 return true;
1416 }
1417
amistry6c70caea2016-06-09 03:08:291418 void OnChannelError() override {
1419 base::MessageLoop::current()->QuitWhenIdle();
1420 }
morrita81b17e02015-02-06 00:58:301421
1422 void set_sender(IPC::Sender* sender) { sender_ = sender; }
1423
1424 private:
1425 IPC::Sender* sender_;
1426};
1427
amistry0027a0952016-05-03 00:52:471428TEST_F(IPCChannelMojoTest, SendPlatformHandleAndPipe) {
rockotcbca72f2015-03-03 16:31:041429 InitWithMojo("IPCChannelMojoTestSendPlatformHandleAndPipeClient");
morrita81b17e02015-02-06 00:58:301430
1431 ListenerThatExpectsOK listener;
1432 CreateChannel(&listener);
1433 ASSERT_TRUE(ConnectChannel());
morrita81b17e02015-02-06 00:58:301434
amistry20e2b1d62016-06-23 06:12:351435 base::ScopedTempDir temp_dir;
1436 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
vabr16e5f602016-09-15 18:14:001437 base::File file(HandleSendingHelper::GetSendingFilePath(temp_dir.GetPath()),
morrita81b17e02015-02-06 00:58:301438 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
1439 base::File::FLAG_READ);
1440 TestingMessagePipe pipe;
1441 HandleSendingHelper::WriteFileAndPipeThenSend(channel(), file, &pipe);
1442
fdoray8e32586852016-06-22 19:56:161443 base::RunLoop().Run();
sammc57ed9f982016-03-10 06:28:351444 channel()->Close();
morrita81b17e02015-02-06 00:58:301445
1446 EXPECT_TRUE(WaitForClientShutdown());
1447 DestroyChannel();
1448}
1449
sammc57ed9f982016-03-10 06:28:351450DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
1451 IPCChannelMojoTestSendPlatformHandleAndPipeClient,
1452 ChannelClient) {
morrita81b17e02015-02-06 00:58:301453 ListenerThatExpectsFileAndPipe listener;
sammc57ed9f982016-03-10 06:28:351454 Connect(&listener);
1455 listener.set_sender(channel());
morrita81b17e02015-02-06 00:58:301456
fdoray8e32586852016-06-22 19:56:161457 base::RunLoop().Run();
morrita81b17e02015-02-06 00:58:301458
sammc57ed9f982016-03-10 06:28:351459 Close();
morrita81b17e02015-02-06 00:58:301460}
1461
rockot7c6bf952016-07-14 00:34:111462#endif // defined(OS_POSIX)
[email protected]64860882014-08-04 23:44:171463
morrita0bd20bd2015-02-25 20:11:271464#if defined(OS_LINUX)
1465
1466const base::ProcessId kMagicChildId = 54321;
1467
1468class ListenerThatVerifiesPeerPid : public IPC::Listener {
1469 public:
tfarina10a5c062015-09-04 18:47:571470 void OnChannelConnected(int32_t peer_pid) override {
morrita0bd20bd2015-02-25 20:11:271471 EXPECT_EQ(peer_pid, kMagicChildId);
ki.stfua21ed8c2015-10-12 17:26:001472 base::MessageLoop::current()->QuitWhenIdle();
morrita0bd20bd2015-02-25 20:11:271473 }
1474
1475 bool OnMessageReceived(const IPC::Message& message) override {
1476 NOTREACHED();
1477 return true;
1478 }
1479};
1480
sammc57ed9f982016-03-10 06:28:351481TEST_F(IPCChannelMojoTest, VerifyGlobalPid) {
rockotcbca72f2015-03-03 16:31:041482 InitWithMojo("IPCChannelMojoTestVerifyGlobalPidClient");
morrita0bd20bd2015-02-25 20:11:271483
1484 ListenerThatVerifiesPeerPid listener;
1485 CreateChannel(&listener);
1486 ASSERT_TRUE(ConnectChannel());
morrita0bd20bd2015-02-25 20:11:271487
fdoray6ef45cf2016-08-25 15:36:371488 base::RunLoop().Run();
rockotcbca72f2015-03-03 16:31:041489 channel()->Close();
morrita0bd20bd2015-02-25 20:11:271490
1491 EXPECT_TRUE(WaitForClientShutdown());
1492 DestroyChannel();
1493}
1494
sammc57ed9f982016-03-10 06:28:351495DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestVerifyGlobalPidClient,
1496 ChannelClient) {
morrita0bd20bd2015-02-25 20:11:271497 IPC::Channel::SetGlobalPid(kMagicChildId);
1498 ListenerThatQuits listener;
sammc57ed9f982016-03-10 06:28:351499 Connect(&listener);
morrita0bd20bd2015-02-25 20:11:271500
fdoray6ef45cf2016-08-25 15:36:371501 base::RunLoop().Run();
morrita0bd20bd2015-02-25 20:11:271502
sammc57ed9f982016-03-10 06:28:351503 Close();
morrita0bd20bd2015-02-25 20:11:271504}
1505
sammc57ed9f982016-03-10 06:28:351506#endif // OS_LINUX
morrita0bd20bd2015-02-25 20:11:271507
[email protected]64860882014-08-04 23:44:171508} // namespace