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, ®ion));
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