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, &region));
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