1 // 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
5 #include "ipc/ipc_channel_mojo.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9
10 #include <memory>
11 #include <utility>
12
13 #include "base/base_paths.h"
14 #include "base/bind.h"
15 #include "base/callback_helpers.h"
16 #include "base/containers/queue.h"
17 #include "base/files/file.h"
18 #include "base/files/scoped_temp_dir.h"
19 #include "base/location.h"
20 #include "base/macros.h"
21 #include "base/memory/platform_shared_memory_region.h"
22 #include "base/memory/read_only_shared_memory_region.h"
23 #include "base/memory/shared_memory_mapping.h"
24 #include "base/memory/unsafe_shared_memory_region.h"
25 #include "base/memory/writable_shared_memory_region.h"
26 #include "base/message_loop/message_pump_type.h"
27 #include "base/optional.h"
28 #include "base/path_service.h"
29 #include "base/pickle.h"
30 #include "base/run_loop.h"
31 #include "base/single_thread_task_runner.h"
32 #include "base/strings/stringprintf.h"
33 #include "base/synchronization/waitable_event.h"
34 #include "base/test/bind.h"
35 #include "base/test/task_environment.h"
36 #include "base/test/test_io_thread.h"
37 #include "base/test/test_shared_memory_util.h"
38 #include "base/test/test_timeouts.h"
39 #include "base/threading/thread.h"
40 #include "base/threading/thread_task_runner_handle.h"
41 #include "build/build_config.h"
42 #include "ipc/ipc_message.h"
43 #include "ipc/ipc_message_utils.h"
44 #include "ipc/ipc_mojo_handle_attachment.h"
45 #include "ipc/ipc_mojo_message_helper.h"
46 #include "ipc/ipc_mojo_param_traits.h"
47 #include "ipc/ipc_sync_channel.h"
48 #include "ipc/ipc_sync_message.h"
49 #include "ipc/ipc_test.mojom.h"
50 #include "ipc/ipc_test_base.h"
51 #include "ipc/ipc_test_channel_listener.h"
52 #include "mojo/public/cpp/bindings/associated_receiver.h"
53 #include "mojo/public/cpp/bindings/associated_remote.h"
54 #include "mojo/public/cpp/bindings/lib/validation_errors.h"
55 #include "mojo/public/cpp/bindings/pending_associated_receiver.h"
56 #include "mojo/public/cpp/system/functions.h"
57 #include "mojo/public/cpp/system/wait.h"
58 #include "testing/gtest/include/gtest/gtest.h"
59
60 #if defined(OS_POSIX) || defined(OS_FUCHSIA)
61 #include "base/file_descriptor_posix.h"
62 #include "ipc/ipc_platform_file_attachment_posix.h"
63 #endif
64
65 namespace {
66
SendString(IPC::Sender * sender,const std::string & str)67 void SendString(IPC::Sender* sender, const std::string& str) {
68 IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
69 message->WriteString(str);
70 ASSERT_TRUE(sender->Send(message));
71 }
72
SendValue(IPC::Sender * sender,int32_t value)73 void SendValue(IPC::Sender* sender, int32_t value) {
74 IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
75 message->WriteInt(value);
76 ASSERT_TRUE(sender->Send(message));
77 }
78
79 class ListenerThatExpectsOK : public IPC::Listener {
80 public:
ListenerThatExpectsOK(base::OnceClosure quit_closure)81 explicit ListenerThatExpectsOK(base::OnceClosure quit_closure)
82 : received_ok_(false), quit_closure_(std::move(quit_closure)) {}
83
84 ~ListenerThatExpectsOK() override = default;
85
OnMessageReceived(const IPC::Message & message)86 bool OnMessageReceived(const IPC::Message& message) override {
87 base::PickleIterator iter(message);
88 std::string should_be_ok;
89 EXPECT_TRUE(iter.ReadString(&should_be_ok));
90 EXPECT_EQ(should_be_ok, "OK");
91 received_ok_ = true;
92 std::move(quit_closure_).Run();
93 return true;
94 }
95
OnChannelError()96 void OnChannelError() override {
97 // The connection should be healthy while the listener is waiting
98 // message. An error can occur after that because the peer
99 // process dies.
100 CHECK(received_ok_);
101 }
102
SendOK(IPC::Sender * sender)103 static void SendOK(IPC::Sender* sender) { SendString(sender, "OK"); }
104
105 private:
106 bool received_ok_;
107 base::OnceClosure quit_closure_;
108 };
109
110 class TestListenerBase : public IPC::Listener {
111 public:
TestListenerBase(base::OnceClosure quit_closure)112 explicit TestListenerBase(base::OnceClosure quit_closure)
113 : quit_closure_(std::move(quit_closure)) {}
114
115 ~TestListenerBase() override = default;
OnChannelError()116 void OnChannelError() override { RunQuitClosure(); }
117
set_sender(IPC::Sender * sender)118 void set_sender(IPC::Sender* sender) { sender_ = sender; }
sender() const119 IPC::Sender* sender() const { return sender_; }
RunQuitClosure()120 void RunQuitClosure() {
121 if (quit_closure_)
122 std::move(quit_closure_).Run();
123 }
124
125 private:
126 IPC::Sender* sender_ = nullptr;
127 base::OnceClosure quit_closure_;
128 };
129
130 using IPCChannelMojoTest = IPCChannelMojoTestBase;
131
132 class TestChannelListenerWithExtraExpectations
133 : public IPC::TestChannelListener {
134 public:
TestChannelListenerWithExtraExpectations()135 TestChannelListenerWithExtraExpectations() : is_connected_called_(false) {}
136
OnChannelConnected(int32_t peer_pid)137 void OnChannelConnected(int32_t peer_pid) override {
138 IPC::TestChannelListener::OnChannelConnected(peer_pid);
139 EXPECT_TRUE(base::kNullProcessId != peer_pid);
140 is_connected_called_ = true;
141 }
142
is_connected_called() const143 bool is_connected_called() const { return is_connected_called_; }
144
145 private:
146 bool is_connected_called_;
147 };
148
TEST_F(IPCChannelMojoTest,ConnectedFromClient)149 TEST_F(IPCChannelMojoTest, ConnectedFromClient) {
150 Init("IPCChannelMojoTestClient");
151
152 // Set up IPC channel and start client.
153 TestChannelListenerWithExtraExpectations listener;
154 CreateChannel(&listener);
155 listener.Init(sender());
156 ASSERT_TRUE(ConnectChannel());
157
158 IPC::TestChannelListener::SendOneMessage(sender(), "hello from parent");
159
160 base::RunLoop().Run();
161
162 channel()->Close();
163
164 EXPECT_TRUE(WaitForClientShutdown());
165 EXPECT_TRUE(listener.is_connected_called());
166 EXPECT_TRUE(listener.HasSentAll());
167
168 DestroyChannel();
169 }
170
171 // A long running process that connects to us
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestClient)172 DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestClient) {
173 TestChannelListenerWithExtraExpectations listener;
174 Connect(&listener);
175 listener.Init(channel());
176
177 IPC::TestChannelListener::SendOneMessage(channel(), "hello from child");
178 base::RunLoop().Run();
179 EXPECT_TRUE(listener.is_connected_called());
180 EXPECT_TRUE(listener.HasSentAll());
181
182 Close();
183 }
184
185 class ListenerExpectingErrors : public TestListenerBase {
186 public:
ListenerExpectingErrors(base::OnceClosure quit_closure)187 ListenerExpectingErrors(base::OnceClosure quit_closure)
188 : TestListenerBase(std::move(quit_closure)), has_error_(false) {}
189
OnMessageReceived(const IPC::Message & message)190 bool OnMessageReceived(const IPC::Message& message) override { return true; }
191
OnChannelError()192 void OnChannelError() override {
193 has_error_ = true;
194 TestListenerBase::OnChannelError();
195 }
196
has_error() const197 bool has_error() const { return has_error_; }
198
199 private:
200 bool has_error_;
201 };
202
203 class ListenerThatQuits : public IPC::Listener {
204 public:
ListenerThatQuits(base::OnceClosure quit_closure)205 explicit ListenerThatQuits(base::OnceClosure quit_closure)
206 : quit_closure_(std::move(quit_closure)) {}
207
OnMessageReceived(const IPC::Message & message)208 bool OnMessageReceived(const IPC::Message& message) override { return true; }
209
OnChannelConnected(int32_t peer_pid)210 void OnChannelConnected(int32_t peer_pid) override {
211 std::move(quit_closure_).Run();
212 }
213
214 private:
215 base::OnceClosure quit_closure_;
216 };
217
218 // A long running process that connects to us.
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoErraticTestClient)219 DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoErraticTestClient) {
220 base::RunLoop run_loop;
221 ListenerThatQuits listener(run_loop.QuitClosure());
222 Connect(&listener);
223
224 run_loop.Run();
225
226 Close();
227 }
228
TEST_F(IPCChannelMojoTest,SendFailWithPendingMessages)229 TEST_F(IPCChannelMojoTest, SendFailWithPendingMessages) {
230 Init("IPCChannelMojoErraticTestClient");
231
232 // Set up IPC channel and start client.
233 base::RunLoop run_loop;
234 ListenerExpectingErrors listener(run_loop.QuitClosure());
235 CreateChannel(&listener);
236 ASSERT_TRUE(ConnectChannel());
237
238 // This matches a value in mojo/edk/system/constants.h
239 const int kMaxMessageNumBytes = 4 * 1024 * 1024;
240 std::string overly_large_data(kMaxMessageNumBytes, '*');
241 // This messages are queued as pending.
242 for (size_t i = 0; i < 10; ++i) {
243 IPC::TestChannelListener::SendOneMessage(sender(),
244 overly_large_data.c_str());
245 }
246
247 run_loop.Run();
248
249 channel()->Close();
250
251 EXPECT_TRUE(WaitForClientShutdown());
252 EXPECT_TRUE(listener.has_error());
253
254 DestroyChannel();
255 }
256
257 class ListenerThatBindsATestStructPasser : public IPC::Listener,
258 public IPC::mojom::TestStructPasser {
259 public:
260 ListenerThatBindsATestStructPasser() = default;
261 ~ListenerThatBindsATestStructPasser() override = default;
262
OnMessageReceived(const IPC::Message & message)263 bool OnMessageReceived(const IPC::Message& message) override { return true; }
264
OnChannelConnected(int32_t peer_pid)265 void OnChannelConnected(int32_t peer_pid) override {}
266
OnChannelError()267 void OnChannelError() override { NOTREACHED(); }
268
OnAssociatedInterfaceRequest(const std::string & interface_name,mojo::ScopedInterfaceEndpointHandle handle)269 void OnAssociatedInterfaceRequest(
270 const std::string& interface_name,
271 mojo::ScopedInterfaceEndpointHandle handle) override {
272 CHECK_EQ(interface_name, IPC::mojom::TestStructPasser::Name_);
273 receiver_.Bind(
274 mojo::PendingAssociatedReceiver<IPC::mojom::TestStructPasser>(
275 std::move(handle)));
276 }
277
278 private:
279 // IPC::mojom::TestStructPasser:
Pass(IPC::mojom::TestStructPtr)280 void Pass(IPC::mojom::TestStructPtr) override { NOTREACHED(); }
281
282 mojo::AssociatedReceiver<IPC::mojom::TestStructPasser> receiver_{this};
283 };
284
285 class ListenerThatExpectsNoError : public IPC::Listener {
286 public:
ListenerThatExpectsNoError(base::OnceClosure connect_closure,base::OnceClosure quit_closure)287 ListenerThatExpectsNoError(base::OnceClosure connect_closure,
288 base::OnceClosure quit_closure)
289 : connect_closure_(std::move(connect_closure)),
290 quit_closure_(std::move(quit_closure)) {}
291
OnMessageReceived(const IPC::Message & message)292 bool OnMessageReceived(const IPC::Message& message) override {
293 base::PickleIterator iter(message);
294 std::string should_be_ok;
295 EXPECT_TRUE(iter.ReadString(&should_be_ok));
296 EXPECT_EQ(should_be_ok, "OK");
297 std::move(quit_closure_).Run();
298 return true;
299 }
300
OnChannelConnected(int32_t peer_pid)301 void OnChannelConnected(int32_t peer_pid) override {
302 std::move(connect_closure_).Run();
303 }
304
OnChannelError()305 void OnChannelError() override { NOTREACHED(); }
306
307 private:
308 base::OnceClosure connect_closure_;
309 base::OnceClosure quit_closure_;
310 };
311
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoNoImplicitChanelClosureClient)312 DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
313 IPCChannelMojoNoImplicitChanelClosureClient) {
314 base::RunLoop wait_to_connect_loop;
315 base::RunLoop wait_to_quit_loop;
316 ListenerThatExpectsNoError listener(wait_to_connect_loop.QuitClosure(),
317 wait_to_quit_loop.QuitClosure());
318 Connect(&listener);
319 wait_to_connect_loop.Run();
320
321 mojo::AssociatedRemote<IPC::mojom::TestStructPasser> passer;
322 channel()->GetAssociatedInterfaceSupport()->GetRemoteAssociatedInterface(
323 passer.BindNewEndpointAndPassReceiver());
324
325 // This avoids hitting DCHECKs in the serialization code meant to stop us from
326 // making such "mistakes" as the one we're about to make below.
327 mojo::internal::SerializationWarningObserverForTesting suppress_those_dchecks;
328
329 // Send an invalid message. The TestStruct argument is not allowed to be null.
330 // This will elicit a validation error in the parent process, but should not
331 // actually disconnect the channel.
332 passer->Pass(nullptr);
333
334 // Wait until the parent says it's OK to quit, so it has time to verify its
335 // expected behavior.
336 wait_to_quit_loop.Run();
337
338 Close();
339 }
340
TEST_F(IPCChannelMojoTest,NoImplicitChannelClosure)341 TEST_F(IPCChannelMojoTest, NoImplicitChannelClosure) {
342 // Verifies that OnChannelError is not invoked due to conditions other than
343 // peer closure (e.g. a malformed inbound message). Instead we should always
344 // be able to handle validation errors via Mojo bad message reporting.
345
346 // NOTE: We can't create a RunLoop before Init() is called, but we have to set
347 // the default ProcessErrorCallback (which we want to reference the RunLoop)
348 // before Init() launches a child process. Hence the base::Optional here.
349 base::Optional<base::RunLoop> wait_for_error_loop;
350 bool process_error_received = false;
351 mojo::SetDefaultProcessErrorHandler(
352 base::BindLambdaForTesting([&](const std::string&) {
353 process_error_received = true;
354 wait_for_error_loop->Quit();
355 }));
356
357 Init("IPCChannelMojoNoImplicitChanelClosureClient");
358
359 wait_for_error_loop.emplace();
360 ListenerThatBindsATestStructPasser listener;
361 CreateChannel(&listener);
362 ASSERT_TRUE(ConnectChannel());
363
364 wait_for_error_loop->Run();
365 EXPECT_TRUE(process_error_received);
366 mojo::SetDefaultProcessErrorHandler(base::NullCallback());
367
368 // Tell the child it can quit and wait for it to shut down.
369 ListenerThatExpectsOK::SendOK(channel());
370 EXPECT_TRUE(WaitForClientShutdown());
371 DestroyChannel();
372 }
373
374 struct TestingMessagePipe {
TestingMessagePipe__anon0a24d34b0111::TestingMessagePipe375 TestingMessagePipe() {
376 EXPECT_EQ(MOJO_RESULT_OK, mojo::CreateMessagePipe(nullptr, &self, &peer));
377 }
378
379 mojo::ScopedMessagePipeHandle self;
380 mojo::ScopedMessagePipeHandle peer;
381 };
382
383 class HandleSendingHelper {
384 public:
GetSendingFileContent()385 static std::string GetSendingFileContent() { return "Hello"; }
386
WritePipe(IPC::Message * message,TestingMessagePipe * pipe)387 static void WritePipe(IPC::Message* message, TestingMessagePipe* pipe) {
388 std::string content = HandleSendingHelper::GetSendingFileContent();
389 EXPECT_EQ(MOJO_RESULT_OK,
390 mojo::WriteMessageRaw(pipe->self.get(), &content[0],
391 static_cast<uint32_t>(content.size()),
392 nullptr, 0, 0));
393 EXPECT_TRUE(IPC::MojoMessageHelper::WriteMessagePipeTo(
394 message, std::move(pipe->peer)));
395 }
396
WritePipeThenSend(IPC::Sender * sender,TestingMessagePipe * pipe)397 static void WritePipeThenSend(IPC::Sender* sender, TestingMessagePipe* pipe) {
398 IPC::Message* message =
399 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
400 WritePipe(message, pipe);
401 ASSERT_TRUE(sender->Send(message));
402 }
403
ReadReceivedPipe(const IPC::Message & message,base::PickleIterator * iter)404 static void ReadReceivedPipe(const IPC::Message& message,
405 base::PickleIterator* iter) {
406 mojo::ScopedMessagePipeHandle pipe;
407 EXPECT_TRUE(
408 IPC::MojoMessageHelper::ReadMessagePipeFrom(&message, iter, &pipe));
409 std::vector<uint8_t> content;
410
411 ASSERT_EQ(MOJO_RESULT_OK,
412 mojo::Wait(pipe.get(), MOJO_HANDLE_SIGNAL_READABLE));
413 EXPECT_EQ(MOJO_RESULT_OK,
414 mojo::ReadMessageRaw(pipe.get(), &content, nullptr, 0));
415 EXPECT_EQ(std::string(content.begin(), content.end()),
416 GetSendingFileContent());
417 }
418
419 #if defined(OS_POSIX) || defined(OS_FUCHSIA)
GetSendingFilePath(const base::FilePath & dir_path)420 static base::FilePath GetSendingFilePath(const base::FilePath& dir_path) {
421 return dir_path.Append("ListenerThatExpectsFile.txt");
422 }
423
WriteFile(IPC::Message * message,base::File & file)424 static void WriteFile(IPC::Message* message, base::File& file) {
425 std::string content = GetSendingFileContent();
426 file.WriteAtCurrentPos(content.data(), content.size());
427 file.Flush();
428 message->WriteAttachment(new IPC::internal::PlatformFileAttachment(
429 base::ScopedFD(file.TakePlatformFile())));
430 }
431
WriteFileThenSend(IPC::Sender * sender,base::File & file)432 static void WriteFileThenSend(IPC::Sender* sender, base::File& file) {
433 IPC::Message* message =
434 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
435 WriteFile(message, file);
436 ASSERT_TRUE(sender->Send(message));
437 }
438
WriteFileAndPipeThenSend(IPC::Sender * sender,base::File & file,TestingMessagePipe * pipe)439 static void WriteFileAndPipeThenSend(IPC::Sender* sender,
440 base::File& file,
441 TestingMessagePipe* pipe) {
442 IPC::Message* message =
443 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
444 WriteFile(message, file);
445 WritePipe(message, pipe);
446 ASSERT_TRUE(sender->Send(message));
447 }
448
ReadReceivedFile(const IPC::Message & message,base::PickleIterator * iter)449 static void ReadReceivedFile(const IPC::Message& message,
450 base::PickleIterator* iter) {
451 scoped_refptr<base::Pickle::Attachment> attachment;
452 EXPECT_TRUE(message.ReadAttachment(iter, &attachment));
453 EXPECT_EQ(
454 IPC::MessageAttachment::Type::PLATFORM_FILE,
455 static_cast<IPC::MessageAttachment*>(attachment.get())->GetType());
456 base::File file(
457 static_cast<IPC::internal::PlatformFileAttachment*>(attachment.get())
458 ->TakePlatformFile());
459 std::string content(GetSendingFileContent().size(), ' ');
460 file.Read(0, &content[0], content.size());
461 EXPECT_EQ(content, GetSendingFileContent());
462 }
463 #endif
464 };
465
466 class ListenerThatExpectsMessagePipe : public TestListenerBase {
467 public:
ListenerThatExpectsMessagePipe(base::OnceClosure quit_closure)468 ListenerThatExpectsMessagePipe(base::OnceClosure quit_closure)
469 : TestListenerBase(std::move(quit_closure)) {}
470
471 ~ListenerThatExpectsMessagePipe() override = default;
472
OnMessageReceived(const IPC::Message & message)473 bool OnMessageReceived(const IPC::Message& message) override {
474 base::PickleIterator iter(message);
475 HandleSendingHelper::ReadReceivedPipe(message, &iter);
476 ListenerThatExpectsOK::SendOK(sender());
477 return true;
478 }
479 };
480
TEST_F(IPCChannelMojoTest,SendMessagePipe)481 TEST_F(IPCChannelMojoTest, SendMessagePipe) {
482 Init("IPCChannelMojoTestSendMessagePipeClient");
483
484 base::RunLoop run_loop;
485 ListenerThatExpectsOK listener(run_loop.QuitClosure());
486 CreateChannel(&listener);
487 ASSERT_TRUE(ConnectChannel());
488
489 TestingMessagePipe pipe;
490 HandleSendingHelper::WritePipeThenSend(channel(), &pipe);
491
492 run_loop.Run();
493 channel()->Close();
494
495 EXPECT_TRUE(WaitForClientShutdown());
496 DestroyChannel();
497 }
498
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendMessagePipeClient)499 DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendMessagePipeClient) {
500 base::RunLoop run_loop;
501 ListenerThatExpectsMessagePipe listener(run_loop.QuitClosure());
502 Connect(&listener);
503 listener.set_sender(channel());
504
505 run_loop.Run();
506
507 Close();
508 }
509
ReadOK(mojo::MessagePipeHandle pipe)510 void ReadOK(mojo::MessagePipeHandle pipe) {
511 std::vector<uint8_t> should_be_ok;
512 CHECK_EQ(MOJO_RESULT_OK, mojo::Wait(pipe, MOJO_HANDLE_SIGNAL_READABLE));
513 CHECK_EQ(MOJO_RESULT_OK,
514 mojo::ReadMessageRaw(pipe, &should_be_ok, nullptr, 0));
515 EXPECT_EQ("OK", std::string(should_be_ok.begin(), should_be_ok.end()));
516 }
517
WriteOK(mojo::MessagePipeHandle pipe)518 void WriteOK(mojo::MessagePipeHandle pipe) {
519 std::string ok("OK");
520 CHECK_EQ(MOJO_RESULT_OK,
521 mojo::WriteMessageRaw(pipe, &ok[0], static_cast<uint32_t>(ok.size()),
522 nullptr, 0, 0));
523 }
524
525 class ListenerThatExpectsMessagePipeUsingParamTrait : public TestListenerBase {
526 public:
ListenerThatExpectsMessagePipeUsingParamTrait(base::OnceClosure quit_closure,bool receiving_valid)527 explicit ListenerThatExpectsMessagePipeUsingParamTrait(
528 base::OnceClosure quit_closure,
529 bool receiving_valid)
530 : TestListenerBase(std::move(quit_closure)),
531 receiving_valid_(receiving_valid) {}
532
533 ~ListenerThatExpectsMessagePipeUsingParamTrait() override = default;
534
OnMessageReceived(const IPC::Message & message)535 bool OnMessageReceived(const IPC::Message& message) override {
536 base::PickleIterator iter(message);
537 mojo::MessagePipeHandle handle;
538 EXPECT_TRUE(IPC::ParamTraits<mojo::MessagePipeHandle>::Read(&message, &iter,
539 &handle));
540 EXPECT_EQ(handle.is_valid(), receiving_valid_);
541 if (receiving_valid_) {
542 ReadOK(handle);
543 MojoClose(handle.value());
544 }
545
546 ListenerThatExpectsOK::SendOK(sender());
547 return true;
548 }
549
550 private:
551 bool receiving_valid_;
552 };
553
554 class ParamTraitMessagePipeClient : public IpcChannelMojoTestClient {
555 public:
RunTest(bool receiving_valid_handle)556 void RunTest(bool receiving_valid_handle) {
557 base::RunLoop run_loop;
558 ListenerThatExpectsMessagePipeUsingParamTrait listener(
559 run_loop.QuitClosure(), receiving_valid_handle);
560 Connect(&listener);
561 listener.set_sender(channel());
562
563 run_loop.Run();
564
565 Close();
566 }
567 };
568
TEST_F(IPCChannelMojoTest,ParamTraitValidMessagePipe)569 TEST_F(IPCChannelMojoTest, ParamTraitValidMessagePipe) {
570 Init("ParamTraitValidMessagePipeClient");
571
572 base::RunLoop run_loop;
573 ListenerThatExpectsOK listener(run_loop.QuitClosure());
574 CreateChannel(&listener);
575 ASSERT_TRUE(ConnectChannel());
576
577 TestingMessagePipe pipe;
578
579 std::unique_ptr<IPC::Message> message(new IPC::Message());
580 IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
581 pipe.peer.release());
582 WriteOK(pipe.self.get());
583
584 channel()->Send(message.release());
585 run_loop.Run();
586 channel()->Close();
587
588 EXPECT_TRUE(WaitForClientShutdown());
589 DestroyChannel();
590 }
591
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(ParamTraitValidMessagePipeClient,ParamTraitMessagePipeClient)592 DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
593 ParamTraitValidMessagePipeClient,
594 ParamTraitMessagePipeClient) {
595 RunTest(true);
596 }
597
TEST_F(IPCChannelMojoTest,ParamTraitInvalidMessagePipe)598 TEST_F(IPCChannelMojoTest, ParamTraitInvalidMessagePipe) {
599 Init("ParamTraitInvalidMessagePipeClient");
600
601 base::RunLoop run_loop;
602 ListenerThatExpectsOK listener(run_loop.QuitClosure());
603 CreateChannel(&listener);
604 ASSERT_TRUE(ConnectChannel());
605
606 mojo::MessagePipeHandle invalid_handle;
607 std::unique_ptr<IPC::Message> message(new IPC::Message());
608 IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
609 invalid_handle);
610
611 channel()->Send(message.release());
612 run_loop.Run();
613 channel()->Close();
614
615 EXPECT_TRUE(WaitForClientShutdown());
616 DestroyChannel();
617 }
618
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(ParamTraitInvalidMessagePipeClient,ParamTraitMessagePipeClient)619 DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
620 ParamTraitInvalidMessagePipeClient,
621 ParamTraitMessagePipeClient) {
622 RunTest(false);
623 }
624
TEST_F(IPCChannelMojoTest,SendFailAfterClose)625 TEST_F(IPCChannelMojoTest, SendFailAfterClose) {
626 Init("IPCChannelMojoTestSendOkClient");
627
628 base::RunLoop run_loop;
629 ListenerThatExpectsOK listener(run_loop.QuitClosure());
630 CreateChannel(&listener);
631 ASSERT_TRUE(ConnectChannel());
632
633 run_loop.Run();
634 channel()->Close();
635 ASSERT_FALSE(channel()->Send(new IPC::Message()));
636
637 EXPECT_TRUE(WaitForClientShutdown());
638 DestroyChannel();
639 }
640
641 class ListenerSendingOneOk : public TestListenerBase {
642 public:
ListenerSendingOneOk(base::OnceClosure quit_closure)643 ListenerSendingOneOk(base::OnceClosure quit_closure)
644 : TestListenerBase(std::move(quit_closure)) {}
645
OnMessageReceived(const IPC::Message & message)646 bool OnMessageReceived(const IPC::Message& message) override { return true; }
647
OnChannelConnected(int32_t peer_pid)648 void OnChannelConnected(int32_t peer_pid) override {
649 ListenerThatExpectsOK::SendOK(sender());
650 RunQuitClosure();
651 }
652 };
653
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendOkClient)654 DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendOkClient) {
655 base::RunLoop run_loop;
656 ListenerSendingOneOk listener(run_loop.QuitClosure());
657 Connect(&listener);
658 listener.set_sender(channel());
659
660 run_loop.Run();
661
662 Close();
663 }
664
665 class ListenerWithSimpleAssociatedInterface
666 : public IPC::Listener,
667 public IPC::mojom::SimpleTestDriver {
668 public:
669 static const int kNumMessages;
670
ListenerWithSimpleAssociatedInterface(base::OnceClosure quit_closure)671 explicit ListenerWithSimpleAssociatedInterface(base::OnceClosure quit_closure)
672 : quit_closure_(std::move(quit_closure)) {}
673
674 ~ListenerWithSimpleAssociatedInterface() override = default;
675
OnMessageReceived(const IPC::Message & message)676 bool OnMessageReceived(const IPC::Message& message) override {
677 base::PickleIterator iter(message);
678 int32_t should_be_expected;
679 EXPECT_TRUE(iter.ReadInt(&should_be_expected));
680 EXPECT_EQ(should_be_expected, next_expected_value_);
681 num_messages_received_++;
682 return true;
683 }
684
OnChannelError()685 void OnChannelError() override { CHECK(!quit_closure_); }
686
RegisterInterfaceFactory(IPC::Channel * channel)687 void RegisterInterfaceFactory(IPC::Channel* channel) {
688 channel->GetAssociatedInterfaceSupport()->AddAssociatedInterface(
689 base::BindRepeating(
690 &ListenerWithSimpleAssociatedInterface::BindReceiver,
691 base::Unretained(this)));
692 }
693
694 private:
695 // IPC::mojom::SimpleTestDriver:
ExpectValue(int32_t value)696 void ExpectValue(int32_t value) override {
697 next_expected_value_ = value;
698 }
699
GetExpectedValue(GetExpectedValueCallback callback)700 void GetExpectedValue(GetExpectedValueCallback callback) override {
701 NOTREACHED();
702 }
703
RequestValue(RequestValueCallback callback)704 void RequestValue(RequestValueCallback callback) override { NOTREACHED(); }
705
RequestQuit(RequestQuitCallback callback)706 void RequestQuit(RequestQuitCallback callback) override {
707 EXPECT_EQ(kNumMessages, num_messages_received_);
708 std::move(callback).Run();
709 std::move(quit_closure_).Run();
710 }
711
BindReceiver(mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestDriver> receiver)712 void BindReceiver(
713 mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestDriver> receiver) {
714 DCHECK(!receiver_.is_bound());
715 receiver_.Bind(std::move(receiver));
716 }
717
718 int32_t next_expected_value_ = 0;
719 int num_messages_received_ = 0;
720 base::OnceClosure quit_closure_;
721
722 mojo::AssociatedReceiver<IPC::mojom::SimpleTestDriver> receiver_{this};
723 };
724
725 const int ListenerWithSimpleAssociatedInterface::kNumMessages = 1000;
726
727 class ListenerSendingAssociatedMessages : public IPC::Listener {
728 public:
ListenerSendingAssociatedMessages(base::OnceClosure quit_closure)729 explicit ListenerSendingAssociatedMessages(base::OnceClosure quit_closure)
730 : quit_closure_(std::move(quit_closure)) {}
731
OnMessageReceived(const IPC::Message & message)732 bool OnMessageReceived(const IPC::Message& message) override { return true; }
733
OnChannelConnected(int32_t peer_pid)734 void OnChannelConnected(int32_t peer_pid) override {
735 DCHECK(channel_);
736 channel_->GetAssociatedInterfaceSupport()->GetRemoteAssociatedInterface(
737 driver_.BindNewEndpointAndPassReceiver());
738
739 // Send a bunch of interleaved messages, alternating between the associated
740 // interface and a legacy IPC::Message.
741 for (int i = 0; i < ListenerWithSimpleAssociatedInterface::kNumMessages;
742 ++i) {
743 driver_->ExpectValue(i);
744 SendValue(channel_, i);
745 }
746 driver_->RequestQuit(base::BindOnce(
747 &ListenerSendingAssociatedMessages::OnQuitAck, base::Unretained(this)));
748 }
749
set_channel(IPC::Channel * channel)750 void set_channel(IPC::Channel* channel) { channel_ = channel; }
751
752 private:
OnQuitAck()753 void OnQuitAck() { std::move(quit_closure_).Run(); }
754
755 IPC::Channel* channel_ = nullptr;
756 mojo::AssociatedRemote<IPC::mojom::SimpleTestDriver> driver_;
757 base::OnceClosure quit_closure_;
758 };
759
TEST_F(IPCChannelMojoTest,SimpleAssociatedInterface)760 TEST_F(IPCChannelMojoTest, SimpleAssociatedInterface) {
761 Init("SimpleAssociatedInterfaceClient");
762
763 base::RunLoop run_loop;
764 ListenerWithSimpleAssociatedInterface listener(run_loop.QuitClosure());
765 CreateChannel(&listener);
766 ASSERT_TRUE(ConnectChannel());
767
768 listener.RegisterInterfaceFactory(channel());
769
770 run_loop.Run();
771 channel()->Close();
772
773 EXPECT_TRUE(WaitForClientShutdown());
774 DestroyChannel();
775 }
776
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(SimpleAssociatedInterfaceClient)777 DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(SimpleAssociatedInterfaceClient) {
778 base::RunLoop run_loop;
779 ListenerSendingAssociatedMessages listener(run_loop.QuitClosure());
780 Connect(&listener);
781 listener.set_channel(channel());
782
783 run_loop.Run();
784
785 Close();
786 }
787
788 class ChannelProxyRunner {
789 public:
ChannelProxyRunner(mojo::ScopedMessagePipeHandle handle,bool for_server)790 ChannelProxyRunner(mojo::ScopedMessagePipeHandle handle,
791 bool for_server)
792 : for_server_(for_server),
793 handle_(std::move(handle)),
794 io_thread_("ChannelProxyRunner IO thread"),
795 never_signaled_(base::WaitableEvent::ResetPolicy::MANUAL,
796 base::WaitableEvent::InitialState::NOT_SIGNALED) {
797 }
798
CreateProxy(IPC::Listener * listener)799 void CreateProxy(IPC::Listener* listener) {
800 io_thread_.StartWithOptions(
801 base::Thread::Options(base::MessagePumpType::IO, 0));
802 proxy_ = IPC::SyncChannel::Create(listener, io_thread_.task_runner(),
803 base::ThreadTaskRunnerHandle::Get(),
804 &never_signaled_);
805 }
806
RunProxy()807 void RunProxy() {
808 std::unique_ptr<IPC::ChannelFactory> factory;
809 if (for_server_) {
810 factory = IPC::ChannelMojo::CreateServerFactory(
811 std::move(handle_), io_thread_.task_runner(),
812 base::ThreadTaskRunnerHandle::Get());
813 } else {
814 factory = IPC::ChannelMojo::CreateClientFactory(
815 std::move(handle_), io_thread_.task_runner(),
816 base::ThreadTaskRunnerHandle::Get());
817 }
818 proxy_->Init(std::move(factory), true);
819 }
820
proxy()821 IPC::ChannelProxy* proxy() { return proxy_.get(); }
822
823 private:
824 const bool for_server_;
825
826 mojo::ScopedMessagePipeHandle handle_;
827 base::Thread io_thread_;
828 base::WaitableEvent never_signaled_;
829 std::unique_ptr<IPC::ChannelProxy> proxy_;
830
831 DISALLOW_COPY_AND_ASSIGN(ChannelProxyRunner);
832 };
833
834 class IPCChannelProxyMojoTest : public IPCChannelMojoTestBase {
835 public:
Init(const std::string & client_name)836 void Init(const std::string& client_name) {
837 IPCChannelMojoTestBase::Init(client_name);
838 runner_.reset(new ChannelProxyRunner(TakeHandle(), true));
839 }
CreateProxy(IPC::Listener * listener)840 void CreateProxy(IPC::Listener* listener) { runner_->CreateProxy(listener); }
RunProxy()841 void RunProxy() {
842 runner_->RunProxy();
843 }
DestroyProxy()844 void DestroyProxy() {
845 runner_.reset();
846 base::RunLoop().RunUntilIdle();
847 }
848
proxy()849 IPC::ChannelProxy* proxy() { return runner_->proxy(); }
850
851 private:
852 std::unique_ptr<ChannelProxyRunner> runner_;
853 };
854
855 class ListenerWithSimpleProxyAssociatedInterface
856 : public IPC::Listener,
857 public IPC::mojom::SimpleTestDriver {
858 public:
859 static const int kNumMessages;
860
ListenerWithSimpleProxyAssociatedInterface(base::OnceClosure quit_closure)861 explicit ListenerWithSimpleProxyAssociatedInterface(
862 base::OnceClosure quit_closure)
863 : quit_closure_(std::move(quit_closure)) {}
864
865 ~ListenerWithSimpleProxyAssociatedInterface() override = default;
866
OnMessageReceived(const IPC::Message & message)867 bool OnMessageReceived(const IPC::Message& message) override {
868 base::PickleIterator iter(message);
869 int32_t should_be_expected;
870 EXPECT_TRUE(iter.ReadInt(&should_be_expected));
871 EXPECT_EQ(should_be_expected, next_expected_value_);
872 num_messages_received_++;
873 return true;
874 }
875
OnChannelError()876 void OnChannelError() override { CHECK(!quit_closure_); }
877
OnAssociatedInterfaceRequest(const std::string & interface_name,mojo::ScopedInterfaceEndpointHandle handle)878 void OnAssociatedInterfaceRequest(
879 const std::string& interface_name,
880 mojo::ScopedInterfaceEndpointHandle handle) override {
881 DCHECK_EQ(interface_name, IPC::mojom::SimpleTestDriver::Name_);
882 receiver_.Bind(
883 mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestDriver>(
884 std::move(handle)));
885 }
886
received_all_messages() const887 bool received_all_messages() const {
888 return num_messages_received_ == kNumMessages && !quit_closure_;
889 }
890
891 private:
892 // IPC::mojom::SimpleTestDriver:
ExpectValue(int32_t value)893 void ExpectValue(int32_t value) override {
894 next_expected_value_ = value;
895 }
896
GetExpectedValue(GetExpectedValueCallback callback)897 void GetExpectedValue(GetExpectedValueCallback callback) override {
898 std::move(callback).Run(next_expected_value_);
899 }
900
RequestValue(RequestValueCallback callback)901 void RequestValue(RequestValueCallback callback) override { NOTREACHED(); }
902
RequestQuit(RequestQuitCallback callback)903 void RequestQuit(RequestQuitCallback callback) override {
904 std::move(callback).Run();
905 receiver_.reset();
906 std::move(quit_closure_).Run();
907 }
908
BindReceiver(mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestDriver> receiver)909 void BindReceiver(
910 mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestDriver> receiver) {
911 DCHECK(!receiver_.is_bound());
912 receiver_.Bind(std::move(receiver));
913 }
914
915 int32_t next_expected_value_ = 0;
916 int num_messages_received_ = 0;
917 base::OnceClosure quit_closure_;
918
919 mojo::AssociatedReceiver<IPC::mojom::SimpleTestDriver> receiver_{this};
920 };
921
922 const int ListenerWithSimpleProxyAssociatedInterface::kNumMessages = 1000;
923
TEST_F(IPCChannelProxyMojoTest,ProxyThreadAssociatedInterface)924 TEST_F(IPCChannelProxyMojoTest, ProxyThreadAssociatedInterface) {
925 Init("ProxyThreadAssociatedInterfaceClient");
926
927 base::RunLoop run_loop;
928 ListenerWithSimpleProxyAssociatedInterface listener(run_loop.QuitClosure());
929 CreateProxy(&listener);
930 RunProxy();
931
932 run_loop.Run();
933
934 EXPECT_TRUE(WaitForClientShutdown());
935 EXPECT_TRUE(listener.received_all_messages());
936
937 DestroyProxy();
938 }
939
940 class ChannelProxyClient {
941 public:
Init(mojo::ScopedMessagePipeHandle handle)942 void Init(mojo::ScopedMessagePipeHandle handle) {
943 runner_.reset(new ChannelProxyRunner(std::move(handle), false));
944 }
945
CreateProxy(IPC::Listener * listener)946 void CreateProxy(IPC::Listener* listener) { runner_->CreateProxy(listener); }
947
RunProxy()948 void RunProxy() { runner_->RunProxy(); }
949
DestroyProxy()950 void DestroyProxy() {
951 runner_.reset();
952 base::RunLoop().RunUntilIdle();
953 }
954
RequestQuitAndWaitForAck(IPC::mojom::SimpleTestDriver * driver)955 void RequestQuitAndWaitForAck(IPC::mojom::SimpleTestDriver* driver) {
956 base::RunLoop loop;
957 driver->RequestQuit(loop.QuitClosure());
958 loop.Run();
959 }
960
proxy()961 IPC::ChannelProxy* proxy() { return runner_->proxy(); }
962
963 private:
964 base::test::SingleThreadTaskEnvironment task_environment_;
965 std::unique_ptr<ChannelProxyRunner> runner_;
966 };
967
968 class DummyListener : public IPC::Listener {
969 public:
970 // IPC::Listener
OnMessageReceived(const IPC::Message & message)971 bool OnMessageReceived(const IPC::Message& message) override { return true; }
972 };
973
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(ProxyThreadAssociatedInterfaceClient,ChannelProxyClient)974 DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
975 ProxyThreadAssociatedInterfaceClient,
976 ChannelProxyClient) {
977 DummyListener listener;
978 CreateProxy(&listener);
979 RunProxy();
980
981 // Send a bunch of interleaved messages, alternating between the associated
982 // interface and a legacy IPC::Message.
983 mojo::AssociatedRemote<IPC::mojom::SimpleTestDriver> driver;
984 proxy()->GetRemoteAssociatedInterface(&driver);
985 for (int i = 0; i < ListenerWithSimpleProxyAssociatedInterface::kNumMessages;
986 ++i) {
987 driver->ExpectValue(i);
988 SendValue(proxy(), i);
989 }
990 base::RunLoop run_loop;
991 driver->RequestQuit(run_loop.QuitClosure());
992 run_loop.Run();
993
994 DestroyProxy();
995 }
996
997 class ListenerWithIndirectProxyAssociatedInterface
998 : public IPC::Listener,
999 public IPC::mojom::IndirectTestDriver,
1000 public IPC::mojom::PingReceiver {
1001 public:
1002 ListenerWithIndirectProxyAssociatedInterface() = default;
1003 ~ListenerWithIndirectProxyAssociatedInterface() override = default;
1004
1005 // IPC::Listener:
OnMessageReceived(const IPC::Message & message)1006 bool OnMessageReceived(const IPC::Message& message) override { return true; }
1007
OnAssociatedInterfaceRequest(const std::string & interface_name,mojo::ScopedInterfaceEndpointHandle handle)1008 void OnAssociatedInterfaceRequest(
1009 const std::string& interface_name,
1010 mojo::ScopedInterfaceEndpointHandle handle) override {
1011 DCHECK(!driver_receiver_.is_bound());
1012 DCHECK_EQ(interface_name, IPC::mojom::IndirectTestDriver::Name_);
1013 driver_receiver_.Bind(
1014 mojo::PendingAssociatedReceiver<IPC::mojom::IndirectTestDriver>(
1015 std::move(handle)));
1016 }
1017
set_ping_handler(const base::RepeatingClosure & handler)1018 void set_ping_handler(const base::RepeatingClosure& handler) {
1019 ping_handler_ = handler;
1020 }
1021
1022 private:
1023 // IPC::mojom::IndirectTestDriver:
GetPingReceiver(mojo::PendingAssociatedReceiver<IPC::mojom::PingReceiver> receiver)1024 void GetPingReceiver(mojo::PendingAssociatedReceiver<IPC::mojom::PingReceiver>
1025 receiver) override {
1026 ping_receiver_receiver_.Bind(std::move(receiver));
1027 }
1028
1029 // IPC::mojom::PingReceiver:
Ping(PingCallback callback)1030 void Ping(PingCallback callback) override {
1031 std::move(callback).Run();
1032 ping_handler_.Run();
1033 }
1034
1035 mojo::AssociatedReceiver<IPC::mojom::IndirectTestDriver> driver_receiver_{
1036 this};
1037 mojo::AssociatedReceiver<IPC::mojom::PingReceiver> ping_receiver_receiver_{
1038 this};
1039
1040 base::RepeatingClosure ping_handler_;
1041 };
1042
TEST_F(IPCChannelProxyMojoTest,ProxyThreadAssociatedInterfaceIndirect)1043 TEST_F(IPCChannelProxyMojoTest, ProxyThreadAssociatedInterfaceIndirect) {
1044 // Tests that we can pipeline interface requests and subsequent messages
1045 // targeting proxy thread bindings, and the channel will still dispatch
1046 // messages appropriately.
1047
1048 Init("ProxyThreadAssociatedInterfaceIndirectClient");
1049
1050 ListenerWithIndirectProxyAssociatedInterface listener;
1051 CreateProxy(&listener);
1052 RunProxy();
1053
1054 base::RunLoop loop;
1055 listener.set_ping_handler(loop.QuitClosure());
1056 loop.Run();
1057
1058 EXPECT_TRUE(WaitForClientShutdown());
1059
1060 DestroyProxy();
1061 }
1062
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(ProxyThreadAssociatedInterfaceIndirectClient,ChannelProxyClient)1063 DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
1064 ProxyThreadAssociatedInterfaceIndirectClient,
1065 ChannelProxyClient) {
1066 DummyListener listener;
1067 CreateProxy(&listener);
1068 RunProxy();
1069
1070 // Use an interface requested via another interface. On the remote end both
1071 // interfaces are bound on the proxy thread. This ensures that the Ping
1072 // message we send will still be dispatched properly even though the remote
1073 // endpoint may not have been bound yet by the time the message is initially
1074 // processed on the IO thread.
1075 mojo::AssociatedRemote<IPC::mojom::IndirectTestDriver> driver;
1076 mojo::AssociatedRemote<IPC::mojom::PingReceiver> ping_receiver;
1077 proxy()->GetRemoteAssociatedInterface(&driver);
1078 driver->GetPingReceiver(ping_receiver.BindNewEndpointAndPassReceiver());
1079
1080 base::RunLoop loop;
1081 ping_receiver->Ping(loop.QuitClosure());
1082 loop.Run();
1083
1084 DestroyProxy();
1085 }
1086
1087 class ListenerWithSyncAssociatedInterface
1088 : public IPC::Listener,
1089 public IPC::mojom::SimpleTestDriver {
1090 public:
1091 ListenerWithSyncAssociatedInterface() = default;
1092 ~ListenerWithSyncAssociatedInterface() override = default;
1093
set_sync_sender(IPC::Sender * sync_sender)1094 void set_sync_sender(IPC::Sender* sync_sender) { sync_sender_ = sync_sender; }
1095
RunUntilQuitRequested()1096 void RunUntilQuitRequested() {
1097 base::RunLoop loop;
1098 quit_closure_ = loop.QuitClosure();
1099 loop.Run();
1100 }
1101
CloseBinding()1102 void CloseBinding() { receiver_.reset(); }
1103
set_response_value(int32_t response)1104 void set_response_value(int32_t response) {
1105 response_value_ = response;
1106 }
1107
1108 private:
1109 // IPC::mojom::SimpleTestDriver:
ExpectValue(int32_t value)1110 void ExpectValue(int32_t value) override {
1111 next_expected_value_ = value;
1112 }
1113
GetExpectedValue(GetExpectedValueCallback callback)1114 void GetExpectedValue(GetExpectedValueCallback callback) override {
1115 std::move(callback).Run(next_expected_value_);
1116 }
1117
RequestValue(RequestValueCallback callback)1118 void RequestValue(RequestValueCallback callback) override {
1119 std::move(callback).Run(response_value_);
1120 }
1121
RequestQuit(RequestQuitCallback callback)1122 void RequestQuit(RequestQuitCallback callback) override {
1123 std::move(quit_closure_).Run();
1124 std::move(callback).Run();
1125 }
1126
1127 // IPC::Listener:
OnMessageReceived(const IPC::Message & message)1128 bool OnMessageReceived(const IPC::Message& message) override {
1129 EXPECT_EQ(0u, message.type());
1130 EXPECT_TRUE(message.is_sync());
1131 EXPECT_TRUE(message.should_unblock());
1132 std::unique_ptr<IPC::Message> reply(
1133 IPC::SyncMessage::GenerateReply(&message));
1134 reply->WriteInt(response_value_);
1135 DCHECK(sync_sender_);
1136 EXPECT_TRUE(sync_sender_->Send(reply.release()));
1137 return true;
1138 }
1139
OnAssociatedInterfaceRequest(const std::string & interface_name,mojo::ScopedInterfaceEndpointHandle handle)1140 void OnAssociatedInterfaceRequest(
1141 const std::string& interface_name,
1142 mojo::ScopedInterfaceEndpointHandle handle) override {
1143 DCHECK(!receiver_.is_bound());
1144 DCHECK_EQ(interface_name, IPC::mojom::SimpleTestDriver::Name_);
1145 receiver_.Bind(
1146 mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestDriver>(
1147 std::move(handle)));
1148 }
1149
BindReceiver(mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestDriver> receiver)1150 void BindReceiver(
1151 mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestDriver> receiver) {
1152 DCHECK(!receiver_.is_bound());
1153 receiver_.Bind(std::move(receiver));
1154 }
1155
1156 IPC::Sender* sync_sender_ = nullptr;
1157 int32_t next_expected_value_ = 0;
1158 int32_t response_value_ = 0;
1159 base::OnceClosure quit_closure_;
1160
1161 mojo::AssociatedReceiver<IPC::mojom::SimpleTestDriver> receiver_{this};
1162 };
1163
1164 class SyncReplyReader : public IPC::MessageReplyDeserializer {
1165 public:
SyncReplyReader(int32_t * storage)1166 explicit SyncReplyReader(int32_t* storage) : storage_(storage) {}
1167 ~SyncReplyReader() override = default;
1168
1169 private:
1170 // IPC::MessageReplyDeserializer:
SerializeOutputParameters(const IPC::Message & message,base::PickleIterator iter)1171 bool SerializeOutputParameters(const IPC::Message& message,
1172 base::PickleIterator iter) override {
1173 if (!iter.ReadInt(storage_))
1174 return false;
1175 return true;
1176 }
1177
1178 int32_t* storage_;
1179
1180 DISALLOW_COPY_AND_ASSIGN(SyncReplyReader);
1181 };
1182
TEST_F(IPCChannelProxyMojoTest,SyncAssociatedInterface)1183 TEST_F(IPCChannelProxyMojoTest, SyncAssociatedInterface) {
1184 Init("SyncAssociatedInterface");
1185
1186 ListenerWithSyncAssociatedInterface listener;
1187 CreateProxy(&listener);
1188 listener.set_sync_sender(proxy());
1189 RunProxy();
1190
1191 // Run the client's simple sanity check to completion.
1192 listener.RunUntilQuitRequested();
1193
1194 // Verify that we can send a sync IPC and service an incoming sync request
1195 // while waiting on it
1196 listener.set_response_value(42);
1197 mojo::AssociatedRemote<IPC::mojom::SimpleTestClient> client;
1198 proxy()->GetRemoteAssociatedInterface(&client);
1199 int32_t received_value;
1200 EXPECT_TRUE(client->RequestValue(&received_value));
1201 EXPECT_EQ(42, received_value);
1202
1203 // Do it again. This time the client will send a classical sync IPC to us
1204 // while we wait.
1205 received_value = 0;
1206 EXPECT_TRUE(client->RequestValue(&received_value));
1207 EXPECT_EQ(42, received_value);
1208
1209 // Now make a classical sync IPC request to the client. It will send a
1210 // sync associated interface message to us while we wait.
1211 received_value = 0;
1212 std::unique_ptr<IPC::SyncMessage> request(
1213 new IPC::SyncMessage(0, 0, IPC::Message::PRIORITY_NORMAL,
1214 new SyncReplyReader(&received_value)));
1215 EXPECT_TRUE(proxy()->Send(request.release()));
1216 EXPECT_EQ(42, received_value);
1217
1218 listener.CloseBinding();
1219 EXPECT_TRUE(WaitForClientShutdown());
1220
1221 DestroyProxy();
1222 }
1223
1224 class SimpleTestClientImpl : public IPC::mojom::SimpleTestClient,
1225 public IPC::Listener {
1226 public:
1227 SimpleTestClientImpl() = default;
1228 ~SimpleTestClientImpl() override = default;
1229
set_driver(IPC::mojom::SimpleTestDriver * driver)1230 void set_driver(IPC::mojom::SimpleTestDriver* driver) { driver_ = driver; }
set_sync_sender(IPC::Sender * sync_sender)1231 void set_sync_sender(IPC::Sender* sync_sender) { sync_sender_ = sync_sender; }
1232
WaitForValueRequest()1233 void WaitForValueRequest() {
1234 run_loop_.reset(new base::RunLoop);
1235 run_loop_->Run();
1236 }
1237
UseSyncSenderForRequest(bool use_sync_sender)1238 void UseSyncSenderForRequest(bool use_sync_sender) {
1239 use_sync_sender_ = use_sync_sender;
1240 }
1241
1242 private:
1243 // IPC::mojom::SimpleTestClient:
RequestValue(RequestValueCallback callback)1244 void RequestValue(RequestValueCallback callback) override {
1245 int32_t response = 0;
1246 if (use_sync_sender_) {
1247 std::unique_ptr<IPC::SyncMessage> reply(new IPC::SyncMessage(
1248 0, 0, IPC::Message::PRIORITY_NORMAL, new SyncReplyReader(&response)));
1249 EXPECT_TRUE(sync_sender_->Send(reply.release()));
1250 } else {
1251 DCHECK(driver_);
1252 EXPECT_TRUE(driver_->RequestValue(&response));
1253 }
1254
1255 std::move(callback).Run(response);
1256
1257 DCHECK(run_loop_);
1258 run_loop_->Quit();
1259 }
1260
1261 // IPC::Listener:
OnMessageReceived(const IPC::Message & message)1262 bool OnMessageReceived(const IPC::Message& message) override {
1263 int32_t response;
1264 DCHECK(driver_);
1265 EXPECT_TRUE(driver_->RequestValue(&response));
1266 std::unique_ptr<IPC::Message> reply(
1267 IPC::SyncMessage::GenerateReply(&message));
1268 reply->WriteInt(response);
1269 EXPECT_TRUE(sync_sender_->Send(reply.release()));
1270
1271 DCHECK(run_loop_);
1272 run_loop_->Quit();
1273 return true;
1274 }
1275
OnAssociatedInterfaceRequest(const std::string & interface_name,mojo::ScopedInterfaceEndpointHandle handle)1276 void OnAssociatedInterfaceRequest(
1277 const std::string& interface_name,
1278 mojo::ScopedInterfaceEndpointHandle handle) override {
1279 DCHECK(!receiver_.is_bound());
1280 DCHECK_EQ(interface_name, IPC::mojom::SimpleTestClient::Name_);
1281
1282 receiver_.Bind(
1283 mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestClient>(
1284 std::move(handle)));
1285 }
1286
1287 bool use_sync_sender_ = false;
1288 mojo::AssociatedReceiver<IPC::mojom::SimpleTestClient> receiver_{this};
1289 IPC::Sender* sync_sender_ = nullptr;
1290 IPC::mojom::SimpleTestDriver* driver_ = nullptr;
1291 std::unique_ptr<base::RunLoop> run_loop_;
1292
1293 DISALLOW_COPY_AND_ASSIGN(SimpleTestClientImpl);
1294 };
1295
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(SyncAssociatedInterface,ChannelProxyClient)1296 DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(SyncAssociatedInterface,
1297 ChannelProxyClient) {
1298 SimpleTestClientImpl client_impl;
1299 CreateProxy(&client_impl);
1300 client_impl.set_sync_sender(proxy());
1301 RunProxy();
1302
1303 mojo::AssociatedRemote<IPC::mojom::SimpleTestDriver> driver;
1304 proxy()->GetRemoteAssociatedInterface(&driver);
1305 client_impl.set_driver(driver.get());
1306
1307 // Simple sync message sanity check.
1308 driver->ExpectValue(42);
1309 int32_t expected_value = 0;
1310 EXPECT_TRUE(driver->GetExpectedValue(&expected_value));
1311 EXPECT_EQ(42, expected_value);
1312 RequestQuitAndWaitForAck(driver.get());
1313
1314 // Wait for the test driver to perform a sync call test with our own sync
1315 // associated interface message nested inside.
1316 client_impl.UseSyncSenderForRequest(false);
1317 client_impl.WaitForValueRequest();
1318
1319 // Wait for the test driver to perform a sync call test with our own classical
1320 // sync IPC nested inside.
1321 client_impl.UseSyncSenderForRequest(true);
1322 client_impl.WaitForValueRequest();
1323
1324 // Wait for the test driver to perform a classical sync IPC request, with our
1325 // own sync associated interface message nested inside.
1326 client_impl.UseSyncSenderForRequest(false);
1327 client_impl.WaitForValueRequest();
1328
1329 DestroyProxy();
1330 }
1331
TEST_F(IPCChannelProxyMojoTest,Pause)1332 TEST_F(IPCChannelProxyMojoTest, Pause) {
1333 // Ensures that pausing a channel elicits the expected behavior when sending
1334 // messages, unpausing, sending more messages, and then manually flushing.
1335 // Specifically a sequence like:
1336 //
1337 // Connect()
1338 // Send(A)
1339 // Pause()
1340 // Send(B)
1341 // Send(C)
1342 // Unpause(false)
1343 // Send(D)
1344 // Send(E)
1345 // Flush()
1346 //
1347 // must result in the other end receiving messages A, D, E, B, D; in that
1348 // order.
1349 //
1350 // This behavior is required by some consumers of IPC::Channel, and it is not
1351 // sufficient to leave this up to the consumer to implement since associated
1352 // interface requests and messages also need to be queued according to the
1353 // same policy.
1354 Init("CreatePausedClient");
1355
1356 DummyListener listener;
1357 CreateProxy(&listener);
1358 RunProxy();
1359
1360 // This message must be sent immediately since the channel is unpaused.
1361 SendValue(proxy(), 1);
1362
1363 proxy()->Pause();
1364
1365 // These messages must be queued internally since the channel is paused.
1366 SendValue(proxy(), 2);
1367 SendValue(proxy(), 3);
1368
1369 proxy()->Unpause(false /* flush */);
1370
1371 // These messages must be sent immediately since the channel is unpaused.
1372 SendValue(proxy(), 4);
1373 SendValue(proxy(), 5);
1374
1375 // Now we flush the previously queued messages.
1376 proxy()->Flush();
1377
1378 EXPECT_TRUE(WaitForClientShutdown());
1379 DestroyProxy();
1380 }
1381
1382 class ExpectValueSequenceListener : public IPC::Listener {
1383 public:
ExpectValueSequenceListener(base::queue<int32_t> * expected_values,base::OnceClosure quit_closure)1384 ExpectValueSequenceListener(base::queue<int32_t>* expected_values,
1385 base::OnceClosure quit_closure)
1386 : expected_values_(expected_values),
1387 quit_closure_(std::move(quit_closure)) {}
1388 ~ExpectValueSequenceListener() override = default;
1389
1390 // IPC::Listener:
OnMessageReceived(const IPC::Message & message)1391 bool OnMessageReceived(const IPC::Message& message) override {
1392 DCHECK(!expected_values_->empty());
1393 base::PickleIterator iter(message);
1394 int32_t should_be_expected;
1395 EXPECT_TRUE(iter.ReadInt(&should_be_expected));
1396 EXPECT_EQ(expected_values_->front(), should_be_expected);
1397 expected_values_->pop();
1398 if (expected_values_->empty())
1399 std::move(quit_closure_).Run();
1400 return true;
1401 }
1402
1403 private:
1404 base::queue<int32_t>* expected_values_;
1405 base::OnceClosure quit_closure_;
1406
1407 DISALLOW_COPY_AND_ASSIGN(ExpectValueSequenceListener);
1408 };
1409
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(CreatePausedClient,ChannelProxyClient)1410 DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(CreatePausedClient,
1411 ChannelProxyClient) {
1412 base::queue<int32_t> expected_values;
1413 base::RunLoop run_loop;
1414 ExpectValueSequenceListener listener(&expected_values,
1415 run_loop.QuitClosure());
1416 CreateProxy(&listener);
1417 expected_values.push(1);
1418 expected_values.push(4);
1419 expected_values.push(5);
1420 expected_values.push(2);
1421 expected_values.push(3);
1422 RunProxy();
1423 run_loop.Run();
1424 EXPECT_TRUE(expected_values.empty());
1425 DestroyProxy();
1426 }
1427
TEST_F(IPCChannelProxyMojoTest,AssociatedRequestClose)1428 TEST_F(IPCChannelProxyMojoTest, AssociatedRequestClose) {
1429 Init("DropAssociatedRequest");
1430
1431 DummyListener listener;
1432 CreateProxy(&listener);
1433 RunProxy();
1434
1435 mojo::AssociatedRemote<IPC::mojom::AssociatedInterfaceVendor> vendor;
1436 proxy()->GetRemoteAssociatedInterface(&vendor);
1437 mojo::AssociatedRemote<IPC::mojom::SimpleTestDriver> tester;
1438 vendor->GetTestInterface(tester.BindNewEndpointAndPassReceiver());
1439 base::RunLoop run_loop;
1440 tester.set_disconnect_handler(run_loop.QuitClosure());
1441 run_loop.Run();
1442
1443 tester.reset();
1444 proxy()->GetRemoteAssociatedInterface(&tester);
1445 EXPECT_TRUE(WaitForClientShutdown());
1446 DestroyProxy();
1447 }
1448
1449 class AssociatedInterfaceDroppingListener : public IPC::Listener {
1450 public:
AssociatedInterfaceDroppingListener(base::OnceClosure callback)1451 AssociatedInterfaceDroppingListener(base::OnceClosure callback)
1452 : callback_(std::move(callback)) {}
OnMessageReceived(const IPC::Message & message)1453 bool OnMessageReceived(const IPC::Message& message) override { return false; }
1454
OnAssociatedInterfaceRequest(const std::string & interface_name,mojo::ScopedInterfaceEndpointHandle handle)1455 void OnAssociatedInterfaceRequest(
1456 const std::string& interface_name,
1457 mojo::ScopedInterfaceEndpointHandle handle) override {
1458 if (interface_name == IPC::mojom::SimpleTestDriver::Name_)
1459 std::move(callback_).Run();
1460 }
1461
1462 private:
1463 base::OnceClosure callback_;
1464 };
1465
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(DropAssociatedRequest,ChannelProxyClient)1466 DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(DropAssociatedRequest,
1467 ChannelProxyClient) {
1468 base::RunLoop run_loop;
1469 AssociatedInterfaceDroppingListener listener(run_loop.QuitClosure());
1470 CreateProxy(&listener);
1471 RunProxy();
1472 run_loop.Run();
1473 DestroyProxy();
1474 }
1475
1476 #if !defined(OS_APPLE)
1477 // TODO(wez): On Mac we need to set up a MachPortBroker before we can transfer
1478 // Mach ports (which underpin Sharedmemory on Mac) across IPC.
1479
1480 template <class SharedMemoryRegionType>
1481 class IPCChannelMojoSharedMemoryRegionTypedTest : public IPCChannelMojoTest {};
1482
1483 struct WritableRegionTraits {
1484 using RegionType = base::WritableSharedMemoryRegion;
1485 static const char kClientName[];
1486 };
1487 const char WritableRegionTraits::kClientName[] =
1488 "IPCChannelMojoTestSendWritableSharedMemoryRegionClient";
1489 struct UnsafeRegionTraits {
1490 using RegionType = base::UnsafeSharedMemoryRegion;
1491 static const char kClientName[];
1492 };
1493 const char UnsafeRegionTraits::kClientName[] =
1494 "IPCChannelMojoTestSendUnsafeSharedMemoryRegionClient";
1495 struct ReadOnlyRegionTraits {
1496 using RegionType = base::ReadOnlySharedMemoryRegion;
1497 static const char kClientName[];
1498 };
1499 const char ReadOnlyRegionTraits::kClientName[] =
1500 "IPCChannelMojoTestSendReadOnlySharedMemoryRegionClient";
1501
1502 typedef ::testing::
1503 Types<WritableRegionTraits, UnsafeRegionTraits, ReadOnlyRegionTraits>
1504 AllSharedMemoryRegionTraits;
1505 TYPED_TEST_SUITE(IPCChannelMojoSharedMemoryRegionTypedTest,
1506 AllSharedMemoryRegionTraits);
1507
1508 template <class SharedMemoryRegionType>
1509 class ListenerThatExpectsSharedMemoryRegion : public TestListenerBase {
1510 public:
ListenerThatExpectsSharedMemoryRegion(base::OnceClosure quit_closure)1511 explicit ListenerThatExpectsSharedMemoryRegion(base::OnceClosure quit_closure)
1512 : TestListenerBase(std::move(quit_closure)) {}
1513
OnMessageReceived(const IPC::Message & message)1514 bool OnMessageReceived(const IPC::Message& message) override {
1515 base::PickleIterator iter(message);
1516
1517 SharedMemoryRegionType region;
1518 EXPECT_TRUE(IPC::ReadParam(&message, &iter, ®ion));
1519 EXPECT_TRUE(region.IsValid());
1520
1521 // Verify the shared memory region has expected content.
1522 typename SharedMemoryRegionType::MappingType mapping = region.Map();
1523 std::string content = HandleSendingHelper::GetSendingFileContent();
1524 EXPECT_EQ(0, memcmp(mapping.memory(), content.data(), content.size()));
1525
1526 ListenerThatExpectsOK::SendOK(sender());
1527 return true;
1528 }
1529 };
1530
TYPED_TEST(IPCChannelMojoSharedMemoryRegionTypedTest,Send)1531 TYPED_TEST(IPCChannelMojoSharedMemoryRegionTypedTest, Send) {
1532 this->Init(TypeParam::kClientName);
1533
1534 const size_t size = 1004;
1535 typename TypeParam::RegionType region;
1536 base::WritableSharedMemoryMapping mapping;
1537 std::tie(region, mapping) =
1538 base::CreateMappedRegion<typename TypeParam::RegionType>(size);
1539
1540 std::string content = HandleSendingHelper::GetSendingFileContent();
1541 memcpy(mapping.memory(), content.data(), content.size());
1542
1543 // Create a success listener, and launch the child process.
1544 base::RunLoop run_loop;
1545 ListenerThatExpectsOK listener(run_loop.QuitClosure());
1546 this->CreateChannel(&listener);
1547 ASSERT_TRUE(this->ConnectChannel());
1548
1549 // Send the child process an IPC with |shmem| attached, to verify
1550 // that is is correctly wrapped, transferred and unwrapped.
1551 IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
1552 IPC::WriteParam(message, region);
1553 ASSERT_TRUE(this->channel()->Send(message));
1554
1555 run_loop.Run();
1556
1557 this->channel()->Close();
1558
1559 EXPECT_TRUE(this->WaitForClientShutdown());
1560 EXPECT_FALSE(region.IsValid());
1561 this->DestroyChannel();
1562 }
1563
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendWritableSharedMemoryRegionClient)1564 DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
1565 IPCChannelMojoTestSendWritableSharedMemoryRegionClient) {
1566 base::RunLoop run_loop;
1567 ListenerThatExpectsSharedMemoryRegion<base::WritableSharedMemoryRegion>
1568 listener(run_loop.QuitClosure());
1569 Connect(&listener);
1570 listener.set_sender(channel());
1571
1572 run_loop.Run();
1573
1574 Close();
1575 }
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendUnsafeSharedMemoryRegionClient)1576 DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
1577 IPCChannelMojoTestSendUnsafeSharedMemoryRegionClient) {
1578 base::RunLoop run_loop;
1579 ListenerThatExpectsSharedMemoryRegion<base::UnsafeSharedMemoryRegion>
1580 listener(run_loop.QuitClosure());
1581 Connect(&listener);
1582 listener.set_sender(channel());
1583
1584 run_loop.Run();
1585
1586 Close();
1587 }
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendReadOnlySharedMemoryRegionClient)1588 DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
1589 IPCChannelMojoTestSendReadOnlySharedMemoryRegionClient) {
1590 base::RunLoop run_loop;
1591 ListenerThatExpectsSharedMemoryRegion<base::ReadOnlySharedMemoryRegion>
1592 listener(run_loop.QuitClosure());
1593 Connect(&listener);
1594 listener.set_sender(channel());
1595
1596 run_loop.Run();
1597
1598 Close();
1599 }
1600 #endif // !defined(OS_APPLE)
1601
1602 #if defined(OS_POSIX) || defined(OS_FUCHSIA)
1603
1604 class ListenerThatExpectsFile : public TestListenerBase {
1605 public:
ListenerThatExpectsFile(base::OnceClosure quit_closure)1606 explicit ListenerThatExpectsFile(base::OnceClosure quit_closure)
1607 : TestListenerBase(std::move(quit_closure)) {}
1608
OnMessageReceived(const IPC::Message & message)1609 bool OnMessageReceived(const IPC::Message& message) override {
1610 base::PickleIterator iter(message);
1611 HandleSendingHelper::ReadReceivedFile(message, &iter);
1612 ListenerThatExpectsOK::SendOK(sender());
1613 return true;
1614 }
1615 };
1616
TEST_F(IPCChannelMojoTest,SendPlatformFile)1617 TEST_F(IPCChannelMojoTest, SendPlatformFile) {
1618 Init("IPCChannelMojoTestSendPlatformFileClient");
1619
1620 base::RunLoop run_loop;
1621 ListenerThatExpectsOK listener(run_loop.QuitClosure());
1622 CreateChannel(&listener);
1623 ASSERT_TRUE(ConnectChannel());
1624
1625 base::ScopedTempDir temp_dir;
1626 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1627 base::File file(HandleSendingHelper::GetSendingFilePath(temp_dir.GetPath()),
1628 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
1629 base::File::FLAG_READ);
1630 HandleSendingHelper::WriteFileThenSend(channel(), file);
1631 run_loop.Run();
1632
1633 channel()->Close();
1634
1635 EXPECT_TRUE(WaitForClientShutdown());
1636 DestroyChannel();
1637 }
1638
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendPlatformFileClient)1639 DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendPlatformFileClient) {
1640 base::RunLoop run_loop;
1641 ListenerThatExpectsFile listener(run_loop.QuitClosure());
1642 Connect(&listener);
1643 listener.set_sender(channel());
1644
1645 run_loop.Run();
1646
1647 Close();
1648 }
1649
1650 class ListenerThatExpectsFileAndMessagePipe : public TestListenerBase {
1651 public:
ListenerThatExpectsFileAndMessagePipe(base::OnceClosure quit_closure)1652 explicit ListenerThatExpectsFileAndMessagePipe(base::OnceClosure quit_closure)
1653 : TestListenerBase(std::move(quit_closure)) {}
1654
1655 ~ListenerThatExpectsFileAndMessagePipe() override = default;
1656
OnMessageReceived(const IPC::Message & message)1657 bool OnMessageReceived(const IPC::Message& message) override {
1658 base::PickleIterator iter(message);
1659 HandleSendingHelper::ReadReceivedFile(message, &iter);
1660 HandleSendingHelper::ReadReceivedPipe(message, &iter);
1661 ListenerThatExpectsOK::SendOK(sender());
1662 return true;
1663 }
1664 };
1665
TEST_F(IPCChannelMojoTest,SendPlatformFileAndMessagePipe)1666 TEST_F(IPCChannelMojoTest, SendPlatformFileAndMessagePipe) {
1667 Init("IPCChannelMojoTestSendPlatformFileAndMessagePipeClient");
1668
1669 base::RunLoop run_loop;
1670 ListenerThatExpectsOK listener(run_loop.QuitClosure());
1671 CreateChannel(&listener);
1672 ASSERT_TRUE(ConnectChannel());
1673
1674 base::ScopedTempDir temp_dir;
1675 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1676 base::File file(HandleSendingHelper::GetSendingFilePath(temp_dir.GetPath()),
1677 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
1678 base::File::FLAG_READ);
1679 TestingMessagePipe pipe;
1680 HandleSendingHelper::WriteFileAndPipeThenSend(channel(), file, &pipe);
1681
1682 run_loop.Run();
1683 channel()->Close();
1684
1685 EXPECT_TRUE(WaitForClientShutdown());
1686 DestroyChannel();
1687 }
1688
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendPlatformFileAndMessagePipeClient)1689 DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
1690 IPCChannelMojoTestSendPlatformFileAndMessagePipeClient) {
1691 base::RunLoop run_loop;
1692 ListenerThatExpectsFileAndMessagePipe listener(run_loop.QuitClosure());
1693 Connect(&listener);
1694 listener.set_sender(channel());
1695
1696 run_loop.Run();
1697
1698 Close();
1699 }
1700
1701 #endif // defined(OS_POSIX) || defined(OS_FUCHSIA)
1702
1703 #if defined(OS_LINUX) || defined(OS_CHROMEOS)
1704
1705 const base::ProcessId kMagicChildId = 54321;
1706
1707 class ListenerThatVerifiesPeerPid : public TestListenerBase {
1708 public:
ListenerThatVerifiesPeerPid(base::OnceClosure quit_closure)1709 explicit ListenerThatVerifiesPeerPid(base::OnceClosure quit_closure)
1710 : TestListenerBase(std::move(quit_closure)) {}
1711
OnChannelConnected(int32_t peer_pid)1712 void OnChannelConnected(int32_t peer_pid) override {
1713 EXPECT_EQ(peer_pid, kMagicChildId);
1714 RunQuitClosure();
1715 }
1716
OnMessageReceived(const IPC::Message & message)1717 bool OnMessageReceived(const IPC::Message& message) override {
1718 NOTREACHED();
1719 return true;
1720 }
1721 };
1722
TEST_F(IPCChannelMojoTest,VerifyGlobalPid)1723 TEST_F(IPCChannelMojoTest, VerifyGlobalPid) {
1724 Init("IPCChannelMojoTestVerifyGlobalPidClient");
1725
1726 base::RunLoop run_loop;
1727 ListenerThatVerifiesPeerPid listener(run_loop.QuitClosure());
1728 CreateChannel(&listener);
1729 ASSERT_TRUE(ConnectChannel());
1730
1731 run_loop.Run();
1732 channel()->Close();
1733
1734 EXPECT_TRUE(WaitForClientShutdown());
1735 DestroyChannel();
1736 }
1737
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestVerifyGlobalPidClient)1738 DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestVerifyGlobalPidClient) {
1739 IPC::Channel::SetGlobalPid(kMagicChildId);
1740
1741 base::RunLoop run_loop;
1742 ListenerThatQuits listener(run_loop.QuitClosure());
1743 Connect(&listener);
1744
1745 run_loop.Run();
1746
1747 Close();
1748 }
1749
1750 #endif // defined(OS_LINUX) || defined(OS_CHROMEOS)
1751
1752 } // namespace
1753