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