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