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