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